Followup to 2011-10-19T09:48:35Z!eliz@gnu.org.
[bpt/emacs.git] / src / xdisp.c
1 /* Display generation from window structure and buffer text.
2
3 Copyright (C) 1985-1988, 1993-1995, 1997-2011 Free Software Foundation, Inc.
4
5 This file is part of GNU Emacs.
6
7 GNU Emacs is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
11
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
19
20 /* New redisplay written by Gerd Moellmann <gerd@gnu.org>.
21
22 Redisplay.
23
24 Emacs separates the task of updating the display from code
25 modifying global state, e.g. buffer text. This way functions
26 operating on buffers don't also have to be concerned with updating
27 the display.
28
29 Updating the display is triggered by the Lisp interpreter when it
30 decides it's time to do it. This is done either automatically for
31 you as part of the interpreter's command loop or as the result of
32 calling Lisp functions like `sit-for'. The C function `redisplay'
33 in xdisp.c is the only entry into the inner redisplay code.
34
35 The following diagram shows how redisplay code is invoked. As you
36 can see, Lisp calls redisplay and vice versa. Under window systems
37 like X, some portions of the redisplay code are also called
38 asynchronously during mouse movement or expose events. It is very
39 important that these code parts do NOT use the C library (malloc,
40 free) because many C libraries under Unix are not reentrant. They
41 may also NOT call functions of the Lisp interpreter which could
42 change the interpreter's state. If you don't follow these rules,
43 you will encounter bugs which are very hard to explain.
44
45 +--------------+ redisplay +----------------+
46 | Lisp machine |---------------->| Redisplay code |<--+
47 +--------------+ (xdisp.c) +----------------+ |
48 ^ | |
49 +----------------------------------+ |
50 Don't use this path when called |
51 asynchronously! |
52 |
53 expose_window (asynchronous) |
54 |
55 X expose events -----+
56
57 What does redisplay do? Obviously, it has to figure out somehow what
58 has been changed since the last time the display has been updated,
59 and to make these changes visible. Preferably it would do that in
60 a moderately intelligent way, i.e. fast.
61
62 Changes in buffer text can be deduced from window and buffer
63 structures, and from some global variables like `beg_unchanged' and
64 `end_unchanged'. The contents of the display are additionally
65 recorded in a `glyph matrix', a two-dimensional matrix of glyph
66 structures. Each row in such a matrix corresponds to a line on the
67 display, and each glyph in a row corresponds to a column displaying
68 a character, an image, or what else. This matrix is called the
69 `current glyph matrix' or `current matrix' in redisplay
70 terminology.
71
72 For buffer parts that have been changed since the last update, a
73 second glyph matrix is constructed, the so called `desired glyph
74 matrix' or short `desired matrix'. Current and desired matrix are
75 then compared to find a cheap way to update the display, e.g. by
76 reusing part of the display by scrolling lines.
77
78 You will find a lot of redisplay optimizations when you start
79 looking at the innards of redisplay. The overall goal of all these
80 optimizations is to make redisplay fast because it is done
81 frequently. Some of these optimizations are implemented by the
82 following functions:
83
84 . try_cursor_movement
85
86 This function tries to update the display if the text in the
87 window did not change and did not scroll, only point moved, and
88 it did not move off the displayed portion of the text.
89
90 . try_window_reusing_current_matrix
91
92 This function reuses the current matrix of a window when text
93 has not changed, but the window start changed (e.g., due to
94 scrolling).
95
96 . try_window_id
97
98 This function attempts to redisplay a window by reusing parts of
99 its existing display. It finds and reuses the part that was not
100 changed, and redraws the rest.
101
102 . try_window
103
104 This function performs the full redisplay of a single window
105 assuming that its fonts were not changed and that the cursor
106 will not end up in the scroll margins. (Loading fonts requires
107 re-adjustment of dimensions of glyph matrices, which makes this
108 method impossible to use.)
109
110 These optimizations are tried in sequence (some can be skipped if
111 it is known that they are not applicable). If none of the
112 optimizations were successful, redisplay calls redisplay_windows,
113 which performs a full redisplay of all windows.
114
115 Desired matrices.
116
117 Desired matrices are always built per Emacs window. The function
118 `display_line' is the central function to look at if you are
119 interested. It constructs one row in a desired matrix given an
120 iterator structure containing both a buffer position and a
121 description of the environment in which the text is to be
122 displayed. But this is too early, read on.
123
124 Characters and pixmaps displayed for a range of buffer text depend
125 on various settings of buffers and windows, on overlays and text
126 properties, on display tables, on selective display. The good news
127 is that all this hairy stuff is hidden behind a small set of
128 interface functions taking an iterator structure (struct it)
129 argument.
130
131 Iteration over things to be displayed is then simple. It is
132 started by initializing an iterator with a call to init_iterator,
133 passing it the buffer position where to start iteration. For
134 iteration over strings, pass -1 as the position to init_iterator,
135 and call reseat_to_string when the string is ready, to initialize
136 the iterator for that string. Thereafter, calls to
137 get_next_display_element fill the iterator structure with relevant
138 information about the next thing to display. Calls to
139 set_iterator_to_next move the iterator to the next thing.
140
141 Besides this, an iterator also contains information about the
142 display environment in which glyphs for display elements are to be
143 produced. It has fields for the width and height of the display,
144 the information whether long lines are truncated or continued, a
145 current X and Y position, and lots of other stuff you can better
146 see in dispextern.h.
147
148 Glyphs in a desired matrix are normally constructed in a loop
149 calling get_next_display_element and then PRODUCE_GLYPHS. The call
150 to PRODUCE_GLYPHS will fill the iterator structure with pixel
151 information about the element being displayed and at the same time
152 produce glyphs for it. If the display element fits on the line
153 being displayed, set_iterator_to_next is called next, otherwise the
154 glyphs produced are discarded. The function display_line is the
155 workhorse of filling glyph rows in the desired matrix with glyphs.
156 In addition to producing glyphs, it also handles line truncation
157 and continuation, word wrap, and cursor positioning (for the
158 latter, see also set_cursor_from_row).
159
160 Frame matrices.
161
162 That just couldn't be all, could it? What about terminal types not
163 supporting operations on sub-windows of the screen? To update the
164 display on such a terminal, window-based glyph matrices are not
165 well suited. To be able to reuse part of the display (scrolling
166 lines up and down), we must instead have a view of the whole
167 screen. This is what `frame matrices' are for. They are a trick.
168
169 Frames on terminals like above have a glyph pool. Windows on such
170 a frame sub-allocate their glyph memory from their frame's glyph
171 pool. The frame itself is given its own glyph matrices. By
172 coincidence---or maybe something else---rows in window glyph
173 matrices are slices of corresponding rows in frame matrices. Thus
174 writing to window matrices implicitly updates a frame matrix which
175 provides us with the view of the whole screen that we originally
176 wanted to have without having to move many bytes around. To be
177 honest, there is a little bit more done, but not much more. If you
178 plan to extend that code, take a look at dispnew.c. The function
179 build_frame_matrix is a good starting point.
180
181 Bidirectional display.
182
183 Bidirectional display adds quite some hair to this already complex
184 design. The good news are that a large portion of that hairy stuff
185 is hidden in bidi.c behind only 3 interfaces. bidi.c implements a
186 reordering engine which is called by set_iterator_to_next and
187 returns the next character to display in the visual order. See
188 commentary on bidi.c for more details. As far as redisplay is
189 concerned, the effect of calling bidi_move_to_visually_next, the
190 main interface of the reordering engine, is that the iterator gets
191 magically placed on the buffer or string position that is to be
192 displayed next. In other words, a linear iteration through the
193 buffer/string is replaced with a non-linear one. All the rest of
194 the redisplay is oblivious to the bidi reordering.
195
196 Well, almost oblivious---there are still complications, most of
197 them due to the fact that buffer and string positions no longer
198 change monotonously with glyph indices in a glyph row. Moreover,
199 for continued lines, the buffer positions may not even be
200 monotonously changing with vertical positions. Also, accounting
201 for face changes, overlays, etc. becomes more complex because
202 non-linear iteration could potentially skip many positions with
203 changes, and then cross them again on the way back...
204
205 One other prominent effect of bidirectional display is that some
206 paragraphs of text need to be displayed starting at the right
207 margin of the window---the so-called right-to-left, or R2L
208 paragraphs. R2L paragraphs are displayed with R2L glyph rows,
209 which have their reversed_p flag set. The bidi reordering engine
210 produces characters in such rows starting from the character which
211 should be the rightmost on display. PRODUCE_GLYPHS then reverses
212 the order, when it fills up the glyph row whose reversed_p flag is
213 set, by prepending each new glyph to what is already there, instead
214 of appending it. When the glyph row is complete, the function
215 extend_face_to_end_of_line fills the empty space to the left of the
216 leftmost character with special glyphs, which will display as,
217 well, empty. On text terminals, these special glyphs are simply
218 blank characters. On graphics terminals, there's a single stretch
219 glyph of a suitably computed width. Both the blanks and the
220 stretch glyph are given the face of the background of the line.
221 This way, the terminal-specific back-end can still draw the glyphs
222 left to right, even for R2L lines.
223
224 Bidirectional display and character compositions
225
226 Some scripts cannot be displayed by drawing each character
227 individually, because adjacent characters change each other's shape
228 on display. For example, Arabic and Indic scripts belong to this
229 category.
230
231 Emacs display supports this by providing "character compositions",
232 most of which is implemented in composite.c. During the buffer
233 scan that delivers characters to PRODUCE_GLYPHS, if the next
234 character to be delivered is a composed character, the iteration
235 calls composition_reseat_it and next_element_from_composition. If
236 they succeed to compose the character with one or more of the
237 following characters, the whole sequence of characters that where
238 composed is recorded in the `struct composition_it' object that is
239 part of the buffer iterator. The composed sequence could produce
240 one or more font glyphs (called "grapheme clusters") on the screen.
241 Each of these grapheme clusters is then delivered to PRODUCE_GLYPHS
242 in the direction corresponding to the current bidi scan direction
243 (recorded in the scan_dir member of the `struct bidi_it' object
244 that is part of the buffer iterator). In particular, if the bidi
245 iterator currently scans the buffer backwards, the grapheme
246 clusters are delivered back to front. This reorders the grapheme
247 clusters as appropriate for the current bidi context. Note that
248 this means that the grapheme clusters are always stored in the
249 LGSTRING object (see composite.c) in the logical order.
250
251 Moving an iterator in bidirectional text
252 without producing glyphs
253
254 Note one important detail mentioned above: that the bidi reordering
255 engine, driven by the iterator, produces characters in R2L rows
256 starting at the character that will be the rightmost on display.
257 As far as the iterator is concerned, the geometry of such rows is
258 still left to right, i.e. the iterator "thinks" the first character
259 is at the leftmost pixel position. The iterator does not know that
260 PRODUCE_GLYPHS reverses the order of the glyphs that the iterator
261 delivers. This is important when functions from the move_it_*
262 family are used to get to certain screen position or to match
263 screen coordinates with buffer coordinates: these functions use the
264 iterator geometry, which is left to right even in R2L paragraphs.
265 This works well with most callers of move_it_*, because they need
266 to get to a specific column, and columns are still numbered in the
267 reading order, i.e. the rightmost character in a R2L paragraph is
268 still column zero. But some callers do not get well with this; a
269 notable example is mouse clicks that need to find the character
270 that corresponds to certain pixel coordinates. See
271 buffer_posn_from_coords in dispnew.c for how this is handled. */
272
273 #include <config.h>
274 #include <stdio.h>
275 #include <limits.h>
276 #include <setjmp.h>
277
278 #include "lisp.h"
279 #include "keyboard.h"
280 #include "frame.h"
281 #include "window.h"
282 #include "termchar.h"
283 #include "dispextern.h"
284 #include "buffer.h"
285 #include "character.h"
286 #include "charset.h"
287 #include "indent.h"
288 #include "commands.h"
289 #include "keymap.h"
290 #include "macros.h"
291 #include "disptab.h"
292 #include "termhooks.h"
293 #include "termopts.h"
294 #include "intervals.h"
295 #include "coding.h"
296 #include "process.h"
297 #include "region-cache.h"
298 #include "font.h"
299 #include "fontset.h"
300 #include "blockinput.h"
301
302 #ifdef HAVE_X_WINDOWS
303 #include "xterm.h"
304 #endif
305 #ifdef WINDOWSNT
306 #include "w32term.h"
307 #endif
308 #ifdef HAVE_NS
309 #include "nsterm.h"
310 #endif
311 #ifdef USE_GTK
312 #include "gtkutil.h"
313 #endif
314
315 #include "font.h"
316
317 #ifndef FRAME_X_OUTPUT
318 #define FRAME_X_OUTPUT(f) ((f)->output_data.x)
319 #endif
320
321 #define INFINITY 10000000
322
323 Lisp_Object Qoverriding_local_map, Qoverriding_terminal_local_map;
324 Lisp_Object Qwindow_scroll_functions;
325 static Lisp_Object Qwindow_text_change_functions;
326 static Lisp_Object Qredisplay_end_trigger_functions;
327 Lisp_Object Qinhibit_point_motion_hooks;
328 static Lisp_Object QCeval, QCpropertize;
329 Lisp_Object QCfile, QCdata;
330 static Lisp_Object Qfontified;
331 static Lisp_Object Qgrow_only;
332 static Lisp_Object Qinhibit_eval_during_redisplay;
333 static Lisp_Object Qbuffer_position, Qposition, Qobject;
334 static Lisp_Object Qright_to_left, Qleft_to_right;
335
336 /* Cursor shapes */
337 Lisp_Object Qbar, Qhbar, Qbox, Qhollow;
338
339 /* Pointer shapes */
340 static Lisp_Object Qarrow, Qhand;
341 Lisp_Object Qtext;
342
343 /* Holds the list (error). */
344 static Lisp_Object list_of_error;
345
346 static Lisp_Object Qfontification_functions;
347
348 static Lisp_Object Qwrap_prefix;
349 static Lisp_Object Qline_prefix;
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 && (IT)->line_wrap != WORD_WRAP)
381
382 #else /* !HAVE_WINDOW_SYSTEM */
383 #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(it) 0
384 #endif /* HAVE_WINDOW_SYSTEM */
385
386 /* Test if the display element loaded in IT is a space or tab
387 character. This is used to determine word wrapping. */
388
389 #define IT_DISPLAYING_WHITESPACE(it) \
390 (it->what == IT_CHARACTER && (it->c == ' ' || it->c == '\t'))
391
392 /* Name of the face used to highlight trailing whitespace. */
393
394 static Lisp_Object Qtrailing_whitespace;
395
396 /* Name and number of the face used to highlight escape glyphs. */
397
398 static Lisp_Object Qescape_glyph;
399
400 /* Name and number of the face used to highlight non-breaking spaces. */
401
402 static Lisp_Object Qnobreak_space;
403
404 /* The symbol `image' which is the car of the lists used to represent
405 images in Lisp. Also a tool bar style. */
406
407 Lisp_Object Qimage;
408
409 /* The image map types. */
410 Lisp_Object QCmap;
411 static Lisp_Object QCpointer;
412 static Lisp_Object Qrect, Qcircle, Qpoly;
413
414 /* Tool bar styles */
415 Lisp_Object Qboth, Qboth_horiz, Qtext_image_horiz;
416
417 /* Non-zero means print newline to stdout before next mini-buffer
418 message. */
419
420 int noninteractive_need_newline;
421
422 /* Non-zero means print newline to message log before next message. */
423
424 static int message_log_need_newline;
425
426 /* Three markers that message_dolog uses.
427 It could allocate them itself, but that causes trouble
428 in handling memory-full errors. */
429 static Lisp_Object message_dolog_marker1;
430 static Lisp_Object message_dolog_marker2;
431 static Lisp_Object message_dolog_marker3;
432 \f
433 /* The buffer position of the first character appearing entirely or
434 partially on the line of the selected window which contains the
435 cursor; <= 0 if not known. Set by set_cursor_from_row, used for
436 redisplay optimization in redisplay_internal. */
437
438 static struct text_pos this_line_start_pos;
439
440 /* Number of characters past the end of the line above, including the
441 terminating newline. */
442
443 static struct text_pos this_line_end_pos;
444
445 /* The vertical positions and the height of this line. */
446
447 static int this_line_vpos;
448 static int this_line_y;
449 static int this_line_pixel_height;
450
451 /* X position at which this display line starts. Usually zero;
452 negative if first character is partially visible. */
453
454 static int this_line_start_x;
455
456 /* The smallest character position seen by move_it_* functions as they
457 move across display lines. Used to set MATRIX_ROW_START_CHARPOS of
458 hscrolled lines, see display_line. */
459
460 static struct text_pos this_line_min_pos;
461
462 /* Buffer that this_line_.* variables are referring to. */
463
464 static struct buffer *this_line_buffer;
465
466
467 /* Values of those variables at last redisplay are stored as
468 properties on `overlay-arrow-position' symbol. However, if
469 Voverlay_arrow_position is a marker, last-arrow-position is its
470 numerical position. */
471
472 static Lisp_Object Qlast_arrow_position, Qlast_arrow_string;
473
474 /* Alternative overlay-arrow-string and overlay-arrow-bitmap
475 properties on a symbol in overlay-arrow-variable-list. */
476
477 static Lisp_Object Qoverlay_arrow_string, Qoverlay_arrow_bitmap;
478
479 Lisp_Object Qmenu_bar_update_hook;
480
481 /* Nonzero if an overlay arrow has been displayed in this window. */
482
483 static int overlay_arrow_seen;
484
485 /* Number of windows showing the buffer of the selected window (or
486 another buffer with the same base buffer). keyboard.c refers to
487 this. */
488
489 int buffer_shared;
490
491 /* Vector containing glyphs for an ellipsis `...'. */
492
493 static Lisp_Object default_invis_vector[3];
494
495 /* This is the window where the echo area message was displayed. It
496 is always a mini-buffer window, but it may not be the same window
497 currently active as a mini-buffer. */
498
499 Lisp_Object echo_area_window;
500
501 /* List of pairs (MESSAGE . MULTIBYTE). The function save_message
502 pushes the current message and the value of
503 message_enable_multibyte on the stack, the function restore_message
504 pops the stack and displays MESSAGE again. */
505
506 static Lisp_Object Vmessage_stack;
507
508 /* Nonzero means multibyte characters were enabled when the echo area
509 message was specified. */
510
511 static int message_enable_multibyte;
512
513 /* Nonzero if we should redraw the mode lines on the next redisplay. */
514
515 int update_mode_lines;
516
517 /* Nonzero if window sizes or contents have changed since last
518 redisplay that finished. */
519
520 int windows_or_buffers_changed;
521
522 /* Nonzero means a frame's cursor type has been changed. */
523
524 int cursor_type_changed;
525
526 /* Nonzero after display_mode_line if %l was used and it displayed a
527 line number. */
528
529 static int line_number_displayed;
530
531 /* The name of the *Messages* buffer, a string. */
532
533 static Lisp_Object Vmessages_buffer_name;
534
535 /* Current, index 0, and last displayed echo area message. Either
536 buffers from echo_buffers, or nil to indicate no message. */
537
538 Lisp_Object echo_area_buffer[2];
539
540 /* The buffers referenced from echo_area_buffer. */
541
542 static Lisp_Object echo_buffer[2];
543
544 /* A vector saved used in with_area_buffer to reduce consing. */
545
546 static Lisp_Object Vwith_echo_area_save_vector;
547
548 /* Non-zero means display_echo_area should display the last echo area
549 message again. Set by redisplay_preserve_echo_area. */
550
551 static int display_last_displayed_message_p;
552
553 /* Nonzero if echo area is being used by print; zero if being used by
554 message. */
555
556 static int message_buf_print;
557
558 /* The symbol `inhibit-menubar-update' and its DEFVAR_BOOL variable. */
559
560 static Lisp_Object Qinhibit_menubar_update;
561 static Lisp_Object Qmessage_truncate_lines;
562
563 /* Set to 1 in clear_message to make redisplay_internal aware
564 of an emptied echo area. */
565
566 static int message_cleared_p;
567
568 /* A scratch glyph row with contents used for generating truncation
569 glyphs. Also used in direct_output_for_insert. */
570
571 #define MAX_SCRATCH_GLYPHS 100
572 static struct glyph_row scratch_glyph_row;
573 static struct glyph scratch_glyphs[MAX_SCRATCH_GLYPHS];
574
575 /* Ascent and height of the last line processed by move_it_to. */
576
577 static int last_max_ascent, last_height;
578
579 /* Non-zero if there's a help-echo in the echo area. */
580
581 int help_echo_showing_p;
582
583 /* If >= 0, computed, exact values of mode-line and header-line height
584 to use in the macros CURRENT_MODE_LINE_HEIGHT and
585 CURRENT_HEADER_LINE_HEIGHT. */
586
587 int current_mode_line_height, current_header_line_height;
588
589 /* The maximum distance to look ahead for text properties. Values
590 that are too small let us call compute_char_face and similar
591 functions too often which is expensive. Values that are too large
592 let us call compute_char_face and alike too often because we
593 might not be interested in text properties that far away. */
594
595 #define TEXT_PROP_DISTANCE_LIMIT 100
596
597 /* SAVE_IT and RESTORE_IT are called when we save a snapshot of the
598 iterator state and later restore it. This is needed because the
599 bidi iterator on bidi.c keeps a stacked cache of its states, which
600 is really a singleton. When we use scratch iterator objects to
601 move around the buffer, we can cause the bidi cache to be pushed or
602 popped, and therefore we need to restore the cache state when we
603 return to the original iterator. */
604 #define SAVE_IT(ITCOPY,ITORIG,CACHE) \
605 do { \
606 if (CACHE) \
607 bidi_unshelve_cache (CACHE, 1); \
608 ITCOPY = ITORIG; \
609 CACHE = bidi_shelve_cache (); \
610 } while (0)
611
612 #define RESTORE_IT(pITORIG,pITCOPY,CACHE) \
613 do { \
614 if (pITORIG != pITCOPY) \
615 *(pITORIG) = *(pITCOPY); \
616 bidi_unshelve_cache (CACHE, 0); \
617 CACHE = NULL; \
618 } while (0)
619
620 #if GLYPH_DEBUG
621
622 /* Non-zero means print traces of redisplay if compiled with
623 GLYPH_DEBUG != 0. */
624
625 int trace_redisplay_p;
626
627 #endif /* GLYPH_DEBUG */
628
629 #ifdef DEBUG_TRACE_MOVE
630 /* Non-zero means trace with TRACE_MOVE to stderr. */
631 int trace_move;
632
633 #define TRACE_MOVE(x) if (trace_move) fprintf x; else (void) 0
634 #else
635 #define TRACE_MOVE(x) (void) 0
636 #endif
637
638 static Lisp_Object Qauto_hscroll_mode;
639
640 /* Buffer being redisplayed -- for redisplay_window_error. */
641
642 static struct buffer *displayed_buffer;
643
644 /* Value returned from text property handlers (see below). */
645
646 enum prop_handled
647 {
648 HANDLED_NORMALLY,
649 HANDLED_RECOMPUTE_PROPS,
650 HANDLED_OVERLAY_STRING_CONSUMED,
651 HANDLED_RETURN
652 };
653
654 /* A description of text properties that redisplay is interested
655 in. */
656
657 struct props
658 {
659 /* The name of the property. */
660 Lisp_Object *name;
661
662 /* A unique index for the property. */
663 enum prop_idx idx;
664
665 /* A handler function called to set up iterator IT from the property
666 at IT's current position. Value is used to steer handle_stop. */
667 enum prop_handled (*handler) (struct it *it);
668 };
669
670 static enum prop_handled handle_face_prop (struct it *);
671 static enum prop_handled handle_invisible_prop (struct it *);
672 static enum prop_handled handle_display_prop (struct it *);
673 static enum prop_handled handle_composition_prop (struct it *);
674 static enum prop_handled handle_overlay_change (struct it *);
675 static enum prop_handled handle_fontified_prop (struct it *);
676
677 /* Properties handled by iterators. */
678
679 static struct props it_props[] =
680 {
681 {&Qfontified, FONTIFIED_PROP_IDX, handle_fontified_prop},
682 /* Handle `face' before `display' because some sub-properties of
683 `display' need to know the face. */
684 {&Qface, FACE_PROP_IDX, handle_face_prop},
685 {&Qdisplay, DISPLAY_PROP_IDX, handle_display_prop},
686 {&Qinvisible, INVISIBLE_PROP_IDX, handle_invisible_prop},
687 {&Qcomposition, COMPOSITION_PROP_IDX, handle_composition_prop},
688 {NULL, 0, NULL}
689 };
690
691 /* Value is the position described by X. If X is a marker, value is
692 the marker_position of X. Otherwise, value is X. */
693
694 #define COERCE_MARKER(X) (MARKERP ((X)) ? Fmarker_position (X) : (X))
695
696 /* Enumeration returned by some move_it_.* functions internally. */
697
698 enum move_it_result
699 {
700 /* Not used. Undefined value. */
701 MOVE_UNDEFINED,
702
703 /* Move ended at the requested buffer position or ZV. */
704 MOVE_POS_MATCH_OR_ZV,
705
706 /* Move ended at the requested X pixel position. */
707 MOVE_X_REACHED,
708
709 /* Move within a line ended at the end of a line that must be
710 continued. */
711 MOVE_LINE_CONTINUED,
712
713 /* Move within a line ended at the end of a line that would
714 be displayed truncated. */
715 MOVE_LINE_TRUNCATED,
716
717 /* Move within a line ended at a line end. */
718 MOVE_NEWLINE_OR_CR
719 };
720
721 /* This counter is used to clear the face cache every once in a while
722 in redisplay_internal. It is incremented for each redisplay.
723 Every CLEAR_FACE_CACHE_COUNT full redisplays, the face cache is
724 cleared. */
725
726 #define CLEAR_FACE_CACHE_COUNT 500
727 static int clear_face_cache_count;
728
729 /* Similarly for the image cache. */
730
731 #ifdef HAVE_WINDOW_SYSTEM
732 #define CLEAR_IMAGE_CACHE_COUNT 101
733 static int clear_image_cache_count;
734
735 /* Null glyph slice */
736 static struct glyph_slice null_glyph_slice = { 0, 0, 0, 0 };
737 #endif
738
739 /* Non-zero while redisplay_internal is in progress. */
740
741 int redisplaying_p;
742
743 static Lisp_Object Qinhibit_free_realized_faces;
744
745 /* If a string, XTread_socket generates an event to display that string.
746 (The display is done in read_char.) */
747
748 Lisp_Object help_echo_string;
749 Lisp_Object help_echo_window;
750 Lisp_Object help_echo_object;
751 EMACS_INT help_echo_pos;
752
753 /* Temporary variable for XTread_socket. */
754
755 Lisp_Object previous_help_echo_string;
756
757 /* Platform-independent portion of hourglass implementation. */
758
759 /* Non-zero means an hourglass cursor is currently shown. */
760 int hourglass_shown_p;
761
762 /* If non-null, an asynchronous timer that, when it expires, displays
763 an hourglass cursor on all frames. */
764 struct atimer *hourglass_atimer;
765
766 /* Name of the face used to display glyphless characters. */
767 Lisp_Object Qglyphless_char;
768
769 /* Symbol for the purpose of Vglyphless_char_display. */
770 static Lisp_Object Qglyphless_char_display;
771
772 /* Method symbols for Vglyphless_char_display. */
773 static Lisp_Object Qhex_code, Qempty_box, Qthin_space, Qzero_width;
774
775 /* Default pixel width of `thin-space' display method. */
776 #define THIN_SPACE_WIDTH 1
777
778 /* Default number of seconds to wait before displaying an hourglass
779 cursor. */
780 #define DEFAULT_HOURGLASS_DELAY 1
781
782 \f
783 /* Function prototypes. */
784
785 static void setup_for_ellipsis (struct it *, int);
786 static void set_iterator_to_next (struct it *, int);
787 static void mark_window_display_accurate_1 (struct window *, int);
788 static int single_display_spec_string_p (Lisp_Object, Lisp_Object);
789 static int display_prop_string_p (Lisp_Object, Lisp_Object);
790 static int cursor_row_p (struct glyph_row *);
791 static int redisplay_mode_lines (Lisp_Object, int);
792 static char *decode_mode_spec_coding (Lisp_Object, char *, int);
793
794 static Lisp_Object get_it_property (struct it *it, Lisp_Object prop);
795
796 static void handle_line_prefix (struct it *);
797
798 static void pint2str (char *, int, EMACS_INT);
799 static void pint2hrstr (char *, int, EMACS_INT);
800 static struct text_pos run_window_scroll_functions (Lisp_Object,
801 struct text_pos);
802 static void reconsider_clip_changes (struct window *, struct buffer *);
803 static int text_outside_line_unchanged_p (struct window *,
804 EMACS_INT, EMACS_INT);
805 static void store_mode_line_noprop_char (char);
806 static int store_mode_line_noprop (const char *, int, int);
807 static void handle_stop (struct it *);
808 static void handle_stop_backwards (struct it *, EMACS_INT);
809 static void vmessage (const char *, va_list) ATTRIBUTE_FORMAT_PRINTF (1, 0);
810 static void ensure_echo_area_buffers (void);
811 static Lisp_Object unwind_with_echo_area_buffer (Lisp_Object);
812 static Lisp_Object with_echo_area_buffer_unwind_data (struct window *);
813 static int with_echo_area_buffer (struct window *, int,
814 int (*) (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT),
815 EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT);
816 static void clear_garbaged_frames (void);
817 static int current_message_1 (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT);
818 static void pop_message (void);
819 static int truncate_message_1 (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT);
820 static void set_message (const char *, Lisp_Object, EMACS_INT, int);
821 static int set_message_1 (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT);
822 static int display_echo_area (struct window *);
823 static int display_echo_area_1 (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT);
824 static int resize_mini_window_1 (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT);
825 static Lisp_Object unwind_redisplay (Lisp_Object);
826 static int string_char_and_length (const unsigned char *, int *);
827 static struct text_pos display_prop_end (struct it *, Lisp_Object,
828 struct text_pos);
829 static int compute_window_start_on_continuation_line (struct window *);
830 static Lisp_Object safe_eval_handler (Lisp_Object);
831 static void insert_left_trunc_glyphs (struct it *);
832 static struct glyph_row *get_overlay_arrow_glyph_row (struct window *,
833 Lisp_Object);
834 static void extend_face_to_end_of_line (struct it *);
835 static int append_space_for_newline (struct it *, int);
836 static int cursor_row_fully_visible_p (struct window *, int, int);
837 static int try_scrolling (Lisp_Object, int, EMACS_INT, EMACS_INT, int, int);
838 static int try_cursor_movement (Lisp_Object, struct text_pos, int *);
839 static int trailing_whitespace_p (EMACS_INT);
840 static intmax_t message_log_check_duplicate (EMACS_INT, EMACS_INT);
841 static void push_it (struct it *, struct text_pos *);
842 static void pop_it (struct it *);
843 static void sync_frame_with_window_matrix_rows (struct window *);
844 static void select_frame_for_redisplay (Lisp_Object);
845 static void redisplay_internal (void);
846 static int echo_area_display (int);
847 static void redisplay_windows (Lisp_Object);
848 static void redisplay_window (Lisp_Object, int);
849 static Lisp_Object redisplay_window_error (Lisp_Object);
850 static Lisp_Object redisplay_window_0 (Lisp_Object);
851 static Lisp_Object redisplay_window_1 (Lisp_Object);
852 static int set_cursor_from_row (struct window *, struct glyph_row *,
853 struct glyph_matrix *, EMACS_INT, EMACS_INT,
854 int, int);
855 static int update_menu_bar (struct frame *, int, int);
856 static int try_window_reusing_current_matrix (struct window *);
857 static int try_window_id (struct window *);
858 static int display_line (struct it *);
859 static int display_mode_lines (struct window *);
860 static int display_mode_line (struct window *, enum face_id, Lisp_Object);
861 static int display_mode_element (struct it *, int, int, int, Lisp_Object, Lisp_Object, int);
862 static int store_mode_line_string (const char *, Lisp_Object, int, int, int, Lisp_Object);
863 static const char *decode_mode_spec (struct window *, int, int, Lisp_Object *);
864 static void display_menu_bar (struct window *);
865 static EMACS_INT display_count_lines (EMACS_INT, EMACS_INT, EMACS_INT,
866 EMACS_INT *);
867 static int display_string (const char *, Lisp_Object, Lisp_Object,
868 EMACS_INT, EMACS_INT, struct it *, int, int, int, int);
869 static void compute_line_metrics (struct it *);
870 static void run_redisplay_end_trigger_hook (struct it *);
871 static int get_overlay_strings (struct it *, EMACS_INT);
872 static int get_overlay_strings_1 (struct it *, EMACS_INT, int);
873 static void next_overlay_string (struct it *);
874 static void reseat (struct it *, struct text_pos, int);
875 static void reseat_1 (struct it *, struct text_pos, int);
876 static void back_to_previous_visible_line_start (struct it *);
877 void reseat_at_previous_visible_line_start (struct it *);
878 static void reseat_at_next_visible_line_start (struct it *, int);
879 static int next_element_from_ellipsis (struct it *);
880 static int next_element_from_display_vector (struct it *);
881 static int next_element_from_string (struct it *);
882 static int next_element_from_c_string (struct it *);
883 static int next_element_from_buffer (struct it *);
884 static int next_element_from_composition (struct it *);
885 static int next_element_from_image (struct it *);
886 static int next_element_from_stretch (struct it *);
887 static void load_overlay_strings (struct it *, EMACS_INT);
888 static int init_from_display_pos (struct it *, struct window *,
889 struct display_pos *);
890 static void reseat_to_string (struct it *, const char *,
891 Lisp_Object, EMACS_INT, EMACS_INT, int, int);
892 static int get_next_display_element (struct it *);
893 static enum move_it_result
894 move_it_in_display_line_to (struct it *, EMACS_INT, int,
895 enum move_operation_enum);
896 void move_it_vertically_backward (struct it *, int);
897 static void init_to_row_start (struct it *, struct window *,
898 struct glyph_row *);
899 static int init_to_row_end (struct it *, struct window *,
900 struct glyph_row *);
901 static void back_to_previous_line_start (struct it *);
902 static int forward_to_next_line_start (struct it *, int *, struct bidi_it *);
903 static struct text_pos string_pos_nchars_ahead (struct text_pos,
904 Lisp_Object, EMACS_INT);
905 static struct text_pos string_pos (EMACS_INT, Lisp_Object);
906 static struct text_pos c_string_pos (EMACS_INT, const char *, int);
907 static EMACS_INT number_of_chars (const char *, int);
908 static void compute_stop_pos (struct it *);
909 static void compute_string_pos (struct text_pos *, struct text_pos,
910 Lisp_Object);
911 static int face_before_or_after_it_pos (struct it *, int);
912 static EMACS_INT next_overlay_change (EMACS_INT);
913 static int handle_display_spec (struct it *, Lisp_Object, Lisp_Object,
914 Lisp_Object, struct text_pos *, EMACS_INT, int);
915 static int handle_single_display_spec (struct it *, Lisp_Object,
916 Lisp_Object, Lisp_Object,
917 struct text_pos *, EMACS_INT, int, int);
918 static int underlying_face_id (struct it *);
919 static int in_ellipses_for_invisible_text_p (struct display_pos *,
920 struct window *);
921
922 #define face_before_it_pos(IT) face_before_or_after_it_pos ((IT), 1)
923 #define face_after_it_pos(IT) face_before_or_after_it_pos ((IT), 0)
924
925 #ifdef HAVE_WINDOW_SYSTEM
926
927 static void x_consider_frame_title (Lisp_Object);
928 static int tool_bar_lines_needed (struct frame *, int *);
929 static void update_tool_bar (struct frame *, int);
930 static void build_desired_tool_bar_string (struct frame *f);
931 static int redisplay_tool_bar (struct frame *);
932 static void display_tool_bar_line (struct it *, int);
933 static void notice_overwritten_cursor (struct window *,
934 enum glyph_row_area,
935 int, int, int, int);
936 static void append_stretch_glyph (struct it *, Lisp_Object,
937 int, int, int);
938
939
940 #endif /* HAVE_WINDOW_SYSTEM */
941
942 static void show_mouse_face (Mouse_HLInfo *, enum draw_glyphs_face);
943 static int coords_in_mouse_face_p (struct window *, int, int);
944
945
946 \f
947 /***********************************************************************
948 Window display dimensions
949 ***********************************************************************/
950
951 /* Return the bottom boundary y-position for text lines in window W.
952 This is the first y position at which a line cannot start.
953 It is relative to the top of the window.
954
955 This is the height of W minus the height of a mode line, if any. */
956
957 inline int
958 window_text_bottom_y (struct window *w)
959 {
960 int height = WINDOW_TOTAL_HEIGHT (w);
961
962 if (WINDOW_WANTS_MODELINE_P (w))
963 height -= CURRENT_MODE_LINE_HEIGHT (w);
964 return height;
965 }
966
967 /* Return the pixel width of display area AREA of window W. AREA < 0
968 means return the total width of W, not including fringes to
969 the left and right of the window. */
970
971 inline int
972 window_box_width (struct window *w, int area)
973 {
974 int cols = XFASTINT (w->total_cols);
975 int pixels = 0;
976
977 if (!w->pseudo_window_p)
978 {
979 cols -= WINDOW_SCROLL_BAR_COLS (w);
980
981 if (area == TEXT_AREA)
982 {
983 if (INTEGERP (w->left_margin_cols))
984 cols -= XFASTINT (w->left_margin_cols);
985 if (INTEGERP (w->right_margin_cols))
986 cols -= XFASTINT (w->right_margin_cols);
987 pixels = -WINDOW_TOTAL_FRINGE_WIDTH (w);
988 }
989 else if (area == LEFT_MARGIN_AREA)
990 {
991 cols = (INTEGERP (w->left_margin_cols)
992 ? XFASTINT (w->left_margin_cols) : 0);
993 pixels = 0;
994 }
995 else if (area == RIGHT_MARGIN_AREA)
996 {
997 cols = (INTEGERP (w->right_margin_cols)
998 ? XFASTINT (w->right_margin_cols) : 0);
999 pixels = 0;
1000 }
1001 }
1002
1003 return cols * WINDOW_FRAME_COLUMN_WIDTH (w) + pixels;
1004 }
1005
1006
1007 /* Return the pixel height of the display area of window W, not
1008 including mode lines of W, if any. */
1009
1010 inline int
1011 window_box_height (struct window *w)
1012 {
1013 struct frame *f = XFRAME (w->frame);
1014 int height = WINDOW_TOTAL_HEIGHT (w);
1015
1016 xassert (height >= 0);
1017
1018 /* Note: the code below that determines the mode-line/header-line
1019 height is essentially the same as that contained in the macro
1020 CURRENT_{MODE,HEADER}_LINE_HEIGHT, except that it checks whether
1021 the appropriate glyph row has its `mode_line_p' flag set,
1022 and if it doesn't, uses estimate_mode_line_height instead. */
1023
1024 if (WINDOW_WANTS_MODELINE_P (w))
1025 {
1026 struct glyph_row *ml_row
1027 = (w->current_matrix && w->current_matrix->rows
1028 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
1029 : 0);
1030 if (ml_row && ml_row->mode_line_p)
1031 height -= ml_row->height;
1032 else
1033 height -= estimate_mode_line_height (f, CURRENT_MODE_LINE_FACE_ID (w));
1034 }
1035
1036 if (WINDOW_WANTS_HEADER_LINE_P (w))
1037 {
1038 struct glyph_row *hl_row
1039 = (w->current_matrix && w->current_matrix->rows
1040 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
1041 : 0);
1042 if (hl_row && hl_row->mode_line_p)
1043 height -= hl_row->height;
1044 else
1045 height -= estimate_mode_line_height (f, HEADER_LINE_FACE_ID);
1046 }
1047
1048 /* With a very small font and a mode-line that's taller than
1049 default, we might end up with a negative height. */
1050 return max (0, height);
1051 }
1052
1053 /* Return the window-relative coordinate of the left edge of display
1054 area AREA of window W. AREA < 0 means return the left edge of the
1055 whole window, to the right of the left fringe of W. */
1056
1057 inline int
1058 window_box_left_offset (struct window *w, int area)
1059 {
1060 int x;
1061
1062 if (w->pseudo_window_p)
1063 return 0;
1064
1065 x = WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
1066
1067 if (area == TEXT_AREA)
1068 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1069 + window_box_width (w, LEFT_MARGIN_AREA));
1070 else if (area == RIGHT_MARGIN_AREA)
1071 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1072 + window_box_width (w, LEFT_MARGIN_AREA)
1073 + window_box_width (w, TEXT_AREA)
1074 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
1075 ? 0
1076 : WINDOW_RIGHT_FRINGE_WIDTH (w)));
1077 else if (area == LEFT_MARGIN_AREA
1078 && WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w))
1079 x += WINDOW_LEFT_FRINGE_WIDTH (w);
1080
1081 return x;
1082 }
1083
1084
1085 /* Return the window-relative coordinate of the right edge of display
1086 area AREA of window W. AREA < 0 means return the right edge of the
1087 whole window, to the left of the right fringe of W. */
1088
1089 inline int
1090 window_box_right_offset (struct window *w, int area)
1091 {
1092 return window_box_left_offset (w, area) + window_box_width (w, area);
1093 }
1094
1095 /* Return the frame-relative coordinate of the left edge of display
1096 area AREA of window W. AREA < 0 means return the left edge of the
1097 whole window, to the right of the left fringe of W. */
1098
1099 inline int
1100 window_box_left (struct window *w, int area)
1101 {
1102 struct frame *f = XFRAME (w->frame);
1103 int x;
1104
1105 if (w->pseudo_window_p)
1106 return FRAME_INTERNAL_BORDER_WIDTH (f);
1107
1108 x = (WINDOW_LEFT_EDGE_X (w)
1109 + window_box_left_offset (w, area));
1110
1111 return x;
1112 }
1113
1114
1115 /* Return the frame-relative coordinate of the right edge of display
1116 area AREA of window W. AREA < 0 means return the right edge of the
1117 whole window, to the left of the right fringe of W. */
1118
1119 inline int
1120 window_box_right (struct window *w, int area)
1121 {
1122 return window_box_left (w, area) + window_box_width (w, area);
1123 }
1124
1125 /* Get the bounding box of the display area AREA of window W, without
1126 mode lines, in frame-relative coordinates. AREA < 0 means the
1127 whole window, not including the left and right fringes of
1128 the window. Return in *BOX_X and *BOX_Y the frame-relative pixel
1129 coordinates of the upper-left corner of the box. Return in
1130 *BOX_WIDTH, and *BOX_HEIGHT the pixel width and height of the box. */
1131
1132 inline void
1133 window_box (struct window *w, int area, int *box_x, int *box_y,
1134 int *box_width, int *box_height)
1135 {
1136 if (box_width)
1137 *box_width = window_box_width (w, area);
1138 if (box_height)
1139 *box_height = window_box_height (w);
1140 if (box_x)
1141 *box_x = window_box_left (w, area);
1142 if (box_y)
1143 {
1144 *box_y = WINDOW_TOP_EDGE_Y (w);
1145 if (WINDOW_WANTS_HEADER_LINE_P (w))
1146 *box_y += CURRENT_HEADER_LINE_HEIGHT (w);
1147 }
1148 }
1149
1150
1151 /* Get the bounding box of the display area AREA of window W, without
1152 mode lines. AREA < 0 means the whole window, not including the
1153 left and right fringe of the window. Return in *TOP_LEFT_X
1154 and TOP_LEFT_Y the frame-relative pixel coordinates of the
1155 upper-left corner of the box. Return in *BOTTOM_RIGHT_X, and
1156 *BOTTOM_RIGHT_Y the coordinates of the bottom-right corner of the
1157 box. */
1158
1159 static inline void
1160 window_box_edges (struct window *w, int area, int *top_left_x, int *top_left_y,
1161 int *bottom_right_x, int *bottom_right_y)
1162 {
1163 window_box (w, area, top_left_x, top_left_y, bottom_right_x,
1164 bottom_right_y);
1165 *bottom_right_x += *top_left_x;
1166 *bottom_right_y += *top_left_y;
1167 }
1168
1169
1170 \f
1171 /***********************************************************************
1172 Utilities
1173 ***********************************************************************/
1174
1175 /* Return the bottom y-position of the line the iterator IT is in.
1176 This can modify IT's settings. */
1177
1178 int
1179 line_bottom_y (struct it *it)
1180 {
1181 int line_height = it->max_ascent + it->max_descent;
1182 int line_top_y = it->current_y;
1183
1184 if (line_height == 0)
1185 {
1186 if (last_height)
1187 line_height = last_height;
1188 else if (IT_CHARPOS (*it) < ZV)
1189 {
1190 move_it_by_lines (it, 1);
1191 line_height = (it->max_ascent || it->max_descent
1192 ? it->max_ascent + it->max_descent
1193 : last_height);
1194 }
1195 else
1196 {
1197 struct glyph_row *row = it->glyph_row;
1198
1199 /* Use the default character height. */
1200 it->glyph_row = NULL;
1201 it->what = IT_CHARACTER;
1202 it->c = ' ';
1203 it->len = 1;
1204 PRODUCE_GLYPHS (it);
1205 line_height = it->ascent + it->descent;
1206 it->glyph_row = row;
1207 }
1208 }
1209
1210 return line_top_y + line_height;
1211 }
1212
1213 /* Subroutine of pos_visible_p below. Extracts a display string, if
1214 any, from the display spec given as its argument. */
1215 static Lisp_Object
1216 string_from_display_spec (Lisp_Object spec)
1217 {
1218 if (CONSP (spec))
1219 {
1220 while (CONSP (spec))
1221 {
1222 if (STRINGP (XCAR (spec)))
1223 return XCAR (spec);
1224 spec = XCDR (spec);
1225 }
1226 }
1227 else if (VECTORP (spec))
1228 {
1229 ptrdiff_t i;
1230
1231 for (i = 0; i < ASIZE (spec); i++)
1232 {
1233 if (STRINGP (AREF (spec, i)))
1234 return AREF (spec, i);
1235 }
1236 return Qnil;
1237 }
1238
1239 return spec;
1240 }
1241
1242 /* Return 1 if position CHARPOS is visible in window W.
1243 CHARPOS < 0 means return info about WINDOW_END position.
1244 If visible, set *X and *Y to pixel coordinates of top left corner.
1245 Set *RTOP and *RBOT to pixel height of an invisible area of glyph at POS.
1246 Set *ROWH and *VPOS to row's visible height and VPOS (row number). */
1247
1248 int
1249 pos_visible_p (struct window *w, EMACS_INT charpos, int *x, int *y,
1250 int *rtop, int *rbot, int *rowh, int *vpos)
1251 {
1252 struct it it;
1253 void *itdata = bidi_shelve_cache ();
1254 struct text_pos top;
1255 int visible_p = 0;
1256 struct buffer *old_buffer = NULL;
1257
1258 if (FRAME_INITIAL_P (XFRAME (WINDOW_FRAME (w))))
1259 return visible_p;
1260
1261 if (XBUFFER (w->buffer) != current_buffer)
1262 {
1263 old_buffer = current_buffer;
1264 set_buffer_internal_1 (XBUFFER (w->buffer));
1265 }
1266
1267 SET_TEXT_POS_FROM_MARKER (top, w->start);
1268
1269 /* Compute exact mode line heights. */
1270 if (WINDOW_WANTS_MODELINE_P (w))
1271 current_mode_line_height
1272 = display_mode_line (w, CURRENT_MODE_LINE_FACE_ID (w),
1273 BVAR (current_buffer, mode_line_format));
1274
1275 if (WINDOW_WANTS_HEADER_LINE_P (w))
1276 current_header_line_height
1277 = display_mode_line (w, HEADER_LINE_FACE_ID,
1278 BVAR (current_buffer, header_line_format));
1279
1280 start_display (&it, w, top);
1281 move_it_to (&it, charpos, -1, it.last_visible_y-1, -1,
1282 (charpos >= 0 ? MOVE_TO_POS : 0) | MOVE_TO_Y);
1283
1284 if (charpos >= 0
1285 && (((!it.bidi_p || it.bidi_it.scan_dir == 1)
1286 && IT_CHARPOS (it) >= charpos)
1287 /* When scanning backwards under bidi iteration, move_it_to
1288 stops at or _before_ CHARPOS, because it stops at or to
1289 the _right_ of the character at CHARPOS. */
1290 || (it.bidi_p && it.bidi_it.scan_dir == -1
1291 && IT_CHARPOS (it) <= charpos)))
1292 {
1293 /* We have reached CHARPOS, or passed it. How the call to
1294 move_it_to can overshoot: (i) If CHARPOS is on invisible text
1295 or covered by a display property, move_it_to stops at the end
1296 of the invisible text, to the right of CHARPOS. (ii) If
1297 CHARPOS is in a display vector, move_it_to stops on its last
1298 glyph. */
1299 int top_x = it.current_x;
1300 int top_y = it.current_y;
1301 enum it_method it_method = it.method;
1302 /* Calling line_bottom_y may change it.method, it.position, etc. */
1303 int bottom_y = (last_height = 0, line_bottom_y (&it));
1304 int window_top_y = WINDOW_HEADER_LINE_HEIGHT (w);
1305
1306 if (top_y < window_top_y)
1307 visible_p = bottom_y > window_top_y;
1308 else if (top_y < it.last_visible_y)
1309 visible_p = 1;
1310 if (visible_p)
1311 {
1312 if (it_method == GET_FROM_DISPLAY_VECTOR)
1313 {
1314 /* We stopped on the last glyph of a display vector.
1315 Try and recompute. Hack alert! */
1316 if (charpos < 2 || top.charpos >= charpos)
1317 top_x = it.glyph_row->x;
1318 else
1319 {
1320 struct it it2;
1321 start_display (&it2, w, top);
1322 move_it_to (&it2, charpos - 1, -1, -1, -1, MOVE_TO_POS);
1323 get_next_display_element (&it2);
1324 PRODUCE_GLYPHS (&it2);
1325 if (ITERATOR_AT_END_OF_LINE_P (&it2)
1326 || it2.current_x > it2.last_visible_x)
1327 top_x = it.glyph_row->x;
1328 else
1329 {
1330 top_x = it2.current_x;
1331 top_y = it2.current_y;
1332 }
1333 }
1334 }
1335 else if (IT_CHARPOS (it) != charpos)
1336 {
1337 Lisp_Object cpos = make_number (charpos);
1338 Lisp_Object spec = Fget_char_property (cpos, Qdisplay, Qnil);
1339 Lisp_Object string = string_from_display_spec (spec);
1340 int newline_in_string = 0;
1341
1342 if (STRINGP (string))
1343 {
1344 const char *s = SSDATA (string);
1345 const char *e = s + SBYTES (string);
1346 while (s < e)
1347 {
1348 if (*s++ == '\n')
1349 {
1350 newline_in_string = 1;
1351 break;
1352 }
1353 }
1354 }
1355 /* The tricky code below is needed because there's a
1356 discrepancy between move_it_to and how we set cursor
1357 when the display line ends in a newline from a
1358 display string. move_it_to will stop _after_ such
1359 display strings, whereas set_cursor_from_row
1360 conspires with cursor_row_p to place the cursor on
1361 the first glyph produced from the display string. */
1362
1363 /* We have overshoot PT because it is covered by a
1364 display property whose value is a string. If the
1365 string includes embedded newlines, we are also in the
1366 wrong display line. Backtrack to the correct line,
1367 where the display string begins. */
1368 if (newline_in_string)
1369 {
1370 Lisp_Object startpos, endpos;
1371 EMACS_INT start, end;
1372 struct it it3;
1373
1374 /* Find the first and the last buffer positions
1375 covered by the display string. */
1376 endpos =
1377 Fnext_single_char_property_change (cpos, Qdisplay,
1378 Qnil, Qnil);
1379 startpos =
1380 Fprevious_single_char_property_change (endpos, Qdisplay,
1381 Qnil, Qnil);
1382 start = XFASTINT (startpos);
1383 end = XFASTINT (endpos);
1384 /* Move to the last buffer position before the
1385 display property. */
1386 start_display (&it3, w, top);
1387 move_it_to (&it3, start - 1, -1, -1, -1, MOVE_TO_POS);
1388 /* Move forward one more line if the position before
1389 the display string is a newline or if it is the
1390 rightmost character on a line that is
1391 continued or word-wrapped. */
1392 if (it3.method == GET_FROM_BUFFER
1393 && it3.c == '\n')
1394 move_it_by_lines (&it3, 1);
1395 else if (move_it_in_display_line_to (&it3, -1,
1396 it3.current_x
1397 + it3.pixel_width,
1398 MOVE_TO_X)
1399 == MOVE_LINE_CONTINUED)
1400 {
1401 move_it_by_lines (&it3, 1);
1402 /* When we are under word-wrap, the #$@%!
1403 move_it_by_lines moves 2 lines, so we need to
1404 fix that up. */
1405 if (it3.line_wrap == WORD_WRAP)
1406 move_it_by_lines (&it3, -1);
1407 }
1408
1409 /* Record the vertical coordinate of the display
1410 line where we wound up. */
1411 top_y = it3.current_y;
1412 if (it3.bidi_p)
1413 {
1414 /* When characters are reordered for display,
1415 the character displayed to the left of the
1416 display string could be _after_ the display
1417 property in the logical order. Use the
1418 smallest vertical position of these two. */
1419 start_display (&it3, w, top);
1420 move_it_to (&it3, end + 1, -1, -1, -1, MOVE_TO_POS);
1421 if (it3.current_y < top_y)
1422 top_y = it3.current_y;
1423 }
1424 /* Move from the top of the window to the beginning
1425 of the display line where the display string
1426 begins. */
1427 start_display (&it3, w, top);
1428 move_it_to (&it3, -1, 0, top_y, -1, MOVE_TO_X | MOVE_TO_Y);
1429 /* Finally, advance the iterator until we hit the
1430 first display element whose character position is
1431 CHARPOS, or until the first newline from the
1432 display string, which signals the end of the
1433 display line. */
1434 while (get_next_display_element (&it3))
1435 {
1436 PRODUCE_GLYPHS (&it3);
1437 if (IT_CHARPOS (it3) == charpos
1438 || ITERATOR_AT_END_OF_LINE_P (&it3))
1439 break;
1440 set_iterator_to_next (&it3, 0);
1441 }
1442 top_x = it3.current_x - it3.pixel_width;
1443 /* Normally, we would exit the above loop because we
1444 found the display element whose character
1445 position is CHARPOS. For the contingency that we
1446 didn't, and stopped at the first newline from the
1447 display string, move back over the glyphs
1448 prfoduced from the string, until we find the
1449 rightmost glyph not from the string. */
1450 if (IT_CHARPOS (it3) != charpos && EQ (it3.object, string))
1451 {
1452 struct glyph *g = it3.glyph_row->glyphs[TEXT_AREA]
1453 + it3.glyph_row->used[TEXT_AREA];
1454
1455 while (EQ ((g - 1)->object, string))
1456 {
1457 --g;
1458 top_x -= g->pixel_width;
1459 }
1460 xassert (g < it3.glyph_row->glyphs[TEXT_AREA]
1461 + it3.glyph_row->used[TEXT_AREA]);
1462 }
1463 }
1464 }
1465
1466 *x = top_x;
1467 *y = max (top_y + max (0, it.max_ascent - it.ascent), window_top_y);
1468 *rtop = max (0, window_top_y - top_y);
1469 *rbot = max (0, bottom_y - it.last_visible_y);
1470 *rowh = max (0, (min (bottom_y, it.last_visible_y)
1471 - max (top_y, window_top_y)));
1472 *vpos = it.vpos;
1473 }
1474 }
1475 else
1476 {
1477 /* We were asked to provide info about WINDOW_END. */
1478 struct it it2;
1479 void *it2data = NULL;
1480
1481 SAVE_IT (it2, it, it2data);
1482 if (IT_CHARPOS (it) < ZV && FETCH_BYTE (IT_BYTEPOS (it)) != '\n')
1483 move_it_by_lines (&it, 1);
1484 if (charpos < IT_CHARPOS (it)
1485 || (it.what == IT_EOB && charpos == IT_CHARPOS (it)))
1486 {
1487 visible_p = 1;
1488 RESTORE_IT (&it2, &it2, it2data);
1489 move_it_to (&it2, charpos, -1, -1, -1, MOVE_TO_POS);
1490 *x = it2.current_x;
1491 *y = it2.current_y + it2.max_ascent - it2.ascent;
1492 *rtop = max (0, -it2.current_y);
1493 *rbot = max (0, ((it2.current_y + it2.max_ascent + it2.max_descent)
1494 - it.last_visible_y));
1495 *rowh = max (0, (min (it2.current_y + it2.max_ascent + it2.max_descent,
1496 it.last_visible_y)
1497 - max (it2.current_y,
1498 WINDOW_HEADER_LINE_HEIGHT (w))));
1499 *vpos = it2.vpos;
1500 }
1501 else
1502 bidi_unshelve_cache (it2data, 1);
1503 }
1504 bidi_unshelve_cache (itdata, 0);
1505
1506 if (old_buffer)
1507 set_buffer_internal_1 (old_buffer);
1508
1509 current_header_line_height = current_mode_line_height = -1;
1510
1511 if (visible_p && XFASTINT (w->hscroll) > 0)
1512 *x -= XFASTINT (w->hscroll) * WINDOW_FRAME_COLUMN_WIDTH (w);
1513
1514 #if 0
1515 /* Debugging code. */
1516 if (visible_p)
1517 fprintf (stderr, "+pv pt=%d vs=%d --> x=%d y=%d rt=%d rb=%d rh=%d vp=%d\n",
1518 charpos, w->vscroll, *x, *y, *rtop, *rbot, *rowh, *vpos);
1519 else
1520 fprintf (stderr, "-pv pt=%d vs=%d\n", charpos, w->vscroll);
1521 #endif
1522
1523 return visible_p;
1524 }
1525
1526
1527 /* Return the next character from STR. Return in *LEN the length of
1528 the character. This is like STRING_CHAR_AND_LENGTH but never
1529 returns an invalid character. If we find one, we return a `?', but
1530 with the length of the invalid character. */
1531
1532 static inline int
1533 string_char_and_length (const unsigned char *str, int *len)
1534 {
1535 int c;
1536
1537 c = STRING_CHAR_AND_LENGTH (str, *len);
1538 if (!CHAR_VALID_P (c))
1539 /* We may not change the length here because other places in Emacs
1540 don't use this function, i.e. they silently accept invalid
1541 characters. */
1542 c = '?';
1543
1544 return c;
1545 }
1546
1547
1548
1549 /* Given a position POS containing a valid character and byte position
1550 in STRING, return the position NCHARS ahead (NCHARS >= 0). */
1551
1552 static struct text_pos
1553 string_pos_nchars_ahead (struct text_pos pos, Lisp_Object string, EMACS_INT nchars)
1554 {
1555 xassert (STRINGP (string) && nchars >= 0);
1556
1557 if (STRING_MULTIBYTE (string))
1558 {
1559 const unsigned char *p = SDATA (string) + BYTEPOS (pos);
1560 int len;
1561
1562 while (nchars--)
1563 {
1564 string_char_and_length (p, &len);
1565 p += len;
1566 CHARPOS (pos) += 1;
1567 BYTEPOS (pos) += len;
1568 }
1569 }
1570 else
1571 SET_TEXT_POS (pos, CHARPOS (pos) + nchars, BYTEPOS (pos) + nchars);
1572
1573 return pos;
1574 }
1575
1576
1577 /* Value is the text position, i.e. character and byte position,
1578 for character position CHARPOS in STRING. */
1579
1580 static inline struct text_pos
1581 string_pos (EMACS_INT charpos, Lisp_Object string)
1582 {
1583 struct text_pos pos;
1584 xassert (STRINGP (string));
1585 xassert (charpos >= 0);
1586 SET_TEXT_POS (pos, charpos, string_char_to_byte (string, charpos));
1587 return pos;
1588 }
1589
1590
1591 /* Value is a text position, i.e. character and byte position, for
1592 character position CHARPOS in C string S. MULTIBYTE_P non-zero
1593 means recognize multibyte characters. */
1594
1595 static struct text_pos
1596 c_string_pos (EMACS_INT charpos, const char *s, int multibyte_p)
1597 {
1598 struct text_pos pos;
1599
1600 xassert (s != NULL);
1601 xassert (charpos >= 0);
1602
1603 if (multibyte_p)
1604 {
1605 int len;
1606
1607 SET_TEXT_POS (pos, 0, 0);
1608 while (charpos--)
1609 {
1610 string_char_and_length ((const unsigned char *) s, &len);
1611 s += len;
1612 CHARPOS (pos) += 1;
1613 BYTEPOS (pos) += len;
1614 }
1615 }
1616 else
1617 SET_TEXT_POS (pos, charpos, charpos);
1618
1619 return pos;
1620 }
1621
1622
1623 /* Value is the number of characters in C string S. MULTIBYTE_P
1624 non-zero means recognize multibyte characters. */
1625
1626 static EMACS_INT
1627 number_of_chars (const char *s, int multibyte_p)
1628 {
1629 EMACS_INT nchars;
1630
1631 if (multibyte_p)
1632 {
1633 EMACS_INT rest = strlen (s);
1634 int len;
1635 const unsigned char *p = (const unsigned char *) s;
1636
1637 for (nchars = 0; rest > 0; ++nchars)
1638 {
1639 string_char_and_length (p, &len);
1640 rest -= len, p += len;
1641 }
1642 }
1643 else
1644 nchars = strlen (s);
1645
1646 return nchars;
1647 }
1648
1649
1650 /* Compute byte position NEWPOS->bytepos corresponding to
1651 NEWPOS->charpos. POS is a known position in string STRING.
1652 NEWPOS->charpos must be >= POS.charpos. */
1653
1654 static void
1655 compute_string_pos (struct text_pos *newpos, struct text_pos pos, Lisp_Object string)
1656 {
1657 xassert (STRINGP (string));
1658 xassert (CHARPOS (*newpos) >= CHARPOS (pos));
1659
1660 if (STRING_MULTIBYTE (string))
1661 *newpos = string_pos_nchars_ahead (pos, string,
1662 CHARPOS (*newpos) - CHARPOS (pos));
1663 else
1664 BYTEPOS (*newpos) = CHARPOS (*newpos);
1665 }
1666
1667 /* EXPORT:
1668 Return an estimation of the pixel height of mode or header lines on
1669 frame F. FACE_ID specifies what line's height to estimate. */
1670
1671 int
1672 estimate_mode_line_height (struct frame *f, enum face_id face_id)
1673 {
1674 #ifdef HAVE_WINDOW_SYSTEM
1675 if (FRAME_WINDOW_P (f))
1676 {
1677 int height = FONT_HEIGHT (FRAME_FONT (f));
1678
1679 /* This function is called so early when Emacs starts that the face
1680 cache and mode line face are not yet initialized. */
1681 if (FRAME_FACE_CACHE (f))
1682 {
1683 struct face *face = FACE_FROM_ID (f, face_id);
1684 if (face)
1685 {
1686 if (face->font)
1687 height = FONT_HEIGHT (face->font);
1688 if (face->box_line_width > 0)
1689 height += 2 * face->box_line_width;
1690 }
1691 }
1692
1693 return height;
1694 }
1695 #endif
1696
1697 return 1;
1698 }
1699
1700 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
1701 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
1702 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
1703 not force the value into range. */
1704
1705 void
1706 pixel_to_glyph_coords (FRAME_PTR f, register int pix_x, register int pix_y,
1707 int *x, int *y, NativeRectangle *bounds, int noclip)
1708 {
1709
1710 #ifdef HAVE_WINDOW_SYSTEM
1711 if (FRAME_WINDOW_P (f))
1712 {
1713 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to round down
1714 even for negative values. */
1715 if (pix_x < 0)
1716 pix_x -= FRAME_COLUMN_WIDTH (f) - 1;
1717 if (pix_y < 0)
1718 pix_y -= FRAME_LINE_HEIGHT (f) - 1;
1719
1720 pix_x = FRAME_PIXEL_X_TO_COL (f, pix_x);
1721 pix_y = FRAME_PIXEL_Y_TO_LINE (f, pix_y);
1722
1723 if (bounds)
1724 STORE_NATIVE_RECT (*bounds,
1725 FRAME_COL_TO_PIXEL_X (f, pix_x),
1726 FRAME_LINE_TO_PIXEL_Y (f, pix_y),
1727 FRAME_COLUMN_WIDTH (f) - 1,
1728 FRAME_LINE_HEIGHT (f) - 1);
1729
1730 if (!noclip)
1731 {
1732 if (pix_x < 0)
1733 pix_x = 0;
1734 else if (pix_x > FRAME_TOTAL_COLS (f))
1735 pix_x = FRAME_TOTAL_COLS (f);
1736
1737 if (pix_y < 0)
1738 pix_y = 0;
1739 else if (pix_y > FRAME_LINES (f))
1740 pix_y = FRAME_LINES (f);
1741 }
1742 }
1743 #endif
1744
1745 *x = pix_x;
1746 *y = pix_y;
1747 }
1748
1749
1750 /* Find the glyph under window-relative coordinates X/Y in window W.
1751 Consider only glyphs from buffer text, i.e. no glyphs from overlay
1752 strings. Return in *HPOS and *VPOS the row and column number of
1753 the glyph found. Return in *AREA the glyph area containing X.
1754 Value is a pointer to the glyph found or null if X/Y is not on
1755 text, or we can't tell because W's current matrix is not up to
1756 date. */
1757
1758 static
1759 struct glyph *
1760 x_y_to_hpos_vpos (struct window *w, int x, int y, int *hpos, int *vpos,
1761 int *dx, int *dy, int *area)
1762 {
1763 struct glyph *glyph, *end;
1764 struct glyph_row *row = NULL;
1765 int x0, i;
1766
1767 /* Find row containing Y. Give up if some row is not enabled. */
1768 for (i = 0; i < w->current_matrix->nrows; ++i)
1769 {
1770 row = MATRIX_ROW (w->current_matrix, i);
1771 if (!row->enabled_p)
1772 return NULL;
1773 if (y >= row->y && y < MATRIX_ROW_BOTTOM_Y (row))
1774 break;
1775 }
1776
1777 *vpos = i;
1778 *hpos = 0;
1779
1780 /* Give up if Y is not in the window. */
1781 if (i == w->current_matrix->nrows)
1782 return NULL;
1783
1784 /* Get the glyph area containing X. */
1785 if (w->pseudo_window_p)
1786 {
1787 *area = TEXT_AREA;
1788 x0 = 0;
1789 }
1790 else
1791 {
1792 if (x < window_box_left_offset (w, TEXT_AREA))
1793 {
1794 *area = LEFT_MARGIN_AREA;
1795 x0 = window_box_left_offset (w, LEFT_MARGIN_AREA);
1796 }
1797 else if (x < window_box_right_offset (w, TEXT_AREA))
1798 {
1799 *area = TEXT_AREA;
1800 x0 = window_box_left_offset (w, TEXT_AREA) + min (row->x, 0);
1801 }
1802 else
1803 {
1804 *area = RIGHT_MARGIN_AREA;
1805 x0 = window_box_left_offset (w, RIGHT_MARGIN_AREA);
1806 }
1807 }
1808
1809 /* Find glyph containing X. */
1810 glyph = row->glyphs[*area];
1811 end = glyph + row->used[*area];
1812 x -= x0;
1813 while (glyph < end && x >= glyph->pixel_width)
1814 {
1815 x -= glyph->pixel_width;
1816 ++glyph;
1817 }
1818
1819 if (glyph == end)
1820 return NULL;
1821
1822 if (dx)
1823 {
1824 *dx = x;
1825 *dy = y - (row->y + row->ascent - glyph->ascent);
1826 }
1827
1828 *hpos = glyph - row->glyphs[*area];
1829 return glyph;
1830 }
1831
1832 /* Convert frame-relative x/y to coordinates relative to window W.
1833 Takes pseudo-windows into account. */
1834
1835 static void
1836 frame_to_window_pixel_xy (struct window *w, int *x, int *y)
1837 {
1838 if (w->pseudo_window_p)
1839 {
1840 /* A pseudo-window is always full-width, and starts at the
1841 left edge of the frame, plus a frame border. */
1842 struct frame *f = XFRAME (w->frame);
1843 *x -= FRAME_INTERNAL_BORDER_WIDTH (f);
1844 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1845 }
1846 else
1847 {
1848 *x -= WINDOW_LEFT_EDGE_X (w);
1849 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1850 }
1851 }
1852
1853 #ifdef HAVE_WINDOW_SYSTEM
1854
1855 /* EXPORT:
1856 Return in RECTS[] at most N clipping rectangles for glyph string S.
1857 Return the number of stored rectangles. */
1858
1859 int
1860 get_glyph_string_clip_rects (struct glyph_string *s, NativeRectangle *rects, int n)
1861 {
1862 XRectangle r;
1863
1864 if (n <= 0)
1865 return 0;
1866
1867 if (s->row->full_width_p)
1868 {
1869 /* Draw full-width. X coordinates are relative to S->w->left_col. */
1870 r.x = WINDOW_LEFT_EDGE_X (s->w);
1871 r.width = WINDOW_TOTAL_WIDTH (s->w);
1872
1873 /* Unless displaying a mode or menu bar line, which are always
1874 fully visible, clip to the visible part of the row. */
1875 if (s->w->pseudo_window_p)
1876 r.height = s->row->visible_height;
1877 else
1878 r.height = s->height;
1879 }
1880 else
1881 {
1882 /* This is a text line that may be partially visible. */
1883 r.x = window_box_left (s->w, s->area);
1884 r.width = window_box_width (s->w, s->area);
1885 r.height = s->row->visible_height;
1886 }
1887
1888 if (s->clip_head)
1889 if (r.x < s->clip_head->x)
1890 {
1891 if (r.width >= s->clip_head->x - r.x)
1892 r.width -= s->clip_head->x - r.x;
1893 else
1894 r.width = 0;
1895 r.x = s->clip_head->x;
1896 }
1897 if (s->clip_tail)
1898 if (r.x + r.width > s->clip_tail->x + s->clip_tail->background_width)
1899 {
1900 if (s->clip_tail->x + s->clip_tail->background_width >= r.x)
1901 r.width = s->clip_tail->x + s->clip_tail->background_width - r.x;
1902 else
1903 r.width = 0;
1904 }
1905
1906 /* If S draws overlapping rows, it's sufficient to use the top and
1907 bottom of the window for clipping because this glyph string
1908 intentionally draws over other lines. */
1909 if (s->for_overlaps)
1910 {
1911 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
1912 r.height = window_text_bottom_y (s->w) - r.y;
1913
1914 /* Alas, the above simple strategy does not work for the
1915 environments with anti-aliased text: if the same text is
1916 drawn onto the same place multiple times, it gets thicker.
1917 If the overlap we are processing is for the erased cursor, we
1918 take the intersection with the rectagle of the cursor. */
1919 if (s->for_overlaps & OVERLAPS_ERASED_CURSOR)
1920 {
1921 XRectangle rc, r_save = r;
1922
1923 rc.x = WINDOW_TEXT_TO_FRAME_PIXEL_X (s->w, s->w->phys_cursor.x);
1924 rc.y = s->w->phys_cursor.y;
1925 rc.width = s->w->phys_cursor_width;
1926 rc.height = s->w->phys_cursor_height;
1927
1928 x_intersect_rectangles (&r_save, &rc, &r);
1929 }
1930 }
1931 else
1932 {
1933 /* Don't use S->y for clipping because it doesn't take partially
1934 visible lines into account. For example, it can be negative for
1935 partially visible lines at the top of a window. */
1936 if (!s->row->full_width_p
1937 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s->w, s->row))
1938 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
1939 else
1940 r.y = max (0, s->row->y);
1941 }
1942
1943 r.y = WINDOW_TO_FRAME_PIXEL_Y (s->w, r.y);
1944
1945 /* If drawing the cursor, don't let glyph draw outside its
1946 advertised boundaries. Cleartype does this under some circumstances. */
1947 if (s->hl == DRAW_CURSOR)
1948 {
1949 struct glyph *glyph = s->first_glyph;
1950 int height, max_y;
1951
1952 if (s->x > r.x)
1953 {
1954 r.width -= s->x - r.x;
1955 r.x = s->x;
1956 }
1957 r.width = min (r.width, glyph->pixel_width);
1958
1959 /* If r.y is below window bottom, ensure that we still see a cursor. */
1960 height = min (glyph->ascent + glyph->descent,
1961 min (FRAME_LINE_HEIGHT (s->f), s->row->visible_height));
1962 max_y = window_text_bottom_y (s->w) - height;
1963 max_y = WINDOW_TO_FRAME_PIXEL_Y (s->w, max_y);
1964 if (s->ybase - glyph->ascent > max_y)
1965 {
1966 r.y = max_y;
1967 r.height = height;
1968 }
1969 else
1970 {
1971 /* Don't draw cursor glyph taller than our actual glyph. */
1972 height = max (FRAME_LINE_HEIGHT (s->f), glyph->ascent + glyph->descent);
1973 if (height < r.height)
1974 {
1975 max_y = r.y + r.height;
1976 r.y = min (max_y, max (r.y, s->ybase + glyph->descent - height));
1977 r.height = min (max_y - r.y, height);
1978 }
1979 }
1980 }
1981
1982 if (s->row->clip)
1983 {
1984 XRectangle r_save = r;
1985
1986 if (! x_intersect_rectangles (&r_save, s->row->clip, &r))
1987 r.width = 0;
1988 }
1989
1990 if ((s->for_overlaps & OVERLAPS_BOTH) == 0
1991 || ((s->for_overlaps & OVERLAPS_BOTH) == OVERLAPS_BOTH && n == 1))
1992 {
1993 #ifdef CONVERT_FROM_XRECT
1994 CONVERT_FROM_XRECT (r, *rects);
1995 #else
1996 *rects = r;
1997 #endif
1998 return 1;
1999 }
2000 else
2001 {
2002 /* If we are processing overlapping and allowed to return
2003 multiple clipping rectangles, we exclude the row of the glyph
2004 string from the clipping rectangle. This is to avoid drawing
2005 the same text on the environment with anti-aliasing. */
2006 #ifdef CONVERT_FROM_XRECT
2007 XRectangle rs[2];
2008 #else
2009 XRectangle *rs = rects;
2010 #endif
2011 int i = 0, row_y = WINDOW_TO_FRAME_PIXEL_Y (s->w, s->row->y);
2012
2013 if (s->for_overlaps & OVERLAPS_PRED)
2014 {
2015 rs[i] = r;
2016 if (r.y + r.height > row_y)
2017 {
2018 if (r.y < row_y)
2019 rs[i].height = row_y - r.y;
2020 else
2021 rs[i].height = 0;
2022 }
2023 i++;
2024 }
2025 if (s->for_overlaps & OVERLAPS_SUCC)
2026 {
2027 rs[i] = r;
2028 if (r.y < row_y + s->row->visible_height)
2029 {
2030 if (r.y + r.height > row_y + s->row->visible_height)
2031 {
2032 rs[i].y = row_y + s->row->visible_height;
2033 rs[i].height = r.y + r.height - rs[i].y;
2034 }
2035 else
2036 rs[i].height = 0;
2037 }
2038 i++;
2039 }
2040
2041 n = i;
2042 #ifdef CONVERT_FROM_XRECT
2043 for (i = 0; i < n; i++)
2044 CONVERT_FROM_XRECT (rs[i], rects[i]);
2045 #endif
2046 return n;
2047 }
2048 }
2049
2050 /* EXPORT:
2051 Return in *NR the clipping rectangle for glyph string S. */
2052
2053 void
2054 get_glyph_string_clip_rect (struct glyph_string *s, NativeRectangle *nr)
2055 {
2056 get_glyph_string_clip_rects (s, nr, 1);
2057 }
2058
2059
2060 /* EXPORT:
2061 Return the position and height of the phys cursor in window W.
2062 Set w->phys_cursor_width to width of phys cursor.
2063 */
2064
2065 void
2066 get_phys_cursor_geometry (struct window *w, struct glyph_row *row,
2067 struct glyph *glyph, int *xp, int *yp, int *heightp)
2068 {
2069 struct frame *f = XFRAME (WINDOW_FRAME (w));
2070 int x, y, wd, h, h0, y0;
2071
2072 /* Compute the width of the rectangle to draw. If on a stretch
2073 glyph, and `x-stretch-block-cursor' is nil, don't draw a
2074 rectangle as wide as the glyph, but use a canonical character
2075 width instead. */
2076 wd = glyph->pixel_width - 1;
2077 #if defined (HAVE_NTGUI) || defined (HAVE_NS)
2078 wd++; /* Why? */
2079 #endif
2080
2081 x = w->phys_cursor.x;
2082 if (x < 0)
2083 {
2084 wd += x;
2085 x = 0;
2086 }
2087
2088 if (glyph->type == STRETCH_GLYPH
2089 && !x_stretch_cursor_p)
2090 wd = min (FRAME_COLUMN_WIDTH (f), wd);
2091 w->phys_cursor_width = wd;
2092
2093 y = w->phys_cursor.y + row->ascent - glyph->ascent;
2094
2095 /* If y is below window bottom, ensure that we still see a cursor. */
2096 h0 = min (FRAME_LINE_HEIGHT (f), row->visible_height);
2097
2098 h = max (h0, glyph->ascent + glyph->descent);
2099 h0 = min (h0, glyph->ascent + glyph->descent);
2100
2101 y0 = WINDOW_HEADER_LINE_HEIGHT (w);
2102 if (y < y0)
2103 {
2104 h = max (h - (y0 - y) + 1, h0);
2105 y = y0 - 1;
2106 }
2107 else
2108 {
2109 y0 = window_text_bottom_y (w) - h0;
2110 if (y > y0)
2111 {
2112 h += y - y0;
2113 y = y0;
2114 }
2115 }
2116
2117 *xp = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, x);
2118 *yp = WINDOW_TO_FRAME_PIXEL_Y (w, y);
2119 *heightp = h;
2120 }
2121
2122 /*
2123 * Remember which glyph the mouse is over.
2124 */
2125
2126 void
2127 remember_mouse_glyph (struct frame *f, int gx, int gy, NativeRectangle *rect)
2128 {
2129 Lisp_Object window;
2130 struct window *w;
2131 struct glyph_row *r, *gr, *end_row;
2132 enum window_part part;
2133 enum glyph_row_area area;
2134 int x, y, width, height;
2135
2136 /* Try to determine frame pixel position and size of the glyph under
2137 frame pixel coordinates X/Y on frame F. */
2138
2139 if (!f->glyphs_initialized_p
2140 || (window = window_from_coordinates (f, gx, gy, &part, 0),
2141 NILP (window)))
2142 {
2143 width = FRAME_SMALLEST_CHAR_WIDTH (f);
2144 height = FRAME_SMALLEST_FONT_HEIGHT (f);
2145 goto virtual_glyph;
2146 }
2147
2148 w = XWINDOW (window);
2149 width = WINDOW_FRAME_COLUMN_WIDTH (w);
2150 height = WINDOW_FRAME_LINE_HEIGHT (w);
2151
2152 x = window_relative_x_coord (w, part, gx);
2153 y = gy - WINDOW_TOP_EDGE_Y (w);
2154
2155 r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
2156 end_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
2157
2158 if (w->pseudo_window_p)
2159 {
2160 area = TEXT_AREA;
2161 part = ON_MODE_LINE; /* Don't adjust margin. */
2162 goto text_glyph;
2163 }
2164
2165 switch (part)
2166 {
2167 case ON_LEFT_MARGIN:
2168 area = LEFT_MARGIN_AREA;
2169 goto text_glyph;
2170
2171 case ON_RIGHT_MARGIN:
2172 area = RIGHT_MARGIN_AREA;
2173 goto text_glyph;
2174
2175 case ON_HEADER_LINE:
2176 case ON_MODE_LINE:
2177 gr = (part == ON_HEADER_LINE
2178 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
2179 : MATRIX_MODE_LINE_ROW (w->current_matrix));
2180 gy = gr->y;
2181 area = TEXT_AREA;
2182 goto text_glyph_row_found;
2183
2184 case ON_TEXT:
2185 area = TEXT_AREA;
2186
2187 text_glyph:
2188 gr = 0; gy = 0;
2189 for (; r <= end_row && r->enabled_p; ++r)
2190 if (r->y + r->height > y)
2191 {
2192 gr = r; gy = r->y;
2193 break;
2194 }
2195
2196 text_glyph_row_found:
2197 if (gr && gy <= y)
2198 {
2199 struct glyph *g = gr->glyphs[area];
2200 struct glyph *end = g + gr->used[area];
2201
2202 height = gr->height;
2203 for (gx = gr->x; g < end; gx += g->pixel_width, ++g)
2204 if (gx + g->pixel_width > x)
2205 break;
2206
2207 if (g < end)
2208 {
2209 if (g->type == IMAGE_GLYPH)
2210 {
2211 /* Don't remember when mouse is over image, as
2212 image may have hot-spots. */
2213 STORE_NATIVE_RECT (*rect, 0, 0, 0, 0);
2214 return;
2215 }
2216 width = g->pixel_width;
2217 }
2218 else
2219 {
2220 /* Use nominal char spacing at end of line. */
2221 x -= gx;
2222 gx += (x / width) * width;
2223 }
2224
2225 if (part != ON_MODE_LINE && part != ON_HEADER_LINE)
2226 gx += window_box_left_offset (w, area);
2227 }
2228 else
2229 {
2230 /* Use nominal line height at end of window. */
2231 gx = (x / width) * width;
2232 y -= gy;
2233 gy += (y / height) * height;
2234 }
2235 break;
2236
2237 case ON_LEFT_FRINGE:
2238 gx = (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2239 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w)
2240 : window_box_right_offset (w, LEFT_MARGIN_AREA));
2241 width = WINDOW_LEFT_FRINGE_WIDTH (w);
2242 goto row_glyph;
2243
2244 case ON_RIGHT_FRINGE:
2245 gx = (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2246 ? window_box_right_offset (w, RIGHT_MARGIN_AREA)
2247 : window_box_right_offset (w, TEXT_AREA));
2248 width = WINDOW_RIGHT_FRINGE_WIDTH (w);
2249 goto row_glyph;
2250
2251 case ON_SCROLL_BAR:
2252 gx = (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w)
2253 ? 0
2254 : (window_box_right_offset (w, RIGHT_MARGIN_AREA)
2255 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2256 ? WINDOW_RIGHT_FRINGE_WIDTH (w)
2257 : 0)));
2258 width = WINDOW_SCROLL_BAR_AREA_WIDTH (w);
2259
2260 row_glyph:
2261 gr = 0, gy = 0;
2262 for (; r <= end_row && r->enabled_p; ++r)
2263 if (r->y + r->height > y)
2264 {
2265 gr = r; gy = r->y;
2266 break;
2267 }
2268
2269 if (gr && gy <= y)
2270 height = gr->height;
2271 else
2272 {
2273 /* Use nominal line height at end of window. */
2274 y -= gy;
2275 gy += (y / height) * height;
2276 }
2277 break;
2278
2279 default:
2280 ;
2281 virtual_glyph:
2282 /* If there is no glyph under the mouse, then we divide the screen
2283 into a grid of the smallest glyph in the frame, and use that
2284 as our "glyph". */
2285
2286 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to
2287 round down even for negative values. */
2288 if (gx < 0)
2289 gx -= width - 1;
2290 if (gy < 0)
2291 gy -= height - 1;
2292
2293 gx = (gx / width) * width;
2294 gy = (gy / height) * height;
2295
2296 goto store_rect;
2297 }
2298
2299 gx += WINDOW_LEFT_EDGE_X (w);
2300 gy += WINDOW_TOP_EDGE_Y (w);
2301
2302 store_rect:
2303 STORE_NATIVE_RECT (*rect, gx, gy, width, height);
2304
2305 /* Visible feedback for debugging. */
2306 #if 0
2307 #if HAVE_X_WINDOWS
2308 XDrawRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2309 f->output_data.x->normal_gc,
2310 gx, gy, width, height);
2311 #endif
2312 #endif
2313 }
2314
2315
2316 #endif /* HAVE_WINDOW_SYSTEM */
2317
2318 \f
2319 /***********************************************************************
2320 Lisp form evaluation
2321 ***********************************************************************/
2322
2323 /* Error handler for safe_eval and safe_call. */
2324
2325 static Lisp_Object
2326 safe_eval_handler (Lisp_Object arg)
2327 {
2328 add_to_log ("Error during redisplay: %S", arg, Qnil);
2329 return Qnil;
2330 }
2331
2332
2333 /* Evaluate SEXPR and return the result, or nil if something went
2334 wrong. Prevent redisplay during the evaluation. */
2335
2336 /* Call function ARGS[0] with arguments ARGS[1] to ARGS[NARGS - 1].
2337 Return the result, or nil if something went wrong. Prevent
2338 redisplay during the evaluation. */
2339
2340 Lisp_Object
2341 safe_call (ptrdiff_t nargs, Lisp_Object *args)
2342 {
2343 Lisp_Object val;
2344
2345 if (inhibit_eval_during_redisplay)
2346 val = Qnil;
2347 else
2348 {
2349 int count = SPECPDL_INDEX ();
2350 struct gcpro gcpro1;
2351
2352 GCPRO1 (args[0]);
2353 gcpro1.nvars = nargs;
2354 specbind (Qinhibit_redisplay, Qt);
2355 /* Use Qt to ensure debugger does not run,
2356 so there is no possibility of wanting to redisplay. */
2357 val = internal_condition_case_n (Ffuncall, nargs, args, Qt,
2358 safe_eval_handler);
2359 UNGCPRO;
2360 val = unbind_to (count, val);
2361 }
2362
2363 return val;
2364 }
2365
2366
2367 /* Call function FN with one argument ARG.
2368 Return the result, or nil if something went wrong. */
2369
2370 Lisp_Object
2371 safe_call1 (Lisp_Object fn, Lisp_Object arg)
2372 {
2373 Lisp_Object args[2];
2374 args[0] = fn;
2375 args[1] = arg;
2376 return safe_call (2, args);
2377 }
2378
2379 static Lisp_Object Qeval;
2380
2381 Lisp_Object
2382 safe_eval (Lisp_Object sexpr)
2383 {
2384 return safe_call1 (Qeval, sexpr);
2385 }
2386
2387 /* Call function FN with one argument ARG.
2388 Return the result, or nil if something went wrong. */
2389
2390 Lisp_Object
2391 safe_call2 (Lisp_Object fn, Lisp_Object arg1, Lisp_Object arg2)
2392 {
2393 Lisp_Object args[3];
2394 args[0] = fn;
2395 args[1] = arg1;
2396 args[2] = arg2;
2397 return safe_call (3, args);
2398 }
2399
2400
2401 \f
2402 /***********************************************************************
2403 Debugging
2404 ***********************************************************************/
2405
2406 #if 0
2407
2408 /* Define CHECK_IT to perform sanity checks on iterators.
2409 This is for debugging. It is too slow to do unconditionally. */
2410
2411 static void
2412 check_it (struct it *it)
2413 {
2414 if (it->method == GET_FROM_STRING)
2415 {
2416 xassert (STRINGP (it->string));
2417 xassert (IT_STRING_CHARPOS (*it) >= 0);
2418 }
2419 else
2420 {
2421 xassert (IT_STRING_CHARPOS (*it) < 0);
2422 if (it->method == GET_FROM_BUFFER)
2423 {
2424 /* Check that character and byte positions agree. */
2425 xassert (IT_CHARPOS (*it) == BYTE_TO_CHAR (IT_BYTEPOS (*it)));
2426 }
2427 }
2428
2429 if (it->dpvec)
2430 xassert (it->current.dpvec_index >= 0);
2431 else
2432 xassert (it->current.dpvec_index < 0);
2433 }
2434
2435 #define CHECK_IT(IT) check_it ((IT))
2436
2437 #else /* not 0 */
2438
2439 #define CHECK_IT(IT) (void) 0
2440
2441 #endif /* not 0 */
2442
2443
2444 #if GLYPH_DEBUG && XASSERTS
2445
2446 /* Check that the window end of window W is what we expect it
2447 to be---the last row in the current matrix displaying text. */
2448
2449 static void
2450 check_window_end (struct window *w)
2451 {
2452 if (!MINI_WINDOW_P (w)
2453 && !NILP (w->window_end_valid))
2454 {
2455 struct glyph_row *row;
2456 xassert ((row = MATRIX_ROW (w->current_matrix,
2457 XFASTINT (w->window_end_vpos)),
2458 !row->enabled_p
2459 || MATRIX_ROW_DISPLAYS_TEXT_P (row)
2460 || MATRIX_ROW_VPOS (row, w->current_matrix) == 0));
2461 }
2462 }
2463
2464 #define CHECK_WINDOW_END(W) check_window_end ((W))
2465
2466 #else
2467
2468 #define CHECK_WINDOW_END(W) (void) 0
2469
2470 #endif
2471
2472
2473 \f
2474 /***********************************************************************
2475 Iterator initialization
2476 ***********************************************************************/
2477
2478 /* Initialize IT for displaying current_buffer in window W, starting
2479 at character position CHARPOS. CHARPOS < 0 means that no buffer
2480 position is specified which is useful when the iterator is assigned
2481 a position later. BYTEPOS is the byte position corresponding to
2482 CHARPOS. BYTEPOS < 0 means compute it from CHARPOS.
2483
2484 If ROW is not null, calls to produce_glyphs with IT as parameter
2485 will produce glyphs in that row.
2486
2487 BASE_FACE_ID is the id of a base face to use. It must be one of
2488 DEFAULT_FACE_ID for normal text, MODE_LINE_FACE_ID,
2489 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID for displaying
2490 mode lines, or TOOL_BAR_FACE_ID for displaying the tool-bar.
2491
2492 If ROW is null and BASE_FACE_ID is equal to MODE_LINE_FACE_ID,
2493 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID, the iterator
2494 will be initialized to use the corresponding mode line glyph row of
2495 the desired matrix of W. */
2496
2497 void
2498 init_iterator (struct it *it, struct window *w,
2499 EMACS_INT charpos, EMACS_INT bytepos,
2500 struct glyph_row *row, enum face_id base_face_id)
2501 {
2502 int highlight_region_p;
2503 enum face_id remapped_base_face_id = base_face_id;
2504
2505 /* Some precondition checks. */
2506 xassert (w != NULL && it != NULL);
2507 xassert (charpos < 0 || (charpos >= BUF_BEG (current_buffer)
2508 && charpos <= ZV));
2509
2510 /* If face attributes have been changed since the last redisplay,
2511 free realized faces now because they depend on face definitions
2512 that might have changed. Don't free faces while there might be
2513 desired matrices pending which reference these faces. */
2514 if (face_change_count && !inhibit_free_realized_faces)
2515 {
2516 face_change_count = 0;
2517 free_all_realized_faces (Qnil);
2518 }
2519
2520 /* Perhaps remap BASE_FACE_ID to a user-specified alternative. */
2521 if (! NILP (Vface_remapping_alist))
2522 remapped_base_face_id = lookup_basic_face (XFRAME (w->frame), base_face_id);
2523
2524 /* Use one of the mode line rows of W's desired matrix if
2525 appropriate. */
2526 if (row == NULL)
2527 {
2528 if (base_face_id == MODE_LINE_FACE_ID
2529 || base_face_id == MODE_LINE_INACTIVE_FACE_ID)
2530 row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
2531 else if (base_face_id == HEADER_LINE_FACE_ID)
2532 row = MATRIX_HEADER_LINE_ROW (w->desired_matrix);
2533 }
2534
2535 /* Clear IT. */
2536 memset (it, 0, sizeof *it);
2537 it->current.overlay_string_index = -1;
2538 it->current.dpvec_index = -1;
2539 it->base_face_id = remapped_base_face_id;
2540 it->string = Qnil;
2541 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
2542 it->paragraph_embedding = L2R;
2543 it->bidi_it.string.lstring = Qnil;
2544 it->bidi_it.string.s = NULL;
2545 it->bidi_it.string.bufpos = 0;
2546
2547 /* The window in which we iterate over current_buffer: */
2548 XSETWINDOW (it->window, w);
2549 it->w = w;
2550 it->f = XFRAME (w->frame);
2551
2552 it->cmp_it.id = -1;
2553
2554 /* Extra space between lines (on window systems only). */
2555 if (base_face_id == DEFAULT_FACE_ID
2556 && FRAME_WINDOW_P (it->f))
2557 {
2558 if (NATNUMP (BVAR (current_buffer, extra_line_spacing)))
2559 it->extra_line_spacing = XFASTINT (BVAR (current_buffer, extra_line_spacing));
2560 else if (FLOATP (BVAR (current_buffer, extra_line_spacing)))
2561 it->extra_line_spacing = (XFLOAT_DATA (BVAR (current_buffer, extra_line_spacing))
2562 * FRAME_LINE_HEIGHT (it->f));
2563 else if (it->f->extra_line_spacing > 0)
2564 it->extra_line_spacing = it->f->extra_line_spacing;
2565 it->max_extra_line_spacing = 0;
2566 }
2567
2568 /* If realized faces have been removed, e.g. because of face
2569 attribute changes of named faces, recompute them. When running
2570 in batch mode, the face cache of the initial frame is null. If
2571 we happen to get called, make a dummy face cache. */
2572 if (FRAME_FACE_CACHE (it->f) == NULL)
2573 init_frame_faces (it->f);
2574 if (FRAME_FACE_CACHE (it->f)->used == 0)
2575 recompute_basic_faces (it->f);
2576
2577 /* Current value of the `slice', `space-width', and 'height' properties. */
2578 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
2579 it->space_width = Qnil;
2580 it->font_height = Qnil;
2581 it->override_ascent = -1;
2582
2583 /* Are control characters displayed as `^C'? */
2584 it->ctl_arrow_p = !NILP (BVAR (current_buffer, ctl_arrow));
2585
2586 /* -1 means everything between a CR and the following line end
2587 is invisible. >0 means lines indented more than this value are
2588 invisible. */
2589 it->selective = (INTEGERP (BVAR (current_buffer, selective_display))
2590 ? XINT (BVAR (current_buffer, selective_display))
2591 : (!NILP (BVAR (current_buffer, selective_display))
2592 ? -1 : 0));
2593 it->selective_display_ellipsis_p
2594 = !NILP (BVAR (current_buffer, selective_display_ellipses));
2595
2596 /* Display table to use. */
2597 it->dp = window_display_table (w);
2598
2599 /* Are multibyte characters enabled in current_buffer? */
2600 it->multibyte_p = !NILP (BVAR (current_buffer, enable_multibyte_characters));
2601
2602 /* Non-zero if we should highlight the region. */
2603 highlight_region_p
2604 = (!NILP (Vtransient_mark_mode)
2605 && !NILP (BVAR (current_buffer, mark_active))
2606 && XMARKER (BVAR (current_buffer, mark))->buffer != 0);
2607
2608 /* Set IT->region_beg_charpos and IT->region_end_charpos to the
2609 start and end of a visible region in window IT->w. Set both to
2610 -1 to indicate no region. */
2611 if (highlight_region_p
2612 /* Maybe highlight only in selected window. */
2613 && (/* Either show region everywhere. */
2614 highlight_nonselected_windows
2615 /* Or show region in the selected window. */
2616 || w == XWINDOW (selected_window)
2617 /* Or show the region if we are in the mini-buffer and W is
2618 the window the mini-buffer refers to. */
2619 || (MINI_WINDOW_P (XWINDOW (selected_window))
2620 && WINDOWP (minibuf_selected_window)
2621 && w == XWINDOW (minibuf_selected_window))))
2622 {
2623 EMACS_INT markpos = marker_position (BVAR (current_buffer, mark));
2624 it->region_beg_charpos = min (PT, markpos);
2625 it->region_end_charpos = max (PT, markpos);
2626 }
2627 else
2628 it->region_beg_charpos = it->region_end_charpos = -1;
2629
2630 /* Get the position at which the redisplay_end_trigger hook should
2631 be run, if it is to be run at all. */
2632 if (MARKERP (w->redisplay_end_trigger)
2633 && XMARKER (w->redisplay_end_trigger)->buffer != 0)
2634 it->redisplay_end_trigger_charpos
2635 = marker_position (w->redisplay_end_trigger);
2636 else if (INTEGERP (w->redisplay_end_trigger))
2637 it->redisplay_end_trigger_charpos = XINT (w->redisplay_end_trigger);
2638
2639 it->tab_width = SANE_TAB_WIDTH (current_buffer);
2640
2641 /* Are lines in the display truncated? */
2642 if (base_face_id != DEFAULT_FACE_ID
2643 || XINT (it->w->hscroll)
2644 || (! WINDOW_FULL_WIDTH_P (it->w)
2645 && ((!NILP (Vtruncate_partial_width_windows)
2646 && !INTEGERP (Vtruncate_partial_width_windows))
2647 || (INTEGERP (Vtruncate_partial_width_windows)
2648 && (WINDOW_TOTAL_COLS (it->w)
2649 < XINT (Vtruncate_partial_width_windows))))))
2650 it->line_wrap = TRUNCATE;
2651 else if (NILP (BVAR (current_buffer, truncate_lines)))
2652 it->line_wrap = NILP (BVAR (current_buffer, word_wrap))
2653 ? WINDOW_WRAP : WORD_WRAP;
2654 else
2655 it->line_wrap = TRUNCATE;
2656
2657 /* Get dimensions of truncation and continuation glyphs. These are
2658 displayed as fringe bitmaps under X, so we don't need them for such
2659 frames. */
2660 if (!FRAME_WINDOW_P (it->f))
2661 {
2662 if (it->line_wrap == TRUNCATE)
2663 {
2664 /* We will need the truncation glyph. */
2665 xassert (it->glyph_row == NULL);
2666 produce_special_glyphs (it, IT_TRUNCATION);
2667 it->truncation_pixel_width = it->pixel_width;
2668 }
2669 else
2670 {
2671 /* We will need the continuation glyph. */
2672 xassert (it->glyph_row == NULL);
2673 produce_special_glyphs (it, IT_CONTINUATION);
2674 it->continuation_pixel_width = it->pixel_width;
2675 }
2676
2677 /* Reset these values to zero because the produce_special_glyphs
2678 above has changed them. */
2679 it->pixel_width = it->ascent = it->descent = 0;
2680 it->phys_ascent = it->phys_descent = 0;
2681 }
2682
2683 /* Set this after getting the dimensions of truncation and
2684 continuation glyphs, so that we don't produce glyphs when calling
2685 produce_special_glyphs, above. */
2686 it->glyph_row = row;
2687 it->area = TEXT_AREA;
2688
2689 /* Forget any previous info about this row being reversed. */
2690 if (it->glyph_row)
2691 it->glyph_row->reversed_p = 0;
2692
2693 /* Get the dimensions of the display area. The display area
2694 consists of the visible window area plus a horizontally scrolled
2695 part to the left of the window. All x-values are relative to the
2696 start of this total display area. */
2697 if (base_face_id != DEFAULT_FACE_ID)
2698 {
2699 /* Mode lines, menu bar in terminal frames. */
2700 it->first_visible_x = 0;
2701 it->last_visible_x = WINDOW_TOTAL_WIDTH (w);
2702 }
2703 else
2704 {
2705 it->first_visible_x
2706 = XFASTINT (it->w->hscroll) * FRAME_COLUMN_WIDTH (it->f);
2707 it->last_visible_x = (it->first_visible_x
2708 + window_box_width (w, TEXT_AREA));
2709
2710 /* If we truncate lines, leave room for the truncator glyph(s) at
2711 the right margin. Otherwise, leave room for the continuation
2712 glyph(s). Truncation and continuation glyphs are not inserted
2713 for window-based redisplay. */
2714 if (!FRAME_WINDOW_P (it->f))
2715 {
2716 if (it->line_wrap == TRUNCATE)
2717 it->last_visible_x -= it->truncation_pixel_width;
2718 else
2719 it->last_visible_x -= it->continuation_pixel_width;
2720 }
2721
2722 it->header_line_p = WINDOW_WANTS_HEADER_LINE_P (w);
2723 it->current_y = WINDOW_HEADER_LINE_HEIGHT (w) + w->vscroll;
2724 }
2725
2726 /* Leave room for a border glyph. */
2727 if (!FRAME_WINDOW_P (it->f)
2728 && !WINDOW_RIGHTMOST_P (it->w))
2729 it->last_visible_x -= 1;
2730
2731 it->last_visible_y = window_text_bottom_y (w);
2732
2733 /* For mode lines and alike, arrange for the first glyph having a
2734 left box line if the face specifies a box. */
2735 if (base_face_id != DEFAULT_FACE_ID)
2736 {
2737 struct face *face;
2738
2739 it->face_id = remapped_base_face_id;
2740
2741 /* If we have a boxed mode line, make the first character appear
2742 with a left box line. */
2743 face = FACE_FROM_ID (it->f, remapped_base_face_id);
2744 if (face->box != FACE_NO_BOX)
2745 it->start_of_box_run_p = 1;
2746 }
2747
2748 /* If a buffer position was specified, set the iterator there,
2749 getting overlays and face properties from that position. */
2750 if (charpos >= BUF_BEG (current_buffer))
2751 {
2752 it->end_charpos = ZV;
2753 it->face_id = -1;
2754 IT_CHARPOS (*it) = charpos;
2755
2756 /* Compute byte position if not specified. */
2757 if (bytepos < charpos)
2758 IT_BYTEPOS (*it) = CHAR_TO_BYTE (charpos);
2759 else
2760 IT_BYTEPOS (*it) = bytepos;
2761
2762 it->start = it->current;
2763 /* Do we need to reorder bidirectional text? Not if this is a
2764 unibyte buffer: by definition, none of the single-byte
2765 characters are strong R2L, so no reordering is needed. And
2766 bidi.c doesn't support unibyte buffers anyway. */
2767 it->bidi_p =
2768 !NILP (BVAR (current_buffer, bidi_display_reordering))
2769 && it->multibyte_p;
2770
2771 /* If we are to reorder bidirectional text, init the bidi
2772 iterator. */
2773 if (it->bidi_p)
2774 {
2775 /* Note the paragraph direction that this buffer wants to
2776 use. */
2777 if (EQ (BVAR (current_buffer, bidi_paragraph_direction),
2778 Qleft_to_right))
2779 it->paragraph_embedding = L2R;
2780 else if (EQ (BVAR (current_buffer, bidi_paragraph_direction),
2781 Qright_to_left))
2782 it->paragraph_embedding = R2L;
2783 else
2784 it->paragraph_embedding = NEUTRAL_DIR;
2785 bidi_unshelve_cache (NULL, 0);
2786 bidi_init_it (charpos, IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f),
2787 &it->bidi_it);
2788 }
2789
2790 /* Compute faces etc. */
2791 reseat (it, it->current.pos, 1);
2792 }
2793
2794 CHECK_IT (it);
2795 }
2796
2797
2798 /* Initialize IT for the display of window W with window start POS. */
2799
2800 void
2801 start_display (struct it *it, struct window *w, struct text_pos pos)
2802 {
2803 struct glyph_row *row;
2804 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
2805
2806 row = w->desired_matrix->rows + first_vpos;
2807 init_iterator (it, w, CHARPOS (pos), BYTEPOS (pos), row, DEFAULT_FACE_ID);
2808 it->first_vpos = first_vpos;
2809
2810 /* Don't reseat to previous visible line start if current start
2811 position is in a string or image. */
2812 if (it->method == GET_FROM_BUFFER && it->line_wrap != TRUNCATE)
2813 {
2814 int start_at_line_beg_p;
2815 int first_y = it->current_y;
2816
2817 /* If window start is not at a line start, skip forward to POS to
2818 get the correct continuation lines width. */
2819 start_at_line_beg_p = (CHARPOS (pos) == BEGV
2820 || FETCH_BYTE (BYTEPOS (pos) - 1) == '\n');
2821 if (!start_at_line_beg_p)
2822 {
2823 int new_x;
2824
2825 reseat_at_previous_visible_line_start (it);
2826 move_it_to (it, CHARPOS (pos), -1, -1, -1, MOVE_TO_POS);
2827
2828 new_x = it->current_x + it->pixel_width;
2829
2830 /* If lines are continued, this line may end in the middle
2831 of a multi-glyph character (e.g. a control character
2832 displayed as \003, or in the middle of an overlay
2833 string). In this case move_it_to above will not have
2834 taken us to the start of the continuation line but to the
2835 end of the continued line. */
2836 if (it->current_x > 0
2837 && it->line_wrap != TRUNCATE /* Lines are continued. */
2838 && (/* And glyph doesn't fit on the line. */
2839 new_x > it->last_visible_x
2840 /* Or it fits exactly and we're on a window
2841 system frame. */
2842 || (new_x == it->last_visible_x
2843 && FRAME_WINDOW_P (it->f))))
2844 {
2845 if (it->current.dpvec_index >= 0
2846 || it->current.overlay_string_index >= 0)
2847 {
2848 set_iterator_to_next (it, 1);
2849 move_it_in_display_line_to (it, -1, -1, 0);
2850 }
2851
2852 it->continuation_lines_width += it->current_x;
2853 }
2854 /* If the character at POS is displayed via a display
2855 vector, move_it_to above stops at the final glyph of
2856 IT->dpvec. To make the caller redisplay that character
2857 again (a.k.a. start at POS), we need to reset the
2858 dpvec_index to the beginning of IT->dpvec. */
2859 else if (it->current.dpvec_index >= 0)
2860 it->current.dpvec_index = 0;
2861
2862 /* We're starting a new display line, not affected by the
2863 height of the continued line, so clear the appropriate
2864 fields in the iterator structure. */
2865 it->max_ascent = it->max_descent = 0;
2866 it->max_phys_ascent = it->max_phys_descent = 0;
2867
2868 it->current_y = first_y;
2869 it->vpos = 0;
2870 it->current_x = it->hpos = 0;
2871 }
2872 }
2873 }
2874
2875
2876 /* Return 1 if POS is a position in ellipses displayed for invisible
2877 text. W is the window we display, for text property lookup. */
2878
2879 static int
2880 in_ellipses_for_invisible_text_p (struct display_pos *pos, struct window *w)
2881 {
2882 Lisp_Object prop, window;
2883 int ellipses_p = 0;
2884 EMACS_INT charpos = CHARPOS (pos->pos);
2885
2886 /* If POS specifies a position in a display vector, this might
2887 be for an ellipsis displayed for invisible text. We won't
2888 get the iterator set up for delivering that ellipsis unless
2889 we make sure that it gets aware of the invisible text. */
2890 if (pos->dpvec_index >= 0
2891 && pos->overlay_string_index < 0
2892 && CHARPOS (pos->string_pos) < 0
2893 && charpos > BEGV
2894 && (XSETWINDOW (window, w),
2895 prop = Fget_char_property (make_number (charpos),
2896 Qinvisible, window),
2897 !TEXT_PROP_MEANS_INVISIBLE (prop)))
2898 {
2899 prop = Fget_char_property (make_number (charpos - 1), Qinvisible,
2900 window);
2901 ellipses_p = 2 == TEXT_PROP_MEANS_INVISIBLE (prop);
2902 }
2903
2904 return ellipses_p;
2905 }
2906
2907
2908 /* Initialize IT for stepping through current_buffer in window W,
2909 starting at position POS that includes overlay string and display
2910 vector/ control character translation position information. Value
2911 is zero if there are overlay strings with newlines at POS. */
2912
2913 static int
2914 init_from_display_pos (struct it *it, struct window *w, struct display_pos *pos)
2915 {
2916 EMACS_INT charpos = CHARPOS (pos->pos), bytepos = BYTEPOS (pos->pos);
2917 int i, overlay_strings_with_newlines = 0;
2918
2919 /* If POS specifies a position in a display vector, this might
2920 be for an ellipsis displayed for invisible text. We won't
2921 get the iterator set up for delivering that ellipsis unless
2922 we make sure that it gets aware of the invisible text. */
2923 if (in_ellipses_for_invisible_text_p (pos, w))
2924 {
2925 --charpos;
2926 bytepos = 0;
2927 }
2928
2929 /* Keep in mind: the call to reseat in init_iterator skips invisible
2930 text, so we might end up at a position different from POS. This
2931 is only a problem when POS is a row start after a newline and an
2932 overlay starts there with an after-string, and the overlay has an
2933 invisible property. Since we don't skip invisible text in
2934 display_line and elsewhere immediately after consuming the
2935 newline before the row start, such a POS will not be in a string,
2936 but the call to init_iterator below will move us to the
2937 after-string. */
2938 init_iterator (it, w, charpos, bytepos, NULL, DEFAULT_FACE_ID);
2939
2940 /* This only scans the current chunk -- it should scan all chunks.
2941 However, OVERLAY_STRING_CHUNK_SIZE has been increased from 3 in 21.1
2942 to 16 in 22.1 to make this a lesser problem. */
2943 for (i = 0; i < it->n_overlay_strings && i < OVERLAY_STRING_CHUNK_SIZE; ++i)
2944 {
2945 const char *s = SSDATA (it->overlay_strings[i]);
2946 const char *e = s + SBYTES (it->overlay_strings[i]);
2947
2948 while (s < e && *s != '\n')
2949 ++s;
2950
2951 if (s < e)
2952 {
2953 overlay_strings_with_newlines = 1;
2954 break;
2955 }
2956 }
2957
2958 /* If position is within an overlay string, set up IT to the right
2959 overlay string. */
2960 if (pos->overlay_string_index >= 0)
2961 {
2962 int relative_index;
2963
2964 /* If the first overlay string happens to have a `display'
2965 property for an image, the iterator will be set up for that
2966 image, and we have to undo that setup first before we can
2967 correct the overlay string index. */
2968 if (it->method == GET_FROM_IMAGE)
2969 pop_it (it);
2970
2971 /* We already have the first chunk of overlay strings in
2972 IT->overlay_strings. Load more until the one for
2973 pos->overlay_string_index is in IT->overlay_strings. */
2974 if (pos->overlay_string_index >= OVERLAY_STRING_CHUNK_SIZE)
2975 {
2976 int n = pos->overlay_string_index / OVERLAY_STRING_CHUNK_SIZE;
2977 it->current.overlay_string_index = 0;
2978 while (n--)
2979 {
2980 load_overlay_strings (it, 0);
2981 it->current.overlay_string_index += OVERLAY_STRING_CHUNK_SIZE;
2982 }
2983 }
2984
2985 it->current.overlay_string_index = pos->overlay_string_index;
2986 relative_index = (it->current.overlay_string_index
2987 % OVERLAY_STRING_CHUNK_SIZE);
2988 it->string = it->overlay_strings[relative_index];
2989 xassert (STRINGP (it->string));
2990 it->current.string_pos = pos->string_pos;
2991 it->method = GET_FROM_STRING;
2992 }
2993
2994 if (CHARPOS (pos->string_pos) >= 0)
2995 {
2996 /* Recorded position is not in an overlay string, but in another
2997 string. This can only be a string from a `display' property.
2998 IT should already be filled with that string. */
2999 it->current.string_pos = pos->string_pos;
3000 xassert (STRINGP (it->string));
3001 }
3002
3003 /* Restore position in display vector translations, control
3004 character translations or ellipses. */
3005 if (pos->dpvec_index >= 0)
3006 {
3007 if (it->dpvec == NULL)
3008 get_next_display_element (it);
3009 xassert (it->dpvec && it->current.dpvec_index == 0);
3010 it->current.dpvec_index = pos->dpvec_index;
3011 }
3012
3013 CHECK_IT (it);
3014 return !overlay_strings_with_newlines;
3015 }
3016
3017
3018 /* Initialize IT for stepping through current_buffer in window W
3019 starting at ROW->start. */
3020
3021 static void
3022 init_to_row_start (struct it *it, struct window *w, struct glyph_row *row)
3023 {
3024 init_from_display_pos (it, w, &row->start);
3025 it->start = row->start;
3026 it->continuation_lines_width = row->continuation_lines_width;
3027 CHECK_IT (it);
3028 }
3029
3030
3031 /* Initialize IT for stepping through current_buffer in window W
3032 starting in the line following ROW, i.e. starting at ROW->end.
3033 Value is zero if there are overlay strings with newlines at ROW's
3034 end position. */
3035
3036 static int
3037 init_to_row_end (struct it *it, struct window *w, struct glyph_row *row)
3038 {
3039 int success = 0;
3040
3041 if (init_from_display_pos (it, w, &row->end))
3042 {
3043 if (row->continued_p)
3044 it->continuation_lines_width
3045 = row->continuation_lines_width + row->pixel_width;
3046 CHECK_IT (it);
3047 success = 1;
3048 }
3049
3050 return success;
3051 }
3052
3053
3054
3055 \f
3056 /***********************************************************************
3057 Text properties
3058 ***********************************************************************/
3059
3060 /* Called when IT reaches IT->stop_charpos. Handle text property and
3061 overlay changes. Set IT->stop_charpos to the next position where
3062 to stop. */
3063
3064 static void
3065 handle_stop (struct it *it)
3066 {
3067 enum prop_handled handled;
3068 int handle_overlay_change_p;
3069 struct props *p;
3070
3071 it->dpvec = NULL;
3072 it->current.dpvec_index = -1;
3073 handle_overlay_change_p = !it->ignore_overlay_strings_at_pos_p;
3074 it->ignore_overlay_strings_at_pos_p = 0;
3075 it->ellipsis_p = 0;
3076
3077 /* Use face of preceding text for ellipsis (if invisible) */
3078 if (it->selective_display_ellipsis_p)
3079 it->saved_face_id = it->face_id;
3080
3081 do
3082 {
3083 handled = HANDLED_NORMALLY;
3084
3085 /* Call text property handlers. */
3086 for (p = it_props; p->handler; ++p)
3087 {
3088 handled = p->handler (it);
3089
3090 if (handled == HANDLED_RECOMPUTE_PROPS)
3091 break;
3092 else if (handled == HANDLED_RETURN)
3093 {
3094 /* We still want to show before and after strings from
3095 overlays even if the actual buffer text is replaced. */
3096 if (!handle_overlay_change_p
3097 || it->sp > 1
3098 || !get_overlay_strings_1 (it, 0, 0))
3099 {
3100 if (it->ellipsis_p)
3101 setup_for_ellipsis (it, 0);
3102 /* When handling a display spec, we might load an
3103 empty string. In that case, discard it here. We
3104 used to discard it in handle_single_display_spec,
3105 but that causes get_overlay_strings_1, above, to
3106 ignore overlay strings that we must check. */
3107 if (STRINGP (it->string) && !SCHARS (it->string))
3108 pop_it (it);
3109 return;
3110 }
3111 else if (STRINGP (it->string) && !SCHARS (it->string))
3112 pop_it (it);
3113 else
3114 {
3115 it->ignore_overlay_strings_at_pos_p = 1;
3116 it->string_from_display_prop_p = 0;
3117 it->from_disp_prop_p = 0;
3118 handle_overlay_change_p = 0;
3119 }
3120 handled = HANDLED_RECOMPUTE_PROPS;
3121 break;
3122 }
3123 else if (handled == HANDLED_OVERLAY_STRING_CONSUMED)
3124 handle_overlay_change_p = 0;
3125 }
3126
3127 if (handled != HANDLED_RECOMPUTE_PROPS)
3128 {
3129 /* Don't check for overlay strings below when set to deliver
3130 characters from a display vector. */
3131 if (it->method == GET_FROM_DISPLAY_VECTOR)
3132 handle_overlay_change_p = 0;
3133
3134 /* Handle overlay changes.
3135 This sets HANDLED to HANDLED_RECOMPUTE_PROPS
3136 if it finds overlays. */
3137 if (handle_overlay_change_p)
3138 handled = handle_overlay_change (it);
3139 }
3140
3141 if (it->ellipsis_p)
3142 {
3143 setup_for_ellipsis (it, 0);
3144 break;
3145 }
3146 }
3147 while (handled == HANDLED_RECOMPUTE_PROPS);
3148
3149 /* Determine where to stop next. */
3150 if (handled == HANDLED_NORMALLY)
3151 compute_stop_pos (it);
3152 }
3153
3154
3155 /* Compute IT->stop_charpos from text property and overlay change
3156 information for IT's current position. */
3157
3158 static void
3159 compute_stop_pos (struct it *it)
3160 {
3161 register INTERVAL iv, next_iv;
3162 Lisp_Object object, limit, position;
3163 EMACS_INT charpos, bytepos;
3164
3165 /* If nowhere else, stop at the end. */
3166 it->stop_charpos = it->end_charpos;
3167
3168 if (STRINGP (it->string))
3169 {
3170 /* Strings are usually short, so don't limit the search for
3171 properties. */
3172 object = it->string;
3173 limit = Qnil;
3174 charpos = IT_STRING_CHARPOS (*it);
3175 bytepos = IT_STRING_BYTEPOS (*it);
3176 }
3177 else
3178 {
3179 EMACS_INT pos;
3180
3181 /* If next overlay change is in front of the current stop pos
3182 (which is IT->end_charpos), stop there. Note: value of
3183 next_overlay_change is point-max if no overlay change
3184 follows. */
3185 charpos = IT_CHARPOS (*it);
3186 bytepos = IT_BYTEPOS (*it);
3187 pos = next_overlay_change (charpos);
3188 if (pos < it->stop_charpos)
3189 it->stop_charpos = pos;
3190
3191 /* If showing the region, we have to stop at the region
3192 start or end because the face might change there. */
3193 if (it->region_beg_charpos > 0)
3194 {
3195 if (IT_CHARPOS (*it) < it->region_beg_charpos)
3196 it->stop_charpos = min (it->stop_charpos, it->region_beg_charpos);
3197 else if (IT_CHARPOS (*it) < it->region_end_charpos)
3198 it->stop_charpos = min (it->stop_charpos, it->region_end_charpos);
3199 }
3200
3201 /* Set up variables for computing the stop position from text
3202 property changes. */
3203 XSETBUFFER (object, current_buffer);
3204 limit = make_number (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT);
3205 }
3206
3207 /* Get the interval containing IT's position. Value is a null
3208 interval if there isn't such an interval. */
3209 position = make_number (charpos);
3210 iv = validate_interval_range (object, &position, &position, 0);
3211 if (!NULL_INTERVAL_P (iv))
3212 {
3213 Lisp_Object values_here[LAST_PROP_IDX];
3214 struct props *p;
3215
3216 /* Get properties here. */
3217 for (p = it_props; p->handler; ++p)
3218 values_here[p->idx] = textget (iv->plist, *p->name);
3219
3220 /* Look for an interval following iv that has different
3221 properties. */
3222 for (next_iv = next_interval (iv);
3223 (!NULL_INTERVAL_P (next_iv)
3224 && (NILP (limit)
3225 || XFASTINT (limit) > next_iv->position));
3226 next_iv = next_interval (next_iv))
3227 {
3228 for (p = it_props; p->handler; ++p)
3229 {
3230 Lisp_Object new_value;
3231
3232 new_value = textget (next_iv->plist, *p->name);
3233 if (!EQ (values_here[p->idx], new_value))
3234 break;
3235 }
3236
3237 if (p->handler)
3238 break;
3239 }
3240
3241 if (!NULL_INTERVAL_P (next_iv))
3242 {
3243 if (INTEGERP (limit)
3244 && next_iv->position >= XFASTINT (limit))
3245 /* No text property change up to limit. */
3246 it->stop_charpos = min (XFASTINT (limit), it->stop_charpos);
3247 else
3248 /* Text properties change in next_iv. */
3249 it->stop_charpos = min (it->stop_charpos, next_iv->position);
3250 }
3251 }
3252
3253 if (it->cmp_it.id < 0)
3254 {
3255 EMACS_INT stoppos = it->end_charpos;
3256
3257 if (it->bidi_p && it->bidi_it.scan_dir < 0)
3258 stoppos = -1;
3259 composition_compute_stop_pos (&it->cmp_it, charpos, bytepos,
3260 stoppos, it->string);
3261 }
3262
3263 xassert (STRINGP (it->string)
3264 || (it->stop_charpos >= BEGV
3265 && it->stop_charpos >= IT_CHARPOS (*it)));
3266 }
3267
3268
3269 /* Return the position of the next overlay change after POS in
3270 current_buffer. Value is point-max if no overlay change
3271 follows. This is like `next-overlay-change' but doesn't use
3272 xmalloc. */
3273
3274 static EMACS_INT
3275 next_overlay_change (EMACS_INT pos)
3276 {
3277 ptrdiff_t i, noverlays;
3278 EMACS_INT endpos;
3279 Lisp_Object *overlays;
3280
3281 /* Get all overlays at the given position. */
3282 GET_OVERLAYS_AT (pos, overlays, noverlays, &endpos, 1);
3283
3284 /* If any of these overlays ends before endpos,
3285 use its ending point instead. */
3286 for (i = 0; i < noverlays; ++i)
3287 {
3288 Lisp_Object oend;
3289 EMACS_INT oendpos;
3290
3291 oend = OVERLAY_END (overlays[i]);
3292 oendpos = OVERLAY_POSITION (oend);
3293 endpos = min (endpos, oendpos);
3294 }
3295
3296 return endpos;
3297 }
3298
3299 /* How many characters forward to search for a display property or
3300 display string. Searching too far forward makes the bidi display
3301 sluggish, especially in small windows. */
3302 #define MAX_DISP_SCAN 250
3303
3304 /* Return the character position of a display string at or after
3305 position specified by POSITION. If no display string exists at or
3306 after POSITION, return ZV. A display string is either an overlay
3307 with `display' property whose value is a string, or a `display'
3308 text property whose value is a string. STRING is data about the
3309 string to iterate; if STRING->lstring is nil, we are iterating a
3310 buffer. FRAME_WINDOW_P is non-zero when we are displaying a window
3311 on a GUI frame. DISP_PROP is set to zero if we searched
3312 MAX_DISP_SCAN characters forward without finding any display
3313 strings, non-zero otherwise. It is set to 2 if the display string
3314 uses any kind of `(space ...)' spec that will produce a stretch of
3315 white space in the text area. */
3316 EMACS_INT
3317 compute_display_string_pos (struct text_pos *position,
3318 struct bidi_string_data *string,
3319 int frame_window_p, int *disp_prop)
3320 {
3321 /* OBJECT = nil means current buffer. */
3322 Lisp_Object object =
3323 (string && STRINGP (string->lstring)) ? string->lstring : Qnil;
3324 Lisp_Object pos, spec, limpos;
3325 int string_p = (string && (STRINGP (string->lstring) || string->s));
3326 EMACS_INT eob = string_p ? string->schars : ZV;
3327 EMACS_INT begb = string_p ? 0 : BEGV;
3328 EMACS_INT bufpos, charpos = CHARPOS (*position);
3329 EMACS_INT lim =
3330 (charpos < eob - MAX_DISP_SCAN) ? charpos + MAX_DISP_SCAN : eob;
3331 struct text_pos tpos;
3332 int rv = 0;
3333
3334 *disp_prop = 1;
3335
3336 if (charpos >= eob
3337 /* We don't support display properties whose values are strings
3338 that have display string properties. */
3339 || string->from_disp_str
3340 /* C strings cannot have display properties. */
3341 || (string->s && !STRINGP (object)))
3342 {
3343 *disp_prop = 0;
3344 return eob;
3345 }
3346
3347 /* If the character at CHARPOS is where the display string begins,
3348 return CHARPOS. */
3349 pos = make_number (charpos);
3350 if (STRINGP (object))
3351 bufpos = string->bufpos;
3352 else
3353 bufpos = charpos;
3354 tpos = *position;
3355 if (!NILP (spec = Fget_char_property (pos, Qdisplay, object))
3356 && (charpos <= begb
3357 || !EQ (Fget_char_property (make_number (charpos - 1), Qdisplay,
3358 object),
3359 spec))
3360 && (rv = handle_display_spec (NULL, spec, object, Qnil, &tpos, bufpos,
3361 frame_window_p)))
3362 {
3363 if (rv == 2)
3364 *disp_prop = 2;
3365 return charpos;
3366 }
3367
3368 /* Look forward for the first character with a `display' property
3369 that will replace the underlying text when displayed. */
3370 limpos = make_number (lim);
3371 do {
3372 pos = Fnext_single_char_property_change (pos, Qdisplay, object, limpos);
3373 CHARPOS (tpos) = XFASTINT (pos);
3374 if (CHARPOS (tpos) >= lim)
3375 {
3376 *disp_prop = 0;
3377 break;
3378 }
3379 if (STRINGP (object))
3380 BYTEPOS (tpos) = string_char_to_byte (object, CHARPOS (tpos));
3381 else
3382 BYTEPOS (tpos) = CHAR_TO_BYTE (CHARPOS (tpos));
3383 spec = Fget_char_property (pos, Qdisplay, object);
3384 if (!STRINGP (object))
3385 bufpos = CHARPOS (tpos);
3386 } while (NILP (spec)
3387 || !(rv = handle_display_spec (NULL, spec, object, Qnil, &tpos,
3388 bufpos, frame_window_p)));
3389 if (rv == 2)
3390 *disp_prop = 2;
3391
3392 return CHARPOS (tpos);
3393 }
3394
3395 /* Return the character position of the end of the display string that
3396 started at CHARPOS. If there's no display string at CHARPOS,
3397 return -1. A display string is either an overlay with `display'
3398 property whose value is a string or a `display' text property whose
3399 value is a string. */
3400 EMACS_INT
3401 compute_display_string_end (EMACS_INT charpos, struct bidi_string_data *string)
3402 {
3403 /* OBJECT = nil means current buffer. */
3404 Lisp_Object object =
3405 (string && STRINGP (string->lstring)) ? string->lstring : Qnil;
3406 Lisp_Object pos = make_number (charpos);
3407 EMACS_INT eob =
3408 (STRINGP (object) || (string && string->s)) ? string->schars : ZV;
3409
3410 if (charpos >= eob || (string->s && !STRINGP (object)))
3411 return eob;
3412
3413 /* It could happen that the display property or overlay was removed
3414 since we found it in compute_display_string_pos above. One way
3415 this can happen is if JIT font-lock was called (through
3416 handle_fontified_prop), and jit-lock-functions remove text
3417 properties or overlays from the portion of buffer that includes
3418 CHARPOS. Muse mode is known to do that, for example. In this
3419 case, we return -1 to the caller, to signal that no display
3420 string is actually present at CHARPOS. See bidi_fetch_char for
3421 how this is handled.
3422
3423 An alternative would be to never look for display properties past
3424 it->stop_charpos. But neither compute_display_string_pos nor
3425 bidi_fetch_char that calls it know or care where the next
3426 stop_charpos is. */
3427 if (NILP (Fget_char_property (pos, Qdisplay, object)))
3428 return -1;
3429
3430 /* Look forward for the first character where the `display' property
3431 changes. */
3432 pos = Fnext_single_char_property_change (pos, Qdisplay, object, Qnil);
3433
3434 return XFASTINT (pos);
3435 }
3436
3437
3438 \f
3439 /***********************************************************************
3440 Fontification
3441 ***********************************************************************/
3442
3443 /* Handle changes in the `fontified' property of the current buffer by
3444 calling hook functions from Qfontification_functions to fontify
3445 regions of text. */
3446
3447 static enum prop_handled
3448 handle_fontified_prop (struct it *it)
3449 {
3450 Lisp_Object prop, pos;
3451 enum prop_handled handled = HANDLED_NORMALLY;
3452
3453 if (!NILP (Vmemory_full))
3454 return handled;
3455
3456 /* Get the value of the `fontified' property at IT's current buffer
3457 position. (The `fontified' property doesn't have a special
3458 meaning in strings.) If the value is nil, call functions from
3459 Qfontification_functions. */
3460 if (!STRINGP (it->string)
3461 && it->s == NULL
3462 && !NILP (Vfontification_functions)
3463 && !NILP (Vrun_hooks)
3464 && (pos = make_number (IT_CHARPOS (*it)),
3465 prop = Fget_char_property (pos, Qfontified, Qnil),
3466 /* Ignore the special cased nil value always present at EOB since
3467 no amount of fontifying will be able to change it. */
3468 NILP (prop) && IT_CHARPOS (*it) < Z))
3469 {
3470 int count = SPECPDL_INDEX ();
3471 Lisp_Object val;
3472 struct buffer *obuf = current_buffer;
3473 int begv = BEGV, zv = ZV;
3474 int old_clip_changed = current_buffer->clip_changed;
3475
3476 val = Vfontification_functions;
3477 specbind (Qfontification_functions, Qnil);
3478
3479 xassert (it->end_charpos == ZV);
3480
3481 if (!CONSP (val) || EQ (XCAR (val), Qlambda))
3482 safe_call1 (val, pos);
3483 else
3484 {
3485 Lisp_Object fns, fn;
3486 struct gcpro gcpro1, gcpro2;
3487
3488 fns = Qnil;
3489 GCPRO2 (val, fns);
3490
3491 for (; CONSP (val); val = XCDR (val))
3492 {
3493 fn = XCAR (val);
3494
3495 if (EQ (fn, Qt))
3496 {
3497 /* A value of t indicates this hook has a local
3498 binding; it means to run the global binding too.
3499 In a global value, t should not occur. If it
3500 does, we must ignore it to avoid an endless
3501 loop. */
3502 for (fns = Fdefault_value (Qfontification_functions);
3503 CONSP (fns);
3504 fns = XCDR (fns))
3505 {
3506 fn = XCAR (fns);
3507 if (!EQ (fn, Qt))
3508 safe_call1 (fn, pos);
3509 }
3510 }
3511 else
3512 safe_call1 (fn, pos);
3513 }
3514
3515 UNGCPRO;
3516 }
3517
3518 unbind_to (count, Qnil);
3519
3520 /* Fontification functions routinely call `save-restriction'.
3521 Normally, this tags clip_changed, which can confuse redisplay
3522 (see discussion in Bug#6671). Since we don't perform any
3523 special handling of fontification changes in the case where
3524 `save-restriction' isn't called, there's no point doing so in
3525 this case either. So, if the buffer's restrictions are
3526 actually left unchanged, reset clip_changed. */
3527 if (obuf == current_buffer)
3528 {
3529 if (begv == BEGV && zv == ZV)
3530 current_buffer->clip_changed = old_clip_changed;
3531 }
3532 /* There isn't much we can reasonably do to protect against
3533 misbehaving fontification, but here's a fig leaf. */
3534 else if (!NILP (BVAR (obuf, name)))
3535 set_buffer_internal_1 (obuf);
3536
3537 /* The fontification code may have added/removed text.
3538 It could do even a lot worse, but let's at least protect against
3539 the most obvious case where only the text past `pos' gets changed',
3540 as is/was done in grep.el where some escapes sequences are turned
3541 into face properties (bug#7876). */
3542 it->end_charpos = ZV;
3543
3544 /* Return HANDLED_RECOMPUTE_PROPS only if function fontified
3545 something. This avoids an endless loop if they failed to
3546 fontify the text for which reason ever. */
3547 if (!NILP (Fget_char_property (pos, Qfontified, Qnil)))
3548 handled = HANDLED_RECOMPUTE_PROPS;
3549 }
3550
3551 return handled;
3552 }
3553
3554
3555 \f
3556 /***********************************************************************
3557 Faces
3558 ***********************************************************************/
3559
3560 /* Set up iterator IT from face properties at its current position.
3561 Called from handle_stop. */
3562
3563 static enum prop_handled
3564 handle_face_prop (struct it *it)
3565 {
3566 int new_face_id;
3567 EMACS_INT next_stop;
3568
3569 if (!STRINGP (it->string))
3570 {
3571 new_face_id
3572 = face_at_buffer_position (it->w,
3573 IT_CHARPOS (*it),
3574 it->region_beg_charpos,
3575 it->region_end_charpos,
3576 &next_stop,
3577 (IT_CHARPOS (*it)
3578 + TEXT_PROP_DISTANCE_LIMIT),
3579 0, it->base_face_id);
3580
3581 /* Is this a start of a run of characters with box face?
3582 Caveat: this can be called for a freshly initialized
3583 iterator; face_id is -1 in this case. We know that the new
3584 face will not change until limit, i.e. if the new face has a
3585 box, all characters up to limit will have one. But, as
3586 usual, we don't know whether limit is really the end. */
3587 if (new_face_id != it->face_id)
3588 {
3589 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
3590
3591 /* If new face has a box but old face has not, this is
3592 the start of a run of characters with box, i.e. it has
3593 a shadow on the left side. The value of face_id of the
3594 iterator will be -1 if this is the initial call that gets
3595 the face. In this case, we have to look in front of IT's
3596 position and see whether there is a face != new_face_id. */
3597 it->start_of_box_run_p
3598 = (new_face->box != FACE_NO_BOX
3599 && (it->face_id >= 0
3600 || IT_CHARPOS (*it) == BEG
3601 || new_face_id != face_before_it_pos (it)));
3602 it->face_box_p = new_face->box != FACE_NO_BOX;
3603 }
3604 }
3605 else
3606 {
3607 int base_face_id;
3608 EMACS_INT bufpos;
3609 int i;
3610 Lisp_Object from_overlay
3611 = (it->current.overlay_string_index >= 0
3612 ? it->string_overlays[it->current.overlay_string_index]
3613 : Qnil);
3614
3615 /* See if we got to this string directly or indirectly from
3616 an overlay property. That includes the before-string or
3617 after-string of an overlay, strings in display properties
3618 provided by an overlay, their text properties, etc.
3619
3620 FROM_OVERLAY is the overlay that brought us here, or nil if none. */
3621 if (! NILP (from_overlay))
3622 for (i = it->sp - 1; i >= 0; i--)
3623 {
3624 if (it->stack[i].current.overlay_string_index >= 0)
3625 from_overlay
3626 = it->string_overlays[it->stack[i].current.overlay_string_index];
3627 else if (! NILP (it->stack[i].from_overlay))
3628 from_overlay = it->stack[i].from_overlay;
3629
3630 if (!NILP (from_overlay))
3631 break;
3632 }
3633
3634 if (! NILP (from_overlay))
3635 {
3636 bufpos = IT_CHARPOS (*it);
3637 /* For a string from an overlay, the base face depends
3638 only on text properties and ignores overlays. */
3639 base_face_id
3640 = face_for_overlay_string (it->w,
3641 IT_CHARPOS (*it),
3642 it->region_beg_charpos,
3643 it->region_end_charpos,
3644 &next_stop,
3645 (IT_CHARPOS (*it)
3646 + TEXT_PROP_DISTANCE_LIMIT),
3647 0,
3648 from_overlay);
3649 }
3650 else
3651 {
3652 bufpos = 0;
3653
3654 /* For strings from a `display' property, use the face at
3655 IT's current buffer position as the base face to merge
3656 with, so that overlay strings appear in the same face as
3657 surrounding text, unless they specify their own
3658 faces. */
3659 base_face_id = underlying_face_id (it);
3660 }
3661
3662 new_face_id = face_at_string_position (it->w,
3663 it->string,
3664 IT_STRING_CHARPOS (*it),
3665 bufpos,
3666 it->region_beg_charpos,
3667 it->region_end_charpos,
3668 &next_stop,
3669 base_face_id, 0);
3670
3671 /* Is this a start of a run of characters with box? Caveat:
3672 this can be called for a freshly allocated iterator; face_id
3673 is -1 is this case. We know that the new face will not
3674 change until the next check pos, i.e. if the new face has a
3675 box, all characters up to that position will have a
3676 box. But, as usual, we don't know whether that position
3677 is really the end. */
3678 if (new_face_id != it->face_id)
3679 {
3680 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
3681 struct face *old_face = FACE_FROM_ID (it->f, it->face_id);
3682
3683 /* If new face has a box but old face hasn't, this is the
3684 start of a run of characters with box, i.e. it has a
3685 shadow on the left side. */
3686 it->start_of_box_run_p
3687 = new_face->box && (old_face == NULL || !old_face->box);
3688 it->face_box_p = new_face->box != FACE_NO_BOX;
3689 }
3690 }
3691
3692 it->face_id = new_face_id;
3693 return HANDLED_NORMALLY;
3694 }
3695
3696
3697 /* Return the ID of the face ``underlying'' IT's current position,
3698 which is in a string. If the iterator is associated with a
3699 buffer, return the face at IT's current buffer position.
3700 Otherwise, use the iterator's base_face_id. */
3701
3702 static int
3703 underlying_face_id (struct it *it)
3704 {
3705 int face_id = it->base_face_id, i;
3706
3707 xassert (STRINGP (it->string));
3708
3709 for (i = it->sp - 1; i >= 0; --i)
3710 if (NILP (it->stack[i].string))
3711 face_id = it->stack[i].face_id;
3712
3713 return face_id;
3714 }
3715
3716
3717 /* Compute the face one character before or after the current position
3718 of IT, in the visual order. BEFORE_P non-zero means get the face
3719 in front (to the left in L2R paragraphs, to the right in R2L
3720 paragraphs) of IT's screen position. Value is the ID of the face. */
3721
3722 static int
3723 face_before_or_after_it_pos (struct it *it, int before_p)
3724 {
3725 int face_id, limit;
3726 EMACS_INT next_check_charpos;
3727 struct it it_copy;
3728 void *it_copy_data = NULL;
3729
3730 xassert (it->s == NULL);
3731
3732 if (STRINGP (it->string))
3733 {
3734 EMACS_INT bufpos, charpos;
3735 int base_face_id;
3736
3737 /* No face change past the end of the string (for the case
3738 we are padding with spaces). No face change before the
3739 string start. */
3740 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string)
3741 || (IT_STRING_CHARPOS (*it) == 0 && before_p))
3742 return it->face_id;
3743
3744 if (!it->bidi_p)
3745 {
3746 /* Set charpos to the position before or after IT's current
3747 position, in the logical order, which in the non-bidi
3748 case is the same as the visual order. */
3749 if (before_p)
3750 charpos = IT_STRING_CHARPOS (*it) - 1;
3751 else if (it->what == IT_COMPOSITION)
3752 /* For composition, we must check the character after the
3753 composition. */
3754 charpos = IT_STRING_CHARPOS (*it) + it->cmp_it.nchars;
3755 else
3756 charpos = IT_STRING_CHARPOS (*it) + 1;
3757 }
3758 else
3759 {
3760 if (before_p)
3761 {
3762 /* With bidi iteration, the character before the current
3763 in the visual order cannot be found by simple
3764 iteration, because "reverse" reordering is not
3765 supported. Instead, we need to use the move_it_*
3766 family of functions. */
3767 /* Ignore face changes before the first visible
3768 character on this display line. */
3769 if (it->current_x <= it->first_visible_x)
3770 return it->face_id;
3771 SAVE_IT (it_copy, *it, it_copy_data);
3772 /* Implementation note: Since move_it_in_display_line
3773 works in the iterator geometry, and thinks the first
3774 character is always the leftmost, even in R2L lines,
3775 we don't need to distinguish between the R2L and L2R
3776 cases here. */
3777 move_it_in_display_line (&it_copy, SCHARS (it_copy.string),
3778 it_copy.current_x - 1, MOVE_TO_X);
3779 charpos = IT_STRING_CHARPOS (it_copy);
3780 RESTORE_IT (it, it, it_copy_data);
3781 }
3782 else
3783 {
3784 /* Set charpos to the string position of the character
3785 that comes after IT's current position in the visual
3786 order. */
3787 int n = (it->what == IT_COMPOSITION ? it->cmp_it.nchars : 1);
3788
3789 it_copy = *it;
3790 while (n--)
3791 bidi_move_to_visually_next (&it_copy.bidi_it);
3792
3793 charpos = it_copy.bidi_it.charpos;
3794 }
3795 }
3796 xassert (0 <= charpos && charpos <= SCHARS (it->string));
3797
3798 if (it->current.overlay_string_index >= 0)
3799 bufpos = IT_CHARPOS (*it);
3800 else
3801 bufpos = 0;
3802
3803 base_face_id = underlying_face_id (it);
3804
3805 /* Get the face for ASCII, or unibyte. */
3806 face_id = face_at_string_position (it->w,
3807 it->string,
3808 charpos,
3809 bufpos,
3810 it->region_beg_charpos,
3811 it->region_end_charpos,
3812 &next_check_charpos,
3813 base_face_id, 0);
3814
3815 /* Correct the face for charsets different from ASCII. Do it
3816 for the multibyte case only. The face returned above is
3817 suitable for unibyte text if IT->string is unibyte. */
3818 if (STRING_MULTIBYTE (it->string))
3819 {
3820 struct text_pos pos1 = string_pos (charpos, it->string);
3821 const unsigned char *p = SDATA (it->string) + BYTEPOS (pos1);
3822 int c, len;
3823 struct face *face = FACE_FROM_ID (it->f, face_id);
3824
3825 c = string_char_and_length (p, &len);
3826 face_id = FACE_FOR_CHAR (it->f, face, c, charpos, it->string);
3827 }
3828 }
3829 else
3830 {
3831 struct text_pos pos;
3832
3833 if ((IT_CHARPOS (*it) >= ZV && !before_p)
3834 || (IT_CHARPOS (*it) <= BEGV && before_p))
3835 return it->face_id;
3836
3837 limit = IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT;
3838 pos = it->current.pos;
3839
3840 if (!it->bidi_p)
3841 {
3842 if (before_p)
3843 DEC_TEXT_POS (pos, it->multibyte_p);
3844 else
3845 {
3846 if (it->what == IT_COMPOSITION)
3847 {
3848 /* For composition, we must check the position after
3849 the composition. */
3850 pos.charpos += it->cmp_it.nchars;
3851 pos.bytepos += it->len;
3852 }
3853 else
3854 INC_TEXT_POS (pos, it->multibyte_p);
3855 }
3856 }
3857 else
3858 {
3859 if (before_p)
3860 {
3861 /* With bidi iteration, the character before the current
3862 in the visual order cannot be found by simple
3863 iteration, because "reverse" reordering is not
3864 supported. Instead, we need to use the move_it_*
3865 family of functions. */
3866 /* Ignore face changes before the first visible
3867 character on this display line. */
3868 if (it->current_x <= it->first_visible_x)
3869 return it->face_id;
3870 SAVE_IT (it_copy, *it, it_copy_data);
3871 /* Implementation note: Since move_it_in_display_line
3872 works in the iterator geometry, and thinks the first
3873 character is always the leftmost, even in R2L lines,
3874 we don't need to distinguish between the R2L and L2R
3875 cases here. */
3876 move_it_in_display_line (&it_copy, ZV,
3877 it_copy.current_x - 1, MOVE_TO_X);
3878 pos = it_copy.current.pos;
3879 RESTORE_IT (it, it, it_copy_data);
3880 }
3881 else
3882 {
3883 /* Set charpos to the buffer position of the character
3884 that comes after IT's current position in the visual
3885 order. */
3886 int n = (it->what == IT_COMPOSITION ? it->cmp_it.nchars : 1);
3887
3888 it_copy = *it;
3889 while (n--)
3890 bidi_move_to_visually_next (&it_copy.bidi_it);
3891
3892 SET_TEXT_POS (pos,
3893 it_copy.bidi_it.charpos, it_copy.bidi_it.bytepos);
3894 }
3895 }
3896 xassert (BEGV <= CHARPOS (pos) && CHARPOS (pos) <= ZV);
3897
3898 /* Determine face for CHARSET_ASCII, or unibyte. */
3899 face_id = face_at_buffer_position (it->w,
3900 CHARPOS (pos),
3901 it->region_beg_charpos,
3902 it->region_end_charpos,
3903 &next_check_charpos,
3904 limit, 0, -1);
3905
3906 /* Correct the face for charsets different from ASCII. Do it
3907 for the multibyte case only. The face returned above is
3908 suitable for unibyte text if current_buffer is unibyte. */
3909 if (it->multibyte_p)
3910 {
3911 int c = FETCH_MULTIBYTE_CHAR (BYTEPOS (pos));
3912 struct face *face = FACE_FROM_ID (it->f, face_id);
3913 face_id = FACE_FOR_CHAR (it->f, face, c, CHARPOS (pos), Qnil);
3914 }
3915 }
3916
3917 return face_id;
3918 }
3919
3920
3921 \f
3922 /***********************************************************************
3923 Invisible text
3924 ***********************************************************************/
3925
3926 /* Set up iterator IT from invisible properties at its current
3927 position. Called from handle_stop. */
3928
3929 static enum prop_handled
3930 handle_invisible_prop (struct it *it)
3931 {
3932 enum prop_handled handled = HANDLED_NORMALLY;
3933
3934 if (STRINGP (it->string))
3935 {
3936 Lisp_Object prop, end_charpos, limit, charpos;
3937
3938 /* Get the value of the invisible text property at the
3939 current position. Value will be nil if there is no such
3940 property. */
3941 charpos = make_number (IT_STRING_CHARPOS (*it));
3942 prop = Fget_text_property (charpos, Qinvisible, it->string);
3943
3944 if (!NILP (prop)
3945 && IT_STRING_CHARPOS (*it) < it->end_charpos)
3946 {
3947 EMACS_INT endpos;
3948
3949 handled = HANDLED_RECOMPUTE_PROPS;
3950
3951 /* Get the position at which the next change of the
3952 invisible text property can be found in IT->string.
3953 Value will be nil if the property value is the same for
3954 all the rest of IT->string. */
3955 XSETINT (limit, SCHARS (it->string));
3956 end_charpos = Fnext_single_property_change (charpos, Qinvisible,
3957 it->string, limit);
3958
3959 /* Text at current position is invisible. The next
3960 change in the property is at position end_charpos.
3961 Move IT's current position to that position. */
3962 if (INTEGERP (end_charpos)
3963 && (endpos = XFASTINT (end_charpos)) < XFASTINT (limit))
3964 {
3965 struct text_pos old;
3966 EMACS_INT oldpos;
3967
3968 old = it->current.string_pos;
3969 oldpos = CHARPOS (old);
3970 if (it->bidi_p)
3971 {
3972 if (it->bidi_it.first_elt
3973 && it->bidi_it.charpos < SCHARS (it->string))
3974 bidi_paragraph_init (it->paragraph_embedding,
3975 &it->bidi_it, 1);
3976 /* Bidi-iterate out of the invisible text. */
3977 do
3978 {
3979 bidi_move_to_visually_next (&it->bidi_it);
3980 }
3981 while (oldpos <= it->bidi_it.charpos
3982 && it->bidi_it.charpos < endpos);
3983
3984 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
3985 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
3986 if (IT_CHARPOS (*it) >= endpos)
3987 it->prev_stop = endpos;
3988 }
3989 else
3990 {
3991 IT_STRING_CHARPOS (*it) = XFASTINT (end_charpos);
3992 compute_string_pos (&it->current.string_pos, old, it->string);
3993 }
3994 }
3995 else
3996 {
3997 /* The rest of the string is invisible. If this is an
3998 overlay string, proceed with the next overlay string
3999 or whatever comes and return a character from there. */
4000 if (it->current.overlay_string_index >= 0)
4001 {
4002 next_overlay_string (it);
4003 /* Don't check for overlay strings when we just
4004 finished processing them. */
4005 handled = HANDLED_OVERLAY_STRING_CONSUMED;
4006 }
4007 else
4008 {
4009 IT_STRING_CHARPOS (*it) = SCHARS (it->string);
4010 IT_STRING_BYTEPOS (*it) = SBYTES (it->string);
4011 }
4012 }
4013 }
4014 }
4015 else
4016 {
4017 int invis_p;
4018 EMACS_INT newpos, next_stop, start_charpos, tem;
4019 Lisp_Object pos, prop, overlay;
4020
4021 /* First of all, is there invisible text at this position? */
4022 tem = start_charpos = IT_CHARPOS (*it);
4023 pos = make_number (tem);
4024 prop = get_char_property_and_overlay (pos, Qinvisible, it->window,
4025 &overlay);
4026 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
4027
4028 /* If we are on invisible text, skip over it. */
4029 if (invis_p && start_charpos < it->end_charpos)
4030 {
4031 /* Record whether we have to display an ellipsis for the
4032 invisible text. */
4033 int display_ellipsis_p = invis_p == 2;
4034
4035 handled = HANDLED_RECOMPUTE_PROPS;
4036
4037 /* Loop skipping over invisible text. The loop is left at
4038 ZV or with IT on the first char being visible again. */
4039 do
4040 {
4041 /* Try to skip some invisible text. Return value is the
4042 position reached which can be equal to where we start
4043 if there is nothing invisible there. This skips both
4044 over invisible text properties and overlays with
4045 invisible property. */
4046 newpos = skip_invisible (tem, &next_stop, ZV, it->window);
4047
4048 /* If we skipped nothing at all we weren't at invisible
4049 text in the first place. If everything to the end of
4050 the buffer was skipped, end the loop. */
4051 if (newpos == tem || newpos >= ZV)
4052 invis_p = 0;
4053 else
4054 {
4055 /* We skipped some characters but not necessarily
4056 all there are. Check if we ended up on visible
4057 text. Fget_char_property returns the property of
4058 the char before the given position, i.e. if we
4059 get invis_p = 0, this means that the char at
4060 newpos is visible. */
4061 pos = make_number (newpos);
4062 prop = Fget_char_property (pos, Qinvisible, it->window);
4063 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
4064 }
4065
4066 /* If we ended up on invisible text, proceed to
4067 skip starting with next_stop. */
4068 if (invis_p)
4069 tem = next_stop;
4070
4071 /* If there are adjacent invisible texts, don't lose the
4072 second one's ellipsis. */
4073 if (invis_p == 2)
4074 display_ellipsis_p = 1;
4075 }
4076 while (invis_p);
4077
4078 /* The position newpos is now either ZV or on visible text. */
4079 if (it->bidi_p && newpos < ZV)
4080 {
4081 EMACS_INT bpos = CHAR_TO_BYTE (newpos);
4082
4083 if (FETCH_BYTE (bpos) == '\n'
4084 || (newpos > BEGV && FETCH_BYTE (bpos - 1) == '\n'))
4085 {
4086 /* If the invisible text ends on a newline or the
4087 character after a newline, we can avoid the
4088 costly, character by character, bidi iteration to
4089 newpos, and instead simply reseat the iterator
4090 there. That's because all bidi reordering
4091 information is tossed at the newline. This is a
4092 big win for modes that hide complete lines, like
4093 Outline, Org, etc. (Implementation note: the
4094 call to reseat_1 is necessary, because it signals
4095 to the bidi iterator that it needs to reinit its
4096 internal information when the next element for
4097 display is requested. */
4098 struct text_pos tpos;
4099
4100 SET_TEXT_POS (tpos, newpos, bpos);
4101 reseat_1 (it, tpos, 0);
4102 }
4103 else /* Must use the slow method. */
4104 {
4105 /* With bidi iteration, the region of invisible text
4106 could start and/or end in the middle of a
4107 non-base embedding level. Therefore, we need to
4108 skip invisible text using the bidi iterator,
4109 starting at IT's current position, until we find
4110 ourselves outside the invisible text. Skipping
4111 invisible text _after_ bidi iteration avoids
4112 affecting the visual order of the displayed text
4113 when invisible properties are added or
4114 removed. */
4115 if (it->bidi_it.first_elt && it->bidi_it.charpos < ZV)
4116 {
4117 /* If we were `reseat'ed to a new paragraph,
4118 determine the paragraph base direction. We
4119 need to do it now because
4120 next_element_from_buffer may not have a
4121 chance to do it, if we are going to skip any
4122 text at the beginning, which resets the
4123 FIRST_ELT flag. */
4124 bidi_paragraph_init (it->paragraph_embedding,
4125 &it->bidi_it, 1);
4126 }
4127 do
4128 {
4129 bidi_move_to_visually_next (&it->bidi_it);
4130 }
4131 while (it->stop_charpos <= it->bidi_it.charpos
4132 && it->bidi_it.charpos < newpos);
4133 IT_CHARPOS (*it) = it->bidi_it.charpos;
4134 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
4135 /* If we overstepped NEWPOS, record its position in
4136 the iterator, so that we skip invisible text if
4137 later the bidi iteration lands us in the
4138 invisible region again. */
4139 if (IT_CHARPOS (*it) >= newpos)
4140 it->prev_stop = newpos;
4141 }
4142 }
4143 else
4144 {
4145 IT_CHARPOS (*it) = newpos;
4146 IT_BYTEPOS (*it) = CHAR_TO_BYTE (newpos);
4147 }
4148
4149 /* If there are before-strings at the start of invisible
4150 text, and the text is invisible because of a text
4151 property, arrange to show before-strings because 20.x did
4152 it that way. (If the text is invisible because of an
4153 overlay property instead of a text property, this is
4154 already handled in the overlay code.) */
4155 if (NILP (overlay)
4156 && get_overlay_strings (it, it->stop_charpos))
4157 {
4158 handled = HANDLED_RECOMPUTE_PROPS;
4159 it->stack[it->sp - 1].display_ellipsis_p = display_ellipsis_p;
4160 }
4161 else if (display_ellipsis_p)
4162 {
4163 /* Make sure that the glyphs of the ellipsis will get
4164 correct `charpos' values. If we would not update
4165 it->position here, the glyphs would belong to the
4166 last visible character _before_ the invisible
4167 text, which confuses `set_cursor_from_row'.
4168
4169 We use the last invisible position instead of the
4170 first because this way the cursor is always drawn on
4171 the first "." of the ellipsis, whenever PT is inside
4172 the invisible text. Otherwise the cursor would be
4173 placed _after_ the ellipsis when the point is after the
4174 first invisible character. */
4175 if (!STRINGP (it->object))
4176 {
4177 it->position.charpos = newpos - 1;
4178 it->position.bytepos = CHAR_TO_BYTE (it->position.charpos);
4179 }
4180 it->ellipsis_p = 1;
4181 /* Let the ellipsis display before
4182 considering any properties of the following char.
4183 Fixes jasonr@gnu.org 01 Oct 07 bug. */
4184 handled = HANDLED_RETURN;
4185 }
4186 }
4187 }
4188
4189 return handled;
4190 }
4191
4192
4193 /* Make iterator IT return `...' next.
4194 Replaces LEN characters from buffer. */
4195
4196 static void
4197 setup_for_ellipsis (struct it *it, int len)
4198 {
4199 /* Use the display table definition for `...'. Invalid glyphs
4200 will be handled by the method returning elements from dpvec. */
4201 if (it->dp && VECTORP (DISP_INVIS_VECTOR (it->dp)))
4202 {
4203 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
4204 it->dpvec = v->contents;
4205 it->dpend = v->contents + v->header.size;
4206 }
4207 else
4208 {
4209 /* Default `...'. */
4210 it->dpvec = default_invis_vector;
4211 it->dpend = default_invis_vector + 3;
4212 }
4213
4214 it->dpvec_char_len = len;
4215 it->current.dpvec_index = 0;
4216 it->dpvec_face_id = -1;
4217
4218 /* Remember the current face id in case glyphs specify faces.
4219 IT's face is restored in set_iterator_to_next.
4220 saved_face_id was set to preceding char's face in handle_stop. */
4221 if (it->saved_face_id < 0 || it->saved_face_id != it->face_id)
4222 it->saved_face_id = it->face_id = DEFAULT_FACE_ID;
4223
4224 it->method = GET_FROM_DISPLAY_VECTOR;
4225 it->ellipsis_p = 1;
4226 }
4227
4228
4229 \f
4230 /***********************************************************************
4231 'display' property
4232 ***********************************************************************/
4233
4234 /* Set up iterator IT from `display' property at its current position.
4235 Called from handle_stop.
4236 We return HANDLED_RETURN if some part of the display property
4237 overrides the display of the buffer text itself.
4238 Otherwise we return HANDLED_NORMALLY. */
4239
4240 static enum prop_handled
4241 handle_display_prop (struct it *it)
4242 {
4243 Lisp_Object propval, object, overlay;
4244 struct text_pos *position;
4245 EMACS_INT bufpos;
4246 /* Nonzero if some property replaces the display of the text itself. */
4247 int display_replaced_p = 0;
4248
4249 if (STRINGP (it->string))
4250 {
4251 object = it->string;
4252 position = &it->current.string_pos;
4253 bufpos = CHARPOS (it->current.pos);
4254 }
4255 else
4256 {
4257 XSETWINDOW (object, it->w);
4258 position = &it->current.pos;
4259 bufpos = CHARPOS (*position);
4260 }
4261
4262 /* Reset those iterator values set from display property values. */
4263 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
4264 it->space_width = Qnil;
4265 it->font_height = Qnil;
4266 it->voffset = 0;
4267
4268 /* We don't support recursive `display' properties, i.e. string
4269 values that have a string `display' property, that have a string
4270 `display' property etc. */
4271 if (!it->string_from_display_prop_p)
4272 it->area = TEXT_AREA;
4273
4274 propval = get_char_property_and_overlay (make_number (position->charpos),
4275 Qdisplay, object, &overlay);
4276 if (NILP (propval))
4277 return HANDLED_NORMALLY;
4278 /* Now OVERLAY is the overlay that gave us this property, or nil
4279 if it was a text property. */
4280
4281 if (!STRINGP (it->string))
4282 object = it->w->buffer;
4283
4284 display_replaced_p = handle_display_spec (it, propval, object, overlay,
4285 position, bufpos,
4286 FRAME_WINDOW_P (it->f));
4287
4288 return display_replaced_p ? HANDLED_RETURN : HANDLED_NORMALLY;
4289 }
4290
4291 /* Subroutine of handle_display_prop. Returns non-zero if the display
4292 specification in SPEC is a replacing specification, i.e. it would
4293 replace the text covered by `display' property with something else,
4294 such as an image or a display string. If SPEC includes any kind or
4295 `(space ...) specification, the value is 2; this is used by
4296 compute_display_string_pos, which see.
4297
4298 See handle_single_display_spec for documentation of arguments.
4299 frame_window_p is non-zero if the window being redisplayed is on a
4300 GUI frame; this argument is used only if IT is NULL, see below.
4301
4302 IT can be NULL, if this is called by the bidi reordering code
4303 through compute_display_string_pos, which see. In that case, this
4304 function only examines SPEC, but does not otherwise "handle" it, in
4305 the sense that it doesn't set up members of IT from the display
4306 spec. */
4307 static int
4308 handle_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
4309 Lisp_Object overlay, struct text_pos *position,
4310 EMACS_INT bufpos, int frame_window_p)
4311 {
4312 int replacing_p = 0;
4313 int rv;
4314
4315 if (CONSP (spec)
4316 /* Simple specerties. */
4317 && !EQ (XCAR (spec), Qimage)
4318 && !EQ (XCAR (spec), Qspace)
4319 && !EQ (XCAR (spec), Qwhen)
4320 && !EQ (XCAR (spec), Qslice)
4321 && !EQ (XCAR (spec), Qspace_width)
4322 && !EQ (XCAR (spec), Qheight)
4323 && !EQ (XCAR (spec), Qraise)
4324 /* Marginal area specifications. */
4325 && !(CONSP (XCAR (spec)) && EQ (XCAR (XCAR (spec)), Qmargin))
4326 && !EQ (XCAR (spec), Qleft_fringe)
4327 && !EQ (XCAR (spec), Qright_fringe)
4328 && !NILP (XCAR (spec)))
4329 {
4330 for (; CONSP (spec); spec = XCDR (spec))
4331 {
4332 if ((rv = handle_single_display_spec (it, XCAR (spec), object,
4333 overlay, position, bufpos,
4334 replacing_p, frame_window_p)))
4335 {
4336 replacing_p = rv;
4337 /* If some text in a string is replaced, `position' no
4338 longer points to the position of `object'. */
4339 if (!it || STRINGP (object))
4340 break;
4341 }
4342 }
4343 }
4344 else if (VECTORP (spec))
4345 {
4346 int i;
4347 for (i = 0; i < ASIZE (spec); ++i)
4348 if ((rv = handle_single_display_spec (it, AREF (spec, i), object,
4349 overlay, position, bufpos,
4350 replacing_p, frame_window_p)))
4351 {
4352 replacing_p = rv;
4353 /* If some text in a string is replaced, `position' no
4354 longer points to the position of `object'. */
4355 if (!it || STRINGP (object))
4356 break;
4357 }
4358 }
4359 else
4360 {
4361 if ((rv = handle_single_display_spec (it, spec, object, overlay,
4362 position, bufpos, 0,
4363 frame_window_p)))
4364 replacing_p = rv;
4365 }
4366
4367 return replacing_p;
4368 }
4369
4370 /* Value is the position of the end of the `display' property starting
4371 at START_POS in OBJECT. */
4372
4373 static struct text_pos
4374 display_prop_end (struct it *it, Lisp_Object object, struct text_pos start_pos)
4375 {
4376 Lisp_Object end;
4377 struct text_pos end_pos;
4378
4379 end = Fnext_single_char_property_change (make_number (CHARPOS (start_pos)),
4380 Qdisplay, object, Qnil);
4381 CHARPOS (end_pos) = XFASTINT (end);
4382 if (STRINGP (object))
4383 compute_string_pos (&end_pos, start_pos, it->string);
4384 else
4385 BYTEPOS (end_pos) = CHAR_TO_BYTE (XFASTINT (end));
4386
4387 return end_pos;
4388 }
4389
4390
4391 /* Set up IT from a single `display' property specification SPEC. OBJECT
4392 is the object in which the `display' property was found. *POSITION
4393 is the position in OBJECT at which the `display' property was found.
4394 BUFPOS is the buffer position of OBJECT (different from POSITION if
4395 OBJECT is not a buffer). DISPLAY_REPLACED_P non-zero means that we
4396 previously saw a display specification which already replaced text
4397 display with something else, for example an image; we ignore such
4398 properties after the first one has been processed.
4399
4400 OVERLAY is the overlay this `display' property came from,
4401 or nil if it was a text property.
4402
4403 If SPEC is a `space' or `image' specification, and in some other
4404 cases too, set *POSITION to the position where the `display'
4405 property ends.
4406
4407 If IT is NULL, only examine the property specification in SPEC, but
4408 don't set up IT. In that case, FRAME_WINDOW_P non-zero means SPEC
4409 is intended to be displayed in a window on a GUI frame.
4410
4411 Value is non-zero if something was found which replaces the display
4412 of buffer or string text. */
4413
4414 static int
4415 handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
4416 Lisp_Object overlay, struct text_pos *position,
4417 EMACS_INT bufpos, int display_replaced_p,
4418 int frame_window_p)
4419 {
4420 Lisp_Object form;
4421 Lisp_Object location, value;
4422 struct text_pos start_pos = *position;
4423 int valid_p;
4424
4425 /* If SPEC is a list of the form `(when FORM . VALUE)', evaluate FORM.
4426 If the result is non-nil, use VALUE instead of SPEC. */
4427 form = Qt;
4428 if (CONSP (spec) && EQ (XCAR (spec), Qwhen))
4429 {
4430 spec = XCDR (spec);
4431 if (!CONSP (spec))
4432 return 0;
4433 form = XCAR (spec);
4434 spec = XCDR (spec);
4435 }
4436
4437 if (!NILP (form) && !EQ (form, Qt))
4438 {
4439 int count = SPECPDL_INDEX ();
4440 struct gcpro gcpro1;
4441
4442 /* Bind `object' to the object having the `display' property, a
4443 buffer or string. Bind `position' to the position in the
4444 object where the property was found, and `buffer-position'
4445 to the current position in the buffer. */
4446
4447 if (NILP (object))
4448 XSETBUFFER (object, current_buffer);
4449 specbind (Qobject, object);
4450 specbind (Qposition, make_number (CHARPOS (*position)));
4451 specbind (Qbuffer_position, make_number (bufpos));
4452 GCPRO1 (form);
4453 form = safe_eval (form);
4454 UNGCPRO;
4455 unbind_to (count, Qnil);
4456 }
4457
4458 if (NILP (form))
4459 return 0;
4460
4461 /* Handle `(height HEIGHT)' specifications. */
4462 if (CONSP (spec)
4463 && EQ (XCAR (spec), Qheight)
4464 && CONSP (XCDR (spec)))
4465 {
4466 if (it)
4467 {
4468 if (!FRAME_WINDOW_P (it->f))
4469 return 0;
4470
4471 it->font_height = XCAR (XCDR (spec));
4472 if (!NILP (it->font_height))
4473 {
4474 struct face *face = FACE_FROM_ID (it->f, it->face_id);
4475 int new_height = -1;
4476
4477 if (CONSP (it->font_height)
4478 && (EQ (XCAR (it->font_height), Qplus)
4479 || EQ (XCAR (it->font_height), Qminus))
4480 && CONSP (XCDR (it->font_height))
4481 && INTEGERP (XCAR (XCDR (it->font_height))))
4482 {
4483 /* `(+ N)' or `(- N)' where N is an integer. */
4484 int steps = XINT (XCAR (XCDR (it->font_height)));
4485 if (EQ (XCAR (it->font_height), Qplus))
4486 steps = - steps;
4487 it->face_id = smaller_face (it->f, it->face_id, steps);
4488 }
4489 else if (FUNCTIONP (it->font_height))
4490 {
4491 /* Call function with current height as argument.
4492 Value is the new height. */
4493 Lisp_Object height;
4494 height = safe_call1 (it->font_height,
4495 face->lface[LFACE_HEIGHT_INDEX]);
4496 if (NUMBERP (height))
4497 new_height = XFLOATINT (height);
4498 }
4499 else if (NUMBERP (it->font_height))
4500 {
4501 /* Value is a multiple of the canonical char height. */
4502 struct face *f;
4503
4504 f = FACE_FROM_ID (it->f,
4505 lookup_basic_face (it->f, DEFAULT_FACE_ID));
4506 new_height = (XFLOATINT (it->font_height)
4507 * XINT (f->lface[LFACE_HEIGHT_INDEX]));
4508 }
4509 else
4510 {
4511 /* Evaluate IT->font_height with `height' bound to the
4512 current specified height to get the new height. */
4513 int count = SPECPDL_INDEX ();
4514
4515 specbind (Qheight, face->lface[LFACE_HEIGHT_INDEX]);
4516 value = safe_eval (it->font_height);
4517 unbind_to (count, Qnil);
4518
4519 if (NUMBERP (value))
4520 new_height = XFLOATINT (value);
4521 }
4522
4523 if (new_height > 0)
4524 it->face_id = face_with_height (it->f, it->face_id, new_height);
4525 }
4526 }
4527
4528 return 0;
4529 }
4530
4531 /* Handle `(space-width WIDTH)'. */
4532 if (CONSP (spec)
4533 && EQ (XCAR (spec), Qspace_width)
4534 && CONSP (XCDR (spec)))
4535 {
4536 if (it)
4537 {
4538 if (!FRAME_WINDOW_P (it->f))
4539 return 0;
4540
4541 value = XCAR (XCDR (spec));
4542 if (NUMBERP (value) && XFLOATINT (value) > 0)
4543 it->space_width = value;
4544 }
4545
4546 return 0;
4547 }
4548
4549 /* Handle `(slice X Y WIDTH HEIGHT)'. */
4550 if (CONSP (spec)
4551 && EQ (XCAR (spec), Qslice))
4552 {
4553 Lisp_Object tem;
4554
4555 if (it)
4556 {
4557 if (!FRAME_WINDOW_P (it->f))
4558 return 0;
4559
4560 if (tem = XCDR (spec), CONSP (tem))
4561 {
4562 it->slice.x = XCAR (tem);
4563 if (tem = XCDR (tem), CONSP (tem))
4564 {
4565 it->slice.y = XCAR (tem);
4566 if (tem = XCDR (tem), CONSP (tem))
4567 {
4568 it->slice.width = XCAR (tem);
4569 if (tem = XCDR (tem), CONSP (tem))
4570 it->slice.height = XCAR (tem);
4571 }
4572 }
4573 }
4574 }
4575
4576 return 0;
4577 }
4578
4579 /* Handle `(raise FACTOR)'. */
4580 if (CONSP (spec)
4581 && EQ (XCAR (spec), Qraise)
4582 && CONSP (XCDR (spec)))
4583 {
4584 if (it)
4585 {
4586 if (!FRAME_WINDOW_P (it->f))
4587 return 0;
4588
4589 #ifdef HAVE_WINDOW_SYSTEM
4590 value = XCAR (XCDR (spec));
4591 if (NUMBERP (value))
4592 {
4593 struct face *face = FACE_FROM_ID (it->f, it->face_id);
4594 it->voffset = - (XFLOATINT (value)
4595 * (FONT_HEIGHT (face->font)));
4596 }
4597 #endif /* HAVE_WINDOW_SYSTEM */
4598 }
4599
4600 return 0;
4601 }
4602
4603 /* Don't handle the other kinds of display specifications
4604 inside a string that we got from a `display' property. */
4605 if (it && it->string_from_display_prop_p)
4606 return 0;
4607
4608 /* Characters having this form of property are not displayed, so
4609 we have to find the end of the property. */
4610 if (it)
4611 {
4612 start_pos = *position;
4613 *position = display_prop_end (it, object, start_pos);
4614 }
4615 value = Qnil;
4616
4617 /* Stop the scan at that end position--we assume that all
4618 text properties change there. */
4619 if (it)
4620 it->stop_charpos = position->charpos;
4621
4622 /* Handle `(left-fringe BITMAP [FACE])'
4623 and `(right-fringe BITMAP [FACE])'. */
4624 if (CONSP (spec)
4625 && (EQ (XCAR (spec), Qleft_fringe)
4626 || EQ (XCAR (spec), Qright_fringe))
4627 && CONSP (XCDR (spec)))
4628 {
4629 int fringe_bitmap;
4630
4631 if (it)
4632 {
4633 if (!FRAME_WINDOW_P (it->f))
4634 /* If we return here, POSITION has been advanced
4635 across the text with this property. */
4636 return 0;
4637 }
4638 else if (!frame_window_p)
4639 return 0;
4640
4641 #ifdef HAVE_WINDOW_SYSTEM
4642 value = XCAR (XCDR (spec));
4643 if (!SYMBOLP (value)
4644 || !(fringe_bitmap = lookup_fringe_bitmap (value)))
4645 /* If we return here, POSITION has been advanced
4646 across the text with this property. */
4647 return 0;
4648
4649 if (it)
4650 {
4651 int face_id = lookup_basic_face (it->f, DEFAULT_FACE_ID);;
4652
4653 if (CONSP (XCDR (XCDR (spec))))
4654 {
4655 Lisp_Object face_name = XCAR (XCDR (XCDR (spec)));
4656 int face_id2 = lookup_derived_face (it->f, face_name,
4657 FRINGE_FACE_ID, 0);
4658 if (face_id2 >= 0)
4659 face_id = face_id2;
4660 }
4661
4662 /* Save current settings of IT so that we can restore them
4663 when we are finished with the glyph property value. */
4664 push_it (it, position);
4665
4666 it->area = TEXT_AREA;
4667 it->what = IT_IMAGE;
4668 it->image_id = -1; /* no image */
4669 it->position = start_pos;
4670 it->object = NILP (object) ? it->w->buffer : object;
4671 it->method = GET_FROM_IMAGE;
4672 it->from_overlay = Qnil;
4673 it->face_id = face_id;
4674 it->from_disp_prop_p = 1;
4675
4676 /* Say that we haven't consumed the characters with
4677 `display' property yet. The call to pop_it in
4678 set_iterator_to_next will clean this up. */
4679 *position = start_pos;
4680
4681 if (EQ (XCAR (spec), Qleft_fringe))
4682 {
4683 it->left_user_fringe_bitmap = fringe_bitmap;
4684 it->left_user_fringe_face_id = face_id;
4685 }
4686 else
4687 {
4688 it->right_user_fringe_bitmap = fringe_bitmap;
4689 it->right_user_fringe_face_id = face_id;
4690 }
4691 }
4692 #endif /* HAVE_WINDOW_SYSTEM */
4693 return 1;
4694 }
4695
4696 /* Prepare to handle `((margin left-margin) ...)',
4697 `((margin right-margin) ...)' and `((margin nil) ...)'
4698 prefixes for display specifications. */
4699 location = Qunbound;
4700 if (CONSP (spec) && CONSP (XCAR (spec)))
4701 {
4702 Lisp_Object tem;
4703
4704 value = XCDR (spec);
4705 if (CONSP (value))
4706 value = XCAR (value);
4707
4708 tem = XCAR (spec);
4709 if (EQ (XCAR (tem), Qmargin)
4710 && (tem = XCDR (tem),
4711 tem = CONSP (tem) ? XCAR (tem) : Qnil,
4712 (NILP (tem)
4713 || EQ (tem, Qleft_margin)
4714 || EQ (tem, Qright_margin))))
4715 location = tem;
4716 }
4717
4718 if (EQ (location, Qunbound))
4719 {
4720 location = Qnil;
4721 value = spec;
4722 }
4723
4724 /* After this point, VALUE is the property after any
4725 margin prefix has been stripped. It must be a string,
4726 an image specification, or `(space ...)'.
4727
4728 LOCATION specifies where to display: `left-margin',
4729 `right-margin' or nil. */
4730
4731 valid_p = (STRINGP (value)
4732 #ifdef HAVE_WINDOW_SYSTEM
4733 || ((it ? FRAME_WINDOW_P (it->f) : frame_window_p)
4734 && valid_image_p (value))
4735 #endif /* not HAVE_WINDOW_SYSTEM */
4736 || (CONSP (value) && EQ (XCAR (value), Qspace)));
4737
4738 if (valid_p && !display_replaced_p)
4739 {
4740 int retval = 1;
4741
4742 if (!it)
4743 {
4744 /* Callers need to know whether the display spec is any kind
4745 of `(space ...)' spec that is about to affect text-area
4746 display. */
4747 if (CONSP (value) && EQ (XCAR (value), Qspace) && NILP (location))
4748 retval = 2;
4749 return retval;
4750 }
4751
4752 /* Save current settings of IT so that we can restore them
4753 when we are finished with the glyph property value. */
4754 push_it (it, position);
4755 it->from_overlay = overlay;
4756 it->from_disp_prop_p = 1;
4757
4758 if (NILP (location))
4759 it->area = TEXT_AREA;
4760 else if (EQ (location, Qleft_margin))
4761 it->area = LEFT_MARGIN_AREA;
4762 else
4763 it->area = RIGHT_MARGIN_AREA;
4764
4765 if (STRINGP (value))
4766 {
4767 it->string = value;
4768 it->multibyte_p = STRING_MULTIBYTE (it->string);
4769 it->current.overlay_string_index = -1;
4770 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
4771 it->end_charpos = it->string_nchars = SCHARS (it->string);
4772 it->method = GET_FROM_STRING;
4773 it->stop_charpos = 0;
4774 it->prev_stop = 0;
4775 it->base_level_stop = 0;
4776 it->string_from_display_prop_p = 1;
4777 /* Say that we haven't consumed the characters with
4778 `display' property yet. The call to pop_it in
4779 set_iterator_to_next will clean this up. */
4780 if (BUFFERP (object))
4781 *position = start_pos;
4782
4783 /* Force paragraph direction to be that of the parent
4784 object. If the parent object's paragraph direction is
4785 not yet determined, default to L2R. */
4786 if (it->bidi_p && it->bidi_it.paragraph_dir == R2L)
4787 it->paragraph_embedding = it->bidi_it.paragraph_dir;
4788 else
4789 it->paragraph_embedding = L2R;
4790
4791 /* Set up the bidi iterator for this display string. */
4792 if (it->bidi_p)
4793 {
4794 it->bidi_it.string.lstring = it->string;
4795 it->bidi_it.string.s = NULL;
4796 it->bidi_it.string.schars = it->end_charpos;
4797 it->bidi_it.string.bufpos = bufpos;
4798 it->bidi_it.string.from_disp_str = 1;
4799 it->bidi_it.string.unibyte = !it->multibyte_p;
4800 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
4801 }
4802 }
4803 else if (CONSP (value) && EQ (XCAR (value), Qspace))
4804 {
4805 it->method = GET_FROM_STRETCH;
4806 it->object = value;
4807 *position = it->position = start_pos;
4808 retval = 1 + (it->area == TEXT_AREA);
4809 }
4810 #ifdef HAVE_WINDOW_SYSTEM
4811 else
4812 {
4813 it->what = IT_IMAGE;
4814 it->image_id = lookup_image (it->f, value);
4815 it->position = start_pos;
4816 it->object = NILP (object) ? it->w->buffer : object;
4817 it->method = GET_FROM_IMAGE;
4818
4819 /* Say that we haven't consumed the characters with
4820 `display' property yet. The call to pop_it in
4821 set_iterator_to_next will clean this up. */
4822 *position = start_pos;
4823 }
4824 #endif /* HAVE_WINDOW_SYSTEM */
4825
4826 return retval;
4827 }
4828
4829 /* Invalid property or property not supported. Restore
4830 POSITION to what it was before. */
4831 *position = start_pos;
4832 return 0;
4833 }
4834
4835 /* Check if PROP is a display property value whose text should be
4836 treated as intangible. OVERLAY is the overlay from which PROP
4837 came, or nil if it came from a text property. CHARPOS and BYTEPOS
4838 specify the buffer position covered by PROP. */
4839
4840 int
4841 display_prop_intangible_p (Lisp_Object prop, Lisp_Object overlay,
4842 EMACS_INT charpos, EMACS_INT bytepos)
4843 {
4844 int frame_window_p = FRAME_WINDOW_P (XFRAME (selected_frame));
4845 struct text_pos position;
4846
4847 SET_TEXT_POS (position, charpos, bytepos);
4848 return handle_display_spec (NULL, prop, Qnil, overlay,
4849 &position, charpos, frame_window_p);
4850 }
4851
4852
4853 /* Return 1 if PROP is a display sub-property value containing STRING.
4854
4855 Implementation note: this and the following function are really
4856 special cases of handle_display_spec and
4857 handle_single_display_spec, and should ideally use the same code.
4858 Until they do, these two pairs must be consistent and must be
4859 modified in sync. */
4860
4861 static int
4862 single_display_spec_string_p (Lisp_Object prop, Lisp_Object string)
4863 {
4864 if (EQ (string, prop))
4865 return 1;
4866
4867 /* Skip over `when FORM'. */
4868 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
4869 {
4870 prop = XCDR (prop);
4871 if (!CONSP (prop))
4872 return 0;
4873 /* Actually, the condition following `when' should be eval'ed,
4874 like handle_single_display_spec does, and we should return
4875 zero if it evaluates to nil. However, this function is
4876 called only when the buffer was already displayed and some
4877 glyph in the glyph matrix was found to come from a display
4878 string. Therefore, the condition was already evaluated, and
4879 the result was non-nil, otherwise the display string wouldn't
4880 have been displayed and we would have never been called for
4881 this property. Thus, we can skip the evaluation and assume
4882 its result is non-nil. */
4883 prop = XCDR (prop);
4884 }
4885
4886 if (CONSP (prop))
4887 /* Skip over `margin LOCATION'. */
4888 if (EQ (XCAR (prop), Qmargin))
4889 {
4890 prop = XCDR (prop);
4891 if (!CONSP (prop))
4892 return 0;
4893
4894 prop = XCDR (prop);
4895 if (!CONSP (prop))
4896 return 0;
4897 }
4898
4899 return EQ (prop, string) || (CONSP (prop) && EQ (XCAR (prop), string));
4900 }
4901
4902
4903 /* Return 1 if STRING appears in the `display' property PROP. */
4904
4905 static int
4906 display_prop_string_p (Lisp_Object prop, Lisp_Object string)
4907 {
4908 if (CONSP (prop)
4909 && !EQ (XCAR (prop), Qwhen)
4910 && !(CONSP (XCAR (prop)) && EQ (Qmargin, XCAR (XCAR (prop)))))
4911 {
4912 /* A list of sub-properties. */
4913 while (CONSP (prop))
4914 {
4915 if (single_display_spec_string_p (XCAR (prop), string))
4916 return 1;
4917 prop = XCDR (prop);
4918 }
4919 }
4920 else if (VECTORP (prop))
4921 {
4922 /* A vector of sub-properties. */
4923 int i;
4924 for (i = 0; i < ASIZE (prop); ++i)
4925 if (single_display_spec_string_p (AREF (prop, i), string))
4926 return 1;
4927 }
4928 else
4929 return single_display_spec_string_p (prop, string);
4930
4931 return 0;
4932 }
4933
4934 /* Look for STRING in overlays and text properties in the current
4935 buffer, between character positions FROM and TO (excluding TO).
4936 BACK_P non-zero means look back (in this case, TO is supposed to be
4937 less than FROM).
4938 Value is the first character position where STRING was found, or
4939 zero if it wasn't found before hitting TO.
4940
4941 This function may only use code that doesn't eval because it is
4942 called asynchronously from note_mouse_highlight. */
4943
4944 static EMACS_INT
4945 string_buffer_position_lim (Lisp_Object string,
4946 EMACS_INT from, EMACS_INT to, int back_p)
4947 {
4948 Lisp_Object limit, prop, pos;
4949 int found = 0;
4950
4951 pos = make_number (from);
4952
4953 if (!back_p) /* looking forward */
4954 {
4955 limit = make_number (min (to, ZV));
4956 while (!found && !EQ (pos, limit))
4957 {
4958 prop = Fget_char_property (pos, Qdisplay, Qnil);
4959 if (!NILP (prop) && display_prop_string_p (prop, string))
4960 found = 1;
4961 else
4962 pos = Fnext_single_char_property_change (pos, Qdisplay, Qnil,
4963 limit);
4964 }
4965 }
4966 else /* looking back */
4967 {
4968 limit = make_number (max (to, BEGV));
4969 while (!found && !EQ (pos, limit))
4970 {
4971 prop = Fget_char_property (pos, Qdisplay, Qnil);
4972 if (!NILP (prop) && display_prop_string_p (prop, string))
4973 found = 1;
4974 else
4975 pos = Fprevious_single_char_property_change (pos, Qdisplay, Qnil,
4976 limit);
4977 }
4978 }
4979
4980 return found ? XINT (pos) : 0;
4981 }
4982
4983 /* Determine which buffer position in current buffer STRING comes from.
4984 AROUND_CHARPOS is an approximate position where it could come from.
4985 Value is the buffer position or 0 if it couldn't be determined.
4986
4987 This function is necessary because we don't record buffer positions
4988 in glyphs generated from strings (to keep struct glyph small).
4989 This function may only use code that doesn't eval because it is
4990 called asynchronously from note_mouse_highlight. */
4991
4992 static EMACS_INT
4993 string_buffer_position (Lisp_Object string, EMACS_INT around_charpos)
4994 {
4995 const int MAX_DISTANCE = 1000;
4996 EMACS_INT found = string_buffer_position_lim (string, around_charpos,
4997 around_charpos + MAX_DISTANCE,
4998 0);
4999
5000 if (!found)
5001 found = string_buffer_position_lim (string, around_charpos,
5002 around_charpos - MAX_DISTANCE, 1);
5003 return found;
5004 }
5005
5006
5007 \f
5008 /***********************************************************************
5009 `composition' property
5010 ***********************************************************************/
5011
5012 /* Set up iterator IT from `composition' property at its current
5013 position. Called from handle_stop. */
5014
5015 static enum prop_handled
5016 handle_composition_prop (struct it *it)
5017 {
5018 Lisp_Object prop, string;
5019 EMACS_INT pos, pos_byte, start, end;
5020
5021 if (STRINGP (it->string))
5022 {
5023 unsigned char *s;
5024
5025 pos = IT_STRING_CHARPOS (*it);
5026 pos_byte = IT_STRING_BYTEPOS (*it);
5027 string = it->string;
5028 s = SDATA (string) + pos_byte;
5029 it->c = STRING_CHAR (s);
5030 }
5031 else
5032 {
5033 pos = IT_CHARPOS (*it);
5034 pos_byte = IT_BYTEPOS (*it);
5035 string = Qnil;
5036 it->c = FETCH_CHAR (pos_byte);
5037 }
5038
5039 /* If there's a valid composition and point is not inside of the
5040 composition (in the case that the composition is from the current
5041 buffer), draw a glyph composed from the composition components. */
5042 if (find_composition (pos, -1, &start, &end, &prop, string)
5043 && COMPOSITION_VALID_P (start, end, prop)
5044 && (STRINGP (it->string) || (PT <= start || PT >= end)))
5045 {
5046 if (start < pos)
5047 /* As we can't handle this situation (perhaps font-lock added
5048 a new composition), we just return here hoping that next
5049 redisplay will detect this composition much earlier. */
5050 return HANDLED_NORMALLY;
5051 if (start != pos)
5052 {
5053 if (STRINGP (it->string))
5054 pos_byte = string_char_to_byte (it->string, start);
5055 else
5056 pos_byte = CHAR_TO_BYTE (start);
5057 }
5058 it->cmp_it.id = get_composition_id (start, pos_byte, end - start,
5059 prop, string);
5060
5061 if (it->cmp_it.id >= 0)
5062 {
5063 it->cmp_it.ch = -1;
5064 it->cmp_it.nchars = COMPOSITION_LENGTH (prop);
5065 it->cmp_it.nglyphs = -1;
5066 }
5067 }
5068
5069 return HANDLED_NORMALLY;
5070 }
5071
5072
5073 \f
5074 /***********************************************************************
5075 Overlay strings
5076 ***********************************************************************/
5077
5078 /* The following structure is used to record overlay strings for
5079 later sorting in load_overlay_strings. */
5080
5081 struct overlay_entry
5082 {
5083 Lisp_Object overlay;
5084 Lisp_Object string;
5085 int priority;
5086 int after_string_p;
5087 };
5088
5089
5090 /* Set up iterator IT from overlay strings at its current position.
5091 Called from handle_stop. */
5092
5093 static enum prop_handled
5094 handle_overlay_change (struct it *it)
5095 {
5096 if (!STRINGP (it->string) && get_overlay_strings (it, 0))
5097 return HANDLED_RECOMPUTE_PROPS;
5098 else
5099 return HANDLED_NORMALLY;
5100 }
5101
5102
5103 /* Set up the next overlay string for delivery by IT, if there is an
5104 overlay string to deliver. Called by set_iterator_to_next when the
5105 end of the current overlay string is reached. If there are more
5106 overlay strings to display, IT->string and
5107 IT->current.overlay_string_index are set appropriately here.
5108 Otherwise IT->string is set to nil. */
5109
5110 static void
5111 next_overlay_string (struct it *it)
5112 {
5113 ++it->current.overlay_string_index;
5114 if (it->current.overlay_string_index == it->n_overlay_strings)
5115 {
5116 /* No more overlay strings. Restore IT's settings to what
5117 they were before overlay strings were processed, and
5118 continue to deliver from current_buffer. */
5119
5120 it->ellipsis_p = (it->stack[it->sp - 1].display_ellipsis_p != 0);
5121 pop_it (it);
5122 xassert (it->sp > 0
5123 || (NILP (it->string)
5124 && it->method == GET_FROM_BUFFER
5125 && it->stop_charpos >= BEGV
5126 && it->stop_charpos <= it->end_charpos));
5127 it->current.overlay_string_index = -1;
5128 it->n_overlay_strings = 0;
5129 it->overlay_strings_charpos = -1;
5130
5131 /* If we're at the end of the buffer, record that we have
5132 processed the overlay strings there already, so that
5133 next_element_from_buffer doesn't try it again. */
5134 if (NILP (it->string) && IT_CHARPOS (*it) >= it->end_charpos)
5135 it->overlay_strings_at_end_processed_p = 1;
5136 }
5137 else
5138 {
5139 /* There are more overlay strings to process. If
5140 IT->current.overlay_string_index has advanced to a position
5141 where we must load IT->overlay_strings with more strings, do
5142 it. We must load at the IT->overlay_strings_charpos where
5143 IT->n_overlay_strings was originally computed; when invisible
5144 text is present, this might not be IT_CHARPOS (Bug#7016). */
5145 int i = it->current.overlay_string_index % OVERLAY_STRING_CHUNK_SIZE;
5146
5147 if (it->current.overlay_string_index && i == 0)
5148 load_overlay_strings (it, it->overlay_strings_charpos);
5149
5150 /* Initialize IT to deliver display elements from the overlay
5151 string. */
5152 it->string = it->overlay_strings[i];
5153 it->multibyte_p = STRING_MULTIBYTE (it->string);
5154 SET_TEXT_POS (it->current.string_pos, 0, 0);
5155 it->method = GET_FROM_STRING;
5156 it->stop_charpos = 0;
5157 if (it->cmp_it.stop_pos >= 0)
5158 it->cmp_it.stop_pos = 0;
5159 it->prev_stop = 0;
5160 it->base_level_stop = 0;
5161
5162 /* Set up the bidi iterator for this overlay string. */
5163 if (it->bidi_p)
5164 {
5165 it->bidi_it.string.lstring = it->string;
5166 it->bidi_it.string.s = NULL;
5167 it->bidi_it.string.schars = SCHARS (it->string);
5168 it->bidi_it.string.bufpos = it->overlay_strings_charpos;
5169 it->bidi_it.string.from_disp_str = it->string_from_display_prop_p;
5170 it->bidi_it.string.unibyte = !it->multibyte_p;
5171 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
5172 }
5173 }
5174
5175 CHECK_IT (it);
5176 }
5177
5178
5179 /* Compare two overlay_entry structures E1 and E2. Used as a
5180 comparison function for qsort in load_overlay_strings. Overlay
5181 strings for the same position are sorted so that
5182
5183 1. All after-strings come in front of before-strings, except
5184 when they come from the same overlay.
5185
5186 2. Within after-strings, strings are sorted so that overlay strings
5187 from overlays with higher priorities come first.
5188
5189 2. Within before-strings, strings are sorted so that overlay
5190 strings from overlays with higher priorities come last.
5191
5192 Value is analogous to strcmp. */
5193
5194
5195 static int
5196 compare_overlay_entries (const void *e1, const void *e2)
5197 {
5198 struct overlay_entry *entry1 = (struct overlay_entry *) e1;
5199 struct overlay_entry *entry2 = (struct overlay_entry *) e2;
5200 int result;
5201
5202 if (entry1->after_string_p != entry2->after_string_p)
5203 {
5204 /* Let after-strings appear in front of before-strings if
5205 they come from different overlays. */
5206 if (EQ (entry1->overlay, entry2->overlay))
5207 result = entry1->after_string_p ? 1 : -1;
5208 else
5209 result = entry1->after_string_p ? -1 : 1;
5210 }
5211 else if (entry1->after_string_p)
5212 /* After-strings sorted in order of decreasing priority. */
5213 result = entry2->priority - entry1->priority;
5214 else
5215 /* Before-strings sorted in order of increasing priority. */
5216 result = entry1->priority - entry2->priority;
5217
5218 return result;
5219 }
5220
5221
5222 /* Load the vector IT->overlay_strings with overlay strings from IT's
5223 current buffer position, or from CHARPOS if that is > 0. Set
5224 IT->n_overlays to the total number of overlay strings found.
5225
5226 Overlay strings are processed OVERLAY_STRING_CHUNK_SIZE strings at
5227 a time. On entry into load_overlay_strings,
5228 IT->current.overlay_string_index gives the number of overlay
5229 strings that have already been loaded by previous calls to this
5230 function.
5231
5232 IT->add_overlay_start contains an additional overlay start
5233 position to consider for taking overlay strings from, if non-zero.
5234 This position comes into play when the overlay has an `invisible'
5235 property, and both before and after-strings. When we've skipped to
5236 the end of the overlay, because of its `invisible' property, we
5237 nevertheless want its before-string to appear.
5238 IT->add_overlay_start will contain the overlay start position
5239 in this case.
5240
5241 Overlay strings are sorted so that after-string strings come in
5242 front of before-string strings. Within before and after-strings,
5243 strings are sorted by overlay priority. See also function
5244 compare_overlay_entries. */
5245
5246 static void
5247 load_overlay_strings (struct it *it, EMACS_INT charpos)
5248 {
5249 Lisp_Object overlay, window, str, invisible;
5250 struct Lisp_Overlay *ov;
5251 EMACS_INT start, end;
5252 int size = 20;
5253 int n = 0, i, j, invis_p;
5254 struct overlay_entry *entries
5255 = (struct overlay_entry *) alloca (size * sizeof *entries);
5256
5257 if (charpos <= 0)
5258 charpos = IT_CHARPOS (*it);
5259
5260 /* Append the overlay string STRING of overlay OVERLAY to vector
5261 `entries' which has size `size' and currently contains `n'
5262 elements. AFTER_P non-zero means STRING is an after-string of
5263 OVERLAY. */
5264 #define RECORD_OVERLAY_STRING(OVERLAY, STRING, AFTER_P) \
5265 do \
5266 { \
5267 Lisp_Object priority; \
5268 \
5269 if (n == size) \
5270 { \
5271 int new_size = 2 * size; \
5272 struct overlay_entry *old = entries; \
5273 entries = \
5274 (struct overlay_entry *) alloca (new_size \
5275 * sizeof *entries); \
5276 memcpy (entries, old, size * sizeof *entries); \
5277 size = new_size; \
5278 } \
5279 \
5280 entries[n].string = (STRING); \
5281 entries[n].overlay = (OVERLAY); \
5282 priority = Foverlay_get ((OVERLAY), Qpriority); \
5283 entries[n].priority = INTEGERP (priority) ? XINT (priority) : 0; \
5284 entries[n].after_string_p = (AFTER_P); \
5285 ++n; \
5286 } \
5287 while (0)
5288
5289 /* Process overlay before the overlay center. */
5290 for (ov = current_buffer->overlays_before; ov; ov = ov->next)
5291 {
5292 XSETMISC (overlay, ov);
5293 xassert (OVERLAYP (overlay));
5294 start = OVERLAY_POSITION (OVERLAY_START (overlay));
5295 end = OVERLAY_POSITION (OVERLAY_END (overlay));
5296
5297 if (end < charpos)
5298 break;
5299
5300 /* Skip this overlay if it doesn't start or end at IT's current
5301 position. */
5302 if (end != charpos && start != charpos)
5303 continue;
5304
5305 /* Skip this overlay if it doesn't apply to IT->w. */
5306 window = Foverlay_get (overlay, Qwindow);
5307 if (WINDOWP (window) && XWINDOW (window) != it->w)
5308 continue;
5309
5310 /* If the text ``under'' the overlay is invisible, both before-
5311 and after-strings from this overlay are visible; start and
5312 end position are indistinguishable. */
5313 invisible = Foverlay_get (overlay, Qinvisible);
5314 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
5315
5316 /* If overlay has a non-empty before-string, record it. */
5317 if ((start == charpos || (end == charpos && invis_p))
5318 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
5319 && SCHARS (str))
5320 RECORD_OVERLAY_STRING (overlay, str, 0);
5321
5322 /* If overlay has a non-empty after-string, record it. */
5323 if ((end == charpos || (start == charpos && invis_p))
5324 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
5325 && SCHARS (str))
5326 RECORD_OVERLAY_STRING (overlay, str, 1);
5327 }
5328
5329 /* Process overlays after the overlay center. */
5330 for (ov = current_buffer->overlays_after; ov; ov = ov->next)
5331 {
5332 XSETMISC (overlay, ov);
5333 xassert (OVERLAYP (overlay));
5334 start = OVERLAY_POSITION (OVERLAY_START (overlay));
5335 end = OVERLAY_POSITION (OVERLAY_END (overlay));
5336
5337 if (start > charpos)
5338 break;
5339
5340 /* Skip this overlay if it doesn't start or end at IT's current
5341 position. */
5342 if (end != charpos && start != charpos)
5343 continue;
5344
5345 /* Skip this overlay if it doesn't apply to IT->w. */
5346 window = Foverlay_get (overlay, Qwindow);
5347 if (WINDOWP (window) && XWINDOW (window) != it->w)
5348 continue;
5349
5350 /* If the text ``under'' the overlay is invisible, it has a zero
5351 dimension, and both before- and after-strings apply. */
5352 invisible = Foverlay_get (overlay, Qinvisible);
5353 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
5354
5355 /* If overlay has a non-empty before-string, record it. */
5356 if ((start == charpos || (end == charpos && invis_p))
5357 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
5358 && SCHARS (str))
5359 RECORD_OVERLAY_STRING (overlay, str, 0);
5360
5361 /* If overlay has a non-empty after-string, record it. */
5362 if ((end == charpos || (start == charpos && invis_p))
5363 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
5364 && SCHARS (str))
5365 RECORD_OVERLAY_STRING (overlay, str, 1);
5366 }
5367
5368 #undef RECORD_OVERLAY_STRING
5369
5370 /* Sort entries. */
5371 if (n > 1)
5372 qsort (entries, n, sizeof *entries, compare_overlay_entries);
5373
5374 /* Record number of overlay strings, and where we computed it. */
5375 it->n_overlay_strings = n;
5376 it->overlay_strings_charpos = charpos;
5377
5378 /* IT->current.overlay_string_index is the number of overlay strings
5379 that have already been consumed by IT. Copy some of the
5380 remaining overlay strings to IT->overlay_strings. */
5381 i = 0;
5382 j = it->current.overlay_string_index;
5383 while (i < OVERLAY_STRING_CHUNK_SIZE && j < n)
5384 {
5385 it->overlay_strings[i] = entries[j].string;
5386 it->string_overlays[i++] = entries[j++].overlay;
5387 }
5388
5389 CHECK_IT (it);
5390 }
5391
5392
5393 /* Get the first chunk of overlay strings at IT's current buffer
5394 position, or at CHARPOS if that is > 0. Value is non-zero if at
5395 least one overlay string was found. */
5396
5397 static int
5398 get_overlay_strings_1 (struct it *it, EMACS_INT charpos, int compute_stop_p)
5399 {
5400 /* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to
5401 process. This fills IT->overlay_strings with strings, and sets
5402 IT->n_overlay_strings to the total number of strings to process.
5403 IT->pos.overlay_string_index has to be set temporarily to zero
5404 because load_overlay_strings needs this; it must be set to -1
5405 when no overlay strings are found because a zero value would
5406 indicate a position in the first overlay string. */
5407 it->current.overlay_string_index = 0;
5408 load_overlay_strings (it, charpos);
5409
5410 /* If we found overlay strings, set up IT to deliver display
5411 elements from the first one. Otherwise set up IT to deliver
5412 from current_buffer. */
5413 if (it->n_overlay_strings)
5414 {
5415 /* Make sure we know settings in current_buffer, so that we can
5416 restore meaningful values when we're done with the overlay
5417 strings. */
5418 if (compute_stop_p)
5419 compute_stop_pos (it);
5420 xassert (it->face_id >= 0);
5421
5422 /* Save IT's settings. They are restored after all overlay
5423 strings have been processed. */
5424 xassert (!compute_stop_p || it->sp == 0);
5425
5426 /* When called from handle_stop, there might be an empty display
5427 string loaded. In that case, don't bother saving it. */
5428 if (!STRINGP (it->string) || SCHARS (it->string))
5429 push_it (it, NULL);
5430
5431 /* Set up IT to deliver display elements from the first overlay
5432 string. */
5433 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
5434 it->string = it->overlay_strings[0];
5435 it->from_overlay = Qnil;
5436 it->stop_charpos = 0;
5437 xassert (STRINGP (it->string));
5438 it->end_charpos = SCHARS (it->string);
5439 it->prev_stop = 0;
5440 it->base_level_stop = 0;
5441 it->multibyte_p = STRING_MULTIBYTE (it->string);
5442 it->method = GET_FROM_STRING;
5443 it->from_disp_prop_p = 0;
5444
5445 /* Force paragraph direction to be that of the parent
5446 buffer. */
5447 if (it->bidi_p && it->bidi_it.paragraph_dir == R2L)
5448 it->paragraph_embedding = it->bidi_it.paragraph_dir;
5449 else
5450 it->paragraph_embedding = L2R;
5451
5452 /* Set up the bidi iterator for this overlay string. */
5453 if (it->bidi_p)
5454 {
5455 EMACS_INT pos = (charpos > 0 ? charpos : IT_CHARPOS (*it));
5456
5457 it->bidi_it.string.lstring = it->string;
5458 it->bidi_it.string.s = NULL;
5459 it->bidi_it.string.schars = SCHARS (it->string);
5460 it->bidi_it.string.bufpos = pos;
5461 it->bidi_it.string.from_disp_str = it->string_from_display_prop_p;
5462 it->bidi_it.string.unibyte = !it->multibyte_p;
5463 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
5464 }
5465 return 1;
5466 }
5467
5468 it->current.overlay_string_index = -1;
5469 return 0;
5470 }
5471
5472 static int
5473 get_overlay_strings (struct it *it, EMACS_INT charpos)
5474 {
5475 it->string = Qnil;
5476 it->method = GET_FROM_BUFFER;
5477
5478 (void) get_overlay_strings_1 (it, charpos, 1);
5479
5480 CHECK_IT (it);
5481
5482 /* Value is non-zero if we found at least one overlay string. */
5483 return STRINGP (it->string);
5484 }
5485
5486
5487 \f
5488 /***********************************************************************
5489 Saving and restoring state
5490 ***********************************************************************/
5491
5492 /* Save current settings of IT on IT->stack. Called, for example,
5493 before setting up IT for an overlay string, to be able to restore
5494 IT's settings to what they were after the overlay string has been
5495 processed. If POSITION is non-NULL, it is the position to save on
5496 the stack instead of IT->position. */
5497
5498 static void
5499 push_it (struct it *it, struct text_pos *position)
5500 {
5501 struct iterator_stack_entry *p;
5502
5503 xassert (it->sp < IT_STACK_SIZE);
5504 p = it->stack + it->sp;
5505
5506 p->stop_charpos = it->stop_charpos;
5507 p->prev_stop = it->prev_stop;
5508 p->base_level_stop = it->base_level_stop;
5509 p->cmp_it = it->cmp_it;
5510 xassert (it->face_id >= 0);
5511 p->face_id = it->face_id;
5512 p->string = it->string;
5513 p->method = it->method;
5514 p->from_overlay = it->from_overlay;
5515 switch (p->method)
5516 {
5517 case GET_FROM_IMAGE:
5518 p->u.image.object = it->object;
5519 p->u.image.image_id = it->image_id;
5520 p->u.image.slice = it->slice;
5521 break;
5522 case GET_FROM_STRETCH:
5523 p->u.stretch.object = it->object;
5524 break;
5525 }
5526 p->position = position ? *position : it->position;
5527 p->current = it->current;
5528 p->end_charpos = it->end_charpos;
5529 p->string_nchars = it->string_nchars;
5530 p->area = it->area;
5531 p->multibyte_p = it->multibyte_p;
5532 p->avoid_cursor_p = it->avoid_cursor_p;
5533 p->space_width = it->space_width;
5534 p->font_height = it->font_height;
5535 p->voffset = it->voffset;
5536 p->string_from_display_prop_p = it->string_from_display_prop_p;
5537 p->display_ellipsis_p = 0;
5538 p->line_wrap = it->line_wrap;
5539 p->bidi_p = it->bidi_p;
5540 p->paragraph_embedding = it->paragraph_embedding;
5541 p->from_disp_prop_p = it->from_disp_prop_p;
5542 ++it->sp;
5543
5544 /* Save the state of the bidi iterator as well. */
5545 if (it->bidi_p)
5546 bidi_push_it (&it->bidi_it);
5547 }
5548
5549 static void
5550 iterate_out_of_display_property (struct it *it)
5551 {
5552 int buffer_p = BUFFERP (it->object);
5553 EMACS_INT eob = (buffer_p ? ZV : it->end_charpos);
5554 EMACS_INT bob = (buffer_p ? BEGV : 0);
5555
5556 xassert (eob >= CHARPOS (it->position) && CHARPOS (it->position) >= bob);
5557
5558 /* Maybe initialize paragraph direction. If we are at the beginning
5559 of a new paragraph, next_element_from_buffer may not have a
5560 chance to do that. */
5561 if (it->bidi_it.first_elt && it->bidi_it.charpos < eob)
5562 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1);
5563 /* prev_stop can be zero, so check against BEGV as well. */
5564 while (it->bidi_it.charpos >= bob
5565 && it->prev_stop <= it->bidi_it.charpos
5566 && it->bidi_it.charpos < CHARPOS (it->position)
5567 && it->bidi_it.charpos < eob)
5568 bidi_move_to_visually_next (&it->bidi_it);
5569 /* Record the stop_pos we just crossed, for when we cross it
5570 back, maybe. */
5571 if (it->bidi_it.charpos > CHARPOS (it->position))
5572 it->prev_stop = CHARPOS (it->position);
5573 /* If we ended up not where pop_it put us, resync IT's
5574 positional members with the bidi iterator. */
5575 if (it->bidi_it.charpos != CHARPOS (it->position))
5576 SET_TEXT_POS (it->position, it->bidi_it.charpos, it->bidi_it.bytepos);
5577 if (buffer_p)
5578 it->current.pos = it->position;
5579 else
5580 it->current.string_pos = it->position;
5581 }
5582
5583 /* Restore IT's settings from IT->stack. Called, for example, when no
5584 more overlay strings must be processed, and we return to delivering
5585 display elements from a buffer, or when the end of a string from a
5586 `display' property is reached and we return to delivering display
5587 elements from an overlay string, or from a buffer. */
5588
5589 static void
5590 pop_it (struct it *it)
5591 {
5592 struct iterator_stack_entry *p;
5593 int from_display_prop = it->from_disp_prop_p;
5594
5595 xassert (it->sp > 0);
5596 --it->sp;
5597 p = it->stack + it->sp;
5598 it->stop_charpos = p->stop_charpos;
5599 it->prev_stop = p->prev_stop;
5600 it->base_level_stop = p->base_level_stop;
5601 it->cmp_it = p->cmp_it;
5602 it->face_id = p->face_id;
5603 it->current = p->current;
5604 it->position = p->position;
5605 it->string = p->string;
5606 it->from_overlay = p->from_overlay;
5607 if (NILP (it->string))
5608 SET_TEXT_POS (it->current.string_pos, -1, -1);
5609 it->method = p->method;
5610 switch (it->method)
5611 {
5612 case GET_FROM_IMAGE:
5613 it->image_id = p->u.image.image_id;
5614 it->object = p->u.image.object;
5615 it->slice = p->u.image.slice;
5616 break;
5617 case GET_FROM_STRETCH:
5618 it->object = p->u.stretch.object;
5619 break;
5620 case GET_FROM_BUFFER:
5621 it->object = it->w->buffer;
5622 break;
5623 case GET_FROM_STRING:
5624 it->object = it->string;
5625 break;
5626 case GET_FROM_DISPLAY_VECTOR:
5627 if (it->s)
5628 it->method = GET_FROM_C_STRING;
5629 else if (STRINGP (it->string))
5630 it->method = GET_FROM_STRING;
5631 else
5632 {
5633 it->method = GET_FROM_BUFFER;
5634 it->object = it->w->buffer;
5635 }
5636 }
5637 it->end_charpos = p->end_charpos;
5638 it->string_nchars = p->string_nchars;
5639 it->area = p->area;
5640 it->multibyte_p = p->multibyte_p;
5641 it->avoid_cursor_p = p->avoid_cursor_p;
5642 it->space_width = p->space_width;
5643 it->font_height = p->font_height;
5644 it->voffset = p->voffset;
5645 it->string_from_display_prop_p = p->string_from_display_prop_p;
5646 it->line_wrap = p->line_wrap;
5647 it->bidi_p = p->bidi_p;
5648 it->paragraph_embedding = p->paragraph_embedding;
5649 it->from_disp_prop_p = p->from_disp_prop_p;
5650 if (it->bidi_p)
5651 {
5652 bidi_pop_it (&it->bidi_it);
5653 /* Bidi-iterate until we get out of the portion of text, if any,
5654 covered by a `display' text property or by an overlay with
5655 `display' property. (We cannot just jump there, because the
5656 internal coherency of the bidi iterator state can not be
5657 preserved across such jumps.) We also must determine the
5658 paragraph base direction if the overlay we just processed is
5659 at the beginning of a new paragraph. */
5660 if (from_display_prop
5661 && (it->method == GET_FROM_BUFFER || it->method == GET_FROM_STRING))
5662 iterate_out_of_display_property (it);
5663
5664 xassert ((BUFFERP (it->object)
5665 && IT_CHARPOS (*it) == it->bidi_it.charpos
5666 && IT_BYTEPOS (*it) == it->bidi_it.bytepos)
5667 || (STRINGP (it->object)
5668 && IT_STRING_CHARPOS (*it) == it->bidi_it.charpos
5669 && IT_STRING_BYTEPOS (*it) == it->bidi_it.bytepos)
5670 || (CONSP (it->object) && it->method == GET_FROM_STRETCH));
5671 }
5672 }
5673
5674
5675 \f
5676 /***********************************************************************
5677 Moving over lines
5678 ***********************************************************************/
5679
5680 /* Set IT's current position to the previous line start. */
5681
5682 static void
5683 back_to_previous_line_start (struct it *it)
5684 {
5685 IT_CHARPOS (*it) = find_next_newline_no_quit (IT_CHARPOS (*it) - 1, -1);
5686 IT_BYTEPOS (*it) = CHAR_TO_BYTE (IT_CHARPOS (*it));
5687 }
5688
5689
5690 /* Move IT to the next line start.
5691
5692 Value is non-zero if a newline was found. Set *SKIPPED_P to 1 if
5693 we skipped over part of the text (as opposed to moving the iterator
5694 continuously over the text). Otherwise, don't change the value
5695 of *SKIPPED_P.
5696
5697 If BIDI_IT_PREV is non-NULL, store into it the state of the bidi
5698 iterator on the newline, if it was found.
5699
5700 Newlines may come from buffer text, overlay strings, or strings
5701 displayed via the `display' property. That's the reason we can't
5702 simply use find_next_newline_no_quit.
5703
5704 Note that this function may not skip over invisible text that is so
5705 because of text properties and immediately follows a newline. If
5706 it would, function reseat_at_next_visible_line_start, when called
5707 from set_iterator_to_next, would effectively make invisible
5708 characters following a newline part of the wrong glyph row, which
5709 leads to wrong cursor motion. */
5710
5711 static int
5712 forward_to_next_line_start (struct it *it, int *skipped_p,
5713 struct bidi_it *bidi_it_prev)
5714 {
5715 EMACS_INT old_selective;
5716 int newline_found_p, n;
5717 const int MAX_NEWLINE_DISTANCE = 500;
5718
5719 /* If already on a newline, just consume it to avoid unintended
5720 skipping over invisible text below. */
5721 if (it->what == IT_CHARACTER
5722 && it->c == '\n'
5723 && CHARPOS (it->position) == IT_CHARPOS (*it))
5724 {
5725 if (it->bidi_p && bidi_it_prev)
5726 *bidi_it_prev = it->bidi_it;
5727 set_iterator_to_next (it, 0);
5728 it->c = 0;
5729 return 1;
5730 }
5731
5732 /* Don't handle selective display in the following. It's (a)
5733 unnecessary because it's done by the caller, and (b) leads to an
5734 infinite recursion because next_element_from_ellipsis indirectly
5735 calls this function. */
5736 old_selective = it->selective;
5737 it->selective = 0;
5738
5739 /* Scan for a newline within MAX_NEWLINE_DISTANCE display elements
5740 from buffer text. */
5741 for (n = newline_found_p = 0;
5742 !newline_found_p && n < MAX_NEWLINE_DISTANCE;
5743 n += STRINGP (it->string) ? 0 : 1)
5744 {
5745 if (!get_next_display_element (it))
5746 return 0;
5747 newline_found_p = it->what == IT_CHARACTER && it->c == '\n';
5748 if (newline_found_p && it->bidi_p && bidi_it_prev)
5749 *bidi_it_prev = it->bidi_it;
5750 set_iterator_to_next (it, 0);
5751 }
5752
5753 /* If we didn't find a newline near enough, see if we can use a
5754 short-cut. */
5755 if (!newline_found_p)
5756 {
5757 EMACS_INT start = IT_CHARPOS (*it);
5758 EMACS_INT limit = find_next_newline_no_quit (start, 1);
5759 Lisp_Object pos;
5760
5761 xassert (!STRINGP (it->string));
5762
5763 /* If there isn't any `display' property in sight, and no
5764 overlays, we can just use the position of the newline in
5765 buffer text. */
5766 if (it->stop_charpos >= limit
5767 || ((pos = Fnext_single_property_change (make_number (start),
5768 Qdisplay, Qnil,
5769 make_number (limit)),
5770 NILP (pos))
5771 && next_overlay_change (start) == ZV))
5772 {
5773 if (!it->bidi_p)
5774 {
5775 IT_CHARPOS (*it) = limit;
5776 IT_BYTEPOS (*it) = CHAR_TO_BYTE (limit);
5777 }
5778 else
5779 {
5780 struct bidi_it bprev;
5781
5782 /* Help bidi.c avoid expensive searches for display
5783 properties and overlays, by telling it that there are
5784 none up to `limit'. */
5785 if (it->bidi_it.disp_pos < limit)
5786 {
5787 it->bidi_it.disp_pos = limit;
5788 it->bidi_it.disp_prop = 0;
5789 }
5790 do {
5791 bprev = it->bidi_it;
5792 bidi_move_to_visually_next (&it->bidi_it);
5793 } while (it->bidi_it.charpos != limit);
5794 IT_CHARPOS (*it) = limit;
5795 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
5796 if (bidi_it_prev)
5797 *bidi_it_prev = bprev;
5798 }
5799 *skipped_p = newline_found_p = 1;
5800 }
5801 else
5802 {
5803 while (get_next_display_element (it)
5804 && !newline_found_p)
5805 {
5806 newline_found_p = ITERATOR_AT_END_OF_LINE_P (it);
5807 if (newline_found_p && it->bidi_p && bidi_it_prev)
5808 *bidi_it_prev = it->bidi_it;
5809 set_iterator_to_next (it, 0);
5810 }
5811 }
5812 }
5813
5814 it->selective = old_selective;
5815 return newline_found_p;
5816 }
5817
5818
5819 /* Set IT's current position to the previous visible line start. Skip
5820 invisible text that is so either due to text properties or due to
5821 selective display. Caution: this does not change IT->current_x and
5822 IT->hpos. */
5823
5824 static void
5825 back_to_previous_visible_line_start (struct it *it)
5826 {
5827 while (IT_CHARPOS (*it) > BEGV)
5828 {
5829 back_to_previous_line_start (it);
5830
5831 if (IT_CHARPOS (*it) <= BEGV)
5832 break;
5833
5834 /* If selective > 0, then lines indented more than its value are
5835 invisible. */
5836 if (it->selective > 0
5837 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
5838 it->selective))
5839 continue;
5840
5841 /* Check the newline before point for invisibility. */
5842 {
5843 Lisp_Object prop;
5844 prop = Fget_char_property (make_number (IT_CHARPOS (*it) - 1),
5845 Qinvisible, it->window);
5846 if (TEXT_PROP_MEANS_INVISIBLE (prop))
5847 continue;
5848 }
5849
5850 if (IT_CHARPOS (*it) <= BEGV)
5851 break;
5852
5853 {
5854 struct it it2;
5855 void *it2data = NULL;
5856 EMACS_INT pos;
5857 EMACS_INT beg, end;
5858 Lisp_Object val, overlay;
5859
5860 SAVE_IT (it2, *it, it2data);
5861
5862 /* If newline is part of a composition, continue from start of composition */
5863 if (find_composition (IT_CHARPOS (*it), -1, &beg, &end, &val, Qnil)
5864 && beg < IT_CHARPOS (*it))
5865 goto replaced;
5866
5867 /* If newline is replaced by a display property, find start of overlay
5868 or interval and continue search from that point. */
5869 pos = --IT_CHARPOS (it2);
5870 --IT_BYTEPOS (it2);
5871 it2.sp = 0;
5872 bidi_unshelve_cache (NULL, 0);
5873 it2.string_from_display_prop_p = 0;
5874 it2.from_disp_prop_p = 0;
5875 if (handle_display_prop (&it2) == HANDLED_RETURN
5876 && !NILP (val = get_char_property_and_overlay
5877 (make_number (pos), Qdisplay, Qnil, &overlay))
5878 && (OVERLAYP (overlay)
5879 ? (beg = OVERLAY_POSITION (OVERLAY_START (overlay)))
5880 : get_property_and_range (pos, Qdisplay, &val, &beg, &end, Qnil)))
5881 {
5882 RESTORE_IT (it, it, it2data);
5883 goto replaced;
5884 }
5885
5886 /* Newline is not replaced by anything -- so we are done. */
5887 RESTORE_IT (it, it, it2data);
5888 break;
5889
5890 replaced:
5891 if (beg < BEGV)
5892 beg = BEGV;
5893 IT_CHARPOS (*it) = beg;
5894 IT_BYTEPOS (*it) = buf_charpos_to_bytepos (current_buffer, beg);
5895 }
5896 }
5897
5898 it->continuation_lines_width = 0;
5899
5900 xassert (IT_CHARPOS (*it) >= BEGV);
5901 xassert (IT_CHARPOS (*it) == BEGV
5902 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
5903 CHECK_IT (it);
5904 }
5905
5906
5907 /* Reseat iterator IT at the previous visible line start. Skip
5908 invisible text that is so either due to text properties or due to
5909 selective display. At the end, update IT's overlay information,
5910 face information etc. */
5911
5912 void
5913 reseat_at_previous_visible_line_start (struct it *it)
5914 {
5915 back_to_previous_visible_line_start (it);
5916 reseat (it, it->current.pos, 1);
5917 CHECK_IT (it);
5918 }
5919
5920
5921 /* Reseat iterator IT on the next visible line start in the current
5922 buffer. ON_NEWLINE_P non-zero means position IT on the newline
5923 preceding the line start. Skip over invisible text that is so
5924 because of selective display. Compute faces, overlays etc at the
5925 new position. Note that this function does not skip over text that
5926 is invisible because of text properties. */
5927
5928 static void
5929 reseat_at_next_visible_line_start (struct it *it, int on_newline_p)
5930 {
5931 int newline_found_p, skipped_p = 0;
5932 struct bidi_it bidi_it_prev;
5933
5934 newline_found_p = forward_to_next_line_start (it, &skipped_p, &bidi_it_prev);
5935
5936 /* Skip over lines that are invisible because they are indented
5937 more than the value of IT->selective. */
5938 if (it->selective > 0)
5939 while (IT_CHARPOS (*it) < ZV
5940 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
5941 it->selective))
5942 {
5943 xassert (IT_BYTEPOS (*it) == BEGV
5944 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
5945 newline_found_p =
5946 forward_to_next_line_start (it, &skipped_p, &bidi_it_prev);
5947 }
5948
5949 /* Position on the newline if that's what's requested. */
5950 if (on_newline_p && newline_found_p)
5951 {
5952 if (STRINGP (it->string))
5953 {
5954 if (IT_STRING_CHARPOS (*it) > 0)
5955 {
5956 if (!it->bidi_p)
5957 {
5958 --IT_STRING_CHARPOS (*it);
5959 --IT_STRING_BYTEPOS (*it);
5960 }
5961 else
5962 {
5963 /* We need to restore the bidi iterator to the state
5964 it had on the newline, and resync the IT's
5965 position with that. */
5966 it->bidi_it = bidi_it_prev;
5967 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
5968 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
5969 }
5970 }
5971 }
5972 else if (IT_CHARPOS (*it) > BEGV)
5973 {
5974 if (!it->bidi_p)
5975 {
5976 --IT_CHARPOS (*it);
5977 --IT_BYTEPOS (*it);
5978 }
5979 else
5980 {
5981 /* We need to restore the bidi iterator to the state it
5982 had on the newline and resync IT with that. */
5983 it->bidi_it = bidi_it_prev;
5984 IT_CHARPOS (*it) = it->bidi_it.charpos;
5985 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
5986 }
5987 reseat (it, it->current.pos, 0);
5988 }
5989 }
5990 else if (skipped_p)
5991 reseat (it, it->current.pos, 0);
5992
5993 CHECK_IT (it);
5994 }
5995
5996
5997 \f
5998 /***********************************************************************
5999 Changing an iterator's position
6000 ***********************************************************************/
6001
6002 /* Change IT's current position to POS in current_buffer. If FORCE_P
6003 is non-zero, always check for text properties at the new position.
6004 Otherwise, text properties are only looked up if POS >=
6005 IT->check_charpos of a property. */
6006
6007 static void
6008 reseat (struct it *it, struct text_pos pos, int force_p)
6009 {
6010 EMACS_INT original_pos = IT_CHARPOS (*it);
6011
6012 reseat_1 (it, pos, 0);
6013
6014 /* Determine where to check text properties. Avoid doing it
6015 where possible because text property lookup is very expensive. */
6016 if (force_p
6017 || CHARPOS (pos) > it->stop_charpos
6018 || CHARPOS (pos) < original_pos)
6019 {
6020 if (it->bidi_p)
6021 {
6022 /* For bidi iteration, we need to prime prev_stop and
6023 base_level_stop with our best estimations. */
6024 /* Implementation note: Of course, POS is not necessarily a
6025 stop position, so assigning prev_pos to it is a lie; we
6026 should have called compute_stop_backwards. However, if
6027 the current buffer does not include any R2L characters,
6028 that call would be a waste of cycles, because the
6029 iterator will never move back, and thus never cross this
6030 "fake" stop position. So we delay that backward search
6031 until the time we really need it, in next_element_from_buffer. */
6032 if (CHARPOS (pos) != it->prev_stop)
6033 it->prev_stop = CHARPOS (pos);
6034 if (CHARPOS (pos) < it->base_level_stop)
6035 it->base_level_stop = 0; /* meaning it's unknown */
6036 handle_stop (it);
6037 }
6038 else
6039 {
6040 handle_stop (it);
6041 it->prev_stop = it->base_level_stop = 0;
6042 }
6043
6044 }
6045
6046 CHECK_IT (it);
6047 }
6048
6049
6050 /* Change IT's buffer position to POS. SET_STOP_P non-zero means set
6051 IT->stop_pos to POS, also. */
6052
6053 static void
6054 reseat_1 (struct it *it, struct text_pos pos, int set_stop_p)
6055 {
6056 /* Don't call this function when scanning a C string. */
6057 xassert (it->s == NULL);
6058
6059 /* POS must be a reasonable value. */
6060 xassert (CHARPOS (pos) >= BEGV && CHARPOS (pos) <= ZV);
6061
6062 it->current.pos = it->position = pos;
6063 it->end_charpos = ZV;
6064 it->dpvec = NULL;
6065 it->current.dpvec_index = -1;
6066 it->current.overlay_string_index = -1;
6067 IT_STRING_CHARPOS (*it) = -1;
6068 IT_STRING_BYTEPOS (*it) = -1;
6069 it->string = Qnil;
6070 it->method = GET_FROM_BUFFER;
6071 it->object = it->w->buffer;
6072 it->area = TEXT_AREA;
6073 it->multibyte_p = !NILP (BVAR (current_buffer, enable_multibyte_characters));
6074 it->sp = 0;
6075 it->string_from_display_prop_p = 0;
6076 it->from_disp_prop_p = 0;
6077 it->face_before_selective_p = 0;
6078 if (it->bidi_p)
6079 {
6080 bidi_init_it (IT_CHARPOS (*it), IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f),
6081 &it->bidi_it);
6082 bidi_unshelve_cache (NULL, 0);
6083 it->bidi_it.paragraph_dir = NEUTRAL_DIR;
6084 it->bidi_it.string.s = NULL;
6085 it->bidi_it.string.lstring = Qnil;
6086 it->bidi_it.string.bufpos = 0;
6087 it->bidi_it.string.unibyte = 0;
6088 }
6089
6090 if (set_stop_p)
6091 {
6092 it->stop_charpos = CHARPOS (pos);
6093 it->base_level_stop = CHARPOS (pos);
6094 }
6095 }
6096
6097
6098 /* Set up IT for displaying a string, starting at CHARPOS in window W.
6099 If S is non-null, it is a C string to iterate over. Otherwise,
6100 STRING gives a Lisp string to iterate over.
6101
6102 If PRECISION > 0, don't return more then PRECISION number of
6103 characters from the string.
6104
6105 If FIELD_WIDTH > 0, return padding spaces until FIELD_WIDTH
6106 characters have been returned. FIELD_WIDTH < 0 means an infinite
6107 field width.
6108
6109 MULTIBYTE = 0 means disable processing of multibyte characters,
6110 MULTIBYTE > 0 means enable it,
6111 MULTIBYTE < 0 means use IT->multibyte_p.
6112
6113 IT must be initialized via a prior call to init_iterator before
6114 calling this function. */
6115
6116 static void
6117 reseat_to_string (struct it *it, const char *s, Lisp_Object string,
6118 EMACS_INT charpos, EMACS_INT precision, int field_width,
6119 int multibyte)
6120 {
6121 /* No region in strings. */
6122 it->region_beg_charpos = it->region_end_charpos = -1;
6123
6124 /* No text property checks performed by default, but see below. */
6125 it->stop_charpos = -1;
6126
6127 /* Set iterator position and end position. */
6128 memset (&it->current, 0, sizeof it->current);
6129 it->current.overlay_string_index = -1;
6130 it->current.dpvec_index = -1;
6131 xassert (charpos >= 0);
6132
6133 /* If STRING is specified, use its multibyteness, otherwise use the
6134 setting of MULTIBYTE, if specified. */
6135 if (multibyte >= 0)
6136 it->multibyte_p = multibyte > 0;
6137
6138 /* Bidirectional reordering of strings is controlled by the default
6139 value of bidi-display-reordering. */
6140 it->bidi_p = !NILP (BVAR (&buffer_defaults, bidi_display_reordering));
6141
6142 if (s == NULL)
6143 {
6144 xassert (STRINGP (string));
6145 it->string = string;
6146 it->s = NULL;
6147 it->end_charpos = it->string_nchars = SCHARS (string);
6148 it->method = GET_FROM_STRING;
6149 it->current.string_pos = string_pos (charpos, string);
6150
6151 if (it->bidi_p)
6152 {
6153 it->bidi_it.string.lstring = string;
6154 it->bidi_it.string.s = NULL;
6155 it->bidi_it.string.schars = it->end_charpos;
6156 it->bidi_it.string.bufpos = 0;
6157 it->bidi_it.string.from_disp_str = 0;
6158 it->bidi_it.string.unibyte = !it->multibyte_p;
6159 bidi_init_it (charpos, IT_STRING_BYTEPOS (*it),
6160 FRAME_WINDOW_P (it->f), &it->bidi_it);
6161 }
6162 }
6163 else
6164 {
6165 it->s = (const unsigned char *) s;
6166 it->string = Qnil;
6167
6168 /* Note that we use IT->current.pos, not it->current.string_pos,
6169 for displaying C strings. */
6170 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
6171 if (it->multibyte_p)
6172 {
6173 it->current.pos = c_string_pos (charpos, s, 1);
6174 it->end_charpos = it->string_nchars = number_of_chars (s, 1);
6175 }
6176 else
6177 {
6178 IT_CHARPOS (*it) = IT_BYTEPOS (*it) = charpos;
6179 it->end_charpos = it->string_nchars = strlen (s);
6180 }
6181
6182 if (it->bidi_p)
6183 {
6184 it->bidi_it.string.lstring = Qnil;
6185 it->bidi_it.string.s = (const unsigned char *) s;
6186 it->bidi_it.string.schars = it->end_charpos;
6187 it->bidi_it.string.bufpos = 0;
6188 it->bidi_it.string.from_disp_str = 0;
6189 it->bidi_it.string.unibyte = !it->multibyte_p;
6190 bidi_init_it (charpos, IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f),
6191 &it->bidi_it);
6192 }
6193 it->method = GET_FROM_C_STRING;
6194 }
6195
6196 /* PRECISION > 0 means don't return more than PRECISION characters
6197 from the string. */
6198 if (precision > 0 && it->end_charpos - charpos > precision)
6199 {
6200 it->end_charpos = it->string_nchars = charpos + precision;
6201 if (it->bidi_p)
6202 it->bidi_it.string.schars = it->end_charpos;
6203 }
6204
6205 /* FIELD_WIDTH > 0 means pad with spaces until FIELD_WIDTH
6206 characters have been returned. FIELD_WIDTH == 0 means don't pad,
6207 FIELD_WIDTH < 0 means infinite field width. This is useful for
6208 padding with `-' at the end of a mode line. */
6209 if (field_width < 0)
6210 field_width = INFINITY;
6211 /* Implementation note: We deliberately don't enlarge
6212 it->bidi_it.string.schars here to fit it->end_charpos, because
6213 the bidi iterator cannot produce characters out of thin air. */
6214 if (field_width > it->end_charpos - charpos)
6215 it->end_charpos = charpos + field_width;
6216
6217 /* Use the standard display table for displaying strings. */
6218 if (DISP_TABLE_P (Vstandard_display_table))
6219 it->dp = XCHAR_TABLE (Vstandard_display_table);
6220
6221 it->stop_charpos = charpos;
6222 it->prev_stop = charpos;
6223 it->base_level_stop = 0;
6224 if (it->bidi_p)
6225 {
6226 it->bidi_it.first_elt = 1;
6227 it->bidi_it.paragraph_dir = NEUTRAL_DIR;
6228 it->bidi_it.disp_pos = -1;
6229 }
6230 if (s == NULL && it->multibyte_p)
6231 {
6232 EMACS_INT endpos = SCHARS (it->string);
6233 if (endpos > it->end_charpos)
6234 endpos = it->end_charpos;
6235 composition_compute_stop_pos (&it->cmp_it, charpos, -1, endpos,
6236 it->string);
6237 }
6238 CHECK_IT (it);
6239 }
6240
6241
6242 \f
6243 /***********************************************************************
6244 Iteration
6245 ***********************************************************************/
6246
6247 /* Map enum it_method value to corresponding next_element_from_* function. */
6248
6249 static int (* get_next_element[NUM_IT_METHODS]) (struct it *it) =
6250 {
6251 next_element_from_buffer,
6252 next_element_from_display_vector,
6253 next_element_from_string,
6254 next_element_from_c_string,
6255 next_element_from_image,
6256 next_element_from_stretch
6257 };
6258
6259 #define GET_NEXT_DISPLAY_ELEMENT(it) (*get_next_element[(it)->method]) (it)
6260
6261
6262 /* Return 1 iff a character at CHARPOS (and BYTEPOS) is composed
6263 (possibly with the following characters). */
6264
6265 #define CHAR_COMPOSED_P(IT,CHARPOS,BYTEPOS,END_CHARPOS) \
6266 ((IT)->cmp_it.id >= 0 \
6267 || ((IT)->cmp_it.stop_pos == (CHARPOS) \
6268 && composition_reseat_it (&(IT)->cmp_it, CHARPOS, BYTEPOS, \
6269 END_CHARPOS, (IT)->w, \
6270 FACE_FROM_ID ((IT)->f, (IT)->face_id), \
6271 (IT)->string)))
6272
6273
6274 /* Lookup the char-table Vglyphless_char_display for character C (-1
6275 if we want information for no-font case), and return the display
6276 method symbol. By side-effect, update it->what and
6277 it->glyphless_method. This function is called from
6278 get_next_display_element for each character element, and from
6279 x_produce_glyphs when no suitable font was found. */
6280
6281 Lisp_Object
6282 lookup_glyphless_char_display (int c, struct it *it)
6283 {
6284 Lisp_Object glyphless_method = Qnil;
6285
6286 if (CHAR_TABLE_P (Vglyphless_char_display)
6287 && CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (Vglyphless_char_display)) >= 1)
6288 {
6289 if (c >= 0)
6290 {
6291 glyphless_method = CHAR_TABLE_REF (Vglyphless_char_display, c);
6292 if (CONSP (glyphless_method))
6293 glyphless_method = FRAME_WINDOW_P (it->f)
6294 ? XCAR (glyphless_method)
6295 : XCDR (glyphless_method);
6296 }
6297 else
6298 glyphless_method = XCHAR_TABLE (Vglyphless_char_display)->extras[0];
6299 }
6300
6301 retry:
6302 if (NILP (glyphless_method))
6303 {
6304 if (c >= 0)
6305 /* The default is to display the character by a proper font. */
6306 return Qnil;
6307 /* The default for the no-font case is to display an empty box. */
6308 glyphless_method = Qempty_box;
6309 }
6310 if (EQ (glyphless_method, Qzero_width))
6311 {
6312 if (c >= 0)
6313 return glyphless_method;
6314 /* This method can't be used for the no-font case. */
6315 glyphless_method = Qempty_box;
6316 }
6317 if (EQ (glyphless_method, Qthin_space))
6318 it->glyphless_method = GLYPHLESS_DISPLAY_THIN_SPACE;
6319 else if (EQ (glyphless_method, Qempty_box))
6320 it->glyphless_method = GLYPHLESS_DISPLAY_EMPTY_BOX;
6321 else if (EQ (glyphless_method, Qhex_code))
6322 it->glyphless_method = GLYPHLESS_DISPLAY_HEX_CODE;
6323 else if (STRINGP (glyphless_method))
6324 it->glyphless_method = GLYPHLESS_DISPLAY_ACRONYM;
6325 else
6326 {
6327 /* Invalid value. We use the default method. */
6328 glyphless_method = Qnil;
6329 goto retry;
6330 }
6331 it->what = IT_GLYPHLESS;
6332 return glyphless_method;
6333 }
6334
6335 /* Load IT's display element fields with information about the next
6336 display element from the current position of IT. Value is zero if
6337 end of buffer (or C string) is reached. */
6338
6339 static struct frame *last_escape_glyph_frame = NULL;
6340 static unsigned last_escape_glyph_face_id = (1 << FACE_ID_BITS);
6341 static int last_escape_glyph_merged_face_id = 0;
6342
6343 struct frame *last_glyphless_glyph_frame = NULL;
6344 unsigned last_glyphless_glyph_face_id = (1 << FACE_ID_BITS);
6345 int last_glyphless_glyph_merged_face_id = 0;
6346
6347 static int
6348 get_next_display_element (struct it *it)
6349 {
6350 /* Non-zero means that we found a display element. Zero means that
6351 we hit the end of what we iterate over. Performance note: the
6352 function pointer `method' used here turns out to be faster than
6353 using a sequence of if-statements. */
6354 int success_p;
6355
6356 get_next:
6357 success_p = GET_NEXT_DISPLAY_ELEMENT (it);
6358
6359 if (it->what == IT_CHARACTER)
6360 {
6361 /* UAX#9, L4: "A character is depicted by a mirrored glyph if
6362 and only if (a) the resolved directionality of that character
6363 is R..." */
6364 /* FIXME: Do we need an exception for characters from display
6365 tables? */
6366 if (it->bidi_p && it->bidi_it.type == STRONG_R)
6367 it->c = bidi_mirror_char (it->c);
6368 /* Map via display table or translate control characters.
6369 IT->c, IT->len etc. have been set to the next character by
6370 the function call above. If we have a display table, and it
6371 contains an entry for IT->c, translate it. Don't do this if
6372 IT->c itself comes from a display table, otherwise we could
6373 end up in an infinite recursion. (An alternative could be to
6374 count the recursion depth of this function and signal an
6375 error when a certain maximum depth is reached.) Is it worth
6376 it? */
6377 if (success_p && it->dpvec == NULL)
6378 {
6379 Lisp_Object dv;
6380 struct charset *unibyte = CHARSET_FROM_ID (charset_unibyte);
6381 int nonascii_space_p = 0;
6382 int nonascii_hyphen_p = 0;
6383 int c = it->c; /* This is the character to display. */
6384
6385 if (! it->multibyte_p && ! ASCII_CHAR_P (c))
6386 {
6387 xassert (SINGLE_BYTE_CHAR_P (c));
6388 if (unibyte_display_via_language_environment)
6389 {
6390 c = DECODE_CHAR (unibyte, c);
6391 if (c < 0)
6392 c = BYTE8_TO_CHAR (it->c);
6393 }
6394 else
6395 c = BYTE8_TO_CHAR (it->c);
6396 }
6397
6398 if (it->dp
6399 && (dv = DISP_CHAR_VECTOR (it->dp, c),
6400 VECTORP (dv)))
6401 {
6402 struct Lisp_Vector *v = XVECTOR (dv);
6403
6404 /* Return the first character from the display table
6405 entry, if not empty. If empty, don't display the
6406 current character. */
6407 if (v->header.size)
6408 {
6409 it->dpvec_char_len = it->len;
6410 it->dpvec = v->contents;
6411 it->dpend = v->contents + v->header.size;
6412 it->current.dpvec_index = 0;
6413 it->dpvec_face_id = -1;
6414 it->saved_face_id = it->face_id;
6415 it->method = GET_FROM_DISPLAY_VECTOR;
6416 it->ellipsis_p = 0;
6417 }
6418 else
6419 {
6420 set_iterator_to_next (it, 0);
6421 }
6422 goto get_next;
6423 }
6424
6425 if (! NILP (lookup_glyphless_char_display (c, it)))
6426 {
6427 if (it->what == IT_GLYPHLESS)
6428 goto done;
6429 /* Don't display this character. */
6430 set_iterator_to_next (it, 0);
6431 goto get_next;
6432 }
6433
6434 /* If `nobreak-char-display' is non-nil, we display
6435 non-ASCII spaces and hyphens specially. */
6436 if (! ASCII_CHAR_P (c) && ! NILP (Vnobreak_char_display))
6437 {
6438 if (c == 0xA0)
6439 nonascii_space_p = 1;
6440 else if (c == 0xAD || c == 0x2010 || c == 0x2011)
6441 nonascii_hyphen_p = 1;
6442 }
6443
6444 /* Translate control characters into `\003' or `^C' form.
6445 Control characters coming from a display table entry are
6446 currently not translated because we use IT->dpvec to hold
6447 the translation. This could easily be changed but I
6448 don't believe that it is worth doing.
6449
6450 The characters handled by `nobreak-char-display' must be
6451 translated too.
6452
6453 Non-printable characters and raw-byte characters are also
6454 translated to octal form. */
6455 if (((c < ' ' || c == 127) /* ASCII control chars */
6456 ? (it->area != TEXT_AREA
6457 /* In mode line, treat \n, \t like other crl chars. */
6458 || (c != '\t'
6459 && it->glyph_row
6460 && (it->glyph_row->mode_line_p || it->avoid_cursor_p))
6461 || (c != '\n' && c != '\t'))
6462 : (nonascii_space_p
6463 || nonascii_hyphen_p
6464 || CHAR_BYTE8_P (c)
6465 || ! CHAR_PRINTABLE_P (c))))
6466 {
6467 /* C is a control character, non-ASCII space/hyphen,
6468 raw-byte, or a non-printable character which must be
6469 displayed either as '\003' or as `^C' where the '\\'
6470 and '^' can be defined in the display table. Fill
6471 IT->ctl_chars with glyphs for what we have to
6472 display. Then, set IT->dpvec to these glyphs. */
6473 Lisp_Object gc;
6474 int ctl_len;
6475 int face_id;
6476 EMACS_INT lface_id = 0;
6477 int escape_glyph;
6478
6479 /* Handle control characters with ^. */
6480
6481 if (ASCII_CHAR_P (c) && it->ctl_arrow_p)
6482 {
6483 int g;
6484
6485 g = '^'; /* default glyph for Control */
6486 /* Set IT->ctl_chars[0] to the glyph for `^'. */
6487 if (it->dp
6488 && (gc = DISP_CTRL_GLYPH (it->dp), GLYPH_CODE_P (gc))
6489 && GLYPH_CODE_CHAR_VALID_P (gc))
6490 {
6491 g = GLYPH_CODE_CHAR (gc);
6492 lface_id = GLYPH_CODE_FACE (gc);
6493 }
6494 if (lface_id)
6495 {
6496 face_id = merge_faces (it->f, Qt, lface_id, it->face_id);
6497 }
6498 else if (it->f == last_escape_glyph_frame
6499 && it->face_id == last_escape_glyph_face_id)
6500 {
6501 face_id = last_escape_glyph_merged_face_id;
6502 }
6503 else
6504 {
6505 /* Merge the escape-glyph face into the current face. */
6506 face_id = merge_faces (it->f, Qescape_glyph, 0,
6507 it->face_id);
6508 last_escape_glyph_frame = it->f;
6509 last_escape_glyph_face_id = it->face_id;
6510 last_escape_glyph_merged_face_id = face_id;
6511 }
6512
6513 XSETINT (it->ctl_chars[0], g);
6514 XSETINT (it->ctl_chars[1], c ^ 0100);
6515 ctl_len = 2;
6516 goto display_control;
6517 }
6518
6519 /* Handle non-ascii space in the mode where it only gets
6520 highlighting. */
6521
6522 if (nonascii_space_p && EQ (Vnobreak_char_display, Qt))
6523 {
6524 /* Merge `nobreak-space' into the current face. */
6525 face_id = merge_faces (it->f, Qnobreak_space, 0,
6526 it->face_id);
6527 XSETINT (it->ctl_chars[0], ' ');
6528 ctl_len = 1;
6529 goto display_control;
6530 }
6531
6532 /* Handle sequences that start with the "escape glyph". */
6533
6534 /* the default escape glyph is \. */
6535 escape_glyph = '\\';
6536
6537 if (it->dp
6538 && (gc = DISP_ESCAPE_GLYPH (it->dp), GLYPH_CODE_P (gc))
6539 && GLYPH_CODE_CHAR_VALID_P (gc))
6540 {
6541 escape_glyph = GLYPH_CODE_CHAR (gc);
6542 lface_id = GLYPH_CODE_FACE (gc);
6543 }
6544 if (lface_id)
6545 {
6546 /* The display table specified a face.
6547 Merge it into face_id and also into escape_glyph. */
6548 face_id = merge_faces (it->f, Qt, lface_id,
6549 it->face_id);
6550 }
6551 else if (it->f == last_escape_glyph_frame
6552 && it->face_id == last_escape_glyph_face_id)
6553 {
6554 face_id = last_escape_glyph_merged_face_id;
6555 }
6556 else
6557 {
6558 /* Merge the escape-glyph face into the current face. */
6559 face_id = merge_faces (it->f, Qescape_glyph, 0,
6560 it->face_id);
6561 last_escape_glyph_frame = it->f;
6562 last_escape_glyph_face_id = it->face_id;
6563 last_escape_glyph_merged_face_id = face_id;
6564 }
6565
6566 /* Draw non-ASCII hyphen with just highlighting: */
6567
6568 if (nonascii_hyphen_p && EQ (Vnobreak_char_display, Qt))
6569 {
6570 XSETINT (it->ctl_chars[0], '-');
6571 ctl_len = 1;
6572 goto display_control;
6573 }
6574
6575 /* Draw non-ASCII space/hyphen with escape glyph: */
6576
6577 if (nonascii_space_p || nonascii_hyphen_p)
6578 {
6579 XSETINT (it->ctl_chars[0], escape_glyph);
6580 XSETINT (it->ctl_chars[1], nonascii_space_p ? ' ' : '-');
6581 ctl_len = 2;
6582 goto display_control;
6583 }
6584
6585 {
6586 char str[10];
6587 int len, i;
6588
6589 if (CHAR_BYTE8_P (c))
6590 /* Display \200 instead of \17777600. */
6591 c = CHAR_TO_BYTE8 (c);
6592 len = sprintf (str, "%03o", c);
6593
6594 XSETINT (it->ctl_chars[0], escape_glyph);
6595 for (i = 0; i < len; i++)
6596 XSETINT (it->ctl_chars[i + 1], str[i]);
6597 ctl_len = len + 1;
6598 }
6599
6600 display_control:
6601 /* Set up IT->dpvec and return first character from it. */
6602 it->dpvec_char_len = it->len;
6603 it->dpvec = it->ctl_chars;
6604 it->dpend = it->dpvec + ctl_len;
6605 it->current.dpvec_index = 0;
6606 it->dpvec_face_id = face_id;
6607 it->saved_face_id = it->face_id;
6608 it->method = GET_FROM_DISPLAY_VECTOR;
6609 it->ellipsis_p = 0;
6610 goto get_next;
6611 }
6612 it->char_to_display = c;
6613 }
6614 else if (success_p)
6615 {
6616 it->char_to_display = it->c;
6617 }
6618 }
6619
6620 /* Adjust face id for a multibyte character. There are no multibyte
6621 character in unibyte text. */
6622 if ((it->what == IT_CHARACTER || it->what == IT_COMPOSITION)
6623 && it->multibyte_p
6624 && success_p
6625 && FRAME_WINDOW_P (it->f))
6626 {
6627 struct face *face = FACE_FROM_ID (it->f, it->face_id);
6628
6629 if (it->what == IT_COMPOSITION && it->cmp_it.ch >= 0)
6630 {
6631 /* Automatic composition with glyph-string. */
6632 Lisp_Object gstring = composition_gstring_from_id (it->cmp_it.id);
6633
6634 it->face_id = face_for_font (it->f, LGSTRING_FONT (gstring), face);
6635 }
6636 else
6637 {
6638 EMACS_INT pos = (it->s ? -1
6639 : STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
6640 : IT_CHARPOS (*it));
6641 int c;
6642
6643 if (it->what == IT_CHARACTER)
6644 c = it->char_to_display;
6645 else
6646 {
6647 struct composition *cmp = composition_table[it->cmp_it.id];
6648 int i;
6649
6650 c = ' ';
6651 for (i = 0; i < cmp->glyph_len; i++)
6652 /* TAB in a composition means display glyphs with
6653 padding space on the left or right. */
6654 if ((c = COMPOSITION_GLYPH (cmp, i)) != '\t')
6655 break;
6656 }
6657 it->face_id = FACE_FOR_CHAR (it->f, face, c, pos, it->string);
6658 }
6659 }
6660
6661 done:
6662 /* Is this character the last one of a run of characters with
6663 box? If yes, set IT->end_of_box_run_p to 1. */
6664 if (it->face_box_p
6665 && it->s == NULL)
6666 {
6667 if (it->method == GET_FROM_STRING && it->sp)
6668 {
6669 int face_id = underlying_face_id (it);
6670 struct face *face = FACE_FROM_ID (it->f, face_id);
6671
6672 if (face)
6673 {
6674 if (face->box == FACE_NO_BOX)
6675 {
6676 /* If the box comes from face properties in a
6677 display string, check faces in that string. */
6678 int string_face_id = face_after_it_pos (it);
6679 it->end_of_box_run_p
6680 = (FACE_FROM_ID (it->f, string_face_id)->box
6681 == FACE_NO_BOX);
6682 }
6683 /* Otherwise, the box comes from the underlying face.
6684 If this is the last string character displayed, check
6685 the next buffer location. */
6686 else if ((IT_STRING_CHARPOS (*it) >= SCHARS (it->string) - 1)
6687 && (it->current.overlay_string_index
6688 == it->n_overlay_strings - 1))
6689 {
6690 EMACS_INT ignore;
6691 int next_face_id;
6692 struct text_pos pos = it->current.pos;
6693 INC_TEXT_POS (pos, it->multibyte_p);
6694
6695 next_face_id = face_at_buffer_position
6696 (it->w, CHARPOS (pos), it->region_beg_charpos,
6697 it->region_end_charpos, &ignore,
6698 (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT), 0,
6699 -1);
6700 it->end_of_box_run_p
6701 = (FACE_FROM_ID (it->f, next_face_id)->box
6702 == FACE_NO_BOX);
6703 }
6704 }
6705 }
6706 else
6707 {
6708 int face_id = face_after_it_pos (it);
6709 it->end_of_box_run_p
6710 = (face_id != it->face_id
6711 && FACE_FROM_ID (it->f, face_id)->box == FACE_NO_BOX);
6712 }
6713 }
6714
6715 /* Value is 0 if end of buffer or string reached. */
6716 return success_p;
6717 }
6718
6719
6720 /* Move IT to the next display element.
6721
6722 RESEAT_P non-zero means if called on a newline in buffer text,
6723 skip to the next visible line start.
6724
6725 Functions get_next_display_element and set_iterator_to_next are
6726 separate because I find this arrangement easier to handle than a
6727 get_next_display_element function that also increments IT's
6728 position. The way it is we can first look at an iterator's current
6729 display element, decide whether it fits on a line, and if it does,
6730 increment the iterator position. The other way around we probably
6731 would either need a flag indicating whether the iterator has to be
6732 incremented the next time, or we would have to implement a
6733 decrement position function which would not be easy to write. */
6734
6735 void
6736 set_iterator_to_next (struct it *it, int reseat_p)
6737 {
6738 /* Reset flags indicating start and end of a sequence of characters
6739 with box. Reset them at the start of this function because
6740 moving the iterator to a new position might set them. */
6741 it->start_of_box_run_p = it->end_of_box_run_p = 0;
6742
6743 switch (it->method)
6744 {
6745 case GET_FROM_BUFFER:
6746 /* The current display element of IT is a character from
6747 current_buffer. Advance in the buffer, and maybe skip over
6748 invisible lines that are so because of selective display. */
6749 if (ITERATOR_AT_END_OF_LINE_P (it) && reseat_p)
6750 reseat_at_next_visible_line_start (it, 0);
6751 else if (it->cmp_it.id >= 0)
6752 {
6753 /* We are currently getting glyphs from a composition. */
6754 int i;
6755
6756 if (! it->bidi_p)
6757 {
6758 IT_CHARPOS (*it) += it->cmp_it.nchars;
6759 IT_BYTEPOS (*it) += it->cmp_it.nbytes;
6760 if (it->cmp_it.to < it->cmp_it.nglyphs)
6761 {
6762 it->cmp_it.from = it->cmp_it.to;
6763 }
6764 else
6765 {
6766 it->cmp_it.id = -1;
6767 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
6768 IT_BYTEPOS (*it),
6769 it->end_charpos, Qnil);
6770 }
6771 }
6772 else if (! it->cmp_it.reversed_p)
6773 {
6774 /* Composition created while scanning forward. */
6775 /* Update IT's char/byte positions to point to the first
6776 character of the next grapheme cluster, or to the
6777 character visually after the current composition. */
6778 for (i = 0; i < it->cmp_it.nchars; i++)
6779 bidi_move_to_visually_next (&it->bidi_it);
6780 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
6781 IT_CHARPOS (*it) = it->bidi_it.charpos;
6782
6783 if (it->cmp_it.to < it->cmp_it.nglyphs)
6784 {
6785 /* Proceed to the next grapheme cluster. */
6786 it->cmp_it.from = it->cmp_it.to;
6787 }
6788 else
6789 {
6790 /* No more grapheme clusters in this composition.
6791 Find the next stop position. */
6792 EMACS_INT stop = it->end_charpos;
6793 if (it->bidi_it.scan_dir < 0)
6794 /* Now we are scanning backward and don't know
6795 where to stop. */
6796 stop = -1;
6797 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
6798 IT_BYTEPOS (*it), stop, Qnil);
6799 }
6800 }
6801 else
6802 {
6803 /* Composition created while scanning backward. */
6804 /* Update IT's char/byte positions to point to the last
6805 character of the previous grapheme cluster, or the
6806 character visually after the current composition. */
6807 for (i = 0; i < it->cmp_it.nchars; i++)
6808 bidi_move_to_visually_next (&it->bidi_it);
6809 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
6810 IT_CHARPOS (*it) = it->bidi_it.charpos;
6811 if (it->cmp_it.from > 0)
6812 {
6813 /* Proceed to the previous grapheme cluster. */
6814 it->cmp_it.to = it->cmp_it.from;
6815 }
6816 else
6817 {
6818 /* No more grapheme clusters in this composition.
6819 Find the next stop position. */
6820 EMACS_INT stop = it->end_charpos;
6821 if (it->bidi_it.scan_dir < 0)
6822 /* Now we are scanning backward and don't know
6823 where to stop. */
6824 stop = -1;
6825 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
6826 IT_BYTEPOS (*it), stop, Qnil);
6827 }
6828 }
6829 }
6830 else
6831 {
6832 xassert (it->len != 0);
6833
6834 if (!it->bidi_p)
6835 {
6836 IT_BYTEPOS (*it) += it->len;
6837 IT_CHARPOS (*it) += 1;
6838 }
6839 else
6840 {
6841 int prev_scan_dir = it->bidi_it.scan_dir;
6842 /* If this is a new paragraph, determine its base
6843 direction (a.k.a. its base embedding level). */
6844 if (it->bidi_it.new_paragraph)
6845 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 0);
6846 bidi_move_to_visually_next (&it->bidi_it);
6847 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
6848 IT_CHARPOS (*it) = it->bidi_it.charpos;
6849 if (prev_scan_dir != it->bidi_it.scan_dir)
6850 {
6851 /* As the scan direction was changed, we must
6852 re-compute the stop position for composition. */
6853 EMACS_INT stop = it->end_charpos;
6854 if (it->bidi_it.scan_dir < 0)
6855 stop = -1;
6856 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
6857 IT_BYTEPOS (*it), stop, Qnil);
6858 }
6859 }
6860 xassert (IT_BYTEPOS (*it) == CHAR_TO_BYTE (IT_CHARPOS (*it)));
6861 }
6862 break;
6863
6864 case GET_FROM_C_STRING:
6865 /* Current display element of IT is from a C string. */
6866 if (!it->bidi_p
6867 /* If the string position is beyond string's end, it means
6868 next_element_from_c_string is padding the string with
6869 blanks, in which case we bypass the bidi iterator,
6870 because it cannot deal with such virtual characters. */
6871 || IT_CHARPOS (*it) >= it->bidi_it.string.schars)
6872 {
6873 IT_BYTEPOS (*it) += it->len;
6874 IT_CHARPOS (*it) += 1;
6875 }
6876 else
6877 {
6878 bidi_move_to_visually_next (&it->bidi_it);
6879 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
6880 IT_CHARPOS (*it) = it->bidi_it.charpos;
6881 }
6882 break;
6883
6884 case GET_FROM_DISPLAY_VECTOR:
6885 /* Current display element of IT is from a display table entry.
6886 Advance in the display table definition. Reset it to null if
6887 end reached, and continue with characters from buffers/
6888 strings. */
6889 ++it->current.dpvec_index;
6890
6891 /* Restore face of the iterator to what they were before the
6892 display vector entry (these entries may contain faces). */
6893 it->face_id = it->saved_face_id;
6894
6895 if (it->dpvec + it->current.dpvec_index == it->dpend)
6896 {
6897 int recheck_faces = it->ellipsis_p;
6898
6899 if (it->s)
6900 it->method = GET_FROM_C_STRING;
6901 else if (STRINGP (it->string))
6902 it->method = GET_FROM_STRING;
6903 else
6904 {
6905 it->method = GET_FROM_BUFFER;
6906 it->object = it->w->buffer;
6907 }
6908
6909 it->dpvec = NULL;
6910 it->current.dpvec_index = -1;
6911
6912 /* Skip over characters which were displayed via IT->dpvec. */
6913 if (it->dpvec_char_len < 0)
6914 reseat_at_next_visible_line_start (it, 1);
6915 else if (it->dpvec_char_len > 0)
6916 {
6917 if (it->method == GET_FROM_STRING
6918 && it->n_overlay_strings > 0)
6919 it->ignore_overlay_strings_at_pos_p = 1;
6920 it->len = it->dpvec_char_len;
6921 set_iterator_to_next (it, reseat_p);
6922 }
6923
6924 /* Maybe recheck faces after display vector */
6925 if (recheck_faces)
6926 it->stop_charpos = IT_CHARPOS (*it);
6927 }
6928 break;
6929
6930 case GET_FROM_STRING:
6931 /* Current display element is a character from a Lisp string. */
6932 xassert (it->s == NULL && STRINGP (it->string));
6933 if (it->cmp_it.id >= 0)
6934 {
6935 int i;
6936
6937 if (! it->bidi_p)
6938 {
6939 IT_STRING_CHARPOS (*it) += it->cmp_it.nchars;
6940 IT_STRING_BYTEPOS (*it) += it->cmp_it.nbytes;
6941 if (it->cmp_it.to < it->cmp_it.nglyphs)
6942 it->cmp_it.from = it->cmp_it.to;
6943 else
6944 {
6945 it->cmp_it.id = -1;
6946 composition_compute_stop_pos (&it->cmp_it,
6947 IT_STRING_CHARPOS (*it),
6948 IT_STRING_BYTEPOS (*it),
6949 it->end_charpos, it->string);
6950 }
6951 }
6952 else if (! it->cmp_it.reversed_p)
6953 {
6954 for (i = 0; i < it->cmp_it.nchars; i++)
6955 bidi_move_to_visually_next (&it->bidi_it);
6956 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
6957 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
6958
6959 if (it->cmp_it.to < it->cmp_it.nglyphs)
6960 it->cmp_it.from = it->cmp_it.to;
6961 else
6962 {
6963 EMACS_INT stop = it->end_charpos;
6964 if (it->bidi_it.scan_dir < 0)
6965 stop = -1;
6966 composition_compute_stop_pos (&it->cmp_it,
6967 IT_STRING_CHARPOS (*it),
6968 IT_STRING_BYTEPOS (*it), stop,
6969 it->string);
6970 }
6971 }
6972 else
6973 {
6974 for (i = 0; i < it->cmp_it.nchars; i++)
6975 bidi_move_to_visually_next (&it->bidi_it);
6976 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
6977 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
6978 if (it->cmp_it.from > 0)
6979 it->cmp_it.to = it->cmp_it.from;
6980 else
6981 {
6982 EMACS_INT stop = it->end_charpos;
6983 if (it->bidi_it.scan_dir < 0)
6984 stop = -1;
6985 composition_compute_stop_pos (&it->cmp_it,
6986 IT_STRING_CHARPOS (*it),
6987 IT_STRING_BYTEPOS (*it), stop,
6988 it->string);
6989 }
6990 }
6991 }
6992 else
6993 {
6994 if (!it->bidi_p
6995 /* If the string position is beyond string's end, it
6996 means next_element_from_string is padding the string
6997 with blanks, in which case we bypass the bidi
6998 iterator, because it cannot deal with such virtual
6999 characters. */
7000 || IT_STRING_CHARPOS (*it) >= it->bidi_it.string.schars)
7001 {
7002 IT_STRING_BYTEPOS (*it) += it->len;
7003 IT_STRING_CHARPOS (*it) += 1;
7004 }
7005 else
7006 {
7007 int prev_scan_dir = it->bidi_it.scan_dir;
7008
7009 bidi_move_to_visually_next (&it->bidi_it);
7010 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
7011 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
7012 if (prev_scan_dir != it->bidi_it.scan_dir)
7013 {
7014 EMACS_INT stop = it->end_charpos;
7015
7016 if (it->bidi_it.scan_dir < 0)
7017 stop = -1;
7018 composition_compute_stop_pos (&it->cmp_it,
7019 IT_STRING_CHARPOS (*it),
7020 IT_STRING_BYTEPOS (*it), stop,
7021 it->string);
7022 }
7023 }
7024 }
7025
7026 consider_string_end:
7027
7028 if (it->current.overlay_string_index >= 0)
7029 {
7030 /* IT->string is an overlay string. Advance to the
7031 next, if there is one. */
7032 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
7033 {
7034 it->ellipsis_p = 0;
7035 next_overlay_string (it);
7036 if (it->ellipsis_p)
7037 setup_for_ellipsis (it, 0);
7038 }
7039 }
7040 else
7041 {
7042 /* IT->string is not an overlay string. If we reached
7043 its end, and there is something on IT->stack, proceed
7044 with what is on the stack. This can be either another
7045 string, this time an overlay string, or a buffer. */
7046 if (IT_STRING_CHARPOS (*it) == SCHARS (it->string)
7047 && it->sp > 0)
7048 {
7049 pop_it (it);
7050 if (it->method == GET_FROM_STRING)
7051 goto consider_string_end;
7052 }
7053 }
7054 break;
7055
7056 case GET_FROM_IMAGE:
7057 case GET_FROM_STRETCH:
7058 /* The position etc with which we have to proceed are on
7059 the stack. The position may be at the end of a string,
7060 if the `display' property takes up the whole string. */
7061 xassert (it->sp > 0);
7062 pop_it (it);
7063 if (it->method == GET_FROM_STRING)
7064 goto consider_string_end;
7065 break;
7066
7067 default:
7068 /* There are no other methods defined, so this should be a bug. */
7069 abort ();
7070 }
7071
7072 xassert (it->method != GET_FROM_STRING
7073 || (STRINGP (it->string)
7074 && IT_STRING_CHARPOS (*it) >= 0));
7075 }
7076
7077 /* Load IT's display element fields with information about the next
7078 display element which comes from a display table entry or from the
7079 result of translating a control character to one of the forms `^C'
7080 or `\003'.
7081
7082 IT->dpvec holds the glyphs to return as characters.
7083 IT->saved_face_id holds the face id before the display vector--it
7084 is restored into IT->face_id in set_iterator_to_next. */
7085
7086 static int
7087 next_element_from_display_vector (struct it *it)
7088 {
7089 Lisp_Object gc;
7090
7091 /* Precondition. */
7092 xassert (it->dpvec && it->current.dpvec_index >= 0);
7093
7094 it->face_id = it->saved_face_id;
7095
7096 /* KFS: This code used to check ip->dpvec[0] instead of the current element.
7097 That seemed totally bogus - so I changed it... */
7098 gc = it->dpvec[it->current.dpvec_index];
7099
7100 if (GLYPH_CODE_P (gc) && GLYPH_CODE_CHAR_VALID_P (gc))
7101 {
7102 it->c = GLYPH_CODE_CHAR (gc);
7103 it->len = CHAR_BYTES (it->c);
7104
7105 /* The entry may contain a face id to use. Such a face id is
7106 the id of a Lisp face, not a realized face. A face id of
7107 zero means no face is specified. */
7108 if (it->dpvec_face_id >= 0)
7109 it->face_id = it->dpvec_face_id;
7110 else
7111 {
7112 EMACS_INT lface_id = GLYPH_CODE_FACE (gc);
7113 if (lface_id > 0)
7114 it->face_id = merge_faces (it->f, Qt, lface_id,
7115 it->saved_face_id);
7116 }
7117 }
7118 else
7119 /* Display table entry is invalid. Return a space. */
7120 it->c = ' ', it->len = 1;
7121
7122 /* Don't change position and object of the iterator here. They are
7123 still the values of the character that had this display table
7124 entry or was translated, and that's what we want. */
7125 it->what = IT_CHARACTER;
7126 return 1;
7127 }
7128
7129 /* Get the first element of string/buffer in the visual order, after
7130 being reseated to a new position in a string or a buffer. */
7131 static void
7132 get_visually_first_element (struct it *it)
7133 {
7134 int string_p = STRINGP (it->string) || it->s;
7135 EMACS_INT eob = (string_p ? it->bidi_it.string.schars : ZV);
7136 EMACS_INT bob = (string_p ? 0 : BEGV);
7137
7138 if (STRINGP (it->string))
7139 {
7140 it->bidi_it.charpos = IT_STRING_CHARPOS (*it);
7141 it->bidi_it.bytepos = IT_STRING_BYTEPOS (*it);
7142 }
7143 else
7144 {
7145 it->bidi_it.charpos = IT_CHARPOS (*it);
7146 it->bidi_it.bytepos = IT_BYTEPOS (*it);
7147 }
7148
7149 if (it->bidi_it.charpos == eob)
7150 {
7151 /* Nothing to do, but reset the FIRST_ELT flag, like
7152 bidi_paragraph_init does, because we are not going to
7153 call it. */
7154 it->bidi_it.first_elt = 0;
7155 }
7156 else if (it->bidi_it.charpos == bob
7157 || (!string_p
7158 && (FETCH_CHAR (it->bidi_it.bytepos - 1) == '\n'
7159 || FETCH_CHAR (it->bidi_it.bytepos) == '\n')))
7160 {
7161 /* If we are at the beginning of a line/string, we can produce
7162 the next element right away. */
7163 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1);
7164 bidi_move_to_visually_next (&it->bidi_it);
7165 }
7166 else
7167 {
7168 EMACS_INT orig_bytepos = it->bidi_it.bytepos;
7169
7170 /* We need to prime the bidi iterator starting at the line's or
7171 string's beginning, before we will be able to produce the
7172 next element. */
7173 if (string_p)
7174 it->bidi_it.charpos = it->bidi_it.bytepos = 0;
7175 else
7176 {
7177 it->bidi_it.charpos = find_next_newline_no_quit (IT_CHARPOS (*it),
7178 -1);
7179 it->bidi_it.bytepos = CHAR_TO_BYTE (it->bidi_it.charpos);
7180 }
7181 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1);
7182 do
7183 {
7184 /* Now return to buffer/string position where we were asked
7185 to get the next display element, and produce that. */
7186 bidi_move_to_visually_next (&it->bidi_it);
7187 }
7188 while (it->bidi_it.bytepos != orig_bytepos
7189 && it->bidi_it.charpos < eob);
7190 }
7191
7192 /* Adjust IT's position information to where we ended up. */
7193 if (STRINGP (it->string))
7194 {
7195 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
7196 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
7197 }
7198 else
7199 {
7200 IT_CHARPOS (*it) = it->bidi_it.charpos;
7201 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
7202 }
7203
7204 if (STRINGP (it->string) || !it->s)
7205 {
7206 EMACS_INT stop, charpos, bytepos;
7207
7208 if (STRINGP (it->string))
7209 {
7210 xassert (!it->s);
7211 stop = SCHARS (it->string);
7212 if (stop > it->end_charpos)
7213 stop = it->end_charpos;
7214 charpos = IT_STRING_CHARPOS (*it);
7215 bytepos = IT_STRING_BYTEPOS (*it);
7216 }
7217 else
7218 {
7219 stop = it->end_charpos;
7220 charpos = IT_CHARPOS (*it);
7221 bytepos = IT_BYTEPOS (*it);
7222 }
7223 if (it->bidi_it.scan_dir < 0)
7224 stop = -1;
7225 composition_compute_stop_pos (&it->cmp_it, charpos, bytepos, stop,
7226 it->string);
7227 }
7228 }
7229
7230 /* Load IT with the next display element from Lisp string IT->string.
7231 IT->current.string_pos is the current position within the string.
7232 If IT->current.overlay_string_index >= 0, the Lisp string is an
7233 overlay string. */
7234
7235 static int
7236 next_element_from_string (struct it *it)
7237 {
7238 struct text_pos position;
7239
7240 xassert (STRINGP (it->string));
7241 xassert (!it->bidi_p || EQ (it->string, it->bidi_it.string.lstring));
7242 xassert (IT_STRING_CHARPOS (*it) >= 0);
7243 position = it->current.string_pos;
7244
7245 /* With bidi reordering, the character to display might not be the
7246 character at IT_STRING_CHARPOS. BIDI_IT.FIRST_ELT non-zero means
7247 that we were reseat()ed to a new string, whose paragraph
7248 direction is not known. */
7249 if (it->bidi_p && it->bidi_it.first_elt)
7250 {
7251 get_visually_first_element (it);
7252 SET_TEXT_POS (position, IT_STRING_CHARPOS (*it), IT_STRING_BYTEPOS (*it));
7253 }
7254
7255 /* Time to check for invisible text? */
7256 if (IT_STRING_CHARPOS (*it) < it->end_charpos)
7257 {
7258 if (IT_STRING_CHARPOS (*it) >= it->stop_charpos)
7259 {
7260 if (!(!it->bidi_p
7261 || BIDI_AT_BASE_LEVEL (it->bidi_it)
7262 || IT_STRING_CHARPOS (*it) == it->stop_charpos))
7263 {
7264 /* With bidi non-linear iteration, we could find
7265 ourselves far beyond the last computed stop_charpos,
7266 with several other stop positions in between that we
7267 missed. Scan them all now, in buffer's logical
7268 order, until we find and handle the last stop_charpos
7269 that precedes our current position. */
7270 handle_stop_backwards (it, it->stop_charpos);
7271 return GET_NEXT_DISPLAY_ELEMENT (it);
7272 }
7273 else
7274 {
7275 if (it->bidi_p)
7276 {
7277 /* Take note of the stop position we just moved
7278 across, for when we will move back across it. */
7279 it->prev_stop = it->stop_charpos;
7280 /* If we are at base paragraph embedding level, take
7281 note of the last stop position seen at this
7282 level. */
7283 if (BIDI_AT_BASE_LEVEL (it->bidi_it))
7284 it->base_level_stop = it->stop_charpos;
7285 }
7286 handle_stop (it);
7287
7288 /* Since a handler may have changed IT->method, we must
7289 recurse here. */
7290 return GET_NEXT_DISPLAY_ELEMENT (it);
7291 }
7292 }
7293 else if (it->bidi_p
7294 /* If we are before prev_stop, we may have overstepped
7295 on our way backwards a stop_pos, and if so, we need
7296 to handle that stop_pos. */
7297 && IT_STRING_CHARPOS (*it) < it->prev_stop
7298 /* We can sometimes back up for reasons that have nothing
7299 to do with bidi reordering. E.g., compositions. The
7300 code below is only needed when we are above the base
7301 embedding level, so test for that explicitly. */
7302 && !BIDI_AT_BASE_LEVEL (it->bidi_it))
7303 {
7304 /* If we lost track of base_level_stop, we have no better
7305 place for handle_stop_backwards to start from than string
7306 beginning. This happens, e.g., when we were reseated to
7307 the previous screenful of text by vertical-motion. */
7308 if (it->base_level_stop <= 0
7309 || IT_STRING_CHARPOS (*it) < it->base_level_stop)
7310 it->base_level_stop = 0;
7311 handle_stop_backwards (it, it->base_level_stop);
7312 return GET_NEXT_DISPLAY_ELEMENT (it);
7313 }
7314 }
7315
7316 if (it->current.overlay_string_index >= 0)
7317 {
7318 /* Get the next character from an overlay string. In overlay
7319 strings, There is no field width or padding with spaces to
7320 do. */
7321 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
7322 {
7323 it->what = IT_EOB;
7324 return 0;
7325 }
7326 else if (CHAR_COMPOSED_P (it, IT_STRING_CHARPOS (*it),
7327 IT_STRING_BYTEPOS (*it),
7328 it->bidi_it.scan_dir < 0
7329 ? -1
7330 : SCHARS (it->string))
7331 && next_element_from_composition (it))
7332 {
7333 return 1;
7334 }
7335 else if (STRING_MULTIBYTE (it->string))
7336 {
7337 const unsigned char *s = (SDATA (it->string)
7338 + IT_STRING_BYTEPOS (*it));
7339 it->c = string_char_and_length (s, &it->len);
7340 }
7341 else
7342 {
7343 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
7344 it->len = 1;
7345 }
7346 }
7347 else
7348 {
7349 /* Get the next character from a Lisp string that is not an
7350 overlay string. Such strings come from the mode line, for
7351 example. We may have to pad with spaces, or truncate the
7352 string. See also next_element_from_c_string. */
7353 if (IT_STRING_CHARPOS (*it) >= it->end_charpos)
7354 {
7355 it->what = IT_EOB;
7356 return 0;
7357 }
7358 else if (IT_STRING_CHARPOS (*it) >= it->string_nchars)
7359 {
7360 /* Pad with spaces. */
7361 it->c = ' ', it->len = 1;
7362 CHARPOS (position) = BYTEPOS (position) = -1;
7363 }
7364 else if (CHAR_COMPOSED_P (it, IT_STRING_CHARPOS (*it),
7365 IT_STRING_BYTEPOS (*it),
7366 it->bidi_it.scan_dir < 0
7367 ? -1
7368 : it->string_nchars)
7369 && next_element_from_composition (it))
7370 {
7371 return 1;
7372 }
7373 else if (STRING_MULTIBYTE (it->string))
7374 {
7375 const unsigned char *s = (SDATA (it->string)
7376 + IT_STRING_BYTEPOS (*it));
7377 it->c = string_char_and_length (s, &it->len);
7378 }
7379 else
7380 {
7381 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
7382 it->len = 1;
7383 }
7384 }
7385
7386 /* Record what we have and where it came from. */
7387 it->what = IT_CHARACTER;
7388 it->object = it->string;
7389 it->position = position;
7390 return 1;
7391 }
7392
7393
7394 /* Load IT with next display element from C string IT->s.
7395 IT->string_nchars is the maximum number of characters to return
7396 from the string. IT->end_charpos may be greater than
7397 IT->string_nchars when this function is called, in which case we
7398 may have to return padding spaces. Value is zero if end of string
7399 reached, including padding spaces. */
7400
7401 static int
7402 next_element_from_c_string (struct it *it)
7403 {
7404 int success_p = 1;
7405
7406 xassert (it->s);
7407 xassert (!it->bidi_p || it->s == it->bidi_it.string.s);
7408 it->what = IT_CHARACTER;
7409 BYTEPOS (it->position) = CHARPOS (it->position) = 0;
7410 it->object = Qnil;
7411
7412 /* With bidi reordering, the character to display might not be the
7413 character at IT_CHARPOS. BIDI_IT.FIRST_ELT non-zero means that
7414 we were reseated to a new string, whose paragraph direction is
7415 not known. */
7416 if (it->bidi_p && it->bidi_it.first_elt)
7417 get_visually_first_element (it);
7418
7419 /* IT's position can be greater than IT->string_nchars in case a
7420 field width or precision has been specified when the iterator was
7421 initialized. */
7422 if (IT_CHARPOS (*it) >= it->end_charpos)
7423 {
7424 /* End of the game. */
7425 it->what = IT_EOB;
7426 success_p = 0;
7427 }
7428 else if (IT_CHARPOS (*it) >= it->string_nchars)
7429 {
7430 /* Pad with spaces. */
7431 it->c = ' ', it->len = 1;
7432 BYTEPOS (it->position) = CHARPOS (it->position) = -1;
7433 }
7434 else if (it->multibyte_p)
7435 it->c = string_char_and_length (it->s + IT_BYTEPOS (*it), &it->len);
7436 else
7437 it->c = it->s[IT_BYTEPOS (*it)], it->len = 1;
7438
7439 return success_p;
7440 }
7441
7442
7443 /* Set up IT to return characters from an ellipsis, if appropriate.
7444 The definition of the ellipsis glyphs may come from a display table
7445 entry. This function fills IT with the first glyph from the
7446 ellipsis if an ellipsis is to be displayed. */
7447
7448 static int
7449 next_element_from_ellipsis (struct it *it)
7450 {
7451 if (it->selective_display_ellipsis_p)
7452 setup_for_ellipsis (it, it->len);
7453 else
7454 {
7455 /* The face at the current position may be different from the
7456 face we find after the invisible text. Remember what it
7457 was in IT->saved_face_id, and signal that it's there by
7458 setting face_before_selective_p. */
7459 it->saved_face_id = it->face_id;
7460 it->method = GET_FROM_BUFFER;
7461 it->object = it->w->buffer;
7462 reseat_at_next_visible_line_start (it, 1);
7463 it->face_before_selective_p = 1;
7464 }
7465
7466 return GET_NEXT_DISPLAY_ELEMENT (it);
7467 }
7468
7469
7470 /* Deliver an image display element. The iterator IT is already
7471 filled with image information (done in handle_display_prop). Value
7472 is always 1. */
7473
7474
7475 static int
7476 next_element_from_image (struct it *it)
7477 {
7478 it->what = IT_IMAGE;
7479 it->ignore_overlay_strings_at_pos_p = 0;
7480 return 1;
7481 }
7482
7483
7484 /* Fill iterator IT with next display element from a stretch glyph
7485 property. IT->object is the value of the text property. Value is
7486 always 1. */
7487
7488 static int
7489 next_element_from_stretch (struct it *it)
7490 {
7491 it->what = IT_STRETCH;
7492 return 1;
7493 }
7494
7495 /* Scan backwards from IT's current position until we find a stop
7496 position, or until BEGV. This is called when we find ourself
7497 before both the last known prev_stop and base_level_stop while
7498 reordering bidirectional text. */
7499
7500 static void
7501 compute_stop_pos_backwards (struct it *it)
7502 {
7503 const int SCAN_BACK_LIMIT = 1000;
7504 struct text_pos pos;
7505 struct display_pos save_current = it->current;
7506 struct text_pos save_position = it->position;
7507 EMACS_INT charpos = IT_CHARPOS (*it);
7508 EMACS_INT where_we_are = charpos;
7509 EMACS_INT save_stop_pos = it->stop_charpos;
7510 EMACS_INT save_end_pos = it->end_charpos;
7511
7512 xassert (NILP (it->string) && !it->s);
7513 xassert (it->bidi_p);
7514 it->bidi_p = 0;
7515 do
7516 {
7517 it->end_charpos = min (charpos + 1, ZV);
7518 charpos = max (charpos - SCAN_BACK_LIMIT, BEGV);
7519 SET_TEXT_POS (pos, charpos, BYTE_TO_CHAR (charpos));
7520 reseat_1 (it, pos, 0);
7521 compute_stop_pos (it);
7522 /* We must advance forward, right? */
7523 if (it->stop_charpos <= charpos)
7524 abort ();
7525 }
7526 while (charpos > BEGV && it->stop_charpos >= it->end_charpos);
7527
7528 if (it->stop_charpos <= where_we_are)
7529 it->prev_stop = it->stop_charpos;
7530 else
7531 it->prev_stop = BEGV;
7532 it->bidi_p = 1;
7533 it->current = save_current;
7534 it->position = save_position;
7535 it->stop_charpos = save_stop_pos;
7536 it->end_charpos = save_end_pos;
7537 }
7538
7539 /* Scan forward from CHARPOS in the current buffer/string, until we
7540 find a stop position > current IT's position. Then handle the stop
7541 position before that. This is called when we bump into a stop
7542 position while reordering bidirectional text. CHARPOS should be
7543 the last previously processed stop_pos (or BEGV/0, if none were
7544 processed yet) whose position is less that IT's current
7545 position. */
7546
7547 static void
7548 handle_stop_backwards (struct it *it, EMACS_INT charpos)
7549 {
7550 int bufp = !STRINGP (it->string);
7551 EMACS_INT where_we_are = (bufp ? IT_CHARPOS (*it) : IT_STRING_CHARPOS (*it));
7552 struct display_pos save_current = it->current;
7553 struct text_pos save_position = it->position;
7554 struct text_pos pos1;
7555 EMACS_INT next_stop;
7556
7557 /* Scan in strict logical order. */
7558 xassert (it->bidi_p);
7559 it->bidi_p = 0;
7560 do
7561 {
7562 it->prev_stop = charpos;
7563 if (bufp)
7564 {
7565 SET_TEXT_POS (pos1, charpos, CHAR_TO_BYTE (charpos));
7566 reseat_1 (it, pos1, 0);
7567 }
7568 else
7569 it->current.string_pos = string_pos (charpos, it->string);
7570 compute_stop_pos (it);
7571 /* We must advance forward, right? */
7572 if (it->stop_charpos <= it->prev_stop)
7573 abort ();
7574 charpos = it->stop_charpos;
7575 }
7576 while (charpos <= where_we_are);
7577
7578 it->bidi_p = 1;
7579 it->current = save_current;
7580 it->position = save_position;
7581 next_stop = it->stop_charpos;
7582 it->stop_charpos = it->prev_stop;
7583 handle_stop (it);
7584 it->stop_charpos = next_stop;
7585 }
7586
7587 /* Load IT with the next display element from current_buffer. Value
7588 is zero if end of buffer reached. IT->stop_charpos is the next
7589 position at which to stop and check for text properties or buffer
7590 end. */
7591
7592 static int
7593 next_element_from_buffer (struct it *it)
7594 {
7595 int success_p = 1;
7596
7597 xassert (IT_CHARPOS (*it) >= BEGV);
7598 xassert (NILP (it->string) && !it->s);
7599 xassert (!it->bidi_p
7600 || (EQ (it->bidi_it.string.lstring, Qnil)
7601 && it->bidi_it.string.s == NULL));
7602
7603 /* With bidi reordering, the character to display might not be the
7604 character at IT_CHARPOS. BIDI_IT.FIRST_ELT non-zero means that
7605 we were reseat()ed to a new buffer position, which is potentially
7606 a different paragraph. */
7607 if (it->bidi_p && it->bidi_it.first_elt)
7608 {
7609 get_visually_first_element (it);
7610 SET_TEXT_POS (it->position, IT_CHARPOS (*it), IT_BYTEPOS (*it));
7611 }
7612
7613 if (IT_CHARPOS (*it) >= it->stop_charpos)
7614 {
7615 if (IT_CHARPOS (*it) >= it->end_charpos)
7616 {
7617 int overlay_strings_follow_p;
7618
7619 /* End of the game, except when overlay strings follow that
7620 haven't been returned yet. */
7621 if (it->overlay_strings_at_end_processed_p)
7622 overlay_strings_follow_p = 0;
7623 else
7624 {
7625 it->overlay_strings_at_end_processed_p = 1;
7626 overlay_strings_follow_p = get_overlay_strings (it, 0);
7627 }
7628
7629 if (overlay_strings_follow_p)
7630 success_p = GET_NEXT_DISPLAY_ELEMENT (it);
7631 else
7632 {
7633 it->what = IT_EOB;
7634 it->position = it->current.pos;
7635 success_p = 0;
7636 }
7637 }
7638 else if (!(!it->bidi_p
7639 || BIDI_AT_BASE_LEVEL (it->bidi_it)
7640 || IT_CHARPOS (*it) == it->stop_charpos))
7641 {
7642 /* With bidi non-linear iteration, we could find ourselves
7643 far beyond the last computed stop_charpos, with several
7644 other stop positions in between that we missed. Scan
7645 them all now, in buffer's logical order, until we find
7646 and handle the last stop_charpos that precedes our
7647 current position. */
7648 handle_stop_backwards (it, it->stop_charpos);
7649 return GET_NEXT_DISPLAY_ELEMENT (it);
7650 }
7651 else
7652 {
7653 if (it->bidi_p)
7654 {
7655 /* Take note of the stop position we just moved across,
7656 for when we will move back across it. */
7657 it->prev_stop = it->stop_charpos;
7658 /* If we are at base paragraph embedding level, take
7659 note of the last stop position seen at this
7660 level. */
7661 if (BIDI_AT_BASE_LEVEL (it->bidi_it))
7662 it->base_level_stop = it->stop_charpos;
7663 }
7664 handle_stop (it);
7665 return GET_NEXT_DISPLAY_ELEMENT (it);
7666 }
7667 }
7668 else if (it->bidi_p
7669 /* If we are before prev_stop, we may have overstepped on
7670 our way backwards a stop_pos, and if so, we need to
7671 handle that stop_pos. */
7672 && IT_CHARPOS (*it) < it->prev_stop
7673 /* We can sometimes back up for reasons that have nothing
7674 to do with bidi reordering. E.g., compositions. The
7675 code below is only needed when we are above the base
7676 embedding level, so test for that explicitly. */
7677 && !BIDI_AT_BASE_LEVEL (it->bidi_it))
7678 {
7679 if (it->base_level_stop <= 0
7680 || IT_CHARPOS (*it) < it->base_level_stop)
7681 {
7682 /* If we lost track of base_level_stop, we need to find
7683 prev_stop by looking backwards. This happens, e.g., when
7684 we were reseated to the previous screenful of text by
7685 vertical-motion. */
7686 it->base_level_stop = BEGV;
7687 compute_stop_pos_backwards (it);
7688 handle_stop_backwards (it, it->prev_stop);
7689 }
7690 else
7691 handle_stop_backwards (it, it->base_level_stop);
7692 return GET_NEXT_DISPLAY_ELEMENT (it);
7693 }
7694 else
7695 {
7696 /* No face changes, overlays etc. in sight, so just return a
7697 character from current_buffer. */
7698 unsigned char *p;
7699 EMACS_INT stop;
7700
7701 /* Maybe run the redisplay end trigger hook. Performance note:
7702 This doesn't seem to cost measurable time. */
7703 if (it->redisplay_end_trigger_charpos
7704 && it->glyph_row
7705 && IT_CHARPOS (*it) >= it->redisplay_end_trigger_charpos)
7706 run_redisplay_end_trigger_hook (it);
7707
7708 stop = it->bidi_it.scan_dir < 0 ? -1 : it->end_charpos;
7709 if (CHAR_COMPOSED_P (it, IT_CHARPOS (*it), IT_BYTEPOS (*it),
7710 stop)
7711 && next_element_from_composition (it))
7712 {
7713 return 1;
7714 }
7715
7716 /* Get the next character, maybe multibyte. */
7717 p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
7718 if (it->multibyte_p && !ASCII_BYTE_P (*p))
7719 it->c = STRING_CHAR_AND_LENGTH (p, it->len);
7720 else
7721 it->c = *p, it->len = 1;
7722
7723 /* Record what we have and where it came from. */
7724 it->what = IT_CHARACTER;
7725 it->object = it->w->buffer;
7726 it->position = it->current.pos;
7727
7728 /* Normally we return the character found above, except when we
7729 really want to return an ellipsis for selective display. */
7730 if (it->selective)
7731 {
7732 if (it->c == '\n')
7733 {
7734 /* A value of selective > 0 means hide lines indented more
7735 than that number of columns. */
7736 if (it->selective > 0
7737 && IT_CHARPOS (*it) + 1 < ZV
7738 && indented_beyond_p (IT_CHARPOS (*it) + 1,
7739 IT_BYTEPOS (*it) + 1,
7740 it->selective))
7741 {
7742 success_p = next_element_from_ellipsis (it);
7743 it->dpvec_char_len = -1;
7744 }
7745 }
7746 else if (it->c == '\r' && it->selective == -1)
7747 {
7748 /* A value of selective == -1 means that everything from the
7749 CR to the end of the line is invisible, with maybe an
7750 ellipsis displayed for it. */
7751 success_p = next_element_from_ellipsis (it);
7752 it->dpvec_char_len = -1;
7753 }
7754 }
7755 }
7756
7757 /* Value is zero if end of buffer reached. */
7758 xassert (!success_p || it->what != IT_CHARACTER || it->len > 0);
7759 return success_p;
7760 }
7761
7762
7763 /* Run the redisplay end trigger hook for IT. */
7764
7765 static void
7766 run_redisplay_end_trigger_hook (struct it *it)
7767 {
7768 Lisp_Object args[3];
7769
7770 /* IT->glyph_row should be non-null, i.e. we should be actually
7771 displaying something, or otherwise we should not run the hook. */
7772 xassert (it->glyph_row);
7773
7774 /* Set up hook arguments. */
7775 args[0] = Qredisplay_end_trigger_functions;
7776 args[1] = it->window;
7777 XSETINT (args[2], it->redisplay_end_trigger_charpos);
7778 it->redisplay_end_trigger_charpos = 0;
7779
7780 /* Since we are *trying* to run these functions, don't try to run
7781 them again, even if they get an error. */
7782 it->w->redisplay_end_trigger = Qnil;
7783 Frun_hook_with_args (3, args);
7784
7785 /* Notice if it changed the face of the character we are on. */
7786 handle_face_prop (it);
7787 }
7788
7789
7790 /* Deliver a composition display element. Unlike the other
7791 next_element_from_XXX, this function is not registered in the array
7792 get_next_element[]. It is called from next_element_from_buffer and
7793 next_element_from_string when necessary. */
7794
7795 static int
7796 next_element_from_composition (struct it *it)
7797 {
7798 it->what = IT_COMPOSITION;
7799 it->len = it->cmp_it.nbytes;
7800 if (STRINGP (it->string))
7801 {
7802 if (it->c < 0)
7803 {
7804 IT_STRING_CHARPOS (*it) += it->cmp_it.nchars;
7805 IT_STRING_BYTEPOS (*it) += it->cmp_it.nbytes;
7806 return 0;
7807 }
7808 it->position = it->current.string_pos;
7809 it->object = it->string;
7810 it->c = composition_update_it (&it->cmp_it, IT_STRING_CHARPOS (*it),
7811 IT_STRING_BYTEPOS (*it), it->string);
7812 }
7813 else
7814 {
7815 if (it->c < 0)
7816 {
7817 IT_CHARPOS (*it) += it->cmp_it.nchars;
7818 IT_BYTEPOS (*it) += it->cmp_it.nbytes;
7819 if (it->bidi_p)
7820 {
7821 if (it->bidi_it.new_paragraph)
7822 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 0);
7823 /* Resync the bidi iterator with IT's new position.
7824 FIXME: this doesn't support bidirectional text. */
7825 while (it->bidi_it.charpos < IT_CHARPOS (*it))
7826 bidi_move_to_visually_next (&it->bidi_it);
7827 }
7828 return 0;
7829 }
7830 it->position = it->current.pos;
7831 it->object = it->w->buffer;
7832 it->c = composition_update_it (&it->cmp_it, IT_CHARPOS (*it),
7833 IT_BYTEPOS (*it), Qnil);
7834 }
7835 return 1;
7836 }
7837
7838
7839 \f
7840 /***********************************************************************
7841 Moving an iterator without producing glyphs
7842 ***********************************************************************/
7843
7844 /* Check if iterator is at a position corresponding to a valid buffer
7845 position after some move_it_ call. */
7846
7847 #define IT_POS_VALID_AFTER_MOVE_P(it) \
7848 ((it)->method == GET_FROM_STRING \
7849 ? IT_STRING_CHARPOS (*it) == 0 \
7850 : 1)
7851
7852
7853 /* Move iterator IT to a specified buffer or X position within one
7854 line on the display without producing glyphs.
7855
7856 OP should be a bit mask including some or all of these bits:
7857 MOVE_TO_X: Stop upon reaching x-position TO_X.
7858 MOVE_TO_POS: Stop upon reaching buffer or string position TO_CHARPOS.
7859 Regardless of OP's value, stop upon reaching the end of the display line.
7860
7861 TO_X is normally a value 0 <= TO_X <= IT->last_visible_x.
7862 This means, in particular, that TO_X includes window's horizontal
7863 scroll amount.
7864
7865 The return value has several possible values that
7866 say what condition caused the scan to stop:
7867
7868 MOVE_POS_MATCH_OR_ZV
7869 - when TO_POS or ZV was reached.
7870
7871 MOVE_X_REACHED
7872 -when TO_X was reached before TO_POS or ZV were reached.
7873
7874 MOVE_LINE_CONTINUED
7875 - when we reached the end of the display area and the line must
7876 be continued.
7877
7878 MOVE_LINE_TRUNCATED
7879 - when we reached the end of the display area and the line is
7880 truncated.
7881
7882 MOVE_NEWLINE_OR_CR
7883 - when we stopped at a line end, i.e. a newline or a CR and selective
7884 display is on. */
7885
7886 static enum move_it_result
7887 move_it_in_display_line_to (struct it *it,
7888 EMACS_INT to_charpos, int to_x,
7889 enum move_operation_enum op)
7890 {
7891 enum move_it_result result = MOVE_UNDEFINED;
7892 struct glyph_row *saved_glyph_row;
7893 struct it wrap_it, atpos_it, atx_it, ppos_it;
7894 void *wrap_data = NULL, *atpos_data = NULL, *atx_data = NULL;
7895 void *ppos_data = NULL;
7896 int may_wrap = 0;
7897 enum it_method prev_method = it->method;
7898 EMACS_INT prev_pos = IT_CHARPOS (*it);
7899 int saw_smaller_pos = prev_pos < to_charpos;
7900
7901 /* Don't produce glyphs in produce_glyphs. */
7902 saved_glyph_row = it->glyph_row;
7903 it->glyph_row = NULL;
7904
7905 /* Use wrap_it to save a copy of IT wherever a word wrap could
7906 occur. Use atpos_it to save a copy of IT at the desired buffer
7907 position, if found, so that we can scan ahead and check if the
7908 word later overshoots the window edge. Use atx_it similarly, for
7909 pixel positions. */
7910 wrap_it.sp = -1;
7911 atpos_it.sp = -1;
7912 atx_it.sp = -1;
7913
7914 /* Use ppos_it under bidi reordering to save a copy of IT for the
7915 position > CHARPOS that is the closest to CHARPOS. We restore
7916 that position in IT when we have scanned the entire display line
7917 without finding a match for CHARPOS and all the character
7918 positions are greater than CHARPOS. */
7919 if (it->bidi_p)
7920 {
7921 SAVE_IT (ppos_it, *it, ppos_data);
7922 SET_TEXT_POS (ppos_it.current.pos, ZV, ZV_BYTE);
7923 if ((op & MOVE_TO_POS) && IT_CHARPOS (*it) >= to_charpos)
7924 SAVE_IT (ppos_it, *it, ppos_data);
7925 }
7926
7927 #define BUFFER_POS_REACHED_P() \
7928 ((op & MOVE_TO_POS) != 0 \
7929 && BUFFERP (it->object) \
7930 && (IT_CHARPOS (*it) == to_charpos \
7931 || ((!it->bidi_p \
7932 || BIDI_AT_BASE_LEVEL (it->bidi_it)) \
7933 && IT_CHARPOS (*it) > to_charpos) \
7934 || (it->what == IT_COMPOSITION \
7935 && ((IT_CHARPOS (*it) > to_charpos \
7936 && to_charpos >= it->cmp_it.charpos) \
7937 || (IT_CHARPOS (*it) < to_charpos \
7938 && to_charpos <= it->cmp_it.charpos)))) \
7939 && (it->method == GET_FROM_BUFFER \
7940 || (it->method == GET_FROM_DISPLAY_VECTOR \
7941 && it->dpvec + it->current.dpvec_index + 1 >= it->dpend)))
7942
7943 /* If there's a line-/wrap-prefix, handle it. */
7944 if (it->hpos == 0 && it->method == GET_FROM_BUFFER
7945 && it->current_y < it->last_visible_y)
7946 handle_line_prefix (it);
7947
7948 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
7949 SET_TEXT_POS (this_line_min_pos, IT_CHARPOS (*it), IT_BYTEPOS (*it));
7950
7951 while (1)
7952 {
7953 int x, i, ascent = 0, descent = 0;
7954
7955 /* Utility macro to reset an iterator with x, ascent, and descent. */
7956 #define IT_RESET_X_ASCENT_DESCENT(IT) \
7957 ((IT)->current_x = x, (IT)->max_ascent = ascent, \
7958 (IT)->max_descent = descent)
7959
7960 /* Stop if we move beyond TO_CHARPOS (after an image or a
7961 display string or stretch glyph). */
7962 if ((op & MOVE_TO_POS) != 0
7963 && BUFFERP (it->object)
7964 && it->method == GET_FROM_BUFFER
7965 && (((!it->bidi_p
7966 /* When the iterator is at base embedding level, we
7967 are guaranteed that characters are delivered for
7968 display in strictly increasing order of their
7969 buffer positions. */
7970 || BIDI_AT_BASE_LEVEL (it->bidi_it))
7971 && IT_CHARPOS (*it) > to_charpos)
7972 || (it->bidi_p
7973 && (prev_method == GET_FROM_IMAGE
7974 || prev_method == GET_FROM_STRETCH
7975 || prev_method == GET_FROM_STRING)
7976 /* Passed TO_CHARPOS from left to right. */
7977 && ((prev_pos < to_charpos
7978 && IT_CHARPOS (*it) > to_charpos)
7979 /* Passed TO_CHARPOS from right to left. */
7980 || (prev_pos > to_charpos
7981 && IT_CHARPOS (*it) < to_charpos)))))
7982 {
7983 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
7984 {
7985 result = MOVE_POS_MATCH_OR_ZV;
7986 break;
7987 }
7988 else if (it->line_wrap == WORD_WRAP && atpos_it.sp < 0)
7989 /* If wrap_it is valid, the current position might be in a
7990 word that is wrapped. So, save the iterator in
7991 atpos_it and continue to see if wrapping happens. */
7992 SAVE_IT (atpos_it, *it, atpos_data);
7993 }
7994
7995 /* Stop when ZV reached.
7996 We used to stop here when TO_CHARPOS reached as well, but that is
7997 too soon if this glyph does not fit on this line. So we handle it
7998 explicitly below. */
7999 if (!get_next_display_element (it))
8000 {
8001 result = MOVE_POS_MATCH_OR_ZV;
8002 break;
8003 }
8004
8005 if (it->line_wrap == TRUNCATE)
8006 {
8007 if (BUFFER_POS_REACHED_P ())
8008 {
8009 result = MOVE_POS_MATCH_OR_ZV;
8010 break;
8011 }
8012 }
8013 else
8014 {
8015 if (it->line_wrap == WORD_WRAP)
8016 {
8017 if (IT_DISPLAYING_WHITESPACE (it))
8018 may_wrap = 1;
8019 else if (may_wrap)
8020 {
8021 /* We have reached a glyph that follows one or more
8022 whitespace characters. If the position is
8023 already found, we are done. */
8024 if (atpos_it.sp >= 0)
8025 {
8026 RESTORE_IT (it, &atpos_it, atpos_data);
8027 result = MOVE_POS_MATCH_OR_ZV;
8028 goto done;
8029 }
8030 if (atx_it.sp >= 0)
8031 {
8032 RESTORE_IT (it, &atx_it, atx_data);
8033 result = MOVE_X_REACHED;
8034 goto done;
8035 }
8036 /* Otherwise, we can wrap here. */
8037 SAVE_IT (wrap_it, *it, wrap_data);
8038 may_wrap = 0;
8039 }
8040 }
8041 }
8042
8043 /* Remember the line height for the current line, in case
8044 the next element doesn't fit on the line. */
8045 ascent = it->max_ascent;
8046 descent = it->max_descent;
8047
8048 /* The call to produce_glyphs will get the metrics of the
8049 display element IT is loaded with. Record the x-position
8050 before this display element, in case it doesn't fit on the
8051 line. */
8052 x = it->current_x;
8053
8054 PRODUCE_GLYPHS (it);
8055
8056 if (it->area != TEXT_AREA)
8057 {
8058 prev_method = it->method;
8059 if (it->method == GET_FROM_BUFFER)
8060 prev_pos = IT_CHARPOS (*it);
8061 set_iterator_to_next (it, 1);
8062 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
8063 SET_TEXT_POS (this_line_min_pos,
8064 IT_CHARPOS (*it), IT_BYTEPOS (*it));
8065 if (it->bidi_p
8066 && (op & MOVE_TO_POS)
8067 && IT_CHARPOS (*it) > to_charpos
8068 && IT_CHARPOS (*it) < IT_CHARPOS (ppos_it))
8069 SAVE_IT (ppos_it, *it, ppos_data);
8070 continue;
8071 }
8072
8073 /* The number of glyphs we get back in IT->nglyphs will normally
8074 be 1 except when IT->c is (i) a TAB, or (ii) a multi-glyph
8075 character on a terminal frame, or (iii) a line end. For the
8076 second case, IT->nglyphs - 1 padding glyphs will be present.
8077 (On X frames, there is only one glyph produced for a
8078 composite character.)
8079
8080 The behavior implemented below means, for continuation lines,
8081 that as many spaces of a TAB as fit on the current line are
8082 displayed there. For terminal frames, as many glyphs of a
8083 multi-glyph character are displayed in the current line, too.
8084 This is what the old redisplay code did, and we keep it that
8085 way. Under X, the whole shape of a complex character must
8086 fit on the line or it will be completely displayed in the
8087 next line.
8088
8089 Note that both for tabs and padding glyphs, all glyphs have
8090 the same width. */
8091 if (it->nglyphs)
8092 {
8093 /* More than one glyph or glyph doesn't fit on line. All
8094 glyphs have the same width. */
8095 int single_glyph_width = it->pixel_width / it->nglyphs;
8096 int new_x;
8097 int x_before_this_char = x;
8098 int hpos_before_this_char = it->hpos;
8099
8100 for (i = 0; i < it->nglyphs; ++i, x = new_x)
8101 {
8102 new_x = x + single_glyph_width;
8103
8104 /* We want to leave anything reaching TO_X to the caller. */
8105 if ((op & MOVE_TO_X) && new_x > to_x)
8106 {
8107 if (BUFFER_POS_REACHED_P ())
8108 {
8109 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
8110 goto buffer_pos_reached;
8111 if (atpos_it.sp < 0)
8112 {
8113 SAVE_IT (atpos_it, *it, atpos_data);
8114 IT_RESET_X_ASCENT_DESCENT (&atpos_it);
8115 }
8116 }
8117 else
8118 {
8119 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
8120 {
8121 it->current_x = x;
8122 result = MOVE_X_REACHED;
8123 break;
8124 }
8125 if (atx_it.sp < 0)
8126 {
8127 SAVE_IT (atx_it, *it, atx_data);
8128 IT_RESET_X_ASCENT_DESCENT (&atx_it);
8129 }
8130 }
8131 }
8132
8133 if (/* Lines are continued. */
8134 it->line_wrap != TRUNCATE
8135 && (/* And glyph doesn't fit on the line. */
8136 new_x > it->last_visible_x
8137 /* Or it fits exactly and we're on a window
8138 system frame. */
8139 || (new_x == it->last_visible_x
8140 && FRAME_WINDOW_P (it->f))))
8141 {
8142 if (/* IT->hpos == 0 means the very first glyph
8143 doesn't fit on the line, e.g. a wide image. */
8144 it->hpos == 0
8145 || (new_x == it->last_visible_x
8146 && FRAME_WINDOW_P (it->f)))
8147 {
8148 ++it->hpos;
8149 it->current_x = new_x;
8150
8151 /* The character's last glyph just barely fits
8152 in this row. */
8153 if (i == it->nglyphs - 1)
8154 {
8155 /* If this is the destination position,
8156 return a position *before* it in this row,
8157 now that we know it fits in this row. */
8158 if (BUFFER_POS_REACHED_P ())
8159 {
8160 if (it->line_wrap != WORD_WRAP
8161 || wrap_it.sp < 0)
8162 {
8163 it->hpos = hpos_before_this_char;
8164 it->current_x = x_before_this_char;
8165 result = MOVE_POS_MATCH_OR_ZV;
8166 break;
8167 }
8168 if (it->line_wrap == WORD_WRAP
8169 && atpos_it.sp < 0)
8170 {
8171 SAVE_IT (atpos_it, *it, atpos_data);
8172 atpos_it.current_x = x_before_this_char;
8173 atpos_it.hpos = hpos_before_this_char;
8174 }
8175 }
8176
8177 prev_method = it->method;
8178 if (it->method == GET_FROM_BUFFER)
8179 prev_pos = IT_CHARPOS (*it);
8180 set_iterator_to_next (it, 1);
8181 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
8182 SET_TEXT_POS (this_line_min_pos,
8183 IT_CHARPOS (*it), IT_BYTEPOS (*it));
8184 /* On graphical terminals, newlines may
8185 "overflow" into the fringe if
8186 overflow-newline-into-fringe is non-nil.
8187 On text-only terminals, newlines may
8188 overflow into the last glyph on the
8189 display line.*/
8190 if (!FRAME_WINDOW_P (it->f)
8191 || IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
8192 {
8193 if (!get_next_display_element (it))
8194 {
8195 result = MOVE_POS_MATCH_OR_ZV;
8196 break;
8197 }
8198 if (BUFFER_POS_REACHED_P ())
8199 {
8200 if (ITERATOR_AT_END_OF_LINE_P (it))
8201 result = MOVE_POS_MATCH_OR_ZV;
8202 else
8203 result = MOVE_LINE_CONTINUED;
8204 break;
8205 }
8206 if (ITERATOR_AT_END_OF_LINE_P (it))
8207 {
8208 result = MOVE_NEWLINE_OR_CR;
8209 break;
8210 }
8211 }
8212 }
8213 }
8214 else
8215 IT_RESET_X_ASCENT_DESCENT (it);
8216
8217 if (wrap_it.sp >= 0)
8218 {
8219 RESTORE_IT (it, &wrap_it, wrap_data);
8220 atpos_it.sp = -1;
8221 atx_it.sp = -1;
8222 }
8223
8224 TRACE_MOVE ((stderr, "move_it_in: continued at %d\n",
8225 IT_CHARPOS (*it)));
8226 result = MOVE_LINE_CONTINUED;
8227 break;
8228 }
8229
8230 if (BUFFER_POS_REACHED_P ())
8231 {
8232 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
8233 goto buffer_pos_reached;
8234 if (it->line_wrap == WORD_WRAP && atpos_it.sp < 0)
8235 {
8236 SAVE_IT (atpos_it, *it, atpos_data);
8237 IT_RESET_X_ASCENT_DESCENT (&atpos_it);
8238 }
8239 }
8240
8241 if (new_x > it->first_visible_x)
8242 {
8243 /* Glyph is visible. Increment number of glyphs that
8244 would be displayed. */
8245 ++it->hpos;
8246 }
8247 }
8248
8249 if (result != MOVE_UNDEFINED)
8250 break;
8251 }
8252 else if (BUFFER_POS_REACHED_P ())
8253 {
8254 buffer_pos_reached:
8255 IT_RESET_X_ASCENT_DESCENT (it);
8256 result = MOVE_POS_MATCH_OR_ZV;
8257 break;
8258 }
8259 else if ((op & MOVE_TO_X) && it->current_x >= to_x)
8260 {
8261 /* Stop when TO_X specified and reached. This check is
8262 necessary here because of lines consisting of a line end,
8263 only. The line end will not produce any glyphs and we
8264 would never get MOVE_X_REACHED. */
8265 xassert (it->nglyphs == 0);
8266 result = MOVE_X_REACHED;
8267 break;
8268 }
8269
8270 /* Is this a line end? If yes, we're done. */
8271 if (ITERATOR_AT_END_OF_LINE_P (it))
8272 {
8273 /* If we are past TO_CHARPOS, but never saw any character
8274 positions smaller than TO_CHARPOS, return
8275 MOVE_POS_MATCH_OR_ZV, like the unidirectional display
8276 did. */
8277 if (it->bidi_p && (op & MOVE_TO_POS) != 0)
8278 {
8279 if (!saw_smaller_pos && IT_CHARPOS (*it) > to_charpos)
8280 {
8281 if (IT_CHARPOS (ppos_it) < ZV)
8282 {
8283 RESTORE_IT (it, &ppos_it, ppos_data);
8284 result = MOVE_POS_MATCH_OR_ZV;
8285 }
8286 else
8287 goto buffer_pos_reached;
8288 }
8289 else if (it->line_wrap == WORD_WRAP && atpos_it.sp >= 0
8290 && IT_CHARPOS (*it) > to_charpos)
8291 goto buffer_pos_reached;
8292 else
8293 result = MOVE_NEWLINE_OR_CR;
8294 }
8295 else
8296 result = MOVE_NEWLINE_OR_CR;
8297 break;
8298 }
8299
8300 prev_method = it->method;
8301 if (it->method == GET_FROM_BUFFER)
8302 prev_pos = IT_CHARPOS (*it);
8303 /* The current display element has been consumed. Advance
8304 to the next. */
8305 set_iterator_to_next (it, 1);
8306 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
8307 SET_TEXT_POS (this_line_min_pos, IT_CHARPOS (*it), IT_BYTEPOS (*it));
8308 if (IT_CHARPOS (*it) < to_charpos)
8309 saw_smaller_pos = 1;
8310 if (it->bidi_p
8311 && (op & MOVE_TO_POS)
8312 && IT_CHARPOS (*it) >= to_charpos
8313 && IT_CHARPOS (*it) < IT_CHARPOS (ppos_it))
8314 SAVE_IT (ppos_it, *it, ppos_data);
8315
8316 /* Stop if lines are truncated and IT's current x-position is
8317 past the right edge of the window now. */
8318 if (it->line_wrap == TRUNCATE
8319 && it->current_x >= it->last_visible_x)
8320 {
8321 if (!FRAME_WINDOW_P (it->f)
8322 || IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
8323 {
8324 int at_eob_p = 0;
8325
8326 if ((at_eob_p = !get_next_display_element (it))
8327 || BUFFER_POS_REACHED_P ()
8328 /* If we are past TO_CHARPOS, but never saw any
8329 character positions smaller than TO_CHARPOS,
8330 return MOVE_POS_MATCH_OR_ZV, like the
8331 unidirectional display did. */
8332 || (it->bidi_p && (op & MOVE_TO_POS) != 0
8333 && !saw_smaller_pos
8334 && IT_CHARPOS (*it) > to_charpos))
8335 {
8336 if (it->bidi_p
8337 && !at_eob_p && IT_CHARPOS (ppos_it) < ZV)
8338 RESTORE_IT (it, &ppos_it, ppos_data);
8339 result = MOVE_POS_MATCH_OR_ZV;
8340 break;
8341 }
8342 if (ITERATOR_AT_END_OF_LINE_P (it))
8343 {
8344 result = MOVE_NEWLINE_OR_CR;
8345 break;
8346 }
8347 }
8348 else if (it->bidi_p && (op & MOVE_TO_POS) != 0
8349 && !saw_smaller_pos
8350 && IT_CHARPOS (*it) > to_charpos)
8351 {
8352 if (IT_CHARPOS (ppos_it) < ZV)
8353 RESTORE_IT (it, &ppos_it, ppos_data);
8354 result = MOVE_POS_MATCH_OR_ZV;
8355 break;
8356 }
8357 result = MOVE_LINE_TRUNCATED;
8358 break;
8359 }
8360 #undef IT_RESET_X_ASCENT_DESCENT
8361 }
8362
8363 #undef BUFFER_POS_REACHED_P
8364
8365 /* If we scanned beyond to_pos and didn't find a point to wrap at,
8366 restore the saved iterator. */
8367 if (atpos_it.sp >= 0)
8368 RESTORE_IT (it, &atpos_it, atpos_data);
8369 else if (atx_it.sp >= 0)
8370 RESTORE_IT (it, &atx_it, atx_data);
8371
8372 done:
8373
8374 if (atpos_data)
8375 bidi_unshelve_cache (atpos_data, 1);
8376 if (atx_data)
8377 bidi_unshelve_cache (atx_data, 1);
8378 if (wrap_data)
8379 bidi_unshelve_cache (wrap_data, 1);
8380 if (ppos_data)
8381 bidi_unshelve_cache (ppos_data, 1);
8382
8383 /* Restore the iterator settings altered at the beginning of this
8384 function. */
8385 it->glyph_row = saved_glyph_row;
8386 return result;
8387 }
8388
8389 /* For external use. */
8390 void
8391 move_it_in_display_line (struct it *it,
8392 EMACS_INT to_charpos, int to_x,
8393 enum move_operation_enum op)
8394 {
8395 if (it->line_wrap == WORD_WRAP
8396 && (op & MOVE_TO_X))
8397 {
8398 struct it save_it;
8399 void *save_data = NULL;
8400 int skip;
8401
8402 SAVE_IT (save_it, *it, save_data);
8403 skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
8404 /* When word-wrap is on, TO_X may lie past the end
8405 of a wrapped line. Then it->current is the
8406 character on the next line, so backtrack to the
8407 space before the wrap point. */
8408 if (skip == MOVE_LINE_CONTINUED)
8409 {
8410 int prev_x = max (it->current_x - 1, 0);
8411 RESTORE_IT (it, &save_it, save_data);
8412 move_it_in_display_line_to
8413 (it, -1, prev_x, MOVE_TO_X);
8414 }
8415 else
8416 bidi_unshelve_cache (save_data, 1);
8417 }
8418 else
8419 move_it_in_display_line_to (it, to_charpos, to_x, op);
8420 }
8421
8422
8423 /* Move IT forward until it satisfies one or more of the criteria in
8424 TO_CHARPOS, TO_X, TO_Y, and TO_VPOS.
8425
8426 OP is a bit-mask that specifies where to stop, and in particular,
8427 which of those four position arguments makes a difference. See the
8428 description of enum move_operation_enum.
8429
8430 If TO_CHARPOS is in invisible text, e.g. a truncated part of a
8431 screen line, this function will set IT to the next position that is
8432 displayed to the right of TO_CHARPOS on the screen. */
8433
8434 void
8435 move_it_to (struct it *it, EMACS_INT to_charpos, int to_x, int to_y, int to_vpos, int op)
8436 {
8437 enum move_it_result skip, skip2 = MOVE_X_REACHED;
8438 int line_height, line_start_x = 0, reached = 0;
8439 void *backup_data = NULL;
8440
8441 for (;;)
8442 {
8443 if (op & MOVE_TO_VPOS)
8444 {
8445 /* If no TO_CHARPOS and no TO_X specified, stop at the
8446 start of the line TO_VPOS. */
8447 if ((op & (MOVE_TO_X | MOVE_TO_POS)) == 0)
8448 {
8449 if (it->vpos == to_vpos)
8450 {
8451 reached = 1;
8452 break;
8453 }
8454 else
8455 skip = move_it_in_display_line_to (it, -1, -1, 0);
8456 }
8457 else
8458 {
8459 /* TO_VPOS >= 0 means stop at TO_X in the line at
8460 TO_VPOS, or at TO_POS, whichever comes first. */
8461 if (it->vpos == to_vpos)
8462 {
8463 reached = 2;
8464 break;
8465 }
8466
8467 skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
8468
8469 if (skip == MOVE_POS_MATCH_OR_ZV || it->vpos == to_vpos)
8470 {
8471 reached = 3;
8472 break;
8473 }
8474 else if (skip == MOVE_X_REACHED && it->vpos != to_vpos)
8475 {
8476 /* We have reached TO_X but not in the line we want. */
8477 skip = move_it_in_display_line_to (it, to_charpos,
8478 -1, MOVE_TO_POS);
8479 if (skip == MOVE_POS_MATCH_OR_ZV)
8480 {
8481 reached = 4;
8482 break;
8483 }
8484 }
8485 }
8486 }
8487 else if (op & MOVE_TO_Y)
8488 {
8489 struct it it_backup;
8490
8491 if (it->line_wrap == WORD_WRAP)
8492 SAVE_IT (it_backup, *it, backup_data);
8493
8494 /* TO_Y specified means stop at TO_X in the line containing
8495 TO_Y---or at TO_CHARPOS if this is reached first. The
8496 problem is that we can't really tell whether the line
8497 contains TO_Y before we have completely scanned it, and
8498 this may skip past TO_X. What we do is to first scan to
8499 TO_X.
8500
8501 If TO_X is not specified, use a TO_X of zero. The reason
8502 is to make the outcome of this function more predictable.
8503 If we didn't use TO_X == 0, we would stop at the end of
8504 the line which is probably not what a caller would expect
8505 to happen. */
8506 skip = move_it_in_display_line_to
8507 (it, to_charpos, ((op & MOVE_TO_X) ? to_x : 0),
8508 (MOVE_TO_X | (op & MOVE_TO_POS)));
8509
8510 /* If TO_CHARPOS is reached or ZV, we don't have to do more. */
8511 if (skip == MOVE_POS_MATCH_OR_ZV)
8512 reached = 5;
8513 else if (skip == MOVE_X_REACHED)
8514 {
8515 /* If TO_X was reached, we want to know whether TO_Y is
8516 in the line. We know this is the case if the already
8517 scanned glyphs make the line tall enough. Otherwise,
8518 we must check by scanning the rest of the line. */
8519 line_height = it->max_ascent + it->max_descent;
8520 if (to_y >= it->current_y
8521 && to_y < it->current_y + line_height)
8522 {
8523 reached = 6;
8524 break;
8525 }
8526 SAVE_IT (it_backup, *it, backup_data);
8527 TRACE_MOVE ((stderr, "move_it: from %d\n", IT_CHARPOS (*it)));
8528 skip2 = move_it_in_display_line_to (it, to_charpos, -1,
8529 op & MOVE_TO_POS);
8530 TRACE_MOVE ((stderr, "move_it: to %d\n", IT_CHARPOS (*it)));
8531 line_height = it->max_ascent + it->max_descent;
8532 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
8533
8534 if (to_y >= it->current_y
8535 && to_y < it->current_y + line_height)
8536 {
8537 /* If TO_Y is in this line and TO_X was reached
8538 above, we scanned too far. We have to restore
8539 IT's settings to the ones before skipping. */
8540 RESTORE_IT (it, &it_backup, backup_data);
8541 reached = 6;
8542 }
8543 else
8544 {
8545 skip = skip2;
8546 if (skip == MOVE_POS_MATCH_OR_ZV)
8547 reached = 7;
8548 }
8549 }
8550 else
8551 {
8552 /* Check whether TO_Y is in this line. */
8553 line_height = it->max_ascent + it->max_descent;
8554 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
8555
8556 if (to_y >= it->current_y
8557 && to_y < it->current_y + line_height)
8558 {
8559 /* When word-wrap is on, TO_X may lie past the end
8560 of a wrapped line. Then it->current is the
8561 character on the next line, so backtrack to the
8562 space before the wrap point. */
8563 if (skip == MOVE_LINE_CONTINUED
8564 && it->line_wrap == WORD_WRAP)
8565 {
8566 int prev_x = max (it->current_x - 1, 0);
8567 RESTORE_IT (it, &it_backup, backup_data);
8568 skip = move_it_in_display_line_to
8569 (it, -1, prev_x, MOVE_TO_X);
8570 }
8571 reached = 6;
8572 }
8573 }
8574
8575 if (reached)
8576 break;
8577 }
8578 else if (BUFFERP (it->object)
8579 && (it->method == GET_FROM_BUFFER
8580 || it->method == GET_FROM_STRETCH)
8581 && IT_CHARPOS (*it) >= to_charpos
8582 /* Under bidi iteration, a call to set_iterator_to_next
8583 can scan far beyond to_charpos if the initial
8584 portion of the next line needs to be reordered. In
8585 that case, give move_it_in_display_line_to another
8586 chance below. */
8587 && !(it->bidi_p
8588 && it->bidi_it.scan_dir == -1))
8589 skip = MOVE_POS_MATCH_OR_ZV;
8590 else
8591 skip = move_it_in_display_line_to (it, to_charpos, -1, MOVE_TO_POS);
8592
8593 switch (skip)
8594 {
8595 case MOVE_POS_MATCH_OR_ZV:
8596 reached = 8;
8597 goto out;
8598
8599 case MOVE_NEWLINE_OR_CR:
8600 set_iterator_to_next (it, 1);
8601 it->continuation_lines_width = 0;
8602 break;
8603
8604 case MOVE_LINE_TRUNCATED:
8605 it->continuation_lines_width = 0;
8606 reseat_at_next_visible_line_start (it, 0);
8607 if ((op & MOVE_TO_POS) != 0
8608 && IT_CHARPOS (*it) > to_charpos)
8609 {
8610 reached = 9;
8611 goto out;
8612 }
8613 break;
8614
8615 case MOVE_LINE_CONTINUED:
8616 /* For continued lines ending in a tab, some of the glyphs
8617 associated with the tab are displayed on the current
8618 line. Since it->current_x does not include these glyphs,
8619 we use it->last_visible_x instead. */
8620 if (it->c == '\t')
8621 {
8622 it->continuation_lines_width += it->last_visible_x;
8623 /* When moving by vpos, ensure that the iterator really
8624 advances to the next line (bug#847, bug#969). Fixme:
8625 do we need to do this in other circumstances? */
8626 if (it->current_x != it->last_visible_x
8627 && (op & MOVE_TO_VPOS)
8628 && !(op & (MOVE_TO_X | MOVE_TO_POS)))
8629 {
8630 line_start_x = it->current_x + it->pixel_width
8631 - it->last_visible_x;
8632 set_iterator_to_next (it, 0);
8633 }
8634 }
8635 else
8636 it->continuation_lines_width += it->current_x;
8637 break;
8638
8639 default:
8640 abort ();
8641 }
8642
8643 /* Reset/increment for the next run. */
8644 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
8645 it->current_x = line_start_x;
8646 line_start_x = 0;
8647 it->hpos = 0;
8648 it->current_y += it->max_ascent + it->max_descent;
8649 ++it->vpos;
8650 last_height = it->max_ascent + it->max_descent;
8651 last_max_ascent = it->max_ascent;
8652 it->max_ascent = it->max_descent = 0;
8653 }
8654
8655 out:
8656
8657 /* On text terminals, we may stop at the end of a line in the middle
8658 of a multi-character glyph. If the glyph itself is continued,
8659 i.e. it is actually displayed on the next line, don't treat this
8660 stopping point as valid; move to the next line instead (unless
8661 that brings us offscreen). */
8662 if (!FRAME_WINDOW_P (it->f)
8663 && op & MOVE_TO_POS
8664 && IT_CHARPOS (*it) == to_charpos
8665 && it->what == IT_CHARACTER
8666 && it->nglyphs > 1
8667 && it->line_wrap == WINDOW_WRAP
8668 && it->current_x == it->last_visible_x - 1
8669 && it->c != '\n'
8670 && it->c != '\t'
8671 && it->vpos < XFASTINT (it->w->window_end_vpos))
8672 {
8673 it->continuation_lines_width += it->current_x;
8674 it->current_x = it->hpos = it->max_ascent = it->max_descent = 0;
8675 it->current_y += it->max_ascent + it->max_descent;
8676 ++it->vpos;
8677 last_height = it->max_ascent + it->max_descent;
8678 last_max_ascent = it->max_ascent;
8679 }
8680
8681 if (backup_data)
8682 bidi_unshelve_cache (backup_data, 1);
8683
8684 TRACE_MOVE ((stderr, "move_it_to: reached %d\n", reached));
8685 }
8686
8687
8688 /* Move iterator IT backward by a specified y-distance DY, DY >= 0.
8689
8690 If DY > 0, move IT backward at least that many pixels. DY = 0
8691 means move IT backward to the preceding line start or BEGV. This
8692 function may move over more than DY pixels if IT->current_y - DY
8693 ends up in the middle of a line; in this case IT->current_y will be
8694 set to the top of the line moved to. */
8695
8696 void
8697 move_it_vertically_backward (struct it *it, int dy)
8698 {
8699 int nlines, h;
8700 struct it it2, it3;
8701 void *it2data = NULL, *it3data = NULL;
8702 EMACS_INT start_pos;
8703
8704 move_further_back:
8705 xassert (dy >= 0);
8706
8707 start_pos = IT_CHARPOS (*it);
8708
8709 /* Estimate how many newlines we must move back. */
8710 nlines = max (1, dy / FRAME_LINE_HEIGHT (it->f));
8711
8712 /* Set the iterator's position that many lines back. */
8713 while (nlines-- && IT_CHARPOS (*it) > BEGV)
8714 back_to_previous_visible_line_start (it);
8715
8716 /* Reseat the iterator here. When moving backward, we don't want
8717 reseat to skip forward over invisible text, set up the iterator
8718 to deliver from overlay strings at the new position etc. So,
8719 use reseat_1 here. */
8720 reseat_1 (it, it->current.pos, 1);
8721
8722 /* We are now surely at a line start. */
8723 it->current_x = it->hpos = 0; /* FIXME: this is incorrect when bidi
8724 reordering is in effect. */
8725 it->continuation_lines_width = 0;
8726
8727 /* Move forward and see what y-distance we moved. First move to the
8728 start of the next line so that we get its height. We need this
8729 height to be able to tell whether we reached the specified
8730 y-distance. */
8731 SAVE_IT (it2, *it, it2data);
8732 it2.max_ascent = it2.max_descent = 0;
8733 do
8734 {
8735 move_it_to (&it2, start_pos, -1, -1, it2.vpos + 1,
8736 MOVE_TO_POS | MOVE_TO_VPOS);
8737 }
8738 while (!(IT_POS_VALID_AFTER_MOVE_P (&it2)
8739 /* If we are in a display string which starts at START_POS,
8740 and that display string includes a newline, and we are
8741 right after that newline (i.e. at the beginning of a
8742 display line), exit the loop, because otherwise we will
8743 infloop, since move_it_to will see that it is already at
8744 START_POS and will not move. */
8745 || (it2.method == GET_FROM_STRING
8746 && IT_CHARPOS (it2) == start_pos
8747 && SREF (it2.string, IT_STRING_BYTEPOS (it2) - 1) == '\n')));
8748 xassert (IT_CHARPOS (*it) >= BEGV);
8749 SAVE_IT (it3, it2, it3data);
8750
8751 move_it_to (&it2, start_pos, -1, -1, -1, MOVE_TO_POS);
8752 xassert (IT_CHARPOS (*it) >= BEGV);
8753 /* H is the actual vertical distance from the position in *IT
8754 and the starting position. */
8755 h = it2.current_y - it->current_y;
8756 /* NLINES is the distance in number of lines. */
8757 nlines = it2.vpos - it->vpos;
8758
8759 /* Correct IT's y and vpos position
8760 so that they are relative to the starting point. */
8761 it->vpos -= nlines;
8762 it->current_y -= h;
8763
8764 if (dy == 0)
8765 {
8766 /* DY == 0 means move to the start of the screen line. The
8767 value of nlines is > 0 if continuation lines were involved,
8768 or if the original IT position was at start of a line. */
8769 RESTORE_IT (it, it, it2data);
8770 if (nlines > 0)
8771 move_it_by_lines (it, nlines);
8772 /* The above code moves us to some position NLINES down,
8773 usually to its first glyph (leftmost in an L2R line), but
8774 that's not necessarily the start of the line, under bidi
8775 reordering. We want to get to the character position
8776 that is immediately after the newline of the previous
8777 line. */
8778 if (it->bidi_p
8779 && !it->continuation_lines_width
8780 && !STRINGP (it->string)
8781 && IT_CHARPOS (*it) > BEGV
8782 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
8783 {
8784 EMACS_INT nl_pos =
8785 find_next_newline_no_quit (IT_CHARPOS (*it) - 1, -1);
8786
8787 move_it_to (it, nl_pos, -1, -1, -1, MOVE_TO_POS);
8788 }
8789 bidi_unshelve_cache (it3data, 1);
8790 }
8791 else
8792 {
8793 /* The y-position we try to reach, relative to *IT.
8794 Note that H has been subtracted in front of the if-statement. */
8795 int target_y = it->current_y + h - dy;
8796 int y0 = it3.current_y;
8797 int y1;
8798 int line_height;
8799
8800 RESTORE_IT (&it3, &it3, it3data);
8801 y1 = line_bottom_y (&it3);
8802 line_height = y1 - y0;
8803 RESTORE_IT (it, it, it2data);
8804 /* If we did not reach target_y, try to move further backward if
8805 we can. If we moved too far backward, try to move forward. */
8806 if (target_y < it->current_y
8807 /* This is heuristic. In a window that's 3 lines high, with
8808 a line height of 13 pixels each, recentering with point
8809 on the bottom line will try to move -39/2 = 19 pixels
8810 backward. Try to avoid moving into the first line. */
8811 && (it->current_y - target_y
8812 > min (window_box_height (it->w), line_height * 2 / 3))
8813 && IT_CHARPOS (*it) > BEGV)
8814 {
8815 TRACE_MOVE ((stderr, " not far enough -> move_vert %d\n",
8816 target_y - it->current_y));
8817 dy = it->current_y - target_y;
8818 goto move_further_back;
8819 }
8820 else if (target_y >= it->current_y + line_height
8821 && IT_CHARPOS (*it) < ZV)
8822 {
8823 /* Should move forward by at least one line, maybe more.
8824
8825 Note: Calling move_it_by_lines can be expensive on
8826 terminal frames, where compute_motion is used (via
8827 vmotion) to do the job, when there are very long lines
8828 and truncate-lines is nil. That's the reason for
8829 treating terminal frames specially here. */
8830
8831 if (!FRAME_WINDOW_P (it->f))
8832 move_it_vertically (it, target_y - (it->current_y + line_height));
8833 else
8834 {
8835 do
8836 {
8837 move_it_by_lines (it, 1);
8838 }
8839 while (target_y >= line_bottom_y (it) && IT_CHARPOS (*it) < ZV);
8840 }
8841 }
8842 }
8843 }
8844
8845
8846 /* Move IT by a specified amount of pixel lines DY. DY negative means
8847 move backwards. DY = 0 means move to start of screen line. At the
8848 end, IT will be on the start of a screen line. */
8849
8850 void
8851 move_it_vertically (struct it *it, int dy)
8852 {
8853 if (dy <= 0)
8854 move_it_vertically_backward (it, -dy);
8855 else
8856 {
8857 TRACE_MOVE ((stderr, "move_it_v: from %d, %d\n", IT_CHARPOS (*it), dy));
8858 move_it_to (it, ZV, -1, it->current_y + dy, -1,
8859 MOVE_TO_POS | MOVE_TO_Y);
8860 TRACE_MOVE ((stderr, "move_it_v: to %d\n", IT_CHARPOS (*it)));
8861
8862 /* If buffer ends in ZV without a newline, move to the start of
8863 the line to satisfy the post-condition. */
8864 if (IT_CHARPOS (*it) == ZV
8865 && ZV > BEGV
8866 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
8867 move_it_by_lines (it, 0);
8868 }
8869 }
8870
8871
8872 /* Move iterator IT past the end of the text line it is in. */
8873
8874 void
8875 move_it_past_eol (struct it *it)
8876 {
8877 enum move_it_result rc;
8878
8879 rc = move_it_in_display_line_to (it, Z, 0, MOVE_TO_POS);
8880 if (rc == MOVE_NEWLINE_OR_CR)
8881 set_iterator_to_next (it, 0);
8882 }
8883
8884
8885 /* Move IT by a specified number DVPOS of screen lines down. DVPOS
8886 negative means move up. DVPOS == 0 means move to the start of the
8887 screen line.
8888
8889 Optimization idea: If we would know that IT->f doesn't use
8890 a face with proportional font, we could be faster for
8891 truncate-lines nil. */
8892
8893 void
8894 move_it_by_lines (struct it *it, int dvpos)
8895 {
8896
8897 /* The commented-out optimization uses vmotion on terminals. This
8898 gives bad results, because elements like it->what, on which
8899 callers such as pos_visible_p rely, aren't updated. */
8900 /* struct position pos;
8901 if (!FRAME_WINDOW_P (it->f))
8902 {
8903 struct text_pos textpos;
8904
8905 pos = *vmotion (IT_CHARPOS (*it), dvpos, it->w);
8906 SET_TEXT_POS (textpos, pos.bufpos, pos.bytepos);
8907 reseat (it, textpos, 1);
8908 it->vpos += pos.vpos;
8909 it->current_y += pos.vpos;
8910 }
8911 else */
8912
8913 if (dvpos == 0)
8914 {
8915 /* DVPOS == 0 means move to the start of the screen line. */
8916 move_it_vertically_backward (it, 0);
8917 xassert (it->current_x == 0 && it->hpos == 0);
8918 /* Let next call to line_bottom_y calculate real line height */
8919 last_height = 0;
8920 }
8921 else if (dvpos > 0)
8922 {
8923 move_it_to (it, -1, -1, -1, it->vpos + dvpos, MOVE_TO_VPOS);
8924 if (!IT_POS_VALID_AFTER_MOVE_P (it))
8925 move_it_to (it, IT_CHARPOS (*it) + 1, -1, -1, -1, MOVE_TO_POS);
8926 }
8927 else
8928 {
8929 struct it it2;
8930 void *it2data = NULL;
8931 EMACS_INT start_charpos, i;
8932
8933 /* Start at the beginning of the screen line containing IT's
8934 position. This may actually move vertically backwards,
8935 in case of overlays, so adjust dvpos accordingly. */
8936 dvpos += it->vpos;
8937 move_it_vertically_backward (it, 0);
8938 dvpos -= it->vpos;
8939
8940 /* Go back -DVPOS visible lines and reseat the iterator there. */
8941 start_charpos = IT_CHARPOS (*it);
8942 for (i = -dvpos; i > 0 && IT_CHARPOS (*it) > BEGV; --i)
8943 back_to_previous_visible_line_start (it);
8944 reseat (it, it->current.pos, 1);
8945
8946 /* Move further back if we end up in a string or an image. */
8947 while (!IT_POS_VALID_AFTER_MOVE_P (it))
8948 {
8949 /* First try to move to start of display line. */
8950 dvpos += it->vpos;
8951 move_it_vertically_backward (it, 0);
8952 dvpos -= it->vpos;
8953 if (IT_POS_VALID_AFTER_MOVE_P (it))
8954 break;
8955 /* If start of line is still in string or image,
8956 move further back. */
8957 back_to_previous_visible_line_start (it);
8958 reseat (it, it->current.pos, 1);
8959 dvpos--;
8960 }
8961
8962 it->current_x = it->hpos = 0;
8963
8964 /* Above call may have moved too far if continuation lines
8965 are involved. Scan forward and see if it did. */
8966 SAVE_IT (it2, *it, it2data);
8967 it2.vpos = it2.current_y = 0;
8968 move_it_to (&it2, start_charpos, -1, -1, -1, MOVE_TO_POS);
8969 it->vpos -= it2.vpos;
8970 it->current_y -= it2.current_y;
8971 it->current_x = it->hpos = 0;
8972
8973 /* If we moved too far back, move IT some lines forward. */
8974 if (it2.vpos > -dvpos)
8975 {
8976 int delta = it2.vpos + dvpos;
8977
8978 RESTORE_IT (&it2, &it2, it2data);
8979 SAVE_IT (it2, *it, it2data);
8980 move_it_to (it, -1, -1, -1, it->vpos + delta, MOVE_TO_VPOS);
8981 /* Move back again if we got too far ahead. */
8982 if (IT_CHARPOS (*it) >= start_charpos)
8983 RESTORE_IT (it, &it2, it2data);
8984 else
8985 bidi_unshelve_cache (it2data, 1);
8986 }
8987 else
8988 RESTORE_IT (it, it, it2data);
8989 }
8990 }
8991
8992 /* Return 1 if IT points into the middle of a display vector. */
8993
8994 int
8995 in_display_vector_p (struct it *it)
8996 {
8997 return (it->method == GET_FROM_DISPLAY_VECTOR
8998 && it->current.dpvec_index > 0
8999 && it->dpvec + it->current.dpvec_index != it->dpend);
9000 }
9001
9002 \f
9003 /***********************************************************************
9004 Messages
9005 ***********************************************************************/
9006
9007
9008 /* Add a message with format string FORMAT and arguments ARG1 and ARG2
9009 to *Messages*. */
9010
9011 void
9012 add_to_log (const char *format, Lisp_Object arg1, Lisp_Object arg2)
9013 {
9014 Lisp_Object args[3];
9015 Lisp_Object msg, fmt;
9016 char *buffer;
9017 EMACS_INT len;
9018 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
9019 USE_SAFE_ALLOCA;
9020
9021 /* Do nothing if called asynchronously. Inserting text into
9022 a buffer may call after-change-functions and alike and
9023 that would means running Lisp asynchronously. */
9024 if (handling_signal)
9025 return;
9026
9027 fmt = msg = Qnil;
9028 GCPRO4 (fmt, msg, arg1, arg2);
9029
9030 args[0] = fmt = build_string (format);
9031 args[1] = arg1;
9032 args[2] = arg2;
9033 msg = Fformat (3, args);
9034
9035 len = SBYTES (msg) + 1;
9036 SAFE_ALLOCA (buffer, char *, len);
9037 memcpy (buffer, SDATA (msg), len);
9038
9039 message_dolog (buffer, len - 1, 1, 0);
9040 SAFE_FREE ();
9041
9042 UNGCPRO;
9043 }
9044
9045
9046 /* Output a newline in the *Messages* buffer if "needs" one. */
9047
9048 void
9049 message_log_maybe_newline (void)
9050 {
9051 if (message_log_need_newline)
9052 message_dolog ("", 0, 1, 0);
9053 }
9054
9055
9056 /* Add a string M of length NBYTES to the message log, optionally
9057 terminated with a newline when NLFLAG is non-zero. MULTIBYTE, if
9058 nonzero, means interpret the contents of M as multibyte. This
9059 function calls low-level routines in order to bypass text property
9060 hooks, etc. which might not be safe to run.
9061
9062 This may GC (insert may run before/after change hooks),
9063 so the buffer M must NOT point to a Lisp string. */
9064
9065 void
9066 message_dolog (const char *m, EMACS_INT nbytes, int nlflag, int multibyte)
9067 {
9068 const unsigned char *msg = (const unsigned char *) m;
9069
9070 if (!NILP (Vmemory_full))
9071 return;
9072
9073 if (!NILP (Vmessage_log_max))
9074 {
9075 struct buffer *oldbuf;
9076 Lisp_Object oldpoint, oldbegv, oldzv;
9077 int old_windows_or_buffers_changed = windows_or_buffers_changed;
9078 EMACS_INT point_at_end = 0;
9079 EMACS_INT zv_at_end = 0;
9080 Lisp_Object old_deactivate_mark, tem;
9081 struct gcpro gcpro1;
9082
9083 old_deactivate_mark = Vdeactivate_mark;
9084 oldbuf = current_buffer;
9085 Fset_buffer (Fget_buffer_create (Vmessages_buffer_name));
9086 BVAR (current_buffer, undo_list) = Qt;
9087
9088 oldpoint = message_dolog_marker1;
9089 set_marker_restricted (oldpoint, make_number (PT), Qnil);
9090 oldbegv = message_dolog_marker2;
9091 set_marker_restricted (oldbegv, make_number (BEGV), Qnil);
9092 oldzv = message_dolog_marker3;
9093 set_marker_restricted (oldzv, make_number (ZV), Qnil);
9094 GCPRO1 (old_deactivate_mark);
9095
9096 if (PT == Z)
9097 point_at_end = 1;
9098 if (ZV == Z)
9099 zv_at_end = 1;
9100
9101 BEGV = BEG;
9102 BEGV_BYTE = BEG_BYTE;
9103 ZV = Z;
9104 ZV_BYTE = Z_BYTE;
9105 TEMP_SET_PT_BOTH (Z, Z_BYTE);
9106
9107 /* Insert the string--maybe converting multibyte to single byte
9108 or vice versa, so that all the text fits the buffer. */
9109 if (multibyte
9110 && NILP (BVAR (current_buffer, enable_multibyte_characters)))
9111 {
9112 EMACS_INT i;
9113 int c, char_bytes;
9114 char work[1];
9115
9116 /* Convert a multibyte string to single-byte
9117 for the *Message* buffer. */
9118 for (i = 0; i < nbytes; i += char_bytes)
9119 {
9120 c = string_char_and_length (msg + i, &char_bytes);
9121 work[0] = (ASCII_CHAR_P (c)
9122 ? c
9123 : multibyte_char_to_unibyte (c));
9124 insert_1_both (work, 1, 1, 1, 0, 0);
9125 }
9126 }
9127 else if (! multibyte
9128 && ! NILP (BVAR (current_buffer, enable_multibyte_characters)))
9129 {
9130 EMACS_INT i;
9131 int c, char_bytes;
9132 unsigned char str[MAX_MULTIBYTE_LENGTH];
9133 /* Convert a single-byte string to multibyte
9134 for the *Message* buffer. */
9135 for (i = 0; i < nbytes; i++)
9136 {
9137 c = msg[i];
9138 MAKE_CHAR_MULTIBYTE (c);
9139 char_bytes = CHAR_STRING (c, str);
9140 insert_1_both ((char *) str, 1, char_bytes, 1, 0, 0);
9141 }
9142 }
9143 else if (nbytes)
9144 insert_1 (m, nbytes, 1, 0, 0);
9145
9146 if (nlflag)
9147 {
9148 EMACS_INT this_bol, this_bol_byte, prev_bol, prev_bol_byte;
9149 printmax_t dups;
9150 insert_1 ("\n", 1, 1, 0, 0);
9151
9152 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE, -2, 0);
9153 this_bol = PT;
9154 this_bol_byte = PT_BYTE;
9155
9156 /* See if this line duplicates the previous one.
9157 If so, combine duplicates. */
9158 if (this_bol > BEG)
9159 {
9160 scan_newline (PT, PT_BYTE, BEG, BEG_BYTE, -2, 0);
9161 prev_bol = PT;
9162 prev_bol_byte = PT_BYTE;
9163
9164 dups = message_log_check_duplicate (prev_bol_byte,
9165 this_bol_byte);
9166 if (dups)
9167 {
9168 del_range_both (prev_bol, prev_bol_byte,
9169 this_bol, this_bol_byte, 0);
9170 if (dups > 1)
9171 {
9172 char dupstr[sizeof " [ times]"
9173 + INT_STRLEN_BOUND (printmax_t)];
9174 int duplen;
9175
9176 /* If you change this format, don't forget to also
9177 change message_log_check_duplicate. */
9178 sprintf (dupstr, " [%"pMd" times]", dups);
9179 duplen = strlen (dupstr);
9180 TEMP_SET_PT_BOTH (Z - 1, Z_BYTE - 1);
9181 insert_1 (dupstr, duplen, 1, 0, 1);
9182 }
9183 }
9184 }
9185
9186 /* If we have more than the desired maximum number of lines
9187 in the *Messages* buffer now, delete the oldest ones.
9188 This is safe because we don't have undo in this buffer. */
9189
9190 if (NATNUMP (Vmessage_log_max))
9191 {
9192 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE,
9193 -XFASTINT (Vmessage_log_max) - 1, 0);
9194 del_range_both (BEG, BEG_BYTE, PT, PT_BYTE, 0);
9195 }
9196 }
9197 BEGV = XMARKER (oldbegv)->charpos;
9198 BEGV_BYTE = marker_byte_position (oldbegv);
9199
9200 if (zv_at_end)
9201 {
9202 ZV = Z;
9203 ZV_BYTE = Z_BYTE;
9204 }
9205 else
9206 {
9207 ZV = XMARKER (oldzv)->charpos;
9208 ZV_BYTE = marker_byte_position (oldzv);
9209 }
9210
9211 if (point_at_end)
9212 TEMP_SET_PT_BOTH (Z, Z_BYTE);
9213 else
9214 /* We can't do Fgoto_char (oldpoint) because it will run some
9215 Lisp code. */
9216 TEMP_SET_PT_BOTH (XMARKER (oldpoint)->charpos,
9217 XMARKER (oldpoint)->bytepos);
9218
9219 UNGCPRO;
9220 unchain_marker (XMARKER (oldpoint));
9221 unchain_marker (XMARKER (oldbegv));
9222 unchain_marker (XMARKER (oldzv));
9223
9224 tem = Fget_buffer_window (Fcurrent_buffer (), Qt);
9225 set_buffer_internal (oldbuf);
9226 if (NILP (tem))
9227 windows_or_buffers_changed = old_windows_or_buffers_changed;
9228 message_log_need_newline = !nlflag;
9229 Vdeactivate_mark = old_deactivate_mark;
9230 }
9231 }
9232
9233
9234 /* We are at the end of the buffer after just having inserted a newline.
9235 (Note: We depend on the fact we won't be crossing the gap.)
9236 Check to see if the most recent message looks a lot like the previous one.
9237 Return 0 if different, 1 if the new one should just replace it, or a
9238 value N > 1 if we should also append " [N times]". */
9239
9240 static intmax_t
9241 message_log_check_duplicate (EMACS_INT prev_bol_byte, EMACS_INT this_bol_byte)
9242 {
9243 EMACS_INT i;
9244 EMACS_INT len = Z_BYTE - 1 - this_bol_byte;
9245 int seen_dots = 0;
9246 unsigned char *p1 = BUF_BYTE_ADDRESS (current_buffer, prev_bol_byte);
9247 unsigned char *p2 = BUF_BYTE_ADDRESS (current_buffer, this_bol_byte);
9248
9249 for (i = 0; i < len; i++)
9250 {
9251 if (i >= 3 && p1[i-3] == '.' && p1[i-2] == '.' && p1[i-1] == '.')
9252 seen_dots = 1;
9253 if (p1[i] != p2[i])
9254 return seen_dots;
9255 }
9256 p1 += len;
9257 if (*p1 == '\n')
9258 return 2;
9259 if (*p1++ == ' ' && *p1++ == '[')
9260 {
9261 char *pend;
9262 intmax_t n = strtoimax ((char *) p1, &pend, 10);
9263 if (0 < n && n < INTMAX_MAX && strncmp (pend, " times]\n", 8) == 0)
9264 return n+1;
9265 }
9266 return 0;
9267 }
9268 \f
9269
9270 /* Display an echo area message M with a specified length of NBYTES
9271 bytes. The string may include null characters. If M is 0, clear
9272 out any existing message, and let the mini-buffer text show
9273 through.
9274
9275 This may GC, so the buffer M must NOT point to a Lisp string. */
9276
9277 void
9278 message2 (const char *m, EMACS_INT nbytes, int multibyte)
9279 {
9280 /* First flush out any partial line written with print. */
9281 message_log_maybe_newline ();
9282 if (m)
9283 message_dolog (m, nbytes, 1, multibyte);
9284 message2_nolog (m, nbytes, multibyte);
9285 }
9286
9287
9288 /* The non-logging counterpart of message2. */
9289
9290 void
9291 message2_nolog (const char *m, EMACS_INT nbytes, int multibyte)
9292 {
9293 struct frame *sf = SELECTED_FRAME ();
9294 message_enable_multibyte = multibyte;
9295
9296 if (FRAME_INITIAL_P (sf))
9297 {
9298 if (noninteractive_need_newline)
9299 putc ('\n', stderr);
9300 noninteractive_need_newline = 0;
9301 if (m)
9302 fwrite (m, nbytes, 1, stderr);
9303 if (cursor_in_echo_area == 0)
9304 fprintf (stderr, "\n");
9305 fflush (stderr);
9306 }
9307 /* A null message buffer means that the frame hasn't really been
9308 initialized yet. Error messages get reported properly by
9309 cmd_error, so this must be just an informative message; toss it. */
9310 else if (INTERACTIVE
9311 && sf->glyphs_initialized_p
9312 && FRAME_MESSAGE_BUF (sf))
9313 {
9314 Lisp_Object mini_window;
9315 struct frame *f;
9316
9317 /* Get the frame containing the mini-buffer
9318 that the selected frame is using. */
9319 mini_window = FRAME_MINIBUF_WINDOW (sf);
9320 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
9321
9322 FRAME_SAMPLE_VISIBILITY (f);
9323 if (FRAME_VISIBLE_P (sf)
9324 && ! FRAME_VISIBLE_P (f))
9325 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (mini_window)));
9326
9327 if (m)
9328 {
9329 set_message (m, Qnil, nbytes, multibyte);
9330 if (minibuffer_auto_raise)
9331 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
9332 }
9333 else
9334 clear_message (1, 1);
9335
9336 do_pending_window_change (0);
9337 echo_area_display (1);
9338 do_pending_window_change (0);
9339 if (FRAME_TERMINAL (f)->frame_up_to_date_hook != 0 && ! gc_in_progress)
9340 (*FRAME_TERMINAL (f)->frame_up_to_date_hook) (f);
9341 }
9342 }
9343
9344
9345 /* Display an echo area message M with a specified length of NBYTES
9346 bytes. The string may include null characters. If M is not a
9347 string, clear out any existing message, and let the mini-buffer
9348 text show through.
9349
9350 This function cancels echoing. */
9351
9352 void
9353 message3 (Lisp_Object m, EMACS_INT nbytes, int multibyte)
9354 {
9355 struct gcpro gcpro1;
9356
9357 GCPRO1 (m);
9358 clear_message (1,1);
9359 cancel_echoing ();
9360
9361 /* First flush out any partial line written with print. */
9362 message_log_maybe_newline ();
9363 if (STRINGP (m))
9364 {
9365 char *buffer;
9366 USE_SAFE_ALLOCA;
9367
9368 SAFE_ALLOCA (buffer, char *, nbytes);
9369 memcpy (buffer, SDATA (m), nbytes);
9370 message_dolog (buffer, nbytes, 1, multibyte);
9371 SAFE_FREE ();
9372 }
9373 message3_nolog (m, nbytes, multibyte);
9374
9375 UNGCPRO;
9376 }
9377
9378
9379 /* The non-logging version of message3.
9380 This does not cancel echoing, because it is used for echoing.
9381 Perhaps we need to make a separate function for echoing
9382 and make this cancel echoing. */
9383
9384 void
9385 message3_nolog (Lisp_Object m, EMACS_INT nbytes, int multibyte)
9386 {
9387 struct frame *sf = SELECTED_FRAME ();
9388 message_enable_multibyte = multibyte;
9389
9390 if (FRAME_INITIAL_P (sf))
9391 {
9392 if (noninteractive_need_newline)
9393 putc ('\n', stderr);
9394 noninteractive_need_newline = 0;
9395 if (STRINGP (m))
9396 fwrite (SDATA (m), nbytes, 1, stderr);
9397 if (cursor_in_echo_area == 0)
9398 fprintf (stderr, "\n");
9399 fflush (stderr);
9400 }
9401 /* A null message buffer means that the frame hasn't really been
9402 initialized yet. Error messages get reported properly by
9403 cmd_error, so this must be just an informative message; toss it. */
9404 else if (INTERACTIVE
9405 && sf->glyphs_initialized_p
9406 && FRAME_MESSAGE_BUF (sf))
9407 {
9408 Lisp_Object mini_window;
9409 Lisp_Object frame;
9410 struct frame *f;
9411
9412 /* Get the frame containing the mini-buffer
9413 that the selected frame is using. */
9414 mini_window = FRAME_MINIBUF_WINDOW (sf);
9415 frame = XWINDOW (mini_window)->frame;
9416 f = XFRAME (frame);
9417
9418 FRAME_SAMPLE_VISIBILITY (f);
9419 if (FRAME_VISIBLE_P (sf)
9420 && !FRAME_VISIBLE_P (f))
9421 Fmake_frame_visible (frame);
9422
9423 if (STRINGP (m) && SCHARS (m) > 0)
9424 {
9425 set_message (NULL, m, nbytes, multibyte);
9426 if (minibuffer_auto_raise)
9427 Fraise_frame (frame);
9428 /* Assume we are not echoing.
9429 (If we are, echo_now will override this.) */
9430 echo_message_buffer = Qnil;
9431 }
9432 else
9433 clear_message (1, 1);
9434
9435 do_pending_window_change (0);
9436 echo_area_display (1);
9437 do_pending_window_change (0);
9438 if (FRAME_TERMINAL (f)->frame_up_to_date_hook != 0 && ! gc_in_progress)
9439 (*FRAME_TERMINAL (f)->frame_up_to_date_hook) (f);
9440 }
9441 }
9442
9443
9444 /* Display a null-terminated echo area message M. If M is 0, clear
9445 out any existing message, and let the mini-buffer text show through.
9446
9447 The buffer M must continue to exist until after the echo area gets
9448 cleared or some other message gets displayed there. Do not pass
9449 text that is stored in a Lisp string. Do not pass text in a buffer
9450 that was alloca'd. */
9451
9452 void
9453 message1 (const char *m)
9454 {
9455 message2 (m, (m ? strlen (m) : 0), 0);
9456 }
9457
9458
9459 /* The non-logging counterpart of message1. */
9460
9461 void
9462 message1_nolog (const char *m)
9463 {
9464 message2_nolog (m, (m ? strlen (m) : 0), 0);
9465 }
9466
9467 /* Display a message M which contains a single %s
9468 which gets replaced with STRING. */
9469
9470 void
9471 message_with_string (const char *m, Lisp_Object string, int log)
9472 {
9473 CHECK_STRING (string);
9474
9475 if (noninteractive)
9476 {
9477 if (m)
9478 {
9479 if (noninteractive_need_newline)
9480 putc ('\n', stderr);
9481 noninteractive_need_newline = 0;
9482 fprintf (stderr, m, SDATA (string));
9483 if (!cursor_in_echo_area)
9484 fprintf (stderr, "\n");
9485 fflush (stderr);
9486 }
9487 }
9488 else if (INTERACTIVE)
9489 {
9490 /* The frame whose minibuffer we're going to display the message on.
9491 It may be larger than the selected frame, so we need
9492 to use its buffer, not the selected frame's buffer. */
9493 Lisp_Object mini_window;
9494 struct frame *f, *sf = SELECTED_FRAME ();
9495
9496 /* Get the frame containing the minibuffer
9497 that the selected frame is using. */
9498 mini_window = FRAME_MINIBUF_WINDOW (sf);
9499 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
9500
9501 /* A null message buffer means that the frame hasn't really been
9502 initialized yet. Error messages get reported properly by
9503 cmd_error, so this must be just an informative message; toss it. */
9504 if (FRAME_MESSAGE_BUF (f))
9505 {
9506 Lisp_Object args[2], msg;
9507 struct gcpro gcpro1, gcpro2;
9508
9509 args[0] = build_string (m);
9510 args[1] = msg = string;
9511 GCPRO2 (args[0], msg);
9512 gcpro1.nvars = 2;
9513
9514 msg = Fformat (2, args);
9515
9516 if (log)
9517 message3 (msg, SBYTES (msg), STRING_MULTIBYTE (msg));
9518 else
9519 message3_nolog (msg, SBYTES (msg), STRING_MULTIBYTE (msg));
9520
9521 UNGCPRO;
9522
9523 /* Print should start at the beginning of the message
9524 buffer next time. */
9525 message_buf_print = 0;
9526 }
9527 }
9528 }
9529
9530
9531 /* Dump an informative message to the minibuf. If M is 0, clear out
9532 any existing message, and let the mini-buffer text show through. */
9533
9534 static void
9535 vmessage (const char *m, va_list ap)
9536 {
9537 if (noninteractive)
9538 {
9539 if (m)
9540 {
9541 if (noninteractive_need_newline)
9542 putc ('\n', stderr);
9543 noninteractive_need_newline = 0;
9544 vfprintf (stderr, m, ap);
9545 if (cursor_in_echo_area == 0)
9546 fprintf (stderr, "\n");
9547 fflush (stderr);
9548 }
9549 }
9550 else if (INTERACTIVE)
9551 {
9552 /* The frame whose mini-buffer we're going to display the message
9553 on. It may be larger than the selected frame, so we need to
9554 use its buffer, not the selected frame's buffer. */
9555 Lisp_Object mini_window;
9556 struct frame *f, *sf = SELECTED_FRAME ();
9557
9558 /* Get the frame containing the mini-buffer
9559 that the selected frame is using. */
9560 mini_window = FRAME_MINIBUF_WINDOW (sf);
9561 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
9562
9563 /* A null message buffer means that the frame hasn't really been
9564 initialized yet. Error messages get reported properly by
9565 cmd_error, so this must be just an informative message; toss
9566 it. */
9567 if (FRAME_MESSAGE_BUF (f))
9568 {
9569 if (m)
9570 {
9571 ptrdiff_t len;
9572
9573 len = doprnt (FRAME_MESSAGE_BUF (f),
9574 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, ap);
9575
9576 message2 (FRAME_MESSAGE_BUF (f), len, 0);
9577 }
9578 else
9579 message1 (0);
9580
9581 /* Print should start at the beginning of the message
9582 buffer next time. */
9583 message_buf_print = 0;
9584 }
9585 }
9586 }
9587
9588 void
9589 message (const char *m, ...)
9590 {
9591 va_list ap;
9592 va_start (ap, m);
9593 vmessage (m, ap);
9594 va_end (ap);
9595 }
9596
9597
9598 #if 0
9599 /* The non-logging version of message. */
9600
9601 void
9602 message_nolog (const char *m, ...)
9603 {
9604 Lisp_Object old_log_max;
9605 va_list ap;
9606 va_start (ap, m);
9607 old_log_max = Vmessage_log_max;
9608 Vmessage_log_max = Qnil;
9609 vmessage (m, ap);
9610 Vmessage_log_max = old_log_max;
9611 va_end (ap);
9612 }
9613 #endif
9614
9615
9616 /* Display the current message in the current mini-buffer. This is
9617 only called from error handlers in process.c, and is not time
9618 critical. */
9619
9620 void
9621 update_echo_area (void)
9622 {
9623 if (!NILP (echo_area_buffer[0]))
9624 {
9625 Lisp_Object string;
9626 string = Fcurrent_message ();
9627 message3 (string, SBYTES (string),
9628 !NILP (BVAR (current_buffer, enable_multibyte_characters)));
9629 }
9630 }
9631
9632
9633 /* Make sure echo area buffers in `echo_buffers' are live.
9634 If they aren't, make new ones. */
9635
9636 static void
9637 ensure_echo_area_buffers (void)
9638 {
9639 int i;
9640
9641 for (i = 0; i < 2; ++i)
9642 if (!BUFFERP (echo_buffer[i])
9643 || NILP (BVAR (XBUFFER (echo_buffer[i]), name)))
9644 {
9645 char name[30];
9646 Lisp_Object old_buffer;
9647 int j;
9648
9649 old_buffer = echo_buffer[i];
9650 sprintf (name, " *Echo Area %d*", i);
9651 echo_buffer[i] = Fget_buffer_create (build_string (name));
9652 BVAR (XBUFFER (echo_buffer[i]), truncate_lines) = Qnil;
9653 /* to force word wrap in echo area -
9654 it was decided to postpone this*/
9655 /* XBUFFER (echo_buffer[i])->word_wrap = Qt; */
9656
9657 for (j = 0; j < 2; ++j)
9658 if (EQ (old_buffer, echo_area_buffer[j]))
9659 echo_area_buffer[j] = echo_buffer[i];
9660 }
9661 }
9662
9663
9664 /* Call FN with args A1..A4 with either the current or last displayed
9665 echo_area_buffer as current buffer.
9666
9667 WHICH zero means use the current message buffer
9668 echo_area_buffer[0]. If that is nil, choose a suitable buffer
9669 from echo_buffer[] and clear it.
9670
9671 WHICH > 0 means use echo_area_buffer[1]. If that is nil, choose a
9672 suitable buffer from echo_buffer[] and clear it.
9673
9674 If WHICH < 0, set echo_area_buffer[1] to echo_area_buffer[0], so
9675 that the current message becomes the last displayed one, make
9676 choose a suitable buffer for echo_area_buffer[0], and clear it.
9677
9678 Value is what FN returns. */
9679
9680 static int
9681 with_echo_area_buffer (struct window *w, int which,
9682 int (*fn) (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT),
9683 EMACS_INT a1, Lisp_Object a2, EMACS_INT a3, EMACS_INT a4)
9684 {
9685 Lisp_Object buffer;
9686 int this_one, the_other, clear_buffer_p, rc;
9687 int count = SPECPDL_INDEX ();
9688
9689 /* If buffers aren't live, make new ones. */
9690 ensure_echo_area_buffers ();
9691
9692 clear_buffer_p = 0;
9693
9694 if (which == 0)
9695 this_one = 0, the_other = 1;
9696 else if (which > 0)
9697 this_one = 1, the_other = 0;
9698 else
9699 {
9700 this_one = 0, the_other = 1;
9701 clear_buffer_p = 1;
9702
9703 /* We need a fresh one in case the current echo buffer equals
9704 the one containing the last displayed echo area message. */
9705 if (!NILP (echo_area_buffer[this_one])
9706 && EQ (echo_area_buffer[this_one], echo_area_buffer[the_other]))
9707 echo_area_buffer[this_one] = Qnil;
9708 }
9709
9710 /* Choose a suitable buffer from echo_buffer[] is we don't
9711 have one. */
9712 if (NILP (echo_area_buffer[this_one]))
9713 {
9714 echo_area_buffer[this_one]
9715 = (EQ (echo_area_buffer[the_other], echo_buffer[this_one])
9716 ? echo_buffer[the_other]
9717 : echo_buffer[this_one]);
9718 clear_buffer_p = 1;
9719 }
9720
9721 buffer = echo_area_buffer[this_one];
9722
9723 /* Don't get confused by reusing the buffer used for echoing
9724 for a different purpose. */
9725 if (echo_kboard == NULL && EQ (buffer, echo_message_buffer))
9726 cancel_echoing ();
9727
9728 record_unwind_protect (unwind_with_echo_area_buffer,
9729 with_echo_area_buffer_unwind_data (w));
9730
9731 /* Make the echo area buffer current. Note that for display
9732 purposes, it is not necessary that the displayed window's buffer
9733 == current_buffer, except for text property lookup. So, let's
9734 only set that buffer temporarily here without doing a full
9735 Fset_window_buffer. We must also change w->pointm, though,
9736 because otherwise an assertions in unshow_buffer fails, and Emacs
9737 aborts. */
9738 set_buffer_internal_1 (XBUFFER (buffer));
9739 if (w)
9740 {
9741 w->buffer = buffer;
9742 set_marker_both (w->pointm, buffer, BEG, BEG_BYTE);
9743 }
9744
9745 BVAR (current_buffer, undo_list) = Qt;
9746 BVAR (current_buffer, read_only) = Qnil;
9747 specbind (Qinhibit_read_only, Qt);
9748 specbind (Qinhibit_modification_hooks, Qt);
9749
9750 if (clear_buffer_p && Z > BEG)
9751 del_range (BEG, Z);
9752
9753 xassert (BEGV >= BEG);
9754 xassert (ZV <= Z && ZV >= BEGV);
9755
9756 rc = fn (a1, a2, a3, a4);
9757
9758 xassert (BEGV >= BEG);
9759 xassert (ZV <= Z && ZV >= BEGV);
9760
9761 unbind_to (count, Qnil);
9762 return rc;
9763 }
9764
9765
9766 /* Save state that should be preserved around the call to the function
9767 FN called in with_echo_area_buffer. */
9768
9769 static Lisp_Object
9770 with_echo_area_buffer_unwind_data (struct window *w)
9771 {
9772 int i = 0;
9773 Lisp_Object vector, tmp;
9774
9775 /* Reduce consing by keeping one vector in
9776 Vwith_echo_area_save_vector. */
9777 vector = Vwith_echo_area_save_vector;
9778 Vwith_echo_area_save_vector = Qnil;
9779
9780 if (NILP (vector))
9781 vector = Fmake_vector (make_number (7), Qnil);
9782
9783 XSETBUFFER (tmp, current_buffer); ASET (vector, i, tmp); ++i;
9784 ASET (vector, i, Vdeactivate_mark); ++i;
9785 ASET (vector, i, make_number (windows_or_buffers_changed)); ++i;
9786
9787 if (w)
9788 {
9789 XSETWINDOW (tmp, w); ASET (vector, i, tmp); ++i;
9790 ASET (vector, i, w->buffer); ++i;
9791 ASET (vector, i, make_number (XMARKER (w->pointm)->charpos)); ++i;
9792 ASET (vector, i, make_number (XMARKER (w->pointm)->bytepos)); ++i;
9793 }
9794 else
9795 {
9796 int end = i + 4;
9797 for (; i < end; ++i)
9798 ASET (vector, i, Qnil);
9799 }
9800
9801 xassert (i == ASIZE (vector));
9802 return vector;
9803 }
9804
9805
9806 /* Restore global state from VECTOR which was created by
9807 with_echo_area_buffer_unwind_data. */
9808
9809 static Lisp_Object
9810 unwind_with_echo_area_buffer (Lisp_Object vector)
9811 {
9812 set_buffer_internal_1 (XBUFFER (AREF (vector, 0)));
9813 Vdeactivate_mark = AREF (vector, 1);
9814 windows_or_buffers_changed = XFASTINT (AREF (vector, 2));
9815
9816 if (WINDOWP (AREF (vector, 3)))
9817 {
9818 struct window *w;
9819 Lisp_Object buffer, charpos, bytepos;
9820
9821 w = XWINDOW (AREF (vector, 3));
9822 buffer = AREF (vector, 4);
9823 charpos = AREF (vector, 5);
9824 bytepos = AREF (vector, 6);
9825
9826 w->buffer = buffer;
9827 set_marker_both (w->pointm, buffer,
9828 XFASTINT (charpos), XFASTINT (bytepos));
9829 }
9830
9831 Vwith_echo_area_save_vector = vector;
9832 return Qnil;
9833 }
9834
9835
9836 /* Set up the echo area for use by print functions. MULTIBYTE_P
9837 non-zero means we will print multibyte. */
9838
9839 void
9840 setup_echo_area_for_printing (int multibyte_p)
9841 {
9842 /* If we can't find an echo area any more, exit. */
9843 if (! FRAME_LIVE_P (XFRAME (selected_frame)))
9844 Fkill_emacs (Qnil);
9845
9846 ensure_echo_area_buffers ();
9847
9848 if (!message_buf_print)
9849 {
9850 /* A message has been output since the last time we printed.
9851 Choose a fresh echo area buffer. */
9852 if (EQ (echo_area_buffer[1], echo_buffer[0]))
9853 echo_area_buffer[0] = echo_buffer[1];
9854 else
9855 echo_area_buffer[0] = echo_buffer[0];
9856
9857 /* Switch to that buffer and clear it. */
9858 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
9859 BVAR (current_buffer, truncate_lines) = Qnil;
9860
9861 if (Z > BEG)
9862 {
9863 int count = SPECPDL_INDEX ();
9864 specbind (Qinhibit_read_only, Qt);
9865 /* Note that undo recording is always disabled. */
9866 del_range (BEG, Z);
9867 unbind_to (count, Qnil);
9868 }
9869 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
9870
9871 /* Set up the buffer for the multibyteness we need. */
9872 if (multibyte_p
9873 != !NILP (BVAR (current_buffer, enable_multibyte_characters)))
9874 Fset_buffer_multibyte (multibyte_p ? Qt : Qnil);
9875
9876 /* Raise the frame containing the echo area. */
9877 if (minibuffer_auto_raise)
9878 {
9879 struct frame *sf = SELECTED_FRAME ();
9880 Lisp_Object mini_window;
9881 mini_window = FRAME_MINIBUF_WINDOW (sf);
9882 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
9883 }
9884
9885 message_log_maybe_newline ();
9886 message_buf_print = 1;
9887 }
9888 else
9889 {
9890 if (NILP (echo_area_buffer[0]))
9891 {
9892 if (EQ (echo_area_buffer[1], echo_buffer[0]))
9893 echo_area_buffer[0] = echo_buffer[1];
9894 else
9895 echo_area_buffer[0] = echo_buffer[0];
9896 }
9897
9898 if (current_buffer != XBUFFER (echo_area_buffer[0]))
9899 {
9900 /* Someone switched buffers between print requests. */
9901 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
9902 BVAR (current_buffer, truncate_lines) = Qnil;
9903 }
9904 }
9905 }
9906
9907
9908 /* Display an echo area message in window W. Value is non-zero if W's
9909 height is changed. If display_last_displayed_message_p is
9910 non-zero, display the message that was last displayed, otherwise
9911 display the current message. */
9912
9913 static int
9914 display_echo_area (struct window *w)
9915 {
9916 int i, no_message_p, window_height_changed_p, count;
9917
9918 /* Temporarily disable garbage collections while displaying the echo
9919 area. This is done because a GC can print a message itself.
9920 That message would modify the echo area buffer's contents while a
9921 redisplay of the buffer is going on, and seriously confuse
9922 redisplay. */
9923 count = inhibit_garbage_collection ();
9924
9925 /* If there is no message, we must call display_echo_area_1
9926 nevertheless because it resizes the window. But we will have to
9927 reset the echo_area_buffer in question to nil at the end because
9928 with_echo_area_buffer will sets it to an empty buffer. */
9929 i = display_last_displayed_message_p ? 1 : 0;
9930 no_message_p = NILP (echo_area_buffer[i]);
9931
9932 window_height_changed_p
9933 = with_echo_area_buffer (w, display_last_displayed_message_p,
9934 display_echo_area_1,
9935 (intptr_t) w, Qnil, 0, 0);
9936
9937 if (no_message_p)
9938 echo_area_buffer[i] = Qnil;
9939
9940 unbind_to (count, Qnil);
9941 return window_height_changed_p;
9942 }
9943
9944
9945 /* Helper for display_echo_area. Display the current buffer which
9946 contains the current echo area message in window W, a mini-window,
9947 a pointer to which is passed in A1. A2..A4 are currently not used.
9948 Change the height of W so that all of the message is displayed.
9949 Value is non-zero if height of W was changed. */
9950
9951 static int
9952 display_echo_area_1 (EMACS_INT a1, Lisp_Object a2, EMACS_INT a3, EMACS_INT a4)
9953 {
9954 intptr_t i1 = a1;
9955 struct window *w = (struct window *) i1;
9956 Lisp_Object window;
9957 struct text_pos start;
9958 int window_height_changed_p = 0;
9959
9960 /* Do this before displaying, so that we have a large enough glyph
9961 matrix for the display. If we can't get enough space for the
9962 whole text, display the last N lines. That works by setting w->start. */
9963 window_height_changed_p = resize_mini_window (w, 0);
9964
9965 /* Use the starting position chosen by resize_mini_window. */
9966 SET_TEXT_POS_FROM_MARKER (start, w->start);
9967
9968 /* Display. */
9969 clear_glyph_matrix (w->desired_matrix);
9970 XSETWINDOW (window, w);
9971 try_window (window, start, 0);
9972
9973 return window_height_changed_p;
9974 }
9975
9976
9977 /* Resize the echo area window to exactly the size needed for the
9978 currently displayed message, if there is one. If a mini-buffer
9979 is active, don't shrink it. */
9980
9981 void
9982 resize_echo_area_exactly (void)
9983 {
9984 if (BUFFERP (echo_area_buffer[0])
9985 && WINDOWP (echo_area_window))
9986 {
9987 struct window *w = XWINDOW (echo_area_window);
9988 int resized_p;
9989 Lisp_Object resize_exactly;
9990
9991 if (minibuf_level == 0)
9992 resize_exactly = Qt;
9993 else
9994 resize_exactly = Qnil;
9995
9996 resized_p = with_echo_area_buffer (w, 0, resize_mini_window_1,
9997 (intptr_t) w, resize_exactly,
9998 0, 0);
9999 if (resized_p)
10000 {
10001 ++windows_or_buffers_changed;
10002 ++update_mode_lines;
10003 redisplay_internal ();
10004 }
10005 }
10006 }
10007
10008
10009 /* Callback function for with_echo_area_buffer, when used from
10010 resize_echo_area_exactly. A1 contains a pointer to the window to
10011 resize, EXACTLY non-nil means resize the mini-window exactly to the
10012 size of the text displayed. A3 and A4 are not used. Value is what
10013 resize_mini_window returns. */
10014
10015 static int
10016 resize_mini_window_1 (EMACS_INT a1, Lisp_Object exactly, EMACS_INT a3, EMACS_INT a4)
10017 {
10018 intptr_t i1 = a1;
10019 return resize_mini_window ((struct window *) i1, !NILP (exactly));
10020 }
10021
10022
10023 /* Resize mini-window W to fit the size of its contents. EXACT_P
10024 means size the window exactly to the size needed. Otherwise, it's
10025 only enlarged until W's buffer is empty.
10026
10027 Set W->start to the right place to begin display. If the whole
10028 contents fit, start at the beginning. Otherwise, start so as
10029 to make the end of the contents appear. This is particularly
10030 important for y-or-n-p, but seems desirable generally.
10031
10032 Value is non-zero if the window height has been changed. */
10033
10034 int
10035 resize_mini_window (struct window *w, int exact_p)
10036 {
10037 struct frame *f = XFRAME (w->frame);
10038 int window_height_changed_p = 0;
10039
10040 xassert (MINI_WINDOW_P (w));
10041
10042 /* By default, start display at the beginning. */
10043 set_marker_both (w->start, w->buffer,
10044 BUF_BEGV (XBUFFER (w->buffer)),
10045 BUF_BEGV_BYTE (XBUFFER (w->buffer)));
10046
10047 /* Don't resize windows while redisplaying a window; it would
10048 confuse redisplay functions when the size of the window they are
10049 displaying changes from under them. Such a resizing can happen,
10050 for instance, when which-func prints a long message while
10051 we are running fontification-functions. We're running these
10052 functions with safe_call which binds inhibit-redisplay to t. */
10053 if (!NILP (Vinhibit_redisplay))
10054 return 0;
10055
10056 /* Nil means don't try to resize. */
10057 if (NILP (Vresize_mini_windows)
10058 || (FRAME_X_P (f) && FRAME_X_OUTPUT (f) == NULL))
10059 return 0;
10060
10061 if (!FRAME_MINIBUF_ONLY_P (f))
10062 {
10063 struct it it;
10064 struct window *root = XWINDOW (FRAME_ROOT_WINDOW (f));
10065 int total_height = WINDOW_TOTAL_LINES (root) + WINDOW_TOTAL_LINES (w);
10066 int height, max_height;
10067 int unit = FRAME_LINE_HEIGHT (f);
10068 struct text_pos start;
10069 struct buffer *old_current_buffer = NULL;
10070
10071 if (current_buffer != XBUFFER (w->buffer))
10072 {
10073 old_current_buffer = current_buffer;
10074 set_buffer_internal (XBUFFER (w->buffer));
10075 }
10076
10077 init_iterator (&it, w, BEGV, BEGV_BYTE, NULL, DEFAULT_FACE_ID);
10078
10079 /* Compute the max. number of lines specified by the user. */
10080 if (FLOATP (Vmax_mini_window_height))
10081 max_height = XFLOATINT (Vmax_mini_window_height) * FRAME_LINES (f);
10082 else if (INTEGERP (Vmax_mini_window_height))
10083 max_height = XINT (Vmax_mini_window_height);
10084 else
10085 max_height = total_height / 4;
10086
10087 /* Correct that max. height if it's bogus. */
10088 max_height = max (1, max_height);
10089 max_height = min (total_height, max_height);
10090
10091 /* Find out the height of the text in the window. */
10092 if (it.line_wrap == TRUNCATE)
10093 height = 1;
10094 else
10095 {
10096 last_height = 0;
10097 move_it_to (&it, ZV, -1, -1, -1, MOVE_TO_POS);
10098 if (it.max_ascent == 0 && it.max_descent == 0)
10099 height = it.current_y + last_height;
10100 else
10101 height = it.current_y + it.max_ascent + it.max_descent;
10102 height -= min (it.extra_line_spacing, it.max_extra_line_spacing);
10103 height = (height + unit - 1) / unit;
10104 }
10105
10106 /* Compute a suitable window start. */
10107 if (height > max_height)
10108 {
10109 height = max_height;
10110 init_iterator (&it, w, ZV, ZV_BYTE, NULL, DEFAULT_FACE_ID);
10111 move_it_vertically_backward (&it, (height - 1) * unit);
10112 start = it.current.pos;
10113 }
10114 else
10115 SET_TEXT_POS (start, BEGV, BEGV_BYTE);
10116 SET_MARKER_FROM_TEXT_POS (w->start, start);
10117
10118 if (EQ (Vresize_mini_windows, Qgrow_only))
10119 {
10120 /* Let it grow only, until we display an empty message, in which
10121 case the window shrinks again. */
10122 if (height > WINDOW_TOTAL_LINES (w))
10123 {
10124 int old_height = WINDOW_TOTAL_LINES (w);
10125 freeze_window_starts (f, 1);
10126 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
10127 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
10128 }
10129 else if (height < WINDOW_TOTAL_LINES (w)
10130 && (exact_p || BEGV == ZV))
10131 {
10132 int old_height = WINDOW_TOTAL_LINES (w);
10133 freeze_window_starts (f, 0);
10134 shrink_mini_window (w);
10135 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
10136 }
10137 }
10138 else
10139 {
10140 /* Always resize to exact size needed. */
10141 if (height > WINDOW_TOTAL_LINES (w))
10142 {
10143 int old_height = WINDOW_TOTAL_LINES (w);
10144 freeze_window_starts (f, 1);
10145 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
10146 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
10147 }
10148 else if (height < WINDOW_TOTAL_LINES (w))
10149 {
10150 int old_height = WINDOW_TOTAL_LINES (w);
10151 freeze_window_starts (f, 0);
10152 shrink_mini_window (w);
10153
10154 if (height)
10155 {
10156 freeze_window_starts (f, 1);
10157 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
10158 }
10159
10160 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
10161 }
10162 }
10163
10164 if (old_current_buffer)
10165 set_buffer_internal (old_current_buffer);
10166 }
10167
10168 return window_height_changed_p;
10169 }
10170
10171
10172 /* Value is the current message, a string, or nil if there is no
10173 current message. */
10174
10175 Lisp_Object
10176 current_message (void)
10177 {
10178 Lisp_Object msg;
10179
10180 if (!BUFFERP (echo_area_buffer[0]))
10181 msg = Qnil;
10182 else
10183 {
10184 with_echo_area_buffer (0, 0, current_message_1,
10185 (intptr_t) &msg, Qnil, 0, 0);
10186 if (NILP (msg))
10187 echo_area_buffer[0] = Qnil;
10188 }
10189
10190 return msg;
10191 }
10192
10193
10194 static int
10195 current_message_1 (EMACS_INT a1, Lisp_Object a2, EMACS_INT a3, EMACS_INT a4)
10196 {
10197 intptr_t i1 = a1;
10198 Lisp_Object *msg = (Lisp_Object *) i1;
10199
10200 if (Z > BEG)
10201 *msg = make_buffer_string (BEG, Z, 1);
10202 else
10203 *msg = Qnil;
10204 return 0;
10205 }
10206
10207
10208 /* Push the current message on Vmessage_stack for later restauration
10209 by restore_message. Value is non-zero if the current message isn't
10210 empty. This is a relatively infrequent operation, so it's not
10211 worth optimizing. */
10212
10213 int
10214 push_message (void)
10215 {
10216 Lisp_Object msg;
10217 msg = current_message ();
10218 Vmessage_stack = Fcons (msg, Vmessage_stack);
10219 return STRINGP (msg);
10220 }
10221
10222
10223 /* Restore message display from the top of Vmessage_stack. */
10224
10225 void
10226 restore_message (void)
10227 {
10228 Lisp_Object msg;
10229
10230 xassert (CONSP (Vmessage_stack));
10231 msg = XCAR (Vmessage_stack);
10232 if (STRINGP (msg))
10233 message3_nolog (msg, SBYTES (msg), STRING_MULTIBYTE (msg));
10234 else
10235 message3_nolog (msg, 0, 0);
10236 }
10237
10238
10239 /* Handler for record_unwind_protect calling pop_message. */
10240
10241 Lisp_Object
10242 pop_message_unwind (Lisp_Object dummy)
10243 {
10244 pop_message ();
10245 return Qnil;
10246 }
10247
10248 /* Pop the top-most entry off Vmessage_stack. */
10249
10250 static void
10251 pop_message (void)
10252 {
10253 xassert (CONSP (Vmessage_stack));
10254 Vmessage_stack = XCDR (Vmessage_stack);
10255 }
10256
10257
10258 /* Check that Vmessage_stack is nil. Called from emacs.c when Emacs
10259 exits. If the stack is not empty, we have a missing pop_message
10260 somewhere. */
10261
10262 void
10263 check_message_stack (void)
10264 {
10265 if (!NILP (Vmessage_stack))
10266 abort ();
10267 }
10268
10269
10270 /* Truncate to NCHARS what will be displayed in the echo area the next
10271 time we display it---but don't redisplay it now. */
10272
10273 void
10274 truncate_echo_area (EMACS_INT nchars)
10275 {
10276 if (nchars == 0)
10277 echo_area_buffer[0] = Qnil;
10278 /* A null message buffer means that the frame hasn't really been
10279 initialized yet. Error messages get reported properly by
10280 cmd_error, so this must be just an informative message; toss it. */
10281 else if (!noninteractive
10282 && INTERACTIVE
10283 && !NILP (echo_area_buffer[0]))
10284 {
10285 struct frame *sf = SELECTED_FRAME ();
10286 if (FRAME_MESSAGE_BUF (sf))
10287 with_echo_area_buffer (0, 0, truncate_message_1, nchars, Qnil, 0, 0);
10288 }
10289 }
10290
10291
10292 /* Helper function for truncate_echo_area. Truncate the current
10293 message to at most NCHARS characters. */
10294
10295 static int
10296 truncate_message_1 (EMACS_INT nchars, Lisp_Object a2, EMACS_INT a3, EMACS_INT a4)
10297 {
10298 if (BEG + nchars < Z)
10299 del_range (BEG + nchars, Z);
10300 if (Z == BEG)
10301 echo_area_buffer[0] = Qnil;
10302 return 0;
10303 }
10304
10305
10306 /* Set the current message to a substring of S or STRING.
10307
10308 If STRING is a Lisp string, set the message to the first NBYTES
10309 bytes from STRING. NBYTES zero means use the whole string. If
10310 STRING is multibyte, the message will be displayed multibyte.
10311
10312 If S is not null, set the message to the first LEN bytes of S. LEN
10313 zero means use the whole string. MULTIBYTE_P non-zero means S is
10314 multibyte. Display the message multibyte in that case.
10315
10316 Doesn't GC, as with_echo_area_buffer binds Qinhibit_modification_hooks
10317 to t before calling set_message_1 (which calls insert).
10318 */
10319
10320 static void
10321 set_message (const char *s, Lisp_Object string,
10322 EMACS_INT nbytes, int multibyte_p)
10323 {
10324 message_enable_multibyte
10325 = ((s && multibyte_p)
10326 || (STRINGP (string) && STRING_MULTIBYTE (string)));
10327
10328 with_echo_area_buffer (0, -1, set_message_1,
10329 (intptr_t) s, string, nbytes, multibyte_p);
10330 message_buf_print = 0;
10331 help_echo_showing_p = 0;
10332 }
10333
10334
10335 /* Helper function for set_message. Arguments have the same meaning
10336 as there, with A1 corresponding to S and A2 corresponding to STRING
10337 This function is called with the echo area buffer being
10338 current. */
10339
10340 static int
10341 set_message_1 (EMACS_INT a1, Lisp_Object a2, EMACS_INT nbytes, EMACS_INT multibyte_p)
10342 {
10343 intptr_t i1 = a1;
10344 const char *s = (const char *) i1;
10345 const unsigned char *msg = (const unsigned char *) s;
10346 Lisp_Object string = a2;
10347
10348 /* Change multibyteness of the echo buffer appropriately. */
10349 if (message_enable_multibyte
10350 != !NILP (BVAR (current_buffer, enable_multibyte_characters)))
10351 Fset_buffer_multibyte (message_enable_multibyte ? Qt : Qnil);
10352
10353 BVAR (current_buffer, truncate_lines) = message_truncate_lines ? Qt : Qnil;
10354 if (!NILP (BVAR (current_buffer, bidi_display_reordering)))
10355 BVAR (current_buffer, bidi_paragraph_direction) = Qleft_to_right;
10356
10357 /* Insert new message at BEG. */
10358 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
10359
10360 if (STRINGP (string))
10361 {
10362 EMACS_INT nchars;
10363
10364 if (nbytes == 0)
10365 nbytes = SBYTES (string);
10366 nchars = string_byte_to_char (string, nbytes);
10367
10368 /* This function takes care of single/multibyte conversion. We
10369 just have to ensure that the echo area buffer has the right
10370 setting of enable_multibyte_characters. */
10371 insert_from_string (string, 0, 0, nchars, nbytes, 1);
10372 }
10373 else if (s)
10374 {
10375 if (nbytes == 0)
10376 nbytes = strlen (s);
10377
10378 if (multibyte_p && NILP (BVAR (current_buffer, enable_multibyte_characters)))
10379 {
10380 /* Convert from multi-byte to single-byte. */
10381 EMACS_INT i;
10382 int c, n;
10383 char work[1];
10384
10385 /* Convert a multibyte string to single-byte. */
10386 for (i = 0; i < nbytes; i += n)
10387 {
10388 c = string_char_and_length (msg + i, &n);
10389 work[0] = (ASCII_CHAR_P (c)
10390 ? c
10391 : multibyte_char_to_unibyte (c));
10392 insert_1_both (work, 1, 1, 1, 0, 0);
10393 }
10394 }
10395 else if (!multibyte_p
10396 && !NILP (BVAR (current_buffer, enable_multibyte_characters)))
10397 {
10398 /* Convert from single-byte to multi-byte. */
10399 EMACS_INT i;
10400 int c, n;
10401 unsigned char str[MAX_MULTIBYTE_LENGTH];
10402
10403 /* Convert a single-byte string to multibyte. */
10404 for (i = 0; i < nbytes; i++)
10405 {
10406 c = msg[i];
10407 MAKE_CHAR_MULTIBYTE (c);
10408 n = CHAR_STRING (c, str);
10409 insert_1_both ((char *) str, 1, n, 1, 0, 0);
10410 }
10411 }
10412 else
10413 insert_1 (s, nbytes, 1, 0, 0);
10414 }
10415
10416 return 0;
10417 }
10418
10419
10420 /* Clear messages. CURRENT_P non-zero means clear the current
10421 message. LAST_DISPLAYED_P non-zero means clear the message
10422 last displayed. */
10423
10424 void
10425 clear_message (int current_p, int last_displayed_p)
10426 {
10427 if (current_p)
10428 {
10429 echo_area_buffer[0] = Qnil;
10430 message_cleared_p = 1;
10431 }
10432
10433 if (last_displayed_p)
10434 echo_area_buffer[1] = Qnil;
10435
10436 message_buf_print = 0;
10437 }
10438
10439 /* Clear garbaged frames.
10440
10441 This function is used where the old redisplay called
10442 redraw_garbaged_frames which in turn called redraw_frame which in
10443 turn called clear_frame. The call to clear_frame was a source of
10444 flickering. I believe a clear_frame is not necessary. It should
10445 suffice in the new redisplay to invalidate all current matrices,
10446 and ensure a complete redisplay of all windows. */
10447
10448 static void
10449 clear_garbaged_frames (void)
10450 {
10451 if (frame_garbaged)
10452 {
10453 Lisp_Object tail, frame;
10454 int changed_count = 0;
10455
10456 FOR_EACH_FRAME (tail, frame)
10457 {
10458 struct frame *f = XFRAME (frame);
10459
10460 if (FRAME_VISIBLE_P (f) && FRAME_GARBAGED_P (f))
10461 {
10462 if (f->resized_p)
10463 {
10464 Fredraw_frame (frame);
10465 f->force_flush_display_p = 1;
10466 }
10467 clear_current_matrices (f);
10468 changed_count++;
10469 f->garbaged = 0;
10470 f->resized_p = 0;
10471 }
10472 }
10473
10474 frame_garbaged = 0;
10475 if (changed_count)
10476 ++windows_or_buffers_changed;
10477 }
10478 }
10479
10480
10481 /* Redisplay the echo area of the selected frame. If UPDATE_FRAME_P
10482 is non-zero update selected_frame. Value is non-zero if the
10483 mini-windows height has been changed. */
10484
10485 static int
10486 echo_area_display (int update_frame_p)
10487 {
10488 Lisp_Object mini_window;
10489 struct window *w;
10490 struct frame *f;
10491 int window_height_changed_p = 0;
10492 struct frame *sf = SELECTED_FRAME ();
10493
10494 mini_window = FRAME_MINIBUF_WINDOW (sf);
10495 w = XWINDOW (mini_window);
10496 f = XFRAME (WINDOW_FRAME (w));
10497
10498 /* Don't display if frame is invisible or not yet initialized. */
10499 if (!FRAME_VISIBLE_P (f) || !f->glyphs_initialized_p)
10500 return 0;
10501
10502 #ifdef HAVE_WINDOW_SYSTEM
10503 /* When Emacs starts, selected_frame may be the initial terminal
10504 frame. If we let this through, a message would be displayed on
10505 the terminal. */
10506 if (FRAME_INITIAL_P (XFRAME (selected_frame)))
10507 return 0;
10508 #endif /* HAVE_WINDOW_SYSTEM */
10509
10510 /* Redraw garbaged frames. */
10511 if (frame_garbaged)
10512 clear_garbaged_frames ();
10513
10514 if (!NILP (echo_area_buffer[0]) || minibuf_level == 0)
10515 {
10516 echo_area_window = mini_window;
10517 window_height_changed_p = display_echo_area (w);
10518 w->must_be_updated_p = 1;
10519
10520 /* Update the display, unless called from redisplay_internal.
10521 Also don't update the screen during redisplay itself. The
10522 update will happen at the end of redisplay, and an update
10523 here could cause confusion. */
10524 if (update_frame_p && !redisplaying_p)
10525 {
10526 int n = 0;
10527
10528 /* If the display update has been interrupted by pending
10529 input, update mode lines in the frame. Due to the
10530 pending input, it might have been that redisplay hasn't
10531 been called, so that mode lines above the echo area are
10532 garbaged. This looks odd, so we prevent it here. */
10533 if (!display_completed)
10534 n = redisplay_mode_lines (FRAME_ROOT_WINDOW (f), 0);
10535
10536 if (window_height_changed_p
10537 /* Don't do this if Emacs is shutting down. Redisplay
10538 needs to run hooks. */
10539 && !NILP (Vrun_hooks))
10540 {
10541 /* Must update other windows. Likewise as in other
10542 cases, don't let this update be interrupted by
10543 pending input. */
10544 int count = SPECPDL_INDEX ();
10545 specbind (Qredisplay_dont_pause, Qt);
10546 windows_or_buffers_changed = 1;
10547 redisplay_internal ();
10548 unbind_to (count, Qnil);
10549 }
10550 else if (FRAME_WINDOW_P (f) && n == 0)
10551 {
10552 /* Window configuration is the same as before.
10553 Can do with a display update of the echo area,
10554 unless we displayed some mode lines. */
10555 update_single_window (w, 1);
10556 FRAME_RIF (f)->flush_display (f);
10557 }
10558 else
10559 update_frame (f, 1, 1);
10560
10561 /* If cursor is in the echo area, make sure that the next
10562 redisplay displays the minibuffer, so that the cursor will
10563 be replaced with what the minibuffer wants. */
10564 if (cursor_in_echo_area)
10565 ++windows_or_buffers_changed;
10566 }
10567 }
10568 else if (!EQ (mini_window, selected_window))
10569 windows_or_buffers_changed++;
10570
10571 /* Last displayed message is now the current message. */
10572 echo_area_buffer[1] = echo_area_buffer[0];
10573 /* Inform read_char that we're not echoing. */
10574 echo_message_buffer = Qnil;
10575
10576 /* Prevent redisplay optimization in redisplay_internal by resetting
10577 this_line_start_pos. This is done because the mini-buffer now
10578 displays the message instead of its buffer text. */
10579 if (EQ (mini_window, selected_window))
10580 CHARPOS (this_line_start_pos) = 0;
10581
10582 return window_height_changed_p;
10583 }
10584
10585
10586 \f
10587 /***********************************************************************
10588 Mode Lines and Frame Titles
10589 ***********************************************************************/
10590
10591 /* A buffer for constructing non-propertized mode-line strings and
10592 frame titles in it; allocated from the heap in init_xdisp and
10593 resized as needed in store_mode_line_noprop_char. */
10594
10595 static char *mode_line_noprop_buf;
10596
10597 /* The buffer's end, and a current output position in it. */
10598
10599 static char *mode_line_noprop_buf_end;
10600 static char *mode_line_noprop_ptr;
10601
10602 #define MODE_LINE_NOPROP_LEN(start) \
10603 ((mode_line_noprop_ptr - mode_line_noprop_buf) - start)
10604
10605 static enum {
10606 MODE_LINE_DISPLAY = 0,
10607 MODE_LINE_TITLE,
10608 MODE_LINE_NOPROP,
10609 MODE_LINE_STRING
10610 } mode_line_target;
10611
10612 /* Alist that caches the results of :propertize.
10613 Each element is (PROPERTIZED-STRING . PROPERTY-LIST). */
10614 static Lisp_Object mode_line_proptrans_alist;
10615
10616 /* List of strings making up the mode-line. */
10617 static Lisp_Object mode_line_string_list;
10618
10619 /* Base face property when building propertized mode line string. */
10620 static Lisp_Object mode_line_string_face;
10621 static Lisp_Object mode_line_string_face_prop;
10622
10623
10624 /* Unwind data for mode line strings */
10625
10626 static Lisp_Object Vmode_line_unwind_vector;
10627
10628 static Lisp_Object
10629 format_mode_line_unwind_data (struct buffer *obuf,
10630 Lisp_Object owin,
10631 int save_proptrans)
10632 {
10633 Lisp_Object vector, tmp;
10634
10635 /* Reduce consing by keeping one vector in
10636 Vwith_echo_area_save_vector. */
10637 vector = Vmode_line_unwind_vector;
10638 Vmode_line_unwind_vector = Qnil;
10639
10640 if (NILP (vector))
10641 vector = Fmake_vector (make_number (8), Qnil);
10642
10643 ASET (vector, 0, make_number (mode_line_target));
10644 ASET (vector, 1, make_number (MODE_LINE_NOPROP_LEN (0)));
10645 ASET (vector, 2, mode_line_string_list);
10646 ASET (vector, 3, save_proptrans ? mode_line_proptrans_alist : Qt);
10647 ASET (vector, 4, mode_line_string_face);
10648 ASET (vector, 5, mode_line_string_face_prop);
10649
10650 if (obuf)
10651 XSETBUFFER (tmp, obuf);
10652 else
10653 tmp = Qnil;
10654 ASET (vector, 6, tmp);
10655 ASET (vector, 7, owin);
10656
10657 return vector;
10658 }
10659
10660 static Lisp_Object
10661 unwind_format_mode_line (Lisp_Object vector)
10662 {
10663 mode_line_target = XINT (AREF (vector, 0));
10664 mode_line_noprop_ptr = mode_line_noprop_buf + XINT (AREF (vector, 1));
10665 mode_line_string_list = AREF (vector, 2);
10666 if (! EQ (AREF (vector, 3), Qt))
10667 mode_line_proptrans_alist = AREF (vector, 3);
10668 mode_line_string_face = AREF (vector, 4);
10669 mode_line_string_face_prop = AREF (vector, 5);
10670
10671 if (!NILP (AREF (vector, 7)))
10672 /* Select window before buffer, since it may change the buffer. */
10673 Fselect_window (AREF (vector, 7), Qt);
10674
10675 if (!NILP (AREF (vector, 6)))
10676 {
10677 set_buffer_internal_1 (XBUFFER (AREF (vector, 6)));
10678 ASET (vector, 6, Qnil);
10679 }
10680
10681 Vmode_line_unwind_vector = vector;
10682 return Qnil;
10683 }
10684
10685
10686 /* Store a single character C for the frame title in mode_line_noprop_buf.
10687 Re-allocate mode_line_noprop_buf if necessary. */
10688
10689 static void
10690 store_mode_line_noprop_char (char c)
10691 {
10692 /* If output position has reached the end of the allocated buffer,
10693 increase the buffer's size. */
10694 if (mode_line_noprop_ptr == mode_line_noprop_buf_end)
10695 {
10696 ptrdiff_t len = MODE_LINE_NOPROP_LEN (0);
10697 ptrdiff_t size = len;
10698 mode_line_noprop_buf =
10699 xpalloc (mode_line_noprop_buf, &size, 1, STRING_BYTES_BOUND, 1);
10700 mode_line_noprop_buf_end = mode_line_noprop_buf + size;
10701 mode_line_noprop_ptr = mode_line_noprop_buf + len;
10702 }
10703
10704 *mode_line_noprop_ptr++ = c;
10705 }
10706
10707
10708 /* Store part of a frame title in mode_line_noprop_buf, beginning at
10709 mode_line_noprop_ptr. STRING is the string to store. Do not copy
10710 characters that yield more columns than PRECISION; PRECISION <= 0
10711 means copy the whole string. Pad with spaces until FIELD_WIDTH
10712 number of characters have been copied; FIELD_WIDTH <= 0 means don't
10713 pad. Called from display_mode_element when it is used to build a
10714 frame title. */
10715
10716 static int
10717 store_mode_line_noprop (const char *string, int field_width, int precision)
10718 {
10719 const unsigned char *str = (const unsigned char *) string;
10720 int n = 0;
10721 EMACS_INT dummy, nbytes;
10722
10723 /* Copy at most PRECISION chars from STR. */
10724 nbytes = strlen (string);
10725 n += c_string_width (str, nbytes, precision, &dummy, &nbytes);
10726 while (nbytes--)
10727 store_mode_line_noprop_char (*str++);
10728
10729 /* Fill up with spaces until FIELD_WIDTH reached. */
10730 while (field_width > 0
10731 && n < field_width)
10732 {
10733 store_mode_line_noprop_char (' ');
10734 ++n;
10735 }
10736
10737 return n;
10738 }
10739
10740 /***********************************************************************
10741 Frame Titles
10742 ***********************************************************************/
10743
10744 #ifdef HAVE_WINDOW_SYSTEM
10745
10746 /* Set the title of FRAME, if it has changed. The title format is
10747 Vicon_title_format if FRAME is iconified, otherwise it is
10748 frame_title_format. */
10749
10750 static void
10751 x_consider_frame_title (Lisp_Object frame)
10752 {
10753 struct frame *f = XFRAME (frame);
10754
10755 if (FRAME_WINDOW_P (f)
10756 || FRAME_MINIBUF_ONLY_P (f)
10757 || f->explicit_name)
10758 {
10759 /* Do we have more than one visible frame on this X display? */
10760 Lisp_Object tail;
10761 Lisp_Object fmt;
10762 ptrdiff_t title_start;
10763 char *title;
10764 ptrdiff_t len;
10765 struct it it;
10766 int count = SPECPDL_INDEX ();
10767
10768 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
10769 {
10770 Lisp_Object other_frame = XCAR (tail);
10771 struct frame *tf = XFRAME (other_frame);
10772
10773 if (tf != f
10774 && FRAME_KBOARD (tf) == FRAME_KBOARD (f)
10775 && !FRAME_MINIBUF_ONLY_P (tf)
10776 && !EQ (other_frame, tip_frame)
10777 && (FRAME_VISIBLE_P (tf) || FRAME_ICONIFIED_P (tf)))
10778 break;
10779 }
10780
10781 /* Set global variable indicating that multiple frames exist. */
10782 multiple_frames = CONSP (tail);
10783
10784 /* Switch to the buffer of selected window of the frame. Set up
10785 mode_line_target so that display_mode_element will output into
10786 mode_line_noprop_buf; then display the title. */
10787 record_unwind_protect (unwind_format_mode_line,
10788 format_mode_line_unwind_data
10789 (current_buffer, selected_window, 0));
10790
10791 Fselect_window (f->selected_window, Qt);
10792 set_buffer_internal_1 (XBUFFER (XWINDOW (f->selected_window)->buffer));
10793 fmt = FRAME_ICONIFIED_P (f) ? Vicon_title_format : Vframe_title_format;
10794
10795 mode_line_target = MODE_LINE_TITLE;
10796 title_start = MODE_LINE_NOPROP_LEN (0);
10797 init_iterator (&it, XWINDOW (f->selected_window), -1, -1,
10798 NULL, DEFAULT_FACE_ID);
10799 display_mode_element (&it, 0, -1, -1, fmt, Qnil, 0);
10800 len = MODE_LINE_NOPROP_LEN (title_start);
10801 title = mode_line_noprop_buf + title_start;
10802 unbind_to (count, Qnil);
10803
10804 /* Set the title only if it's changed. This avoids consing in
10805 the common case where it hasn't. (If it turns out that we've
10806 already wasted too much time by walking through the list with
10807 display_mode_element, then we might need to optimize at a
10808 higher level than this.) */
10809 if (! STRINGP (f->name)
10810 || SBYTES (f->name) != len
10811 || memcmp (title, SDATA (f->name), len) != 0)
10812 x_implicitly_set_name (f, make_string (title, len), Qnil);
10813 }
10814 }
10815
10816 #endif /* not HAVE_WINDOW_SYSTEM */
10817
10818
10819
10820 \f
10821 /***********************************************************************
10822 Menu Bars
10823 ***********************************************************************/
10824
10825
10826 /* Prepare for redisplay by updating menu-bar item lists when
10827 appropriate. This can call eval. */
10828
10829 void
10830 prepare_menu_bars (void)
10831 {
10832 int all_windows;
10833 struct gcpro gcpro1, gcpro2;
10834 struct frame *f;
10835 Lisp_Object tooltip_frame;
10836
10837 #ifdef HAVE_WINDOW_SYSTEM
10838 tooltip_frame = tip_frame;
10839 #else
10840 tooltip_frame = Qnil;
10841 #endif
10842
10843 /* Update all frame titles based on their buffer names, etc. We do
10844 this before the menu bars so that the buffer-menu will show the
10845 up-to-date frame titles. */
10846 #ifdef HAVE_WINDOW_SYSTEM
10847 if (windows_or_buffers_changed || update_mode_lines)
10848 {
10849 Lisp_Object tail, frame;
10850
10851 FOR_EACH_FRAME (tail, frame)
10852 {
10853 f = XFRAME (frame);
10854 if (!EQ (frame, tooltip_frame)
10855 && (FRAME_VISIBLE_P (f) || FRAME_ICONIFIED_P (f)))
10856 x_consider_frame_title (frame);
10857 }
10858 }
10859 #endif /* HAVE_WINDOW_SYSTEM */
10860
10861 /* Update the menu bar item lists, if appropriate. This has to be
10862 done before any actual redisplay or generation of display lines. */
10863 all_windows = (update_mode_lines
10864 || buffer_shared > 1
10865 || windows_or_buffers_changed);
10866 if (all_windows)
10867 {
10868 Lisp_Object tail, frame;
10869 int count = SPECPDL_INDEX ();
10870 /* 1 means that update_menu_bar has run its hooks
10871 so any further calls to update_menu_bar shouldn't do so again. */
10872 int menu_bar_hooks_run = 0;
10873
10874 record_unwind_save_match_data ();
10875
10876 FOR_EACH_FRAME (tail, frame)
10877 {
10878 f = XFRAME (frame);
10879
10880 /* Ignore tooltip frame. */
10881 if (EQ (frame, tooltip_frame))
10882 continue;
10883
10884 /* If a window on this frame changed size, report that to
10885 the user and clear the size-change flag. */
10886 if (FRAME_WINDOW_SIZES_CHANGED (f))
10887 {
10888 Lisp_Object functions;
10889
10890 /* Clear flag first in case we get an error below. */
10891 FRAME_WINDOW_SIZES_CHANGED (f) = 0;
10892 functions = Vwindow_size_change_functions;
10893 GCPRO2 (tail, functions);
10894
10895 while (CONSP (functions))
10896 {
10897 if (!EQ (XCAR (functions), Qt))
10898 call1 (XCAR (functions), frame);
10899 functions = XCDR (functions);
10900 }
10901 UNGCPRO;
10902 }
10903
10904 GCPRO1 (tail);
10905 menu_bar_hooks_run = update_menu_bar (f, 0, menu_bar_hooks_run);
10906 #ifdef HAVE_WINDOW_SYSTEM
10907 update_tool_bar (f, 0);
10908 #endif
10909 #ifdef HAVE_NS
10910 if (windows_or_buffers_changed
10911 && FRAME_NS_P (f))
10912 ns_set_doc_edited (f, Fbuffer_modified_p
10913 (XWINDOW (f->selected_window)->buffer));
10914 #endif
10915 UNGCPRO;
10916 }
10917
10918 unbind_to (count, Qnil);
10919 }
10920 else
10921 {
10922 struct frame *sf = SELECTED_FRAME ();
10923 update_menu_bar (sf, 1, 0);
10924 #ifdef HAVE_WINDOW_SYSTEM
10925 update_tool_bar (sf, 1);
10926 #endif
10927 }
10928 }
10929
10930
10931 /* Update the menu bar item list for frame F. This has to be done
10932 before we start to fill in any display lines, because it can call
10933 eval.
10934
10935 If SAVE_MATCH_DATA is non-zero, we must save and restore it here.
10936
10937 If HOOKS_RUN is 1, that means a previous call to update_menu_bar
10938 already ran the menu bar hooks for this redisplay, so there
10939 is no need to run them again. The return value is the
10940 updated value of this flag, to pass to the next call. */
10941
10942 static int
10943 update_menu_bar (struct frame *f, int save_match_data, int hooks_run)
10944 {
10945 Lisp_Object window;
10946 register struct window *w;
10947
10948 /* If called recursively during a menu update, do nothing. This can
10949 happen when, for instance, an activate-menubar-hook causes a
10950 redisplay. */
10951 if (inhibit_menubar_update)
10952 return hooks_run;
10953
10954 window = FRAME_SELECTED_WINDOW (f);
10955 w = XWINDOW (window);
10956
10957 if (FRAME_WINDOW_P (f)
10958 ?
10959 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
10960 || defined (HAVE_NS) || defined (USE_GTK)
10961 FRAME_EXTERNAL_MENU_BAR (f)
10962 #else
10963 FRAME_MENU_BAR_LINES (f) > 0
10964 #endif
10965 : FRAME_MENU_BAR_LINES (f) > 0)
10966 {
10967 /* If the user has switched buffers or windows, we need to
10968 recompute to reflect the new bindings. But we'll
10969 recompute when update_mode_lines is set too; that means
10970 that people can use force-mode-line-update to request
10971 that the menu bar be recomputed. The adverse effect on
10972 the rest of the redisplay algorithm is about the same as
10973 windows_or_buffers_changed anyway. */
10974 if (windows_or_buffers_changed
10975 /* This used to test w->update_mode_line, but we believe
10976 there is no need to recompute the menu in that case. */
10977 || update_mode_lines
10978 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
10979 < BUF_MODIFF (XBUFFER (w->buffer)))
10980 != !NILP (w->last_had_star))
10981 || ((!NILP (Vtransient_mark_mode)
10982 && !NILP (BVAR (XBUFFER (w->buffer), mark_active)))
10983 != !NILP (w->region_showing)))
10984 {
10985 struct buffer *prev = current_buffer;
10986 int count = SPECPDL_INDEX ();
10987
10988 specbind (Qinhibit_menubar_update, Qt);
10989
10990 set_buffer_internal_1 (XBUFFER (w->buffer));
10991 if (save_match_data)
10992 record_unwind_save_match_data ();
10993 if (NILP (Voverriding_local_map_menu_flag))
10994 {
10995 specbind (Qoverriding_terminal_local_map, Qnil);
10996 specbind (Qoverriding_local_map, Qnil);
10997 }
10998
10999 if (!hooks_run)
11000 {
11001 /* Run the Lucid hook. */
11002 safe_run_hooks (Qactivate_menubar_hook);
11003
11004 /* If it has changed current-menubar from previous value,
11005 really recompute the menu-bar from the value. */
11006 if (! NILP (Vlucid_menu_bar_dirty_flag))
11007 call0 (Qrecompute_lucid_menubar);
11008
11009 safe_run_hooks (Qmenu_bar_update_hook);
11010
11011 hooks_run = 1;
11012 }
11013
11014 XSETFRAME (Vmenu_updating_frame, f);
11015 FRAME_MENU_BAR_ITEMS (f) = menu_bar_items (FRAME_MENU_BAR_ITEMS (f));
11016
11017 /* Redisplay the menu bar in case we changed it. */
11018 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
11019 || defined (HAVE_NS) || defined (USE_GTK)
11020 if (FRAME_WINDOW_P (f))
11021 {
11022 #if defined (HAVE_NS)
11023 /* All frames on Mac OS share the same menubar. So only
11024 the selected frame should be allowed to set it. */
11025 if (f == SELECTED_FRAME ())
11026 #endif
11027 set_frame_menubar (f, 0, 0);
11028 }
11029 else
11030 /* On a terminal screen, the menu bar is an ordinary screen
11031 line, and this makes it get updated. */
11032 w->update_mode_line = Qt;
11033 #else /* ! (USE_X_TOOLKIT || HAVE_NTGUI || HAVE_NS || USE_GTK) */
11034 /* In the non-toolkit version, the menu bar is an ordinary screen
11035 line, and this makes it get updated. */
11036 w->update_mode_line = Qt;
11037 #endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI || HAVE_NS || USE_GTK) */
11038
11039 unbind_to (count, Qnil);
11040 set_buffer_internal_1 (prev);
11041 }
11042 }
11043
11044 return hooks_run;
11045 }
11046
11047
11048 \f
11049 /***********************************************************************
11050 Output Cursor
11051 ***********************************************************************/
11052
11053 #ifdef HAVE_WINDOW_SYSTEM
11054
11055 /* EXPORT:
11056 Nominal cursor position -- where to draw output.
11057 HPOS and VPOS are window relative glyph matrix coordinates.
11058 X and Y are window relative pixel coordinates. */
11059
11060 struct cursor_pos output_cursor;
11061
11062
11063 /* EXPORT:
11064 Set the global variable output_cursor to CURSOR. All cursor
11065 positions are relative to updated_window. */
11066
11067 void
11068 set_output_cursor (struct cursor_pos *cursor)
11069 {
11070 output_cursor.hpos = cursor->hpos;
11071 output_cursor.vpos = cursor->vpos;
11072 output_cursor.x = cursor->x;
11073 output_cursor.y = cursor->y;
11074 }
11075
11076
11077 /* EXPORT for RIF:
11078 Set a nominal cursor position.
11079
11080 HPOS and VPOS are column/row positions in a window glyph matrix. X
11081 and Y are window text area relative pixel positions.
11082
11083 If this is done during an update, updated_window will contain the
11084 window that is being updated and the position is the future output
11085 cursor position for that window. If updated_window is null, use
11086 selected_window and display the cursor at the given position. */
11087
11088 void
11089 x_cursor_to (int vpos, int hpos, int y, int x)
11090 {
11091 struct window *w;
11092
11093 /* If updated_window is not set, work on selected_window. */
11094 if (updated_window)
11095 w = updated_window;
11096 else
11097 w = XWINDOW (selected_window);
11098
11099 /* Set the output cursor. */
11100 output_cursor.hpos = hpos;
11101 output_cursor.vpos = vpos;
11102 output_cursor.x = x;
11103 output_cursor.y = y;
11104
11105 /* If not called as part of an update, really display the cursor.
11106 This will also set the cursor position of W. */
11107 if (updated_window == NULL)
11108 {
11109 BLOCK_INPUT;
11110 display_and_set_cursor (w, 1, hpos, vpos, x, y);
11111 if (FRAME_RIF (SELECTED_FRAME ())->flush_display_optional)
11112 FRAME_RIF (SELECTED_FRAME ())->flush_display_optional (SELECTED_FRAME ());
11113 UNBLOCK_INPUT;
11114 }
11115 }
11116
11117 #endif /* HAVE_WINDOW_SYSTEM */
11118
11119 \f
11120 /***********************************************************************
11121 Tool-bars
11122 ***********************************************************************/
11123
11124 #ifdef HAVE_WINDOW_SYSTEM
11125
11126 /* Where the mouse was last time we reported a mouse event. */
11127
11128 FRAME_PTR last_mouse_frame;
11129
11130 /* Tool-bar item index of the item on which a mouse button was pressed
11131 or -1. */
11132
11133 int last_tool_bar_item;
11134
11135
11136 static Lisp_Object
11137 update_tool_bar_unwind (Lisp_Object frame)
11138 {
11139 selected_frame = frame;
11140 return Qnil;
11141 }
11142
11143 /* Update the tool-bar item list for frame F. This has to be done
11144 before we start to fill in any display lines. Called from
11145 prepare_menu_bars. If SAVE_MATCH_DATA is non-zero, we must save
11146 and restore it here. */
11147
11148 static void
11149 update_tool_bar (struct frame *f, int save_match_data)
11150 {
11151 #if defined (USE_GTK) || defined (HAVE_NS)
11152 int do_update = FRAME_EXTERNAL_TOOL_BAR (f);
11153 #else
11154 int do_update = WINDOWP (f->tool_bar_window)
11155 && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)) > 0;
11156 #endif
11157
11158 if (do_update)
11159 {
11160 Lisp_Object window;
11161 struct window *w;
11162
11163 window = FRAME_SELECTED_WINDOW (f);
11164 w = XWINDOW (window);
11165
11166 /* If the user has switched buffers or windows, we need to
11167 recompute to reflect the new bindings. But we'll
11168 recompute when update_mode_lines is set too; that means
11169 that people can use force-mode-line-update to request
11170 that the menu bar be recomputed. The adverse effect on
11171 the rest of the redisplay algorithm is about the same as
11172 windows_or_buffers_changed anyway. */
11173 if (windows_or_buffers_changed
11174 || !NILP (w->update_mode_line)
11175 || update_mode_lines
11176 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
11177 < BUF_MODIFF (XBUFFER (w->buffer)))
11178 != !NILP (w->last_had_star))
11179 || ((!NILP (Vtransient_mark_mode)
11180 && !NILP (BVAR (XBUFFER (w->buffer), mark_active)))
11181 != !NILP (w->region_showing)))
11182 {
11183 struct buffer *prev = current_buffer;
11184 int count = SPECPDL_INDEX ();
11185 Lisp_Object frame, new_tool_bar;
11186 int new_n_tool_bar;
11187 struct gcpro gcpro1;
11188
11189 /* Set current_buffer to the buffer of the selected
11190 window of the frame, so that we get the right local
11191 keymaps. */
11192 set_buffer_internal_1 (XBUFFER (w->buffer));
11193
11194 /* Save match data, if we must. */
11195 if (save_match_data)
11196 record_unwind_save_match_data ();
11197
11198 /* Make sure that we don't accidentally use bogus keymaps. */
11199 if (NILP (Voverriding_local_map_menu_flag))
11200 {
11201 specbind (Qoverriding_terminal_local_map, Qnil);
11202 specbind (Qoverriding_local_map, Qnil);
11203 }
11204
11205 GCPRO1 (new_tool_bar);
11206
11207 /* We must temporarily set the selected frame to this frame
11208 before calling tool_bar_items, because the calculation of
11209 the tool-bar keymap uses the selected frame (see
11210 `tool-bar-make-keymap' in tool-bar.el). */
11211 record_unwind_protect (update_tool_bar_unwind, selected_frame);
11212 XSETFRAME (frame, f);
11213 selected_frame = frame;
11214
11215 /* Build desired tool-bar items from keymaps. */
11216 new_tool_bar = tool_bar_items (Fcopy_sequence (f->tool_bar_items),
11217 &new_n_tool_bar);
11218
11219 /* Redisplay the tool-bar if we changed it. */
11220 if (new_n_tool_bar != f->n_tool_bar_items
11221 || NILP (Fequal (new_tool_bar, f->tool_bar_items)))
11222 {
11223 /* Redisplay that happens asynchronously due to an expose event
11224 may access f->tool_bar_items. Make sure we update both
11225 variables within BLOCK_INPUT so no such event interrupts. */
11226 BLOCK_INPUT;
11227 f->tool_bar_items = new_tool_bar;
11228 f->n_tool_bar_items = new_n_tool_bar;
11229 w->update_mode_line = Qt;
11230 UNBLOCK_INPUT;
11231 }
11232
11233 UNGCPRO;
11234
11235 unbind_to (count, Qnil);
11236 set_buffer_internal_1 (prev);
11237 }
11238 }
11239 }
11240
11241
11242 /* Set F->desired_tool_bar_string to a Lisp string representing frame
11243 F's desired tool-bar contents. F->tool_bar_items must have
11244 been set up previously by calling prepare_menu_bars. */
11245
11246 static void
11247 build_desired_tool_bar_string (struct frame *f)
11248 {
11249 int i, size, size_needed;
11250 struct gcpro gcpro1, gcpro2, gcpro3;
11251 Lisp_Object image, plist, props;
11252
11253 image = plist = props = Qnil;
11254 GCPRO3 (image, plist, props);
11255
11256 /* Prepare F->desired_tool_bar_string. If we can reuse it, do so.
11257 Otherwise, make a new string. */
11258
11259 /* The size of the string we might be able to reuse. */
11260 size = (STRINGP (f->desired_tool_bar_string)
11261 ? SCHARS (f->desired_tool_bar_string)
11262 : 0);
11263
11264 /* We need one space in the string for each image. */
11265 size_needed = f->n_tool_bar_items;
11266
11267 /* Reuse f->desired_tool_bar_string, if possible. */
11268 if (size < size_needed || NILP (f->desired_tool_bar_string))
11269 f->desired_tool_bar_string = Fmake_string (make_number (size_needed),
11270 make_number (' '));
11271 else
11272 {
11273 props = list4 (Qdisplay, Qnil, Qmenu_item, Qnil);
11274 Fremove_text_properties (make_number (0), make_number (size),
11275 props, f->desired_tool_bar_string);
11276 }
11277
11278 /* Put a `display' property on the string for the images to display,
11279 put a `menu_item' property on tool-bar items with a value that
11280 is the index of the item in F's tool-bar item vector. */
11281 for (i = 0; i < f->n_tool_bar_items; ++i)
11282 {
11283 #define PROP(IDX) AREF (f->tool_bar_items, i * TOOL_BAR_ITEM_NSLOTS + (IDX))
11284
11285 int enabled_p = !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P));
11286 int selected_p = !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P));
11287 int hmargin, vmargin, relief, idx, end;
11288
11289 /* If image is a vector, choose the image according to the
11290 button state. */
11291 image = PROP (TOOL_BAR_ITEM_IMAGES);
11292 if (VECTORP (image))
11293 {
11294 if (enabled_p)
11295 idx = (selected_p
11296 ? TOOL_BAR_IMAGE_ENABLED_SELECTED
11297 : TOOL_BAR_IMAGE_ENABLED_DESELECTED);
11298 else
11299 idx = (selected_p
11300 ? TOOL_BAR_IMAGE_DISABLED_SELECTED
11301 : TOOL_BAR_IMAGE_DISABLED_DESELECTED);
11302
11303 xassert (ASIZE (image) >= idx);
11304 image = AREF (image, idx);
11305 }
11306 else
11307 idx = -1;
11308
11309 /* Ignore invalid image specifications. */
11310 if (!valid_image_p (image))
11311 continue;
11312
11313 /* Display the tool-bar button pressed, or depressed. */
11314 plist = Fcopy_sequence (XCDR (image));
11315
11316 /* Compute margin and relief to draw. */
11317 relief = (tool_bar_button_relief >= 0
11318 ? tool_bar_button_relief
11319 : DEFAULT_TOOL_BAR_BUTTON_RELIEF);
11320 hmargin = vmargin = relief;
11321
11322 if (INTEGERP (Vtool_bar_button_margin)
11323 && XINT (Vtool_bar_button_margin) > 0)
11324 {
11325 hmargin += XFASTINT (Vtool_bar_button_margin);
11326 vmargin += XFASTINT (Vtool_bar_button_margin);
11327 }
11328 else if (CONSP (Vtool_bar_button_margin))
11329 {
11330 if (INTEGERP (XCAR (Vtool_bar_button_margin))
11331 && XINT (XCAR (Vtool_bar_button_margin)) > 0)
11332 hmargin += XFASTINT (XCAR (Vtool_bar_button_margin));
11333
11334 if (INTEGERP (XCDR (Vtool_bar_button_margin))
11335 && XINT (XCDR (Vtool_bar_button_margin)) > 0)
11336 vmargin += XFASTINT (XCDR (Vtool_bar_button_margin));
11337 }
11338
11339 if (auto_raise_tool_bar_buttons_p)
11340 {
11341 /* Add a `:relief' property to the image spec if the item is
11342 selected. */
11343 if (selected_p)
11344 {
11345 plist = Fplist_put (plist, QCrelief, make_number (-relief));
11346 hmargin -= relief;
11347 vmargin -= relief;
11348 }
11349 }
11350 else
11351 {
11352 /* If image is selected, display it pressed, i.e. with a
11353 negative relief. If it's not selected, display it with a
11354 raised relief. */
11355 plist = Fplist_put (plist, QCrelief,
11356 (selected_p
11357 ? make_number (-relief)
11358 : make_number (relief)));
11359 hmargin -= relief;
11360 vmargin -= relief;
11361 }
11362
11363 /* Put a margin around the image. */
11364 if (hmargin || vmargin)
11365 {
11366 if (hmargin == vmargin)
11367 plist = Fplist_put (plist, QCmargin, make_number (hmargin));
11368 else
11369 plist = Fplist_put (plist, QCmargin,
11370 Fcons (make_number (hmargin),
11371 make_number (vmargin)));
11372 }
11373
11374 /* If button is not enabled, and we don't have special images
11375 for the disabled state, make the image appear disabled by
11376 applying an appropriate algorithm to it. */
11377 if (!enabled_p && idx < 0)
11378 plist = Fplist_put (plist, QCconversion, Qdisabled);
11379
11380 /* Put a `display' text property on the string for the image to
11381 display. Put a `menu-item' property on the string that gives
11382 the start of this item's properties in the tool-bar items
11383 vector. */
11384 image = Fcons (Qimage, plist);
11385 props = list4 (Qdisplay, image,
11386 Qmenu_item, make_number (i * TOOL_BAR_ITEM_NSLOTS));
11387
11388 /* Let the last image hide all remaining spaces in the tool bar
11389 string. The string can be longer than needed when we reuse a
11390 previous string. */
11391 if (i + 1 == f->n_tool_bar_items)
11392 end = SCHARS (f->desired_tool_bar_string);
11393 else
11394 end = i + 1;
11395 Fadd_text_properties (make_number (i), make_number (end),
11396 props, f->desired_tool_bar_string);
11397 #undef PROP
11398 }
11399
11400 UNGCPRO;
11401 }
11402
11403
11404 /* Display one line of the tool-bar of frame IT->f.
11405
11406 HEIGHT specifies the desired height of the tool-bar line.
11407 If the actual height of the glyph row is less than HEIGHT, the
11408 row's height is increased to HEIGHT, and the icons are centered
11409 vertically in the new height.
11410
11411 If HEIGHT is -1, we are counting needed tool-bar lines, so don't
11412 count a final empty row in case the tool-bar width exactly matches
11413 the window width.
11414 */
11415
11416 static void
11417 display_tool_bar_line (struct it *it, int height)
11418 {
11419 struct glyph_row *row = it->glyph_row;
11420 int max_x = it->last_visible_x;
11421 struct glyph *last;
11422
11423 prepare_desired_row (row);
11424 row->y = it->current_y;
11425
11426 /* Note that this isn't made use of if the face hasn't a box,
11427 so there's no need to check the face here. */
11428 it->start_of_box_run_p = 1;
11429
11430 while (it->current_x < max_x)
11431 {
11432 int x, n_glyphs_before, i, nglyphs;
11433 struct it it_before;
11434
11435 /* Get the next display element. */
11436 if (!get_next_display_element (it))
11437 {
11438 /* Don't count empty row if we are counting needed tool-bar lines. */
11439 if (height < 0 && !it->hpos)
11440 return;
11441 break;
11442 }
11443
11444 /* Produce glyphs. */
11445 n_glyphs_before = row->used[TEXT_AREA];
11446 it_before = *it;
11447
11448 PRODUCE_GLYPHS (it);
11449
11450 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
11451 i = 0;
11452 x = it_before.current_x;
11453 while (i < nglyphs)
11454 {
11455 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
11456
11457 if (x + glyph->pixel_width > max_x)
11458 {
11459 /* Glyph doesn't fit on line. Backtrack. */
11460 row->used[TEXT_AREA] = n_glyphs_before;
11461 *it = it_before;
11462 /* If this is the only glyph on this line, it will never fit on the
11463 tool-bar, so skip it. But ensure there is at least one glyph,
11464 so we don't accidentally disable the tool-bar. */
11465 if (n_glyphs_before == 0
11466 && (it->vpos > 0 || IT_STRING_CHARPOS (*it) < it->end_charpos-1))
11467 break;
11468 goto out;
11469 }
11470
11471 ++it->hpos;
11472 x += glyph->pixel_width;
11473 ++i;
11474 }
11475
11476 /* Stop at line end. */
11477 if (ITERATOR_AT_END_OF_LINE_P (it))
11478 break;
11479
11480 set_iterator_to_next (it, 1);
11481 }
11482
11483 out:;
11484
11485 row->displays_text_p = row->used[TEXT_AREA] != 0;
11486
11487 /* Use default face for the border below the tool bar.
11488
11489 FIXME: When auto-resize-tool-bars is grow-only, there is
11490 no additional border below the possibly empty tool-bar lines.
11491 So to make the extra empty lines look "normal", we have to
11492 use the tool-bar face for the border too. */
11493 if (!row->displays_text_p && !EQ (Vauto_resize_tool_bars, Qgrow_only))
11494 it->face_id = DEFAULT_FACE_ID;
11495
11496 extend_face_to_end_of_line (it);
11497 last = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
11498 last->right_box_line_p = 1;
11499 if (last == row->glyphs[TEXT_AREA])
11500 last->left_box_line_p = 1;
11501
11502 /* Make line the desired height and center it vertically. */
11503 if ((height -= it->max_ascent + it->max_descent) > 0)
11504 {
11505 /* Don't add more than one line height. */
11506 height %= FRAME_LINE_HEIGHT (it->f);
11507 it->max_ascent += height / 2;
11508 it->max_descent += (height + 1) / 2;
11509 }
11510
11511 compute_line_metrics (it);
11512
11513 /* If line is empty, make it occupy the rest of the tool-bar. */
11514 if (!row->displays_text_p)
11515 {
11516 row->height = row->phys_height = it->last_visible_y - row->y;
11517 row->visible_height = row->height;
11518 row->ascent = row->phys_ascent = 0;
11519 row->extra_line_spacing = 0;
11520 }
11521
11522 row->full_width_p = 1;
11523 row->continued_p = 0;
11524 row->truncated_on_left_p = 0;
11525 row->truncated_on_right_p = 0;
11526
11527 it->current_x = it->hpos = 0;
11528 it->current_y += row->height;
11529 ++it->vpos;
11530 ++it->glyph_row;
11531 }
11532
11533
11534 /* Max tool-bar height. */
11535
11536 #define MAX_FRAME_TOOL_BAR_HEIGHT(f) \
11537 ((FRAME_LINE_HEIGHT (f) * FRAME_LINES (f)))
11538
11539 /* Value is the number of screen lines needed to make all tool-bar
11540 items of frame F visible. The number of actual rows needed is
11541 returned in *N_ROWS if non-NULL. */
11542
11543 static int
11544 tool_bar_lines_needed (struct frame *f, int *n_rows)
11545 {
11546 struct window *w = XWINDOW (f->tool_bar_window);
11547 struct it it;
11548 /* tool_bar_lines_needed is called from redisplay_tool_bar after building
11549 the desired matrix, so use (unused) mode-line row as temporary row to
11550 avoid destroying the first tool-bar row. */
11551 struct glyph_row *temp_row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
11552
11553 /* Initialize an iterator for iteration over
11554 F->desired_tool_bar_string in the tool-bar window of frame F. */
11555 init_iterator (&it, w, -1, -1, temp_row, TOOL_BAR_FACE_ID);
11556 it.first_visible_x = 0;
11557 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
11558 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
11559 it.paragraph_embedding = L2R;
11560
11561 while (!ITERATOR_AT_END_P (&it))
11562 {
11563 clear_glyph_row (temp_row);
11564 it.glyph_row = temp_row;
11565 display_tool_bar_line (&it, -1);
11566 }
11567 clear_glyph_row (temp_row);
11568
11569 /* f->n_tool_bar_rows == 0 means "unknown"; -1 means no tool-bar. */
11570 if (n_rows)
11571 *n_rows = it.vpos > 0 ? it.vpos : -1;
11572
11573 return (it.current_y + FRAME_LINE_HEIGHT (f) - 1) / FRAME_LINE_HEIGHT (f);
11574 }
11575
11576
11577 DEFUN ("tool-bar-lines-needed", Ftool_bar_lines_needed, Stool_bar_lines_needed,
11578 0, 1, 0,
11579 doc: /* Return the number of lines occupied by the tool bar of FRAME. */)
11580 (Lisp_Object frame)
11581 {
11582 struct frame *f;
11583 struct window *w;
11584 int nlines = 0;
11585
11586 if (NILP (frame))
11587 frame = selected_frame;
11588 else
11589 CHECK_FRAME (frame);
11590 f = XFRAME (frame);
11591
11592 if (WINDOWP (f->tool_bar_window)
11593 && (w = XWINDOW (f->tool_bar_window),
11594 WINDOW_TOTAL_LINES (w) > 0))
11595 {
11596 update_tool_bar (f, 1);
11597 if (f->n_tool_bar_items)
11598 {
11599 build_desired_tool_bar_string (f);
11600 nlines = tool_bar_lines_needed (f, NULL);
11601 }
11602 }
11603
11604 return make_number (nlines);
11605 }
11606
11607
11608 /* Display the tool-bar of frame F. Value is non-zero if tool-bar's
11609 height should be changed. */
11610
11611 static int
11612 redisplay_tool_bar (struct frame *f)
11613 {
11614 struct window *w;
11615 struct it it;
11616 struct glyph_row *row;
11617
11618 #if defined (USE_GTK) || defined (HAVE_NS)
11619 if (FRAME_EXTERNAL_TOOL_BAR (f))
11620 update_frame_tool_bar (f);
11621 return 0;
11622 #endif
11623
11624 /* If frame hasn't a tool-bar window or if it is zero-height, don't
11625 do anything. This means you must start with tool-bar-lines
11626 non-zero to get the auto-sizing effect. Or in other words, you
11627 can turn off tool-bars by specifying tool-bar-lines zero. */
11628 if (!WINDOWP (f->tool_bar_window)
11629 || (w = XWINDOW (f->tool_bar_window),
11630 WINDOW_TOTAL_LINES (w) == 0))
11631 return 0;
11632
11633 /* Set up an iterator for the tool-bar window. */
11634 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
11635 it.first_visible_x = 0;
11636 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
11637 row = it.glyph_row;
11638
11639 /* Build a string that represents the contents of the tool-bar. */
11640 build_desired_tool_bar_string (f);
11641 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
11642 /* FIXME: This should be controlled by a user option. But it
11643 doesn't make sense to have an R2L tool bar if the menu bar cannot
11644 be drawn also R2L, and making the menu bar R2L is tricky due
11645 toolkit-specific code that implements it. If an R2L tool bar is
11646 ever supported, display_tool_bar_line should also be augmented to
11647 call unproduce_glyphs like display_line and display_string
11648 do. */
11649 it.paragraph_embedding = L2R;
11650
11651 if (f->n_tool_bar_rows == 0)
11652 {
11653 int nlines;
11654
11655 if ((nlines = tool_bar_lines_needed (f, &f->n_tool_bar_rows),
11656 nlines != WINDOW_TOTAL_LINES (w)))
11657 {
11658 Lisp_Object frame;
11659 int old_height = WINDOW_TOTAL_LINES (w);
11660
11661 XSETFRAME (frame, f);
11662 Fmodify_frame_parameters (frame,
11663 Fcons (Fcons (Qtool_bar_lines,
11664 make_number (nlines)),
11665 Qnil));
11666 if (WINDOW_TOTAL_LINES (w) != old_height)
11667 {
11668 clear_glyph_matrix (w->desired_matrix);
11669 fonts_changed_p = 1;
11670 return 1;
11671 }
11672 }
11673 }
11674
11675 /* Display as many lines as needed to display all tool-bar items. */
11676
11677 if (f->n_tool_bar_rows > 0)
11678 {
11679 int border, rows, height, extra;
11680
11681 if (INTEGERP (Vtool_bar_border))
11682 border = XINT (Vtool_bar_border);
11683 else if (EQ (Vtool_bar_border, Qinternal_border_width))
11684 border = FRAME_INTERNAL_BORDER_WIDTH (f);
11685 else if (EQ (Vtool_bar_border, Qborder_width))
11686 border = f->border_width;
11687 else
11688 border = 0;
11689 if (border < 0)
11690 border = 0;
11691
11692 rows = f->n_tool_bar_rows;
11693 height = max (1, (it.last_visible_y - border) / rows);
11694 extra = it.last_visible_y - border - height * rows;
11695
11696 while (it.current_y < it.last_visible_y)
11697 {
11698 int h = 0;
11699 if (extra > 0 && rows-- > 0)
11700 {
11701 h = (extra + rows - 1) / rows;
11702 extra -= h;
11703 }
11704 display_tool_bar_line (&it, height + h);
11705 }
11706 }
11707 else
11708 {
11709 while (it.current_y < it.last_visible_y)
11710 display_tool_bar_line (&it, 0);
11711 }
11712
11713 /* It doesn't make much sense to try scrolling in the tool-bar
11714 window, so don't do it. */
11715 w->desired_matrix->no_scrolling_p = 1;
11716 w->must_be_updated_p = 1;
11717
11718 if (!NILP (Vauto_resize_tool_bars))
11719 {
11720 int max_tool_bar_height = MAX_FRAME_TOOL_BAR_HEIGHT (f);
11721 int change_height_p = 0;
11722
11723 /* If we couldn't display everything, change the tool-bar's
11724 height if there is room for more. */
11725 if (IT_STRING_CHARPOS (it) < it.end_charpos
11726 && it.current_y < max_tool_bar_height)
11727 change_height_p = 1;
11728
11729 row = it.glyph_row - 1;
11730
11731 /* If there are blank lines at the end, except for a partially
11732 visible blank line at the end that is smaller than
11733 FRAME_LINE_HEIGHT, change the tool-bar's height. */
11734 if (!row->displays_text_p
11735 && row->height >= FRAME_LINE_HEIGHT (f))
11736 change_height_p = 1;
11737
11738 /* If row displays tool-bar items, but is partially visible,
11739 change the tool-bar's height. */
11740 if (row->displays_text_p
11741 && MATRIX_ROW_BOTTOM_Y (row) > it.last_visible_y
11742 && MATRIX_ROW_BOTTOM_Y (row) < max_tool_bar_height)
11743 change_height_p = 1;
11744
11745 /* Resize windows as needed by changing the `tool-bar-lines'
11746 frame parameter. */
11747 if (change_height_p)
11748 {
11749 Lisp_Object frame;
11750 int old_height = WINDOW_TOTAL_LINES (w);
11751 int nrows;
11752 int nlines = tool_bar_lines_needed (f, &nrows);
11753
11754 change_height_p = ((EQ (Vauto_resize_tool_bars, Qgrow_only)
11755 && !f->minimize_tool_bar_window_p)
11756 ? (nlines > old_height)
11757 : (nlines != old_height));
11758 f->minimize_tool_bar_window_p = 0;
11759
11760 if (change_height_p)
11761 {
11762 XSETFRAME (frame, f);
11763 Fmodify_frame_parameters (frame,
11764 Fcons (Fcons (Qtool_bar_lines,
11765 make_number (nlines)),
11766 Qnil));
11767 if (WINDOW_TOTAL_LINES (w) != old_height)
11768 {
11769 clear_glyph_matrix (w->desired_matrix);
11770 f->n_tool_bar_rows = nrows;
11771 fonts_changed_p = 1;
11772 return 1;
11773 }
11774 }
11775 }
11776 }
11777
11778 f->minimize_tool_bar_window_p = 0;
11779 return 0;
11780 }
11781
11782
11783 /* Get information about the tool-bar item which is displayed in GLYPH
11784 on frame F. Return in *PROP_IDX the index where tool-bar item
11785 properties start in F->tool_bar_items. Value is zero if
11786 GLYPH doesn't display a tool-bar item. */
11787
11788 static int
11789 tool_bar_item_info (struct frame *f, struct glyph *glyph, int *prop_idx)
11790 {
11791 Lisp_Object prop;
11792 int success_p;
11793 int charpos;
11794
11795 /* This function can be called asynchronously, which means we must
11796 exclude any possibility that Fget_text_property signals an
11797 error. */
11798 charpos = min (SCHARS (f->current_tool_bar_string), glyph->charpos);
11799 charpos = max (0, charpos);
11800
11801 /* Get the text property `menu-item' at pos. The value of that
11802 property is the start index of this item's properties in
11803 F->tool_bar_items. */
11804 prop = Fget_text_property (make_number (charpos),
11805 Qmenu_item, f->current_tool_bar_string);
11806 if (INTEGERP (prop))
11807 {
11808 *prop_idx = XINT (prop);
11809 success_p = 1;
11810 }
11811 else
11812 success_p = 0;
11813
11814 return success_p;
11815 }
11816
11817 \f
11818 /* Get information about the tool-bar item at position X/Y on frame F.
11819 Return in *GLYPH a pointer to the glyph of the tool-bar item in
11820 the current matrix of the tool-bar window of F, or NULL if not
11821 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
11822 item in F->tool_bar_items. Value is
11823
11824 -1 if X/Y is not on a tool-bar item
11825 0 if X/Y is on the same item that was highlighted before.
11826 1 otherwise. */
11827
11828 static int
11829 get_tool_bar_item (struct frame *f, int x, int y, struct glyph **glyph,
11830 int *hpos, int *vpos, int *prop_idx)
11831 {
11832 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
11833 struct window *w = XWINDOW (f->tool_bar_window);
11834 int area;
11835
11836 /* Find the glyph under X/Y. */
11837 *glyph = x_y_to_hpos_vpos (w, x, y, hpos, vpos, 0, 0, &area);
11838 if (*glyph == NULL)
11839 return -1;
11840
11841 /* Get the start of this tool-bar item's properties in
11842 f->tool_bar_items. */
11843 if (!tool_bar_item_info (f, *glyph, prop_idx))
11844 return -1;
11845
11846 /* Is mouse on the highlighted item? */
11847 if (EQ (f->tool_bar_window, hlinfo->mouse_face_window)
11848 && *vpos >= hlinfo->mouse_face_beg_row
11849 && *vpos <= hlinfo->mouse_face_end_row
11850 && (*vpos > hlinfo->mouse_face_beg_row
11851 || *hpos >= hlinfo->mouse_face_beg_col)
11852 && (*vpos < hlinfo->mouse_face_end_row
11853 || *hpos < hlinfo->mouse_face_end_col
11854 || hlinfo->mouse_face_past_end))
11855 return 0;
11856
11857 return 1;
11858 }
11859
11860
11861 /* EXPORT:
11862 Handle mouse button event on the tool-bar of frame F, at
11863 frame-relative coordinates X/Y. DOWN_P is 1 for a button press,
11864 0 for button release. MODIFIERS is event modifiers for button
11865 release. */
11866
11867 void
11868 handle_tool_bar_click (struct frame *f, int x, int y, int down_p,
11869 unsigned int modifiers)
11870 {
11871 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
11872 struct window *w = XWINDOW (f->tool_bar_window);
11873 int hpos, vpos, prop_idx;
11874 struct glyph *glyph;
11875 Lisp_Object enabled_p;
11876
11877 /* If not on the highlighted tool-bar item, return. */
11878 frame_to_window_pixel_xy (w, &x, &y);
11879 if (get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx) != 0)
11880 return;
11881
11882 /* If item is disabled, do nothing. */
11883 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
11884 if (NILP (enabled_p))
11885 return;
11886
11887 if (down_p)
11888 {
11889 /* Show item in pressed state. */
11890 show_mouse_face (hlinfo, DRAW_IMAGE_SUNKEN);
11891 hlinfo->mouse_face_image_state = DRAW_IMAGE_SUNKEN;
11892 last_tool_bar_item = prop_idx;
11893 }
11894 else
11895 {
11896 Lisp_Object key, frame;
11897 struct input_event event;
11898 EVENT_INIT (event);
11899
11900 /* Show item in released state. */
11901 show_mouse_face (hlinfo, DRAW_IMAGE_RAISED);
11902 hlinfo->mouse_face_image_state = DRAW_IMAGE_RAISED;
11903
11904 key = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_KEY);
11905
11906 XSETFRAME (frame, f);
11907 event.kind = TOOL_BAR_EVENT;
11908 event.frame_or_window = frame;
11909 event.arg = frame;
11910 kbd_buffer_store_event (&event);
11911
11912 event.kind = TOOL_BAR_EVENT;
11913 event.frame_or_window = frame;
11914 event.arg = key;
11915 event.modifiers = modifiers;
11916 kbd_buffer_store_event (&event);
11917 last_tool_bar_item = -1;
11918 }
11919 }
11920
11921
11922 /* Possibly highlight a tool-bar item on frame F when mouse moves to
11923 tool-bar window-relative coordinates X/Y. Called from
11924 note_mouse_highlight. */
11925
11926 static void
11927 note_tool_bar_highlight (struct frame *f, int x, int y)
11928 {
11929 Lisp_Object window = f->tool_bar_window;
11930 struct window *w = XWINDOW (window);
11931 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
11932 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
11933 int hpos, vpos;
11934 struct glyph *glyph;
11935 struct glyph_row *row;
11936 int i;
11937 Lisp_Object enabled_p;
11938 int prop_idx;
11939 enum draw_glyphs_face draw = DRAW_IMAGE_RAISED;
11940 int mouse_down_p, rc;
11941
11942 /* Function note_mouse_highlight is called with negative X/Y
11943 values when mouse moves outside of the frame. */
11944 if (x <= 0 || y <= 0)
11945 {
11946 clear_mouse_face (hlinfo);
11947 return;
11948 }
11949
11950 rc = get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx);
11951 if (rc < 0)
11952 {
11953 /* Not on tool-bar item. */
11954 clear_mouse_face (hlinfo);
11955 return;
11956 }
11957 else if (rc == 0)
11958 /* On same tool-bar item as before. */
11959 goto set_help_echo;
11960
11961 clear_mouse_face (hlinfo);
11962
11963 /* Mouse is down, but on different tool-bar item? */
11964 mouse_down_p = (dpyinfo->grabbed
11965 && f == last_mouse_frame
11966 && FRAME_LIVE_P (f));
11967 if (mouse_down_p
11968 && last_tool_bar_item != prop_idx)
11969 return;
11970
11971 hlinfo->mouse_face_image_state = DRAW_NORMAL_TEXT;
11972 draw = mouse_down_p ? DRAW_IMAGE_SUNKEN : DRAW_IMAGE_RAISED;
11973
11974 /* If tool-bar item is not enabled, don't highlight it. */
11975 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
11976 if (!NILP (enabled_p))
11977 {
11978 /* Compute the x-position of the glyph. In front and past the
11979 image is a space. We include this in the highlighted area. */
11980 row = MATRIX_ROW (w->current_matrix, vpos);
11981 for (i = x = 0; i < hpos; ++i)
11982 x += row->glyphs[TEXT_AREA][i].pixel_width;
11983
11984 /* Record this as the current active region. */
11985 hlinfo->mouse_face_beg_col = hpos;
11986 hlinfo->mouse_face_beg_row = vpos;
11987 hlinfo->mouse_face_beg_x = x;
11988 hlinfo->mouse_face_beg_y = row->y;
11989 hlinfo->mouse_face_past_end = 0;
11990
11991 hlinfo->mouse_face_end_col = hpos + 1;
11992 hlinfo->mouse_face_end_row = vpos;
11993 hlinfo->mouse_face_end_x = x + glyph->pixel_width;
11994 hlinfo->mouse_face_end_y = row->y;
11995 hlinfo->mouse_face_window = window;
11996 hlinfo->mouse_face_face_id = TOOL_BAR_FACE_ID;
11997
11998 /* Display it as active. */
11999 show_mouse_face (hlinfo, draw);
12000 hlinfo->mouse_face_image_state = draw;
12001 }
12002
12003 set_help_echo:
12004
12005 /* Set help_echo_string to a help string to display for this tool-bar item.
12006 XTread_socket does the rest. */
12007 help_echo_object = help_echo_window = Qnil;
12008 help_echo_pos = -1;
12009 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_HELP);
12010 if (NILP (help_echo_string))
12011 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_CAPTION);
12012 }
12013
12014 #endif /* HAVE_WINDOW_SYSTEM */
12015
12016
12017 \f
12018 /************************************************************************
12019 Horizontal scrolling
12020 ************************************************************************/
12021
12022 static int hscroll_window_tree (Lisp_Object);
12023 static int hscroll_windows (Lisp_Object);
12024
12025 /* For all leaf windows in the window tree rooted at WINDOW, set their
12026 hscroll value so that PT is (i) visible in the window, and (ii) so
12027 that it is not within a certain margin at the window's left and
12028 right border. Value is non-zero if any window's hscroll has been
12029 changed. */
12030
12031 static int
12032 hscroll_window_tree (Lisp_Object window)
12033 {
12034 int hscrolled_p = 0;
12035 int hscroll_relative_p = FLOATP (Vhscroll_step);
12036 int hscroll_step_abs = 0;
12037 double hscroll_step_rel = 0;
12038
12039 if (hscroll_relative_p)
12040 {
12041 hscroll_step_rel = XFLOAT_DATA (Vhscroll_step);
12042 if (hscroll_step_rel < 0)
12043 {
12044 hscroll_relative_p = 0;
12045 hscroll_step_abs = 0;
12046 }
12047 }
12048 else if (INTEGERP (Vhscroll_step))
12049 {
12050 hscroll_step_abs = XINT (Vhscroll_step);
12051 if (hscroll_step_abs < 0)
12052 hscroll_step_abs = 0;
12053 }
12054 else
12055 hscroll_step_abs = 0;
12056
12057 while (WINDOWP (window))
12058 {
12059 struct window *w = XWINDOW (window);
12060
12061 if (WINDOWP (w->hchild))
12062 hscrolled_p |= hscroll_window_tree (w->hchild);
12063 else if (WINDOWP (w->vchild))
12064 hscrolled_p |= hscroll_window_tree (w->vchild);
12065 else if (w->cursor.vpos >= 0)
12066 {
12067 int h_margin;
12068 int text_area_width;
12069 struct glyph_row *current_cursor_row
12070 = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
12071 struct glyph_row *desired_cursor_row
12072 = MATRIX_ROW (w->desired_matrix, w->cursor.vpos);
12073 struct glyph_row *cursor_row
12074 = (desired_cursor_row->enabled_p
12075 ? desired_cursor_row
12076 : current_cursor_row);
12077 int row_r2l_p = cursor_row->reversed_p;
12078
12079 text_area_width = window_box_width (w, TEXT_AREA);
12080
12081 /* Scroll when cursor is inside this scroll margin. */
12082 h_margin = hscroll_margin * WINDOW_FRAME_COLUMN_WIDTH (w);
12083
12084 if (!NILP (Fbuffer_local_value (Qauto_hscroll_mode, w->buffer))
12085 /* For left-to-right rows, hscroll when cursor is either
12086 (i) inside the right hscroll margin, or (ii) if it is
12087 inside the left margin and the window is already
12088 hscrolled. */
12089 && ((!row_r2l_p
12090 && ((XFASTINT (w->hscroll)
12091 && w->cursor.x <= h_margin)
12092 || (cursor_row->enabled_p
12093 && cursor_row->truncated_on_right_p
12094 && (w->cursor.x >= text_area_width - h_margin))))
12095 /* For right-to-left rows, the logic is similar,
12096 except that rules for scrolling to left and right
12097 are reversed. E.g., if cursor.x <= h_margin, we
12098 need to hscroll "to the right" unconditionally,
12099 and that will scroll the screen to the left so as
12100 to reveal the next portion of the row. */
12101 || (row_r2l_p
12102 && ((cursor_row->enabled_p
12103 /* FIXME: It is confusing to set the
12104 truncated_on_right_p flag when R2L rows
12105 are actually truncated on the left. */
12106 && cursor_row->truncated_on_right_p
12107 && w->cursor.x <= h_margin)
12108 || (XFASTINT (w->hscroll)
12109 && (w->cursor.x >= text_area_width - h_margin))))))
12110 {
12111 struct it it;
12112 int hscroll;
12113 struct buffer *saved_current_buffer;
12114 EMACS_INT pt;
12115 int wanted_x;
12116
12117 /* Find point in a display of infinite width. */
12118 saved_current_buffer = current_buffer;
12119 current_buffer = XBUFFER (w->buffer);
12120
12121 if (w == XWINDOW (selected_window))
12122 pt = PT;
12123 else
12124 {
12125 pt = marker_position (w->pointm);
12126 pt = max (BEGV, pt);
12127 pt = min (ZV, pt);
12128 }
12129
12130 /* Move iterator to pt starting at cursor_row->start in
12131 a line with infinite width. */
12132 init_to_row_start (&it, w, cursor_row);
12133 it.last_visible_x = INFINITY;
12134 move_it_in_display_line_to (&it, pt, -1, MOVE_TO_POS);
12135 current_buffer = saved_current_buffer;
12136
12137 /* Position cursor in window. */
12138 if (!hscroll_relative_p && hscroll_step_abs == 0)
12139 hscroll = max (0, (it.current_x
12140 - (ITERATOR_AT_END_OF_LINE_P (&it)
12141 ? (text_area_width - 4 * FRAME_COLUMN_WIDTH (it.f))
12142 : (text_area_width / 2))))
12143 / FRAME_COLUMN_WIDTH (it.f);
12144 else if ((!row_r2l_p
12145 && w->cursor.x >= text_area_width - h_margin)
12146 || (row_r2l_p && w->cursor.x <= h_margin))
12147 {
12148 if (hscroll_relative_p)
12149 wanted_x = text_area_width * (1 - hscroll_step_rel)
12150 - h_margin;
12151 else
12152 wanted_x = text_area_width
12153 - hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
12154 - h_margin;
12155 hscroll
12156 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
12157 }
12158 else
12159 {
12160 if (hscroll_relative_p)
12161 wanted_x = text_area_width * hscroll_step_rel
12162 + h_margin;
12163 else
12164 wanted_x = hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
12165 + h_margin;
12166 hscroll
12167 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
12168 }
12169 hscroll = max (hscroll, XFASTINT (w->min_hscroll));
12170
12171 /* Don't prevent redisplay optimizations if hscroll
12172 hasn't changed, as it will unnecessarily slow down
12173 redisplay. */
12174 if (XFASTINT (w->hscroll) != hscroll)
12175 {
12176 XBUFFER (w->buffer)->prevent_redisplay_optimizations_p = 1;
12177 w->hscroll = make_number (hscroll);
12178 hscrolled_p = 1;
12179 }
12180 }
12181 }
12182
12183 window = w->next;
12184 }
12185
12186 /* Value is non-zero if hscroll of any leaf window has been changed. */
12187 return hscrolled_p;
12188 }
12189
12190
12191 /* Set hscroll so that cursor is visible and not inside horizontal
12192 scroll margins for all windows in the tree rooted at WINDOW. See
12193 also hscroll_window_tree above. Value is non-zero if any window's
12194 hscroll has been changed. If it has, desired matrices on the frame
12195 of WINDOW are cleared. */
12196
12197 static int
12198 hscroll_windows (Lisp_Object window)
12199 {
12200 int hscrolled_p = hscroll_window_tree (window);
12201 if (hscrolled_p)
12202 clear_desired_matrices (XFRAME (WINDOW_FRAME (XWINDOW (window))));
12203 return hscrolled_p;
12204 }
12205
12206
12207 \f
12208 /************************************************************************
12209 Redisplay
12210 ************************************************************************/
12211
12212 /* Variables holding some state of redisplay if GLYPH_DEBUG is defined
12213 to a non-zero value. This is sometimes handy to have in a debugger
12214 session. */
12215
12216 #if GLYPH_DEBUG
12217
12218 /* First and last unchanged row for try_window_id. */
12219
12220 static int debug_first_unchanged_at_end_vpos;
12221 static int debug_last_unchanged_at_beg_vpos;
12222
12223 /* Delta vpos and y. */
12224
12225 static int debug_dvpos, debug_dy;
12226
12227 /* Delta in characters and bytes for try_window_id. */
12228
12229 static EMACS_INT debug_delta, debug_delta_bytes;
12230
12231 /* Values of window_end_pos and window_end_vpos at the end of
12232 try_window_id. */
12233
12234 static EMACS_INT debug_end_vpos;
12235
12236 /* Append a string to W->desired_matrix->method. FMT is a printf
12237 format string. If trace_redisplay_p is non-zero also printf the
12238 resulting string to stderr. */
12239
12240 static void debug_method_add (struct window *, char const *, ...)
12241 ATTRIBUTE_FORMAT_PRINTF (2, 3);
12242
12243 static void
12244 debug_method_add (struct window *w, char const *fmt, ...)
12245 {
12246 char buffer[512];
12247 char *method = w->desired_matrix->method;
12248 int len = strlen (method);
12249 int size = sizeof w->desired_matrix->method;
12250 int remaining = size - len - 1;
12251 va_list ap;
12252
12253 va_start (ap, fmt);
12254 vsprintf (buffer, fmt, ap);
12255 va_end (ap);
12256 if (len && remaining)
12257 {
12258 method[len] = '|';
12259 --remaining, ++len;
12260 }
12261
12262 strncpy (method + len, buffer, remaining);
12263
12264 if (trace_redisplay_p)
12265 fprintf (stderr, "%p (%s): %s\n",
12266 w,
12267 ((BUFFERP (w->buffer)
12268 && STRINGP (BVAR (XBUFFER (w->buffer), name)))
12269 ? SSDATA (BVAR (XBUFFER (w->buffer), name))
12270 : "no buffer"),
12271 buffer);
12272 }
12273
12274 #endif /* GLYPH_DEBUG */
12275
12276
12277 /* Value is non-zero if all changes in window W, which displays
12278 current_buffer, are in the text between START and END. START is a
12279 buffer position, END is given as a distance from Z. Used in
12280 redisplay_internal for display optimization. */
12281
12282 static inline int
12283 text_outside_line_unchanged_p (struct window *w,
12284 EMACS_INT start, EMACS_INT end)
12285 {
12286 int unchanged_p = 1;
12287
12288 /* If text or overlays have changed, see where. */
12289 if (XFASTINT (w->last_modified) < MODIFF
12290 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
12291 {
12292 /* Gap in the line? */
12293 if (GPT < start || Z - GPT < end)
12294 unchanged_p = 0;
12295
12296 /* Changes start in front of the line, or end after it? */
12297 if (unchanged_p
12298 && (BEG_UNCHANGED < start - 1
12299 || END_UNCHANGED < end))
12300 unchanged_p = 0;
12301
12302 /* If selective display, can't optimize if changes start at the
12303 beginning of the line. */
12304 if (unchanged_p
12305 && INTEGERP (BVAR (current_buffer, selective_display))
12306 && XINT (BVAR (current_buffer, selective_display)) > 0
12307 && (BEG_UNCHANGED < start || GPT <= start))
12308 unchanged_p = 0;
12309
12310 /* If there are overlays at the start or end of the line, these
12311 may have overlay strings with newlines in them. A change at
12312 START, for instance, may actually concern the display of such
12313 overlay strings as well, and they are displayed on different
12314 lines. So, quickly rule out this case. (For the future, it
12315 might be desirable to implement something more telling than
12316 just BEG/END_UNCHANGED.) */
12317 if (unchanged_p)
12318 {
12319 if (BEG + BEG_UNCHANGED == start
12320 && overlay_touches_p (start))
12321 unchanged_p = 0;
12322 if (END_UNCHANGED == end
12323 && overlay_touches_p (Z - end))
12324 unchanged_p = 0;
12325 }
12326
12327 /* Under bidi reordering, adding or deleting a character in the
12328 beginning of a paragraph, before the first strong directional
12329 character, can change the base direction of the paragraph (unless
12330 the buffer specifies a fixed paragraph direction), which will
12331 require to redisplay the whole paragraph. It might be worthwhile
12332 to find the paragraph limits and widen the range of redisplayed
12333 lines to that, but for now just give up this optimization. */
12334 if (!NILP (BVAR (XBUFFER (w->buffer), bidi_display_reordering))
12335 && NILP (BVAR (XBUFFER (w->buffer), bidi_paragraph_direction)))
12336 unchanged_p = 0;
12337 }
12338
12339 return unchanged_p;
12340 }
12341
12342
12343 /* Do a frame update, taking possible shortcuts into account. This is
12344 the main external entry point for redisplay.
12345
12346 If the last redisplay displayed an echo area message and that message
12347 is no longer requested, we clear the echo area or bring back the
12348 mini-buffer if that is in use. */
12349
12350 void
12351 redisplay (void)
12352 {
12353 redisplay_internal ();
12354 }
12355
12356
12357 static Lisp_Object
12358 overlay_arrow_string_or_property (Lisp_Object var)
12359 {
12360 Lisp_Object val;
12361
12362 if (val = Fget (var, Qoverlay_arrow_string), STRINGP (val))
12363 return val;
12364
12365 return Voverlay_arrow_string;
12366 }
12367
12368 /* Return 1 if there are any overlay-arrows in current_buffer. */
12369 static int
12370 overlay_arrow_in_current_buffer_p (void)
12371 {
12372 Lisp_Object vlist;
12373
12374 for (vlist = Voverlay_arrow_variable_list;
12375 CONSP (vlist);
12376 vlist = XCDR (vlist))
12377 {
12378 Lisp_Object var = XCAR (vlist);
12379 Lisp_Object val;
12380
12381 if (!SYMBOLP (var))
12382 continue;
12383 val = find_symbol_value (var);
12384 if (MARKERP (val)
12385 && current_buffer == XMARKER (val)->buffer)
12386 return 1;
12387 }
12388 return 0;
12389 }
12390
12391
12392 /* Return 1 if any overlay_arrows have moved or overlay-arrow-string
12393 has changed. */
12394
12395 static int
12396 overlay_arrows_changed_p (void)
12397 {
12398 Lisp_Object vlist;
12399
12400 for (vlist = Voverlay_arrow_variable_list;
12401 CONSP (vlist);
12402 vlist = XCDR (vlist))
12403 {
12404 Lisp_Object var = XCAR (vlist);
12405 Lisp_Object val, pstr;
12406
12407 if (!SYMBOLP (var))
12408 continue;
12409 val = find_symbol_value (var);
12410 if (!MARKERP (val))
12411 continue;
12412 if (! EQ (COERCE_MARKER (val),
12413 Fget (var, Qlast_arrow_position))
12414 || ! (pstr = overlay_arrow_string_or_property (var),
12415 EQ (pstr, Fget (var, Qlast_arrow_string))))
12416 return 1;
12417 }
12418 return 0;
12419 }
12420
12421 /* Mark overlay arrows to be updated on next redisplay. */
12422
12423 static void
12424 update_overlay_arrows (int up_to_date)
12425 {
12426 Lisp_Object vlist;
12427
12428 for (vlist = Voverlay_arrow_variable_list;
12429 CONSP (vlist);
12430 vlist = XCDR (vlist))
12431 {
12432 Lisp_Object var = XCAR (vlist);
12433
12434 if (!SYMBOLP (var))
12435 continue;
12436
12437 if (up_to_date > 0)
12438 {
12439 Lisp_Object val = find_symbol_value (var);
12440 Fput (var, Qlast_arrow_position,
12441 COERCE_MARKER (val));
12442 Fput (var, Qlast_arrow_string,
12443 overlay_arrow_string_or_property (var));
12444 }
12445 else if (up_to_date < 0
12446 || !NILP (Fget (var, Qlast_arrow_position)))
12447 {
12448 Fput (var, Qlast_arrow_position, Qt);
12449 Fput (var, Qlast_arrow_string, Qt);
12450 }
12451 }
12452 }
12453
12454
12455 /* Return overlay arrow string to display at row.
12456 Return integer (bitmap number) for arrow bitmap in left fringe.
12457 Return nil if no overlay arrow. */
12458
12459 static Lisp_Object
12460 overlay_arrow_at_row (struct it *it, struct glyph_row *row)
12461 {
12462 Lisp_Object vlist;
12463
12464 for (vlist = Voverlay_arrow_variable_list;
12465 CONSP (vlist);
12466 vlist = XCDR (vlist))
12467 {
12468 Lisp_Object var = XCAR (vlist);
12469 Lisp_Object val;
12470
12471 if (!SYMBOLP (var))
12472 continue;
12473
12474 val = find_symbol_value (var);
12475
12476 if (MARKERP (val)
12477 && current_buffer == XMARKER (val)->buffer
12478 && (MATRIX_ROW_START_CHARPOS (row) == marker_position (val)))
12479 {
12480 if (FRAME_WINDOW_P (it->f)
12481 /* FIXME: if ROW->reversed_p is set, this should test
12482 the right fringe, not the left one. */
12483 && WINDOW_LEFT_FRINGE_WIDTH (it->w) > 0)
12484 {
12485 #ifdef HAVE_WINDOW_SYSTEM
12486 if (val = Fget (var, Qoverlay_arrow_bitmap), SYMBOLP (val))
12487 {
12488 int fringe_bitmap;
12489 if ((fringe_bitmap = lookup_fringe_bitmap (val)) != 0)
12490 return make_number (fringe_bitmap);
12491 }
12492 #endif
12493 return make_number (-1); /* Use default arrow bitmap */
12494 }
12495 return overlay_arrow_string_or_property (var);
12496 }
12497 }
12498
12499 return Qnil;
12500 }
12501
12502 /* Return 1 if point moved out of or into a composition. Otherwise
12503 return 0. PREV_BUF and PREV_PT are the last point buffer and
12504 position. BUF and PT are the current point buffer and position. */
12505
12506 static int
12507 check_point_in_composition (struct buffer *prev_buf, EMACS_INT prev_pt,
12508 struct buffer *buf, EMACS_INT pt)
12509 {
12510 EMACS_INT start, end;
12511 Lisp_Object prop;
12512 Lisp_Object buffer;
12513
12514 XSETBUFFER (buffer, buf);
12515 /* Check a composition at the last point if point moved within the
12516 same buffer. */
12517 if (prev_buf == buf)
12518 {
12519 if (prev_pt == pt)
12520 /* Point didn't move. */
12521 return 0;
12522
12523 if (prev_pt > BUF_BEGV (buf) && prev_pt < BUF_ZV (buf)
12524 && find_composition (prev_pt, -1, &start, &end, &prop, buffer)
12525 && COMPOSITION_VALID_P (start, end, prop)
12526 && start < prev_pt && end > prev_pt)
12527 /* The last point was within the composition. Return 1 iff
12528 point moved out of the composition. */
12529 return (pt <= start || pt >= end);
12530 }
12531
12532 /* Check a composition at the current point. */
12533 return (pt > BUF_BEGV (buf) && pt < BUF_ZV (buf)
12534 && find_composition (pt, -1, &start, &end, &prop, buffer)
12535 && COMPOSITION_VALID_P (start, end, prop)
12536 && start < pt && end > pt);
12537 }
12538
12539
12540 /* Reconsider the setting of B->clip_changed which is displayed
12541 in window W. */
12542
12543 static inline void
12544 reconsider_clip_changes (struct window *w, struct buffer *b)
12545 {
12546 if (b->clip_changed
12547 && !NILP (w->window_end_valid)
12548 && w->current_matrix->buffer == b
12549 && w->current_matrix->zv == BUF_ZV (b)
12550 && w->current_matrix->begv == BUF_BEGV (b))
12551 b->clip_changed = 0;
12552
12553 /* If display wasn't paused, and W is not a tool bar window, see if
12554 point has been moved into or out of a composition. In that case,
12555 we set b->clip_changed to 1 to force updating the screen. If
12556 b->clip_changed has already been set to 1, we can skip this
12557 check. */
12558 if (!b->clip_changed
12559 && BUFFERP (w->buffer) && !NILP (w->window_end_valid))
12560 {
12561 EMACS_INT pt;
12562
12563 if (w == XWINDOW (selected_window))
12564 pt = PT;
12565 else
12566 pt = marker_position (w->pointm);
12567
12568 if ((w->current_matrix->buffer != XBUFFER (w->buffer)
12569 || pt != XINT (w->last_point))
12570 && check_point_in_composition (w->current_matrix->buffer,
12571 XINT (w->last_point),
12572 XBUFFER (w->buffer), pt))
12573 b->clip_changed = 1;
12574 }
12575 }
12576 \f
12577
12578 /* Select FRAME to forward the values of frame-local variables into C
12579 variables so that the redisplay routines can access those values
12580 directly. */
12581
12582 static void
12583 select_frame_for_redisplay (Lisp_Object frame)
12584 {
12585 Lisp_Object tail, tem;
12586 Lisp_Object old = selected_frame;
12587 struct Lisp_Symbol *sym;
12588
12589 xassert (FRAMEP (frame) && FRAME_LIVE_P (XFRAME (frame)));
12590
12591 selected_frame = frame;
12592
12593 do {
12594 for (tail = XFRAME (frame)->param_alist; CONSP (tail); tail = XCDR (tail))
12595 if (CONSP (XCAR (tail))
12596 && (tem = XCAR (XCAR (tail)),
12597 SYMBOLP (tem))
12598 && (sym = indirect_variable (XSYMBOL (tem)),
12599 sym->redirect == SYMBOL_LOCALIZED)
12600 && sym->val.blv->frame_local)
12601 /* Use find_symbol_value rather than Fsymbol_value
12602 to avoid an error if it is void. */
12603 find_symbol_value (tem);
12604 } while (!EQ (frame, old) && (frame = old, 1));
12605 }
12606
12607
12608 #define STOP_POLLING \
12609 do { if (! polling_stopped_here) stop_polling (); \
12610 polling_stopped_here = 1; } while (0)
12611
12612 #define RESUME_POLLING \
12613 do { if (polling_stopped_here) start_polling (); \
12614 polling_stopped_here = 0; } while (0)
12615
12616
12617 /* Perhaps in the future avoid recentering windows if it
12618 is not necessary; currently that causes some problems. */
12619
12620 static void
12621 redisplay_internal (void)
12622 {
12623 struct window *w = XWINDOW (selected_window);
12624 struct window *sw;
12625 struct frame *fr;
12626 int pending;
12627 int must_finish = 0;
12628 struct text_pos tlbufpos, tlendpos;
12629 int number_of_visible_frames;
12630 int count, count1;
12631 struct frame *sf;
12632 int polling_stopped_here = 0;
12633 Lisp_Object old_frame = selected_frame;
12634
12635 /* Non-zero means redisplay has to consider all windows on all
12636 frames. Zero means, only selected_window is considered. */
12637 int consider_all_windows_p;
12638
12639 TRACE ((stderr, "redisplay_internal %d\n", redisplaying_p));
12640
12641 /* No redisplay if running in batch mode or frame is not yet fully
12642 initialized, or redisplay is explicitly turned off by setting
12643 Vinhibit_redisplay. */
12644 if (FRAME_INITIAL_P (SELECTED_FRAME ())
12645 || !NILP (Vinhibit_redisplay))
12646 return;
12647
12648 /* Don't examine these until after testing Vinhibit_redisplay.
12649 When Emacs is shutting down, perhaps because its connection to
12650 X has dropped, we should not look at them at all. */
12651 fr = XFRAME (w->frame);
12652 sf = SELECTED_FRAME ();
12653
12654 if (!fr->glyphs_initialized_p)
12655 return;
12656
12657 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS)
12658 if (popup_activated ())
12659 return;
12660 #endif
12661
12662 /* I don't think this happens but let's be paranoid. */
12663 if (redisplaying_p)
12664 return;
12665
12666 /* Record a function that resets redisplaying_p to its old value
12667 when we leave this function. */
12668 count = SPECPDL_INDEX ();
12669 record_unwind_protect (unwind_redisplay,
12670 Fcons (make_number (redisplaying_p), selected_frame));
12671 ++redisplaying_p;
12672 specbind (Qinhibit_free_realized_faces, Qnil);
12673
12674 {
12675 Lisp_Object tail, frame;
12676
12677 FOR_EACH_FRAME (tail, frame)
12678 {
12679 struct frame *f = XFRAME (frame);
12680 f->already_hscrolled_p = 0;
12681 }
12682 }
12683
12684 retry:
12685 /* Remember the currently selected window. */
12686 sw = w;
12687
12688 if (!EQ (old_frame, selected_frame)
12689 && FRAME_LIVE_P (XFRAME (old_frame)))
12690 /* When running redisplay, we play a bit fast-and-loose and allow e.g.
12691 selected_frame and selected_window to be temporarily out-of-sync so
12692 when we come back here via `goto retry', we need to resync because we
12693 may need to run Elisp code (via prepare_menu_bars). */
12694 select_frame_for_redisplay (old_frame);
12695
12696 pending = 0;
12697 reconsider_clip_changes (w, current_buffer);
12698 last_escape_glyph_frame = NULL;
12699 last_escape_glyph_face_id = (1 << FACE_ID_BITS);
12700 last_glyphless_glyph_frame = NULL;
12701 last_glyphless_glyph_face_id = (1 << FACE_ID_BITS);
12702
12703 /* If new fonts have been loaded that make a glyph matrix adjustment
12704 necessary, do it. */
12705 if (fonts_changed_p)
12706 {
12707 adjust_glyphs (NULL);
12708 ++windows_or_buffers_changed;
12709 fonts_changed_p = 0;
12710 }
12711
12712 /* If face_change_count is non-zero, init_iterator will free all
12713 realized faces, which includes the faces referenced from current
12714 matrices. So, we can't reuse current matrices in this case. */
12715 if (face_change_count)
12716 ++windows_or_buffers_changed;
12717
12718 if ((FRAME_TERMCAP_P (sf) || FRAME_MSDOS_P (sf))
12719 && FRAME_TTY (sf)->previous_frame != sf)
12720 {
12721 /* Since frames on a single ASCII terminal share the same
12722 display area, displaying a different frame means redisplay
12723 the whole thing. */
12724 windows_or_buffers_changed++;
12725 SET_FRAME_GARBAGED (sf);
12726 #ifndef DOS_NT
12727 set_tty_color_mode (FRAME_TTY (sf), sf);
12728 #endif
12729 FRAME_TTY (sf)->previous_frame = sf;
12730 }
12731
12732 /* Set the visible flags for all frames. Do this before checking
12733 for resized or garbaged frames; they want to know if their frames
12734 are visible. See the comment in frame.h for
12735 FRAME_SAMPLE_VISIBILITY. */
12736 {
12737 Lisp_Object tail, frame;
12738
12739 number_of_visible_frames = 0;
12740
12741 FOR_EACH_FRAME (tail, frame)
12742 {
12743 struct frame *f = XFRAME (frame);
12744
12745 FRAME_SAMPLE_VISIBILITY (f);
12746 if (FRAME_VISIBLE_P (f))
12747 ++number_of_visible_frames;
12748 clear_desired_matrices (f);
12749 }
12750 }
12751
12752 /* Notice any pending interrupt request to change frame size. */
12753 do_pending_window_change (1);
12754
12755 /* do_pending_window_change could change the selected_window due to
12756 frame resizing which makes the selected window too small. */
12757 if (WINDOWP (selected_window) && (w = XWINDOW (selected_window)) != sw)
12758 {
12759 sw = w;
12760 reconsider_clip_changes (w, current_buffer);
12761 }
12762
12763 /* Clear frames marked as garbaged. */
12764 if (frame_garbaged)
12765 clear_garbaged_frames ();
12766
12767 /* Build menubar and tool-bar items. */
12768 if (NILP (Vmemory_full))
12769 prepare_menu_bars ();
12770
12771 if (windows_or_buffers_changed)
12772 update_mode_lines++;
12773
12774 /* Detect case that we need to write or remove a star in the mode line. */
12775 if ((SAVE_MODIFF < MODIFF) != !NILP (w->last_had_star))
12776 {
12777 w->update_mode_line = Qt;
12778 if (buffer_shared > 1)
12779 update_mode_lines++;
12780 }
12781
12782 /* Avoid invocation of point motion hooks by `current_column' below. */
12783 count1 = SPECPDL_INDEX ();
12784 specbind (Qinhibit_point_motion_hooks, Qt);
12785
12786 /* If %c is in the mode line, update it if needed. */
12787 if (!NILP (w->column_number_displayed)
12788 /* This alternative quickly identifies a common case
12789 where no change is needed. */
12790 && !(PT == XFASTINT (w->last_point)
12791 && XFASTINT (w->last_modified) >= MODIFF
12792 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
12793 && (XFASTINT (w->column_number_displayed) != current_column ()))
12794 w->update_mode_line = Qt;
12795
12796 unbind_to (count1, Qnil);
12797
12798 FRAME_SCROLL_BOTTOM_VPOS (XFRAME (w->frame)) = -1;
12799
12800 /* The variable buffer_shared is set in redisplay_window and
12801 indicates that we redisplay a buffer in different windows. See
12802 there. */
12803 consider_all_windows_p = (update_mode_lines || buffer_shared > 1
12804 || cursor_type_changed);
12805
12806 /* If specs for an arrow have changed, do thorough redisplay
12807 to ensure we remove any arrow that should no longer exist. */
12808 if (overlay_arrows_changed_p ())
12809 consider_all_windows_p = windows_or_buffers_changed = 1;
12810
12811 /* Normally the message* functions will have already displayed and
12812 updated the echo area, but the frame may have been trashed, or
12813 the update may have been preempted, so display the echo area
12814 again here. Checking message_cleared_p captures the case that
12815 the echo area should be cleared. */
12816 if ((!NILP (echo_area_buffer[0]) && !display_last_displayed_message_p)
12817 || (!NILP (echo_area_buffer[1]) && display_last_displayed_message_p)
12818 || (message_cleared_p
12819 && minibuf_level == 0
12820 /* If the mini-window is currently selected, this means the
12821 echo-area doesn't show through. */
12822 && !MINI_WINDOW_P (XWINDOW (selected_window))))
12823 {
12824 int window_height_changed_p = echo_area_display (0);
12825 must_finish = 1;
12826
12827 /* If we don't display the current message, don't clear the
12828 message_cleared_p flag, because, if we did, we wouldn't clear
12829 the echo area in the next redisplay which doesn't preserve
12830 the echo area. */
12831 if (!display_last_displayed_message_p)
12832 message_cleared_p = 0;
12833
12834 if (fonts_changed_p)
12835 goto retry;
12836 else if (window_height_changed_p)
12837 {
12838 consider_all_windows_p = 1;
12839 ++update_mode_lines;
12840 ++windows_or_buffers_changed;
12841
12842 /* If window configuration was changed, frames may have been
12843 marked garbaged. Clear them or we will experience
12844 surprises wrt scrolling. */
12845 if (frame_garbaged)
12846 clear_garbaged_frames ();
12847 }
12848 }
12849 else if (EQ (selected_window, minibuf_window)
12850 && (current_buffer->clip_changed
12851 || XFASTINT (w->last_modified) < MODIFF
12852 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
12853 && resize_mini_window (w, 0))
12854 {
12855 /* Resized active mini-window to fit the size of what it is
12856 showing if its contents might have changed. */
12857 must_finish = 1;
12858 /* FIXME: this causes all frames to be updated, which seems unnecessary
12859 since only the current frame needs to be considered. This function needs
12860 to be rewritten with two variables, consider_all_windows and
12861 consider_all_frames. */
12862 consider_all_windows_p = 1;
12863 ++windows_or_buffers_changed;
12864 ++update_mode_lines;
12865
12866 /* If window configuration was changed, frames may have been
12867 marked garbaged. Clear them or we will experience
12868 surprises wrt scrolling. */
12869 if (frame_garbaged)
12870 clear_garbaged_frames ();
12871 }
12872
12873
12874 /* If showing the region, and mark has changed, we must redisplay
12875 the whole window. The assignment to this_line_start_pos prevents
12876 the optimization directly below this if-statement. */
12877 if (((!NILP (Vtransient_mark_mode)
12878 && !NILP (BVAR (XBUFFER (w->buffer), mark_active)))
12879 != !NILP (w->region_showing))
12880 || (!NILP (w->region_showing)
12881 && !EQ (w->region_showing,
12882 Fmarker_position (BVAR (XBUFFER (w->buffer), mark)))))
12883 CHARPOS (this_line_start_pos) = 0;
12884
12885 /* Optimize the case that only the line containing the cursor in the
12886 selected window has changed. Variables starting with this_ are
12887 set in display_line and record information about the line
12888 containing the cursor. */
12889 tlbufpos = this_line_start_pos;
12890 tlendpos = this_line_end_pos;
12891 if (!consider_all_windows_p
12892 && CHARPOS (tlbufpos) > 0
12893 && NILP (w->update_mode_line)
12894 && !current_buffer->clip_changed
12895 && !current_buffer->prevent_redisplay_optimizations_p
12896 && FRAME_VISIBLE_P (XFRAME (w->frame))
12897 && !FRAME_OBSCURED_P (XFRAME (w->frame))
12898 /* Make sure recorded data applies to current buffer, etc. */
12899 && this_line_buffer == current_buffer
12900 && current_buffer == XBUFFER (w->buffer)
12901 && NILP (w->force_start)
12902 && NILP (w->optional_new_start)
12903 /* Point must be on the line that we have info recorded about. */
12904 && PT >= CHARPOS (tlbufpos)
12905 && PT <= Z - CHARPOS (tlendpos)
12906 /* All text outside that line, including its final newline,
12907 must be unchanged. */
12908 && text_outside_line_unchanged_p (w, CHARPOS (tlbufpos),
12909 CHARPOS (tlendpos)))
12910 {
12911 if (CHARPOS (tlbufpos) > BEGV
12912 && FETCH_BYTE (BYTEPOS (tlbufpos) - 1) != '\n'
12913 && (CHARPOS (tlbufpos) == ZV
12914 || FETCH_BYTE (BYTEPOS (tlbufpos)) == '\n'))
12915 /* Former continuation line has disappeared by becoming empty. */
12916 goto cancel;
12917 else if (XFASTINT (w->last_modified) < MODIFF
12918 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF
12919 || MINI_WINDOW_P (w))
12920 {
12921 /* We have to handle the case of continuation around a
12922 wide-column character (see the comment in indent.c around
12923 line 1340).
12924
12925 For instance, in the following case:
12926
12927 -------- Insert --------
12928 K_A_N_\\ `a' K_A_N_a\ `X_' are wide-column chars.
12929 J_I_ ==> J_I_ `^^' are cursors.
12930 ^^ ^^
12931 -------- --------
12932
12933 As we have to redraw the line above, we cannot use this
12934 optimization. */
12935
12936 struct it it;
12937 int line_height_before = this_line_pixel_height;
12938
12939 /* Note that start_display will handle the case that the
12940 line starting at tlbufpos is a continuation line. */
12941 start_display (&it, w, tlbufpos);
12942
12943 /* Implementation note: It this still necessary? */
12944 if (it.current_x != this_line_start_x)
12945 goto cancel;
12946
12947 TRACE ((stderr, "trying display optimization 1\n"));
12948 w->cursor.vpos = -1;
12949 overlay_arrow_seen = 0;
12950 it.vpos = this_line_vpos;
12951 it.current_y = this_line_y;
12952 it.glyph_row = MATRIX_ROW (w->desired_matrix, this_line_vpos);
12953 display_line (&it);
12954
12955 /* If line contains point, is not continued,
12956 and ends at same distance from eob as before, we win. */
12957 if (w->cursor.vpos >= 0
12958 /* Line is not continued, otherwise this_line_start_pos
12959 would have been set to 0 in display_line. */
12960 && CHARPOS (this_line_start_pos)
12961 /* Line ends as before. */
12962 && CHARPOS (this_line_end_pos) == CHARPOS (tlendpos)
12963 /* Line has same height as before. Otherwise other lines
12964 would have to be shifted up or down. */
12965 && this_line_pixel_height == line_height_before)
12966 {
12967 /* If this is not the window's last line, we must adjust
12968 the charstarts of the lines below. */
12969 if (it.current_y < it.last_visible_y)
12970 {
12971 struct glyph_row *row
12972 = MATRIX_ROW (w->current_matrix, this_line_vpos + 1);
12973 EMACS_INT delta, delta_bytes;
12974
12975 /* We used to distinguish between two cases here,
12976 conditioned by Z - CHARPOS (tlendpos) == ZV, for
12977 when the line ends in a newline or the end of the
12978 buffer's accessible portion. But both cases did
12979 the same, so they were collapsed. */
12980 delta = (Z
12981 - CHARPOS (tlendpos)
12982 - MATRIX_ROW_START_CHARPOS (row));
12983 delta_bytes = (Z_BYTE
12984 - BYTEPOS (tlendpos)
12985 - MATRIX_ROW_START_BYTEPOS (row));
12986
12987 increment_matrix_positions (w->current_matrix,
12988 this_line_vpos + 1,
12989 w->current_matrix->nrows,
12990 delta, delta_bytes);
12991 }
12992
12993 /* If this row displays text now but previously didn't,
12994 or vice versa, w->window_end_vpos may have to be
12995 adjusted. */
12996 if ((it.glyph_row - 1)->displays_text_p)
12997 {
12998 if (XFASTINT (w->window_end_vpos) < this_line_vpos)
12999 XSETINT (w->window_end_vpos, this_line_vpos);
13000 }
13001 else if (XFASTINT (w->window_end_vpos) == this_line_vpos
13002 && this_line_vpos > 0)
13003 XSETINT (w->window_end_vpos, this_line_vpos - 1);
13004 w->window_end_valid = Qnil;
13005
13006 /* Update hint: No need to try to scroll in update_window. */
13007 w->desired_matrix->no_scrolling_p = 1;
13008
13009 #if GLYPH_DEBUG
13010 *w->desired_matrix->method = 0;
13011 debug_method_add (w, "optimization 1");
13012 #endif
13013 #ifdef HAVE_WINDOW_SYSTEM
13014 update_window_fringes (w, 0);
13015 #endif
13016 goto update;
13017 }
13018 else
13019 goto cancel;
13020 }
13021 else if (/* Cursor position hasn't changed. */
13022 PT == XFASTINT (w->last_point)
13023 /* Make sure the cursor was last displayed
13024 in this window. Otherwise we have to reposition it. */
13025 && 0 <= w->cursor.vpos
13026 && WINDOW_TOTAL_LINES (w) > w->cursor.vpos)
13027 {
13028 if (!must_finish)
13029 {
13030 do_pending_window_change (1);
13031 /* If selected_window changed, redisplay again. */
13032 if (WINDOWP (selected_window)
13033 && (w = XWINDOW (selected_window)) != sw)
13034 goto retry;
13035
13036 /* We used to always goto end_of_redisplay here, but this
13037 isn't enough if we have a blinking cursor. */
13038 if (w->cursor_off_p == w->last_cursor_off_p)
13039 goto end_of_redisplay;
13040 }
13041 goto update;
13042 }
13043 /* If highlighting the region, or if the cursor is in the echo area,
13044 then we can't just move the cursor. */
13045 else if (! (!NILP (Vtransient_mark_mode)
13046 && !NILP (BVAR (current_buffer, mark_active)))
13047 && (EQ (selected_window, BVAR (current_buffer, last_selected_window))
13048 || highlight_nonselected_windows)
13049 && NILP (w->region_showing)
13050 && NILP (Vshow_trailing_whitespace)
13051 && !cursor_in_echo_area)
13052 {
13053 struct it it;
13054 struct glyph_row *row;
13055
13056 /* Skip from tlbufpos to PT and see where it is. Note that
13057 PT may be in invisible text. If so, we will end at the
13058 next visible position. */
13059 init_iterator (&it, w, CHARPOS (tlbufpos), BYTEPOS (tlbufpos),
13060 NULL, DEFAULT_FACE_ID);
13061 it.current_x = this_line_start_x;
13062 it.current_y = this_line_y;
13063 it.vpos = this_line_vpos;
13064
13065 /* The call to move_it_to stops in front of PT, but
13066 moves over before-strings. */
13067 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
13068
13069 if (it.vpos == this_line_vpos
13070 && (row = MATRIX_ROW (w->current_matrix, this_line_vpos),
13071 row->enabled_p))
13072 {
13073 xassert (this_line_vpos == it.vpos);
13074 xassert (this_line_y == it.current_y);
13075 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
13076 #if GLYPH_DEBUG
13077 *w->desired_matrix->method = 0;
13078 debug_method_add (w, "optimization 3");
13079 #endif
13080 goto update;
13081 }
13082 else
13083 goto cancel;
13084 }
13085
13086 cancel:
13087 /* Text changed drastically or point moved off of line. */
13088 SET_MATRIX_ROW_ENABLED_P (w->desired_matrix, this_line_vpos, 0);
13089 }
13090
13091 CHARPOS (this_line_start_pos) = 0;
13092 consider_all_windows_p |= buffer_shared > 1;
13093 ++clear_face_cache_count;
13094 #ifdef HAVE_WINDOW_SYSTEM
13095 ++clear_image_cache_count;
13096 #endif
13097
13098 /* Build desired matrices, and update the display. If
13099 consider_all_windows_p is non-zero, do it for all windows on all
13100 frames. Otherwise do it for selected_window, only. */
13101
13102 if (consider_all_windows_p)
13103 {
13104 Lisp_Object tail, frame;
13105
13106 FOR_EACH_FRAME (tail, frame)
13107 XFRAME (frame)->updated_p = 0;
13108
13109 /* Recompute # windows showing selected buffer. This will be
13110 incremented each time such a window is displayed. */
13111 buffer_shared = 0;
13112
13113 FOR_EACH_FRAME (tail, frame)
13114 {
13115 struct frame *f = XFRAME (frame);
13116
13117 if (FRAME_WINDOW_P (f) || FRAME_TERMCAP_P (f) || f == sf)
13118 {
13119 if (! EQ (frame, selected_frame))
13120 /* Select the frame, for the sake of frame-local
13121 variables. */
13122 select_frame_for_redisplay (frame);
13123
13124 /* Mark all the scroll bars to be removed; we'll redeem
13125 the ones we want when we redisplay their windows. */
13126 if (FRAME_TERMINAL (f)->condemn_scroll_bars_hook)
13127 FRAME_TERMINAL (f)->condemn_scroll_bars_hook (f);
13128
13129 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
13130 redisplay_windows (FRAME_ROOT_WINDOW (f));
13131
13132 /* The X error handler may have deleted that frame. */
13133 if (!FRAME_LIVE_P (f))
13134 continue;
13135
13136 /* Any scroll bars which redisplay_windows should have
13137 nuked should now go away. */
13138 if (FRAME_TERMINAL (f)->judge_scroll_bars_hook)
13139 FRAME_TERMINAL (f)->judge_scroll_bars_hook (f);
13140
13141 /* If fonts changed, display again. */
13142 /* ??? rms: I suspect it is a mistake to jump all the way
13143 back to retry here. It should just retry this frame. */
13144 if (fonts_changed_p)
13145 goto retry;
13146
13147 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
13148 {
13149 /* See if we have to hscroll. */
13150 if (!f->already_hscrolled_p)
13151 {
13152 f->already_hscrolled_p = 1;
13153 if (hscroll_windows (f->root_window))
13154 goto retry;
13155 }
13156
13157 /* Prevent various kinds of signals during display
13158 update. stdio is not robust about handling
13159 signals, which can cause an apparent I/O
13160 error. */
13161 if (interrupt_input)
13162 unrequest_sigio ();
13163 STOP_POLLING;
13164
13165 /* Update the display. */
13166 set_window_update_flags (XWINDOW (f->root_window), 1);
13167 pending |= update_frame (f, 0, 0);
13168 f->updated_p = 1;
13169 }
13170 }
13171 }
13172
13173 if (!EQ (old_frame, selected_frame)
13174 && FRAME_LIVE_P (XFRAME (old_frame)))
13175 /* We played a bit fast-and-loose above and allowed selected_frame
13176 and selected_window to be temporarily out-of-sync but let's make
13177 sure this stays contained. */
13178 select_frame_for_redisplay (old_frame);
13179 eassert (EQ (XFRAME (selected_frame)->selected_window, selected_window));
13180
13181 if (!pending)
13182 {
13183 /* Do the mark_window_display_accurate after all windows have
13184 been redisplayed because this call resets flags in buffers
13185 which are needed for proper redisplay. */
13186 FOR_EACH_FRAME (tail, frame)
13187 {
13188 struct frame *f = XFRAME (frame);
13189 if (f->updated_p)
13190 {
13191 mark_window_display_accurate (f->root_window, 1);
13192 if (FRAME_TERMINAL (f)->frame_up_to_date_hook)
13193 FRAME_TERMINAL (f)->frame_up_to_date_hook (f);
13194 }
13195 }
13196 }
13197 }
13198 else if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
13199 {
13200 Lisp_Object mini_window;
13201 struct frame *mini_frame;
13202
13203 displayed_buffer = XBUFFER (XWINDOW (selected_window)->buffer);
13204 /* Use list_of_error, not Qerror, so that
13205 we catch only errors and don't run the debugger. */
13206 internal_condition_case_1 (redisplay_window_1, selected_window,
13207 list_of_error,
13208 redisplay_window_error);
13209
13210 /* Compare desired and current matrices, perform output. */
13211
13212 update:
13213 /* If fonts changed, display again. */
13214 if (fonts_changed_p)
13215 goto retry;
13216
13217 /* Prevent various kinds of signals during display update.
13218 stdio is not robust about handling signals,
13219 which can cause an apparent I/O error. */
13220 if (interrupt_input)
13221 unrequest_sigio ();
13222 STOP_POLLING;
13223
13224 if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
13225 {
13226 if (hscroll_windows (selected_window))
13227 goto retry;
13228
13229 XWINDOW (selected_window)->must_be_updated_p = 1;
13230 pending = update_frame (sf, 0, 0);
13231 }
13232
13233 /* We may have called echo_area_display at the top of this
13234 function. If the echo area is on another frame, that may
13235 have put text on a frame other than the selected one, so the
13236 above call to update_frame would not have caught it. Catch
13237 it here. */
13238 mini_window = FRAME_MINIBUF_WINDOW (sf);
13239 mini_frame = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
13240
13241 if (mini_frame != sf && FRAME_WINDOW_P (mini_frame))
13242 {
13243 XWINDOW (mini_window)->must_be_updated_p = 1;
13244 pending |= update_frame (mini_frame, 0, 0);
13245 if (!pending && hscroll_windows (mini_window))
13246 goto retry;
13247 }
13248 }
13249
13250 /* If display was paused because of pending input, make sure we do a
13251 thorough update the next time. */
13252 if (pending)
13253 {
13254 /* Prevent the optimization at the beginning of
13255 redisplay_internal that tries a single-line update of the
13256 line containing the cursor in the selected window. */
13257 CHARPOS (this_line_start_pos) = 0;
13258
13259 /* Let the overlay arrow be updated the next time. */
13260 update_overlay_arrows (0);
13261
13262 /* If we pause after scrolling, some rows in the current
13263 matrices of some windows are not valid. */
13264 if (!WINDOW_FULL_WIDTH_P (w)
13265 && !FRAME_WINDOW_P (XFRAME (w->frame)))
13266 update_mode_lines = 1;
13267 }
13268 else
13269 {
13270 if (!consider_all_windows_p)
13271 {
13272 /* This has already been done above if
13273 consider_all_windows_p is set. */
13274 mark_window_display_accurate_1 (w, 1);
13275
13276 /* Say overlay arrows are up to date. */
13277 update_overlay_arrows (1);
13278
13279 if (FRAME_TERMINAL (sf)->frame_up_to_date_hook != 0)
13280 FRAME_TERMINAL (sf)->frame_up_to_date_hook (sf);
13281 }
13282
13283 update_mode_lines = 0;
13284 windows_or_buffers_changed = 0;
13285 cursor_type_changed = 0;
13286 }
13287
13288 /* Start SIGIO interrupts coming again. Having them off during the
13289 code above makes it less likely one will discard output, but not
13290 impossible, since there might be stuff in the system buffer here.
13291 But it is much hairier to try to do anything about that. */
13292 if (interrupt_input)
13293 request_sigio ();
13294 RESUME_POLLING;
13295
13296 /* If a frame has become visible which was not before, redisplay
13297 again, so that we display it. Expose events for such a frame
13298 (which it gets when becoming visible) don't call the parts of
13299 redisplay constructing glyphs, so simply exposing a frame won't
13300 display anything in this case. So, we have to display these
13301 frames here explicitly. */
13302 if (!pending)
13303 {
13304 Lisp_Object tail, frame;
13305 int new_count = 0;
13306
13307 FOR_EACH_FRAME (tail, frame)
13308 {
13309 int this_is_visible = 0;
13310
13311 if (XFRAME (frame)->visible)
13312 this_is_visible = 1;
13313 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
13314 if (XFRAME (frame)->visible)
13315 this_is_visible = 1;
13316
13317 if (this_is_visible)
13318 new_count++;
13319 }
13320
13321 if (new_count != number_of_visible_frames)
13322 windows_or_buffers_changed++;
13323 }
13324
13325 /* Change frame size now if a change is pending. */
13326 do_pending_window_change (1);
13327
13328 /* If we just did a pending size change, or have additional
13329 visible frames, or selected_window changed, redisplay again. */
13330 if ((windows_or_buffers_changed && !pending)
13331 || (WINDOWP (selected_window) && (w = XWINDOW (selected_window)) != sw))
13332 goto retry;
13333
13334 /* Clear the face and image caches.
13335
13336 We used to do this only if consider_all_windows_p. But the cache
13337 needs to be cleared if a timer creates images in the current
13338 buffer (e.g. the test case in Bug#6230). */
13339
13340 if (clear_face_cache_count > CLEAR_FACE_CACHE_COUNT)
13341 {
13342 clear_face_cache (0);
13343 clear_face_cache_count = 0;
13344 }
13345
13346 #ifdef HAVE_WINDOW_SYSTEM
13347 if (clear_image_cache_count > CLEAR_IMAGE_CACHE_COUNT)
13348 {
13349 clear_image_caches (Qnil);
13350 clear_image_cache_count = 0;
13351 }
13352 #endif /* HAVE_WINDOW_SYSTEM */
13353
13354 end_of_redisplay:
13355 unbind_to (count, Qnil);
13356 RESUME_POLLING;
13357 }
13358
13359
13360 /* Redisplay, but leave alone any recent echo area message unless
13361 another message has been requested in its place.
13362
13363 This is useful in situations where you need to redisplay but no
13364 user action has occurred, making it inappropriate for the message
13365 area to be cleared. See tracking_off and
13366 wait_reading_process_output for examples of these situations.
13367
13368 FROM_WHERE is an integer saying from where this function was
13369 called. This is useful for debugging. */
13370
13371 void
13372 redisplay_preserve_echo_area (int from_where)
13373 {
13374 TRACE ((stderr, "redisplay_preserve_echo_area (%d)\n", from_where));
13375
13376 if (!NILP (echo_area_buffer[1]))
13377 {
13378 /* We have a previously displayed message, but no current
13379 message. Redisplay the previous message. */
13380 display_last_displayed_message_p = 1;
13381 redisplay_internal ();
13382 display_last_displayed_message_p = 0;
13383 }
13384 else
13385 redisplay_internal ();
13386
13387 if (FRAME_RIF (SELECTED_FRAME ()) != NULL
13388 && FRAME_RIF (SELECTED_FRAME ())->flush_display_optional)
13389 FRAME_RIF (SELECTED_FRAME ())->flush_display_optional (NULL);
13390 }
13391
13392
13393 /* Function registered with record_unwind_protect in
13394 redisplay_internal. Reset redisplaying_p to the value it had
13395 before redisplay_internal was called, and clear
13396 prevent_freeing_realized_faces_p. It also selects the previously
13397 selected frame, unless it has been deleted (by an X connection
13398 failure during redisplay, for example). */
13399
13400 static Lisp_Object
13401 unwind_redisplay (Lisp_Object val)
13402 {
13403 Lisp_Object old_redisplaying_p, old_frame;
13404
13405 old_redisplaying_p = XCAR (val);
13406 redisplaying_p = XFASTINT (old_redisplaying_p);
13407 old_frame = XCDR (val);
13408 if (! EQ (old_frame, selected_frame)
13409 && FRAME_LIVE_P (XFRAME (old_frame)))
13410 select_frame_for_redisplay (old_frame);
13411 return Qnil;
13412 }
13413
13414
13415 /* Mark the display of window W as accurate or inaccurate. If
13416 ACCURATE_P is non-zero mark display of W as accurate. If
13417 ACCURATE_P is zero, arrange for W to be redisplayed the next time
13418 redisplay_internal is called. */
13419
13420 static void
13421 mark_window_display_accurate_1 (struct window *w, int accurate_p)
13422 {
13423 if (BUFFERP (w->buffer))
13424 {
13425 struct buffer *b = XBUFFER (w->buffer);
13426
13427 w->last_modified
13428 = make_number (accurate_p ? BUF_MODIFF (b) : 0);
13429 w->last_overlay_modified
13430 = make_number (accurate_p ? BUF_OVERLAY_MODIFF (b) : 0);
13431 w->last_had_star
13432 = BUF_MODIFF (b) > BUF_SAVE_MODIFF (b) ? Qt : Qnil;
13433
13434 if (accurate_p)
13435 {
13436 b->clip_changed = 0;
13437 b->prevent_redisplay_optimizations_p = 0;
13438
13439 BUF_UNCHANGED_MODIFIED (b) = BUF_MODIFF (b);
13440 BUF_OVERLAY_UNCHANGED_MODIFIED (b) = BUF_OVERLAY_MODIFF (b);
13441 BUF_BEG_UNCHANGED (b) = BUF_GPT (b) - BUF_BEG (b);
13442 BUF_END_UNCHANGED (b) = BUF_Z (b) - BUF_GPT (b);
13443
13444 w->current_matrix->buffer = b;
13445 w->current_matrix->begv = BUF_BEGV (b);
13446 w->current_matrix->zv = BUF_ZV (b);
13447
13448 w->last_cursor = w->cursor;
13449 w->last_cursor_off_p = w->cursor_off_p;
13450
13451 if (w == XWINDOW (selected_window))
13452 w->last_point = make_number (BUF_PT (b));
13453 else
13454 w->last_point = make_number (XMARKER (w->pointm)->charpos);
13455 }
13456 }
13457
13458 if (accurate_p)
13459 {
13460 w->window_end_valid = w->buffer;
13461 w->update_mode_line = Qnil;
13462 }
13463 }
13464
13465
13466 /* Mark the display of windows in the window tree rooted at WINDOW as
13467 accurate or inaccurate. If ACCURATE_P is non-zero mark display of
13468 windows as accurate. If ACCURATE_P is zero, arrange for windows to
13469 be redisplayed the next time redisplay_internal is called. */
13470
13471 void
13472 mark_window_display_accurate (Lisp_Object window, int accurate_p)
13473 {
13474 struct window *w;
13475
13476 for (; !NILP (window); window = w->next)
13477 {
13478 w = XWINDOW (window);
13479 mark_window_display_accurate_1 (w, accurate_p);
13480
13481 if (!NILP (w->vchild))
13482 mark_window_display_accurate (w->vchild, accurate_p);
13483 if (!NILP (w->hchild))
13484 mark_window_display_accurate (w->hchild, accurate_p);
13485 }
13486
13487 if (accurate_p)
13488 {
13489 update_overlay_arrows (1);
13490 }
13491 else
13492 {
13493 /* Force a thorough redisplay the next time by setting
13494 last_arrow_position and last_arrow_string to t, which is
13495 unequal to any useful value of Voverlay_arrow_... */
13496 update_overlay_arrows (-1);
13497 }
13498 }
13499
13500
13501 /* Return value in display table DP (Lisp_Char_Table *) for character
13502 C. Since a display table doesn't have any parent, we don't have to
13503 follow parent. Do not call this function directly but use the
13504 macro DISP_CHAR_VECTOR. */
13505
13506 Lisp_Object
13507 disp_char_vector (struct Lisp_Char_Table *dp, int c)
13508 {
13509 Lisp_Object val;
13510
13511 if (ASCII_CHAR_P (c))
13512 {
13513 val = dp->ascii;
13514 if (SUB_CHAR_TABLE_P (val))
13515 val = XSUB_CHAR_TABLE (val)->contents[c];
13516 }
13517 else
13518 {
13519 Lisp_Object table;
13520
13521 XSETCHAR_TABLE (table, dp);
13522 val = char_table_ref (table, c);
13523 }
13524 if (NILP (val))
13525 val = dp->defalt;
13526 return val;
13527 }
13528
13529
13530 \f
13531 /***********************************************************************
13532 Window Redisplay
13533 ***********************************************************************/
13534
13535 /* Redisplay all leaf windows in the window tree rooted at WINDOW. */
13536
13537 static void
13538 redisplay_windows (Lisp_Object window)
13539 {
13540 while (!NILP (window))
13541 {
13542 struct window *w = XWINDOW (window);
13543
13544 if (!NILP (w->hchild))
13545 redisplay_windows (w->hchild);
13546 else if (!NILP (w->vchild))
13547 redisplay_windows (w->vchild);
13548 else if (!NILP (w->buffer))
13549 {
13550 displayed_buffer = XBUFFER (w->buffer);
13551 /* Use list_of_error, not Qerror, so that
13552 we catch only errors and don't run the debugger. */
13553 internal_condition_case_1 (redisplay_window_0, window,
13554 list_of_error,
13555 redisplay_window_error);
13556 }
13557
13558 window = w->next;
13559 }
13560 }
13561
13562 static Lisp_Object
13563 redisplay_window_error (Lisp_Object ignore)
13564 {
13565 displayed_buffer->display_error_modiff = BUF_MODIFF (displayed_buffer);
13566 return Qnil;
13567 }
13568
13569 static Lisp_Object
13570 redisplay_window_0 (Lisp_Object window)
13571 {
13572 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
13573 redisplay_window (window, 0);
13574 return Qnil;
13575 }
13576
13577 static Lisp_Object
13578 redisplay_window_1 (Lisp_Object window)
13579 {
13580 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
13581 redisplay_window (window, 1);
13582 return Qnil;
13583 }
13584 \f
13585
13586 /* Set cursor position of W. PT is assumed to be displayed in ROW.
13587 DELTA and DELTA_BYTES are the numbers of characters and bytes by
13588 which positions recorded in ROW differ from current buffer
13589 positions.
13590
13591 Return 0 if cursor is not on this row, 1 otherwise. */
13592
13593 static int
13594 set_cursor_from_row (struct window *w, struct glyph_row *row,
13595 struct glyph_matrix *matrix,
13596 EMACS_INT delta, EMACS_INT delta_bytes,
13597 int dy, int dvpos)
13598 {
13599 struct glyph *glyph = row->glyphs[TEXT_AREA];
13600 struct glyph *end = glyph + row->used[TEXT_AREA];
13601 struct glyph *cursor = NULL;
13602 /* The last known character position in row. */
13603 EMACS_INT last_pos = MATRIX_ROW_START_CHARPOS (row) + delta;
13604 int x = row->x;
13605 EMACS_INT pt_old = PT - delta;
13606 EMACS_INT pos_before = MATRIX_ROW_START_CHARPOS (row) + delta;
13607 EMACS_INT pos_after = MATRIX_ROW_END_CHARPOS (row) + delta;
13608 struct glyph *glyph_before = glyph - 1, *glyph_after = end;
13609 /* A glyph beyond the edge of TEXT_AREA which we should never
13610 touch. */
13611 struct glyph *glyphs_end = end;
13612 /* Non-zero means we've found a match for cursor position, but that
13613 glyph has the avoid_cursor_p flag set. */
13614 int match_with_avoid_cursor = 0;
13615 /* Non-zero means we've seen at least one glyph that came from a
13616 display string. */
13617 int string_seen = 0;
13618 /* Largest and smalles buffer positions seen so far during scan of
13619 glyph row. */
13620 EMACS_INT bpos_max = pos_before;
13621 EMACS_INT bpos_min = pos_after;
13622 /* Last buffer position covered by an overlay string with an integer
13623 `cursor' property. */
13624 EMACS_INT bpos_covered = 0;
13625 /* Non-zero means the display string on which to display the cursor
13626 comes from a text property, not from an overlay. */
13627 int string_from_text_prop = 0;
13628
13629 /* Skip over glyphs not having an object at the start and the end of
13630 the row. These are special glyphs like truncation marks on
13631 terminal frames. */
13632 if (row->displays_text_p)
13633 {
13634 if (!row->reversed_p)
13635 {
13636 while (glyph < end
13637 && INTEGERP (glyph->object)
13638 && glyph->charpos < 0)
13639 {
13640 x += glyph->pixel_width;
13641 ++glyph;
13642 }
13643 while (end > glyph
13644 && INTEGERP ((end - 1)->object)
13645 /* CHARPOS is zero for blanks and stretch glyphs
13646 inserted by extend_face_to_end_of_line. */
13647 && (end - 1)->charpos <= 0)
13648 --end;
13649 glyph_before = glyph - 1;
13650 glyph_after = end;
13651 }
13652 else
13653 {
13654 struct glyph *g;
13655
13656 /* If the glyph row is reversed, we need to process it from back
13657 to front, so swap the edge pointers. */
13658 glyphs_end = end = glyph - 1;
13659 glyph += row->used[TEXT_AREA] - 1;
13660
13661 while (glyph > end + 1
13662 && INTEGERP (glyph->object)
13663 && glyph->charpos < 0)
13664 {
13665 --glyph;
13666 x -= glyph->pixel_width;
13667 }
13668 if (INTEGERP (glyph->object) && glyph->charpos < 0)
13669 --glyph;
13670 /* By default, in reversed rows we put the cursor on the
13671 rightmost (first in the reading order) glyph. */
13672 for (g = end + 1; g < glyph; g++)
13673 x += g->pixel_width;
13674 while (end < glyph
13675 && INTEGERP ((end + 1)->object)
13676 && (end + 1)->charpos <= 0)
13677 ++end;
13678 glyph_before = glyph + 1;
13679 glyph_after = end;
13680 }
13681 }
13682 else if (row->reversed_p)
13683 {
13684 /* In R2L rows that don't display text, put the cursor on the
13685 rightmost glyph. Case in point: an empty last line that is
13686 part of an R2L paragraph. */
13687 cursor = end - 1;
13688 /* Avoid placing the cursor on the last glyph of the row, where
13689 on terminal frames we hold the vertical border between
13690 adjacent windows. */
13691 if (!FRAME_WINDOW_P (WINDOW_XFRAME (w))
13692 && !WINDOW_RIGHTMOST_P (w)
13693 && cursor == row->glyphs[LAST_AREA] - 1)
13694 cursor--;
13695 x = -1; /* will be computed below, at label compute_x */
13696 }
13697
13698 /* Step 1: Try to find the glyph whose character position
13699 corresponds to point. If that's not possible, find 2 glyphs
13700 whose character positions are the closest to point, one before
13701 point, the other after it. */
13702 if (!row->reversed_p)
13703 while (/* not marched to end of glyph row */
13704 glyph < end
13705 /* glyph was not inserted by redisplay for internal purposes */
13706 && !INTEGERP (glyph->object))
13707 {
13708 if (BUFFERP (glyph->object))
13709 {
13710 EMACS_INT dpos = glyph->charpos - pt_old;
13711
13712 if (glyph->charpos > bpos_max)
13713 bpos_max = glyph->charpos;
13714 if (glyph->charpos < bpos_min)
13715 bpos_min = glyph->charpos;
13716 if (!glyph->avoid_cursor_p)
13717 {
13718 /* If we hit point, we've found the glyph on which to
13719 display the cursor. */
13720 if (dpos == 0)
13721 {
13722 match_with_avoid_cursor = 0;
13723 break;
13724 }
13725 /* See if we've found a better approximation to
13726 POS_BEFORE or to POS_AFTER. Note that we want the
13727 first (leftmost) glyph of all those that are the
13728 closest from below, and the last (rightmost) of all
13729 those from above. */
13730 if (0 > dpos && dpos > pos_before - pt_old)
13731 {
13732 pos_before = glyph->charpos;
13733 glyph_before = glyph;
13734 }
13735 else if (0 < dpos && dpos <= pos_after - pt_old)
13736 {
13737 pos_after = glyph->charpos;
13738 glyph_after = glyph;
13739 }
13740 }
13741 else if (dpos == 0)
13742 match_with_avoid_cursor = 1;
13743 }
13744 else if (STRINGP (glyph->object))
13745 {
13746 Lisp_Object chprop;
13747 EMACS_INT glyph_pos = glyph->charpos;
13748
13749 chprop = Fget_char_property (make_number (glyph_pos), Qcursor,
13750 glyph->object);
13751 if (INTEGERP (chprop))
13752 {
13753 bpos_covered = bpos_max + XINT (chprop);
13754 /* If the `cursor' property covers buffer positions up
13755 to and including point, we should display cursor on
13756 this glyph. Note that overlays and text properties
13757 with string values stop bidi reordering, so every
13758 buffer position to the left of the string is always
13759 smaller than any position to the right of the
13760 string. Therefore, if a `cursor' property on one
13761 of the string's characters has an integer value, we
13762 will break out of the loop below _before_ we get to
13763 the position match above. IOW, integer values of
13764 the `cursor' property override the "exact match for
13765 point" strategy of positioning the cursor. */
13766 /* Implementation note: bpos_max == pt_old when, e.g.,
13767 we are in an empty line, where bpos_max is set to
13768 MATRIX_ROW_START_CHARPOS, see above. */
13769 if (bpos_max <= pt_old && bpos_covered >= pt_old)
13770 {
13771 cursor = glyph;
13772 break;
13773 }
13774 }
13775
13776 string_seen = 1;
13777 }
13778 x += glyph->pixel_width;
13779 ++glyph;
13780 }
13781 else if (glyph > end) /* row is reversed */
13782 while (!INTEGERP (glyph->object))
13783 {
13784 if (BUFFERP (glyph->object))
13785 {
13786 EMACS_INT dpos = glyph->charpos - pt_old;
13787
13788 if (glyph->charpos > bpos_max)
13789 bpos_max = glyph->charpos;
13790 if (glyph->charpos < bpos_min)
13791 bpos_min = glyph->charpos;
13792 if (!glyph->avoid_cursor_p)
13793 {
13794 if (dpos == 0)
13795 {
13796 match_with_avoid_cursor = 0;
13797 break;
13798 }
13799 if (0 > dpos && dpos > pos_before - pt_old)
13800 {
13801 pos_before = glyph->charpos;
13802 glyph_before = glyph;
13803 }
13804 else if (0 < dpos && dpos <= pos_after - pt_old)
13805 {
13806 pos_after = glyph->charpos;
13807 glyph_after = glyph;
13808 }
13809 }
13810 else if (dpos == 0)
13811 match_with_avoid_cursor = 1;
13812 }
13813 else if (STRINGP (glyph->object))
13814 {
13815 Lisp_Object chprop;
13816 EMACS_INT glyph_pos = glyph->charpos;
13817
13818 chprop = Fget_char_property (make_number (glyph_pos), Qcursor,
13819 glyph->object);
13820 if (INTEGERP (chprop))
13821 {
13822 bpos_covered = bpos_max + XINT (chprop);
13823 /* If the `cursor' property covers buffer positions up
13824 to and including point, we should display cursor on
13825 this glyph. */
13826 if (bpos_max <= pt_old && bpos_covered >= pt_old)
13827 {
13828 cursor = glyph;
13829 break;
13830 }
13831 }
13832 string_seen = 1;
13833 }
13834 --glyph;
13835 if (glyph == glyphs_end) /* don't dereference outside TEXT_AREA */
13836 {
13837 x--; /* can't use any pixel_width */
13838 break;
13839 }
13840 x -= glyph->pixel_width;
13841 }
13842
13843 /* Step 2: If we didn't find an exact match for point, we need to
13844 look for a proper place to put the cursor among glyphs between
13845 GLYPH_BEFORE and GLYPH_AFTER. */
13846 if (!((row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end)
13847 && BUFFERP (glyph->object) && glyph->charpos == pt_old)
13848 && bpos_covered < pt_old)
13849 {
13850 /* An empty line has a single glyph whose OBJECT is zero and
13851 whose CHARPOS is the position of a newline on that line.
13852 Note that on a TTY, there are more glyphs after that, which
13853 were produced by extend_face_to_end_of_line, but their
13854 CHARPOS is zero or negative. */
13855 int empty_line_p =
13856 (row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end)
13857 && INTEGERP (glyph->object) && glyph->charpos > 0;
13858
13859 if (row->ends_in_ellipsis_p && pos_after == last_pos)
13860 {
13861 EMACS_INT ellipsis_pos;
13862
13863 /* Scan back over the ellipsis glyphs. */
13864 if (!row->reversed_p)
13865 {
13866 ellipsis_pos = (glyph - 1)->charpos;
13867 while (glyph > row->glyphs[TEXT_AREA]
13868 && (glyph - 1)->charpos == ellipsis_pos)
13869 glyph--, x -= glyph->pixel_width;
13870 /* That loop always goes one position too far, including
13871 the glyph before the ellipsis. So scan forward over
13872 that one. */
13873 x += glyph->pixel_width;
13874 glyph++;
13875 }
13876 else /* row is reversed */
13877 {
13878 ellipsis_pos = (glyph + 1)->charpos;
13879 while (glyph < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1
13880 && (glyph + 1)->charpos == ellipsis_pos)
13881 glyph++, x += glyph->pixel_width;
13882 x -= glyph->pixel_width;
13883 glyph--;
13884 }
13885 }
13886 else if (match_with_avoid_cursor)
13887 {
13888 cursor = glyph_after;
13889 x = -1;
13890 }
13891 else if (string_seen)
13892 {
13893 int incr = row->reversed_p ? -1 : +1;
13894
13895 /* Need to find the glyph that came out of a string which is
13896 present at point. That glyph is somewhere between
13897 GLYPH_BEFORE and GLYPH_AFTER, and it came from a string
13898 positioned between POS_BEFORE and POS_AFTER in the
13899 buffer. */
13900 struct glyph *start, *stop;
13901 EMACS_INT pos = pos_before;
13902
13903 x = -1;
13904
13905 /* If the row ends in a newline from a display string,
13906 reordering could have moved the glyphs belonging to the
13907 string out of the [GLYPH_BEFORE..GLYPH_AFTER] range. So
13908 in this case we extend the search to the last glyph in
13909 the row that was not inserted by redisplay. */
13910 if (row->ends_in_newline_from_string_p)
13911 {
13912 glyph_after = end;
13913 pos_after = MATRIX_ROW_END_CHARPOS (row) + delta;
13914 }
13915
13916 /* GLYPH_BEFORE and GLYPH_AFTER are the glyphs that
13917 correspond to POS_BEFORE and POS_AFTER, respectively. We
13918 need START and STOP in the order that corresponds to the
13919 row's direction as given by its reversed_p flag. If the
13920 directionality of characters between POS_BEFORE and
13921 POS_AFTER is the opposite of the row's base direction,
13922 these characters will have been reordered for display,
13923 and we need to reverse START and STOP. */
13924 if (!row->reversed_p)
13925 {
13926 start = min (glyph_before, glyph_after);
13927 stop = max (glyph_before, glyph_after);
13928 }
13929 else
13930 {
13931 start = max (glyph_before, glyph_after);
13932 stop = min (glyph_before, glyph_after);
13933 }
13934 for (glyph = start + incr;
13935 row->reversed_p ? glyph > stop : glyph < stop; )
13936 {
13937
13938 /* Any glyphs that come from the buffer are here because
13939 of bidi reordering. Skip them, and only pay
13940 attention to glyphs that came from some string. */
13941 if (STRINGP (glyph->object))
13942 {
13943 Lisp_Object str;
13944 EMACS_INT tem;
13945 /* If the display property covers the newline, we
13946 need to search for it one position farther. */
13947 EMACS_INT lim = pos_after
13948 + (pos_after == MATRIX_ROW_END_CHARPOS (row) + delta);
13949
13950 string_from_text_prop = 0;
13951 str = glyph->object;
13952 tem = string_buffer_position_lim (str, pos, lim, 0);
13953 if (tem == 0 /* from overlay */
13954 || pos <= tem)
13955 {
13956 /* If the string from which this glyph came is
13957 found in the buffer at point, then we've
13958 found the glyph we've been looking for. If
13959 it comes from an overlay (tem == 0), and it
13960 has the `cursor' property on one of its
13961 glyphs, record that glyph as a candidate for
13962 displaying the cursor. (As in the
13963 unidirectional version, we will display the
13964 cursor on the last candidate we find.) */
13965 if (tem == 0 || tem == pt_old)
13966 {
13967 /* The glyphs from this string could have
13968 been reordered. Find the one with the
13969 smallest string position. Or there could
13970 be a character in the string with the
13971 `cursor' property, which means display
13972 cursor on that character's glyph. */
13973 EMACS_INT strpos = glyph->charpos;
13974
13975 if (tem)
13976 {
13977 cursor = glyph;
13978 string_from_text_prop = 1;
13979 }
13980 for ( ;
13981 (row->reversed_p ? glyph > stop : glyph < stop)
13982 && EQ (glyph->object, str);
13983 glyph += incr)
13984 {
13985 Lisp_Object cprop;
13986 EMACS_INT gpos = glyph->charpos;
13987
13988 cprop = Fget_char_property (make_number (gpos),
13989 Qcursor,
13990 glyph->object);
13991 if (!NILP (cprop))
13992 {
13993 cursor = glyph;
13994 break;
13995 }
13996 if (tem && glyph->charpos < strpos)
13997 {
13998 strpos = glyph->charpos;
13999 cursor = glyph;
14000 }
14001 }
14002
14003 if (tem == pt_old)
14004 goto compute_x;
14005 }
14006 if (tem)
14007 pos = tem + 1; /* don't find previous instances */
14008 }
14009 /* This string is not what we want; skip all of the
14010 glyphs that came from it. */
14011 while ((row->reversed_p ? glyph > stop : glyph < stop)
14012 && EQ (glyph->object, str))
14013 glyph += incr;
14014 }
14015 else
14016 glyph += incr;
14017 }
14018
14019 /* If we reached the end of the line, and END was from a string,
14020 the cursor is not on this line. */
14021 if (cursor == NULL
14022 && (row->reversed_p ? glyph <= end : glyph >= end)
14023 && STRINGP (end->object)
14024 && row->continued_p)
14025 return 0;
14026 }
14027 /* A truncated row may not include PT among its character positions.
14028 Setting the cursor inside the scroll margin will trigger
14029 recalculation of hscroll in hscroll_window_tree. But if a
14030 display string covers point, defer to the string-handling
14031 code below to figure this out. */
14032 else if (row->truncated_on_left_p && pt_old < bpos_min)
14033 {
14034 cursor = glyph_before;
14035 x = -1;
14036 }
14037 else if ((row->truncated_on_right_p && pt_old > bpos_max)
14038 /* Zero-width characters produce no glyphs. */
14039 || (!empty_line_p
14040 && (row->reversed_p
14041 ? glyph_after > glyphs_end
14042 : glyph_after < glyphs_end)))
14043 {
14044 cursor = glyph_after;
14045 x = -1;
14046 }
14047 }
14048
14049 compute_x:
14050 if (cursor != NULL)
14051 glyph = cursor;
14052 if (x < 0)
14053 {
14054 struct glyph *g;
14055
14056 /* Need to compute x that corresponds to GLYPH. */
14057 for (g = row->glyphs[TEXT_AREA], x = row->x; g < glyph; g++)
14058 {
14059 if (g >= row->glyphs[TEXT_AREA] + row->used[TEXT_AREA])
14060 abort ();
14061 x += g->pixel_width;
14062 }
14063 }
14064
14065 /* ROW could be part of a continued line, which, under bidi
14066 reordering, might have other rows whose start and end charpos
14067 occlude point. Only set w->cursor if we found a better
14068 approximation to the cursor position than we have from previously
14069 examined candidate rows belonging to the same continued line. */
14070 if (/* we already have a candidate row */
14071 w->cursor.vpos >= 0
14072 /* that candidate is not the row we are processing */
14073 && MATRIX_ROW (matrix, w->cursor.vpos) != row
14074 /* Make sure cursor.vpos specifies a row whose start and end
14075 charpos occlude point, and it is valid candidate for being a
14076 cursor-row. This is because some callers of this function
14077 leave cursor.vpos at the row where the cursor was displayed
14078 during the last redisplay cycle. */
14079 && MATRIX_ROW_START_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos)) <= pt_old
14080 && pt_old <= MATRIX_ROW_END_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))
14081 && cursor_row_p (MATRIX_ROW (matrix, w->cursor.vpos)))
14082 {
14083 struct glyph *g1 =
14084 MATRIX_ROW_GLYPH_START (matrix, w->cursor.vpos) + w->cursor.hpos;
14085
14086 /* Don't consider glyphs that are outside TEXT_AREA. */
14087 if (!(row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end))
14088 return 0;
14089 /* Keep the candidate whose buffer position is the closest to
14090 point or has the `cursor' property. */
14091 if (/* previous candidate is a glyph in TEXT_AREA of that row */
14092 w->cursor.hpos >= 0
14093 && w->cursor.hpos < MATRIX_ROW_USED (matrix, w->cursor.vpos)
14094 && ((BUFFERP (g1->object)
14095 && (g1->charpos == pt_old /* an exact match always wins */
14096 || (BUFFERP (glyph->object)
14097 && eabs (g1->charpos - pt_old)
14098 < eabs (glyph->charpos - pt_old))))
14099 /* previous candidate is a glyph from a string that has
14100 a non-nil `cursor' property */
14101 || (STRINGP (g1->object)
14102 && (!NILP (Fget_char_property (make_number (g1->charpos),
14103 Qcursor, g1->object))
14104 /* pevious candidate is from the same display
14105 string as this one, and the display string
14106 came from a text property */
14107 || (EQ (g1->object, glyph->object)
14108 && string_from_text_prop)
14109 /* this candidate is from newline and its
14110 position is not an exact match */
14111 || (INTEGERP (glyph->object)
14112 && glyph->charpos != pt_old)))))
14113 return 0;
14114 /* If this candidate gives an exact match, use that. */
14115 if (!((BUFFERP (glyph->object) && glyph->charpos == pt_old)
14116 /* If this candidate is a glyph created for the
14117 terminating newline of a line, and point is on that
14118 newline, it wins because it's an exact match. */
14119 || (!row->continued_p
14120 && INTEGERP (glyph->object)
14121 && glyph->charpos == 0
14122 && pt_old == MATRIX_ROW_END_CHARPOS (row) - 1))
14123 /* Otherwise, keep the candidate that comes from a row
14124 spanning less buffer positions. This may win when one or
14125 both candidate positions are on glyphs that came from
14126 display strings, for which we cannot compare buffer
14127 positions. */
14128 && MATRIX_ROW_END_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))
14129 - MATRIX_ROW_START_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))
14130 < MATRIX_ROW_END_CHARPOS (row) - MATRIX_ROW_START_CHARPOS (row))
14131 return 0;
14132 }
14133 w->cursor.hpos = glyph - row->glyphs[TEXT_AREA];
14134 w->cursor.x = x;
14135 w->cursor.vpos = MATRIX_ROW_VPOS (row, matrix) + dvpos;
14136 w->cursor.y = row->y + dy;
14137
14138 if (w == XWINDOW (selected_window))
14139 {
14140 if (!row->continued_p
14141 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
14142 && row->x == 0)
14143 {
14144 this_line_buffer = XBUFFER (w->buffer);
14145
14146 CHARPOS (this_line_start_pos)
14147 = MATRIX_ROW_START_CHARPOS (row) + delta;
14148 BYTEPOS (this_line_start_pos)
14149 = MATRIX_ROW_START_BYTEPOS (row) + delta_bytes;
14150
14151 CHARPOS (this_line_end_pos)
14152 = Z - (MATRIX_ROW_END_CHARPOS (row) + delta);
14153 BYTEPOS (this_line_end_pos)
14154 = Z_BYTE - (MATRIX_ROW_END_BYTEPOS (row) + delta_bytes);
14155
14156 this_line_y = w->cursor.y;
14157 this_line_pixel_height = row->height;
14158 this_line_vpos = w->cursor.vpos;
14159 this_line_start_x = row->x;
14160 }
14161 else
14162 CHARPOS (this_line_start_pos) = 0;
14163 }
14164
14165 return 1;
14166 }
14167
14168
14169 /* Run window scroll functions, if any, for WINDOW with new window
14170 start STARTP. Sets the window start of WINDOW to that position.
14171
14172 We assume that the window's buffer is really current. */
14173
14174 static inline struct text_pos
14175 run_window_scroll_functions (Lisp_Object window, struct text_pos startp)
14176 {
14177 struct window *w = XWINDOW (window);
14178 SET_MARKER_FROM_TEXT_POS (w->start, startp);
14179
14180 if (current_buffer != XBUFFER (w->buffer))
14181 abort ();
14182
14183 if (!NILP (Vwindow_scroll_functions))
14184 {
14185 run_hook_with_args_2 (Qwindow_scroll_functions, window,
14186 make_number (CHARPOS (startp)));
14187 SET_TEXT_POS_FROM_MARKER (startp, w->start);
14188 /* In case the hook functions switch buffers. */
14189 if (current_buffer != XBUFFER (w->buffer))
14190 set_buffer_internal_1 (XBUFFER (w->buffer));
14191 }
14192
14193 return startp;
14194 }
14195
14196
14197 /* Make sure the line containing the cursor is fully visible.
14198 A value of 1 means there is nothing to be done.
14199 (Either the line is fully visible, or it cannot be made so,
14200 or we cannot tell.)
14201
14202 If FORCE_P is non-zero, return 0 even if partial visible cursor row
14203 is higher than window.
14204
14205 A value of 0 means the caller should do scrolling
14206 as if point had gone off the screen. */
14207
14208 static int
14209 cursor_row_fully_visible_p (struct window *w, int force_p, int current_matrix_p)
14210 {
14211 struct glyph_matrix *matrix;
14212 struct glyph_row *row;
14213 int window_height;
14214
14215 if (!make_cursor_line_fully_visible_p)
14216 return 1;
14217
14218 /* It's not always possible to find the cursor, e.g, when a window
14219 is full of overlay strings. Don't do anything in that case. */
14220 if (w->cursor.vpos < 0)
14221 return 1;
14222
14223 matrix = current_matrix_p ? w->current_matrix : w->desired_matrix;
14224 row = MATRIX_ROW (matrix, w->cursor.vpos);
14225
14226 /* If the cursor row is not partially visible, there's nothing to do. */
14227 if (!MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row))
14228 return 1;
14229
14230 /* If the row the cursor is in is taller than the window's height,
14231 it's not clear what to do, so do nothing. */
14232 window_height = window_box_height (w);
14233 if (row->height >= window_height)
14234 {
14235 if (!force_p || MINI_WINDOW_P (w)
14236 || w->vscroll || w->cursor.vpos == 0)
14237 return 1;
14238 }
14239 return 0;
14240 }
14241
14242
14243 /* Try scrolling PT into view in window WINDOW. JUST_THIS_ONE_P
14244 non-zero means only WINDOW is redisplayed in redisplay_internal.
14245 TEMP_SCROLL_STEP has the same meaning as emacs_scroll_step, and is used
14246 in redisplay_window to bring a partially visible line into view in
14247 the case that only the cursor has moved.
14248
14249 LAST_LINE_MISFIT should be nonzero if we're scrolling because the
14250 last screen line's vertical height extends past the end of the screen.
14251
14252 Value is
14253
14254 1 if scrolling succeeded
14255
14256 0 if scrolling didn't find point.
14257
14258 -1 if new fonts have been loaded so that we must interrupt
14259 redisplay, adjust glyph matrices, and try again. */
14260
14261 enum
14262 {
14263 SCROLLING_SUCCESS,
14264 SCROLLING_FAILED,
14265 SCROLLING_NEED_LARGER_MATRICES
14266 };
14267
14268 /* If scroll-conservatively is more than this, never recenter.
14269
14270 If you change this, don't forget to update the doc string of
14271 `scroll-conservatively' and the Emacs manual. */
14272 #define SCROLL_LIMIT 100
14273
14274 static int
14275 try_scrolling (Lisp_Object window, int just_this_one_p,
14276 EMACS_INT arg_scroll_conservatively, EMACS_INT scroll_step,
14277 int temp_scroll_step, int last_line_misfit)
14278 {
14279 struct window *w = XWINDOW (window);
14280 struct frame *f = XFRAME (w->frame);
14281 struct text_pos pos, startp;
14282 struct it it;
14283 int this_scroll_margin, scroll_max, rc, height;
14284 int dy = 0, amount_to_scroll = 0, scroll_down_p = 0;
14285 int extra_scroll_margin_lines = last_line_misfit ? 1 : 0;
14286 Lisp_Object aggressive;
14287 /* We will never try scrolling more than this number of lines. */
14288 int scroll_limit = SCROLL_LIMIT;
14289
14290 #if GLYPH_DEBUG
14291 debug_method_add (w, "try_scrolling");
14292 #endif
14293
14294 SET_TEXT_POS_FROM_MARKER (startp, w->start);
14295
14296 /* Compute scroll margin height in pixels. We scroll when point is
14297 within this distance from the top or bottom of the window. */
14298 if (scroll_margin > 0)
14299 this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4)
14300 * FRAME_LINE_HEIGHT (f);
14301 else
14302 this_scroll_margin = 0;
14303
14304 /* Force arg_scroll_conservatively to have a reasonable value, to
14305 avoid scrolling too far away with slow move_it_* functions. Note
14306 that the user can supply scroll-conservatively equal to
14307 `most-positive-fixnum', which can be larger than INT_MAX. */
14308 if (arg_scroll_conservatively > scroll_limit)
14309 {
14310 arg_scroll_conservatively = scroll_limit + 1;
14311 scroll_max = scroll_limit * FRAME_LINE_HEIGHT (f);
14312 }
14313 else if (scroll_step || arg_scroll_conservatively || temp_scroll_step)
14314 /* Compute how much we should try to scroll maximally to bring
14315 point into view. */
14316 scroll_max = (max (scroll_step,
14317 max (arg_scroll_conservatively, temp_scroll_step))
14318 * FRAME_LINE_HEIGHT (f));
14319 else if (NUMBERP (BVAR (current_buffer, scroll_down_aggressively))
14320 || NUMBERP (BVAR (current_buffer, scroll_up_aggressively)))
14321 /* We're trying to scroll because of aggressive scrolling but no
14322 scroll_step is set. Choose an arbitrary one. */
14323 scroll_max = 10 * FRAME_LINE_HEIGHT (f);
14324 else
14325 scroll_max = 0;
14326
14327 too_near_end:
14328
14329 /* Decide whether to scroll down. */
14330 if (PT > CHARPOS (startp))
14331 {
14332 int scroll_margin_y;
14333
14334 /* Compute the pixel ypos of the scroll margin, then move it to
14335 either that ypos or PT, whichever comes first. */
14336 start_display (&it, w, startp);
14337 scroll_margin_y = it.last_visible_y - this_scroll_margin
14338 - FRAME_LINE_HEIGHT (f) * extra_scroll_margin_lines;
14339 move_it_to (&it, PT, -1, scroll_margin_y - 1, -1,
14340 (MOVE_TO_POS | MOVE_TO_Y));
14341
14342 if (PT > CHARPOS (it.current.pos))
14343 {
14344 int y0 = line_bottom_y (&it);
14345 /* Compute how many pixels below window bottom to stop searching
14346 for PT. This avoids costly search for PT that is far away if
14347 the user limited scrolling by a small number of lines, but
14348 always finds PT if scroll_conservatively is set to a large
14349 number, such as most-positive-fixnum. */
14350 int slack = max (scroll_max, 10 * FRAME_LINE_HEIGHT (f));
14351 int y_to_move = it.last_visible_y + slack;
14352
14353 /* Compute the distance from the scroll margin to PT or to
14354 the scroll limit, whichever comes first. This should
14355 include the height of the cursor line, to make that line
14356 fully visible. */
14357 move_it_to (&it, PT, -1, y_to_move,
14358 -1, MOVE_TO_POS | MOVE_TO_Y);
14359 dy = line_bottom_y (&it) - y0;
14360
14361 if (dy > scroll_max)
14362 return SCROLLING_FAILED;
14363
14364 scroll_down_p = 1;
14365 }
14366 }
14367
14368 if (scroll_down_p)
14369 {
14370 /* Point is in or below the bottom scroll margin, so move the
14371 window start down. If scrolling conservatively, move it just
14372 enough down to make point visible. If scroll_step is set,
14373 move it down by scroll_step. */
14374 if (arg_scroll_conservatively)
14375 amount_to_scroll
14376 = min (max (dy, FRAME_LINE_HEIGHT (f)),
14377 FRAME_LINE_HEIGHT (f) * arg_scroll_conservatively);
14378 else if (scroll_step || temp_scroll_step)
14379 amount_to_scroll = scroll_max;
14380 else
14381 {
14382 aggressive = BVAR (current_buffer, scroll_up_aggressively);
14383 height = WINDOW_BOX_TEXT_HEIGHT (w);
14384 if (NUMBERP (aggressive))
14385 {
14386 double float_amount = XFLOATINT (aggressive) * height;
14387 amount_to_scroll = float_amount;
14388 if (amount_to_scroll == 0 && float_amount > 0)
14389 amount_to_scroll = 1;
14390 /* Don't let point enter the scroll margin near top of
14391 the window. */
14392 if (amount_to_scroll > height - 2*this_scroll_margin + dy)
14393 amount_to_scroll = height - 2*this_scroll_margin + dy;
14394 }
14395 }
14396
14397 if (amount_to_scroll <= 0)
14398 return SCROLLING_FAILED;
14399
14400 start_display (&it, w, startp);
14401 if (arg_scroll_conservatively <= scroll_limit)
14402 move_it_vertically (&it, amount_to_scroll);
14403 else
14404 {
14405 /* Extra precision for users who set scroll-conservatively
14406 to a large number: make sure the amount we scroll
14407 the window start is never less than amount_to_scroll,
14408 which was computed as distance from window bottom to
14409 point. This matters when lines at window top and lines
14410 below window bottom have different height. */
14411 struct it it1;
14412 void *it1data = NULL;
14413 /* We use a temporary it1 because line_bottom_y can modify
14414 its argument, if it moves one line down; see there. */
14415 int start_y;
14416
14417 SAVE_IT (it1, it, it1data);
14418 start_y = line_bottom_y (&it1);
14419 do {
14420 RESTORE_IT (&it, &it, it1data);
14421 move_it_by_lines (&it, 1);
14422 SAVE_IT (it1, it, it1data);
14423 } while (line_bottom_y (&it1) - start_y < amount_to_scroll);
14424 }
14425
14426 /* If STARTP is unchanged, move it down another screen line. */
14427 if (CHARPOS (it.current.pos) == CHARPOS (startp))
14428 move_it_by_lines (&it, 1);
14429 startp = it.current.pos;
14430 }
14431 else
14432 {
14433 struct text_pos scroll_margin_pos = startp;
14434
14435 /* See if point is inside the scroll margin at the top of the
14436 window. */
14437 if (this_scroll_margin)
14438 {
14439 start_display (&it, w, startp);
14440 move_it_vertically (&it, this_scroll_margin);
14441 scroll_margin_pos = it.current.pos;
14442 }
14443
14444 if (PT < CHARPOS (scroll_margin_pos))
14445 {
14446 /* Point is in the scroll margin at the top of the window or
14447 above what is displayed in the window. */
14448 int y0, y_to_move;
14449
14450 /* Compute the vertical distance from PT to the scroll
14451 margin position. Move as far as scroll_max allows, or
14452 one screenful, or 10 screen lines, whichever is largest.
14453 Give up if distance is greater than scroll_max. */
14454 SET_TEXT_POS (pos, PT, PT_BYTE);
14455 start_display (&it, w, pos);
14456 y0 = it.current_y;
14457 y_to_move = max (it.last_visible_y,
14458 max (scroll_max, 10 * FRAME_LINE_HEIGHT (f)));
14459 move_it_to (&it, CHARPOS (scroll_margin_pos), 0,
14460 y_to_move, -1,
14461 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
14462 dy = it.current_y - y0;
14463 if (dy > scroll_max)
14464 return SCROLLING_FAILED;
14465
14466 /* Compute new window start. */
14467 start_display (&it, w, startp);
14468
14469 if (arg_scroll_conservatively)
14470 amount_to_scroll = max (dy, FRAME_LINE_HEIGHT (f) *
14471 max (scroll_step, temp_scroll_step));
14472 else if (scroll_step || temp_scroll_step)
14473 amount_to_scroll = scroll_max;
14474 else
14475 {
14476 aggressive = BVAR (current_buffer, scroll_down_aggressively);
14477 height = WINDOW_BOX_TEXT_HEIGHT (w);
14478 if (NUMBERP (aggressive))
14479 {
14480 double float_amount = XFLOATINT (aggressive) * height;
14481 amount_to_scroll = float_amount;
14482 if (amount_to_scroll == 0 && float_amount > 0)
14483 amount_to_scroll = 1;
14484 amount_to_scroll -=
14485 this_scroll_margin - dy - FRAME_LINE_HEIGHT (f);
14486 /* Don't let point enter the scroll margin near
14487 bottom of the window. */
14488 if (amount_to_scroll > height - 2*this_scroll_margin + dy)
14489 amount_to_scroll = height - 2*this_scroll_margin + dy;
14490 }
14491 }
14492
14493 if (amount_to_scroll <= 0)
14494 return SCROLLING_FAILED;
14495
14496 move_it_vertically_backward (&it, amount_to_scroll);
14497 startp = it.current.pos;
14498 }
14499 }
14500
14501 /* Run window scroll functions. */
14502 startp = run_window_scroll_functions (window, startp);
14503
14504 /* Display the window. Give up if new fonts are loaded, or if point
14505 doesn't appear. */
14506 if (!try_window (window, startp, 0))
14507 rc = SCROLLING_NEED_LARGER_MATRICES;
14508 else if (w->cursor.vpos < 0)
14509 {
14510 clear_glyph_matrix (w->desired_matrix);
14511 rc = SCROLLING_FAILED;
14512 }
14513 else
14514 {
14515 /* Maybe forget recorded base line for line number display. */
14516 if (!just_this_one_p
14517 || current_buffer->clip_changed
14518 || BEG_UNCHANGED < CHARPOS (startp))
14519 w->base_line_number = Qnil;
14520
14521 /* If cursor ends up on a partially visible line,
14522 treat that as being off the bottom of the screen. */
14523 if (! cursor_row_fully_visible_p (w, extra_scroll_margin_lines <= 1, 0)
14524 /* It's possible that the cursor is on the first line of the
14525 buffer, which is partially obscured due to a vscroll
14526 (Bug#7537). In that case, avoid looping forever . */
14527 && extra_scroll_margin_lines < w->desired_matrix->nrows - 1)
14528 {
14529 clear_glyph_matrix (w->desired_matrix);
14530 ++extra_scroll_margin_lines;
14531 goto too_near_end;
14532 }
14533 rc = SCROLLING_SUCCESS;
14534 }
14535
14536 return rc;
14537 }
14538
14539
14540 /* Compute a suitable window start for window W if display of W starts
14541 on a continuation line. Value is non-zero if a new window start
14542 was computed.
14543
14544 The new window start will be computed, based on W's width, starting
14545 from the start of the continued line. It is the start of the
14546 screen line with the minimum distance from the old start W->start. */
14547
14548 static int
14549 compute_window_start_on_continuation_line (struct window *w)
14550 {
14551 struct text_pos pos, start_pos;
14552 int window_start_changed_p = 0;
14553
14554 SET_TEXT_POS_FROM_MARKER (start_pos, w->start);
14555
14556 /* If window start is on a continuation line... Window start may be
14557 < BEGV in case there's invisible text at the start of the
14558 buffer (M-x rmail, for example). */
14559 if (CHARPOS (start_pos) > BEGV
14560 && FETCH_BYTE (BYTEPOS (start_pos) - 1) != '\n')
14561 {
14562 struct it it;
14563 struct glyph_row *row;
14564
14565 /* Handle the case that the window start is out of range. */
14566 if (CHARPOS (start_pos) < BEGV)
14567 SET_TEXT_POS (start_pos, BEGV, BEGV_BYTE);
14568 else if (CHARPOS (start_pos) > ZV)
14569 SET_TEXT_POS (start_pos, ZV, ZV_BYTE);
14570
14571 /* Find the start of the continued line. This should be fast
14572 because scan_buffer is fast (newline cache). */
14573 row = w->desired_matrix->rows + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0);
14574 init_iterator (&it, w, CHARPOS (start_pos), BYTEPOS (start_pos),
14575 row, DEFAULT_FACE_ID);
14576 reseat_at_previous_visible_line_start (&it);
14577
14578 /* If the line start is "too far" away from the window start,
14579 say it takes too much time to compute a new window start. */
14580 if (CHARPOS (start_pos) - IT_CHARPOS (it)
14581 < WINDOW_TOTAL_LINES (w) * WINDOW_TOTAL_COLS (w))
14582 {
14583 int min_distance, distance;
14584
14585 /* Move forward by display lines to find the new window
14586 start. If window width was enlarged, the new start can
14587 be expected to be > the old start. If window width was
14588 decreased, the new window start will be < the old start.
14589 So, we're looking for the display line start with the
14590 minimum distance from the old window start. */
14591 pos = it.current.pos;
14592 min_distance = INFINITY;
14593 while ((distance = eabs (CHARPOS (start_pos) - IT_CHARPOS (it))),
14594 distance < min_distance)
14595 {
14596 min_distance = distance;
14597 pos = it.current.pos;
14598 move_it_by_lines (&it, 1);
14599 }
14600
14601 /* Set the window start there. */
14602 SET_MARKER_FROM_TEXT_POS (w->start, pos);
14603 window_start_changed_p = 1;
14604 }
14605 }
14606
14607 return window_start_changed_p;
14608 }
14609
14610
14611 /* Try cursor movement in case text has not changed in window WINDOW,
14612 with window start STARTP. Value is
14613
14614 CURSOR_MOVEMENT_SUCCESS if successful
14615
14616 CURSOR_MOVEMENT_CANNOT_BE_USED if this method cannot be used
14617
14618 CURSOR_MOVEMENT_MUST_SCROLL if we know we have to scroll the
14619 display. *SCROLL_STEP is set to 1, under certain circumstances, if
14620 we want to scroll as if scroll-step were set to 1. See the code.
14621
14622 CURSOR_MOVEMENT_NEED_LARGER_MATRICES if we need larger matrices, in
14623 which case we have to abort this redisplay, and adjust matrices
14624 first. */
14625
14626 enum
14627 {
14628 CURSOR_MOVEMENT_SUCCESS,
14629 CURSOR_MOVEMENT_CANNOT_BE_USED,
14630 CURSOR_MOVEMENT_MUST_SCROLL,
14631 CURSOR_MOVEMENT_NEED_LARGER_MATRICES
14632 };
14633
14634 static int
14635 try_cursor_movement (Lisp_Object window, struct text_pos startp, int *scroll_step)
14636 {
14637 struct window *w = XWINDOW (window);
14638 struct frame *f = XFRAME (w->frame);
14639 int rc = CURSOR_MOVEMENT_CANNOT_BE_USED;
14640
14641 #if GLYPH_DEBUG
14642 if (inhibit_try_cursor_movement)
14643 return rc;
14644 #endif
14645
14646 /* Handle case where text has not changed, only point, and it has
14647 not moved off the frame. */
14648 if (/* Point may be in this window. */
14649 PT >= CHARPOS (startp)
14650 /* Selective display hasn't changed. */
14651 && !current_buffer->clip_changed
14652 /* Function force-mode-line-update is used to force a thorough
14653 redisplay. It sets either windows_or_buffers_changed or
14654 update_mode_lines. So don't take a shortcut here for these
14655 cases. */
14656 && !update_mode_lines
14657 && !windows_or_buffers_changed
14658 && !cursor_type_changed
14659 /* Can't use this case if highlighting a region. When a
14660 region exists, cursor movement has to do more than just
14661 set the cursor. */
14662 && !(!NILP (Vtransient_mark_mode)
14663 && !NILP (BVAR (current_buffer, mark_active)))
14664 && NILP (w->region_showing)
14665 && NILP (Vshow_trailing_whitespace)
14666 /* Right after splitting windows, last_point may be nil. */
14667 && INTEGERP (w->last_point)
14668 /* This code is not used for mini-buffer for the sake of the case
14669 of redisplaying to replace an echo area message; since in
14670 that case the mini-buffer contents per se are usually
14671 unchanged. This code is of no real use in the mini-buffer
14672 since the handling of this_line_start_pos, etc., in redisplay
14673 handles the same cases. */
14674 && !EQ (window, minibuf_window)
14675 /* When splitting windows or for new windows, it happens that
14676 redisplay is called with a nil window_end_vpos or one being
14677 larger than the window. This should really be fixed in
14678 window.c. I don't have this on my list, now, so we do
14679 approximately the same as the old redisplay code. --gerd. */
14680 && INTEGERP (w->window_end_vpos)
14681 && XFASTINT (w->window_end_vpos) < w->current_matrix->nrows
14682 && (FRAME_WINDOW_P (f)
14683 || !overlay_arrow_in_current_buffer_p ()))
14684 {
14685 int this_scroll_margin, top_scroll_margin;
14686 struct glyph_row *row = NULL;
14687
14688 #if GLYPH_DEBUG
14689 debug_method_add (w, "cursor movement");
14690 #endif
14691
14692 /* Scroll if point within this distance from the top or bottom
14693 of the window. This is a pixel value. */
14694 if (scroll_margin > 0)
14695 {
14696 this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
14697 this_scroll_margin *= FRAME_LINE_HEIGHT (f);
14698 }
14699 else
14700 this_scroll_margin = 0;
14701
14702 top_scroll_margin = this_scroll_margin;
14703 if (WINDOW_WANTS_HEADER_LINE_P (w))
14704 top_scroll_margin += CURRENT_HEADER_LINE_HEIGHT (w);
14705
14706 /* Start with the row the cursor was displayed during the last
14707 not paused redisplay. Give up if that row is not valid. */
14708 if (w->last_cursor.vpos < 0
14709 || w->last_cursor.vpos >= w->current_matrix->nrows)
14710 rc = CURSOR_MOVEMENT_MUST_SCROLL;
14711 else
14712 {
14713 row = MATRIX_ROW (w->current_matrix, w->last_cursor.vpos);
14714 if (row->mode_line_p)
14715 ++row;
14716 if (!row->enabled_p)
14717 rc = CURSOR_MOVEMENT_MUST_SCROLL;
14718 }
14719
14720 if (rc == CURSOR_MOVEMENT_CANNOT_BE_USED)
14721 {
14722 int scroll_p = 0, must_scroll = 0;
14723 int last_y = window_text_bottom_y (w) - this_scroll_margin;
14724
14725 if (PT > XFASTINT (w->last_point))
14726 {
14727 /* Point has moved forward. */
14728 while (MATRIX_ROW_END_CHARPOS (row) < PT
14729 && MATRIX_ROW_BOTTOM_Y (row) < last_y)
14730 {
14731 xassert (row->enabled_p);
14732 ++row;
14733 }
14734
14735 /* If the end position of a row equals the start
14736 position of the next row, and PT is at that position,
14737 we would rather display cursor in the next line. */
14738 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
14739 && MATRIX_ROW_END_CHARPOS (row) == PT
14740 && row < w->current_matrix->rows
14741 + w->current_matrix->nrows - 1
14742 && MATRIX_ROW_START_CHARPOS (row+1) == PT
14743 && !cursor_row_p (row))
14744 ++row;
14745
14746 /* If within the scroll margin, scroll. Note that
14747 MATRIX_ROW_BOTTOM_Y gives the pixel position at which
14748 the next line would be drawn, and that
14749 this_scroll_margin can be zero. */
14750 if (MATRIX_ROW_BOTTOM_Y (row) > last_y
14751 || PT > MATRIX_ROW_END_CHARPOS (row)
14752 /* Line is completely visible last line in window
14753 and PT is to be set in the next line. */
14754 || (MATRIX_ROW_BOTTOM_Y (row) == last_y
14755 && PT == MATRIX_ROW_END_CHARPOS (row)
14756 && !row->ends_at_zv_p
14757 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
14758 scroll_p = 1;
14759 }
14760 else if (PT < XFASTINT (w->last_point))
14761 {
14762 /* Cursor has to be moved backward. Note that PT >=
14763 CHARPOS (startp) because of the outer if-statement. */
14764 while (!row->mode_line_p
14765 && (MATRIX_ROW_START_CHARPOS (row) > PT
14766 || (MATRIX_ROW_START_CHARPOS (row) == PT
14767 && (MATRIX_ROW_STARTS_IN_MIDDLE_OF_CHAR_P (row)
14768 || (/* STARTS_IN_MIDDLE_OF_STRING_P (row) */
14769 row > w->current_matrix->rows
14770 && (row-1)->ends_in_newline_from_string_p))))
14771 && (row->y > top_scroll_margin
14772 || CHARPOS (startp) == BEGV))
14773 {
14774 xassert (row->enabled_p);
14775 --row;
14776 }
14777
14778 /* Consider the following case: Window starts at BEGV,
14779 there is invisible, intangible text at BEGV, so that
14780 display starts at some point START > BEGV. It can
14781 happen that we are called with PT somewhere between
14782 BEGV and START. Try to handle that case. */
14783 if (row < w->current_matrix->rows
14784 || row->mode_line_p)
14785 {
14786 row = w->current_matrix->rows;
14787 if (row->mode_line_p)
14788 ++row;
14789 }
14790
14791 /* Due to newlines in overlay strings, we may have to
14792 skip forward over overlay strings. */
14793 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
14794 && MATRIX_ROW_END_CHARPOS (row) == PT
14795 && !cursor_row_p (row))
14796 ++row;
14797
14798 /* If within the scroll margin, scroll. */
14799 if (row->y < top_scroll_margin
14800 && CHARPOS (startp) != BEGV)
14801 scroll_p = 1;
14802 }
14803 else
14804 {
14805 /* Cursor did not move. So don't scroll even if cursor line
14806 is partially visible, as it was so before. */
14807 rc = CURSOR_MOVEMENT_SUCCESS;
14808 }
14809
14810 if (PT < MATRIX_ROW_START_CHARPOS (row)
14811 || PT > MATRIX_ROW_END_CHARPOS (row))
14812 {
14813 /* if PT is not in the glyph row, give up. */
14814 rc = CURSOR_MOVEMENT_MUST_SCROLL;
14815 must_scroll = 1;
14816 }
14817 else if (rc != CURSOR_MOVEMENT_SUCCESS
14818 && !NILP (BVAR (XBUFFER (w->buffer), bidi_display_reordering)))
14819 {
14820 /* If rows are bidi-reordered and point moved, back up
14821 until we find a row that does not belong to a
14822 continuation line. This is because we must consider
14823 all rows of a continued line as candidates for the
14824 new cursor positioning, since row start and end
14825 positions change non-linearly with vertical position
14826 in such rows. */
14827 /* FIXME: Revisit this when glyph ``spilling'' in
14828 continuation lines' rows is implemented for
14829 bidi-reordered rows. */
14830 while (MATRIX_ROW_CONTINUATION_LINE_P (row))
14831 {
14832 xassert (row->enabled_p);
14833 --row;
14834 /* If we hit the beginning of the displayed portion
14835 without finding the first row of a continued
14836 line, give up. */
14837 if (row <= w->current_matrix->rows)
14838 {
14839 rc = CURSOR_MOVEMENT_MUST_SCROLL;
14840 break;
14841 }
14842
14843 }
14844 }
14845 if (must_scroll)
14846 ;
14847 else if (rc != CURSOR_MOVEMENT_SUCCESS
14848 && MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row)
14849 && make_cursor_line_fully_visible_p)
14850 {
14851 if (PT == MATRIX_ROW_END_CHARPOS (row)
14852 && !row->ends_at_zv_p
14853 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
14854 rc = CURSOR_MOVEMENT_MUST_SCROLL;
14855 else if (row->height > window_box_height (w))
14856 {
14857 /* If we end up in a partially visible line, let's
14858 make it fully visible, except when it's taller
14859 than the window, in which case we can't do much
14860 about it. */
14861 *scroll_step = 1;
14862 rc = CURSOR_MOVEMENT_MUST_SCROLL;
14863 }
14864 else
14865 {
14866 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
14867 if (!cursor_row_fully_visible_p (w, 0, 1))
14868 rc = CURSOR_MOVEMENT_MUST_SCROLL;
14869 else
14870 rc = CURSOR_MOVEMENT_SUCCESS;
14871 }
14872 }
14873 else if (scroll_p)
14874 rc = CURSOR_MOVEMENT_MUST_SCROLL;
14875 else if (rc != CURSOR_MOVEMENT_SUCCESS
14876 && !NILP (BVAR (XBUFFER (w->buffer), bidi_display_reordering)))
14877 {
14878 /* With bidi-reordered rows, there could be more than
14879 one candidate row whose start and end positions
14880 occlude point. We need to let set_cursor_from_row
14881 find the best candidate. */
14882 /* FIXME: Revisit this when glyph ``spilling'' in
14883 continuation lines' rows is implemented for
14884 bidi-reordered rows. */
14885 int rv = 0;
14886
14887 do
14888 {
14889 int at_zv_p = 0, exact_match_p = 0;
14890
14891 if (MATRIX_ROW_START_CHARPOS (row) <= PT
14892 && PT <= MATRIX_ROW_END_CHARPOS (row)
14893 && cursor_row_p (row))
14894 rv |= set_cursor_from_row (w, row, w->current_matrix,
14895 0, 0, 0, 0);
14896 /* As soon as we've found the exact match for point,
14897 or the first suitable row whose ends_at_zv_p flag
14898 is set, we are done. */
14899 at_zv_p =
14900 MATRIX_ROW (w->current_matrix, w->cursor.vpos)->ends_at_zv_p;
14901 if (rv && !at_zv_p
14902 && w->cursor.hpos >= 0
14903 && w->cursor.hpos < MATRIX_ROW_USED (w->current_matrix,
14904 w->cursor.vpos))
14905 {
14906 struct glyph_row *candidate =
14907 MATRIX_ROW (w->current_matrix, w->cursor.vpos);
14908 struct glyph *g =
14909 candidate->glyphs[TEXT_AREA] + w->cursor.hpos;
14910 EMACS_INT endpos = MATRIX_ROW_END_CHARPOS (candidate);
14911
14912 exact_match_p =
14913 (BUFFERP (g->object) && g->charpos == PT)
14914 || (INTEGERP (g->object)
14915 && (g->charpos == PT
14916 || (g->charpos == 0 && endpos - 1 == PT)));
14917 }
14918 if (rv && (at_zv_p || exact_match_p))
14919 {
14920 rc = CURSOR_MOVEMENT_SUCCESS;
14921 break;
14922 }
14923 if (MATRIX_ROW_BOTTOM_Y (row) == last_y)
14924 break;
14925 ++row;
14926 }
14927 while (((MATRIX_ROW_CONTINUATION_LINE_P (row)
14928 || row->continued_p)
14929 && MATRIX_ROW_BOTTOM_Y (row) <= last_y)
14930 || (MATRIX_ROW_START_CHARPOS (row) == PT
14931 && MATRIX_ROW_BOTTOM_Y (row) < last_y));
14932 /* If we didn't find any candidate rows, or exited the
14933 loop before all the candidates were examined, signal
14934 to the caller that this method failed. */
14935 if (rc != CURSOR_MOVEMENT_SUCCESS
14936 && !(rv
14937 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
14938 && !row->continued_p))
14939 rc = CURSOR_MOVEMENT_MUST_SCROLL;
14940 else if (rv)
14941 rc = CURSOR_MOVEMENT_SUCCESS;
14942 }
14943 else
14944 {
14945 do
14946 {
14947 if (set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0))
14948 {
14949 rc = CURSOR_MOVEMENT_SUCCESS;
14950 break;
14951 }
14952 ++row;
14953 }
14954 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
14955 && MATRIX_ROW_START_CHARPOS (row) == PT
14956 && cursor_row_p (row));
14957 }
14958 }
14959 }
14960
14961 return rc;
14962 }
14963
14964 #if !defined USE_TOOLKIT_SCROLL_BARS || defined USE_GTK
14965 static
14966 #endif
14967 void
14968 set_vertical_scroll_bar (struct window *w)
14969 {
14970 EMACS_INT start, end, whole;
14971
14972 /* Calculate the start and end positions for the current window.
14973 At some point, it would be nice to choose between scrollbars
14974 which reflect the whole buffer size, with special markers
14975 indicating narrowing, and scrollbars which reflect only the
14976 visible region.
14977
14978 Note that mini-buffers sometimes aren't displaying any text. */
14979 if (!MINI_WINDOW_P (w)
14980 || (w == XWINDOW (minibuf_window)
14981 && NILP (echo_area_buffer[0])))
14982 {
14983 struct buffer *buf = XBUFFER (w->buffer);
14984 whole = BUF_ZV (buf) - BUF_BEGV (buf);
14985 start = marker_position (w->start) - BUF_BEGV (buf);
14986 /* I don't think this is guaranteed to be right. For the
14987 moment, we'll pretend it is. */
14988 end = BUF_Z (buf) - XFASTINT (w->window_end_pos) - BUF_BEGV (buf);
14989
14990 if (end < start)
14991 end = start;
14992 if (whole < (end - start))
14993 whole = end - start;
14994 }
14995 else
14996 start = end = whole = 0;
14997
14998 /* Indicate what this scroll bar ought to be displaying now. */
14999 if (FRAME_TERMINAL (XFRAME (w->frame))->set_vertical_scroll_bar_hook)
15000 (*FRAME_TERMINAL (XFRAME (w->frame))->set_vertical_scroll_bar_hook)
15001 (w, end - start, whole, start);
15002 }
15003
15004
15005 /* Redisplay leaf window WINDOW. JUST_THIS_ONE_P non-zero means only
15006 selected_window is redisplayed.
15007
15008 We can return without actually redisplaying the window if
15009 fonts_changed_p is nonzero. In that case, redisplay_internal will
15010 retry. */
15011
15012 static void
15013 redisplay_window (Lisp_Object window, int just_this_one_p)
15014 {
15015 struct window *w = XWINDOW (window);
15016 struct frame *f = XFRAME (w->frame);
15017 struct buffer *buffer = XBUFFER (w->buffer);
15018 struct buffer *old = current_buffer;
15019 struct text_pos lpoint, opoint, startp;
15020 int update_mode_line;
15021 int tem;
15022 struct it it;
15023 /* Record it now because it's overwritten. */
15024 int current_matrix_up_to_date_p = 0;
15025 int used_current_matrix_p = 0;
15026 /* This is less strict than current_matrix_up_to_date_p.
15027 It indictes that the buffer contents and narrowing are unchanged. */
15028 int buffer_unchanged_p = 0;
15029 int temp_scroll_step = 0;
15030 int count = SPECPDL_INDEX ();
15031 int rc;
15032 int centering_position = -1;
15033 int last_line_misfit = 0;
15034 EMACS_INT beg_unchanged, end_unchanged;
15035
15036 SET_TEXT_POS (lpoint, PT, PT_BYTE);
15037 opoint = lpoint;
15038
15039 /* W must be a leaf window here. */
15040 xassert (!NILP (w->buffer));
15041 #if GLYPH_DEBUG
15042 *w->desired_matrix->method = 0;
15043 #endif
15044
15045 restart:
15046 reconsider_clip_changes (w, buffer);
15047
15048 /* Has the mode line to be updated? */
15049 update_mode_line = (!NILP (w->update_mode_line)
15050 || update_mode_lines
15051 || buffer->clip_changed
15052 || buffer->prevent_redisplay_optimizations_p);
15053
15054 if (MINI_WINDOW_P (w))
15055 {
15056 if (w == XWINDOW (echo_area_window)
15057 && !NILP (echo_area_buffer[0]))
15058 {
15059 if (update_mode_line)
15060 /* We may have to update a tty frame's menu bar or a
15061 tool-bar. Example `M-x C-h C-h C-g'. */
15062 goto finish_menu_bars;
15063 else
15064 /* We've already displayed the echo area glyphs in this window. */
15065 goto finish_scroll_bars;
15066 }
15067 else if ((w != XWINDOW (minibuf_window)
15068 || minibuf_level == 0)
15069 /* When buffer is nonempty, redisplay window normally. */
15070 && BUF_Z (XBUFFER (w->buffer)) == BUF_BEG (XBUFFER (w->buffer))
15071 /* Quail displays non-mini buffers in minibuffer window.
15072 In that case, redisplay the window normally. */
15073 && !NILP (Fmemq (w->buffer, Vminibuffer_list)))
15074 {
15075 /* W is a mini-buffer window, but it's not active, so clear
15076 it. */
15077 int yb = window_text_bottom_y (w);
15078 struct glyph_row *row;
15079 int y;
15080
15081 for (y = 0, row = w->desired_matrix->rows;
15082 y < yb;
15083 y += row->height, ++row)
15084 blank_row (w, row, y);
15085 goto finish_scroll_bars;
15086 }
15087
15088 clear_glyph_matrix (w->desired_matrix);
15089 }
15090
15091 /* Otherwise set up data on this window; select its buffer and point
15092 value. */
15093 /* Really select the buffer, for the sake of buffer-local
15094 variables. */
15095 set_buffer_internal_1 (XBUFFER (w->buffer));
15096
15097 current_matrix_up_to_date_p
15098 = (!NILP (w->window_end_valid)
15099 && !current_buffer->clip_changed
15100 && !current_buffer->prevent_redisplay_optimizations_p
15101 && XFASTINT (w->last_modified) >= MODIFF
15102 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
15103
15104 /* Run the window-bottom-change-functions
15105 if it is possible that the text on the screen has changed
15106 (either due to modification of the text, or any other reason). */
15107 if (!current_matrix_up_to_date_p
15108 && !NILP (Vwindow_text_change_functions))
15109 {
15110 safe_run_hooks (Qwindow_text_change_functions);
15111 goto restart;
15112 }
15113
15114 beg_unchanged = BEG_UNCHANGED;
15115 end_unchanged = END_UNCHANGED;
15116
15117 SET_TEXT_POS (opoint, PT, PT_BYTE);
15118
15119 specbind (Qinhibit_point_motion_hooks, Qt);
15120
15121 buffer_unchanged_p
15122 = (!NILP (w->window_end_valid)
15123 && !current_buffer->clip_changed
15124 && XFASTINT (w->last_modified) >= MODIFF
15125 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
15126
15127 /* When windows_or_buffers_changed is non-zero, we can't rely on
15128 the window end being valid, so set it to nil there. */
15129 if (windows_or_buffers_changed)
15130 {
15131 /* If window starts on a continuation line, maybe adjust the
15132 window start in case the window's width changed. */
15133 if (XMARKER (w->start)->buffer == current_buffer)
15134 compute_window_start_on_continuation_line (w);
15135
15136 w->window_end_valid = Qnil;
15137 }
15138
15139 /* Some sanity checks. */
15140 CHECK_WINDOW_END (w);
15141 if (Z == Z_BYTE && CHARPOS (opoint) != BYTEPOS (opoint))
15142 abort ();
15143 if (BYTEPOS (opoint) < CHARPOS (opoint))
15144 abort ();
15145
15146 /* If %c is in mode line, update it if needed. */
15147 if (!NILP (w->column_number_displayed)
15148 /* This alternative quickly identifies a common case
15149 where no change is needed. */
15150 && !(PT == XFASTINT (w->last_point)
15151 && XFASTINT (w->last_modified) >= MODIFF
15152 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
15153 && (XFASTINT (w->column_number_displayed) != current_column ()))
15154 update_mode_line = 1;
15155
15156 /* Count number of windows showing the selected buffer. An indirect
15157 buffer counts as its base buffer. */
15158 if (!just_this_one_p)
15159 {
15160 struct buffer *current_base, *window_base;
15161 current_base = current_buffer;
15162 window_base = XBUFFER (XWINDOW (selected_window)->buffer);
15163 if (current_base->base_buffer)
15164 current_base = current_base->base_buffer;
15165 if (window_base->base_buffer)
15166 window_base = window_base->base_buffer;
15167 if (current_base == window_base)
15168 buffer_shared++;
15169 }
15170
15171 /* Point refers normally to the selected window. For any other
15172 window, set up appropriate value. */
15173 if (!EQ (window, selected_window))
15174 {
15175 EMACS_INT new_pt = XMARKER (w->pointm)->charpos;
15176 EMACS_INT new_pt_byte = marker_byte_position (w->pointm);
15177 if (new_pt < BEGV)
15178 {
15179 new_pt = BEGV;
15180 new_pt_byte = BEGV_BYTE;
15181 set_marker_both (w->pointm, Qnil, BEGV, BEGV_BYTE);
15182 }
15183 else if (new_pt > (ZV - 1))
15184 {
15185 new_pt = ZV;
15186 new_pt_byte = ZV_BYTE;
15187 set_marker_both (w->pointm, Qnil, ZV, ZV_BYTE);
15188 }
15189
15190 /* We don't use SET_PT so that the point-motion hooks don't run. */
15191 TEMP_SET_PT_BOTH (new_pt, new_pt_byte);
15192 }
15193
15194 /* If any of the character widths specified in the display table
15195 have changed, invalidate the width run cache. It's true that
15196 this may be a bit late to catch such changes, but the rest of
15197 redisplay goes (non-fatally) haywire when the display table is
15198 changed, so why should we worry about doing any better? */
15199 if (current_buffer->width_run_cache)
15200 {
15201 struct Lisp_Char_Table *disptab = buffer_display_table ();
15202
15203 if (! disptab_matches_widthtab (disptab,
15204 XVECTOR (BVAR (current_buffer, width_table))))
15205 {
15206 invalidate_region_cache (current_buffer,
15207 current_buffer->width_run_cache,
15208 BEG, Z);
15209 recompute_width_table (current_buffer, disptab);
15210 }
15211 }
15212
15213 /* If window-start is screwed up, choose a new one. */
15214 if (XMARKER (w->start)->buffer != current_buffer)
15215 goto recenter;
15216
15217 SET_TEXT_POS_FROM_MARKER (startp, w->start);
15218
15219 /* If someone specified a new starting point but did not insist,
15220 check whether it can be used. */
15221 if (!NILP (w->optional_new_start)
15222 && CHARPOS (startp) >= BEGV
15223 && CHARPOS (startp) <= ZV)
15224 {
15225 w->optional_new_start = Qnil;
15226 start_display (&it, w, startp);
15227 move_it_to (&it, PT, 0, it.last_visible_y, -1,
15228 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
15229 if (IT_CHARPOS (it) == PT)
15230 w->force_start = Qt;
15231 /* IT may overshoot PT if text at PT is invisible. */
15232 else if (IT_CHARPOS (it) > PT && CHARPOS (startp) <= PT)
15233 w->force_start = Qt;
15234 }
15235
15236 force_start:
15237
15238 /* Handle case where place to start displaying has been specified,
15239 unless the specified location is outside the accessible range. */
15240 if (!NILP (w->force_start)
15241 || w->frozen_window_start_p)
15242 {
15243 /* We set this later on if we have to adjust point. */
15244 int new_vpos = -1;
15245
15246 w->force_start = Qnil;
15247 w->vscroll = 0;
15248 w->window_end_valid = Qnil;
15249
15250 /* Forget any recorded base line for line number display. */
15251 if (!buffer_unchanged_p)
15252 w->base_line_number = Qnil;
15253
15254 /* Redisplay the mode line. Select the buffer properly for that.
15255 Also, run the hook window-scroll-functions
15256 because we have scrolled. */
15257 /* Note, we do this after clearing force_start because
15258 if there's an error, it is better to forget about force_start
15259 than to get into an infinite loop calling the hook functions
15260 and having them get more errors. */
15261 if (!update_mode_line
15262 || ! NILP (Vwindow_scroll_functions))
15263 {
15264 update_mode_line = 1;
15265 w->update_mode_line = Qt;
15266 startp = run_window_scroll_functions (window, startp);
15267 }
15268
15269 w->last_modified = make_number (0);
15270 w->last_overlay_modified = make_number (0);
15271 if (CHARPOS (startp) < BEGV)
15272 SET_TEXT_POS (startp, BEGV, BEGV_BYTE);
15273 else if (CHARPOS (startp) > ZV)
15274 SET_TEXT_POS (startp, ZV, ZV_BYTE);
15275
15276 /* Redisplay, then check if cursor has been set during the
15277 redisplay. Give up if new fonts were loaded. */
15278 /* We used to issue a CHECK_MARGINS argument to try_window here,
15279 but this causes scrolling to fail when point begins inside
15280 the scroll margin (bug#148) -- cyd */
15281 if (!try_window (window, startp, 0))
15282 {
15283 w->force_start = Qt;
15284 clear_glyph_matrix (w->desired_matrix);
15285 goto need_larger_matrices;
15286 }
15287
15288 if (w->cursor.vpos < 0 && !w->frozen_window_start_p)
15289 {
15290 /* If point does not appear, try to move point so it does
15291 appear. The desired matrix has been built above, so we
15292 can use it here. */
15293 new_vpos = window_box_height (w) / 2;
15294 }
15295
15296 if (!cursor_row_fully_visible_p (w, 0, 0))
15297 {
15298 /* Point does appear, but on a line partly visible at end of window.
15299 Move it back to a fully-visible line. */
15300 new_vpos = window_box_height (w);
15301 }
15302
15303 /* If we need to move point for either of the above reasons,
15304 now actually do it. */
15305 if (new_vpos >= 0)
15306 {
15307 struct glyph_row *row;
15308
15309 row = MATRIX_FIRST_TEXT_ROW (w->desired_matrix);
15310 while (MATRIX_ROW_BOTTOM_Y (row) < new_vpos)
15311 ++row;
15312
15313 TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row),
15314 MATRIX_ROW_START_BYTEPOS (row));
15315
15316 if (w != XWINDOW (selected_window))
15317 set_marker_both (w->pointm, Qnil, PT, PT_BYTE);
15318 else if (current_buffer == old)
15319 SET_TEXT_POS (lpoint, PT, PT_BYTE);
15320
15321 set_cursor_from_row (w, row, w->desired_matrix, 0, 0, 0, 0);
15322
15323 /* If we are highlighting the region, then we just changed
15324 the region, so redisplay to show it. */
15325 if (!NILP (Vtransient_mark_mode)
15326 && !NILP (BVAR (current_buffer, mark_active)))
15327 {
15328 clear_glyph_matrix (w->desired_matrix);
15329 if (!try_window (window, startp, 0))
15330 goto need_larger_matrices;
15331 }
15332 }
15333
15334 #if GLYPH_DEBUG
15335 debug_method_add (w, "forced window start");
15336 #endif
15337 goto done;
15338 }
15339
15340 /* Handle case where text has not changed, only point, and it has
15341 not moved off the frame, and we are not retrying after hscroll.
15342 (current_matrix_up_to_date_p is nonzero when retrying.) */
15343 if (current_matrix_up_to_date_p
15344 && (rc = try_cursor_movement (window, startp, &temp_scroll_step),
15345 rc != CURSOR_MOVEMENT_CANNOT_BE_USED))
15346 {
15347 switch (rc)
15348 {
15349 case CURSOR_MOVEMENT_SUCCESS:
15350 used_current_matrix_p = 1;
15351 goto done;
15352
15353 case CURSOR_MOVEMENT_MUST_SCROLL:
15354 goto try_to_scroll;
15355
15356 default:
15357 abort ();
15358 }
15359 }
15360 /* If current starting point was originally the beginning of a line
15361 but no longer is, find a new starting point. */
15362 else if (!NILP (w->start_at_line_beg)
15363 && !(CHARPOS (startp) <= BEGV
15364 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n'))
15365 {
15366 #if GLYPH_DEBUG
15367 debug_method_add (w, "recenter 1");
15368 #endif
15369 goto recenter;
15370 }
15371
15372 /* Try scrolling with try_window_id. Value is > 0 if update has
15373 been done, it is -1 if we know that the same window start will
15374 not work. It is 0 if unsuccessful for some other reason. */
15375 else if ((tem = try_window_id (w)) != 0)
15376 {
15377 #if GLYPH_DEBUG
15378 debug_method_add (w, "try_window_id %d", tem);
15379 #endif
15380
15381 if (fonts_changed_p)
15382 goto need_larger_matrices;
15383 if (tem > 0)
15384 goto done;
15385
15386 /* Otherwise try_window_id has returned -1 which means that we
15387 don't want the alternative below this comment to execute. */
15388 }
15389 else if (CHARPOS (startp) >= BEGV
15390 && CHARPOS (startp) <= ZV
15391 && PT >= CHARPOS (startp)
15392 && (CHARPOS (startp) < ZV
15393 /* Avoid starting at end of buffer. */
15394 || CHARPOS (startp) == BEGV
15395 || (XFASTINT (w->last_modified) >= MODIFF
15396 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)))
15397 {
15398 int d1, d2, d3, d4, d5, d6;
15399
15400 /* If first window line is a continuation line, and window start
15401 is inside the modified region, but the first change is before
15402 current window start, we must select a new window start.
15403
15404 However, if this is the result of a down-mouse event (e.g. by
15405 extending the mouse-drag-overlay), we don't want to select a
15406 new window start, since that would change the position under
15407 the mouse, resulting in an unwanted mouse-movement rather
15408 than a simple mouse-click. */
15409 if (NILP (w->start_at_line_beg)
15410 && NILP (do_mouse_tracking)
15411 && CHARPOS (startp) > BEGV
15412 && CHARPOS (startp) > BEG + beg_unchanged
15413 && CHARPOS (startp) <= Z - end_unchanged
15414 /* Even if w->start_at_line_beg is nil, a new window may
15415 start at a line_beg, since that's how set_buffer_window
15416 sets it. So, we need to check the return value of
15417 compute_window_start_on_continuation_line. (See also
15418 bug#197). */
15419 && XMARKER (w->start)->buffer == current_buffer
15420 && compute_window_start_on_continuation_line (w)
15421 /* It doesn't make sense to force the window start like we
15422 do at label force_start if it is already known that point
15423 will not be visible in the resulting window, because
15424 doing so will move point from its correct position
15425 instead of scrolling the window to bring point into view.
15426 See bug#9324. */
15427 && pos_visible_p (w, PT, &d1, &d2, &d3, &d4, &d5, &d6))
15428 {
15429 w->force_start = Qt;
15430 SET_TEXT_POS_FROM_MARKER (startp, w->start);
15431 goto force_start;
15432 }
15433
15434 #if GLYPH_DEBUG
15435 debug_method_add (w, "same window start");
15436 #endif
15437
15438 /* Try to redisplay starting at same place as before.
15439 If point has not moved off frame, accept the results. */
15440 if (!current_matrix_up_to_date_p
15441 /* Don't use try_window_reusing_current_matrix in this case
15442 because a window scroll function can have changed the
15443 buffer. */
15444 || !NILP (Vwindow_scroll_functions)
15445 || MINI_WINDOW_P (w)
15446 || !(used_current_matrix_p
15447 = try_window_reusing_current_matrix (w)))
15448 {
15449 IF_DEBUG (debug_method_add (w, "1"));
15450 if (try_window (window, startp, TRY_WINDOW_CHECK_MARGINS) < 0)
15451 /* -1 means we need to scroll.
15452 0 means we need new matrices, but fonts_changed_p
15453 is set in that case, so we will detect it below. */
15454 goto try_to_scroll;
15455 }
15456
15457 if (fonts_changed_p)
15458 goto need_larger_matrices;
15459
15460 if (w->cursor.vpos >= 0)
15461 {
15462 if (!just_this_one_p
15463 || current_buffer->clip_changed
15464 || BEG_UNCHANGED < CHARPOS (startp))
15465 /* Forget any recorded base line for line number display. */
15466 w->base_line_number = Qnil;
15467
15468 if (!cursor_row_fully_visible_p (w, 1, 0))
15469 {
15470 clear_glyph_matrix (w->desired_matrix);
15471 last_line_misfit = 1;
15472 }
15473 /* Drop through and scroll. */
15474 else
15475 goto done;
15476 }
15477 else
15478 clear_glyph_matrix (w->desired_matrix);
15479 }
15480
15481 try_to_scroll:
15482
15483 w->last_modified = make_number (0);
15484 w->last_overlay_modified = make_number (0);
15485
15486 /* Redisplay the mode line. Select the buffer properly for that. */
15487 if (!update_mode_line)
15488 {
15489 update_mode_line = 1;
15490 w->update_mode_line = Qt;
15491 }
15492
15493 /* Try to scroll by specified few lines. */
15494 if ((scroll_conservatively
15495 || emacs_scroll_step
15496 || temp_scroll_step
15497 || NUMBERP (BVAR (current_buffer, scroll_up_aggressively))
15498 || NUMBERP (BVAR (current_buffer, scroll_down_aggressively)))
15499 && CHARPOS (startp) >= BEGV
15500 && CHARPOS (startp) <= ZV)
15501 {
15502 /* The function returns -1 if new fonts were loaded, 1 if
15503 successful, 0 if not successful. */
15504 int ss = try_scrolling (window, just_this_one_p,
15505 scroll_conservatively,
15506 emacs_scroll_step,
15507 temp_scroll_step, last_line_misfit);
15508 switch (ss)
15509 {
15510 case SCROLLING_SUCCESS:
15511 goto done;
15512
15513 case SCROLLING_NEED_LARGER_MATRICES:
15514 goto need_larger_matrices;
15515
15516 case SCROLLING_FAILED:
15517 break;
15518
15519 default:
15520 abort ();
15521 }
15522 }
15523
15524 /* Finally, just choose a place to start which positions point
15525 according to user preferences. */
15526
15527 recenter:
15528
15529 #if GLYPH_DEBUG
15530 debug_method_add (w, "recenter");
15531 #endif
15532
15533 /* w->vscroll = 0; */
15534
15535 /* Forget any previously recorded base line for line number display. */
15536 if (!buffer_unchanged_p)
15537 w->base_line_number = Qnil;
15538
15539 /* Determine the window start relative to point. */
15540 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
15541 it.current_y = it.last_visible_y;
15542 if (centering_position < 0)
15543 {
15544 int margin =
15545 scroll_margin > 0
15546 ? min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4)
15547 : 0;
15548 EMACS_INT margin_pos = CHARPOS (startp);
15549 int scrolling_up;
15550 Lisp_Object aggressive;
15551
15552 /* If there is a scroll margin at the top of the window, find
15553 its character position. */
15554 if (margin
15555 /* Cannot call start_display if startp is not in the
15556 accessible region of the buffer. This can happen when we
15557 have just switched to a different buffer and/or changed
15558 its restriction. In that case, startp is initialized to
15559 the character position 1 (BEG) because we did not yet
15560 have chance to display the buffer even once. */
15561 && BEGV <= CHARPOS (startp) && CHARPOS (startp) <= ZV)
15562 {
15563 struct it it1;
15564 void *it1data = NULL;
15565
15566 SAVE_IT (it1, it, it1data);
15567 start_display (&it1, w, startp);
15568 move_it_vertically (&it1, margin);
15569 margin_pos = IT_CHARPOS (it1);
15570 RESTORE_IT (&it, &it, it1data);
15571 }
15572 scrolling_up = PT > margin_pos;
15573 aggressive =
15574 scrolling_up
15575 ? BVAR (current_buffer, scroll_up_aggressively)
15576 : BVAR (current_buffer, scroll_down_aggressively);
15577
15578 if (!MINI_WINDOW_P (w)
15579 && (scroll_conservatively > SCROLL_LIMIT || NUMBERP (aggressive)))
15580 {
15581 int pt_offset = 0;
15582
15583 /* Setting scroll-conservatively overrides
15584 scroll-*-aggressively. */
15585 if (!scroll_conservatively && NUMBERP (aggressive))
15586 {
15587 double float_amount = XFLOATINT (aggressive);
15588
15589 pt_offset = float_amount * WINDOW_BOX_TEXT_HEIGHT (w);
15590 if (pt_offset == 0 && float_amount > 0)
15591 pt_offset = 1;
15592 if (pt_offset)
15593 margin -= 1;
15594 }
15595 /* Compute how much to move the window start backward from
15596 point so that point will be displayed where the user
15597 wants it. */
15598 if (scrolling_up)
15599 {
15600 centering_position = it.last_visible_y;
15601 if (pt_offset)
15602 centering_position -= pt_offset;
15603 centering_position -=
15604 FRAME_LINE_HEIGHT (f) * (1 + margin + (last_line_misfit != 0))
15605 + WINDOW_HEADER_LINE_HEIGHT (w);
15606 /* Don't let point enter the scroll margin near top of
15607 the window. */
15608 if (centering_position < margin * FRAME_LINE_HEIGHT (f))
15609 centering_position = margin * FRAME_LINE_HEIGHT (f);
15610 }
15611 else
15612 centering_position = margin * FRAME_LINE_HEIGHT (f) + pt_offset;
15613 }
15614 else
15615 /* Set the window start half the height of the window backward
15616 from point. */
15617 centering_position = window_box_height (w) / 2;
15618 }
15619 move_it_vertically_backward (&it, centering_position);
15620
15621 xassert (IT_CHARPOS (it) >= BEGV);
15622
15623 /* The function move_it_vertically_backward may move over more
15624 than the specified y-distance. If it->w is small, e.g. a
15625 mini-buffer window, we may end up in front of the window's
15626 display area. Start displaying at the start of the line
15627 containing PT in this case. */
15628 if (it.current_y <= 0)
15629 {
15630 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
15631 move_it_vertically_backward (&it, 0);
15632 it.current_y = 0;
15633 }
15634
15635 it.current_x = it.hpos = 0;
15636
15637 /* Set the window start position here explicitly, to avoid an
15638 infinite loop in case the functions in window-scroll-functions
15639 get errors. */
15640 set_marker_both (w->start, Qnil, IT_CHARPOS (it), IT_BYTEPOS (it));
15641
15642 /* Run scroll hooks. */
15643 startp = run_window_scroll_functions (window, it.current.pos);
15644
15645 /* Redisplay the window. */
15646 if (!current_matrix_up_to_date_p
15647 || windows_or_buffers_changed
15648 || cursor_type_changed
15649 /* Don't use try_window_reusing_current_matrix in this case
15650 because it can have changed the buffer. */
15651 || !NILP (Vwindow_scroll_functions)
15652 || !just_this_one_p
15653 || MINI_WINDOW_P (w)
15654 || !(used_current_matrix_p
15655 = try_window_reusing_current_matrix (w)))
15656 try_window (window, startp, 0);
15657
15658 /* If new fonts have been loaded (due to fontsets), give up. We
15659 have to start a new redisplay since we need to re-adjust glyph
15660 matrices. */
15661 if (fonts_changed_p)
15662 goto need_larger_matrices;
15663
15664 /* If cursor did not appear assume that the middle of the window is
15665 in the first line of the window. Do it again with the next line.
15666 (Imagine a window of height 100, displaying two lines of height
15667 60. Moving back 50 from it->last_visible_y will end in the first
15668 line.) */
15669 if (w->cursor.vpos < 0)
15670 {
15671 if (!NILP (w->window_end_valid)
15672 && PT >= Z - XFASTINT (w->window_end_pos))
15673 {
15674 clear_glyph_matrix (w->desired_matrix);
15675 move_it_by_lines (&it, 1);
15676 try_window (window, it.current.pos, 0);
15677 }
15678 else if (PT < IT_CHARPOS (it))
15679 {
15680 clear_glyph_matrix (w->desired_matrix);
15681 move_it_by_lines (&it, -1);
15682 try_window (window, it.current.pos, 0);
15683 }
15684 else
15685 {
15686 /* Not much we can do about it. */
15687 }
15688 }
15689
15690 /* Consider the following case: Window starts at BEGV, there is
15691 invisible, intangible text at BEGV, so that display starts at
15692 some point START > BEGV. It can happen that we are called with
15693 PT somewhere between BEGV and START. Try to handle that case. */
15694 if (w->cursor.vpos < 0)
15695 {
15696 struct glyph_row *row = w->current_matrix->rows;
15697 if (row->mode_line_p)
15698 ++row;
15699 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
15700 }
15701
15702 if (!cursor_row_fully_visible_p (w, 0, 0))
15703 {
15704 /* If vscroll is enabled, disable it and try again. */
15705 if (w->vscroll)
15706 {
15707 w->vscroll = 0;
15708 clear_glyph_matrix (w->desired_matrix);
15709 goto recenter;
15710 }
15711
15712 /* If centering point failed to make the whole line visible,
15713 put point at the top instead. That has to make the whole line
15714 visible, if it can be done. */
15715 if (centering_position == 0)
15716 goto done;
15717
15718 clear_glyph_matrix (w->desired_matrix);
15719 centering_position = 0;
15720 goto recenter;
15721 }
15722
15723 done:
15724
15725 SET_TEXT_POS_FROM_MARKER (startp, w->start);
15726 w->start_at_line_beg = ((CHARPOS (startp) == BEGV
15727 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n')
15728 ? Qt : Qnil);
15729
15730 /* Display the mode line, if we must. */
15731 if ((update_mode_line
15732 /* If window not full width, must redo its mode line
15733 if (a) the window to its side is being redone and
15734 (b) we do a frame-based redisplay. This is a consequence
15735 of how inverted lines are drawn in frame-based redisplay. */
15736 || (!just_this_one_p
15737 && !FRAME_WINDOW_P (f)
15738 && !WINDOW_FULL_WIDTH_P (w))
15739 /* Line number to display. */
15740 || INTEGERP (w->base_line_pos)
15741 /* Column number is displayed and different from the one displayed. */
15742 || (!NILP (w->column_number_displayed)
15743 && (XFASTINT (w->column_number_displayed) != current_column ())))
15744 /* This means that the window has a mode line. */
15745 && (WINDOW_WANTS_MODELINE_P (w)
15746 || WINDOW_WANTS_HEADER_LINE_P (w)))
15747 {
15748 display_mode_lines (w);
15749
15750 /* If mode line height has changed, arrange for a thorough
15751 immediate redisplay using the correct mode line height. */
15752 if (WINDOW_WANTS_MODELINE_P (w)
15753 && CURRENT_MODE_LINE_HEIGHT (w) != DESIRED_MODE_LINE_HEIGHT (w))
15754 {
15755 fonts_changed_p = 1;
15756 MATRIX_MODE_LINE_ROW (w->current_matrix)->height
15757 = DESIRED_MODE_LINE_HEIGHT (w);
15758 }
15759
15760 /* If header line height has changed, arrange for a thorough
15761 immediate redisplay using the correct header line height. */
15762 if (WINDOW_WANTS_HEADER_LINE_P (w)
15763 && CURRENT_HEADER_LINE_HEIGHT (w) != DESIRED_HEADER_LINE_HEIGHT (w))
15764 {
15765 fonts_changed_p = 1;
15766 MATRIX_HEADER_LINE_ROW (w->current_matrix)->height
15767 = DESIRED_HEADER_LINE_HEIGHT (w);
15768 }
15769
15770 if (fonts_changed_p)
15771 goto need_larger_matrices;
15772 }
15773
15774 if (!line_number_displayed
15775 && !BUFFERP (w->base_line_pos))
15776 {
15777 w->base_line_pos = Qnil;
15778 w->base_line_number = Qnil;
15779 }
15780
15781 finish_menu_bars:
15782
15783 /* When we reach a frame's selected window, redo the frame's menu bar. */
15784 if (update_mode_line
15785 && EQ (FRAME_SELECTED_WINDOW (f), window))
15786 {
15787 int redisplay_menu_p = 0;
15788
15789 if (FRAME_WINDOW_P (f))
15790 {
15791 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
15792 || defined (HAVE_NS) || defined (USE_GTK)
15793 redisplay_menu_p = FRAME_EXTERNAL_MENU_BAR (f);
15794 #else
15795 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
15796 #endif
15797 }
15798 else
15799 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
15800
15801 if (redisplay_menu_p)
15802 display_menu_bar (w);
15803
15804 #ifdef HAVE_WINDOW_SYSTEM
15805 if (FRAME_WINDOW_P (f))
15806 {
15807 #if defined (USE_GTK) || defined (HAVE_NS)
15808 if (FRAME_EXTERNAL_TOOL_BAR (f))
15809 redisplay_tool_bar (f);
15810 #else
15811 if (WINDOWP (f->tool_bar_window)
15812 && (FRAME_TOOL_BAR_LINES (f) > 0
15813 || !NILP (Vauto_resize_tool_bars))
15814 && redisplay_tool_bar (f))
15815 ignore_mouse_drag_p = 1;
15816 #endif
15817 }
15818 #endif
15819 }
15820
15821 #ifdef HAVE_WINDOW_SYSTEM
15822 if (FRAME_WINDOW_P (f)
15823 && update_window_fringes (w, (just_this_one_p
15824 || (!used_current_matrix_p && !overlay_arrow_seen)
15825 || w->pseudo_window_p)))
15826 {
15827 update_begin (f);
15828 BLOCK_INPUT;
15829 if (draw_window_fringes (w, 1))
15830 x_draw_vertical_border (w);
15831 UNBLOCK_INPUT;
15832 update_end (f);
15833 }
15834 #endif /* HAVE_WINDOW_SYSTEM */
15835
15836 /* We go to this label, with fonts_changed_p nonzero,
15837 if it is necessary to try again using larger glyph matrices.
15838 We have to redeem the scroll bar even in this case,
15839 because the loop in redisplay_internal expects that. */
15840 need_larger_matrices:
15841 ;
15842 finish_scroll_bars:
15843
15844 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
15845 {
15846 /* Set the thumb's position and size. */
15847 set_vertical_scroll_bar (w);
15848
15849 /* Note that we actually used the scroll bar attached to this
15850 window, so it shouldn't be deleted at the end of redisplay. */
15851 if (FRAME_TERMINAL (f)->redeem_scroll_bar_hook)
15852 (*FRAME_TERMINAL (f)->redeem_scroll_bar_hook) (w);
15853 }
15854
15855 /* Restore current_buffer and value of point in it. The window
15856 update may have changed the buffer, so first make sure `opoint'
15857 is still valid (Bug#6177). */
15858 if (CHARPOS (opoint) < BEGV)
15859 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
15860 else if (CHARPOS (opoint) > ZV)
15861 TEMP_SET_PT_BOTH (Z, Z_BYTE);
15862 else
15863 TEMP_SET_PT_BOTH (CHARPOS (opoint), BYTEPOS (opoint));
15864
15865 set_buffer_internal_1 (old);
15866 /* Avoid an abort in TEMP_SET_PT_BOTH if the buffer has become
15867 shorter. This can be caused by log truncation in *Messages*. */
15868 if (CHARPOS (lpoint) <= ZV)
15869 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
15870
15871 unbind_to (count, Qnil);
15872 }
15873
15874
15875 /* Build the complete desired matrix of WINDOW with a window start
15876 buffer position POS.
15877
15878 Value is 1 if successful. It is zero if fonts were loaded during
15879 redisplay which makes re-adjusting glyph matrices necessary, and -1
15880 if point would appear in the scroll margins.
15881 (We check the former only if TRY_WINDOW_IGNORE_FONTS_CHANGE is
15882 unset in FLAGS, and the latter only if TRY_WINDOW_CHECK_MARGINS is
15883 set in FLAGS.) */
15884
15885 int
15886 try_window (Lisp_Object window, struct text_pos pos, int flags)
15887 {
15888 struct window *w = XWINDOW (window);
15889 struct it it;
15890 struct glyph_row *last_text_row = NULL;
15891 struct frame *f = XFRAME (w->frame);
15892
15893 /* Make POS the new window start. */
15894 set_marker_both (w->start, Qnil, CHARPOS (pos), BYTEPOS (pos));
15895
15896 /* Mark cursor position as unknown. No overlay arrow seen. */
15897 w->cursor.vpos = -1;
15898 overlay_arrow_seen = 0;
15899
15900 /* Initialize iterator and info to start at POS. */
15901 start_display (&it, w, pos);
15902
15903 /* Display all lines of W. */
15904 while (it.current_y < it.last_visible_y)
15905 {
15906 if (display_line (&it))
15907 last_text_row = it.glyph_row - 1;
15908 if (fonts_changed_p && !(flags & TRY_WINDOW_IGNORE_FONTS_CHANGE))
15909 return 0;
15910 }
15911
15912 /* Don't let the cursor end in the scroll margins. */
15913 if ((flags & TRY_WINDOW_CHECK_MARGINS)
15914 && !MINI_WINDOW_P (w))
15915 {
15916 int this_scroll_margin;
15917
15918 if (scroll_margin > 0)
15919 {
15920 this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
15921 this_scroll_margin *= FRAME_LINE_HEIGHT (f);
15922 }
15923 else
15924 this_scroll_margin = 0;
15925
15926 if ((w->cursor.y >= 0 /* not vscrolled */
15927 && w->cursor.y < this_scroll_margin
15928 && CHARPOS (pos) > BEGV
15929 && IT_CHARPOS (it) < ZV)
15930 /* rms: considering make_cursor_line_fully_visible_p here
15931 seems to give wrong results. We don't want to recenter
15932 when the last line is partly visible, we want to allow
15933 that case to be handled in the usual way. */
15934 || w->cursor.y > it.last_visible_y - this_scroll_margin - 1)
15935 {
15936 w->cursor.vpos = -1;
15937 clear_glyph_matrix (w->desired_matrix);
15938 return -1;
15939 }
15940 }
15941
15942 /* If bottom moved off end of frame, change mode line percentage. */
15943 if (XFASTINT (w->window_end_pos) <= 0
15944 && Z != IT_CHARPOS (it))
15945 w->update_mode_line = Qt;
15946
15947 /* Set window_end_pos to the offset of the last character displayed
15948 on the window from the end of current_buffer. Set
15949 window_end_vpos to its row number. */
15950 if (last_text_row)
15951 {
15952 xassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row));
15953 w->window_end_bytepos
15954 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
15955 w->window_end_pos
15956 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
15957 w->window_end_vpos
15958 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
15959 xassert (MATRIX_ROW (w->desired_matrix, XFASTINT (w->window_end_vpos))
15960 ->displays_text_p);
15961 }
15962 else
15963 {
15964 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
15965 w->window_end_pos = make_number (Z - ZV);
15966 w->window_end_vpos = make_number (0);
15967 }
15968
15969 /* But that is not valid info until redisplay finishes. */
15970 w->window_end_valid = Qnil;
15971 return 1;
15972 }
15973
15974
15975 \f
15976 /************************************************************************
15977 Window redisplay reusing current matrix when buffer has not changed
15978 ************************************************************************/
15979
15980 /* Try redisplay of window W showing an unchanged buffer with a
15981 different window start than the last time it was displayed by
15982 reusing its current matrix. Value is non-zero if successful.
15983 W->start is the new window start. */
15984
15985 static int
15986 try_window_reusing_current_matrix (struct window *w)
15987 {
15988 struct frame *f = XFRAME (w->frame);
15989 struct glyph_row *bottom_row;
15990 struct it it;
15991 struct run run;
15992 struct text_pos start, new_start;
15993 int nrows_scrolled, i;
15994 struct glyph_row *last_text_row;
15995 struct glyph_row *last_reused_text_row;
15996 struct glyph_row *start_row;
15997 int start_vpos, min_y, max_y;
15998
15999 #if GLYPH_DEBUG
16000 if (inhibit_try_window_reusing)
16001 return 0;
16002 #endif
16003
16004 if (/* This function doesn't handle terminal frames. */
16005 !FRAME_WINDOW_P (f)
16006 /* Don't try to reuse the display if windows have been split
16007 or such. */
16008 || windows_or_buffers_changed
16009 || cursor_type_changed)
16010 return 0;
16011
16012 /* Can't do this if region may have changed. */
16013 if ((!NILP (Vtransient_mark_mode)
16014 && !NILP (BVAR (current_buffer, mark_active)))
16015 || !NILP (w->region_showing)
16016 || !NILP (Vshow_trailing_whitespace))
16017 return 0;
16018
16019 /* If top-line visibility has changed, give up. */
16020 if (WINDOW_WANTS_HEADER_LINE_P (w)
16021 != MATRIX_HEADER_LINE_ROW (w->current_matrix)->mode_line_p)
16022 return 0;
16023
16024 /* Give up if old or new display is scrolled vertically. We could
16025 make this function handle this, but right now it doesn't. */
16026 start_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
16027 if (w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row))
16028 return 0;
16029
16030 /* The variable new_start now holds the new window start. The old
16031 start `start' can be determined from the current matrix. */
16032 SET_TEXT_POS_FROM_MARKER (new_start, w->start);
16033 start = start_row->minpos;
16034 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
16035
16036 /* Clear the desired matrix for the display below. */
16037 clear_glyph_matrix (w->desired_matrix);
16038
16039 if (CHARPOS (new_start) <= CHARPOS (start))
16040 {
16041 /* Don't use this method if the display starts with an ellipsis
16042 displayed for invisible text. It's not easy to handle that case
16043 below, and it's certainly not worth the effort since this is
16044 not a frequent case. */
16045 if (in_ellipses_for_invisible_text_p (&start_row->start, w))
16046 return 0;
16047
16048 IF_DEBUG (debug_method_add (w, "twu1"));
16049
16050 /* Display up to a row that can be reused. The variable
16051 last_text_row is set to the last row displayed that displays
16052 text. Note that it.vpos == 0 if or if not there is a
16053 header-line; it's not the same as the MATRIX_ROW_VPOS! */
16054 start_display (&it, w, new_start);
16055 w->cursor.vpos = -1;
16056 last_text_row = last_reused_text_row = NULL;
16057
16058 while (it.current_y < it.last_visible_y
16059 && !fonts_changed_p)
16060 {
16061 /* If we have reached into the characters in the START row,
16062 that means the line boundaries have changed. So we
16063 can't start copying with the row START. Maybe it will
16064 work to start copying with the following row. */
16065 while (IT_CHARPOS (it) > CHARPOS (start))
16066 {
16067 /* Advance to the next row as the "start". */
16068 start_row++;
16069 start = start_row->minpos;
16070 /* If there are no more rows to try, or just one, give up. */
16071 if (start_row == MATRIX_MODE_LINE_ROW (w->current_matrix) - 1
16072 || w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row)
16073 || CHARPOS (start) == ZV)
16074 {
16075 clear_glyph_matrix (w->desired_matrix);
16076 return 0;
16077 }
16078
16079 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
16080 }
16081 /* If we have reached alignment, we can copy the rest of the
16082 rows. */
16083 if (IT_CHARPOS (it) == CHARPOS (start)
16084 /* Don't accept "alignment" inside a display vector,
16085 since start_row could have started in the middle of
16086 that same display vector (thus their character
16087 positions match), and we have no way of telling if
16088 that is the case. */
16089 && it.current.dpvec_index < 0)
16090 break;
16091
16092 if (display_line (&it))
16093 last_text_row = it.glyph_row - 1;
16094
16095 }
16096
16097 /* A value of current_y < last_visible_y means that we stopped
16098 at the previous window start, which in turn means that we
16099 have at least one reusable row. */
16100 if (it.current_y < it.last_visible_y)
16101 {
16102 struct glyph_row *row;
16103
16104 /* IT.vpos always starts from 0; it counts text lines. */
16105 nrows_scrolled = it.vpos - (start_row - MATRIX_FIRST_TEXT_ROW (w->current_matrix));
16106
16107 /* Find PT if not already found in the lines displayed. */
16108 if (w->cursor.vpos < 0)
16109 {
16110 int dy = it.current_y - start_row->y;
16111
16112 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
16113 row = row_containing_pos (w, PT, row, NULL, dy);
16114 if (row)
16115 set_cursor_from_row (w, row, w->current_matrix, 0, 0,
16116 dy, nrows_scrolled);
16117 else
16118 {
16119 clear_glyph_matrix (w->desired_matrix);
16120 return 0;
16121 }
16122 }
16123
16124 /* Scroll the display. Do it before the current matrix is
16125 changed. The problem here is that update has not yet
16126 run, i.e. part of the current matrix is not up to date.
16127 scroll_run_hook will clear the cursor, and use the
16128 current matrix to get the height of the row the cursor is
16129 in. */
16130 run.current_y = start_row->y;
16131 run.desired_y = it.current_y;
16132 run.height = it.last_visible_y - it.current_y;
16133
16134 if (run.height > 0 && run.current_y != run.desired_y)
16135 {
16136 update_begin (f);
16137 FRAME_RIF (f)->update_window_begin_hook (w);
16138 FRAME_RIF (f)->clear_window_mouse_face (w);
16139 FRAME_RIF (f)->scroll_run_hook (w, &run);
16140 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
16141 update_end (f);
16142 }
16143
16144 /* Shift current matrix down by nrows_scrolled lines. */
16145 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
16146 rotate_matrix (w->current_matrix,
16147 start_vpos,
16148 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
16149 nrows_scrolled);
16150
16151 /* Disable lines that must be updated. */
16152 for (i = 0; i < nrows_scrolled; ++i)
16153 (start_row + i)->enabled_p = 0;
16154
16155 /* Re-compute Y positions. */
16156 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
16157 max_y = it.last_visible_y;
16158 for (row = start_row + nrows_scrolled;
16159 row < bottom_row;
16160 ++row)
16161 {
16162 row->y = it.current_y;
16163 row->visible_height = row->height;
16164
16165 if (row->y < min_y)
16166 row->visible_height -= min_y - row->y;
16167 if (row->y + row->height > max_y)
16168 row->visible_height -= row->y + row->height - max_y;
16169 if (row->fringe_bitmap_periodic_p)
16170 row->redraw_fringe_bitmaps_p = 1;
16171
16172 it.current_y += row->height;
16173
16174 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
16175 last_reused_text_row = row;
16176 if (MATRIX_ROW_BOTTOM_Y (row) >= it.last_visible_y)
16177 break;
16178 }
16179
16180 /* Disable lines in the current matrix which are now
16181 below the window. */
16182 for (++row; row < bottom_row; ++row)
16183 row->enabled_p = row->mode_line_p = 0;
16184 }
16185
16186 /* Update window_end_pos etc.; last_reused_text_row is the last
16187 reused row from the current matrix containing text, if any.
16188 The value of last_text_row is the last displayed line
16189 containing text. */
16190 if (last_reused_text_row)
16191 {
16192 w->window_end_bytepos
16193 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_reused_text_row);
16194 w->window_end_pos
16195 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_reused_text_row));
16196 w->window_end_vpos
16197 = make_number (MATRIX_ROW_VPOS (last_reused_text_row,
16198 w->current_matrix));
16199 }
16200 else if (last_text_row)
16201 {
16202 w->window_end_bytepos
16203 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
16204 w->window_end_pos
16205 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
16206 w->window_end_vpos
16207 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
16208 }
16209 else
16210 {
16211 /* This window must be completely empty. */
16212 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
16213 w->window_end_pos = make_number (Z - ZV);
16214 w->window_end_vpos = make_number (0);
16215 }
16216 w->window_end_valid = Qnil;
16217
16218 /* Update hint: don't try scrolling again in update_window. */
16219 w->desired_matrix->no_scrolling_p = 1;
16220
16221 #if GLYPH_DEBUG
16222 debug_method_add (w, "try_window_reusing_current_matrix 1");
16223 #endif
16224 return 1;
16225 }
16226 else if (CHARPOS (new_start) > CHARPOS (start))
16227 {
16228 struct glyph_row *pt_row, *row;
16229 struct glyph_row *first_reusable_row;
16230 struct glyph_row *first_row_to_display;
16231 int dy;
16232 int yb = window_text_bottom_y (w);
16233
16234 /* Find the row starting at new_start, if there is one. Don't
16235 reuse a partially visible line at the end. */
16236 first_reusable_row = start_row;
16237 while (first_reusable_row->enabled_p
16238 && MATRIX_ROW_BOTTOM_Y (first_reusable_row) < yb
16239 && (MATRIX_ROW_START_CHARPOS (first_reusable_row)
16240 < CHARPOS (new_start)))
16241 ++first_reusable_row;
16242
16243 /* Give up if there is no row to reuse. */
16244 if (MATRIX_ROW_BOTTOM_Y (first_reusable_row) >= yb
16245 || !first_reusable_row->enabled_p
16246 || (MATRIX_ROW_START_CHARPOS (first_reusable_row)
16247 != CHARPOS (new_start)))
16248 return 0;
16249
16250 /* We can reuse fully visible rows beginning with
16251 first_reusable_row to the end of the window. Set
16252 first_row_to_display to the first row that cannot be reused.
16253 Set pt_row to the row containing point, if there is any. */
16254 pt_row = NULL;
16255 for (first_row_to_display = first_reusable_row;
16256 MATRIX_ROW_BOTTOM_Y (first_row_to_display) < yb;
16257 ++first_row_to_display)
16258 {
16259 if (PT >= MATRIX_ROW_START_CHARPOS (first_row_to_display)
16260 && PT < MATRIX_ROW_END_CHARPOS (first_row_to_display))
16261 pt_row = first_row_to_display;
16262 }
16263
16264 /* Start displaying at the start of first_row_to_display. */
16265 xassert (first_row_to_display->y < yb);
16266 init_to_row_start (&it, w, first_row_to_display);
16267
16268 nrows_scrolled = (MATRIX_ROW_VPOS (first_reusable_row, w->current_matrix)
16269 - start_vpos);
16270 it.vpos = (MATRIX_ROW_VPOS (first_row_to_display, w->current_matrix)
16271 - nrows_scrolled);
16272 it.current_y = (first_row_to_display->y - first_reusable_row->y
16273 + WINDOW_HEADER_LINE_HEIGHT (w));
16274
16275 /* Display lines beginning with first_row_to_display in the
16276 desired matrix. Set last_text_row to the last row displayed
16277 that displays text. */
16278 it.glyph_row = MATRIX_ROW (w->desired_matrix, it.vpos);
16279 if (pt_row == NULL)
16280 w->cursor.vpos = -1;
16281 last_text_row = NULL;
16282 while (it.current_y < it.last_visible_y && !fonts_changed_p)
16283 if (display_line (&it))
16284 last_text_row = it.glyph_row - 1;
16285
16286 /* If point is in a reused row, adjust y and vpos of the cursor
16287 position. */
16288 if (pt_row)
16289 {
16290 w->cursor.vpos -= nrows_scrolled;
16291 w->cursor.y -= first_reusable_row->y - start_row->y;
16292 }
16293
16294 /* Give up if point isn't in a row displayed or reused. (This
16295 also handles the case where w->cursor.vpos < nrows_scrolled
16296 after the calls to display_line, which can happen with scroll
16297 margins. See bug#1295.) */
16298 if (w->cursor.vpos < 0)
16299 {
16300 clear_glyph_matrix (w->desired_matrix);
16301 return 0;
16302 }
16303
16304 /* Scroll the display. */
16305 run.current_y = first_reusable_row->y;
16306 run.desired_y = WINDOW_HEADER_LINE_HEIGHT (w);
16307 run.height = it.last_visible_y - run.current_y;
16308 dy = run.current_y - run.desired_y;
16309
16310 if (run.height)
16311 {
16312 update_begin (f);
16313 FRAME_RIF (f)->update_window_begin_hook (w);
16314 FRAME_RIF (f)->clear_window_mouse_face (w);
16315 FRAME_RIF (f)->scroll_run_hook (w, &run);
16316 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
16317 update_end (f);
16318 }
16319
16320 /* Adjust Y positions of reused rows. */
16321 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
16322 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
16323 max_y = it.last_visible_y;
16324 for (row = first_reusable_row; row < first_row_to_display; ++row)
16325 {
16326 row->y -= dy;
16327 row->visible_height = row->height;
16328 if (row->y < min_y)
16329 row->visible_height -= min_y - row->y;
16330 if (row->y + row->height > max_y)
16331 row->visible_height -= row->y + row->height - max_y;
16332 if (row->fringe_bitmap_periodic_p)
16333 row->redraw_fringe_bitmaps_p = 1;
16334 }
16335
16336 /* Scroll the current matrix. */
16337 xassert (nrows_scrolled > 0);
16338 rotate_matrix (w->current_matrix,
16339 start_vpos,
16340 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
16341 -nrows_scrolled);
16342
16343 /* Disable rows not reused. */
16344 for (row -= nrows_scrolled; row < bottom_row; ++row)
16345 row->enabled_p = 0;
16346
16347 /* Point may have moved to a different line, so we cannot assume that
16348 the previous cursor position is valid; locate the correct row. */
16349 if (pt_row)
16350 {
16351 for (row = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
16352 row < bottom_row && PT >= MATRIX_ROW_END_CHARPOS (row);
16353 row++)
16354 {
16355 w->cursor.vpos++;
16356 w->cursor.y = row->y;
16357 }
16358 if (row < bottom_row)
16359 {
16360 struct glyph *glyph = row->glyphs[TEXT_AREA] + w->cursor.hpos;
16361 struct glyph *end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
16362
16363 /* Can't use this optimization with bidi-reordered glyph
16364 rows, unless cursor is already at point. */
16365 if (!NILP (BVAR (XBUFFER (w->buffer), bidi_display_reordering)))
16366 {
16367 if (!(w->cursor.hpos >= 0
16368 && w->cursor.hpos < row->used[TEXT_AREA]
16369 && BUFFERP (glyph->object)
16370 && glyph->charpos == PT))
16371 return 0;
16372 }
16373 else
16374 for (; glyph < end
16375 && (!BUFFERP (glyph->object)
16376 || glyph->charpos < PT);
16377 glyph++)
16378 {
16379 w->cursor.hpos++;
16380 w->cursor.x += glyph->pixel_width;
16381 }
16382 }
16383 }
16384
16385 /* Adjust window end. A null value of last_text_row means that
16386 the window end is in reused rows which in turn means that
16387 only its vpos can have changed. */
16388 if (last_text_row)
16389 {
16390 w->window_end_bytepos
16391 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
16392 w->window_end_pos
16393 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
16394 w->window_end_vpos
16395 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
16396 }
16397 else
16398 {
16399 w->window_end_vpos
16400 = make_number (XFASTINT (w->window_end_vpos) - nrows_scrolled);
16401 }
16402
16403 w->window_end_valid = Qnil;
16404 w->desired_matrix->no_scrolling_p = 1;
16405
16406 #if GLYPH_DEBUG
16407 debug_method_add (w, "try_window_reusing_current_matrix 2");
16408 #endif
16409 return 1;
16410 }
16411
16412 return 0;
16413 }
16414
16415
16416 \f
16417 /************************************************************************
16418 Window redisplay reusing current matrix when buffer has changed
16419 ************************************************************************/
16420
16421 static struct glyph_row *find_last_unchanged_at_beg_row (struct window *);
16422 static struct glyph_row *find_first_unchanged_at_end_row (struct window *,
16423 EMACS_INT *, EMACS_INT *);
16424 static struct glyph_row *
16425 find_last_row_displaying_text (struct glyph_matrix *, struct it *,
16426 struct glyph_row *);
16427
16428
16429 /* Return the last row in MATRIX displaying text. If row START is
16430 non-null, start searching with that row. IT gives the dimensions
16431 of the display. Value is null if matrix is empty; otherwise it is
16432 a pointer to the row found. */
16433
16434 static struct glyph_row *
16435 find_last_row_displaying_text (struct glyph_matrix *matrix, struct it *it,
16436 struct glyph_row *start)
16437 {
16438 struct glyph_row *row, *row_found;
16439
16440 /* Set row_found to the last row in IT->w's current matrix
16441 displaying text. The loop looks funny but think of partially
16442 visible lines. */
16443 row_found = NULL;
16444 row = start ? start : MATRIX_FIRST_TEXT_ROW (matrix);
16445 while (MATRIX_ROW_DISPLAYS_TEXT_P (row))
16446 {
16447 xassert (row->enabled_p);
16448 row_found = row;
16449 if (MATRIX_ROW_BOTTOM_Y (row) >= it->last_visible_y)
16450 break;
16451 ++row;
16452 }
16453
16454 return row_found;
16455 }
16456
16457
16458 /* Return the last row in the current matrix of W that is not affected
16459 by changes at the start of current_buffer that occurred since W's
16460 current matrix was built. Value is null if no such row exists.
16461
16462 BEG_UNCHANGED us the number of characters unchanged at the start of
16463 current_buffer. BEG + BEG_UNCHANGED is the buffer position of the
16464 first changed character in current_buffer. Characters at positions <
16465 BEG + BEG_UNCHANGED are at the same buffer positions as they were
16466 when the current matrix was built. */
16467
16468 static struct glyph_row *
16469 find_last_unchanged_at_beg_row (struct window *w)
16470 {
16471 EMACS_INT first_changed_pos = BEG + BEG_UNCHANGED;
16472 struct glyph_row *row;
16473 struct glyph_row *row_found = NULL;
16474 int yb = window_text_bottom_y (w);
16475
16476 /* Find the last row displaying unchanged text. */
16477 for (row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
16478 MATRIX_ROW_DISPLAYS_TEXT_P (row)
16479 && MATRIX_ROW_START_CHARPOS (row) < first_changed_pos;
16480 ++row)
16481 {
16482 if (/* If row ends before first_changed_pos, it is unchanged,
16483 except in some case. */
16484 MATRIX_ROW_END_CHARPOS (row) <= first_changed_pos
16485 /* When row ends in ZV and we write at ZV it is not
16486 unchanged. */
16487 && !row->ends_at_zv_p
16488 /* When first_changed_pos is the end of a continued line,
16489 row is not unchanged because it may be no longer
16490 continued. */
16491 && !(MATRIX_ROW_END_CHARPOS (row) == first_changed_pos
16492 && (row->continued_p
16493 || row->exact_window_width_line_p)))
16494 row_found = row;
16495
16496 /* Stop if last visible row. */
16497 if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
16498 break;
16499 }
16500
16501 return row_found;
16502 }
16503
16504
16505 /* Find the first glyph row in the current matrix of W that is not
16506 affected by changes at the end of current_buffer since the
16507 time W's current matrix was built.
16508
16509 Return in *DELTA the number of chars by which buffer positions in
16510 unchanged text at the end of current_buffer must be adjusted.
16511
16512 Return in *DELTA_BYTES the corresponding number of bytes.
16513
16514 Value is null if no such row exists, i.e. all rows are affected by
16515 changes. */
16516
16517 static struct glyph_row *
16518 find_first_unchanged_at_end_row (struct window *w,
16519 EMACS_INT *delta, EMACS_INT *delta_bytes)
16520 {
16521 struct glyph_row *row;
16522 struct glyph_row *row_found = NULL;
16523
16524 *delta = *delta_bytes = 0;
16525
16526 /* Display must not have been paused, otherwise the current matrix
16527 is not up to date. */
16528 eassert (!NILP (w->window_end_valid));
16529
16530 /* A value of window_end_pos >= END_UNCHANGED means that the window
16531 end is in the range of changed text. If so, there is no
16532 unchanged row at the end of W's current matrix. */
16533 if (XFASTINT (w->window_end_pos) >= END_UNCHANGED)
16534 return NULL;
16535
16536 /* Set row to the last row in W's current matrix displaying text. */
16537 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
16538
16539 /* If matrix is entirely empty, no unchanged row exists. */
16540 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
16541 {
16542 /* The value of row is the last glyph row in the matrix having a
16543 meaningful buffer position in it. The end position of row
16544 corresponds to window_end_pos. This allows us to translate
16545 buffer positions in the current matrix to current buffer
16546 positions for characters not in changed text. */
16547 EMACS_INT Z_old =
16548 MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
16549 EMACS_INT Z_BYTE_old =
16550 MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
16551 EMACS_INT last_unchanged_pos, last_unchanged_pos_old;
16552 struct glyph_row *first_text_row
16553 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
16554
16555 *delta = Z - Z_old;
16556 *delta_bytes = Z_BYTE - Z_BYTE_old;
16557
16558 /* Set last_unchanged_pos to the buffer position of the last
16559 character in the buffer that has not been changed. Z is the
16560 index + 1 of the last character in current_buffer, i.e. by
16561 subtracting END_UNCHANGED we get the index of the last
16562 unchanged character, and we have to add BEG to get its buffer
16563 position. */
16564 last_unchanged_pos = Z - END_UNCHANGED + BEG;
16565 last_unchanged_pos_old = last_unchanged_pos - *delta;
16566
16567 /* Search backward from ROW for a row displaying a line that
16568 starts at a minimum position >= last_unchanged_pos_old. */
16569 for (; row > first_text_row; --row)
16570 {
16571 /* This used to abort, but it can happen.
16572 It is ok to just stop the search instead here. KFS. */
16573 if (!row->enabled_p || !MATRIX_ROW_DISPLAYS_TEXT_P (row))
16574 break;
16575
16576 if (MATRIX_ROW_START_CHARPOS (row) >= last_unchanged_pos_old)
16577 row_found = row;
16578 }
16579 }
16580
16581 eassert (!row_found || MATRIX_ROW_DISPLAYS_TEXT_P (row_found));
16582
16583 return row_found;
16584 }
16585
16586
16587 /* Make sure that glyph rows in the current matrix of window W
16588 reference the same glyph memory as corresponding rows in the
16589 frame's frame matrix. This function is called after scrolling W's
16590 current matrix on a terminal frame in try_window_id and
16591 try_window_reusing_current_matrix. */
16592
16593 static void
16594 sync_frame_with_window_matrix_rows (struct window *w)
16595 {
16596 struct frame *f = XFRAME (w->frame);
16597 struct glyph_row *window_row, *window_row_end, *frame_row;
16598
16599 /* Preconditions: W must be a leaf window and full-width. Its frame
16600 must have a frame matrix. */
16601 xassert (NILP (w->hchild) && NILP (w->vchild));
16602 xassert (WINDOW_FULL_WIDTH_P (w));
16603 xassert (!FRAME_WINDOW_P (f));
16604
16605 /* If W is a full-width window, glyph pointers in W's current matrix
16606 have, by definition, to be the same as glyph pointers in the
16607 corresponding frame matrix. Note that frame matrices have no
16608 marginal areas (see build_frame_matrix). */
16609 window_row = w->current_matrix->rows;
16610 window_row_end = window_row + w->current_matrix->nrows;
16611 frame_row = f->current_matrix->rows + WINDOW_TOP_EDGE_LINE (w);
16612 while (window_row < window_row_end)
16613 {
16614 struct glyph *start = window_row->glyphs[LEFT_MARGIN_AREA];
16615 struct glyph *end = window_row->glyphs[LAST_AREA];
16616
16617 frame_row->glyphs[LEFT_MARGIN_AREA] = start;
16618 frame_row->glyphs[TEXT_AREA] = start;
16619 frame_row->glyphs[RIGHT_MARGIN_AREA] = end;
16620 frame_row->glyphs[LAST_AREA] = end;
16621
16622 /* Disable frame rows whose corresponding window rows have
16623 been disabled in try_window_id. */
16624 if (!window_row->enabled_p)
16625 frame_row->enabled_p = 0;
16626
16627 ++window_row, ++frame_row;
16628 }
16629 }
16630
16631
16632 /* Find the glyph row in window W containing CHARPOS. Consider all
16633 rows between START and END (not inclusive). END null means search
16634 all rows to the end of the display area of W. Value is the row
16635 containing CHARPOS or null. */
16636
16637 struct glyph_row *
16638 row_containing_pos (struct window *w, EMACS_INT charpos,
16639 struct glyph_row *start, struct glyph_row *end, int dy)
16640 {
16641 struct glyph_row *row = start;
16642 struct glyph_row *best_row = NULL;
16643 EMACS_INT mindif = BUF_ZV (XBUFFER (w->buffer)) + 1;
16644 int last_y;
16645
16646 /* If we happen to start on a header-line, skip that. */
16647 if (row->mode_line_p)
16648 ++row;
16649
16650 if ((end && row >= end) || !row->enabled_p)
16651 return NULL;
16652
16653 last_y = window_text_bottom_y (w) - dy;
16654
16655 while (1)
16656 {
16657 /* Give up if we have gone too far. */
16658 if (end && row >= end)
16659 return NULL;
16660 /* This formerly returned if they were equal.
16661 I think that both quantities are of a "last plus one" type;
16662 if so, when they are equal, the row is within the screen. -- rms. */
16663 if (MATRIX_ROW_BOTTOM_Y (row) > last_y)
16664 return NULL;
16665
16666 /* If it is in this row, return this row. */
16667 if (! (MATRIX_ROW_END_CHARPOS (row) < charpos
16668 || (MATRIX_ROW_END_CHARPOS (row) == charpos
16669 /* The end position of a row equals the start
16670 position of the next row. If CHARPOS is there, we
16671 would rather display it in the next line, except
16672 when this line ends in ZV. */
16673 && !row->ends_at_zv_p
16674 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
16675 && charpos >= MATRIX_ROW_START_CHARPOS (row))
16676 {
16677 struct glyph *g;
16678
16679 if (NILP (BVAR (XBUFFER (w->buffer), bidi_display_reordering))
16680 || (!best_row && !row->continued_p))
16681 return row;
16682 /* In bidi-reordered rows, there could be several rows
16683 occluding point, all of them belonging to the same
16684 continued line. We need to find the row which fits
16685 CHARPOS the best. */
16686 for (g = row->glyphs[TEXT_AREA];
16687 g < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
16688 g++)
16689 {
16690 if (!STRINGP (g->object))
16691 {
16692 if (g->charpos > 0 && eabs (g->charpos - charpos) < mindif)
16693 {
16694 mindif = eabs (g->charpos - charpos);
16695 best_row = row;
16696 /* Exact match always wins. */
16697 if (mindif == 0)
16698 return best_row;
16699 }
16700 }
16701 }
16702 }
16703 else if (best_row && !row->continued_p)
16704 return best_row;
16705 ++row;
16706 }
16707 }
16708
16709
16710 /* Try to redisplay window W by reusing its existing display. W's
16711 current matrix must be up to date when this function is called,
16712 i.e. window_end_valid must not be nil.
16713
16714 Value is
16715
16716 1 if display has been updated
16717 0 if otherwise unsuccessful
16718 -1 if redisplay with same window start is known not to succeed
16719
16720 The following steps are performed:
16721
16722 1. Find the last row in the current matrix of W that is not
16723 affected by changes at the start of current_buffer. If no such row
16724 is found, give up.
16725
16726 2. Find the first row in W's current matrix that is not affected by
16727 changes at the end of current_buffer. Maybe there is no such row.
16728
16729 3. Display lines beginning with the row + 1 found in step 1 to the
16730 row found in step 2 or, if step 2 didn't find a row, to the end of
16731 the window.
16732
16733 4. If cursor is not known to appear on the window, give up.
16734
16735 5. If display stopped at the row found in step 2, scroll the
16736 display and current matrix as needed.
16737
16738 6. Maybe display some lines at the end of W, if we must. This can
16739 happen under various circumstances, like a partially visible line
16740 becoming fully visible, or because newly displayed lines are displayed
16741 in smaller font sizes.
16742
16743 7. Update W's window end information. */
16744
16745 static int
16746 try_window_id (struct window *w)
16747 {
16748 struct frame *f = XFRAME (w->frame);
16749 struct glyph_matrix *current_matrix = w->current_matrix;
16750 struct glyph_matrix *desired_matrix = w->desired_matrix;
16751 struct glyph_row *last_unchanged_at_beg_row;
16752 struct glyph_row *first_unchanged_at_end_row;
16753 struct glyph_row *row;
16754 struct glyph_row *bottom_row;
16755 int bottom_vpos;
16756 struct it it;
16757 EMACS_INT delta = 0, delta_bytes = 0, stop_pos;
16758 int dvpos, dy;
16759 struct text_pos start_pos;
16760 struct run run;
16761 int first_unchanged_at_end_vpos = 0;
16762 struct glyph_row *last_text_row, *last_text_row_at_end;
16763 struct text_pos start;
16764 EMACS_INT first_changed_charpos, last_changed_charpos;
16765
16766 #if GLYPH_DEBUG
16767 if (inhibit_try_window_id)
16768 return 0;
16769 #endif
16770
16771 /* This is handy for debugging. */
16772 #if 0
16773 #define GIVE_UP(X) \
16774 do { \
16775 fprintf (stderr, "try_window_id give up %d\n", (X)); \
16776 return 0; \
16777 } while (0)
16778 #else
16779 #define GIVE_UP(X) return 0
16780 #endif
16781
16782 SET_TEXT_POS_FROM_MARKER (start, w->start);
16783
16784 /* Don't use this for mini-windows because these can show
16785 messages and mini-buffers, and we don't handle that here. */
16786 if (MINI_WINDOW_P (w))
16787 GIVE_UP (1);
16788
16789 /* This flag is used to prevent redisplay optimizations. */
16790 if (windows_or_buffers_changed || cursor_type_changed)
16791 GIVE_UP (2);
16792
16793 /* Verify that narrowing has not changed.
16794 Also verify that we were not told to prevent redisplay optimizations.
16795 It would be nice to further
16796 reduce the number of cases where this prevents try_window_id. */
16797 if (current_buffer->clip_changed
16798 || current_buffer->prevent_redisplay_optimizations_p)
16799 GIVE_UP (3);
16800
16801 /* Window must either use window-based redisplay or be full width. */
16802 if (!FRAME_WINDOW_P (f)
16803 && (!FRAME_LINE_INS_DEL_OK (f)
16804 || !WINDOW_FULL_WIDTH_P (w)))
16805 GIVE_UP (4);
16806
16807 /* Give up if point is known NOT to appear in W. */
16808 if (PT < CHARPOS (start))
16809 GIVE_UP (5);
16810
16811 /* Another way to prevent redisplay optimizations. */
16812 if (XFASTINT (w->last_modified) == 0)
16813 GIVE_UP (6);
16814
16815 /* Verify that window is not hscrolled. */
16816 if (XFASTINT (w->hscroll) != 0)
16817 GIVE_UP (7);
16818
16819 /* Verify that display wasn't paused. */
16820 if (NILP (w->window_end_valid))
16821 GIVE_UP (8);
16822
16823 /* Can't use this if highlighting a region because a cursor movement
16824 will do more than just set the cursor. */
16825 if (!NILP (Vtransient_mark_mode)
16826 && !NILP (BVAR (current_buffer, mark_active)))
16827 GIVE_UP (9);
16828
16829 /* Likewise if highlighting trailing whitespace. */
16830 if (!NILP (Vshow_trailing_whitespace))
16831 GIVE_UP (11);
16832
16833 /* Likewise if showing a region. */
16834 if (!NILP (w->region_showing))
16835 GIVE_UP (10);
16836
16837 /* Can't use this if overlay arrow position and/or string have
16838 changed. */
16839 if (overlay_arrows_changed_p ())
16840 GIVE_UP (12);
16841
16842 /* When word-wrap is on, adding a space to the first word of a
16843 wrapped line can change the wrap position, altering the line
16844 above it. It might be worthwhile to handle this more
16845 intelligently, but for now just redisplay from scratch. */
16846 if (!NILP (BVAR (XBUFFER (w->buffer), word_wrap)))
16847 GIVE_UP (21);
16848
16849 /* Under bidi reordering, adding or deleting a character in the
16850 beginning of a paragraph, before the first strong directional
16851 character, can change the base direction of the paragraph (unless
16852 the buffer specifies a fixed paragraph direction), which will
16853 require to redisplay the whole paragraph. It might be worthwhile
16854 to find the paragraph limits and widen the range of redisplayed
16855 lines to that, but for now just give up this optimization and
16856 redisplay from scratch. */
16857 if (!NILP (BVAR (XBUFFER (w->buffer), bidi_display_reordering))
16858 && NILP (BVAR (XBUFFER (w->buffer), bidi_paragraph_direction)))
16859 GIVE_UP (22);
16860
16861 /* Make sure beg_unchanged and end_unchanged are up to date. Do it
16862 only if buffer has really changed. The reason is that the gap is
16863 initially at Z for freshly visited files. The code below would
16864 set end_unchanged to 0 in that case. */
16865 if (MODIFF > SAVE_MODIFF
16866 /* This seems to happen sometimes after saving a buffer. */
16867 || BEG_UNCHANGED + END_UNCHANGED > Z_BYTE)
16868 {
16869 if (GPT - BEG < BEG_UNCHANGED)
16870 BEG_UNCHANGED = GPT - BEG;
16871 if (Z - GPT < END_UNCHANGED)
16872 END_UNCHANGED = Z - GPT;
16873 }
16874
16875 /* The position of the first and last character that has been changed. */
16876 first_changed_charpos = BEG + BEG_UNCHANGED;
16877 last_changed_charpos = Z - END_UNCHANGED;
16878
16879 /* If window starts after a line end, and the last change is in
16880 front of that newline, then changes don't affect the display.
16881 This case happens with stealth-fontification. Note that although
16882 the display is unchanged, glyph positions in the matrix have to
16883 be adjusted, of course. */
16884 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
16885 if (MATRIX_ROW_DISPLAYS_TEXT_P (row)
16886 && ((last_changed_charpos < CHARPOS (start)
16887 && CHARPOS (start) == BEGV)
16888 || (last_changed_charpos < CHARPOS (start) - 1
16889 && FETCH_BYTE (BYTEPOS (start) - 1) == '\n')))
16890 {
16891 EMACS_INT Z_old, Z_delta, Z_BYTE_old, Z_delta_bytes;
16892 struct glyph_row *r0;
16893
16894 /* Compute how many chars/bytes have been added to or removed
16895 from the buffer. */
16896 Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
16897 Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
16898 Z_delta = Z - Z_old;
16899 Z_delta_bytes = Z_BYTE - Z_BYTE_old;
16900
16901 /* Give up if PT is not in the window. Note that it already has
16902 been checked at the start of try_window_id that PT is not in
16903 front of the window start. */
16904 if (PT >= MATRIX_ROW_END_CHARPOS (row) + Z_delta)
16905 GIVE_UP (13);
16906
16907 /* If window start is unchanged, we can reuse the whole matrix
16908 as is, after adjusting glyph positions. No need to compute
16909 the window end again, since its offset from Z hasn't changed. */
16910 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
16911 if (CHARPOS (start) == MATRIX_ROW_START_CHARPOS (r0) + Z_delta
16912 && BYTEPOS (start) == MATRIX_ROW_START_BYTEPOS (r0) + Z_delta_bytes
16913 /* PT must not be in a partially visible line. */
16914 && !(PT >= MATRIX_ROW_START_CHARPOS (row) + Z_delta
16915 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
16916 {
16917 /* Adjust positions in the glyph matrix. */
16918 if (Z_delta || Z_delta_bytes)
16919 {
16920 struct glyph_row *r1
16921 = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
16922 increment_matrix_positions (w->current_matrix,
16923 MATRIX_ROW_VPOS (r0, current_matrix),
16924 MATRIX_ROW_VPOS (r1, current_matrix),
16925 Z_delta, Z_delta_bytes);
16926 }
16927
16928 /* Set the cursor. */
16929 row = row_containing_pos (w, PT, r0, NULL, 0);
16930 if (row)
16931 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
16932 else
16933 abort ();
16934 return 1;
16935 }
16936 }
16937
16938 /* Handle the case that changes are all below what is displayed in
16939 the window, and that PT is in the window. This shortcut cannot
16940 be taken if ZV is visible in the window, and text has been added
16941 there that is visible in the window. */
16942 if (first_changed_charpos >= MATRIX_ROW_END_CHARPOS (row)
16943 /* ZV is not visible in the window, or there are no
16944 changes at ZV, actually. */
16945 && (current_matrix->zv > MATRIX_ROW_END_CHARPOS (row)
16946 || first_changed_charpos == last_changed_charpos))
16947 {
16948 struct glyph_row *r0;
16949
16950 /* Give up if PT is not in the window. Note that it already has
16951 been checked at the start of try_window_id that PT is not in
16952 front of the window start. */
16953 if (PT >= MATRIX_ROW_END_CHARPOS (row))
16954 GIVE_UP (14);
16955
16956 /* If window start is unchanged, we can reuse the whole matrix
16957 as is, without changing glyph positions since no text has
16958 been added/removed in front of the window end. */
16959 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
16960 if (TEXT_POS_EQUAL_P (start, r0->minpos)
16961 /* PT must not be in a partially visible line. */
16962 && !(PT >= MATRIX_ROW_START_CHARPOS (row)
16963 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
16964 {
16965 /* We have to compute the window end anew since text
16966 could have been added/removed after it. */
16967 w->window_end_pos
16968 = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
16969 w->window_end_bytepos
16970 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
16971
16972 /* Set the cursor. */
16973 row = row_containing_pos (w, PT, r0, NULL, 0);
16974 if (row)
16975 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
16976 else
16977 abort ();
16978 return 2;
16979 }
16980 }
16981
16982 /* Give up if window start is in the changed area.
16983
16984 The condition used to read
16985
16986 (BEG_UNCHANGED + END_UNCHANGED != Z - BEG && ...)
16987
16988 but why that was tested escapes me at the moment. */
16989 if (CHARPOS (start) >= first_changed_charpos
16990 && CHARPOS (start) <= last_changed_charpos)
16991 GIVE_UP (15);
16992
16993 /* Check that window start agrees with the start of the first glyph
16994 row in its current matrix. Check this after we know the window
16995 start is not in changed text, otherwise positions would not be
16996 comparable. */
16997 row = MATRIX_FIRST_TEXT_ROW (current_matrix);
16998 if (!TEXT_POS_EQUAL_P (start, row->minpos))
16999 GIVE_UP (16);
17000
17001 /* Give up if the window ends in strings. Overlay strings
17002 at the end are difficult to handle, so don't try. */
17003 row = MATRIX_ROW (current_matrix, XFASTINT (w->window_end_vpos));
17004 if (MATRIX_ROW_START_CHARPOS (row) == MATRIX_ROW_END_CHARPOS (row))
17005 GIVE_UP (20);
17006
17007 /* Compute the position at which we have to start displaying new
17008 lines. Some of the lines at the top of the window might be
17009 reusable because they are not displaying changed text. Find the
17010 last row in W's current matrix not affected by changes at the
17011 start of current_buffer. Value is null if changes start in the
17012 first line of window. */
17013 last_unchanged_at_beg_row = find_last_unchanged_at_beg_row (w);
17014 if (last_unchanged_at_beg_row)
17015 {
17016 /* Avoid starting to display in the moddle of a character, a TAB
17017 for instance. This is easier than to set up the iterator
17018 exactly, and it's not a frequent case, so the additional
17019 effort wouldn't really pay off. */
17020 while ((MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row)
17021 || last_unchanged_at_beg_row->ends_in_newline_from_string_p)
17022 && last_unchanged_at_beg_row > w->current_matrix->rows)
17023 --last_unchanged_at_beg_row;
17024
17025 if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row))
17026 GIVE_UP (17);
17027
17028 if (init_to_row_end (&it, w, last_unchanged_at_beg_row) == 0)
17029 GIVE_UP (18);
17030 start_pos = it.current.pos;
17031
17032 /* Start displaying new lines in the desired matrix at the same
17033 vpos we would use in the current matrix, i.e. below
17034 last_unchanged_at_beg_row. */
17035 it.vpos = 1 + MATRIX_ROW_VPOS (last_unchanged_at_beg_row,
17036 current_matrix);
17037 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
17038 it.current_y = MATRIX_ROW_BOTTOM_Y (last_unchanged_at_beg_row);
17039
17040 xassert (it.hpos == 0 && it.current_x == 0);
17041 }
17042 else
17043 {
17044 /* There are no reusable lines at the start of the window.
17045 Start displaying in the first text line. */
17046 start_display (&it, w, start);
17047 it.vpos = it.first_vpos;
17048 start_pos = it.current.pos;
17049 }
17050
17051 /* Find the first row that is not affected by changes at the end of
17052 the buffer. Value will be null if there is no unchanged row, in
17053 which case we must redisplay to the end of the window. delta
17054 will be set to the value by which buffer positions beginning with
17055 first_unchanged_at_end_row have to be adjusted due to text
17056 changes. */
17057 first_unchanged_at_end_row
17058 = find_first_unchanged_at_end_row (w, &delta, &delta_bytes);
17059 IF_DEBUG (debug_delta = delta);
17060 IF_DEBUG (debug_delta_bytes = delta_bytes);
17061
17062 /* Set stop_pos to the buffer position up to which we will have to
17063 display new lines. If first_unchanged_at_end_row != NULL, this
17064 is the buffer position of the start of the line displayed in that
17065 row. For first_unchanged_at_end_row == NULL, use 0 to indicate
17066 that we don't stop at a buffer position. */
17067 stop_pos = 0;
17068 if (first_unchanged_at_end_row)
17069 {
17070 xassert (last_unchanged_at_beg_row == NULL
17071 || first_unchanged_at_end_row >= last_unchanged_at_beg_row);
17072
17073 /* If this is a continuation line, move forward to the next one
17074 that isn't. Changes in lines above affect this line.
17075 Caution: this may move first_unchanged_at_end_row to a row
17076 not displaying text. */
17077 while (MATRIX_ROW_CONTINUATION_LINE_P (first_unchanged_at_end_row)
17078 && MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
17079 && (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
17080 < it.last_visible_y))
17081 ++first_unchanged_at_end_row;
17082
17083 if (!MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
17084 || (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
17085 >= it.last_visible_y))
17086 first_unchanged_at_end_row = NULL;
17087 else
17088 {
17089 stop_pos = (MATRIX_ROW_START_CHARPOS (first_unchanged_at_end_row)
17090 + delta);
17091 first_unchanged_at_end_vpos
17092 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, current_matrix);
17093 xassert (stop_pos >= Z - END_UNCHANGED);
17094 }
17095 }
17096 else if (last_unchanged_at_beg_row == NULL)
17097 GIVE_UP (19);
17098
17099
17100 #if GLYPH_DEBUG
17101
17102 /* Either there is no unchanged row at the end, or the one we have
17103 now displays text. This is a necessary condition for the window
17104 end pos calculation at the end of this function. */
17105 xassert (first_unchanged_at_end_row == NULL
17106 || MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
17107
17108 debug_last_unchanged_at_beg_vpos
17109 = (last_unchanged_at_beg_row
17110 ? MATRIX_ROW_VPOS (last_unchanged_at_beg_row, current_matrix)
17111 : -1);
17112 debug_first_unchanged_at_end_vpos = first_unchanged_at_end_vpos;
17113
17114 #endif /* GLYPH_DEBUG != 0 */
17115
17116
17117 /* Display new lines. Set last_text_row to the last new line
17118 displayed which has text on it, i.e. might end up as being the
17119 line where the window_end_vpos is. */
17120 w->cursor.vpos = -1;
17121 last_text_row = NULL;
17122 overlay_arrow_seen = 0;
17123 while (it.current_y < it.last_visible_y
17124 && !fonts_changed_p
17125 && (first_unchanged_at_end_row == NULL
17126 || IT_CHARPOS (it) < stop_pos))
17127 {
17128 if (display_line (&it))
17129 last_text_row = it.glyph_row - 1;
17130 }
17131
17132 if (fonts_changed_p)
17133 return -1;
17134
17135
17136 /* Compute differences in buffer positions, y-positions etc. for
17137 lines reused at the bottom of the window. Compute what we can
17138 scroll. */
17139 if (first_unchanged_at_end_row
17140 /* No lines reused because we displayed everything up to the
17141 bottom of the window. */
17142 && it.current_y < it.last_visible_y)
17143 {
17144 dvpos = (it.vpos
17145 - MATRIX_ROW_VPOS (first_unchanged_at_end_row,
17146 current_matrix));
17147 dy = it.current_y - first_unchanged_at_end_row->y;
17148 run.current_y = first_unchanged_at_end_row->y;
17149 run.desired_y = run.current_y + dy;
17150 run.height = it.last_visible_y - max (run.current_y, run.desired_y);
17151 }
17152 else
17153 {
17154 delta = delta_bytes = dvpos = dy
17155 = run.current_y = run.desired_y = run.height = 0;
17156 first_unchanged_at_end_row = NULL;
17157 }
17158 IF_DEBUG (debug_dvpos = dvpos; debug_dy = dy);
17159
17160
17161 /* Find the cursor if not already found. We have to decide whether
17162 PT will appear on this window (it sometimes doesn't, but this is
17163 not a very frequent case.) This decision has to be made before
17164 the current matrix is altered. A value of cursor.vpos < 0 means
17165 that PT is either in one of the lines beginning at
17166 first_unchanged_at_end_row or below the window. Don't care for
17167 lines that might be displayed later at the window end; as
17168 mentioned, this is not a frequent case. */
17169 if (w->cursor.vpos < 0)
17170 {
17171 /* Cursor in unchanged rows at the top? */
17172 if (PT < CHARPOS (start_pos)
17173 && last_unchanged_at_beg_row)
17174 {
17175 row = row_containing_pos (w, PT,
17176 MATRIX_FIRST_TEXT_ROW (w->current_matrix),
17177 last_unchanged_at_beg_row + 1, 0);
17178 if (row)
17179 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
17180 }
17181
17182 /* Start from first_unchanged_at_end_row looking for PT. */
17183 else if (first_unchanged_at_end_row)
17184 {
17185 row = row_containing_pos (w, PT - delta,
17186 first_unchanged_at_end_row, NULL, 0);
17187 if (row)
17188 set_cursor_from_row (w, row, w->current_matrix, delta,
17189 delta_bytes, dy, dvpos);
17190 }
17191
17192 /* Give up if cursor was not found. */
17193 if (w->cursor.vpos < 0)
17194 {
17195 clear_glyph_matrix (w->desired_matrix);
17196 return -1;
17197 }
17198 }
17199
17200 /* Don't let the cursor end in the scroll margins. */
17201 {
17202 int this_scroll_margin, cursor_height;
17203
17204 this_scroll_margin =
17205 max (0, min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4));
17206 this_scroll_margin *= FRAME_LINE_HEIGHT (it.f);
17207 cursor_height = MATRIX_ROW (w->desired_matrix, w->cursor.vpos)->height;
17208
17209 if ((w->cursor.y < this_scroll_margin
17210 && CHARPOS (start) > BEGV)
17211 /* Old redisplay didn't take scroll margin into account at the bottom,
17212 but then global-hl-line-mode doesn't scroll. KFS 2004-06-14 */
17213 || (w->cursor.y + (make_cursor_line_fully_visible_p
17214 ? cursor_height + this_scroll_margin
17215 : 1)) > it.last_visible_y)
17216 {
17217 w->cursor.vpos = -1;
17218 clear_glyph_matrix (w->desired_matrix);
17219 return -1;
17220 }
17221 }
17222
17223 /* Scroll the display. Do it before changing the current matrix so
17224 that xterm.c doesn't get confused about where the cursor glyph is
17225 found. */
17226 if (dy && run.height)
17227 {
17228 update_begin (f);
17229
17230 if (FRAME_WINDOW_P (f))
17231 {
17232 FRAME_RIF (f)->update_window_begin_hook (w);
17233 FRAME_RIF (f)->clear_window_mouse_face (w);
17234 FRAME_RIF (f)->scroll_run_hook (w, &run);
17235 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
17236 }
17237 else
17238 {
17239 /* Terminal frame. In this case, dvpos gives the number of
17240 lines to scroll by; dvpos < 0 means scroll up. */
17241 int from_vpos
17242 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, w->current_matrix);
17243 int from = WINDOW_TOP_EDGE_LINE (w) + from_vpos;
17244 int end = (WINDOW_TOP_EDGE_LINE (w)
17245 + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0)
17246 + window_internal_height (w));
17247
17248 #if defined (HAVE_GPM) || defined (MSDOS)
17249 x_clear_window_mouse_face (w);
17250 #endif
17251 /* Perform the operation on the screen. */
17252 if (dvpos > 0)
17253 {
17254 /* Scroll last_unchanged_at_beg_row to the end of the
17255 window down dvpos lines. */
17256 set_terminal_window (f, end);
17257
17258 /* On dumb terminals delete dvpos lines at the end
17259 before inserting dvpos empty lines. */
17260 if (!FRAME_SCROLL_REGION_OK (f))
17261 ins_del_lines (f, end - dvpos, -dvpos);
17262
17263 /* Insert dvpos empty lines in front of
17264 last_unchanged_at_beg_row. */
17265 ins_del_lines (f, from, dvpos);
17266 }
17267 else if (dvpos < 0)
17268 {
17269 /* Scroll up last_unchanged_at_beg_vpos to the end of
17270 the window to last_unchanged_at_beg_vpos - |dvpos|. */
17271 set_terminal_window (f, end);
17272
17273 /* Delete dvpos lines in front of
17274 last_unchanged_at_beg_vpos. ins_del_lines will set
17275 the cursor to the given vpos and emit |dvpos| delete
17276 line sequences. */
17277 ins_del_lines (f, from + dvpos, dvpos);
17278
17279 /* On a dumb terminal insert dvpos empty lines at the
17280 end. */
17281 if (!FRAME_SCROLL_REGION_OK (f))
17282 ins_del_lines (f, end + dvpos, -dvpos);
17283 }
17284
17285 set_terminal_window (f, 0);
17286 }
17287
17288 update_end (f);
17289 }
17290
17291 /* Shift reused rows of the current matrix to the right position.
17292 BOTTOM_ROW is the last + 1 row in the current matrix reserved for
17293 text. */
17294 bottom_row = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
17295 bottom_vpos = MATRIX_ROW_VPOS (bottom_row, current_matrix);
17296 if (dvpos < 0)
17297 {
17298 rotate_matrix (current_matrix, first_unchanged_at_end_vpos + dvpos,
17299 bottom_vpos, dvpos);
17300 enable_glyph_matrix_rows (current_matrix, bottom_vpos + dvpos,
17301 bottom_vpos, 0);
17302 }
17303 else if (dvpos > 0)
17304 {
17305 rotate_matrix (current_matrix, first_unchanged_at_end_vpos,
17306 bottom_vpos, dvpos);
17307 enable_glyph_matrix_rows (current_matrix, first_unchanged_at_end_vpos,
17308 first_unchanged_at_end_vpos + dvpos, 0);
17309 }
17310
17311 /* For frame-based redisplay, make sure that current frame and window
17312 matrix are in sync with respect to glyph memory. */
17313 if (!FRAME_WINDOW_P (f))
17314 sync_frame_with_window_matrix_rows (w);
17315
17316 /* Adjust buffer positions in reused rows. */
17317 if (delta || delta_bytes)
17318 increment_matrix_positions (current_matrix,
17319 first_unchanged_at_end_vpos + dvpos,
17320 bottom_vpos, delta, delta_bytes);
17321
17322 /* Adjust Y positions. */
17323 if (dy)
17324 shift_glyph_matrix (w, current_matrix,
17325 first_unchanged_at_end_vpos + dvpos,
17326 bottom_vpos, dy);
17327
17328 if (first_unchanged_at_end_row)
17329 {
17330 first_unchanged_at_end_row += dvpos;
17331 if (first_unchanged_at_end_row->y >= it.last_visible_y
17332 || !MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row))
17333 first_unchanged_at_end_row = NULL;
17334 }
17335
17336 /* If scrolling up, there may be some lines to display at the end of
17337 the window. */
17338 last_text_row_at_end = NULL;
17339 if (dy < 0)
17340 {
17341 /* Scrolling up can leave for example a partially visible line
17342 at the end of the window to be redisplayed. */
17343 /* Set last_row to the glyph row in the current matrix where the
17344 window end line is found. It has been moved up or down in
17345 the matrix by dvpos. */
17346 int last_vpos = XFASTINT (w->window_end_vpos) + dvpos;
17347 struct glyph_row *last_row = MATRIX_ROW (current_matrix, last_vpos);
17348
17349 /* If last_row is the window end line, it should display text. */
17350 xassert (last_row->displays_text_p);
17351
17352 /* If window end line was partially visible before, begin
17353 displaying at that line. Otherwise begin displaying with the
17354 line following it. */
17355 if (MATRIX_ROW_BOTTOM_Y (last_row) - dy >= it.last_visible_y)
17356 {
17357 init_to_row_start (&it, w, last_row);
17358 it.vpos = last_vpos;
17359 it.current_y = last_row->y;
17360 }
17361 else
17362 {
17363 init_to_row_end (&it, w, last_row);
17364 it.vpos = 1 + last_vpos;
17365 it.current_y = MATRIX_ROW_BOTTOM_Y (last_row);
17366 ++last_row;
17367 }
17368
17369 /* We may start in a continuation line. If so, we have to
17370 get the right continuation_lines_width and current_x. */
17371 it.continuation_lines_width = last_row->continuation_lines_width;
17372 it.hpos = it.current_x = 0;
17373
17374 /* Display the rest of the lines at the window end. */
17375 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
17376 while (it.current_y < it.last_visible_y
17377 && !fonts_changed_p)
17378 {
17379 /* Is it always sure that the display agrees with lines in
17380 the current matrix? I don't think so, so we mark rows
17381 displayed invalid in the current matrix by setting their
17382 enabled_p flag to zero. */
17383 MATRIX_ROW (w->current_matrix, it.vpos)->enabled_p = 0;
17384 if (display_line (&it))
17385 last_text_row_at_end = it.glyph_row - 1;
17386 }
17387 }
17388
17389 /* Update window_end_pos and window_end_vpos. */
17390 if (first_unchanged_at_end_row
17391 && !last_text_row_at_end)
17392 {
17393 /* Window end line if one of the preserved rows from the current
17394 matrix. Set row to the last row displaying text in current
17395 matrix starting at first_unchanged_at_end_row, after
17396 scrolling. */
17397 xassert (first_unchanged_at_end_row->displays_text_p);
17398 row = find_last_row_displaying_text (w->current_matrix, &it,
17399 first_unchanged_at_end_row);
17400 xassert (row && MATRIX_ROW_DISPLAYS_TEXT_P (row));
17401
17402 w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
17403 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
17404 w->window_end_vpos
17405 = make_number (MATRIX_ROW_VPOS (row, w->current_matrix));
17406 xassert (w->window_end_bytepos >= 0);
17407 IF_DEBUG (debug_method_add (w, "A"));
17408 }
17409 else if (last_text_row_at_end)
17410 {
17411 w->window_end_pos
17412 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row_at_end));
17413 w->window_end_bytepos
17414 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row_at_end);
17415 w->window_end_vpos
17416 = make_number (MATRIX_ROW_VPOS (last_text_row_at_end, desired_matrix));
17417 xassert (w->window_end_bytepos >= 0);
17418 IF_DEBUG (debug_method_add (w, "B"));
17419 }
17420 else if (last_text_row)
17421 {
17422 /* We have displayed either to the end of the window or at the
17423 end of the window, i.e. the last row with text is to be found
17424 in the desired matrix. */
17425 w->window_end_pos
17426 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
17427 w->window_end_bytepos
17428 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
17429 w->window_end_vpos
17430 = make_number (MATRIX_ROW_VPOS (last_text_row, desired_matrix));
17431 xassert (w->window_end_bytepos >= 0);
17432 }
17433 else if (first_unchanged_at_end_row == NULL
17434 && last_text_row == NULL
17435 && last_text_row_at_end == NULL)
17436 {
17437 /* Displayed to end of window, but no line containing text was
17438 displayed. Lines were deleted at the end of the window. */
17439 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
17440 int vpos = XFASTINT (w->window_end_vpos);
17441 struct glyph_row *current_row = current_matrix->rows + vpos;
17442 struct glyph_row *desired_row = desired_matrix->rows + vpos;
17443
17444 for (row = NULL;
17445 row == NULL && vpos >= first_vpos;
17446 --vpos, --current_row, --desired_row)
17447 {
17448 if (desired_row->enabled_p)
17449 {
17450 if (desired_row->displays_text_p)
17451 row = desired_row;
17452 }
17453 else if (current_row->displays_text_p)
17454 row = current_row;
17455 }
17456
17457 xassert (row != NULL);
17458 w->window_end_vpos = make_number (vpos + 1);
17459 w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
17460 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
17461 xassert (w->window_end_bytepos >= 0);
17462 IF_DEBUG (debug_method_add (w, "C"));
17463 }
17464 else
17465 abort ();
17466
17467 IF_DEBUG (debug_end_pos = XFASTINT (w->window_end_pos);
17468 debug_end_vpos = XFASTINT (w->window_end_vpos));
17469
17470 /* Record that display has not been completed. */
17471 w->window_end_valid = Qnil;
17472 w->desired_matrix->no_scrolling_p = 1;
17473 return 3;
17474
17475 #undef GIVE_UP
17476 }
17477
17478
17479 \f
17480 /***********************************************************************
17481 More debugging support
17482 ***********************************************************************/
17483
17484 #if GLYPH_DEBUG
17485
17486 void dump_glyph_row (struct glyph_row *, int, int) EXTERNALLY_VISIBLE;
17487 void dump_glyph_matrix (struct glyph_matrix *, int) EXTERNALLY_VISIBLE;
17488 void dump_glyph (struct glyph_row *, struct glyph *, int) EXTERNALLY_VISIBLE;
17489
17490
17491 /* Dump the contents of glyph matrix MATRIX on stderr.
17492
17493 GLYPHS 0 means don't show glyph contents.
17494 GLYPHS 1 means show glyphs in short form
17495 GLYPHS > 1 means show glyphs in long form. */
17496
17497 void
17498 dump_glyph_matrix (struct glyph_matrix *matrix, int glyphs)
17499 {
17500 int i;
17501 for (i = 0; i < matrix->nrows; ++i)
17502 dump_glyph_row (MATRIX_ROW (matrix, i), i, glyphs);
17503 }
17504
17505
17506 /* Dump contents of glyph GLYPH to stderr. ROW and AREA are
17507 the glyph row and area where the glyph comes from. */
17508
17509 void
17510 dump_glyph (struct glyph_row *row, struct glyph *glyph, int area)
17511 {
17512 if (glyph->type == CHAR_GLYPH)
17513 {
17514 fprintf (stderr,
17515 " %5td %4c %6"pI"d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
17516 glyph - row->glyphs[TEXT_AREA],
17517 'C',
17518 glyph->charpos,
17519 (BUFFERP (glyph->object)
17520 ? 'B'
17521 : (STRINGP (glyph->object)
17522 ? 'S'
17523 : '-')),
17524 glyph->pixel_width,
17525 glyph->u.ch,
17526 (glyph->u.ch < 0x80 && glyph->u.ch >= ' '
17527 ? glyph->u.ch
17528 : '.'),
17529 glyph->face_id,
17530 glyph->left_box_line_p,
17531 glyph->right_box_line_p);
17532 }
17533 else if (glyph->type == STRETCH_GLYPH)
17534 {
17535 fprintf (stderr,
17536 " %5td %4c %6"pI"d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
17537 glyph - row->glyphs[TEXT_AREA],
17538 'S',
17539 glyph->charpos,
17540 (BUFFERP (glyph->object)
17541 ? 'B'
17542 : (STRINGP (glyph->object)
17543 ? 'S'
17544 : '-')),
17545 glyph->pixel_width,
17546 0,
17547 '.',
17548 glyph->face_id,
17549 glyph->left_box_line_p,
17550 glyph->right_box_line_p);
17551 }
17552 else if (glyph->type == IMAGE_GLYPH)
17553 {
17554 fprintf (stderr,
17555 " %5td %4c %6"pI"d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
17556 glyph - row->glyphs[TEXT_AREA],
17557 'I',
17558 glyph->charpos,
17559 (BUFFERP (glyph->object)
17560 ? 'B'
17561 : (STRINGP (glyph->object)
17562 ? 'S'
17563 : '-')),
17564 glyph->pixel_width,
17565 glyph->u.img_id,
17566 '.',
17567 glyph->face_id,
17568 glyph->left_box_line_p,
17569 glyph->right_box_line_p);
17570 }
17571 else if (glyph->type == COMPOSITE_GLYPH)
17572 {
17573 fprintf (stderr,
17574 " %5td %4c %6"pI"d %c %3d 0x%05x",
17575 glyph - row->glyphs[TEXT_AREA],
17576 '+',
17577 glyph->charpos,
17578 (BUFFERP (glyph->object)
17579 ? 'B'
17580 : (STRINGP (glyph->object)
17581 ? 'S'
17582 : '-')),
17583 glyph->pixel_width,
17584 glyph->u.cmp.id);
17585 if (glyph->u.cmp.automatic)
17586 fprintf (stderr,
17587 "[%d-%d]",
17588 glyph->slice.cmp.from, glyph->slice.cmp.to);
17589 fprintf (stderr, " . %4d %1.1d%1.1d\n",
17590 glyph->face_id,
17591 glyph->left_box_line_p,
17592 glyph->right_box_line_p);
17593 }
17594 }
17595
17596
17597 /* Dump the contents of glyph row at VPOS in MATRIX to stderr.
17598 GLYPHS 0 means don't show glyph contents.
17599 GLYPHS 1 means show glyphs in short form
17600 GLYPHS > 1 means show glyphs in long form. */
17601
17602 void
17603 dump_glyph_row (struct glyph_row *row, int vpos, int glyphs)
17604 {
17605 if (glyphs != 1)
17606 {
17607 fprintf (stderr, "Row Start End Used oE><\\CTZFesm X Y W H V A P\n");
17608 fprintf (stderr, "======================================================================\n");
17609
17610 fprintf (stderr, "%3d %5"pI"d %5"pI"d %4d %1.1d%1.1d%1.1d%1.1d\
17611 %1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d %4d %4d %4d %4d %4d %4d %4d\n",
17612 vpos,
17613 MATRIX_ROW_START_CHARPOS (row),
17614 MATRIX_ROW_END_CHARPOS (row),
17615 row->used[TEXT_AREA],
17616 row->contains_overlapping_glyphs_p,
17617 row->enabled_p,
17618 row->truncated_on_left_p,
17619 row->truncated_on_right_p,
17620 row->continued_p,
17621 MATRIX_ROW_CONTINUATION_LINE_P (row),
17622 row->displays_text_p,
17623 row->ends_at_zv_p,
17624 row->fill_line_p,
17625 row->ends_in_middle_of_char_p,
17626 row->starts_in_middle_of_char_p,
17627 row->mouse_face_p,
17628 row->x,
17629 row->y,
17630 row->pixel_width,
17631 row->height,
17632 row->visible_height,
17633 row->ascent,
17634 row->phys_ascent);
17635 fprintf (stderr, "%9d %5d\t%5d\n", row->start.overlay_string_index,
17636 row->end.overlay_string_index,
17637 row->continuation_lines_width);
17638 fprintf (stderr, "%9"pI"d %5"pI"d\n",
17639 CHARPOS (row->start.string_pos),
17640 CHARPOS (row->end.string_pos));
17641 fprintf (stderr, "%9d %5d\n", row->start.dpvec_index,
17642 row->end.dpvec_index);
17643 }
17644
17645 if (glyphs > 1)
17646 {
17647 int area;
17648
17649 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
17650 {
17651 struct glyph *glyph = row->glyphs[area];
17652 struct glyph *glyph_end = glyph + row->used[area];
17653
17654 /* Glyph for a line end in text. */
17655 if (area == TEXT_AREA && glyph == glyph_end && glyph->charpos > 0)
17656 ++glyph_end;
17657
17658 if (glyph < glyph_end)
17659 fprintf (stderr, " Glyph Type Pos O W Code C Face LR\n");
17660
17661 for (; glyph < glyph_end; ++glyph)
17662 dump_glyph (row, glyph, area);
17663 }
17664 }
17665 else if (glyphs == 1)
17666 {
17667 int area;
17668
17669 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
17670 {
17671 char *s = (char *) alloca (row->used[area] + 1);
17672 int i;
17673
17674 for (i = 0; i < row->used[area]; ++i)
17675 {
17676 struct glyph *glyph = row->glyphs[area] + i;
17677 if (glyph->type == CHAR_GLYPH
17678 && glyph->u.ch < 0x80
17679 && glyph->u.ch >= ' ')
17680 s[i] = glyph->u.ch;
17681 else
17682 s[i] = '.';
17683 }
17684
17685 s[i] = '\0';
17686 fprintf (stderr, "%3d: (%d) '%s'\n", vpos, row->enabled_p, s);
17687 }
17688 }
17689 }
17690
17691
17692 DEFUN ("dump-glyph-matrix", Fdump_glyph_matrix,
17693 Sdump_glyph_matrix, 0, 1, "p",
17694 doc: /* Dump the current matrix of the selected window to stderr.
17695 Shows contents of glyph row structures. With non-nil
17696 parameter GLYPHS, dump glyphs as well. If GLYPHS is 1 show
17697 glyphs in short form, otherwise show glyphs in long form. */)
17698 (Lisp_Object glyphs)
17699 {
17700 struct window *w = XWINDOW (selected_window);
17701 struct buffer *buffer = XBUFFER (w->buffer);
17702
17703 fprintf (stderr, "PT = %"pI"d, BEGV = %"pI"d. ZV = %"pI"d\n",
17704 BUF_PT (buffer), BUF_BEGV (buffer), BUF_ZV (buffer));
17705 fprintf (stderr, "Cursor x = %d, y = %d, hpos = %d, vpos = %d\n",
17706 w->cursor.x, w->cursor.y, w->cursor.hpos, w->cursor.vpos);
17707 fprintf (stderr, "=============================================\n");
17708 dump_glyph_matrix (w->current_matrix,
17709 NILP (glyphs) ? 0 : XINT (glyphs));
17710 return Qnil;
17711 }
17712
17713
17714 DEFUN ("dump-frame-glyph-matrix", Fdump_frame_glyph_matrix,
17715 Sdump_frame_glyph_matrix, 0, 0, "", doc: /* */)
17716 (void)
17717 {
17718 struct frame *f = XFRAME (selected_frame);
17719 dump_glyph_matrix (f->current_matrix, 1);
17720 return Qnil;
17721 }
17722
17723
17724 DEFUN ("dump-glyph-row", Fdump_glyph_row, Sdump_glyph_row, 1, 2, "",
17725 doc: /* Dump glyph row ROW to stderr.
17726 GLYPH 0 means don't dump glyphs.
17727 GLYPH 1 means dump glyphs in short form.
17728 GLYPH > 1 or omitted means dump glyphs in long form. */)
17729 (Lisp_Object row, Lisp_Object glyphs)
17730 {
17731 struct glyph_matrix *matrix;
17732 int vpos;
17733
17734 CHECK_NUMBER (row);
17735 matrix = XWINDOW (selected_window)->current_matrix;
17736 vpos = XINT (row);
17737 if (vpos >= 0 && vpos < matrix->nrows)
17738 dump_glyph_row (MATRIX_ROW (matrix, vpos),
17739 vpos,
17740 INTEGERP (glyphs) ? XINT (glyphs) : 2);
17741 return Qnil;
17742 }
17743
17744
17745 DEFUN ("dump-tool-bar-row", Fdump_tool_bar_row, Sdump_tool_bar_row, 1, 2, "",
17746 doc: /* Dump glyph row ROW of the tool-bar of the current frame to stderr.
17747 GLYPH 0 means don't dump glyphs.
17748 GLYPH 1 means dump glyphs in short form.
17749 GLYPH > 1 or omitted means dump glyphs in long form. */)
17750 (Lisp_Object row, Lisp_Object glyphs)
17751 {
17752 struct frame *sf = SELECTED_FRAME ();
17753 struct glyph_matrix *m = XWINDOW (sf->tool_bar_window)->current_matrix;
17754 int vpos;
17755
17756 CHECK_NUMBER (row);
17757 vpos = XINT (row);
17758 if (vpos >= 0 && vpos < m->nrows)
17759 dump_glyph_row (MATRIX_ROW (m, vpos), vpos,
17760 INTEGERP (glyphs) ? XINT (glyphs) : 2);
17761 return Qnil;
17762 }
17763
17764
17765 DEFUN ("trace-redisplay", Ftrace_redisplay, Strace_redisplay, 0, 1, "P",
17766 doc: /* Toggle tracing of redisplay.
17767 With ARG, turn tracing on if and only if ARG is positive. */)
17768 (Lisp_Object arg)
17769 {
17770 if (NILP (arg))
17771 trace_redisplay_p = !trace_redisplay_p;
17772 else
17773 {
17774 arg = Fprefix_numeric_value (arg);
17775 trace_redisplay_p = XINT (arg) > 0;
17776 }
17777
17778 return Qnil;
17779 }
17780
17781
17782 DEFUN ("trace-to-stderr", Ftrace_to_stderr, Strace_to_stderr, 1, MANY, "",
17783 doc: /* Like `format', but print result to stderr.
17784 usage: (trace-to-stderr STRING &rest OBJECTS) */)
17785 (ptrdiff_t nargs, Lisp_Object *args)
17786 {
17787 Lisp_Object s = Fformat (nargs, args);
17788 fprintf (stderr, "%s", SDATA (s));
17789 return Qnil;
17790 }
17791
17792 #endif /* GLYPH_DEBUG */
17793
17794
17795 \f
17796 /***********************************************************************
17797 Building Desired Matrix Rows
17798 ***********************************************************************/
17799
17800 /* Return a temporary glyph row holding the glyphs of an overlay arrow.
17801 Used for non-window-redisplay windows, and for windows w/o left fringe. */
17802
17803 static struct glyph_row *
17804 get_overlay_arrow_glyph_row (struct window *w, Lisp_Object overlay_arrow_string)
17805 {
17806 struct frame *f = XFRAME (WINDOW_FRAME (w));
17807 struct buffer *buffer = XBUFFER (w->buffer);
17808 struct buffer *old = current_buffer;
17809 const unsigned char *arrow_string = SDATA (overlay_arrow_string);
17810 int arrow_len = SCHARS (overlay_arrow_string);
17811 const unsigned char *arrow_end = arrow_string + arrow_len;
17812 const unsigned char *p;
17813 struct it it;
17814 int multibyte_p;
17815 int n_glyphs_before;
17816
17817 set_buffer_temp (buffer);
17818 init_iterator (&it, w, -1, -1, &scratch_glyph_row, DEFAULT_FACE_ID);
17819 it.glyph_row->used[TEXT_AREA] = 0;
17820 SET_TEXT_POS (it.position, 0, 0);
17821
17822 multibyte_p = !NILP (BVAR (buffer, enable_multibyte_characters));
17823 p = arrow_string;
17824 while (p < arrow_end)
17825 {
17826 Lisp_Object face, ilisp;
17827
17828 /* Get the next character. */
17829 if (multibyte_p)
17830 it.c = it.char_to_display = string_char_and_length (p, &it.len);
17831 else
17832 {
17833 it.c = it.char_to_display = *p, it.len = 1;
17834 if (! ASCII_CHAR_P (it.c))
17835 it.char_to_display = BYTE8_TO_CHAR (it.c);
17836 }
17837 p += it.len;
17838
17839 /* Get its face. */
17840 ilisp = make_number (p - arrow_string);
17841 face = Fget_text_property (ilisp, Qface, overlay_arrow_string);
17842 it.face_id = compute_char_face (f, it.char_to_display, face);
17843
17844 /* Compute its width, get its glyphs. */
17845 n_glyphs_before = it.glyph_row->used[TEXT_AREA];
17846 SET_TEXT_POS (it.position, -1, -1);
17847 PRODUCE_GLYPHS (&it);
17848
17849 /* If this character doesn't fit any more in the line, we have
17850 to remove some glyphs. */
17851 if (it.current_x > it.last_visible_x)
17852 {
17853 it.glyph_row->used[TEXT_AREA] = n_glyphs_before;
17854 break;
17855 }
17856 }
17857
17858 set_buffer_temp (old);
17859 return it.glyph_row;
17860 }
17861
17862
17863 /* Insert truncation glyphs at the start of IT->glyph_row. Truncation
17864 glyphs are only inserted for terminal frames since we can't really
17865 win with truncation glyphs when partially visible glyphs are
17866 involved. Which glyphs to insert is determined by
17867 produce_special_glyphs. */
17868
17869 static void
17870 insert_left_trunc_glyphs (struct it *it)
17871 {
17872 struct it truncate_it;
17873 struct glyph *from, *end, *to, *toend;
17874
17875 xassert (!FRAME_WINDOW_P (it->f));
17876
17877 /* Get the truncation glyphs. */
17878 truncate_it = *it;
17879 truncate_it.current_x = 0;
17880 truncate_it.face_id = DEFAULT_FACE_ID;
17881 truncate_it.glyph_row = &scratch_glyph_row;
17882 truncate_it.glyph_row->used[TEXT_AREA] = 0;
17883 CHARPOS (truncate_it.position) = BYTEPOS (truncate_it.position) = -1;
17884 truncate_it.object = make_number (0);
17885 produce_special_glyphs (&truncate_it, IT_TRUNCATION);
17886
17887 /* Overwrite glyphs from IT with truncation glyphs. */
17888 if (!it->glyph_row->reversed_p)
17889 {
17890 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
17891 end = from + truncate_it.glyph_row->used[TEXT_AREA];
17892 to = it->glyph_row->glyphs[TEXT_AREA];
17893 toend = to + it->glyph_row->used[TEXT_AREA];
17894
17895 while (from < end)
17896 *to++ = *from++;
17897
17898 /* There may be padding glyphs left over. Overwrite them too. */
17899 while (to < toend && CHAR_GLYPH_PADDING_P (*to))
17900 {
17901 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
17902 while (from < end)
17903 *to++ = *from++;
17904 }
17905
17906 if (to > toend)
17907 it->glyph_row->used[TEXT_AREA] = to - it->glyph_row->glyphs[TEXT_AREA];
17908 }
17909 else
17910 {
17911 /* In R2L rows, overwrite the last (rightmost) glyphs, and do
17912 that back to front. */
17913 end = truncate_it.glyph_row->glyphs[TEXT_AREA];
17914 from = end + truncate_it.glyph_row->used[TEXT_AREA] - 1;
17915 toend = it->glyph_row->glyphs[TEXT_AREA];
17916 to = toend + it->glyph_row->used[TEXT_AREA] - 1;
17917
17918 while (from >= end && to >= toend)
17919 *to-- = *from--;
17920 while (to >= toend && CHAR_GLYPH_PADDING_P (*to))
17921 {
17922 from =
17923 truncate_it.glyph_row->glyphs[TEXT_AREA]
17924 + truncate_it.glyph_row->used[TEXT_AREA] - 1;
17925 while (from >= end && to >= toend)
17926 *to-- = *from--;
17927 }
17928 if (from >= end)
17929 {
17930 /* Need to free some room before prepending additional
17931 glyphs. */
17932 int move_by = from - end + 1;
17933 struct glyph *g0 = it->glyph_row->glyphs[TEXT_AREA];
17934 struct glyph *g = g0 + it->glyph_row->used[TEXT_AREA] - 1;
17935
17936 for ( ; g >= g0; g--)
17937 g[move_by] = *g;
17938 while (from >= end)
17939 *to-- = *from--;
17940 it->glyph_row->used[TEXT_AREA] += move_by;
17941 }
17942 }
17943 }
17944
17945
17946 /* Compute the pixel height and width of IT->glyph_row.
17947
17948 Most of the time, ascent and height of a display line will be equal
17949 to the max_ascent and max_height values of the display iterator
17950 structure. This is not the case if
17951
17952 1. We hit ZV without displaying anything. In this case, max_ascent
17953 and max_height will be zero.
17954
17955 2. We have some glyphs that don't contribute to the line height.
17956 (The glyph row flag contributes_to_line_height_p is for future
17957 pixmap extensions).
17958
17959 The first case is easily covered by using default values because in
17960 these cases, the line height does not really matter, except that it
17961 must not be zero. */
17962
17963 static void
17964 compute_line_metrics (struct it *it)
17965 {
17966 struct glyph_row *row = it->glyph_row;
17967
17968 if (FRAME_WINDOW_P (it->f))
17969 {
17970 int i, min_y, max_y;
17971
17972 /* The line may consist of one space only, that was added to
17973 place the cursor on it. If so, the row's height hasn't been
17974 computed yet. */
17975 if (row->height == 0)
17976 {
17977 if (it->max_ascent + it->max_descent == 0)
17978 it->max_descent = it->max_phys_descent = FRAME_LINE_HEIGHT (it->f);
17979 row->ascent = it->max_ascent;
17980 row->height = it->max_ascent + it->max_descent;
17981 row->phys_ascent = it->max_phys_ascent;
17982 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
17983 row->extra_line_spacing = it->max_extra_line_spacing;
17984 }
17985
17986 /* Compute the width of this line. */
17987 row->pixel_width = row->x;
17988 for (i = 0; i < row->used[TEXT_AREA]; ++i)
17989 row->pixel_width += row->glyphs[TEXT_AREA][i].pixel_width;
17990
17991 xassert (row->pixel_width >= 0);
17992 xassert (row->ascent >= 0 && row->height > 0);
17993
17994 row->overlapping_p = (MATRIX_ROW_OVERLAPS_SUCC_P (row)
17995 || MATRIX_ROW_OVERLAPS_PRED_P (row));
17996
17997 /* If first line's physical ascent is larger than its logical
17998 ascent, use the physical ascent, and make the row taller.
17999 This makes accented characters fully visible. */
18000 if (row == MATRIX_FIRST_TEXT_ROW (it->w->desired_matrix)
18001 && row->phys_ascent > row->ascent)
18002 {
18003 row->height += row->phys_ascent - row->ascent;
18004 row->ascent = row->phys_ascent;
18005 }
18006
18007 /* Compute how much of the line is visible. */
18008 row->visible_height = row->height;
18009
18010 min_y = WINDOW_HEADER_LINE_HEIGHT (it->w);
18011 max_y = WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w);
18012
18013 if (row->y < min_y)
18014 row->visible_height -= min_y - row->y;
18015 if (row->y + row->height > max_y)
18016 row->visible_height -= row->y + row->height - max_y;
18017 }
18018 else
18019 {
18020 row->pixel_width = row->used[TEXT_AREA];
18021 if (row->continued_p)
18022 row->pixel_width -= it->continuation_pixel_width;
18023 else if (row->truncated_on_right_p)
18024 row->pixel_width -= it->truncation_pixel_width;
18025 row->ascent = row->phys_ascent = 0;
18026 row->height = row->phys_height = row->visible_height = 1;
18027 row->extra_line_spacing = 0;
18028 }
18029
18030 /* Compute a hash code for this row. */
18031 {
18032 int area, i;
18033 row->hash = 0;
18034 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
18035 for (i = 0; i < row->used[area]; ++i)
18036 row->hash = ((((row->hash << 4) + (row->hash >> 24)) & 0x0fffffff)
18037 + row->glyphs[area][i].u.val
18038 + row->glyphs[area][i].face_id
18039 + row->glyphs[area][i].padding_p
18040 + (row->glyphs[area][i].type << 2));
18041 }
18042
18043 it->max_ascent = it->max_descent = 0;
18044 it->max_phys_ascent = it->max_phys_descent = 0;
18045 }
18046
18047
18048 /* Append one space to the glyph row of iterator IT if doing a
18049 window-based redisplay. The space has the same face as
18050 IT->face_id. Value is non-zero if a space was added.
18051
18052 This function is called to make sure that there is always one glyph
18053 at the end of a glyph row that the cursor can be set on under
18054 window-systems. (If there weren't such a glyph we would not know
18055 how wide and tall a box cursor should be displayed).
18056
18057 At the same time this space let's a nicely handle clearing to the
18058 end of the line if the row ends in italic text. */
18059
18060 static int
18061 append_space_for_newline (struct it *it, int default_face_p)
18062 {
18063 if (FRAME_WINDOW_P (it->f))
18064 {
18065 int n = it->glyph_row->used[TEXT_AREA];
18066
18067 if (it->glyph_row->glyphs[TEXT_AREA] + n
18068 < it->glyph_row->glyphs[1 + TEXT_AREA])
18069 {
18070 /* Save some values that must not be changed.
18071 Must save IT->c and IT->len because otherwise
18072 ITERATOR_AT_END_P wouldn't work anymore after
18073 append_space_for_newline has been called. */
18074 enum display_element_type saved_what = it->what;
18075 int saved_c = it->c, saved_len = it->len;
18076 int saved_char_to_display = it->char_to_display;
18077 int saved_x = it->current_x;
18078 int saved_face_id = it->face_id;
18079 struct text_pos saved_pos;
18080 Lisp_Object saved_object;
18081 struct face *face;
18082
18083 saved_object = it->object;
18084 saved_pos = it->position;
18085
18086 it->what = IT_CHARACTER;
18087 memset (&it->position, 0, sizeof it->position);
18088 it->object = make_number (0);
18089 it->c = it->char_to_display = ' ';
18090 it->len = 1;
18091
18092 if (default_face_p)
18093 it->face_id = DEFAULT_FACE_ID;
18094 else if (it->face_before_selective_p)
18095 it->face_id = it->saved_face_id;
18096 face = FACE_FROM_ID (it->f, it->face_id);
18097 it->face_id = FACE_FOR_CHAR (it->f, face, 0, -1, Qnil);
18098
18099 PRODUCE_GLYPHS (it);
18100
18101 it->override_ascent = -1;
18102 it->constrain_row_ascent_descent_p = 0;
18103 it->current_x = saved_x;
18104 it->object = saved_object;
18105 it->position = saved_pos;
18106 it->what = saved_what;
18107 it->face_id = saved_face_id;
18108 it->len = saved_len;
18109 it->c = saved_c;
18110 it->char_to_display = saved_char_to_display;
18111 return 1;
18112 }
18113 }
18114
18115 return 0;
18116 }
18117
18118
18119 /* Extend the face of the last glyph in the text area of IT->glyph_row
18120 to the end of the display line. Called from display_line. If the
18121 glyph row is empty, add a space glyph to it so that we know the
18122 face to draw. Set the glyph row flag fill_line_p. If the glyph
18123 row is R2L, prepend a stretch glyph to cover the empty space to the
18124 left of the leftmost glyph. */
18125
18126 static void
18127 extend_face_to_end_of_line (struct it *it)
18128 {
18129 struct face *face;
18130 struct frame *f = it->f;
18131
18132 /* If line is already filled, do nothing. Non window-system frames
18133 get a grace of one more ``pixel'' because their characters are
18134 1-``pixel'' wide, so they hit the equality too early. This grace
18135 is needed only for R2L rows that are not continued, to produce
18136 one extra blank where we could display the cursor. */
18137 if (it->current_x >= it->last_visible_x
18138 + (!FRAME_WINDOW_P (f)
18139 && it->glyph_row->reversed_p
18140 && !it->glyph_row->continued_p))
18141 return;
18142
18143 /* Face extension extends the background and box of IT->face_id
18144 to the end of the line. If the background equals the background
18145 of the frame, we don't have to do anything. */
18146 if (it->face_before_selective_p)
18147 face = FACE_FROM_ID (f, it->saved_face_id);
18148 else
18149 face = FACE_FROM_ID (f, it->face_id);
18150
18151 if (FRAME_WINDOW_P (f)
18152 && it->glyph_row->displays_text_p
18153 && face->box == FACE_NO_BOX
18154 && face->background == FRAME_BACKGROUND_PIXEL (f)
18155 && !face->stipple
18156 && !it->glyph_row->reversed_p)
18157 return;
18158
18159 /* Set the glyph row flag indicating that the face of the last glyph
18160 in the text area has to be drawn to the end of the text area. */
18161 it->glyph_row->fill_line_p = 1;
18162
18163 /* If current character of IT is not ASCII, make sure we have the
18164 ASCII face. This will be automatically undone the next time
18165 get_next_display_element returns a multibyte character. Note
18166 that the character will always be single byte in unibyte
18167 text. */
18168 if (!ASCII_CHAR_P (it->c))
18169 {
18170 it->face_id = FACE_FOR_CHAR (f, face, 0, -1, Qnil);
18171 }
18172
18173 if (FRAME_WINDOW_P (f))
18174 {
18175 /* If the row is empty, add a space with the current face of IT,
18176 so that we know which face to draw. */
18177 if (it->glyph_row->used[TEXT_AREA] == 0)
18178 {
18179 it->glyph_row->glyphs[TEXT_AREA][0] = space_glyph;
18180 it->glyph_row->glyphs[TEXT_AREA][0].face_id = it->face_id;
18181 it->glyph_row->used[TEXT_AREA] = 1;
18182 }
18183 #ifdef HAVE_WINDOW_SYSTEM
18184 if (it->glyph_row->reversed_p)
18185 {
18186 /* Prepend a stretch glyph to the row, such that the
18187 rightmost glyph will be drawn flushed all the way to the
18188 right margin of the window. The stretch glyph that will
18189 occupy the empty space, if any, to the left of the
18190 glyphs. */
18191 struct font *font = face->font ? face->font : FRAME_FONT (f);
18192 struct glyph *row_start = it->glyph_row->glyphs[TEXT_AREA];
18193 struct glyph *row_end = row_start + it->glyph_row->used[TEXT_AREA];
18194 struct glyph *g;
18195 int row_width, stretch_ascent, stretch_width;
18196 struct text_pos saved_pos;
18197 int saved_face_id, saved_avoid_cursor;
18198
18199 for (row_width = 0, g = row_start; g < row_end; g++)
18200 row_width += g->pixel_width;
18201 stretch_width = window_box_width (it->w, TEXT_AREA) - row_width;
18202 if (stretch_width > 0)
18203 {
18204 stretch_ascent =
18205 (((it->ascent + it->descent)
18206 * FONT_BASE (font)) / FONT_HEIGHT (font));
18207 saved_pos = it->position;
18208 memset (&it->position, 0, sizeof it->position);
18209 saved_avoid_cursor = it->avoid_cursor_p;
18210 it->avoid_cursor_p = 1;
18211 saved_face_id = it->face_id;
18212 /* The last row's stretch glyph should get the default
18213 face, to avoid painting the rest of the window with
18214 the region face, if the region ends at ZV. */
18215 if (it->glyph_row->ends_at_zv_p)
18216 it->face_id = DEFAULT_FACE_ID;
18217 else
18218 it->face_id = face->id;
18219 append_stretch_glyph (it, make_number (0), stretch_width,
18220 it->ascent + it->descent, stretch_ascent);
18221 it->position = saved_pos;
18222 it->avoid_cursor_p = saved_avoid_cursor;
18223 it->face_id = saved_face_id;
18224 }
18225 }
18226 #endif /* HAVE_WINDOW_SYSTEM */
18227 }
18228 else
18229 {
18230 /* Save some values that must not be changed. */
18231 int saved_x = it->current_x;
18232 struct text_pos saved_pos;
18233 Lisp_Object saved_object;
18234 enum display_element_type saved_what = it->what;
18235 int saved_face_id = it->face_id;
18236
18237 saved_object = it->object;
18238 saved_pos = it->position;
18239
18240 it->what = IT_CHARACTER;
18241 memset (&it->position, 0, sizeof it->position);
18242 it->object = make_number (0);
18243 it->c = it->char_to_display = ' ';
18244 it->len = 1;
18245 /* The last row's blank glyphs should get the default face, to
18246 avoid painting the rest of the window with the region face,
18247 if the region ends at ZV. */
18248 if (it->glyph_row->ends_at_zv_p)
18249 it->face_id = DEFAULT_FACE_ID;
18250 else
18251 it->face_id = face->id;
18252
18253 PRODUCE_GLYPHS (it);
18254
18255 while (it->current_x <= it->last_visible_x)
18256 PRODUCE_GLYPHS (it);
18257
18258 /* Don't count these blanks really. It would let us insert a left
18259 truncation glyph below and make us set the cursor on them, maybe. */
18260 it->current_x = saved_x;
18261 it->object = saved_object;
18262 it->position = saved_pos;
18263 it->what = saved_what;
18264 it->face_id = saved_face_id;
18265 }
18266 }
18267
18268
18269 /* Value is non-zero if text starting at CHARPOS in current_buffer is
18270 trailing whitespace. */
18271
18272 static int
18273 trailing_whitespace_p (EMACS_INT charpos)
18274 {
18275 EMACS_INT bytepos = CHAR_TO_BYTE (charpos);
18276 int c = 0;
18277
18278 while (bytepos < ZV_BYTE
18279 && (c = FETCH_CHAR (bytepos),
18280 c == ' ' || c == '\t'))
18281 ++bytepos;
18282
18283 if (bytepos >= ZV_BYTE || c == '\n' || c == '\r')
18284 {
18285 if (bytepos != PT_BYTE)
18286 return 1;
18287 }
18288 return 0;
18289 }
18290
18291
18292 /* Highlight trailing whitespace, if any, in ROW. */
18293
18294 static void
18295 highlight_trailing_whitespace (struct frame *f, struct glyph_row *row)
18296 {
18297 int used = row->used[TEXT_AREA];
18298
18299 if (used)
18300 {
18301 struct glyph *start = row->glyphs[TEXT_AREA];
18302 struct glyph *glyph = start + used - 1;
18303
18304 if (row->reversed_p)
18305 {
18306 /* Right-to-left rows need to be processed in the opposite
18307 direction, so swap the edge pointers. */
18308 glyph = start;
18309 start = row->glyphs[TEXT_AREA] + used - 1;
18310 }
18311
18312 /* Skip over glyphs inserted to display the cursor at the
18313 end of a line, for extending the face of the last glyph
18314 to the end of the line on terminals, and for truncation
18315 and continuation glyphs. */
18316 if (!row->reversed_p)
18317 {
18318 while (glyph >= start
18319 && glyph->type == CHAR_GLYPH
18320 && INTEGERP (glyph->object))
18321 --glyph;
18322 }
18323 else
18324 {
18325 while (glyph <= start
18326 && glyph->type == CHAR_GLYPH
18327 && INTEGERP (glyph->object))
18328 ++glyph;
18329 }
18330
18331 /* If last glyph is a space or stretch, and it's trailing
18332 whitespace, set the face of all trailing whitespace glyphs in
18333 IT->glyph_row to `trailing-whitespace'. */
18334 if ((row->reversed_p ? glyph <= start : glyph >= start)
18335 && BUFFERP (glyph->object)
18336 && (glyph->type == STRETCH_GLYPH
18337 || (glyph->type == CHAR_GLYPH
18338 && glyph->u.ch == ' '))
18339 && trailing_whitespace_p (glyph->charpos))
18340 {
18341 int face_id = lookup_named_face (f, Qtrailing_whitespace, 0);
18342 if (face_id < 0)
18343 return;
18344
18345 if (!row->reversed_p)
18346 {
18347 while (glyph >= start
18348 && BUFFERP (glyph->object)
18349 && (glyph->type == STRETCH_GLYPH
18350 || (glyph->type == CHAR_GLYPH
18351 && glyph->u.ch == ' ')))
18352 (glyph--)->face_id = face_id;
18353 }
18354 else
18355 {
18356 while (glyph <= start
18357 && BUFFERP (glyph->object)
18358 && (glyph->type == STRETCH_GLYPH
18359 || (glyph->type == CHAR_GLYPH
18360 && glyph->u.ch == ' ')))
18361 (glyph++)->face_id = face_id;
18362 }
18363 }
18364 }
18365 }
18366
18367
18368 /* Value is non-zero if glyph row ROW should be
18369 used to hold the cursor. */
18370
18371 static int
18372 cursor_row_p (struct glyph_row *row)
18373 {
18374 int result = 1;
18375
18376 if (PT == CHARPOS (row->end.pos)
18377 || PT == MATRIX_ROW_END_CHARPOS (row))
18378 {
18379 /* Suppose the row ends on a string.
18380 Unless the row is continued, that means it ends on a newline
18381 in the string. If it's anything other than a display string
18382 (e.g. a before-string from an overlay), we don't want the
18383 cursor there. (This heuristic seems to give the optimal
18384 behavior for the various types of multi-line strings.) */
18385 if (CHARPOS (row->end.string_pos) >= 0)
18386 {
18387 if (row->continued_p)
18388 result = 1;
18389 else
18390 {
18391 /* Check for `display' property. */
18392 struct glyph *beg = row->glyphs[TEXT_AREA];
18393 struct glyph *end = beg + row->used[TEXT_AREA] - 1;
18394 struct glyph *glyph;
18395
18396 result = 0;
18397 for (glyph = end; glyph >= beg; --glyph)
18398 if (STRINGP (glyph->object))
18399 {
18400 Lisp_Object prop
18401 = Fget_char_property (make_number (PT),
18402 Qdisplay, Qnil);
18403 result =
18404 (!NILP (prop)
18405 && display_prop_string_p (prop, glyph->object));
18406 break;
18407 }
18408 }
18409 }
18410 else if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
18411 {
18412 /* If the row ends in middle of a real character,
18413 and the line is continued, we want the cursor here.
18414 That's because CHARPOS (ROW->end.pos) would equal
18415 PT if PT is before the character. */
18416 if (!row->ends_in_ellipsis_p)
18417 result = row->continued_p;
18418 else
18419 /* If the row ends in an ellipsis, then
18420 CHARPOS (ROW->end.pos) will equal point after the
18421 invisible text. We want that position to be displayed
18422 after the ellipsis. */
18423 result = 0;
18424 }
18425 /* If the row ends at ZV, display the cursor at the end of that
18426 row instead of at the start of the row below. */
18427 else if (row->ends_at_zv_p)
18428 result = 1;
18429 else
18430 result = 0;
18431 }
18432
18433 return result;
18434 }
18435
18436 \f
18437
18438 /* Push the property PROP so that it will be rendered at the current
18439 position in IT. Return 1 if PROP was successfully pushed, 0
18440 otherwise. Called from handle_line_prefix to handle the
18441 `line-prefix' and `wrap-prefix' properties. */
18442
18443 static int
18444 push_display_prop (struct it *it, Lisp_Object prop)
18445 {
18446 struct text_pos pos =
18447 STRINGP (it->string) ? it->current.string_pos : it->current.pos;
18448
18449 xassert (it->method == GET_FROM_BUFFER
18450 || it->method == GET_FROM_DISPLAY_VECTOR
18451 || it->method == GET_FROM_STRING);
18452
18453 /* We need to save the current buffer/string position, so it will be
18454 restored by pop_it, because iterate_out_of_display_property
18455 depends on that being set correctly, but some situations leave
18456 it->position not yet set when this function is called. */
18457 push_it (it, &pos);
18458
18459 if (STRINGP (prop))
18460 {
18461 if (SCHARS (prop) == 0)
18462 {
18463 pop_it (it);
18464 return 0;
18465 }
18466
18467 it->string = prop;
18468 it->multibyte_p = STRING_MULTIBYTE (it->string);
18469 it->current.overlay_string_index = -1;
18470 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
18471 it->end_charpos = it->string_nchars = SCHARS (it->string);
18472 it->method = GET_FROM_STRING;
18473 it->stop_charpos = 0;
18474 it->prev_stop = 0;
18475 it->base_level_stop = 0;
18476
18477 /* Force paragraph direction to be that of the parent
18478 buffer/string. */
18479 if (it->bidi_p && it->bidi_it.paragraph_dir == R2L)
18480 it->paragraph_embedding = it->bidi_it.paragraph_dir;
18481 else
18482 it->paragraph_embedding = L2R;
18483
18484 /* Set up the bidi iterator for this display string. */
18485 if (it->bidi_p)
18486 {
18487 it->bidi_it.string.lstring = it->string;
18488 it->bidi_it.string.s = NULL;
18489 it->bidi_it.string.schars = it->end_charpos;
18490 it->bidi_it.string.bufpos = IT_CHARPOS (*it);
18491 it->bidi_it.string.from_disp_str = it->string_from_display_prop_p;
18492 it->bidi_it.string.unibyte = !it->multibyte_p;
18493 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
18494 }
18495 }
18496 else if (CONSP (prop) && EQ (XCAR (prop), Qspace))
18497 {
18498 it->method = GET_FROM_STRETCH;
18499 it->object = prop;
18500 }
18501 #ifdef HAVE_WINDOW_SYSTEM
18502 else if (IMAGEP (prop))
18503 {
18504 it->what = IT_IMAGE;
18505 it->image_id = lookup_image (it->f, prop);
18506 it->method = GET_FROM_IMAGE;
18507 }
18508 #endif /* HAVE_WINDOW_SYSTEM */
18509 else
18510 {
18511 pop_it (it); /* bogus display property, give up */
18512 return 0;
18513 }
18514
18515 return 1;
18516 }
18517
18518 /* Return the character-property PROP at the current position in IT. */
18519
18520 static Lisp_Object
18521 get_it_property (struct it *it, Lisp_Object prop)
18522 {
18523 Lisp_Object position;
18524
18525 if (STRINGP (it->object))
18526 position = make_number (IT_STRING_CHARPOS (*it));
18527 else if (BUFFERP (it->object))
18528 position = make_number (IT_CHARPOS (*it));
18529 else
18530 return Qnil;
18531
18532 return Fget_char_property (position, prop, it->object);
18533 }
18534
18535 /* See if there's a line- or wrap-prefix, and if so, push it on IT. */
18536
18537 static void
18538 handle_line_prefix (struct it *it)
18539 {
18540 Lisp_Object prefix;
18541
18542 if (it->continuation_lines_width > 0)
18543 {
18544 prefix = get_it_property (it, Qwrap_prefix);
18545 if (NILP (prefix))
18546 prefix = Vwrap_prefix;
18547 }
18548 else
18549 {
18550 prefix = get_it_property (it, Qline_prefix);
18551 if (NILP (prefix))
18552 prefix = Vline_prefix;
18553 }
18554 if (! NILP (prefix) && push_display_prop (it, prefix))
18555 {
18556 /* If the prefix is wider than the window, and we try to wrap
18557 it, it would acquire its own wrap prefix, and so on till the
18558 iterator stack overflows. So, don't wrap the prefix. */
18559 it->line_wrap = TRUNCATE;
18560 it->avoid_cursor_p = 1;
18561 }
18562 }
18563
18564 \f
18565
18566 /* Remove N glyphs at the start of a reversed IT->glyph_row. Called
18567 only for R2L lines from display_line and display_string, when they
18568 decide that too many glyphs were produced by PRODUCE_GLYPHS, and
18569 the line/string needs to be continued on the next glyph row. */
18570 static void
18571 unproduce_glyphs (struct it *it, int n)
18572 {
18573 struct glyph *glyph, *end;
18574
18575 xassert (it->glyph_row);
18576 xassert (it->glyph_row->reversed_p);
18577 xassert (it->area == TEXT_AREA);
18578 xassert (n <= it->glyph_row->used[TEXT_AREA]);
18579
18580 if (n > it->glyph_row->used[TEXT_AREA])
18581 n = it->glyph_row->used[TEXT_AREA];
18582 glyph = it->glyph_row->glyphs[TEXT_AREA] + n;
18583 end = it->glyph_row->glyphs[TEXT_AREA] + it->glyph_row->used[TEXT_AREA];
18584 for ( ; glyph < end; glyph++)
18585 glyph[-n] = *glyph;
18586 }
18587
18588 /* Find the positions in a bidi-reordered ROW to serve as ROW->minpos
18589 and ROW->maxpos. */
18590 static void
18591 find_row_edges (struct it *it, struct glyph_row *row,
18592 EMACS_INT min_pos, EMACS_INT min_bpos,
18593 EMACS_INT max_pos, EMACS_INT max_bpos)
18594 {
18595 /* FIXME: Revisit this when glyph ``spilling'' in continuation
18596 lines' rows is implemented for bidi-reordered rows. */
18597
18598 /* ROW->minpos is the value of min_pos, the minimal buffer position
18599 we have in ROW, or ROW->start.pos if that is smaller. */
18600 if (min_pos <= ZV && min_pos < row->start.pos.charpos)
18601 SET_TEXT_POS (row->minpos, min_pos, min_bpos);
18602 else
18603 /* We didn't find buffer positions smaller than ROW->start, or
18604 didn't find _any_ valid buffer positions in any of the glyphs,
18605 so we must trust the iterator's computed positions. */
18606 row->minpos = row->start.pos;
18607 if (max_pos <= 0)
18608 {
18609 max_pos = CHARPOS (it->current.pos);
18610 max_bpos = BYTEPOS (it->current.pos);
18611 }
18612
18613 /* Here are the various use-cases for ending the row, and the
18614 corresponding values for ROW->maxpos:
18615
18616 Line ends in a newline from buffer eol_pos + 1
18617 Line is continued from buffer max_pos + 1
18618 Line is truncated on right it->current.pos
18619 Line ends in a newline from string max_pos + 1(*)
18620 (*) + 1 only when line ends in a forward scan
18621 Line is continued from string max_pos
18622 Line is continued from display vector max_pos
18623 Line is entirely from a string min_pos == max_pos
18624 Line is entirely from a display vector min_pos == max_pos
18625 Line that ends at ZV ZV
18626
18627 If you discover other use-cases, please add them here as
18628 appropriate. */
18629 if (row->ends_at_zv_p)
18630 row->maxpos = it->current.pos;
18631 else if (row->used[TEXT_AREA])
18632 {
18633 int seen_this_string = 0;
18634 struct glyph_row *r1 = row - 1;
18635
18636 /* Did we see the same display string on the previous row? */
18637 if (STRINGP (it->object)
18638 /* this is not the first row */
18639 && row > it->w->desired_matrix->rows
18640 /* previous row is not the header line */
18641 && !r1->mode_line_p
18642 /* previous row also ends in a newline from a string */
18643 && r1->ends_in_newline_from_string_p)
18644 {
18645 struct glyph *start, *end;
18646
18647 /* Search for the last glyph of the previous row that came
18648 from buffer or string. Depending on whether the row is
18649 L2R or R2L, we need to process it front to back or the
18650 other way round. */
18651 if (!r1->reversed_p)
18652 {
18653 start = r1->glyphs[TEXT_AREA];
18654 end = start + r1->used[TEXT_AREA];
18655 /* Glyphs inserted by redisplay have an integer (zero)
18656 as their object. */
18657 while (end > start
18658 && INTEGERP ((end - 1)->object)
18659 && (end - 1)->charpos <= 0)
18660 --end;
18661 if (end > start)
18662 {
18663 if (EQ ((end - 1)->object, it->object))
18664 seen_this_string = 1;
18665 }
18666 else
18667 /* If all the glyphs of the previous row were inserted
18668 by redisplay, it means the previous row was
18669 produced from a single newline, which is only
18670 possible if that newline came from the same string
18671 as the one which produced this ROW. */
18672 seen_this_string = 1;
18673 }
18674 else
18675 {
18676 end = r1->glyphs[TEXT_AREA] - 1;
18677 start = end + r1->used[TEXT_AREA];
18678 while (end < start
18679 && INTEGERP ((end + 1)->object)
18680 && (end + 1)->charpos <= 0)
18681 ++end;
18682 if (end < start)
18683 {
18684 if (EQ ((end + 1)->object, it->object))
18685 seen_this_string = 1;
18686 }
18687 else
18688 seen_this_string = 1;
18689 }
18690 }
18691 /* Take note of each display string that covers a newline only
18692 once, the first time we see it. This is for when a display
18693 string includes more than one newline in it. */
18694 if (row->ends_in_newline_from_string_p && !seen_this_string)
18695 {
18696 /* If we were scanning the buffer forward when we displayed
18697 the string, we want to account for at least one buffer
18698 position that belongs to this row (position covered by
18699 the display string), so that cursor positioning will
18700 consider this row as a candidate when point is at the end
18701 of the visual line represented by this row. This is not
18702 required when scanning back, because max_pos will already
18703 have a much larger value. */
18704 if (CHARPOS (row->end.pos) > max_pos)
18705 INC_BOTH (max_pos, max_bpos);
18706 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
18707 }
18708 else if (CHARPOS (it->eol_pos) > 0)
18709 SET_TEXT_POS (row->maxpos,
18710 CHARPOS (it->eol_pos) + 1, BYTEPOS (it->eol_pos) + 1);
18711 else if (row->continued_p)
18712 {
18713 /* If max_pos is different from IT's current position, it
18714 means IT->method does not belong to the display element
18715 at max_pos. However, it also means that the display
18716 element at max_pos was displayed in its entirety on this
18717 line, which is equivalent to saying that the next line
18718 starts at the next buffer position. */
18719 if (IT_CHARPOS (*it) == max_pos && it->method != GET_FROM_BUFFER)
18720 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
18721 else
18722 {
18723 INC_BOTH (max_pos, max_bpos);
18724 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
18725 }
18726 }
18727 else if (row->truncated_on_right_p)
18728 /* display_line already called reseat_at_next_visible_line_start,
18729 which puts the iterator at the beginning of the next line, in
18730 the logical order. */
18731 row->maxpos = it->current.pos;
18732 else if (max_pos == min_pos && it->method != GET_FROM_BUFFER)
18733 /* A line that is entirely from a string/image/stretch... */
18734 row->maxpos = row->minpos;
18735 else
18736 abort ();
18737 }
18738 else
18739 row->maxpos = it->current.pos;
18740 }
18741
18742 /* Construct the glyph row IT->glyph_row in the desired matrix of
18743 IT->w from text at the current position of IT. See dispextern.h
18744 for an overview of struct it. Value is non-zero if
18745 IT->glyph_row displays text, as opposed to a line displaying ZV
18746 only. */
18747
18748 static int
18749 display_line (struct it *it)
18750 {
18751 struct glyph_row *row = it->glyph_row;
18752 Lisp_Object overlay_arrow_string;
18753 struct it wrap_it;
18754 void *wrap_data = NULL;
18755 int may_wrap = 0, wrap_x IF_LINT (= 0);
18756 int wrap_row_used = -1;
18757 int wrap_row_ascent IF_LINT (= 0), wrap_row_height IF_LINT (= 0);
18758 int wrap_row_phys_ascent IF_LINT (= 0), wrap_row_phys_height IF_LINT (= 0);
18759 int wrap_row_extra_line_spacing IF_LINT (= 0);
18760 EMACS_INT wrap_row_min_pos IF_LINT (= 0), wrap_row_min_bpos IF_LINT (= 0);
18761 EMACS_INT wrap_row_max_pos IF_LINT (= 0), wrap_row_max_bpos IF_LINT (= 0);
18762 int cvpos;
18763 EMACS_INT min_pos = ZV + 1, max_pos = 0;
18764 EMACS_INT min_bpos IF_LINT (= 0), max_bpos IF_LINT (= 0);
18765
18766 /* We always start displaying at hpos zero even if hscrolled. */
18767 xassert (it->hpos == 0 && it->current_x == 0);
18768
18769 if (MATRIX_ROW_VPOS (row, it->w->desired_matrix)
18770 >= it->w->desired_matrix->nrows)
18771 {
18772 it->w->nrows_scale_factor++;
18773 fonts_changed_p = 1;
18774 return 0;
18775 }
18776
18777 /* Is IT->w showing the region? */
18778 it->w->region_showing = it->region_beg_charpos > 0 ? Qt : Qnil;
18779
18780 /* Clear the result glyph row and enable it. */
18781 prepare_desired_row (row);
18782
18783 row->y = it->current_y;
18784 row->start = it->start;
18785 row->continuation_lines_width = it->continuation_lines_width;
18786 row->displays_text_p = 1;
18787 row->starts_in_middle_of_char_p = it->starts_in_middle_of_char_p;
18788 it->starts_in_middle_of_char_p = 0;
18789
18790 /* Arrange the overlays nicely for our purposes. Usually, we call
18791 display_line on only one line at a time, in which case this
18792 can't really hurt too much, or we call it on lines which appear
18793 one after another in the buffer, in which case all calls to
18794 recenter_overlay_lists but the first will be pretty cheap. */
18795 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
18796
18797 /* Move over display elements that are not visible because we are
18798 hscrolled. This may stop at an x-position < IT->first_visible_x
18799 if the first glyph is partially visible or if we hit a line end. */
18800 if (it->current_x < it->first_visible_x)
18801 {
18802 this_line_min_pos = row->start.pos;
18803 move_it_in_display_line_to (it, ZV, it->first_visible_x,
18804 MOVE_TO_POS | MOVE_TO_X);
18805 /* Record the smallest positions seen while we moved over
18806 display elements that are not visible. This is needed by
18807 redisplay_internal for optimizing the case where the cursor
18808 stays inside the same line. The rest of this function only
18809 considers positions that are actually displayed, so
18810 RECORD_MAX_MIN_POS will not otherwise record positions that
18811 are hscrolled to the left of the left edge of the window. */
18812 min_pos = CHARPOS (this_line_min_pos);
18813 min_bpos = BYTEPOS (this_line_min_pos);
18814 }
18815 else
18816 {
18817 /* We only do this when not calling `move_it_in_display_line_to'
18818 above, because move_it_in_display_line_to calls
18819 handle_line_prefix itself. */
18820 handle_line_prefix (it);
18821 }
18822
18823 /* Get the initial row height. This is either the height of the
18824 text hscrolled, if there is any, or zero. */
18825 row->ascent = it->max_ascent;
18826 row->height = it->max_ascent + it->max_descent;
18827 row->phys_ascent = it->max_phys_ascent;
18828 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
18829 row->extra_line_spacing = it->max_extra_line_spacing;
18830
18831 /* Utility macro to record max and min buffer positions seen until now. */
18832 #define RECORD_MAX_MIN_POS(IT) \
18833 do \
18834 { \
18835 int composition_p = (IT)->what == IT_COMPOSITION; \
18836 EMACS_INT current_pos = \
18837 composition_p ? (IT)->cmp_it.charpos \
18838 : IT_CHARPOS (*(IT)); \
18839 EMACS_INT current_bpos = \
18840 composition_p ? CHAR_TO_BYTE (current_pos) \
18841 : IT_BYTEPOS (*(IT)); \
18842 if (current_pos < min_pos) \
18843 { \
18844 min_pos = current_pos; \
18845 min_bpos = current_bpos; \
18846 } \
18847 if (IT_CHARPOS (*it) > max_pos) \
18848 { \
18849 max_pos = IT_CHARPOS (*it); \
18850 max_bpos = IT_BYTEPOS (*it); \
18851 } \
18852 } \
18853 while (0)
18854
18855 /* Loop generating characters. The loop is left with IT on the next
18856 character to display. */
18857 while (1)
18858 {
18859 int n_glyphs_before, hpos_before, x_before;
18860 int x, nglyphs;
18861 int ascent = 0, descent = 0, phys_ascent = 0, phys_descent = 0;
18862
18863 /* Retrieve the next thing to display. Value is zero if end of
18864 buffer reached. */
18865 if (!get_next_display_element (it))
18866 {
18867 /* Maybe add a space at the end of this line that is used to
18868 display the cursor there under X. Set the charpos of the
18869 first glyph of blank lines not corresponding to any text
18870 to -1. */
18871 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
18872 row->exact_window_width_line_p = 1;
18873 else if ((append_space_for_newline (it, 1) && row->used[TEXT_AREA] == 1)
18874 || row->used[TEXT_AREA] == 0)
18875 {
18876 row->glyphs[TEXT_AREA]->charpos = -1;
18877 row->displays_text_p = 0;
18878
18879 if (!NILP (BVAR (XBUFFER (it->w->buffer), indicate_empty_lines))
18880 && (!MINI_WINDOW_P (it->w)
18881 || (minibuf_level && EQ (it->window, minibuf_window))))
18882 row->indicate_empty_line_p = 1;
18883 }
18884
18885 it->continuation_lines_width = 0;
18886 row->ends_at_zv_p = 1;
18887 /* A row that displays right-to-left text must always have
18888 its last face extended all the way to the end of line,
18889 even if this row ends in ZV, because we still write to
18890 the screen left to right. */
18891 if (row->reversed_p)
18892 extend_face_to_end_of_line (it);
18893 break;
18894 }
18895
18896 /* Now, get the metrics of what we want to display. This also
18897 generates glyphs in `row' (which is IT->glyph_row). */
18898 n_glyphs_before = row->used[TEXT_AREA];
18899 x = it->current_x;
18900
18901 /* Remember the line height so far in case the next element doesn't
18902 fit on the line. */
18903 if (it->line_wrap != TRUNCATE)
18904 {
18905 ascent = it->max_ascent;
18906 descent = it->max_descent;
18907 phys_ascent = it->max_phys_ascent;
18908 phys_descent = it->max_phys_descent;
18909
18910 if (it->line_wrap == WORD_WRAP && it->area == TEXT_AREA)
18911 {
18912 if (IT_DISPLAYING_WHITESPACE (it))
18913 may_wrap = 1;
18914 else if (may_wrap)
18915 {
18916 SAVE_IT (wrap_it, *it, wrap_data);
18917 wrap_x = x;
18918 wrap_row_used = row->used[TEXT_AREA];
18919 wrap_row_ascent = row->ascent;
18920 wrap_row_height = row->height;
18921 wrap_row_phys_ascent = row->phys_ascent;
18922 wrap_row_phys_height = row->phys_height;
18923 wrap_row_extra_line_spacing = row->extra_line_spacing;
18924 wrap_row_min_pos = min_pos;
18925 wrap_row_min_bpos = min_bpos;
18926 wrap_row_max_pos = max_pos;
18927 wrap_row_max_bpos = max_bpos;
18928 may_wrap = 0;
18929 }
18930 }
18931 }
18932
18933 PRODUCE_GLYPHS (it);
18934
18935 /* If this display element was in marginal areas, continue with
18936 the next one. */
18937 if (it->area != TEXT_AREA)
18938 {
18939 row->ascent = max (row->ascent, it->max_ascent);
18940 row->height = max (row->height, it->max_ascent + it->max_descent);
18941 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
18942 row->phys_height = max (row->phys_height,
18943 it->max_phys_ascent + it->max_phys_descent);
18944 row->extra_line_spacing = max (row->extra_line_spacing,
18945 it->max_extra_line_spacing);
18946 set_iterator_to_next (it, 1);
18947 continue;
18948 }
18949
18950 /* Does the display element fit on the line? If we truncate
18951 lines, we should draw past the right edge of the window. If
18952 we don't truncate, we want to stop so that we can display the
18953 continuation glyph before the right margin. If lines are
18954 continued, there are two possible strategies for characters
18955 resulting in more than 1 glyph (e.g. tabs): Display as many
18956 glyphs as possible in this line and leave the rest for the
18957 continuation line, or display the whole element in the next
18958 line. Original redisplay did the former, so we do it also. */
18959 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
18960 hpos_before = it->hpos;
18961 x_before = x;
18962
18963 if (/* Not a newline. */
18964 nglyphs > 0
18965 /* Glyphs produced fit entirely in the line. */
18966 && it->current_x < it->last_visible_x)
18967 {
18968 it->hpos += nglyphs;
18969 row->ascent = max (row->ascent, it->max_ascent);
18970 row->height = max (row->height, it->max_ascent + it->max_descent);
18971 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
18972 row->phys_height = max (row->phys_height,
18973 it->max_phys_ascent + it->max_phys_descent);
18974 row->extra_line_spacing = max (row->extra_line_spacing,
18975 it->max_extra_line_spacing);
18976 if (it->current_x - it->pixel_width < it->first_visible_x)
18977 row->x = x - it->first_visible_x;
18978 /* Record the maximum and minimum buffer positions seen so
18979 far in glyphs that will be displayed by this row. */
18980 if (it->bidi_p)
18981 RECORD_MAX_MIN_POS (it);
18982 }
18983 else
18984 {
18985 int i, new_x;
18986 struct glyph *glyph;
18987
18988 for (i = 0; i < nglyphs; ++i, x = new_x)
18989 {
18990 glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
18991 new_x = x + glyph->pixel_width;
18992
18993 if (/* Lines are continued. */
18994 it->line_wrap != TRUNCATE
18995 && (/* Glyph doesn't fit on the line. */
18996 new_x > it->last_visible_x
18997 /* Or it fits exactly on a window system frame. */
18998 || (new_x == it->last_visible_x
18999 && FRAME_WINDOW_P (it->f))))
19000 {
19001 /* End of a continued line. */
19002
19003 if (it->hpos == 0
19004 || (new_x == it->last_visible_x
19005 && FRAME_WINDOW_P (it->f)))
19006 {
19007 /* Current glyph is the only one on the line or
19008 fits exactly on the line. We must continue
19009 the line because we can't draw the cursor
19010 after the glyph. */
19011 row->continued_p = 1;
19012 it->current_x = new_x;
19013 it->continuation_lines_width += new_x;
19014 ++it->hpos;
19015 if (i == nglyphs - 1)
19016 {
19017 /* If line-wrap is on, check if a previous
19018 wrap point was found. */
19019 if (wrap_row_used > 0
19020 /* Even if there is a previous wrap
19021 point, continue the line here as
19022 usual, if (i) the previous character
19023 was a space or tab AND (ii) the
19024 current character is not. */
19025 && (!may_wrap
19026 || IT_DISPLAYING_WHITESPACE (it)))
19027 goto back_to_wrap;
19028
19029 /* Record the maximum and minimum buffer
19030 positions seen so far in glyphs that will be
19031 displayed by this row. */
19032 if (it->bidi_p)
19033 RECORD_MAX_MIN_POS (it);
19034 set_iterator_to_next (it, 1);
19035 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
19036 {
19037 if (!get_next_display_element (it))
19038 {
19039 row->exact_window_width_line_p = 1;
19040 it->continuation_lines_width = 0;
19041 row->continued_p = 0;
19042 row->ends_at_zv_p = 1;
19043 }
19044 else if (ITERATOR_AT_END_OF_LINE_P (it))
19045 {
19046 row->continued_p = 0;
19047 row->exact_window_width_line_p = 1;
19048 }
19049 }
19050 }
19051 else if (it->bidi_p)
19052 RECORD_MAX_MIN_POS (it);
19053 }
19054 else if (CHAR_GLYPH_PADDING_P (*glyph)
19055 && !FRAME_WINDOW_P (it->f))
19056 {
19057 /* A padding glyph that doesn't fit on this line.
19058 This means the whole character doesn't fit
19059 on the line. */
19060 if (row->reversed_p)
19061 unproduce_glyphs (it, row->used[TEXT_AREA]
19062 - n_glyphs_before);
19063 row->used[TEXT_AREA] = n_glyphs_before;
19064
19065 /* Fill the rest of the row with continuation
19066 glyphs like in 20.x. */
19067 while (row->glyphs[TEXT_AREA] + row->used[TEXT_AREA]
19068 < row->glyphs[1 + TEXT_AREA])
19069 produce_special_glyphs (it, IT_CONTINUATION);
19070
19071 row->continued_p = 1;
19072 it->current_x = x_before;
19073 it->continuation_lines_width += x_before;
19074
19075 /* Restore the height to what it was before the
19076 element not fitting on the line. */
19077 it->max_ascent = ascent;
19078 it->max_descent = descent;
19079 it->max_phys_ascent = phys_ascent;
19080 it->max_phys_descent = phys_descent;
19081 }
19082 else if (wrap_row_used > 0)
19083 {
19084 back_to_wrap:
19085 if (row->reversed_p)
19086 unproduce_glyphs (it,
19087 row->used[TEXT_AREA] - wrap_row_used);
19088 RESTORE_IT (it, &wrap_it, wrap_data);
19089 it->continuation_lines_width += wrap_x;
19090 row->used[TEXT_AREA] = wrap_row_used;
19091 row->ascent = wrap_row_ascent;
19092 row->height = wrap_row_height;
19093 row->phys_ascent = wrap_row_phys_ascent;
19094 row->phys_height = wrap_row_phys_height;
19095 row->extra_line_spacing = wrap_row_extra_line_spacing;
19096 min_pos = wrap_row_min_pos;
19097 min_bpos = wrap_row_min_bpos;
19098 max_pos = wrap_row_max_pos;
19099 max_bpos = wrap_row_max_bpos;
19100 row->continued_p = 1;
19101 row->ends_at_zv_p = 0;
19102 row->exact_window_width_line_p = 0;
19103 it->continuation_lines_width += x;
19104
19105 /* Make sure that a non-default face is extended
19106 up to the right margin of the window. */
19107 extend_face_to_end_of_line (it);
19108 }
19109 else if (it->c == '\t' && FRAME_WINDOW_P (it->f))
19110 {
19111 /* A TAB that extends past the right edge of the
19112 window. This produces a single glyph on
19113 window system frames. We leave the glyph in
19114 this row and let it fill the row, but don't
19115 consume the TAB. */
19116 it->continuation_lines_width += it->last_visible_x;
19117 row->ends_in_middle_of_char_p = 1;
19118 row->continued_p = 1;
19119 glyph->pixel_width = it->last_visible_x - x;
19120 it->starts_in_middle_of_char_p = 1;
19121 }
19122 else
19123 {
19124 /* Something other than a TAB that draws past
19125 the right edge of the window. Restore
19126 positions to values before the element. */
19127 if (row->reversed_p)
19128 unproduce_glyphs (it, row->used[TEXT_AREA]
19129 - (n_glyphs_before + i));
19130 row->used[TEXT_AREA] = n_glyphs_before + i;
19131
19132 /* Display continuation glyphs. */
19133 if (!FRAME_WINDOW_P (it->f))
19134 produce_special_glyphs (it, IT_CONTINUATION);
19135 row->continued_p = 1;
19136
19137 it->current_x = x_before;
19138 it->continuation_lines_width += x;
19139 extend_face_to_end_of_line (it);
19140
19141 if (nglyphs > 1 && i > 0)
19142 {
19143 row->ends_in_middle_of_char_p = 1;
19144 it->starts_in_middle_of_char_p = 1;
19145 }
19146
19147 /* Restore the height to what it was before the
19148 element not fitting on the line. */
19149 it->max_ascent = ascent;
19150 it->max_descent = descent;
19151 it->max_phys_ascent = phys_ascent;
19152 it->max_phys_descent = phys_descent;
19153 }
19154
19155 break;
19156 }
19157 else if (new_x > it->first_visible_x)
19158 {
19159 /* Increment number of glyphs actually displayed. */
19160 ++it->hpos;
19161
19162 /* Record the maximum and minimum buffer positions
19163 seen so far in glyphs that will be displayed by
19164 this row. */
19165 if (it->bidi_p)
19166 RECORD_MAX_MIN_POS (it);
19167
19168 if (x < it->first_visible_x)
19169 /* Glyph is partially visible, i.e. row starts at
19170 negative X position. */
19171 row->x = x - it->first_visible_x;
19172 }
19173 else
19174 {
19175 /* Glyph is completely off the left margin of the
19176 window. This should not happen because of the
19177 move_it_in_display_line at the start of this
19178 function, unless the text display area of the
19179 window is empty. */
19180 xassert (it->first_visible_x <= it->last_visible_x);
19181 }
19182 }
19183 /* Even if this display element produced no glyphs at all,
19184 we want to record its position. */
19185 if (it->bidi_p && nglyphs == 0)
19186 RECORD_MAX_MIN_POS (it);
19187
19188 row->ascent = max (row->ascent, it->max_ascent);
19189 row->height = max (row->height, it->max_ascent + it->max_descent);
19190 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
19191 row->phys_height = max (row->phys_height,
19192 it->max_phys_ascent + it->max_phys_descent);
19193 row->extra_line_spacing = max (row->extra_line_spacing,
19194 it->max_extra_line_spacing);
19195
19196 /* End of this display line if row is continued. */
19197 if (row->continued_p || row->ends_at_zv_p)
19198 break;
19199 }
19200
19201 at_end_of_line:
19202 /* Is this a line end? If yes, we're also done, after making
19203 sure that a non-default face is extended up to the right
19204 margin of the window. */
19205 if (ITERATOR_AT_END_OF_LINE_P (it))
19206 {
19207 int used_before = row->used[TEXT_AREA];
19208
19209 row->ends_in_newline_from_string_p = STRINGP (it->object);
19210
19211 /* Add a space at the end of the line that is used to
19212 display the cursor there. */
19213 if (!IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
19214 append_space_for_newline (it, 0);
19215
19216 /* Extend the face to the end of the line. */
19217 extend_face_to_end_of_line (it);
19218
19219 /* Make sure we have the position. */
19220 if (used_before == 0)
19221 row->glyphs[TEXT_AREA]->charpos = CHARPOS (it->position);
19222
19223 /* Record the position of the newline, for use in
19224 find_row_edges. */
19225 it->eol_pos = it->current.pos;
19226
19227 /* Consume the line end. This skips over invisible lines. */
19228 set_iterator_to_next (it, 1);
19229 it->continuation_lines_width = 0;
19230 break;
19231 }
19232
19233 /* Proceed with next display element. Note that this skips
19234 over lines invisible because of selective display. */
19235 set_iterator_to_next (it, 1);
19236
19237 /* If we truncate lines, we are done when the last displayed
19238 glyphs reach past the right margin of the window. */
19239 if (it->line_wrap == TRUNCATE
19240 && (FRAME_WINDOW_P (it->f)
19241 ? (it->current_x >= it->last_visible_x)
19242 : (it->current_x > it->last_visible_x)))
19243 {
19244 /* Maybe add truncation glyphs. */
19245 if (!FRAME_WINDOW_P (it->f))
19246 {
19247 int i, n;
19248
19249 if (!row->reversed_p)
19250 {
19251 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
19252 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
19253 break;
19254 }
19255 else
19256 {
19257 for (i = 0; i < row->used[TEXT_AREA]; i++)
19258 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
19259 break;
19260 /* Remove any padding glyphs at the front of ROW, to
19261 make room for the truncation glyphs we will be
19262 adding below. The loop below always inserts at
19263 least one truncation glyph, so also remove the
19264 last glyph added to ROW. */
19265 unproduce_glyphs (it, i + 1);
19266 /* Adjust i for the loop below. */
19267 i = row->used[TEXT_AREA] - (i + 1);
19268 }
19269
19270 for (n = row->used[TEXT_AREA]; i < n; ++i)
19271 {
19272 row->used[TEXT_AREA] = i;
19273 produce_special_glyphs (it, IT_TRUNCATION);
19274 }
19275 }
19276 else if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
19277 {
19278 /* Don't truncate if we can overflow newline into fringe. */
19279 if (!get_next_display_element (it))
19280 {
19281 it->continuation_lines_width = 0;
19282 row->ends_at_zv_p = 1;
19283 row->exact_window_width_line_p = 1;
19284 break;
19285 }
19286 if (ITERATOR_AT_END_OF_LINE_P (it))
19287 {
19288 row->exact_window_width_line_p = 1;
19289 goto at_end_of_line;
19290 }
19291 }
19292
19293 row->truncated_on_right_p = 1;
19294 it->continuation_lines_width = 0;
19295 reseat_at_next_visible_line_start (it, 0);
19296 row->ends_at_zv_p = FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n';
19297 it->hpos = hpos_before;
19298 it->current_x = x_before;
19299 break;
19300 }
19301 }
19302
19303 if (wrap_data)
19304 bidi_unshelve_cache (wrap_data, 1);
19305
19306 /* If line is not empty and hscrolled, maybe insert truncation glyphs
19307 at the left window margin. */
19308 if (it->first_visible_x
19309 && IT_CHARPOS (*it) != CHARPOS (row->start.pos))
19310 {
19311 if (!FRAME_WINDOW_P (it->f))
19312 insert_left_trunc_glyphs (it);
19313 row->truncated_on_left_p = 1;
19314 }
19315
19316 /* Remember the position at which this line ends.
19317
19318 BIDI Note: any code that needs MATRIX_ROW_START/END_CHARPOS
19319 cannot be before the call to find_row_edges below, since that is
19320 where these positions are determined. */
19321 row->end = it->current;
19322 if (!it->bidi_p)
19323 {
19324 row->minpos = row->start.pos;
19325 row->maxpos = row->end.pos;
19326 }
19327 else
19328 {
19329 /* ROW->minpos and ROW->maxpos must be the smallest and
19330 `1 + the largest' buffer positions in ROW. But if ROW was
19331 bidi-reordered, these two positions can be anywhere in the
19332 row, so we must determine them now. */
19333 find_row_edges (it, row, min_pos, min_bpos, max_pos, max_bpos);
19334 }
19335
19336 /* If the start of this line is the overlay arrow-position, then
19337 mark this glyph row as the one containing the overlay arrow.
19338 This is clearly a mess with variable size fonts. It would be
19339 better to let it be displayed like cursors under X. */
19340 if ((row->displays_text_p || !overlay_arrow_seen)
19341 && (overlay_arrow_string = overlay_arrow_at_row (it, row),
19342 !NILP (overlay_arrow_string)))
19343 {
19344 /* Overlay arrow in window redisplay is a fringe bitmap. */
19345 if (STRINGP (overlay_arrow_string))
19346 {
19347 struct glyph_row *arrow_row
19348 = get_overlay_arrow_glyph_row (it->w, overlay_arrow_string);
19349 struct glyph *glyph = arrow_row->glyphs[TEXT_AREA];
19350 struct glyph *arrow_end = glyph + arrow_row->used[TEXT_AREA];
19351 struct glyph *p = row->glyphs[TEXT_AREA];
19352 struct glyph *p2, *end;
19353
19354 /* Copy the arrow glyphs. */
19355 while (glyph < arrow_end)
19356 *p++ = *glyph++;
19357
19358 /* Throw away padding glyphs. */
19359 p2 = p;
19360 end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
19361 while (p2 < end && CHAR_GLYPH_PADDING_P (*p2))
19362 ++p2;
19363 if (p2 > p)
19364 {
19365 while (p2 < end)
19366 *p++ = *p2++;
19367 row->used[TEXT_AREA] = p2 - row->glyphs[TEXT_AREA];
19368 }
19369 }
19370 else
19371 {
19372 xassert (INTEGERP (overlay_arrow_string));
19373 row->overlay_arrow_bitmap = XINT (overlay_arrow_string);
19374 }
19375 overlay_arrow_seen = 1;
19376 }
19377
19378 /* Compute pixel dimensions of this line. */
19379 compute_line_metrics (it);
19380
19381 /* Record whether this row ends inside an ellipsis. */
19382 row->ends_in_ellipsis_p
19383 = (it->method == GET_FROM_DISPLAY_VECTOR
19384 && it->ellipsis_p);
19385
19386 /* Save fringe bitmaps in this row. */
19387 row->left_user_fringe_bitmap = it->left_user_fringe_bitmap;
19388 row->left_user_fringe_face_id = it->left_user_fringe_face_id;
19389 row->right_user_fringe_bitmap = it->right_user_fringe_bitmap;
19390 row->right_user_fringe_face_id = it->right_user_fringe_face_id;
19391
19392 it->left_user_fringe_bitmap = 0;
19393 it->left_user_fringe_face_id = 0;
19394 it->right_user_fringe_bitmap = 0;
19395 it->right_user_fringe_face_id = 0;
19396
19397 /* Maybe set the cursor. */
19398 cvpos = it->w->cursor.vpos;
19399 if ((cvpos < 0
19400 /* In bidi-reordered rows, keep checking for proper cursor
19401 position even if one has been found already, because buffer
19402 positions in such rows change non-linearly with ROW->VPOS,
19403 when a line is continued. One exception: when we are at ZV,
19404 display cursor on the first suitable glyph row, since all
19405 the empty rows after that also have their position set to ZV. */
19406 /* FIXME: Revisit this when glyph ``spilling'' in continuation
19407 lines' rows is implemented for bidi-reordered rows. */
19408 || (it->bidi_p
19409 && !MATRIX_ROW (it->w->desired_matrix, cvpos)->ends_at_zv_p))
19410 && PT >= MATRIX_ROW_START_CHARPOS (row)
19411 && PT <= MATRIX_ROW_END_CHARPOS (row)
19412 && cursor_row_p (row))
19413 set_cursor_from_row (it->w, row, it->w->desired_matrix, 0, 0, 0, 0);
19414
19415 /* Highlight trailing whitespace. */
19416 if (!NILP (Vshow_trailing_whitespace))
19417 highlight_trailing_whitespace (it->f, it->glyph_row);
19418
19419 /* Prepare for the next line. This line starts horizontally at (X
19420 HPOS) = (0 0). Vertical positions are incremented. As a
19421 convenience for the caller, IT->glyph_row is set to the next
19422 row to be used. */
19423 it->current_x = it->hpos = 0;
19424 it->current_y += row->height;
19425 SET_TEXT_POS (it->eol_pos, 0, 0);
19426 ++it->vpos;
19427 ++it->glyph_row;
19428 /* The next row should by default use the same value of the
19429 reversed_p flag as this one. set_iterator_to_next decides when
19430 it's a new paragraph, and PRODUCE_GLYPHS recomputes the value of
19431 the flag accordingly. */
19432 if (it->glyph_row < MATRIX_BOTTOM_TEXT_ROW (it->w->desired_matrix, it->w))
19433 it->glyph_row->reversed_p = row->reversed_p;
19434 it->start = row->end;
19435 return row->displays_text_p;
19436
19437 #undef RECORD_MAX_MIN_POS
19438 }
19439
19440 DEFUN ("current-bidi-paragraph-direction", Fcurrent_bidi_paragraph_direction,
19441 Scurrent_bidi_paragraph_direction, 0, 1, 0,
19442 doc: /* Return paragraph direction at point in BUFFER.
19443 Value is either `left-to-right' or `right-to-left'.
19444 If BUFFER is omitted or nil, it defaults to the current buffer.
19445
19446 Paragraph direction determines how the text in the paragraph is displayed.
19447 In left-to-right paragraphs, text begins at the left margin of the window
19448 and the reading direction is generally left to right. In right-to-left
19449 paragraphs, text begins at the right margin and is read from right to left.
19450
19451 See also `bidi-paragraph-direction'. */)
19452 (Lisp_Object buffer)
19453 {
19454 struct buffer *buf = current_buffer;
19455 struct buffer *old = buf;
19456
19457 if (! NILP (buffer))
19458 {
19459 CHECK_BUFFER (buffer);
19460 buf = XBUFFER (buffer);
19461 }
19462
19463 if (NILP (BVAR (buf, bidi_display_reordering))
19464 || NILP (BVAR (buf, enable_multibyte_characters)))
19465 return Qleft_to_right;
19466 else if (!NILP (BVAR (buf, bidi_paragraph_direction)))
19467 return BVAR (buf, bidi_paragraph_direction);
19468 else
19469 {
19470 /* Determine the direction from buffer text. We could try to
19471 use current_matrix if it is up to date, but this seems fast
19472 enough as it is. */
19473 struct bidi_it itb;
19474 EMACS_INT pos = BUF_PT (buf);
19475 EMACS_INT bytepos = BUF_PT_BYTE (buf);
19476 int c;
19477 void *itb_data = bidi_shelve_cache ();
19478
19479 set_buffer_temp (buf);
19480 /* bidi_paragraph_init finds the base direction of the paragraph
19481 by searching forward from paragraph start. We need the base
19482 direction of the current or _previous_ paragraph, so we need
19483 to make sure we are within that paragraph. To that end, find
19484 the previous non-empty line. */
19485 if (pos >= ZV && pos > BEGV)
19486 {
19487 pos--;
19488 bytepos = CHAR_TO_BYTE (pos);
19489 }
19490 if (fast_looking_at (build_string ("[\f\t ]*\n"),
19491 pos, bytepos, ZV, ZV_BYTE, Qnil) > 0)
19492 {
19493 while ((c = FETCH_BYTE (bytepos)) == '\n'
19494 || c == ' ' || c == '\t' || c == '\f')
19495 {
19496 if (bytepos <= BEGV_BYTE)
19497 break;
19498 bytepos--;
19499 pos--;
19500 }
19501 while (!CHAR_HEAD_P (FETCH_BYTE (bytepos)))
19502 bytepos--;
19503 }
19504 bidi_init_it (pos, bytepos, FRAME_WINDOW_P (SELECTED_FRAME ()), &itb);
19505 itb.paragraph_dir = NEUTRAL_DIR;
19506 itb.string.s = NULL;
19507 itb.string.lstring = Qnil;
19508 itb.string.bufpos = 0;
19509 itb.string.unibyte = 0;
19510 bidi_paragraph_init (NEUTRAL_DIR, &itb, 1);
19511 bidi_unshelve_cache (itb_data, 0);
19512 set_buffer_temp (old);
19513 switch (itb.paragraph_dir)
19514 {
19515 case L2R:
19516 return Qleft_to_right;
19517 break;
19518 case R2L:
19519 return Qright_to_left;
19520 break;
19521 default:
19522 abort ();
19523 }
19524 }
19525 }
19526
19527
19528 \f
19529 /***********************************************************************
19530 Menu Bar
19531 ***********************************************************************/
19532
19533 /* Redisplay the menu bar in the frame for window W.
19534
19535 The menu bar of X frames that don't have X toolkit support is
19536 displayed in a special window W->frame->menu_bar_window.
19537
19538 The menu bar of terminal frames is treated specially as far as
19539 glyph matrices are concerned. Menu bar lines are not part of
19540 windows, so the update is done directly on the frame matrix rows
19541 for the menu bar. */
19542
19543 static void
19544 display_menu_bar (struct window *w)
19545 {
19546 struct frame *f = XFRAME (WINDOW_FRAME (w));
19547 struct it it;
19548 Lisp_Object items;
19549 int i;
19550
19551 /* Don't do all this for graphical frames. */
19552 #ifdef HAVE_NTGUI
19553 if (FRAME_W32_P (f))
19554 return;
19555 #endif
19556 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
19557 if (FRAME_X_P (f))
19558 return;
19559 #endif
19560
19561 #ifdef HAVE_NS
19562 if (FRAME_NS_P (f))
19563 return;
19564 #endif /* HAVE_NS */
19565
19566 #ifdef USE_X_TOOLKIT
19567 xassert (!FRAME_WINDOW_P (f));
19568 init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MENU_FACE_ID);
19569 it.first_visible_x = 0;
19570 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
19571 #else /* not USE_X_TOOLKIT */
19572 if (FRAME_WINDOW_P (f))
19573 {
19574 /* Menu bar lines are displayed in the desired matrix of the
19575 dummy window menu_bar_window. */
19576 struct window *menu_w;
19577 xassert (WINDOWP (f->menu_bar_window));
19578 menu_w = XWINDOW (f->menu_bar_window);
19579 init_iterator (&it, menu_w, -1, -1, menu_w->desired_matrix->rows,
19580 MENU_FACE_ID);
19581 it.first_visible_x = 0;
19582 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
19583 }
19584 else
19585 {
19586 /* This is a TTY frame, i.e. character hpos/vpos are used as
19587 pixel x/y. */
19588 init_iterator (&it, w, -1, -1, f->desired_matrix->rows,
19589 MENU_FACE_ID);
19590 it.first_visible_x = 0;
19591 it.last_visible_x = FRAME_COLS (f);
19592 }
19593 #endif /* not USE_X_TOOLKIT */
19594
19595 /* FIXME: This should be controlled by a user option. See the
19596 comments in redisplay_tool_bar and display_mode_line about
19597 this. */
19598 it.paragraph_embedding = L2R;
19599
19600 if (! mode_line_inverse_video)
19601 /* Force the menu-bar to be displayed in the default face. */
19602 it.base_face_id = it.face_id = DEFAULT_FACE_ID;
19603
19604 /* Clear all rows of the menu bar. */
19605 for (i = 0; i < FRAME_MENU_BAR_LINES (f); ++i)
19606 {
19607 struct glyph_row *row = it.glyph_row + i;
19608 clear_glyph_row (row);
19609 row->enabled_p = 1;
19610 row->full_width_p = 1;
19611 }
19612
19613 /* Display all items of the menu bar. */
19614 items = FRAME_MENU_BAR_ITEMS (it.f);
19615 for (i = 0; i < ASIZE (items); i += 4)
19616 {
19617 Lisp_Object string;
19618
19619 /* Stop at nil string. */
19620 string = AREF (items, i + 1);
19621 if (NILP (string))
19622 break;
19623
19624 /* Remember where item was displayed. */
19625 ASET (items, i + 3, make_number (it.hpos));
19626
19627 /* Display the item, pad with one space. */
19628 if (it.current_x < it.last_visible_x)
19629 display_string (NULL, string, Qnil, 0, 0, &it,
19630 SCHARS (string) + 1, 0, 0, -1);
19631 }
19632
19633 /* Fill out the line with spaces. */
19634 if (it.current_x < it.last_visible_x)
19635 display_string ("", Qnil, Qnil, 0, 0, &it, -1, 0, 0, -1);
19636
19637 /* Compute the total height of the lines. */
19638 compute_line_metrics (&it);
19639 }
19640
19641
19642 \f
19643 /***********************************************************************
19644 Mode Line
19645 ***********************************************************************/
19646
19647 /* Redisplay mode lines in the window tree whose root is WINDOW. If
19648 FORCE is non-zero, redisplay mode lines unconditionally.
19649 Otherwise, redisplay only mode lines that are garbaged. Value is
19650 the number of windows whose mode lines were redisplayed. */
19651
19652 static int
19653 redisplay_mode_lines (Lisp_Object window, int force)
19654 {
19655 int nwindows = 0;
19656
19657 while (!NILP (window))
19658 {
19659 struct window *w = XWINDOW (window);
19660
19661 if (WINDOWP (w->hchild))
19662 nwindows += redisplay_mode_lines (w->hchild, force);
19663 else if (WINDOWP (w->vchild))
19664 nwindows += redisplay_mode_lines (w->vchild, force);
19665 else if (force
19666 || FRAME_GARBAGED_P (XFRAME (w->frame))
19667 || !MATRIX_MODE_LINE_ROW (w->current_matrix)->enabled_p)
19668 {
19669 struct text_pos lpoint;
19670 struct buffer *old = current_buffer;
19671
19672 /* Set the window's buffer for the mode line display. */
19673 SET_TEXT_POS (lpoint, PT, PT_BYTE);
19674 set_buffer_internal_1 (XBUFFER (w->buffer));
19675
19676 /* Point refers normally to the selected window. For any
19677 other window, set up appropriate value. */
19678 if (!EQ (window, selected_window))
19679 {
19680 struct text_pos pt;
19681
19682 SET_TEXT_POS_FROM_MARKER (pt, w->pointm);
19683 if (CHARPOS (pt) < BEGV)
19684 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
19685 else if (CHARPOS (pt) > (ZV - 1))
19686 TEMP_SET_PT_BOTH (ZV, ZV_BYTE);
19687 else
19688 TEMP_SET_PT_BOTH (CHARPOS (pt), BYTEPOS (pt));
19689 }
19690
19691 /* Display mode lines. */
19692 clear_glyph_matrix (w->desired_matrix);
19693 if (display_mode_lines (w))
19694 {
19695 ++nwindows;
19696 w->must_be_updated_p = 1;
19697 }
19698
19699 /* Restore old settings. */
19700 set_buffer_internal_1 (old);
19701 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
19702 }
19703
19704 window = w->next;
19705 }
19706
19707 return nwindows;
19708 }
19709
19710
19711 /* Display the mode and/or header line of window W. Value is the
19712 sum number of mode lines and header lines displayed. */
19713
19714 static int
19715 display_mode_lines (struct window *w)
19716 {
19717 Lisp_Object old_selected_window, old_selected_frame;
19718 int n = 0;
19719
19720 old_selected_frame = selected_frame;
19721 selected_frame = w->frame;
19722 old_selected_window = selected_window;
19723 XSETWINDOW (selected_window, w);
19724
19725 /* These will be set while the mode line specs are processed. */
19726 line_number_displayed = 0;
19727 w->column_number_displayed = Qnil;
19728
19729 if (WINDOW_WANTS_MODELINE_P (w))
19730 {
19731 struct window *sel_w = XWINDOW (old_selected_window);
19732
19733 /* Select mode line face based on the real selected window. */
19734 display_mode_line (w, CURRENT_MODE_LINE_FACE_ID_3 (sel_w, sel_w, w),
19735 BVAR (current_buffer, mode_line_format));
19736 ++n;
19737 }
19738
19739 if (WINDOW_WANTS_HEADER_LINE_P (w))
19740 {
19741 display_mode_line (w, HEADER_LINE_FACE_ID,
19742 BVAR (current_buffer, header_line_format));
19743 ++n;
19744 }
19745
19746 selected_frame = old_selected_frame;
19747 selected_window = old_selected_window;
19748 return n;
19749 }
19750
19751
19752 /* Display mode or header line of window W. FACE_ID specifies which
19753 line to display; it is either MODE_LINE_FACE_ID or
19754 HEADER_LINE_FACE_ID. FORMAT is the mode/header line format to
19755 display. Value is the pixel height of the mode/header line
19756 displayed. */
19757
19758 static int
19759 display_mode_line (struct window *w, enum face_id face_id, Lisp_Object format)
19760 {
19761 struct it it;
19762 struct face *face;
19763 int count = SPECPDL_INDEX ();
19764
19765 init_iterator (&it, w, -1, -1, NULL, face_id);
19766 /* Don't extend on a previously drawn mode-line.
19767 This may happen if called from pos_visible_p. */
19768 it.glyph_row->enabled_p = 0;
19769 prepare_desired_row (it.glyph_row);
19770
19771 it.glyph_row->mode_line_p = 1;
19772
19773 if (! mode_line_inverse_video)
19774 /* Force the mode-line to be displayed in the default face. */
19775 it.base_face_id = it.face_id = DEFAULT_FACE_ID;
19776
19777 /* FIXME: This should be controlled by a user option. But
19778 supporting such an option is not trivial, since the mode line is
19779 made up of many separate strings. */
19780 it.paragraph_embedding = L2R;
19781
19782 record_unwind_protect (unwind_format_mode_line,
19783 format_mode_line_unwind_data (NULL, Qnil, 0));
19784
19785 mode_line_target = MODE_LINE_DISPLAY;
19786
19787 /* Temporarily make frame's keyboard the current kboard so that
19788 kboard-local variables in the mode_line_format will get the right
19789 values. */
19790 push_kboard (FRAME_KBOARD (it.f));
19791 record_unwind_save_match_data ();
19792 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
19793 pop_kboard ();
19794
19795 unbind_to (count, Qnil);
19796
19797 /* Fill up with spaces. */
19798 display_string (" ", Qnil, Qnil, 0, 0, &it, 10000, -1, -1, 0);
19799
19800 compute_line_metrics (&it);
19801 it.glyph_row->full_width_p = 1;
19802 it.glyph_row->continued_p = 0;
19803 it.glyph_row->truncated_on_left_p = 0;
19804 it.glyph_row->truncated_on_right_p = 0;
19805
19806 /* Make a 3D mode-line have a shadow at its right end. */
19807 face = FACE_FROM_ID (it.f, face_id);
19808 extend_face_to_end_of_line (&it);
19809 if (face->box != FACE_NO_BOX)
19810 {
19811 struct glyph *last = (it.glyph_row->glyphs[TEXT_AREA]
19812 + it.glyph_row->used[TEXT_AREA] - 1);
19813 last->right_box_line_p = 1;
19814 }
19815
19816 return it.glyph_row->height;
19817 }
19818
19819 /* Move element ELT in LIST to the front of LIST.
19820 Return the updated list. */
19821
19822 static Lisp_Object
19823 move_elt_to_front (Lisp_Object elt, Lisp_Object list)
19824 {
19825 register Lisp_Object tail, prev;
19826 register Lisp_Object tem;
19827
19828 tail = list;
19829 prev = Qnil;
19830 while (CONSP (tail))
19831 {
19832 tem = XCAR (tail);
19833
19834 if (EQ (elt, tem))
19835 {
19836 /* Splice out the link TAIL. */
19837 if (NILP (prev))
19838 list = XCDR (tail);
19839 else
19840 Fsetcdr (prev, XCDR (tail));
19841
19842 /* Now make it the first. */
19843 Fsetcdr (tail, list);
19844 return tail;
19845 }
19846 else
19847 prev = tail;
19848 tail = XCDR (tail);
19849 QUIT;
19850 }
19851
19852 /* Not found--return unchanged LIST. */
19853 return list;
19854 }
19855
19856 /* Contribute ELT to the mode line for window IT->w. How it
19857 translates into text depends on its data type.
19858
19859 IT describes the display environment in which we display, as usual.
19860
19861 DEPTH is the depth in recursion. It is used to prevent
19862 infinite recursion here.
19863
19864 FIELD_WIDTH is the number of characters the display of ELT should
19865 occupy in the mode line, and PRECISION is the maximum number of
19866 characters to display from ELT's representation. See
19867 display_string for details.
19868
19869 Returns the hpos of the end of the text generated by ELT.
19870
19871 PROPS is a property list to add to any string we encounter.
19872
19873 If RISKY is nonzero, remove (disregard) any properties in any string
19874 we encounter, and ignore :eval and :propertize.
19875
19876 The global variable `mode_line_target' determines whether the
19877 output is passed to `store_mode_line_noprop',
19878 `store_mode_line_string', or `display_string'. */
19879
19880 static int
19881 display_mode_element (struct it *it, int depth, int field_width, int precision,
19882 Lisp_Object elt, Lisp_Object props, int risky)
19883 {
19884 int n = 0, field, prec;
19885 int literal = 0;
19886
19887 tail_recurse:
19888 if (depth > 100)
19889 elt = build_string ("*too-deep*");
19890
19891 depth++;
19892
19893 switch (SWITCH_ENUM_CAST (XTYPE (elt)))
19894 {
19895 case Lisp_String:
19896 {
19897 /* A string: output it and check for %-constructs within it. */
19898 unsigned char c;
19899 EMACS_INT offset = 0;
19900
19901 if (SCHARS (elt) > 0
19902 && (!NILP (props) || risky))
19903 {
19904 Lisp_Object oprops, aelt;
19905 oprops = Ftext_properties_at (make_number (0), elt);
19906
19907 /* If the starting string's properties are not what
19908 we want, translate the string. Also, if the string
19909 is risky, do that anyway. */
19910
19911 if (NILP (Fequal (props, oprops)) || risky)
19912 {
19913 /* If the starting string has properties,
19914 merge the specified ones onto the existing ones. */
19915 if (! NILP (oprops) && !risky)
19916 {
19917 Lisp_Object tem;
19918
19919 oprops = Fcopy_sequence (oprops);
19920 tem = props;
19921 while (CONSP (tem))
19922 {
19923 oprops = Fplist_put (oprops, XCAR (tem),
19924 XCAR (XCDR (tem)));
19925 tem = XCDR (XCDR (tem));
19926 }
19927 props = oprops;
19928 }
19929
19930 aelt = Fassoc (elt, mode_line_proptrans_alist);
19931 if (! NILP (aelt) && !NILP (Fequal (props, XCDR (aelt))))
19932 {
19933 /* AELT is what we want. Move it to the front
19934 without consing. */
19935 elt = XCAR (aelt);
19936 mode_line_proptrans_alist
19937 = move_elt_to_front (aelt, mode_line_proptrans_alist);
19938 }
19939 else
19940 {
19941 Lisp_Object tem;
19942
19943 /* If AELT has the wrong props, it is useless.
19944 so get rid of it. */
19945 if (! NILP (aelt))
19946 mode_line_proptrans_alist
19947 = Fdelq (aelt, mode_line_proptrans_alist);
19948
19949 elt = Fcopy_sequence (elt);
19950 Fset_text_properties (make_number (0), Flength (elt),
19951 props, elt);
19952 /* Add this item to mode_line_proptrans_alist. */
19953 mode_line_proptrans_alist
19954 = Fcons (Fcons (elt, props),
19955 mode_line_proptrans_alist);
19956 /* Truncate mode_line_proptrans_alist
19957 to at most 50 elements. */
19958 tem = Fnthcdr (make_number (50),
19959 mode_line_proptrans_alist);
19960 if (! NILP (tem))
19961 XSETCDR (tem, Qnil);
19962 }
19963 }
19964 }
19965
19966 offset = 0;
19967
19968 if (literal)
19969 {
19970 prec = precision - n;
19971 switch (mode_line_target)
19972 {
19973 case MODE_LINE_NOPROP:
19974 case MODE_LINE_TITLE:
19975 n += store_mode_line_noprop (SSDATA (elt), -1, prec);
19976 break;
19977 case MODE_LINE_STRING:
19978 n += store_mode_line_string (NULL, elt, 1, 0, prec, Qnil);
19979 break;
19980 case MODE_LINE_DISPLAY:
19981 n += display_string (NULL, elt, Qnil, 0, 0, it,
19982 0, prec, 0, STRING_MULTIBYTE (elt));
19983 break;
19984 }
19985
19986 break;
19987 }
19988
19989 /* Handle the non-literal case. */
19990
19991 while ((precision <= 0 || n < precision)
19992 && SREF (elt, offset) != 0
19993 && (mode_line_target != MODE_LINE_DISPLAY
19994 || it->current_x < it->last_visible_x))
19995 {
19996 EMACS_INT last_offset = offset;
19997
19998 /* Advance to end of string or next format specifier. */
19999 while ((c = SREF (elt, offset++)) != '\0' && c != '%')
20000 ;
20001
20002 if (offset - 1 != last_offset)
20003 {
20004 EMACS_INT nchars, nbytes;
20005
20006 /* Output to end of string or up to '%'. Field width
20007 is length of string. Don't output more than
20008 PRECISION allows us. */
20009 offset--;
20010
20011 prec = c_string_width (SDATA (elt) + last_offset,
20012 offset - last_offset, precision - n,
20013 &nchars, &nbytes);
20014
20015 switch (mode_line_target)
20016 {
20017 case MODE_LINE_NOPROP:
20018 case MODE_LINE_TITLE:
20019 n += store_mode_line_noprop (SSDATA (elt) + last_offset, 0, prec);
20020 break;
20021 case MODE_LINE_STRING:
20022 {
20023 EMACS_INT bytepos = last_offset;
20024 EMACS_INT charpos = string_byte_to_char (elt, bytepos);
20025 EMACS_INT endpos = (precision <= 0
20026 ? string_byte_to_char (elt, offset)
20027 : charpos + nchars);
20028
20029 n += store_mode_line_string (NULL,
20030 Fsubstring (elt, make_number (charpos),
20031 make_number (endpos)),
20032 0, 0, 0, Qnil);
20033 }
20034 break;
20035 case MODE_LINE_DISPLAY:
20036 {
20037 EMACS_INT bytepos = last_offset;
20038 EMACS_INT charpos = string_byte_to_char (elt, bytepos);
20039
20040 if (precision <= 0)
20041 nchars = string_byte_to_char (elt, offset) - charpos;
20042 n += display_string (NULL, elt, Qnil, 0, charpos,
20043 it, 0, nchars, 0,
20044 STRING_MULTIBYTE (elt));
20045 }
20046 break;
20047 }
20048 }
20049 else /* c == '%' */
20050 {
20051 EMACS_INT percent_position = offset;
20052
20053 /* Get the specified minimum width. Zero means
20054 don't pad. */
20055 field = 0;
20056 while ((c = SREF (elt, offset++)) >= '0' && c <= '9')
20057 field = field * 10 + c - '0';
20058
20059 /* Don't pad beyond the total padding allowed. */
20060 if (field_width - n > 0 && field > field_width - n)
20061 field = field_width - n;
20062
20063 /* Note that either PRECISION <= 0 or N < PRECISION. */
20064 prec = precision - n;
20065
20066 if (c == 'M')
20067 n += display_mode_element (it, depth, field, prec,
20068 Vglobal_mode_string, props,
20069 risky);
20070 else if (c != 0)
20071 {
20072 int multibyte;
20073 EMACS_INT bytepos, charpos;
20074 const char *spec;
20075 Lisp_Object string;
20076
20077 bytepos = percent_position;
20078 charpos = (STRING_MULTIBYTE (elt)
20079 ? string_byte_to_char (elt, bytepos)
20080 : bytepos);
20081 spec = decode_mode_spec (it->w, c, field, &string);
20082 multibyte = STRINGP (string) && STRING_MULTIBYTE (string);
20083
20084 switch (mode_line_target)
20085 {
20086 case MODE_LINE_NOPROP:
20087 case MODE_LINE_TITLE:
20088 n += store_mode_line_noprop (spec, field, prec);
20089 break;
20090 case MODE_LINE_STRING:
20091 {
20092 Lisp_Object tem = build_string (spec);
20093 props = Ftext_properties_at (make_number (charpos), elt);
20094 /* Should only keep face property in props */
20095 n += store_mode_line_string (NULL, tem, 0, field, prec, props);
20096 }
20097 break;
20098 case MODE_LINE_DISPLAY:
20099 {
20100 int nglyphs_before, nwritten;
20101
20102 nglyphs_before = it->glyph_row->used[TEXT_AREA];
20103 nwritten = display_string (spec, string, elt,
20104 charpos, 0, it,
20105 field, prec, 0,
20106 multibyte);
20107
20108 /* Assign to the glyphs written above the
20109 string where the `%x' came from, position
20110 of the `%'. */
20111 if (nwritten > 0)
20112 {
20113 struct glyph *glyph
20114 = (it->glyph_row->glyphs[TEXT_AREA]
20115 + nglyphs_before);
20116 int i;
20117
20118 for (i = 0; i < nwritten; ++i)
20119 {
20120 glyph[i].object = elt;
20121 glyph[i].charpos = charpos;
20122 }
20123
20124 n += nwritten;
20125 }
20126 }
20127 break;
20128 }
20129 }
20130 else /* c == 0 */
20131 break;
20132 }
20133 }
20134 }
20135 break;
20136
20137 case Lisp_Symbol:
20138 /* A symbol: process the value of the symbol recursively
20139 as if it appeared here directly. Avoid error if symbol void.
20140 Special case: if value of symbol is a string, output the string
20141 literally. */
20142 {
20143 register Lisp_Object tem;
20144
20145 /* If the variable is not marked as risky to set
20146 then its contents are risky to use. */
20147 if (NILP (Fget (elt, Qrisky_local_variable)))
20148 risky = 1;
20149
20150 tem = Fboundp (elt);
20151 if (!NILP (tem))
20152 {
20153 tem = Fsymbol_value (elt);
20154 /* If value is a string, output that string literally:
20155 don't check for % within it. */
20156 if (STRINGP (tem))
20157 literal = 1;
20158
20159 if (!EQ (tem, elt))
20160 {
20161 /* Give up right away for nil or t. */
20162 elt = tem;
20163 goto tail_recurse;
20164 }
20165 }
20166 }
20167 break;
20168
20169 case Lisp_Cons:
20170 {
20171 register Lisp_Object car, tem;
20172
20173 /* A cons cell: five distinct cases.
20174 If first element is :eval or :propertize, do something special.
20175 If first element is a string or a cons, process all the elements
20176 and effectively concatenate them.
20177 If first element is a negative number, truncate displaying cdr to
20178 at most that many characters. If positive, pad (with spaces)
20179 to at least that many characters.
20180 If first element is a symbol, process the cadr or caddr recursively
20181 according to whether the symbol's value is non-nil or nil. */
20182 car = XCAR (elt);
20183 if (EQ (car, QCeval))
20184 {
20185 /* An element of the form (:eval FORM) means evaluate FORM
20186 and use the result as mode line elements. */
20187
20188 if (risky)
20189 break;
20190
20191 if (CONSP (XCDR (elt)))
20192 {
20193 Lisp_Object spec;
20194 spec = safe_eval (XCAR (XCDR (elt)));
20195 n += display_mode_element (it, depth, field_width - n,
20196 precision - n, spec, props,
20197 risky);
20198 }
20199 }
20200 else if (EQ (car, QCpropertize))
20201 {
20202 /* An element of the form (:propertize ELT PROPS...)
20203 means display ELT but applying properties PROPS. */
20204
20205 if (risky)
20206 break;
20207
20208 if (CONSP (XCDR (elt)))
20209 n += display_mode_element (it, depth, field_width - n,
20210 precision - n, XCAR (XCDR (elt)),
20211 XCDR (XCDR (elt)), risky);
20212 }
20213 else if (SYMBOLP (car))
20214 {
20215 tem = Fboundp (car);
20216 elt = XCDR (elt);
20217 if (!CONSP (elt))
20218 goto invalid;
20219 /* elt is now the cdr, and we know it is a cons cell.
20220 Use its car if CAR has a non-nil value. */
20221 if (!NILP (tem))
20222 {
20223 tem = Fsymbol_value (car);
20224 if (!NILP (tem))
20225 {
20226 elt = XCAR (elt);
20227 goto tail_recurse;
20228 }
20229 }
20230 /* Symbol's value is nil (or symbol is unbound)
20231 Get the cddr of the original list
20232 and if possible find the caddr and use that. */
20233 elt = XCDR (elt);
20234 if (NILP (elt))
20235 break;
20236 else if (!CONSP (elt))
20237 goto invalid;
20238 elt = XCAR (elt);
20239 goto tail_recurse;
20240 }
20241 else if (INTEGERP (car))
20242 {
20243 register int lim = XINT (car);
20244 elt = XCDR (elt);
20245 if (lim < 0)
20246 {
20247 /* Negative int means reduce maximum width. */
20248 if (precision <= 0)
20249 precision = -lim;
20250 else
20251 precision = min (precision, -lim);
20252 }
20253 else if (lim > 0)
20254 {
20255 /* Padding specified. Don't let it be more than
20256 current maximum. */
20257 if (precision > 0)
20258 lim = min (precision, lim);
20259
20260 /* If that's more padding than already wanted, queue it.
20261 But don't reduce padding already specified even if
20262 that is beyond the current truncation point. */
20263 field_width = max (lim, field_width);
20264 }
20265 goto tail_recurse;
20266 }
20267 else if (STRINGP (car) || CONSP (car))
20268 {
20269 Lisp_Object halftail = elt;
20270 int len = 0;
20271
20272 while (CONSP (elt)
20273 && (precision <= 0 || n < precision))
20274 {
20275 n += display_mode_element (it, depth,
20276 /* Do padding only after the last
20277 element in the list. */
20278 (! CONSP (XCDR (elt))
20279 ? field_width - n
20280 : 0),
20281 precision - n, XCAR (elt),
20282 props, risky);
20283 elt = XCDR (elt);
20284 len++;
20285 if ((len & 1) == 0)
20286 halftail = XCDR (halftail);
20287 /* Check for cycle. */
20288 if (EQ (halftail, elt))
20289 break;
20290 }
20291 }
20292 }
20293 break;
20294
20295 default:
20296 invalid:
20297 elt = build_string ("*invalid*");
20298 goto tail_recurse;
20299 }
20300
20301 /* Pad to FIELD_WIDTH. */
20302 if (field_width > 0 && n < field_width)
20303 {
20304 switch (mode_line_target)
20305 {
20306 case MODE_LINE_NOPROP:
20307 case MODE_LINE_TITLE:
20308 n += store_mode_line_noprop ("", field_width - n, 0);
20309 break;
20310 case MODE_LINE_STRING:
20311 n += store_mode_line_string ("", Qnil, 0, field_width - n, 0, Qnil);
20312 break;
20313 case MODE_LINE_DISPLAY:
20314 n += display_string ("", Qnil, Qnil, 0, 0, it, field_width - n,
20315 0, 0, 0);
20316 break;
20317 }
20318 }
20319
20320 return n;
20321 }
20322
20323 /* Store a mode-line string element in mode_line_string_list.
20324
20325 If STRING is non-null, display that C string. Otherwise, the Lisp
20326 string LISP_STRING is displayed.
20327
20328 FIELD_WIDTH is the minimum number of output glyphs to produce.
20329 If STRING has fewer characters than FIELD_WIDTH, pad to the right
20330 with spaces. FIELD_WIDTH <= 0 means don't pad.
20331
20332 PRECISION is the maximum number of characters to output from
20333 STRING. PRECISION <= 0 means don't truncate the string.
20334
20335 If COPY_STRING is non-zero, make a copy of LISP_STRING before adding
20336 properties to the string.
20337
20338 PROPS are the properties to add to the string.
20339 The mode_line_string_face face property is always added to the string.
20340 */
20341
20342 static int
20343 store_mode_line_string (const char *string, Lisp_Object lisp_string, int copy_string,
20344 int field_width, int precision, Lisp_Object props)
20345 {
20346 EMACS_INT len;
20347 int n = 0;
20348
20349 if (string != NULL)
20350 {
20351 len = strlen (string);
20352 if (precision > 0 && len > precision)
20353 len = precision;
20354 lisp_string = make_string (string, len);
20355 if (NILP (props))
20356 props = mode_line_string_face_prop;
20357 else if (!NILP (mode_line_string_face))
20358 {
20359 Lisp_Object face = Fplist_get (props, Qface);
20360 props = Fcopy_sequence (props);
20361 if (NILP (face))
20362 face = mode_line_string_face;
20363 else
20364 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
20365 props = Fplist_put (props, Qface, face);
20366 }
20367 Fadd_text_properties (make_number (0), make_number (len),
20368 props, lisp_string);
20369 }
20370 else
20371 {
20372 len = XFASTINT (Flength (lisp_string));
20373 if (precision > 0 && len > precision)
20374 {
20375 len = precision;
20376 lisp_string = Fsubstring (lisp_string, make_number (0), make_number (len));
20377 precision = -1;
20378 }
20379 if (!NILP (mode_line_string_face))
20380 {
20381 Lisp_Object face;
20382 if (NILP (props))
20383 props = Ftext_properties_at (make_number (0), lisp_string);
20384 face = Fplist_get (props, Qface);
20385 if (NILP (face))
20386 face = mode_line_string_face;
20387 else
20388 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
20389 props = Fcons (Qface, Fcons (face, Qnil));
20390 if (copy_string)
20391 lisp_string = Fcopy_sequence (lisp_string);
20392 }
20393 if (!NILP (props))
20394 Fadd_text_properties (make_number (0), make_number (len),
20395 props, lisp_string);
20396 }
20397
20398 if (len > 0)
20399 {
20400 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
20401 n += len;
20402 }
20403
20404 if (field_width > len)
20405 {
20406 field_width -= len;
20407 lisp_string = Fmake_string (make_number (field_width), make_number (' '));
20408 if (!NILP (props))
20409 Fadd_text_properties (make_number (0), make_number (field_width),
20410 props, lisp_string);
20411 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
20412 n += field_width;
20413 }
20414
20415 return n;
20416 }
20417
20418
20419 DEFUN ("format-mode-line", Fformat_mode_line, Sformat_mode_line,
20420 1, 4, 0,
20421 doc: /* Format a string out of a mode line format specification.
20422 First arg FORMAT specifies the mode line format (see `mode-line-format'
20423 for details) to use.
20424
20425 By default, the format is evaluated for the currently selected window.
20426
20427 Optional second arg FACE specifies the face property to put on all
20428 characters for which no face is specified. The value nil means the
20429 default face. The value t means whatever face the window's mode line
20430 currently uses (either `mode-line' or `mode-line-inactive',
20431 depending on whether the window is the selected window or not).
20432 An integer value means the value string has no text
20433 properties.
20434
20435 Optional third and fourth args WINDOW and BUFFER specify the window
20436 and buffer to use as the context for the formatting (defaults
20437 are the selected window and the WINDOW's buffer). */)
20438 (Lisp_Object format, Lisp_Object face,
20439 Lisp_Object window, Lisp_Object buffer)
20440 {
20441 struct it it;
20442 int len;
20443 struct window *w;
20444 struct buffer *old_buffer = NULL;
20445 int face_id;
20446 int no_props = INTEGERP (face);
20447 int count = SPECPDL_INDEX ();
20448 Lisp_Object str;
20449 int string_start = 0;
20450
20451 if (NILP (window))
20452 window = selected_window;
20453 CHECK_WINDOW (window);
20454 w = XWINDOW (window);
20455
20456 if (NILP (buffer))
20457 buffer = w->buffer;
20458 CHECK_BUFFER (buffer);
20459
20460 /* Make formatting the modeline a non-op when noninteractive, otherwise
20461 there will be problems later caused by a partially initialized frame. */
20462 if (NILP (format) || noninteractive)
20463 return empty_unibyte_string;
20464
20465 if (no_props)
20466 face = Qnil;
20467
20468 face_id = (NILP (face) || EQ (face, Qdefault)) ? DEFAULT_FACE_ID
20469 : EQ (face, Qt) ? (EQ (window, selected_window)
20470 ? MODE_LINE_FACE_ID : MODE_LINE_INACTIVE_FACE_ID)
20471 : EQ (face, Qmode_line) ? MODE_LINE_FACE_ID
20472 : EQ (face, Qmode_line_inactive) ? MODE_LINE_INACTIVE_FACE_ID
20473 : EQ (face, Qheader_line) ? HEADER_LINE_FACE_ID
20474 : EQ (face, Qtool_bar) ? TOOL_BAR_FACE_ID
20475 : DEFAULT_FACE_ID;
20476
20477 if (XBUFFER (buffer) != current_buffer)
20478 old_buffer = current_buffer;
20479
20480 /* Save things including mode_line_proptrans_alist,
20481 and set that to nil so that we don't alter the outer value. */
20482 record_unwind_protect (unwind_format_mode_line,
20483 format_mode_line_unwind_data
20484 (old_buffer, selected_window, 1));
20485 mode_line_proptrans_alist = Qnil;
20486
20487 Fselect_window (window, Qt);
20488 if (old_buffer)
20489 set_buffer_internal_1 (XBUFFER (buffer));
20490
20491 init_iterator (&it, w, -1, -1, NULL, face_id);
20492
20493 if (no_props)
20494 {
20495 mode_line_target = MODE_LINE_NOPROP;
20496 mode_line_string_face_prop = Qnil;
20497 mode_line_string_list = Qnil;
20498 string_start = MODE_LINE_NOPROP_LEN (0);
20499 }
20500 else
20501 {
20502 mode_line_target = MODE_LINE_STRING;
20503 mode_line_string_list = Qnil;
20504 mode_line_string_face = face;
20505 mode_line_string_face_prop
20506 = (NILP (face) ? Qnil : Fcons (Qface, Fcons (face, Qnil)));
20507 }
20508
20509 push_kboard (FRAME_KBOARD (it.f));
20510 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
20511 pop_kboard ();
20512
20513 if (no_props)
20514 {
20515 len = MODE_LINE_NOPROP_LEN (string_start);
20516 str = make_string (mode_line_noprop_buf + string_start, len);
20517 }
20518 else
20519 {
20520 mode_line_string_list = Fnreverse (mode_line_string_list);
20521 str = Fmapconcat (intern ("identity"), mode_line_string_list,
20522 empty_unibyte_string);
20523 }
20524
20525 unbind_to (count, Qnil);
20526 return str;
20527 }
20528
20529 /* Write a null-terminated, right justified decimal representation of
20530 the positive integer D to BUF using a minimal field width WIDTH. */
20531
20532 static void
20533 pint2str (register char *buf, register int width, register EMACS_INT d)
20534 {
20535 register char *p = buf;
20536
20537 if (d <= 0)
20538 *p++ = '0';
20539 else
20540 {
20541 while (d > 0)
20542 {
20543 *p++ = d % 10 + '0';
20544 d /= 10;
20545 }
20546 }
20547
20548 for (width -= (int) (p - buf); width > 0; --width)
20549 *p++ = ' ';
20550 *p-- = '\0';
20551 while (p > buf)
20552 {
20553 d = *buf;
20554 *buf++ = *p;
20555 *p-- = d;
20556 }
20557 }
20558
20559 /* Write a null-terminated, right justified decimal and "human
20560 readable" representation of the nonnegative integer D to BUF using
20561 a minimal field width WIDTH. D should be smaller than 999.5e24. */
20562
20563 static const char power_letter[] =
20564 {
20565 0, /* no letter */
20566 'k', /* kilo */
20567 'M', /* mega */
20568 'G', /* giga */
20569 'T', /* tera */
20570 'P', /* peta */
20571 'E', /* exa */
20572 'Z', /* zetta */
20573 'Y' /* yotta */
20574 };
20575
20576 static void
20577 pint2hrstr (char *buf, int width, EMACS_INT d)
20578 {
20579 /* We aim to represent the nonnegative integer D as
20580 QUOTIENT.TENTHS * 10 ^ (3 * EXPONENT). */
20581 EMACS_INT quotient = d;
20582 int remainder = 0;
20583 /* -1 means: do not use TENTHS. */
20584 int tenths = -1;
20585 int exponent = 0;
20586
20587 /* Length of QUOTIENT.TENTHS as a string. */
20588 int length;
20589
20590 char * psuffix;
20591 char * p;
20592
20593 if (1000 <= quotient)
20594 {
20595 /* Scale to the appropriate EXPONENT. */
20596 do
20597 {
20598 remainder = quotient % 1000;
20599 quotient /= 1000;
20600 exponent++;
20601 }
20602 while (1000 <= quotient);
20603
20604 /* Round to nearest and decide whether to use TENTHS or not. */
20605 if (quotient <= 9)
20606 {
20607 tenths = remainder / 100;
20608 if (50 <= remainder % 100)
20609 {
20610 if (tenths < 9)
20611 tenths++;
20612 else
20613 {
20614 quotient++;
20615 if (quotient == 10)
20616 tenths = -1;
20617 else
20618 tenths = 0;
20619 }
20620 }
20621 }
20622 else
20623 if (500 <= remainder)
20624 {
20625 if (quotient < 999)
20626 quotient++;
20627 else
20628 {
20629 quotient = 1;
20630 exponent++;
20631 tenths = 0;
20632 }
20633 }
20634 }
20635
20636 /* Calculate the LENGTH of QUOTIENT.TENTHS as a string. */
20637 if (tenths == -1 && quotient <= 99)
20638 if (quotient <= 9)
20639 length = 1;
20640 else
20641 length = 2;
20642 else
20643 length = 3;
20644 p = psuffix = buf + max (width, length);
20645
20646 /* Print EXPONENT. */
20647 *psuffix++ = power_letter[exponent];
20648 *psuffix = '\0';
20649
20650 /* Print TENTHS. */
20651 if (tenths >= 0)
20652 {
20653 *--p = '0' + tenths;
20654 *--p = '.';
20655 }
20656
20657 /* Print QUOTIENT. */
20658 do
20659 {
20660 int digit = quotient % 10;
20661 *--p = '0' + digit;
20662 }
20663 while ((quotient /= 10) != 0);
20664
20665 /* Print leading spaces. */
20666 while (buf < p)
20667 *--p = ' ';
20668 }
20669
20670 /* Set a mnemonic character for coding_system (Lisp symbol) in BUF.
20671 If EOL_FLAG is 1, set also a mnemonic character for end-of-line
20672 type of CODING_SYSTEM. Return updated pointer into BUF. */
20673
20674 static unsigned char invalid_eol_type[] = "(*invalid*)";
20675
20676 static char *
20677 decode_mode_spec_coding (Lisp_Object coding_system, register char *buf, int eol_flag)
20678 {
20679 Lisp_Object val;
20680 int multibyte = !NILP (BVAR (current_buffer, enable_multibyte_characters));
20681 const unsigned char *eol_str;
20682 int eol_str_len;
20683 /* The EOL conversion we are using. */
20684 Lisp_Object eoltype;
20685
20686 val = CODING_SYSTEM_SPEC (coding_system);
20687 eoltype = Qnil;
20688
20689 if (!VECTORP (val)) /* Not yet decided. */
20690 {
20691 if (multibyte)
20692 *buf++ = '-';
20693 if (eol_flag)
20694 eoltype = eol_mnemonic_undecided;
20695 /* Don't mention EOL conversion if it isn't decided. */
20696 }
20697 else
20698 {
20699 Lisp_Object attrs;
20700 Lisp_Object eolvalue;
20701
20702 attrs = AREF (val, 0);
20703 eolvalue = AREF (val, 2);
20704
20705 if (multibyte)
20706 *buf++ = XFASTINT (CODING_ATTR_MNEMONIC (attrs));
20707
20708 if (eol_flag)
20709 {
20710 /* The EOL conversion that is normal on this system. */
20711
20712 if (NILP (eolvalue)) /* Not yet decided. */
20713 eoltype = eol_mnemonic_undecided;
20714 else if (VECTORP (eolvalue)) /* Not yet decided. */
20715 eoltype = eol_mnemonic_undecided;
20716 else /* eolvalue is Qunix, Qdos, or Qmac. */
20717 eoltype = (EQ (eolvalue, Qunix)
20718 ? eol_mnemonic_unix
20719 : (EQ (eolvalue, Qdos) == 1
20720 ? eol_mnemonic_dos : eol_mnemonic_mac));
20721 }
20722 }
20723
20724 if (eol_flag)
20725 {
20726 /* Mention the EOL conversion if it is not the usual one. */
20727 if (STRINGP (eoltype))
20728 {
20729 eol_str = SDATA (eoltype);
20730 eol_str_len = SBYTES (eoltype);
20731 }
20732 else if (CHARACTERP (eoltype))
20733 {
20734 unsigned char *tmp = (unsigned char *) alloca (MAX_MULTIBYTE_LENGTH);
20735 int c = XFASTINT (eoltype);
20736 eol_str_len = CHAR_STRING (c, tmp);
20737 eol_str = tmp;
20738 }
20739 else
20740 {
20741 eol_str = invalid_eol_type;
20742 eol_str_len = sizeof (invalid_eol_type) - 1;
20743 }
20744 memcpy (buf, eol_str, eol_str_len);
20745 buf += eol_str_len;
20746 }
20747
20748 return buf;
20749 }
20750
20751 /* Return a string for the output of a mode line %-spec for window W,
20752 generated by character C. FIELD_WIDTH > 0 means pad the string
20753 returned with spaces to that value. Return a Lisp string in
20754 *STRING if the resulting string is taken from that Lisp string.
20755
20756 Note we operate on the current buffer for most purposes,
20757 the exception being w->base_line_pos. */
20758
20759 static char lots_of_dashes[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
20760
20761 static const char *
20762 decode_mode_spec (struct window *w, register int c, int field_width,
20763 Lisp_Object *string)
20764 {
20765 Lisp_Object obj;
20766 struct frame *f = XFRAME (WINDOW_FRAME (w));
20767 char *decode_mode_spec_buf = f->decode_mode_spec_buffer;
20768 struct buffer *b = current_buffer;
20769
20770 obj = Qnil;
20771 *string = Qnil;
20772
20773 switch (c)
20774 {
20775 case '*':
20776 if (!NILP (BVAR (b, read_only)))
20777 return "%";
20778 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
20779 return "*";
20780 return "-";
20781
20782 case '+':
20783 /* This differs from %* only for a modified read-only buffer. */
20784 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
20785 return "*";
20786 if (!NILP (BVAR (b, read_only)))
20787 return "%";
20788 return "-";
20789
20790 case '&':
20791 /* This differs from %* in ignoring read-only-ness. */
20792 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
20793 return "*";
20794 return "-";
20795
20796 case '%':
20797 return "%";
20798
20799 case '[':
20800 {
20801 int i;
20802 char *p;
20803
20804 if (command_loop_level > 5)
20805 return "[[[... ";
20806 p = decode_mode_spec_buf;
20807 for (i = 0; i < command_loop_level; i++)
20808 *p++ = '[';
20809 *p = 0;
20810 return decode_mode_spec_buf;
20811 }
20812
20813 case ']':
20814 {
20815 int i;
20816 char *p;
20817
20818 if (command_loop_level > 5)
20819 return " ...]]]";
20820 p = decode_mode_spec_buf;
20821 for (i = 0; i < command_loop_level; i++)
20822 *p++ = ']';
20823 *p = 0;
20824 return decode_mode_spec_buf;
20825 }
20826
20827 case '-':
20828 {
20829 register int i;
20830
20831 /* Let lots_of_dashes be a string of infinite length. */
20832 if (mode_line_target == MODE_LINE_NOPROP ||
20833 mode_line_target == MODE_LINE_STRING)
20834 return "--";
20835 if (field_width <= 0
20836 || field_width > sizeof (lots_of_dashes))
20837 {
20838 for (i = 0; i < FRAME_MESSAGE_BUF_SIZE (f) - 1; ++i)
20839 decode_mode_spec_buf[i] = '-';
20840 decode_mode_spec_buf[i] = '\0';
20841 return decode_mode_spec_buf;
20842 }
20843 else
20844 return lots_of_dashes;
20845 }
20846
20847 case 'b':
20848 obj = BVAR (b, name);
20849 break;
20850
20851 case 'c':
20852 /* %c and %l are ignored in `frame-title-format'.
20853 (In redisplay_internal, the frame title is drawn _before_ the
20854 windows are updated, so the stuff which depends on actual
20855 window contents (such as %l) may fail to render properly, or
20856 even crash emacs.) */
20857 if (mode_line_target == MODE_LINE_TITLE)
20858 return "";
20859 else
20860 {
20861 EMACS_INT col = current_column ();
20862 w->column_number_displayed = make_number (col);
20863 pint2str (decode_mode_spec_buf, field_width, col);
20864 return decode_mode_spec_buf;
20865 }
20866
20867 case 'e':
20868 #ifndef SYSTEM_MALLOC
20869 {
20870 if (NILP (Vmemory_full))
20871 return "";
20872 else
20873 return "!MEM FULL! ";
20874 }
20875 #else
20876 return "";
20877 #endif
20878
20879 case 'F':
20880 /* %F displays the frame name. */
20881 if (!NILP (f->title))
20882 return SSDATA (f->title);
20883 if (f->explicit_name || ! FRAME_WINDOW_P (f))
20884 return SSDATA (f->name);
20885 return "Emacs";
20886
20887 case 'f':
20888 obj = BVAR (b, filename);
20889 break;
20890
20891 case 'i':
20892 {
20893 EMACS_INT size = ZV - BEGV;
20894 pint2str (decode_mode_spec_buf, field_width, size);
20895 return decode_mode_spec_buf;
20896 }
20897
20898 case 'I':
20899 {
20900 EMACS_INT size = ZV - BEGV;
20901 pint2hrstr (decode_mode_spec_buf, field_width, size);
20902 return decode_mode_spec_buf;
20903 }
20904
20905 case 'l':
20906 {
20907 EMACS_INT startpos, startpos_byte, line, linepos, linepos_byte;
20908 EMACS_INT topline, nlines, height;
20909 EMACS_INT junk;
20910
20911 /* %c and %l are ignored in `frame-title-format'. */
20912 if (mode_line_target == MODE_LINE_TITLE)
20913 return "";
20914
20915 startpos = XMARKER (w->start)->charpos;
20916 startpos_byte = marker_byte_position (w->start);
20917 height = WINDOW_TOTAL_LINES (w);
20918
20919 /* If we decided that this buffer isn't suitable for line numbers,
20920 don't forget that too fast. */
20921 if (EQ (w->base_line_pos, w->buffer))
20922 goto no_value;
20923 /* But do forget it, if the window shows a different buffer now. */
20924 else if (BUFFERP (w->base_line_pos))
20925 w->base_line_pos = Qnil;
20926
20927 /* If the buffer is very big, don't waste time. */
20928 if (INTEGERP (Vline_number_display_limit)
20929 && BUF_ZV (b) - BUF_BEGV (b) > XINT (Vline_number_display_limit))
20930 {
20931 w->base_line_pos = Qnil;
20932 w->base_line_number = Qnil;
20933 goto no_value;
20934 }
20935
20936 if (INTEGERP (w->base_line_number)
20937 && INTEGERP (w->base_line_pos)
20938 && XFASTINT (w->base_line_pos) <= startpos)
20939 {
20940 line = XFASTINT (w->base_line_number);
20941 linepos = XFASTINT (w->base_line_pos);
20942 linepos_byte = buf_charpos_to_bytepos (b, linepos);
20943 }
20944 else
20945 {
20946 line = 1;
20947 linepos = BUF_BEGV (b);
20948 linepos_byte = BUF_BEGV_BYTE (b);
20949 }
20950
20951 /* Count lines from base line to window start position. */
20952 nlines = display_count_lines (linepos_byte,
20953 startpos_byte,
20954 startpos, &junk);
20955
20956 topline = nlines + line;
20957
20958 /* Determine a new base line, if the old one is too close
20959 or too far away, or if we did not have one.
20960 "Too close" means it's plausible a scroll-down would
20961 go back past it. */
20962 if (startpos == BUF_BEGV (b))
20963 {
20964 w->base_line_number = make_number (topline);
20965 w->base_line_pos = make_number (BUF_BEGV (b));
20966 }
20967 else if (nlines < height + 25 || nlines > height * 3 + 50
20968 || linepos == BUF_BEGV (b))
20969 {
20970 EMACS_INT limit = BUF_BEGV (b);
20971 EMACS_INT limit_byte = BUF_BEGV_BYTE (b);
20972 EMACS_INT position;
20973 EMACS_INT distance =
20974 (height * 2 + 30) * line_number_display_limit_width;
20975
20976 if (startpos - distance > limit)
20977 {
20978 limit = startpos - distance;
20979 limit_byte = CHAR_TO_BYTE (limit);
20980 }
20981
20982 nlines = display_count_lines (startpos_byte,
20983 limit_byte,
20984 - (height * 2 + 30),
20985 &position);
20986 /* If we couldn't find the lines we wanted within
20987 line_number_display_limit_width chars per line,
20988 give up on line numbers for this window. */
20989 if (position == limit_byte && limit == startpos - distance)
20990 {
20991 w->base_line_pos = w->buffer;
20992 w->base_line_number = Qnil;
20993 goto no_value;
20994 }
20995
20996 w->base_line_number = make_number (topline - nlines);
20997 w->base_line_pos = make_number (BYTE_TO_CHAR (position));
20998 }
20999
21000 /* Now count lines from the start pos to point. */
21001 nlines = display_count_lines (startpos_byte,
21002 PT_BYTE, PT, &junk);
21003
21004 /* Record that we did display the line number. */
21005 line_number_displayed = 1;
21006
21007 /* Make the string to show. */
21008 pint2str (decode_mode_spec_buf, field_width, topline + nlines);
21009 return decode_mode_spec_buf;
21010 no_value:
21011 {
21012 char* p = decode_mode_spec_buf;
21013 int pad = field_width - 2;
21014 while (pad-- > 0)
21015 *p++ = ' ';
21016 *p++ = '?';
21017 *p++ = '?';
21018 *p = '\0';
21019 return decode_mode_spec_buf;
21020 }
21021 }
21022 break;
21023
21024 case 'm':
21025 obj = BVAR (b, mode_name);
21026 break;
21027
21028 case 'n':
21029 if (BUF_BEGV (b) > BUF_BEG (b) || BUF_ZV (b) < BUF_Z (b))
21030 return " Narrow";
21031 break;
21032
21033 case 'p':
21034 {
21035 EMACS_INT pos = marker_position (w->start);
21036 EMACS_INT total = BUF_ZV (b) - BUF_BEGV (b);
21037
21038 if (XFASTINT (w->window_end_pos) <= BUF_Z (b) - BUF_ZV (b))
21039 {
21040 if (pos <= BUF_BEGV (b))
21041 return "All";
21042 else
21043 return "Bottom";
21044 }
21045 else if (pos <= BUF_BEGV (b))
21046 return "Top";
21047 else
21048 {
21049 if (total > 1000000)
21050 /* Do it differently for a large value, to avoid overflow. */
21051 total = ((pos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
21052 else
21053 total = ((pos - BUF_BEGV (b)) * 100 + total - 1) / total;
21054 /* We can't normally display a 3-digit number,
21055 so get us a 2-digit number that is close. */
21056 if (total == 100)
21057 total = 99;
21058 sprintf (decode_mode_spec_buf, "%2"pI"d%%", total);
21059 return decode_mode_spec_buf;
21060 }
21061 }
21062
21063 /* Display percentage of size above the bottom of the screen. */
21064 case 'P':
21065 {
21066 EMACS_INT toppos = marker_position (w->start);
21067 EMACS_INT botpos = BUF_Z (b) - XFASTINT (w->window_end_pos);
21068 EMACS_INT total = BUF_ZV (b) - BUF_BEGV (b);
21069
21070 if (botpos >= BUF_ZV (b))
21071 {
21072 if (toppos <= BUF_BEGV (b))
21073 return "All";
21074 else
21075 return "Bottom";
21076 }
21077 else
21078 {
21079 if (total > 1000000)
21080 /* Do it differently for a large value, to avoid overflow. */
21081 total = ((botpos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
21082 else
21083 total = ((botpos - BUF_BEGV (b)) * 100 + total - 1) / total;
21084 /* We can't normally display a 3-digit number,
21085 so get us a 2-digit number that is close. */
21086 if (total == 100)
21087 total = 99;
21088 if (toppos <= BUF_BEGV (b))
21089 sprintf (decode_mode_spec_buf, "Top%2"pI"d%%", total);
21090 else
21091 sprintf (decode_mode_spec_buf, "%2"pI"d%%", total);
21092 return decode_mode_spec_buf;
21093 }
21094 }
21095
21096 case 's':
21097 /* status of process */
21098 obj = Fget_buffer_process (Fcurrent_buffer ());
21099 if (NILP (obj))
21100 return "no process";
21101 #ifndef MSDOS
21102 obj = Fsymbol_name (Fprocess_status (obj));
21103 #endif
21104 break;
21105
21106 case '@':
21107 {
21108 int count = inhibit_garbage_collection ();
21109 Lisp_Object val = call1 (intern ("file-remote-p"),
21110 BVAR (current_buffer, directory));
21111 unbind_to (count, Qnil);
21112
21113 if (NILP (val))
21114 return "-";
21115 else
21116 return "@";
21117 }
21118
21119 case 't': /* indicate TEXT or BINARY */
21120 return "T";
21121
21122 case 'z':
21123 /* coding-system (not including end-of-line format) */
21124 case 'Z':
21125 /* coding-system (including end-of-line type) */
21126 {
21127 int eol_flag = (c == 'Z');
21128 char *p = decode_mode_spec_buf;
21129
21130 if (! FRAME_WINDOW_P (f))
21131 {
21132 /* No need to mention EOL here--the terminal never needs
21133 to do EOL conversion. */
21134 p = decode_mode_spec_coding (CODING_ID_NAME
21135 (FRAME_KEYBOARD_CODING (f)->id),
21136 p, 0);
21137 p = decode_mode_spec_coding (CODING_ID_NAME
21138 (FRAME_TERMINAL_CODING (f)->id),
21139 p, 0);
21140 }
21141 p = decode_mode_spec_coding (BVAR (b, buffer_file_coding_system),
21142 p, eol_flag);
21143
21144 #if 0 /* This proves to be annoying; I think we can do without. -- rms. */
21145 #ifdef subprocesses
21146 obj = Fget_buffer_process (Fcurrent_buffer ());
21147 if (PROCESSP (obj))
21148 {
21149 p = decode_mode_spec_coding (XPROCESS (obj)->decode_coding_system,
21150 p, eol_flag);
21151 p = decode_mode_spec_coding (XPROCESS (obj)->encode_coding_system,
21152 p, eol_flag);
21153 }
21154 #endif /* subprocesses */
21155 #endif /* 0 */
21156 *p = 0;
21157 return decode_mode_spec_buf;
21158 }
21159 }
21160
21161 if (STRINGP (obj))
21162 {
21163 *string = obj;
21164 return SSDATA (obj);
21165 }
21166 else
21167 return "";
21168 }
21169
21170
21171 /* Count up to COUNT lines starting from START_BYTE.
21172 But don't go beyond LIMIT_BYTE.
21173 Return the number of lines thus found (always nonnegative).
21174
21175 Set *BYTE_POS_PTR to 1 if we found COUNT lines, 0 if we hit LIMIT. */
21176
21177 static EMACS_INT
21178 display_count_lines (EMACS_INT start_byte,
21179 EMACS_INT limit_byte, EMACS_INT count,
21180 EMACS_INT *byte_pos_ptr)
21181 {
21182 register unsigned char *cursor;
21183 unsigned char *base;
21184
21185 register EMACS_INT ceiling;
21186 register unsigned char *ceiling_addr;
21187 EMACS_INT orig_count = count;
21188
21189 /* If we are not in selective display mode,
21190 check only for newlines. */
21191 int selective_display = (!NILP (BVAR (current_buffer, selective_display))
21192 && !INTEGERP (BVAR (current_buffer, selective_display)));
21193
21194 if (count > 0)
21195 {
21196 while (start_byte < limit_byte)
21197 {
21198 ceiling = BUFFER_CEILING_OF (start_byte);
21199 ceiling = min (limit_byte - 1, ceiling);
21200 ceiling_addr = BYTE_POS_ADDR (ceiling) + 1;
21201 base = (cursor = BYTE_POS_ADDR (start_byte));
21202 while (1)
21203 {
21204 if (selective_display)
21205 while (*cursor != '\n' && *cursor != 015 && ++cursor != ceiling_addr)
21206 ;
21207 else
21208 while (*cursor != '\n' && ++cursor != ceiling_addr)
21209 ;
21210
21211 if (cursor != ceiling_addr)
21212 {
21213 if (--count == 0)
21214 {
21215 start_byte += cursor - base + 1;
21216 *byte_pos_ptr = start_byte;
21217 return orig_count;
21218 }
21219 else
21220 if (++cursor == ceiling_addr)
21221 break;
21222 }
21223 else
21224 break;
21225 }
21226 start_byte += cursor - base;
21227 }
21228 }
21229 else
21230 {
21231 while (start_byte > limit_byte)
21232 {
21233 ceiling = BUFFER_FLOOR_OF (start_byte - 1);
21234 ceiling = max (limit_byte, ceiling);
21235 ceiling_addr = BYTE_POS_ADDR (ceiling) - 1;
21236 base = (cursor = BYTE_POS_ADDR (start_byte - 1) + 1);
21237 while (1)
21238 {
21239 if (selective_display)
21240 while (--cursor != ceiling_addr
21241 && *cursor != '\n' && *cursor != 015)
21242 ;
21243 else
21244 while (--cursor != ceiling_addr && *cursor != '\n')
21245 ;
21246
21247 if (cursor != ceiling_addr)
21248 {
21249 if (++count == 0)
21250 {
21251 start_byte += cursor - base + 1;
21252 *byte_pos_ptr = start_byte;
21253 /* When scanning backwards, we should
21254 not count the newline posterior to which we stop. */
21255 return - orig_count - 1;
21256 }
21257 }
21258 else
21259 break;
21260 }
21261 /* Here we add 1 to compensate for the last decrement
21262 of CURSOR, which took it past the valid range. */
21263 start_byte += cursor - base + 1;
21264 }
21265 }
21266
21267 *byte_pos_ptr = limit_byte;
21268
21269 if (count < 0)
21270 return - orig_count + count;
21271 return orig_count - count;
21272
21273 }
21274
21275
21276 \f
21277 /***********************************************************************
21278 Displaying strings
21279 ***********************************************************************/
21280
21281 /* Display a NUL-terminated string, starting with index START.
21282
21283 If STRING is non-null, display that C string. Otherwise, the Lisp
21284 string LISP_STRING is displayed. There's a case that STRING is
21285 non-null and LISP_STRING is not nil. It means STRING is a string
21286 data of LISP_STRING. In that case, we display LISP_STRING while
21287 ignoring its text properties.
21288
21289 If FACE_STRING is not nil, FACE_STRING_POS is a position in
21290 FACE_STRING. Display STRING or LISP_STRING with the face at
21291 FACE_STRING_POS in FACE_STRING:
21292
21293 Display the string in the environment given by IT, but use the
21294 standard display table, temporarily.
21295
21296 FIELD_WIDTH is the minimum number of output glyphs to produce.
21297 If STRING has fewer characters than FIELD_WIDTH, pad to the right
21298 with spaces. If STRING has more characters, more than FIELD_WIDTH
21299 glyphs will be produced. FIELD_WIDTH <= 0 means don't pad.
21300
21301 PRECISION is the maximum number of characters to output from
21302 STRING. PRECISION < 0 means don't truncate the string.
21303
21304 This is roughly equivalent to printf format specifiers:
21305
21306 FIELD_WIDTH PRECISION PRINTF
21307 ----------------------------------------
21308 -1 -1 %s
21309 -1 10 %.10s
21310 10 -1 %10s
21311 20 10 %20.10s
21312
21313 MULTIBYTE zero means do not display multibyte chars, > 0 means do
21314 display them, and < 0 means obey the current buffer's value of
21315 enable_multibyte_characters.
21316
21317 Value is the number of columns displayed. */
21318
21319 static int
21320 display_string (const char *string, Lisp_Object lisp_string, Lisp_Object face_string,
21321 EMACS_INT face_string_pos, EMACS_INT start, struct it *it,
21322 int field_width, int precision, int max_x, int multibyte)
21323 {
21324 int hpos_at_start = it->hpos;
21325 int saved_face_id = it->face_id;
21326 struct glyph_row *row = it->glyph_row;
21327 EMACS_INT it_charpos;
21328
21329 /* Initialize the iterator IT for iteration over STRING beginning
21330 with index START. */
21331 reseat_to_string (it, NILP (lisp_string) ? string : NULL, lisp_string, start,
21332 precision, field_width, multibyte);
21333 if (string && STRINGP (lisp_string))
21334 /* LISP_STRING is the one returned by decode_mode_spec. We should
21335 ignore its text properties. */
21336 it->stop_charpos = it->end_charpos;
21337
21338 /* If displaying STRING, set up the face of the iterator from
21339 FACE_STRING, if that's given. */
21340 if (STRINGP (face_string))
21341 {
21342 EMACS_INT endptr;
21343 struct face *face;
21344
21345 it->face_id
21346 = face_at_string_position (it->w, face_string, face_string_pos,
21347 0, it->region_beg_charpos,
21348 it->region_end_charpos,
21349 &endptr, it->base_face_id, 0);
21350 face = FACE_FROM_ID (it->f, it->face_id);
21351 it->face_box_p = face->box != FACE_NO_BOX;
21352 }
21353
21354 /* Set max_x to the maximum allowed X position. Don't let it go
21355 beyond the right edge of the window. */
21356 if (max_x <= 0)
21357 max_x = it->last_visible_x;
21358 else
21359 max_x = min (max_x, it->last_visible_x);
21360
21361 /* Skip over display elements that are not visible. because IT->w is
21362 hscrolled. */
21363 if (it->current_x < it->first_visible_x)
21364 move_it_in_display_line_to (it, 100000, it->first_visible_x,
21365 MOVE_TO_POS | MOVE_TO_X);
21366
21367 row->ascent = it->max_ascent;
21368 row->height = it->max_ascent + it->max_descent;
21369 row->phys_ascent = it->max_phys_ascent;
21370 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
21371 row->extra_line_spacing = it->max_extra_line_spacing;
21372
21373 if (STRINGP (it->string))
21374 it_charpos = IT_STRING_CHARPOS (*it);
21375 else
21376 it_charpos = IT_CHARPOS (*it);
21377
21378 /* This condition is for the case that we are called with current_x
21379 past last_visible_x. */
21380 while (it->current_x < max_x)
21381 {
21382 int x_before, x, n_glyphs_before, i, nglyphs;
21383
21384 /* Get the next display element. */
21385 if (!get_next_display_element (it))
21386 break;
21387
21388 /* Produce glyphs. */
21389 x_before = it->current_x;
21390 n_glyphs_before = row->used[TEXT_AREA];
21391 PRODUCE_GLYPHS (it);
21392
21393 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
21394 i = 0;
21395 x = x_before;
21396 while (i < nglyphs)
21397 {
21398 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
21399
21400 if (it->line_wrap != TRUNCATE
21401 && x + glyph->pixel_width > max_x)
21402 {
21403 /* End of continued line or max_x reached. */
21404 if (CHAR_GLYPH_PADDING_P (*glyph))
21405 {
21406 /* A wide character is unbreakable. */
21407 if (row->reversed_p)
21408 unproduce_glyphs (it, row->used[TEXT_AREA]
21409 - n_glyphs_before);
21410 row->used[TEXT_AREA] = n_glyphs_before;
21411 it->current_x = x_before;
21412 }
21413 else
21414 {
21415 if (row->reversed_p)
21416 unproduce_glyphs (it, row->used[TEXT_AREA]
21417 - (n_glyphs_before + i));
21418 row->used[TEXT_AREA] = n_glyphs_before + i;
21419 it->current_x = x;
21420 }
21421 break;
21422 }
21423 else if (x + glyph->pixel_width >= it->first_visible_x)
21424 {
21425 /* Glyph is at least partially visible. */
21426 ++it->hpos;
21427 if (x < it->first_visible_x)
21428 row->x = x - it->first_visible_x;
21429 }
21430 else
21431 {
21432 /* Glyph is off the left margin of the display area.
21433 Should not happen. */
21434 abort ();
21435 }
21436
21437 row->ascent = max (row->ascent, it->max_ascent);
21438 row->height = max (row->height, it->max_ascent + it->max_descent);
21439 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
21440 row->phys_height = max (row->phys_height,
21441 it->max_phys_ascent + it->max_phys_descent);
21442 row->extra_line_spacing = max (row->extra_line_spacing,
21443 it->max_extra_line_spacing);
21444 x += glyph->pixel_width;
21445 ++i;
21446 }
21447
21448 /* Stop if max_x reached. */
21449 if (i < nglyphs)
21450 break;
21451
21452 /* Stop at line ends. */
21453 if (ITERATOR_AT_END_OF_LINE_P (it))
21454 {
21455 it->continuation_lines_width = 0;
21456 break;
21457 }
21458
21459 set_iterator_to_next (it, 1);
21460 if (STRINGP (it->string))
21461 it_charpos = IT_STRING_CHARPOS (*it);
21462 else
21463 it_charpos = IT_CHARPOS (*it);
21464
21465 /* Stop if truncating at the right edge. */
21466 if (it->line_wrap == TRUNCATE
21467 && it->current_x >= it->last_visible_x)
21468 {
21469 /* Add truncation mark, but don't do it if the line is
21470 truncated at a padding space. */
21471 if (it_charpos < it->string_nchars)
21472 {
21473 if (!FRAME_WINDOW_P (it->f))
21474 {
21475 int ii, n;
21476
21477 if (it->current_x > it->last_visible_x)
21478 {
21479 if (!row->reversed_p)
21480 {
21481 for (ii = row->used[TEXT_AREA] - 1; ii > 0; --ii)
21482 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][ii]))
21483 break;
21484 }
21485 else
21486 {
21487 for (ii = 0; ii < row->used[TEXT_AREA]; ii++)
21488 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][ii]))
21489 break;
21490 unproduce_glyphs (it, ii + 1);
21491 ii = row->used[TEXT_AREA] - (ii + 1);
21492 }
21493 for (n = row->used[TEXT_AREA]; ii < n; ++ii)
21494 {
21495 row->used[TEXT_AREA] = ii;
21496 produce_special_glyphs (it, IT_TRUNCATION);
21497 }
21498 }
21499 produce_special_glyphs (it, IT_TRUNCATION);
21500 }
21501 row->truncated_on_right_p = 1;
21502 }
21503 break;
21504 }
21505 }
21506
21507 /* Maybe insert a truncation at the left. */
21508 if (it->first_visible_x
21509 && it_charpos > 0)
21510 {
21511 if (!FRAME_WINDOW_P (it->f))
21512 insert_left_trunc_glyphs (it);
21513 row->truncated_on_left_p = 1;
21514 }
21515
21516 it->face_id = saved_face_id;
21517
21518 /* Value is number of columns displayed. */
21519 return it->hpos - hpos_at_start;
21520 }
21521
21522
21523 \f
21524 /* This is like a combination of memq and assq. Return 1/2 if PROPVAL
21525 appears as an element of LIST or as the car of an element of LIST.
21526 If PROPVAL is a list, compare each element against LIST in that
21527 way, and return 1/2 if any element of PROPVAL is found in LIST.
21528 Otherwise return 0. This function cannot quit.
21529 The return value is 2 if the text is invisible but with an ellipsis
21530 and 1 if it's invisible and without an ellipsis. */
21531
21532 int
21533 invisible_p (register Lisp_Object propval, Lisp_Object list)
21534 {
21535 register Lisp_Object tail, proptail;
21536
21537 for (tail = list; CONSP (tail); tail = XCDR (tail))
21538 {
21539 register Lisp_Object tem;
21540 tem = XCAR (tail);
21541 if (EQ (propval, tem))
21542 return 1;
21543 if (CONSP (tem) && EQ (propval, XCAR (tem)))
21544 return NILP (XCDR (tem)) ? 1 : 2;
21545 }
21546
21547 if (CONSP (propval))
21548 {
21549 for (proptail = propval; CONSP (proptail); proptail = XCDR (proptail))
21550 {
21551 Lisp_Object propelt;
21552 propelt = XCAR (proptail);
21553 for (tail = list; CONSP (tail); tail = XCDR (tail))
21554 {
21555 register Lisp_Object tem;
21556 tem = XCAR (tail);
21557 if (EQ (propelt, tem))
21558 return 1;
21559 if (CONSP (tem) && EQ (propelt, XCAR (tem)))
21560 return NILP (XCDR (tem)) ? 1 : 2;
21561 }
21562 }
21563 }
21564
21565 return 0;
21566 }
21567
21568 DEFUN ("invisible-p", Finvisible_p, Sinvisible_p, 1, 1, 0,
21569 doc: /* Non-nil if the property makes the text invisible.
21570 POS-OR-PROP can be a marker or number, in which case it is taken to be
21571 a position in the current buffer and the value of the `invisible' property
21572 is checked; or it can be some other value, which is then presumed to be the
21573 value of the `invisible' property of the text of interest.
21574 The non-nil value returned can be t for truly invisible text or something
21575 else if the text is replaced by an ellipsis. */)
21576 (Lisp_Object pos_or_prop)
21577 {
21578 Lisp_Object prop
21579 = (NATNUMP (pos_or_prop) || MARKERP (pos_or_prop)
21580 ? Fget_char_property (pos_or_prop, Qinvisible, Qnil)
21581 : pos_or_prop);
21582 int invis = TEXT_PROP_MEANS_INVISIBLE (prop);
21583 return (invis == 0 ? Qnil
21584 : invis == 1 ? Qt
21585 : make_number (invis));
21586 }
21587
21588 /* Calculate a width or height in pixels from a specification using
21589 the following elements:
21590
21591 SPEC ::=
21592 NUM - a (fractional) multiple of the default font width/height
21593 (NUM) - specifies exactly NUM pixels
21594 UNIT - a fixed number of pixels, see below.
21595 ELEMENT - size of a display element in pixels, see below.
21596 (NUM . SPEC) - equals NUM * SPEC
21597 (+ SPEC SPEC ...) - add pixel values
21598 (- SPEC SPEC ...) - subtract pixel values
21599 (- SPEC) - negate pixel value
21600
21601 NUM ::=
21602 INT or FLOAT - a number constant
21603 SYMBOL - use symbol's (buffer local) variable binding.
21604
21605 UNIT ::=
21606 in - pixels per inch *)
21607 mm - pixels per 1/1000 meter *)
21608 cm - pixels per 1/100 meter *)
21609 width - width of current font in pixels.
21610 height - height of current font in pixels.
21611
21612 *) using the ratio(s) defined in display-pixels-per-inch.
21613
21614 ELEMENT ::=
21615
21616 left-fringe - left fringe width in pixels
21617 right-fringe - right fringe width in pixels
21618
21619 left-margin - left margin width in pixels
21620 right-margin - right margin width in pixels
21621
21622 scroll-bar - scroll-bar area width in pixels
21623
21624 Examples:
21625
21626 Pixels corresponding to 5 inches:
21627 (5 . in)
21628
21629 Total width of non-text areas on left side of window (if scroll-bar is on left):
21630 '(space :width (+ left-fringe left-margin scroll-bar))
21631
21632 Align to first text column (in header line):
21633 '(space :align-to 0)
21634
21635 Align to middle of text area minus half the width of variable `my-image'
21636 containing a loaded image:
21637 '(space :align-to (0.5 . (- text my-image)))
21638
21639 Width of left margin minus width of 1 character in the default font:
21640 '(space :width (- left-margin 1))
21641
21642 Width of left margin minus width of 2 characters in the current font:
21643 '(space :width (- left-margin (2 . width)))
21644
21645 Center 1 character over left-margin (in header line):
21646 '(space :align-to (+ left-margin (0.5 . left-margin) -0.5))
21647
21648 Different ways to express width of left fringe plus left margin minus one pixel:
21649 '(space :width (- (+ left-fringe left-margin) (1)))
21650 '(space :width (+ left-fringe left-margin (- (1))))
21651 '(space :width (+ left-fringe left-margin (-1)))
21652
21653 */
21654
21655 #define NUMVAL(X) \
21656 ((INTEGERP (X) || FLOATP (X)) \
21657 ? XFLOATINT (X) \
21658 : - 1)
21659
21660 static int
21661 calc_pixel_width_or_height (double *res, struct it *it, Lisp_Object prop,
21662 struct font *font, int width_p, int *align_to)
21663 {
21664 double pixels;
21665
21666 #define OK_PIXELS(val) ((*res = (double)(val)), 1)
21667 #define OK_ALIGN_TO(val) ((*align_to = (int)(val)), 1)
21668
21669 if (NILP (prop))
21670 return OK_PIXELS (0);
21671
21672 xassert (FRAME_LIVE_P (it->f));
21673
21674 if (SYMBOLP (prop))
21675 {
21676 if (SCHARS (SYMBOL_NAME (prop)) == 2)
21677 {
21678 char *unit = SSDATA (SYMBOL_NAME (prop));
21679
21680 if (unit[0] == 'i' && unit[1] == 'n')
21681 pixels = 1.0;
21682 else if (unit[0] == 'm' && unit[1] == 'm')
21683 pixels = 25.4;
21684 else if (unit[0] == 'c' && unit[1] == 'm')
21685 pixels = 2.54;
21686 else
21687 pixels = 0;
21688 if (pixels > 0)
21689 {
21690 double ppi;
21691 #ifdef HAVE_WINDOW_SYSTEM
21692 if (FRAME_WINDOW_P (it->f)
21693 && (ppi = (width_p
21694 ? FRAME_X_DISPLAY_INFO (it->f)->resx
21695 : FRAME_X_DISPLAY_INFO (it->f)->resy),
21696 ppi > 0))
21697 return OK_PIXELS (ppi / pixels);
21698 #endif
21699
21700 if ((ppi = NUMVAL (Vdisplay_pixels_per_inch), ppi > 0)
21701 || (CONSP (Vdisplay_pixels_per_inch)
21702 && (ppi = (width_p
21703 ? NUMVAL (XCAR (Vdisplay_pixels_per_inch))
21704 : NUMVAL (XCDR (Vdisplay_pixels_per_inch))),
21705 ppi > 0)))
21706 return OK_PIXELS (ppi / pixels);
21707
21708 return 0;
21709 }
21710 }
21711
21712 #ifdef HAVE_WINDOW_SYSTEM
21713 if (EQ (prop, Qheight))
21714 return OK_PIXELS (font ? FONT_HEIGHT (font) : FRAME_LINE_HEIGHT (it->f));
21715 if (EQ (prop, Qwidth))
21716 return OK_PIXELS (font ? FONT_WIDTH (font) : FRAME_COLUMN_WIDTH (it->f));
21717 #else
21718 if (EQ (prop, Qheight) || EQ (prop, Qwidth))
21719 return OK_PIXELS (1);
21720 #endif
21721
21722 if (EQ (prop, Qtext))
21723 return OK_PIXELS (width_p
21724 ? window_box_width (it->w, TEXT_AREA)
21725 : WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w));
21726
21727 if (align_to && *align_to < 0)
21728 {
21729 *res = 0;
21730 if (EQ (prop, Qleft))
21731 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA));
21732 if (EQ (prop, Qright))
21733 return OK_ALIGN_TO (window_box_right_offset (it->w, TEXT_AREA));
21734 if (EQ (prop, Qcenter))
21735 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA)
21736 + window_box_width (it->w, TEXT_AREA) / 2);
21737 if (EQ (prop, Qleft_fringe))
21738 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
21739 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (it->w)
21740 : window_box_right_offset (it->w, LEFT_MARGIN_AREA));
21741 if (EQ (prop, Qright_fringe))
21742 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
21743 ? window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
21744 : window_box_right_offset (it->w, TEXT_AREA));
21745 if (EQ (prop, Qleft_margin))
21746 return OK_ALIGN_TO (window_box_left_offset (it->w, LEFT_MARGIN_AREA));
21747 if (EQ (prop, Qright_margin))
21748 return OK_ALIGN_TO (window_box_left_offset (it->w, RIGHT_MARGIN_AREA));
21749 if (EQ (prop, Qscroll_bar))
21750 return OK_ALIGN_TO (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (it->w)
21751 ? 0
21752 : (window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
21753 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
21754 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
21755 : 0)));
21756 }
21757 else
21758 {
21759 if (EQ (prop, Qleft_fringe))
21760 return OK_PIXELS (WINDOW_LEFT_FRINGE_WIDTH (it->w));
21761 if (EQ (prop, Qright_fringe))
21762 return OK_PIXELS (WINDOW_RIGHT_FRINGE_WIDTH (it->w));
21763 if (EQ (prop, Qleft_margin))
21764 return OK_PIXELS (WINDOW_LEFT_MARGIN_WIDTH (it->w));
21765 if (EQ (prop, Qright_margin))
21766 return OK_PIXELS (WINDOW_RIGHT_MARGIN_WIDTH (it->w));
21767 if (EQ (prop, Qscroll_bar))
21768 return OK_PIXELS (WINDOW_SCROLL_BAR_AREA_WIDTH (it->w));
21769 }
21770
21771 prop = Fbuffer_local_value (prop, it->w->buffer);
21772 }
21773
21774 if (INTEGERP (prop) || FLOATP (prop))
21775 {
21776 int base_unit = (width_p
21777 ? FRAME_COLUMN_WIDTH (it->f)
21778 : FRAME_LINE_HEIGHT (it->f));
21779 return OK_PIXELS (XFLOATINT (prop) * base_unit);
21780 }
21781
21782 if (CONSP (prop))
21783 {
21784 Lisp_Object car = XCAR (prop);
21785 Lisp_Object cdr = XCDR (prop);
21786
21787 if (SYMBOLP (car))
21788 {
21789 #ifdef HAVE_WINDOW_SYSTEM
21790 if (FRAME_WINDOW_P (it->f)
21791 && valid_image_p (prop))
21792 {
21793 ptrdiff_t id = lookup_image (it->f, prop);
21794 struct image *img = IMAGE_FROM_ID (it->f, id);
21795
21796 return OK_PIXELS (width_p ? img->width : img->height);
21797 }
21798 #endif
21799 if (EQ (car, Qplus) || EQ (car, Qminus))
21800 {
21801 int first = 1;
21802 double px;
21803
21804 pixels = 0;
21805 while (CONSP (cdr))
21806 {
21807 if (!calc_pixel_width_or_height (&px, it, XCAR (cdr),
21808 font, width_p, align_to))
21809 return 0;
21810 if (first)
21811 pixels = (EQ (car, Qplus) ? px : -px), first = 0;
21812 else
21813 pixels += px;
21814 cdr = XCDR (cdr);
21815 }
21816 if (EQ (car, Qminus))
21817 pixels = -pixels;
21818 return OK_PIXELS (pixels);
21819 }
21820
21821 car = Fbuffer_local_value (car, it->w->buffer);
21822 }
21823
21824 if (INTEGERP (car) || FLOATP (car))
21825 {
21826 double fact;
21827 pixels = XFLOATINT (car);
21828 if (NILP (cdr))
21829 return OK_PIXELS (pixels);
21830 if (calc_pixel_width_or_height (&fact, it, cdr,
21831 font, width_p, align_to))
21832 return OK_PIXELS (pixels * fact);
21833 return 0;
21834 }
21835
21836 return 0;
21837 }
21838
21839 return 0;
21840 }
21841
21842 \f
21843 /***********************************************************************
21844 Glyph Display
21845 ***********************************************************************/
21846
21847 #ifdef HAVE_WINDOW_SYSTEM
21848
21849 #if GLYPH_DEBUG
21850
21851 void
21852 dump_glyph_string (struct glyph_string *s)
21853 {
21854 fprintf (stderr, "glyph string\n");
21855 fprintf (stderr, " x, y, w, h = %d, %d, %d, %d\n",
21856 s->x, s->y, s->width, s->height);
21857 fprintf (stderr, " ybase = %d\n", s->ybase);
21858 fprintf (stderr, " hl = %d\n", s->hl);
21859 fprintf (stderr, " left overhang = %d, right = %d\n",
21860 s->left_overhang, s->right_overhang);
21861 fprintf (stderr, " nchars = %d\n", s->nchars);
21862 fprintf (stderr, " extends to end of line = %d\n",
21863 s->extends_to_end_of_line_p);
21864 fprintf (stderr, " font height = %d\n", FONT_HEIGHT (s->font));
21865 fprintf (stderr, " bg width = %d\n", s->background_width);
21866 }
21867
21868 #endif /* GLYPH_DEBUG */
21869
21870 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
21871 of XChar2b structures for S; it can't be allocated in
21872 init_glyph_string because it must be allocated via `alloca'. W
21873 is the window on which S is drawn. ROW and AREA are the glyph row
21874 and area within the row from which S is constructed. START is the
21875 index of the first glyph structure covered by S. HL is a
21876 face-override for drawing S. */
21877
21878 #ifdef HAVE_NTGUI
21879 #define OPTIONAL_HDC(hdc) HDC hdc,
21880 #define DECLARE_HDC(hdc) HDC hdc;
21881 #define ALLOCATE_HDC(hdc, f) hdc = get_frame_dc ((f))
21882 #define RELEASE_HDC(hdc, f) release_frame_dc ((f), (hdc))
21883 #endif
21884
21885 #ifndef OPTIONAL_HDC
21886 #define OPTIONAL_HDC(hdc)
21887 #define DECLARE_HDC(hdc)
21888 #define ALLOCATE_HDC(hdc, f)
21889 #define RELEASE_HDC(hdc, f)
21890 #endif
21891
21892 static void
21893 init_glyph_string (struct glyph_string *s,
21894 OPTIONAL_HDC (hdc)
21895 XChar2b *char2b, struct window *w, struct glyph_row *row,
21896 enum glyph_row_area area, int start, enum draw_glyphs_face hl)
21897 {
21898 memset (s, 0, sizeof *s);
21899 s->w = w;
21900 s->f = XFRAME (w->frame);
21901 #ifdef HAVE_NTGUI
21902 s->hdc = hdc;
21903 #endif
21904 s->display = FRAME_X_DISPLAY (s->f);
21905 s->window = FRAME_X_WINDOW (s->f);
21906 s->char2b = char2b;
21907 s->hl = hl;
21908 s->row = row;
21909 s->area = area;
21910 s->first_glyph = row->glyphs[area] + start;
21911 s->height = row->height;
21912 s->y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
21913 s->ybase = s->y + row->ascent;
21914 }
21915
21916
21917 /* Append the list of glyph strings with head H and tail T to the list
21918 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
21919
21920 static inline void
21921 append_glyph_string_lists (struct glyph_string **head, struct glyph_string **tail,
21922 struct glyph_string *h, struct glyph_string *t)
21923 {
21924 if (h)
21925 {
21926 if (*head)
21927 (*tail)->next = h;
21928 else
21929 *head = h;
21930 h->prev = *tail;
21931 *tail = t;
21932 }
21933 }
21934
21935
21936 /* Prepend the list of glyph strings with head H and tail T to the
21937 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
21938 result. */
21939
21940 static inline void
21941 prepend_glyph_string_lists (struct glyph_string **head, struct glyph_string **tail,
21942 struct glyph_string *h, struct glyph_string *t)
21943 {
21944 if (h)
21945 {
21946 if (*head)
21947 (*head)->prev = t;
21948 else
21949 *tail = t;
21950 t->next = *head;
21951 *head = h;
21952 }
21953 }
21954
21955
21956 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
21957 Set *HEAD and *TAIL to the resulting list. */
21958
21959 static inline void
21960 append_glyph_string (struct glyph_string **head, struct glyph_string **tail,
21961 struct glyph_string *s)
21962 {
21963 s->next = s->prev = NULL;
21964 append_glyph_string_lists (head, tail, s, s);
21965 }
21966
21967
21968 /* Get face and two-byte form of character C in face FACE_ID on frame F.
21969 The encoding of C is returned in *CHAR2B. DISPLAY_P non-zero means
21970 make sure that X resources for the face returned are allocated.
21971 Value is a pointer to a realized face that is ready for display if
21972 DISPLAY_P is non-zero. */
21973
21974 static inline struct face *
21975 get_char_face_and_encoding (struct frame *f, int c, int face_id,
21976 XChar2b *char2b, int display_p)
21977 {
21978 struct face *face = FACE_FROM_ID (f, face_id);
21979
21980 if (face->font)
21981 {
21982 unsigned code = face->font->driver->encode_char (face->font, c);
21983
21984 if (code != FONT_INVALID_CODE)
21985 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
21986 else
21987 STORE_XCHAR2B (char2b, 0, 0);
21988 }
21989
21990 /* Make sure X resources of the face are allocated. */
21991 #ifdef HAVE_X_WINDOWS
21992 if (display_p)
21993 #endif
21994 {
21995 xassert (face != NULL);
21996 PREPARE_FACE_FOR_DISPLAY (f, face);
21997 }
21998
21999 return face;
22000 }
22001
22002
22003 /* Get face and two-byte form of character glyph GLYPH on frame F.
22004 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
22005 a pointer to a realized face that is ready for display. */
22006
22007 static inline struct face *
22008 get_glyph_face_and_encoding (struct frame *f, struct glyph *glyph,
22009 XChar2b *char2b, int *two_byte_p)
22010 {
22011 struct face *face;
22012
22013 xassert (glyph->type == CHAR_GLYPH);
22014 face = FACE_FROM_ID (f, glyph->face_id);
22015
22016 if (two_byte_p)
22017 *two_byte_p = 0;
22018
22019 if (face->font)
22020 {
22021 unsigned code;
22022
22023 if (CHAR_BYTE8_P (glyph->u.ch))
22024 code = CHAR_TO_BYTE8 (glyph->u.ch);
22025 else
22026 code = face->font->driver->encode_char (face->font, glyph->u.ch);
22027
22028 if (code != FONT_INVALID_CODE)
22029 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
22030 else
22031 STORE_XCHAR2B (char2b, 0, 0);
22032 }
22033
22034 /* Make sure X resources of the face are allocated. */
22035 xassert (face != NULL);
22036 PREPARE_FACE_FOR_DISPLAY (f, face);
22037 return face;
22038 }
22039
22040
22041 /* Get glyph code of character C in FONT in the two-byte form CHAR2B.
22042 Retunr 1 if FONT has a glyph for C, otherwise return 0. */
22043
22044 static inline int
22045 get_char_glyph_code (int c, struct font *font, XChar2b *char2b)
22046 {
22047 unsigned code;
22048
22049 if (CHAR_BYTE8_P (c))
22050 code = CHAR_TO_BYTE8 (c);
22051 else
22052 code = font->driver->encode_char (font, c);
22053
22054 if (code == FONT_INVALID_CODE)
22055 return 0;
22056 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
22057 return 1;
22058 }
22059
22060
22061 /* Fill glyph string S with composition components specified by S->cmp.
22062
22063 BASE_FACE is the base face of the composition.
22064 S->cmp_from is the index of the first component for S.
22065
22066 OVERLAPS non-zero means S should draw the foreground only, and use
22067 its physical height for clipping. See also draw_glyphs.
22068
22069 Value is the index of a component not in S. */
22070
22071 static int
22072 fill_composite_glyph_string (struct glyph_string *s, struct face *base_face,
22073 int overlaps)
22074 {
22075 int i;
22076 /* For all glyphs of this composition, starting at the offset
22077 S->cmp_from, until we reach the end of the definition or encounter a
22078 glyph that requires the different face, add it to S. */
22079 struct face *face;
22080
22081 xassert (s);
22082
22083 s->for_overlaps = overlaps;
22084 s->face = NULL;
22085 s->font = NULL;
22086 for (i = s->cmp_from; i < s->cmp->glyph_len; i++)
22087 {
22088 int c = COMPOSITION_GLYPH (s->cmp, i);
22089
22090 /* TAB in a composition means display glyphs with padding space
22091 on the left or right. */
22092 if (c != '\t')
22093 {
22094 int face_id = FACE_FOR_CHAR (s->f, base_face->ascii_face, c,
22095 -1, Qnil);
22096
22097 face = get_char_face_and_encoding (s->f, c, face_id,
22098 s->char2b + i, 1);
22099 if (face)
22100 {
22101 if (! s->face)
22102 {
22103 s->face = face;
22104 s->font = s->face->font;
22105 }
22106 else if (s->face != face)
22107 break;
22108 }
22109 }
22110 ++s->nchars;
22111 }
22112 s->cmp_to = i;
22113
22114 /* All glyph strings for the same composition has the same width,
22115 i.e. the width set for the first component of the composition. */
22116 s->width = s->first_glyph->pixel_width;
22117
22118 /* If the specified font could not be loaded, use the frame's
22119 default font, but record the fact that we couldn't load it in
22120 the glyph string so that we can draw rectangles for the
22121 characters of the glyph string. */
22122 if (s->font == NULL)
22123 {
22124 s->font_not_found_p = 1;
22125 s->font = FRAME_FONT (s->f);
22126 }
22127
22128 /* Adjust base line for subscript/superscript text. */
22129 s->ybase += s->first_glyph->voffset;
22130
22131 /* This glyph string must always be drawn with 16-bit functions. */
22132 s->two_byte_p = 1;
22133
22134 return s->cmp_to;
22135 }
22136
22137 static int
22138 fill_gstring_glyph_string (struct glyph_string *s, int face_id,
22139 int start, int end, int overlaps)
22140 {
22141 struct glyph *glyph, *last;
22142 Lisp_Object lgstring;
22143 int i;
22144
22145 s->for_overlaps = overlaps;
22146 glyph = s->row->glyphs[s->area] + start;
22147 last = s->row->glyphs[s->area] + end;
22148 s->cmp_id = glyph->u.cmp.id;
22149 s->cmp_from = glyph->slice.cmp.from;
22150 s->cmp_to = glyph->slice.cmp.to + 1;
22151 s->face = FACE_FROM_ID (s->f, face_id);
22152 lgstring = composition_gstring_from_id (s->cmp_id);
22153 s->font = XFONT_OBJECT (LGSTRING_FONT (lgstring));
22154 glyph++;
22155 while (glyph < last
22156 && glyph->u.cmp.automatic
22157 && glyph->u.cmp.id == s->cmp_id
22158 && s->cmp_to == glyph->slice.cmp.from)
22159 s->cmp_to = (glyph++)->slice.cmp.to + 1;
22160
22161 for (i = s->cmp_from; i < s->cmp_to; i++)
22162 {
22163 Lisp_Object lglyph = LGSTRING_GLYPH (lgstring, i);
22164 unsigned code = LGLYPH_CODE (lglyph);
22165
22166 STORE_XCHAR2B ((s->char2b + i), code >> 8, code & 0xFF);
22167 }
22168 s->width = composition_gstring_width (lgstring, s->cmp_from, s->cmp_to, NULL);
22169 return glyph - s->row->glyphs[s->area];
22170 }
22171
22172
22173 /* Fill glyph string S from a sequence glyphs for glyphless characters.
22174 See the comment of fill_glyph_string for arguments.
22175 Value is the index of the first glyph not in S. */
22176
22177
22178 static int
22179 fill_glyphless_glyph_string (struct glyph_string *s, int face_id,
22180 int start, int end, int overlaps)
22181 {
22182 struct glyph *glyph, *last;
22183 int voffset;
22184
22185 xassert (s->first_glyph->type == GLYPHLESS_GLYPH);
22186 s->for_overlaps = overlaps;
22187 glyph = s->row->glyphs[s->area] + start;
22188 last = s->row->glyphs[s->area] + end;
22189 voffset = glyph->voffset;
22190 s->face = FACE_FROM_ID (s->f, face_id);
22191 s->font = s->face->font;
22192 s->nchars = 1;
22193 s->width = glyph->pixel_width;
22194 glyph++;
22195 while (glyph < last
22196 && glyph->type == GLYPHLESS_GLYPH
22197 && glyph->voffset == voffset
22198 && glyph->face_id == face_id)
22199 {
22200 s->nchars++;
22201 s->width += glyph->pixel_width;
22202 glyph++;
22203 }
22204 s->ybase += voffset;
22205 return glyph - s->row->glyphs[s->area];
22206 }
22207
22208
22209 /* Fill glyph string S from a sequence of character glyphs.
22210
22211 FACE_ID is the face id of the string. START is the index of the
22212 first glyph to consider, END is the index of the last + 1.
22213 OVERLAPS non-zero means S should draw the foreground only, and use
22214 its physical height for clipping. See also draw_glyphs.
22215
22216 Value is the index of the first glyph not in S. */
22217
22218 static int
22219 fill_glyph_string (struct glyph_string *s, int face_id,
22220 int start, int end, int overlaps)
22221 {
22222 struct glyph *glyph, *last;
22223 int voffset;
22224 int glyph_not_available_p;
22225
22226 xassert (s->f == XFRAME (s->w->frame));
22227 xassert (s->nchars == 0);
22228 xassert (start >= 0 && end > start);
22229
22230 s->for_overlaps = overlaps;
22231 glyph = s->row->glyphs[s->area] + start;
22232 last = s->row->glyphs[s->area] + end;
22233 voffset = glyph->voffset;
22234 s->padding_p = glyph->padding_p;
22235 glyph_not_available_p = glyph->glyph_not_available_p;
22236
22237 while (glyph < last
22238 && glyph->type == CHAR_GLYPH
22239 && glyph->voffset == voffset
22240 /* Same face id implies same font, nowadays. */
22241 && glyph->face_id == face_id
22242 && glyph->glyph_not_available_p == glyph_not_available_p)
22243 {
22244 int two_byte_p;
22245
22246 s->face = get_glyph_face_and_encoding (s->f, glyph,
22247 s->char2b + s->nchars,
22248 &two_byte_p);
22249 s->two_byte_p = two_byte_p;
22250 ++s->nchars;
22251 xassert (s->nchars <= end - start);
22252 s->width += glyph->pixel_width;
22253 if (glyph++->padding_p != s->padding_p)
22254 break;
22255 }
22256
22257 s->font = s->face->font;
22258
22259 /* If the specified font could not be loaded, use the frame's font,
22260 but record the fact that we couldn't load it in
22261 S->font_not_found_p so that we can draw rectangles for the
22262 characters of the glyph string. */
22263 if (s->font == NULL || glyph_not_available_p)
22264 {
22265 s->font_not_found_p = 1;
22266 s->font = FRAME_FONT (s->f);
22267 }
22268
22269 /* Adjust base line for subscript/superscript text. */
22270 s->ybase += voffset;
22271
22272 xassert (s->face && s->face->gc);
22273 return glyph - s->row->glyphs[s->area];
22274 }
22275
22276
22277 /* Fill glyph string S from image glyph S->first_glyph. */
22278
22279 static void
22280 fill_image_glyph_string (struct glyph_string *s)
22281 {
22282 xassert (s->first_glyph->type == IMAGE_GLYPH);
22283 s->img = IMAGE_FROM_ID (s->f, s->first_glyph->u.img_id);
22284 xassert (s->img);
22285 s->slice = s->first_glyph->slice.img;
22286 s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
22287 s->font = s->face->font;
22288 s->width = s->first_glyph->pixel_width;
22289
22290 /* Adjust base line for subscript/superscript text. */
22291 s->ybase += s->first_glyph->voffset;
22292 }
22293
22294
22295 /* Fill glyph string S from a sequence of stretch glyphs.
22296
22297 START is the index of the first glyph to consider,
22298 END is the index of the last + 1.
22299
22300 Value is the index of the first glyph not in S. */
22301
22302 static int
22303 fill_stretch_glyph_string (struct glyph_string *s, int start, int end)
22304 {
22305 struct glyph *glyph, *last;
22306 int voffset, face_id;
22307
22308 xassert (s->first_glyph->type == STRETCH_GLYPH);
22309
22310 glyph = s->row->glyphs[s->area] + start;
22311 last = s->row->glyphs[s->area] + end;
22312 face_id = glyph->face_id;
22313 s->face = FACE_FROM_ID (s->f, face_id);
22314 s->font = s->face->font;
22315 s->width = glyph->pixel_width;
22316 s->nchars = 1;
22317 voffset = glyph->voffset;
22318
22319 for (++glyph;
22320 (glyph < last
22321 && glyph->type == STRETCH_GLYPH
22322 && glyph->voffset == voffset
22323 && glyph->face_id == face_id);
22324 ++glyph)
22325 s->width += glyph->pixel_width;
22326
22327 /* Adjust base line for subscript/superscript text. */
22328 s->ybase += voffset;
22329
22330 /* The case that face->gc == 0 is handled when drawing the glyph
22331 string by calling PREPARE_FACE_FOR_DISPLAY. */
22332 xassert (s->face);
22333 return glyph - s->row->glyphs[s->area];
22334 }
22335
22336 static struct font_metrics *
22337 get_per_char_metric (struct font *font, XChar2b *char2b)
22338 {
22339 static struct font_metrics metrics;
22340 unsigned code = (XCHAR2B_BYTE1 (char2b) << 8) | XCHAR2B_BYTE2 (char2b);
22341
22342 if (! font || code == FONT_INVALID_CODE)
22343 return NULL;
22344 font->driver->text_extents (font, &code, 1, &metrics);
22345 return &metrics;
22346 }
22347
22348 /* EXPORT for RIF:
22349 Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
22350 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
22351 assumed to be zero. */
22352
22353 void
22354 x_get_glyph_overhangs (struct glyph *glyph, struct frame *f, int *left, int *right)
22355 {
22356 *left = *right = 0;
22357
22358 if (glyph->type == CHAR_GLYPH)
22359 {
22360 struct face *face;
22361 XChar2b char2b;
22362 struct font_metrics *pcm;
22363
22364 face = get_glyph_face_and_encoding (f, glyph, &char2b, NULL);
22365 if (face->font && (pcm = get_per_char_metric (face->font, &char2b)))
22366 {
22367 if (pcm->rbearing > pcm->width)
22368 *right = pcm->rbearing - pcm->width;
22369 if (pcm->lbearing < 0)
22370 *left = -pcm->lbearing;
22371 }
22372 }
22373 else if (glyph->type == COMPOSITE_GLYPH)
22374 {
22375 if (! glyph->u.cmp.automatic)
22376 {
22377 struct composition *cmp = composition_table[glyph->u.cmp.id];
22378
22379 if (cmp->rbearing > cmp->pixel_width)
22380 *right = cmp->rbearing - cmp->pixel_width;
22381 if (cmp->lbearing < 0)
22382 *left = - cmp->lbearing;
22383 }
22384 else
22385 {
22386 Lisp_Object gstring = composition_gstring_from_id (glyph->u.cmp.id);
22387 struct font_metrics metrics;
22388
22389 composition_gstring_width (gstring, glyph->slice.cmp.from,
22390 glyph->slice.cmp.to + 1, &metrics);
22391 if (metrics.rbearing > metrics.width)
22392 *right = metrics.rbearing - metrics.width;
22393 if (metrics.lbearing < 0)
22394 *left = - metrics.lbearing;
22395 }
22396 }
22397 }
22398
22399
22400 /* Return the index of the first glyph preceding glyph string S that
22401 is overwritten by S because of S's left overhang. Value is -1
22402 if no glyphs are overwritten. */
22403
22404 static int
22405 left_overwritten (struct glyph_string *s)
22406 {
22407 int k;
22408
22409 if (s->left_overhang)
22410 {
22411 int x = 0, i;
22412 struct glyph *glyphs = s->row->glyphs[s->area];
22413 int first = s->first_glyph - glyphs;
22414
22415 for (i = first - 1; i >= 0 && x > -s->left_overhang; --i)
22416 x -= glyphs[i].pixel_width;
22417
22418 k = i + 1;
22419 }
22420 else
22421 k = -1;
22422
22423 return k;
22424 }
22425
22426
22427 /* Return the index of the first glyph preceding glyph string S that
22428 is overwriting S because of its right overhang. Value is -1 if no
22429 glyph in front of S overwrites S. */
22430
22431 static int
22432 left_overwriting (struct glyph_string *s)
22433 {
22434 int i, k, x;
22435 struct glyph *glyphs = s->row->glyphs[s->area];
22436 int first = s->first_glyph - glyphs;
22437
22438 k = -1;
22439 x = 0;
22440 for (i = first - 1; i >= 0; --i)
22441 {
22442 int left, right;
22443 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
22444 if (x + right > 0)
22445 k = i;
22446 x -= glyphs[i].pixel_width;
22447 }
22448
22449 return k;
22450 }
22451
22452
22453 /* Return the index of the last glyph following glyph string S that is
22454 overwritten by S because of S's right overhang. Value is -1 if
22455 no such glyph is found. */
22456
22457 static int
22458 right_overwritten (struct glyph_string *s)
22459 {
22460 int k = -1;
22461
22462 if (s->right_overhang)
22463 {
22464 int x = 0, i;
22465 struct glyph *glyphs = s->row->glyphs[s->area];
22466 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
22467 int end = s->row->used[s->area];
22468
22469 for (i = first; i < end && s->right_overhang > x; ++i)
22470 x += glyphs[i].pixel_width;
22471
22472 k = i;
22473 }
22474
22475 return k;
22476 }
22477
22478
22479 /* Return the index of the last glyph following glyph string S that
22480 overwrites S because of its left overhang. Value is negative
22481 if no such glyph is found. */
22482
22483 static int
22484 right_overwriting (struct glyph_string *s)
22485 {
22486 int i, k, x;
22487 int end = s->row->used[s->area];
22488 struct glyph *glyphs = s->row->glyphs[s->area];
22489 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
22490
22491 k = -1;
22492 x = 0;
22493 for (i = first; i < end; ++i)
22494 {
22495 int left, right;
22496 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
22497 if (x - left < 0)
22498 k = i;
22499 x += glyphs[i].pixel_width;
22500 }
22501
22502 return k;
22503 }
22504
22505
22506 /* Set background width of glyph string S. START is the index of the
22507 first glyph following S. LAST_X is the right-most x-position + 1
22508 in the drawing area. */
22509
22510 static inline void
22511 set_glyph_string_background_width (struct glyph_string *s, int start, int last_x)
22512 {
22513 /* If the face of this glyph string has to be drawn to the end of
22514 the drawing area, set S->extends_to_end_of_line_p. */
22515
22516 if (start == s->row->used[s->area]
22517 && s->area == TEXT_AREA
22518 && ((s->row->fill_line_p
22519 && (s->hl == DRAW_NORMAL_TEXT
22520 || s->hl == DRAW_IMAGE_RAISED
22521 || s->hl == DRAW_IMAGE_SUNKEN))
22522 || s->hl == DRAW_MOUSE_FACE))
22523 s->extends_to_end_of_line_p = 1;
22524
22525 /* If S extends its face to the end of the line, set its
22526 background_width to the distance to the right edge of the drawing
22527 area. */
22528 if (s->extends_to_end_of_line_p)
22529 s->background_width = last_x - s->x + 1;
22530 else
22531 s->background_width = s->width;
22532 }
22533
22534
22535 /* Compute overhangs and x-positions for glyph string S and its
22536 predecessors, or successors. X is the starting x-position for S.
22537 BACKWARD_P non-zero means process predecessors. */
22538
22539 static void
22540 compute_overhangs_and_x (struct glyph_string *s, int x, int backward_p)
22541 {
22542 if (backward_p)
22543 {
22544 while (s)
22545 {
22546 if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
22547 FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
22548 x -= s->width;
22549 s->x = x;
22550 s = s->prev;
22551 }
22552 }
22553 else
22554 {
22555 while (s)
22556 {
22557 if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
22558 FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
22559 s->x = x;
22560 x += s->width;
22561 s = s->next;
22562 }
22563 }
22564 }
22565
22566
22567
22568 /* The following macros are only called from draw_glyphs below.
22569 They reference the following parameters of that function directly:
22570 `w', `row', `area', and `overlap_p'
22571 as well as the following local variables:
22572 `s', `f', and `hdc' (in W32) */
22573
22574 #ifdef HAVE_NTGUI
22575 /* On W32, silently add local `hdc' variable to argument list of
22576 init_glyph_string. */
22577 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
22578 init_glyph_string (s, hdc, char2b, w, row, area, start, hl)
22579 #else
22580 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
22581 init_glyph_string (s, char2b, w, row, area, start, hl)
22582 #endif
22583
22584 /* Add a glyph string for a stretch glyph to the list of strings
22585 between HEAD and TAIL. START is the index of the stretch glyph in
22586 row area AREA of glyph row ROW. END is the index of the last glyph
22587 in that glyph row area. X is the current output position assigned
22588 to the new glyph string constructed. HL overrides that face of the
22589 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
22590 is the right-most x-position of the drawing area. */
22591
22592 /* SunOS 4 bundled cc, barfed on continuations in the arg lists here
22593 and below -- keep them on one line. */
22594 #define BUILD_STRETCH_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
22595 do \
22596 { \
22597 s = (struct glyph_string *) alloca (sizeof *s); \
22598 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
22599 START = fill_stretch_glyph_string (s, START, END); \
22600 append_glyph_string (&HEAD, &TAIL, s); \
22601 s->x = (X); \
22602 } \
22603 while (0)
22604
22605
22606 /* Add a glyph string for an image glyph to the list of strings
22607 between HEAD and TAIL. START is the index of the image glyph in
22608 row area AREA of glyph row ROW. END is the index of the last glyph
22609 in that glyph row area. X is the current output position assigned
22610 to the new glyph string constructed. HL overrides that face of the
22611 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
22612 is the right-most x-position of the drawing area. */
22613
22614 #define BUILD_IMAGE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
22615 do \
22616 { \
22617 s = (struct glyph_string *) alloca (sizeof *s); \
22618 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
22619 fill_image_glyph_string (s); \
22620 append_glyph_string (&HEAD, &TAIL, s); \
22621 ++START; \
22622 s->x = (X); \
22623 } \
22624 while (0)
22625
22626
22627 /* Add a glyph string for a sequence of character glyphs to the list
22628 of strings between HEAD and TAIL. START is the index of the first
22629 glyph in row area AREA of glyph row ROW that is part of the new
22630 glyph string. END is the index of the last glyph in that glyph row
22631 area. X is the current output position assigned to the new glyph
22632 string constructed. HL overrides that face of the glyph; e.g. it
22633 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
22634 right-most x-position of the drawing area. */
22635
22636 #define BUILD_CHAR_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
22637 do \
22638 { \
22639 int face_id; \
22640 XChar2b *char2b; \
22641 \
22642 face_id = (row)->glyphs[area][START].face_id; \
22643 \
22644 s = (struct glyph_string *) alloca (sizeof *s); \
22645 char2b = (XChar2b *) alloca ((END - START) * sizeof *char2b); \
22646 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
22647 append_glyph_string (&HEAD, &TAIL, s); \
22648 s->x = (X); \
22649 START = fill_glyph_string (s, face_id, START, END, overlaps); \
22650 } \
22651 while (0)
22652
22653
22654 /* Add a glyph string for a composite sequence to the list of strings
22655 between HEAD and TAIL. START is the index of the first glyph in
22656 row area AREA of glyph row ROW that is part of the new glyph
22657 string. END is the index of the last glyph in that glyph row area.
22658 X is the current output position assigned to the new glyph string
22659 constructed. HL overrides that face of the glyph; e.g. it is
22660 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
22661 x-position of the drawing area. */
22662
22663 #define BUILD_COMPOSITE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
22664 do { \
22665 int face_id = (row)->glyphs[area][START].face_id; \
22666 struct face *base_face = FACE_FROM_ID (f, face_id); \
22667 ptrdiff_t cmp_id = (row)->glyphs[area][START].u.cmp.id; \
22668 struct composition *cmp = composition_table[cmp_id]; \
22669 XChar2b *char2b; \
22670 struct glyph_string *first_s IF_LINT (= NULL); \
22671 int n; \
22672 \
22673 char2b = (XChar2b *) alloca ((sizeof *char2b) * cmp->glyph_len); \
22674 \
22675 /* Make glyph_strings for each glyph sequence that is drawable by \
22676 the same face, and append them to HEAD/TAIL. */ \
22677 for (n = 0; n < cmp->glyph_len;) \
22678 { \
22679 s = (struct glyph_string *) alloca (sizeof *s); \
22680 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
22681 append_glyph_string (&(HEAD), &(TAIL), s); \
22682 s->cmp = cmp; \
22683 s->cmp_from = n; \
22684 s->x = (X); \
22685 if (n == 0) \
22686 first_s = s; \
22687 n = fill_composite_glyph_string (s, base_face, overlaps); \
22688 } \
22689 \
22690 ++START; \
22691 s = first_s; \
22692 } while (0)
22693
22694
22695 /* Add a glyph string for a glyph-string sequence to the list of strings
22696 between HEAD and TAIL. */
22697
22698 #define BUILD_GSTRING_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
22699 do { \
22700 int face_id; \
22701 XChar2b *char2b; \
22702 Lisp_Object gstring; \
22703 \
22704 face_id = (row)->glyphs[area][START].face_id; \
22705 gstring = (composition_gstring_from_id \
22706 ((row)->glyphs[area][START].u.cmp.id)); \
22707 s = (struct glyph_string *) alloca (sizeof *s); \
22708 char2b = (XChar2b *) alloca ((sizeof *char2b) \
22709 * LGSTRING_GLYPH_LEN (gstring)); \
22710 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
22711 append_glyph_string (&(HEAD), &(TAIL), s); \
22712 s->x = (X); \
22713 START = fill_gstring_glyph_string (s, face_id, START, END, overlaps); \
22714 } while (0)
22715
22716
22717 /* Add a glyph string for a sequence of glyphless character's glyphs
22718 to the list of strings between HEAD and TAIL. The meanings of
22719 arguments are the same as those of BUILD_CHAR_GLYPH_STRINGS. */
22720
22721 #define BUILD_GLYPHLESS_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
22722 do \
22723 { \
22724 int face_id; \
22725 \
22726 face_id = (row)->glyphs[area][START].face_id; \
22727 \
22728 s = (struct glyph_string *) alloca (sizeof *s); \
22729 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
22730 append_glyph_string (&HEAD, &TAIL, s); \
22731 s->x = (X); \
22732 START = fill_glyphless_glyph_string (s, face_id, START, END, \
22733 overlaps); \
22734 } \
22735 while (0)
22736
22737
22738 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
22739 of AREA of glyph row ROW on window W between indices START and END.
22740 HL overrides the face for drawing glyph strings, e.g. it is
22741 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
22742 x-positions of the drawing area.
22743
22744 This is an ugly monster macro construct because we must use alloca
22745 to allocate glyph strings (because draw_glyphs can be called
22746 asynchronously). */
22747
22748 #define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
22749 do \
22750 { \
22751 HEAD = TAIL = NULL; \
22752 while (START < END) \
22753 { \
22754 struct glyph *first_glyph = (row)->glyphs[area] + START; \
22755 switch (first_glyph->type) \
22756 { \
22757 case CHAR_GLYPH: \
22758 BUILD_CHAR_GLYPH_STRINGS (START, END, HEAD, TAIL, \
22759 HL, X, LAST_X); \
22760 break; \
22761 \
22762 case COMPOSITE_GLYPH: \
22763 if (first_glyph->u.cmp.automatic) \
22764 BUILD_GSTRING_GLYPH_STRING (START, END, HEAD, TAIL, \
22765 HL, X, LAST_X); \
22766 else \
22767 BUILD_COMPOSITE_GLYPH_STRING (START, END, HEAD, TAIL, \
22768 HL, X, LAST_X); \
22769 break; \
22770 \
22771 case STRETCH_GLYPH: \
22772 BUILD_STRETCH_GLYPH_STRING (START, END, HEAD, TAIL, \
22773 HL, X, LAST_X); \
22774 break; \
22775 \
22776 case IMAGE_GLYPH: \
22777 BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL, \
22778 HL, X, LAST_X); \
22779 break; \
22780 \
22781 case GLYPHLESS_GLYPH: \
22782 BUILD_GLYPHLESS_GLYPH_STRING (START, END, HEAD, TAIL, \
22783 HL, X, LAST_X); \
22784 break; \
22785 \
22786 default: \
22787 abort (); \
22788 } \
22789 \
22790 if (s) \
22791 { \
22792 set_glyph_string_background_width (s, START, LAST_X); \
22793 (X) += s->width; \
22794 } \
22795 } \
22796 } while (0)
22797
22798
22799 /* Draw glyphs between START and END in AREA of ROW on window W,
22800 starting at x-position X. X is relative to AREA in W. HL is a
22801 face-override with the following meaning:
22802
22803 DRAW_NORMAL_TEXT draw normally
22804 DRAW_CURSOR draw in cursor face
22805 DRAW_MOUSE_FACE draw in mouse face.
22806 DRAW_INVERSE_VIDEO draw in mode line face
22807 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
22808 DRAW_IMAGE_RAISED draw an image with a raised relief around it
22809
22810 If OVERLAPS is non-zero, draw only the foreground of characters and
22811 clip to the physical height of ROW. Non-zero value also defines
22812 the overlapping part to be drawn:
22813
22814 OVERLAPS_PRED overlap with preceding rows
22815 OVERLAPS_SUCC overlap with succeeding rows
22816 OVERLAPS_BOTH overlap with both preceding/succeeding rows
22817 OVERLAPS_ERASED_CURSOR overlap with erased cursor area
22818
22819 Value is the x-position reached, relative to AREA of W. */
22820
22821 static int
22822 draw_glyphs (struct window *w, int x, struct glyph_row *row,
22823 enum glyph_row_area area, EMACS_INT start, EMACS_INT end,
22824 enum draw_glyphs_face hl, int overlaps)
22825 {
22826 struct glyph_string *head, *tail;
22827 struct glyph_string *s;
22828 struct glyph_string *clip_head = NULL, *clip_tail = NULL;
22829 int i, j, x_reached, last_x, area_left = 0;
22830 struct frame *f = XFRAME (WINDOW_FRAME (w));
22831 DECLARE_HDC (hdc);
22832
22833 ALLOCATE_HDC (hdc, f);
22834
22835 /* Let's rather be paranoid than getting a SEGV. */
22836 end = min (end, row->used[area]);
22837 start = max (0, start);
22838 start = min (end, start);
22839
22840 /* Translate X to frame coordinates. Set last_x to the right
22841 end of the drawing area. */
22842 if (row->full_width_p)
22843 {
22844 /* X is relative to the left edge of W, without scroll bars
22845 or fringes. */
22846 area_left = WINDOW_LEFT_EDGE_X (w);
22847 last_x = WINDOW_LEFT_EDGE_X (w) + WINDOW_TOTAL_WIDTH (w);
22848 }
22849 else
22850 {
22851 area_left = window_box_left (w, area);
22852 last_x = area_left + window_box_width (w, area);
22853 }
22854 x += area_left;
22855
22856 /* Build a doubly-linked list of glyph_string structures between
22857 head and tail from what we have to draw. Note that the macro
22858 BUILD_GLYPH_STRINGS will modify its start parameter. That's
22859 the reason we use a separate variable `i'. */
22860 i = start;
22861 BUILD_GLYPH_STRINGS (i, end, head, tail, hl, x, last_x);
22862 if (tail)
22863 x_reached = tail->x + tail->background_width;
22864 else
22865 x_reached = x;
22866
22867 /* If there are any glyphs with lbearing < 0 or rbearing > width in
22868 the row, redraw some glyphs in front or following the glyph
22869 strings built above. */
22870 if (head && !overlaps && row->contains_overlapping_glyphs_p)
22871 {
22872 struct glyph_string *h, *t;
22873 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
22874 int mouse_beg_col IF_LINT (= 0), mouse_end_col IF_LINT (= 0);
22875 int check_mouse_face = 0;
22876 int dummy_x = 0;
22877
22878 /* If mouse highlighting is on, we may need to draw adjacent
22879 glyphs using mouse-face highlighting. */
22880 if (area == TEXT_AREA && row->mouse_face_p)
22881 {
22882 struct glyph_row *mouse_beg_row, *mouse_end_row;
22883
22884 mouse_beg_row = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_beg_row);
22885 mouse_end_row = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_end_row);
22886
22887 if (row >= mouse_beg_row && row <= mouse_end_row)
22888 {
22889 check_mouse_face = 1;
22890 mouse_beg_col = (row == mouse_beg_row)
22891 ? hlinfo->mouse_face_beg_col : 0;
22892 mouse_end_col = (row == mouse_end_row)
22893 ? hlinfo->mouse_face_end_col
22894 : row->used[TEXT_AREA];
22895 }
22896 }
22897
22898 /* Compute overhangs for all glyph strings. */
22899 if (FRAME_RIF (f)->compute_glyph_string_overhangs)
22900 for (s = head; s; s = s->next)
22901 FRAME_RIF (f)->compute_glyph_string_overhangs (s);
22902
22903 /* Prepend glyph strings for glyphs in front of the first glyph
22904 string that are overwritten because of the first glyph
22905 string's left overhang. The background of all strings
22906 prepended must be drawn because the first glyph string
22907 draws over it. */
22908 i = left_overwritten (head);
22909 if (i >= 0)
22910 {
22911 enum draw_glyphs_face overlap_hl;
22912
22913 /* If this row contains mouse highlighting, attempt to draw
22914 the overlapped glyphs with the correct highlight. This
22915 code fails if the overlap encompasses more than one glyph
22916 and mouse-highlight spans only some of these glyphs.
22917 However, making it work perfectly involves a lot more
22918 code, and I don't know if the pathological case occurs in
22919 practice, so we'll stick to this for now. --- cyd */
22920 if (check_mouse_face
22921 && mouse_beg_col < start && mouse_end_col > i)
22922 overlap_hl = DRAW_MOUSE_FACE;
22923 else
22924 overlap_hl = DRAW_NORMAL_TEXT;
22925
22926 j = i;
22927 BUILD_GLYPH_STRINGS (j, start, h, t,
22928 overlap_hl, dummy_x, last_x);
22929 start = i;
22930 compute_overhangs_and_x (t, head->x, 1);
22931 prepend_glyph_string_lists (&head, &tail, h, t);
22932 clip_head = head;
22933 }
22934
22935 /* Prepend glyph strings for glyphs in front of the first glyph
22936 string that overwrite that glyph string because of their
22937 right overhang. For these strings, only the foreground must
22938 be drawn, because it draws over the glyph string at `head'.
22939 The background must not be drawn because this would overwrite
22940 right overhangs of preceding glyphs for which no glyph
22941 strings exist. */
22942 i = left_overwriting (head);
22943 if (i >= 0)
22944 {
22945 enum draw_glyphs_face overlap_hl;
22946
22947 if (check_mouse_face
22948 && mouse_beg_col < start && mouse_end_col > i)
22949 overlap_hl = DRAW_MOUSE_FACE;
22950 else
22951 overlap_hl = DRAW_NORMAL_TEXT;
22952
22953 clip_head = head;
22954 BUILD_GLYPH_STRINGS (i, start, h, t,
22955 overlap_hl, dummy_x, last_x);
22956 for (s = h; s; s = s->next)
22957 s->background_filled_p = 1;
22958 compute_overhangs_and_x (t, head->x, 1);
22959 prepend_glyph_string_lists (&head, &tail, h, t);
22960 }
22961
22962 /* Append glyphs strings for glyphs following the last glyph
22963 string tail that are overwritten by tail. The background of
22964 these strings has to be drawn because tail's foreground draws
22965 over it. */
22966 i = right_overwritten (tail);
22967 if (i >= 0)
22968 {
22969 enum draw_glyphs_face overlap_hl;
22970
22971 if (check_mouse_face
22972 && mouse_beg_col < i && mouse_end_col > end)
22973 overlap_hl = DRAW_MOUSE_FACE;
22974 else
22975 overlap_hl = DRAW_NORMAL_TEXT;
22976
22977 BUILD_GLYPH_STRINGS (end, i, h, t,
22978 overlap_hl, x, last_x);
22979 /* Because BUILD_GLYPH_STRINGS updates the first argument,
22980 we don't have `end = i;' here. */
22981 compute_overhangs_and_x (h, tail->x + tail->width, 0);
22982 append_glyph_string_lists (&head, &tail, h, t);
22983 clip_tail = tail;
22984 }
22985
22986 /* Append glyph strings for glyphs following the last glyph
22987 string tail that overwrite tail. The foreground of such
22988 glyphs has to be drawn because it writes into the background
22989 of tail. The background must not be drawn because it could
22990 paint over the foreground of following glyphs. */
22991 i = right_overwriting (tail);
22992 if (i >= 0)
22993 {
22994 enum draw_glyphs_face overlap_hl;
22995 if (check_mouse_face
22996 && mouse_beg_col < i && mouse_end_col > end)
22997 overlap_hl = DRAW_MOUSE_FACE;
22998 else
22999 overlap_hl = DRAW_NORMAL_TEXT;
23000
23001 clip_tail = tail;
23002 i++; /* We must include the Ith glyph. */
23003 BUILD_GLYPH_STRINGS (end, i, h, t,
23004 overlap_hl, x, last_x);
23005 for (s = h; s; s = s->next)
23006 s->background_filled_p = 1;
23007 compute_overhangs_and_x (h, tail->x + tail->width, 0);
23008 append_glyph_string_lists (&head, &tail, h, t);
23009 }
23010 if (clip_head || clip_tail)
23011 for (s = head; s; s = s->next)
23012 {
23013 s->clip_head = clip_head;
23014 s->clip_tail = clip_tail;
23015 }
23016 }
23017
23018 /* Draw all strings. */
23019 for (s = head; s; s = s->next)
23020 FRAME_RIF (f)->draw_glyph_string (s);
23021
23022 #ifndef HAVE_NS
23023 /* When focus a sole frame and move horizontally, this sets on_p to 0
23024 causing a failure to erase prev cursor position. */
23025 if (area == TEXT_AREA
23026 && !row->full_width_p
23027 /* When drawing overlapping rows, only the glyph strings'
23028 foreground is drawn, which doesn't erase a cursor
23029 completely. */
23030 && !overlaps)
23031 {
23032 int x0 = clip_head ? clip_head->x : (head ? head->x : x);
23033 int x1 = (clip_tail ? clip_tail->x + clip_tail->background_width
23034 : (tail ? tail->x + tail->background_width : x));
23035 x0 -= area_left;
23036 x1 -= area_left;
23037
23038 notice_overwritten_cursor (w, TEXT_AREA, x0, x1,
23039 row->y, MATRIX_ROW_BOTTOM_Y (row));
23040 }
23041 #endif
23042
23043 /* Value is the x-position up to which drawn, relative to AREA of W.
23044 This doesn't include parts drawn because of overhangs. */
23045 if (row->full_width_p)
23046 x_reached = FRAME_TO_WINDOW_PIXEL_X (w, x_reached);
23047 else
23048 x_reached -= area_left;
23049
23050 RELEASE_HDC (hdc, f);
23051
23052 return x_reached;
23053 }
23054
23055 /* Expand row matrix if too narrow. Don't expand if area
23056 is not present. */
23057
23058 #define IT_EXPAND_MATRIX_WIDTH(it, area) \
23059 { \
23060 if (!fonts_changed_p \
23061 && (it->glyph_row->glyphs[area] \
23062 < it->glyph_row->glyphs[area + 1])) \
23063 { \
23064 it->w->ncols_scale_factor++; \
23065 fonts_changed_p = 1; \
23066 } \
23067 }
23068
23069 /* Store one glyph for IT->char_to_display in IT->glyph_row.
23070 Called from x_produce_glyphs when IT->glyph_row is non-null. */
23071
23072 static inline void
23073 append_glyph (struct it *it)
23074 {
23075 struct glyph *glyph;
23076 enum glyph_row_area area = it->area;
23077
23078 xassert (it->glyph_row);
23079 xassert (it->char_to_display != '\n' && it->char_to_display != '\t');
23080
23081 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
23082 if (glyph < it->glyph_row->glyphs[area + 1])
23083 {
23084 /* If the glyph row is reversed, we need to prepend the glyph
23085 rather than append it. */
23086 if (it->glyph_row->reversed_p && area == TEXT_AREA)
23087 {
23088 struct glyph *g;
23089
23090 /* Make room for the additional glyph. */
23091 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
23092 g[1] = *g;
23093 glyph = it->glyph_row->glyphs[area];
23094 }
23095 glyph->charpos = CHARPOS (it->position);
23096 glyph->object = it->object;
23097 if (it->pixel_width > 0)
23098 {
23099 glyph->pixel_width = it->pixel_width;
23100 glyph->padding_p = 0;
23101 }
23102 else
23103 {
23104 /* Assure at least 1-pixel width. Otherwise, cursor can't
23105 be displayed correctly. */
23106 glyph->pixel_width = 1;
23107 glyph->padding_p = 1;
23108 }
23109 glyph->ascent = it->ascent;
23110 glyph->descent = it->descent;
23111 glyph->voffset = it->voffset;
23112 glyph->type = CHAR_GLYPH;
23113 glyph->avoid_cursor_p = it->avoid_cursor_p;
23114 glyph->multibyte_p = it->multibyte_p;
23115 glyph->left_box_line_p = it->start_of_box_run_p;
23116 glyph->right_box_line_p = it->end_of_box_run_p;
23117 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
23118 || it->phys_descent > it->descent);
23119 glyph->glyph_not_available_p = it->glyph_not_available_p;
23120 glyph->face_id = it->face_id;
23121 glyph->u.ch = it->char_to_display;
23122 glyph->slice.img = null_glyph_slice;
23123 glyph->font_type = FONT_TYPE_UNKNOWN;
23124 if (it->bidi_p)
23125 {
23126 glyph->resolved_level = it->bidi_it.resolved_level;
23127 if ((it->bidi_it.type & 7) != it->bidi_it.type)
23128 abort ();
23129 glyph->bidi_type = it->bidi_it.type;
23130 }
23131 else
23132 {
23133 glyph->resolved_level = 0;
23134 glyph->bidi_type = UNKNOWN_BT;
23135 }
23136 ++it->glyph_row->used[area];
23137 }
23138 else
23139 IT_EXPAND_MATRIX_WIDTH (it, area);
23140 }
23141
23142 /* Store one glyph for the composition IT->cmp_it.id in
23143 IT->glyph_row. Called from x_produce_glyphs when IT->glyph_row is
23144 non-null. */
23145
23146 static inline void
23147 append_composite_glyph (struct it *it)
23148 {
23149 struct glyph *glyph;
23150 enum glyph_row_area area = it->area;
23151
23152 xassert (it->glyph_row);
23153
23154 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
23155 if (glyph < it->glyph_row->glyphs[area + 1])
23156 {
23157 /* If the glyph row is reversed, we need to prepend the glyph
23158 rather than append it. */
23159 if (it->glyph_row->reversed_p && it->area == TEXT_AREA)
23160 {
23161 struct glyph *g;
23162
23163 /* Make room for the new glyph. */
23164 for (g = glyph - 1; g >= it->glyph_row->glyphs[it->area]; g--)
23165 g[1] = *g;
23166 glyph = it->glyph_row->glyphs[it->area];
23167 }
23168 glyph->charpos = it->cmp_it.charpos;
23169 glyph->object = it->object;
23170 glyph->pixel_width = it->pixel_width;
23171 glyph->ascent = it->ascent;
23172 glyph->descent = it->descent;
23173 glyph->voffset = it->voffset;
23174 glyph->type = COMPOSITE_GLYPH;
23175 if (it->cmp_it.ch < 0)
23176 {
23177 glyph->u.cmp.automatic = 0;
23178 glyph->u.cmp.id = it->cmp_it.id;
23179 glyph->slice.cmp.from = glyph->slice.cmp.to = 0;
23180 }
23181 else
23182 {
23183 glyph->u.cmp.automatic = 1;
23184 glyph->u.cmp.id = it->cmp_it.id;
23185 glyph->slice.cmp.from = it->cmp_it.from;
23186 glyph->slice.cmp.to = it->cmp_it.to - 1;
23187 }
23188 glyph->avoid_cursor_p = it->avoid_cursor_p;
23189 glyph->multibyte_p = it->multibyte_p;
23190 glyph->left_box_line_p = it->start_of_box_run_p;
23191 glyph->right_box_line_p = it->end_of_box_run_p;
23192 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
23193 || it->phys_descent > it->descent);
23194 glyph->padding_p = 0;
23195 glyph->glyph_not_available_p = 0;
23196 glyph->face_id = it->face_id;
23197 glyph->font_type = FONT_TYPE_UNKNOWN;
23198 if (it->bidi_p)
23199 {
23200 glyph->resolved_level = it->bidi_it.resolved_level;
23201 if ((it->bidi_it.type & 7) != it->bidi_it.type)
23202 abort ();
23203 glyph->bidi_type = it->bidi_it.type;
23204 }
23205 ++it->glyph_row->used[area];
23206 }
23207 else
23208 IT_EXPAND_MATRIX_WIDTH (it, area);
23209 }
23210
23211
23212 /* Change IT->ascent and IT->height according to the setting of
23213 IT->voffset. */
23214
23215 static inline void
23216 take_vertical_position_into_account (struct it *it)
23217 {
23218 if (it->voffset)
23219 {
23220 if (it->voffset < 0)
23221 /* Increase the ascent so that we can display the text higher
23222 in the line. */
23223 it->ascent -= it->voffset;
23224 else
23225 /* Increase the descent so that we can display the text lower
23226 in the line. */
23227 it->descent += it->voffset;
23228 }
23229 }
23230
23231
23232 /* Produce glyphs/get display metrics for the image IT is loaded with.
23233 See the description of struct display_iterator in dispextern.h for
23234 an overview of struct display_iterator. */
23235
23236 static void
23237 produce_image_glyph (struct it *it)
23238 {
23239 struct image *img;
23240 struct face *face;
23241 int glyph_ascent, crop;
23242 struct glyph_slice slice;
23243
23244 xassert (it->what == IT_IMAGE);
23245
23246 face = FACE_FROM_ID (it->f, it->face_id);
23247 xassert (face);
23248 /* Make sure X resources of the face is loaded. */
23249 PREPARE_FACE_FOR_DISPLAY (it->f, face);
23250
23251 if (it->image_id < 0)
23252 {
23253 /* Fringe bitmap. */
23254 it->ascent = it->phys_ascent = 0;
23255 it->descent = it->phys_descent = 0;
23256 it->pixel_width = 0;
23257 it->nglyphs = 0;
23258 return;
23259 }
23260
23261 img = IMAGE_FROM_ID (it->f, it->image_id);
23262 xassert (img);
23263 /* Make sure X resources of the image is loaded. */
23264 prepare_image_for_display (it->f, img);
23265
23266 slice.x = slice.y = 0;
23267 slice.width = img->width;
23268 slice.height = img->height;
23269
23270 if (INTEGERP (it->slice.x))
23271 slice.x = XINT (it->slice.x);
23272 else if (FLOATP (it->slice.x))
23273 slice.x = XFLOAT_DATA (it->slice.x) * img->width;
23274
23275 if (INTEGERP (it->slice.y))
23276 slice.y = XINT (it->slice.y);
23277 else if (FLOATP (it->slice.y))
23278 slice.y = XFLOAT_DATA (it->slice.y) * img->height;
23279
23280 if (INTEGERP (it->slice.width))
23281 slice.width = XINT (it->slice.width);
23282 else if (FLOATP (it->slice.width))
23283 slice.width = XFLOAT_DATA (it->slice.width) * img->width;
23284
23285 if (INTEGERP (it->slice.height))
23286 slice.height = XINT (it->slice.height);
23287 else if (FLOATP (it->slice.height))
23288 slice.height = XFLOAT_DATA (it->slice.height) * img->height;
23289
23290 if (slice.x >= img->width)
23291 slice.x = img->width;
23292 if (slice.y >= img->height)
23293 slice.y = img->height;
23294 if (slice.x + slice.width >= img->width)
23295 slice.width = img->width - slice.x;
23296 if (slice.y + slice.height > img->height)
23297 slice.height = img->height - slice.y;
23298
23299 if (slice.width == 0 || slice.height == 0)
23300 return;
23301
23302 it->ascent = it->phys_ascent = glyph_ascent = image_ascent (img, face, &slice);
23303
23304 it->descent = slice.height - glyph_ascent;
23305 if (slice.y == 0)
23306 it->descent += img->vmargin;
23307 if (slice.y + slice.height == img->height)
23308 it->descent += img->vmargin;
23309 it->phys_descent = it->descent;
23310
23311 it->pixel_width = slice.width;
23312 if (slice.x == 0)
23313 it->pixel_width += img->hmargin;
23314 if (slice.x + slice.width == img->width)
23315 it->pixel_width += img->hmargin;
23316
23317 /* It's quite possible for images to have an ascent greater than
23318 their height, so don't get confused in that case. */
23319 if (it->descent < 0)
23320 it->descent = 0;
23321
23322 it->nglyphs = 1;
23323
23324 if (face->box != FACE_NO_BOX)
23325 {
23326 if (face->box_line_width > 0)
23327 {
23328 if (slice.y == 0)
23329 it->ascent += face->box_line_width;
23330 if (slice.y + slice.height == img->height)
23331 it->descent += face->box_line_width;
23332 }
23333
23334 if (it->start_of_box_run_p && slice.x == 0)
23335 it->pixel_width += eabs (face->box_line_width);
23336 if (it->end_of_box_run_p && slice.x + slice.width == img->width)
23337 it->pixel_width += eabs (face->box_line_width);
23338 }
23339
23340 take_vertical_position_into_account (it);
23341
23342 /* Automatically crop wide image glyphs at right edge so we can
23343 draw the cursor on same display row. */
23344 if ((crop = it->pixel_width - (it->last_visible_x - it->current_x), crop > 0)
23345 && (it->hpos == 0 || it->pixel_width > it->last_visible_x / 4))
23346 {
23347 it->pixel_width -= crop;
23348 slice.width -= crop;
23349 }
23350
23351 if (it->glyph_row)
23352 {
23353 struct glyph *glyph;
23354 enum glyph_row_area area = it->area;
23355
23356 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
23357 if (glyph < it->glyph_row->glyphs[area + 1])
23358 {
23359 glyph->charpos = CHARPOS (it->position);
23360 glyph->object = it->object;
23361 glyph->pixel_width = it->pixel_width;
23362 glyph->ascent = glyph_ascent;
23363 glyph->descent = it->descent;
23364 glyph->voffset = it->voffset;
23365 glyph->type = IMAGE_GLYPH;
23366 glyph->avoid_cursor_p = it->avoid_cursor_p;
23367 glyph->multibyte_p = it->multibyte_p;
23368 glyph->left_box_line_p = it->start_of_box_run_p;
23369 glyph->right_box_line_p = it->end_of_box_run_p;
23370 glyph->overlaps_vertically_p = 0;
23371 glyph->padding_p = 0;
23372 glyph->glyph_not_available_p = 0;
23373 glyph->face_id = it->face_id;
23374 glyph->u.img_id = img->id;
23375 glyph->slice.img = slice;
23376 glyph->font_type = FONT_TYPE_UNKNOWN;
23377 if (it->bidi_p)
23378 {
23379 glyph->resolved_level = it->bidi_it.resolved_level;
23380 if ((it->bidi_it.type & 7) != it->bidi_it.type)
23381 abort ();
23382 glyph->bidi_type = it->bidi_it.type;
23383 }
23384 ++it->glyph_row->used[area];
23385 }
23386 else
23387 IT_EXPAND_MATRIX_WIDTH (it, area);
23388 }
23389 }
23390
23391
23392 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
23393 of the glyph, WIDTH and HEIGHT are the width and height of the
23394 stretch. ASCENT is the ascent of the glyph (0 <= ASCENT <= HEIGHT). */
23395
23396 static void
23397 append_stretch_glyph (struct it *it, Lisp_Object object,
23398 int width, int height, int ascent)
23399 {
23400 struct glyph *glyph;
23401 enum glyph_row_area area = it->area;
23402
23403 xassert (ascent >= 0 && ascent <= height);
23404
23405 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
23406 if (glyph < it->glyph_row->glyphs[area + 1])
23407 {
23408 /* If the glyph row is reversed, we need to prepend the glyph
23409 rather than append it. */
23410 if (it->glyph_row->reversed_p && area == TEXT_AREA)
23411 {
23412 struct glyph *g;
23413
23414 /* Make room for the additional glyph. */
23415 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
23416 g[1] = *g;
23417 glyph = it->glyph_row->glyphs[area];
23418 }
23419 glyph->charpos = CHARPOS (it->position);
23420 glyph->object = object;
23421 glyph->pixel_width = width;
23422 glyph->ascent = ascent;
23423 glyph->descent = height - ascent;
23424 glyph->voffset = it->voffset;
23425 glyph->type = STRETCH_GLYPH;
23426 glyph->avoid_cursor_p = it->avoid_cursor_p;
23427 glyph->multibyte_p = it->multibyte_p;
23428 glyph->left_box_line_p = it->start_of_box_run_p;
23429 glyph->right_box_line_p = it->end_of_box_run_p;
23430 glyph->overlaps_vertically_p = 0;
23431 glyph->padding_p = 0;
23432 glyph->glyph_not_available_p = 0;
23433 glyph->face_id = it->face_id;
23434 glyph->u.stretch.ascent = ascent;
23435 glyph->u.stretch.height = height;
23436 glyph->slice.img = null_glyph_slice;
23437 glyph->font_type = FONT_TYPE_UNKNOWN;
23438 if (it->bidi_p)
23439 {
23440 glyph->resolved_level = it->bidi_it.resolved_level;
23441 if ((it->bidi_it.type & 7) != it->bidi_it.type)
23442 abort ();
23443 glyph->bidi_type = it->bidi_it.type;
23444 }
23445 else
23446 {
23447 glyph->resolved_level = 0;
23448 glyph->bidi_type = UNKNOWN_BT;
23449 }
23450 ++it->glyph_row->used[area];
23451 }
23452 else
23453 IT_EXPAND_MATRIX_WIDTH (it, area);
23454 }
23455
23456 #endif /* HAVE_WINDOW_SYSTEM */
23457
23458 /* Produce a stretch glyph for iterator IT. IT->object is the value
23459 of the glyph property displayed. The value must be a list
23460 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
23461 being recognized:
23462
23463 1. `:width WIDTH' specifies that the space should be WIDTH *
23464 canonical char width wide. WIDTH may be an integer or floating
23465 point number.
23466
23467 2. `:relative-width FACTOR' specifies that the width of the stretch
23468 should be computed from the width of the first character having the
23469 `glyph' property, and should be FACTOR times that width.
23470
23471 3. `:align-to HPOS' specifies that the space should be wide enough
23472 to reach HPOS, a value in canonical character units.
23473
23474 Exactly one of the above pairs must be present.
23475
23476 4. `:height HEIGHT' specifies that the height of the stretch produced
23477 should be HEIGHT, measured in canonical character units.
23478
23479 5. `:relative-height FACTOR' specifies that the height of the
23480 stretch should be FACTOR times the height of the characters having
23481 the glyph property.
23482
23483 Either none or exactly one of 4 or 5 must be present.
23484
23485 6. `:ascent ASCENT' specifies that ASCENT percent of the height
23486 of the stretch should be used for the ascent of the stretch.
23487 ASCENT must be in the range 0 <= ASCENT <= 100. */
23488
23489 void
23490 produce_stretch_glyph (struct it *it)
23491 {
23492 /* (space :width WIDTH :height HEIGHT ...) */
23493 Lisp_Object prop, plist;
23494 int width = 0, height = 0, align_to = -1;
23495 int zero_width_ok_p = 0;
23496 int ascent = 0;
23497 double tem;
23498 struct face *face = NULL;
23499 struct font *font = NULL;
23500
23501 #ifdef HAVE_WINDOW_SYSTEM
23502 int zero_height_ok_p = 0;
23503
23504 if (FRAME_WINDOW_P (it->f))
23505 {
23506 face = FACE_FROM_ID (it->f, it->face_id);
23507 font = face->font ? face->font : FRAME_FONT (it->f);
23508 PREPARE_FACE_FOR_DISPLAY (it->f, face);
23509 }
23510 #endif
23511
23512 /* List should start with `space'. */
23513 xassert (CONSP (it->object) && EQ (XCAR (it->object), Qspace));
23514 plist = XCDR (it->object);
23515
23516 /* Compute the width of the stretch. */
23517 if ((prop = Fplist_get (plist, QCwidth), !NILP (prop))
23518 && calc_pixel_width_or_height (&tem, it, prop, font, 1, 0))
23519 {
23520 /* Absolute width `:width WIDTH' specified and valid. */
23521 zero_width_ok_p = 1;
23522 width = (int)tem;
23523 }
23524 #ifdef HAVE_WINDOW_SYSTEM
23525 else if (FRAME_WINDOW_P (it->f)
23526 && (prop = Fplist_get (plist, QCrelative_width), NUMVAL (prop) > 0))
23527 {
23528 /* Relative width `:relative-width FACTOR' specified and valid.
23529 Compute the width of the characters having the `glyph'
23530 property. */
23531 struct it it2;
23532 unsigned char *p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
23533
23534 it2 = *it;
23535 if (it->multibyte_p)
23536 it2.c = it2.char_to_display = STRING_CHAR_AND_LENGTH (p, it2.len);
23537 else
23538 {
23539 it2.c = it2.char_to_display = *p, it2.len = 1;
23540 if (! ASCII_CHAR_P (it2.c))
23541 it2.char_to_display = BYTE8_TO_CHAR (it2.c);
23542 }
23543
23544 it2.glyph_row = NULL;
23545 it2.what = IT_CHARACTER;
23546 x_produce_glyphs (&it2);
23547 width = NUMVAL (prop) * it2.pixel_width;
23548 }
23549 #endif /* HAVE_WINDOW_SYSTEM */
23550 else if ((prop = Fplist_get (plist, QCalign_to), !NILP (prop))
23551 && calc_pixel_width_or_height (&tem, it, prop, font, 1, &align_to))
23552 {
23553 if (it->glyph_row == NULL || !it->glyph_row->mode_line_p)
23554 align_to = (align_to < 0
23555 ? 0
23556 : align_to - window_box_left_offset (it->w, TEXT_AREA));
23557 else if (align_to < 0)
23558 align_to = window_box_left_offset (it->w, TEXT_AREA);
23559 width = max (0, (int)tem + align_to - it->current_x);
23560 zero_width_ok_p = 1;
23561 }
23562 else
23563 /* Nothing specified -> width defaults to canonical char width. */
23564 width = FRAME_COLUMN_WIDTH (it->f);
23565
23566 if (width <= 0 && (width < 0 || !zero_width_ok_p))
23567 width = 1;
23568
23569 #ifdef HAVE_WINDOW_SYSTEM
23570 /* Compute height. */
23571 if (FRAME_WINDOW_P (it->f))
23572 {
23573 if ((prop = Fplist_get (plist, QCheight), !NILP (prop))
23574 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
23575 {
23576 height = (int)tem;
23577 zero_height_ok_p = 1;
23578 }
23579 else if (prop = Fplist_get (plist, QCrelative_height),
23580 NUMVAL (prop) > 0)
23581 height = FONT_HEIGHT (font) * NUMVAL (prop);
23582 else
23583 height = FONT_HEIGHT (font);
23584
23585 if (height <= 0 && (height < 0 || !zero_height_ok_p))
23586 height = 1;
23587
23588 /* Compute percentage of height used for ascent. If
23589 `:ascent ASCENT' is present and valid, use that. Otherwise,
23590 derive the ascent from the font in use. */
23591 if (prop = Fplist_get (plist, QCascent),
23592 NUMVAL (prop) > 0 && NUMVAL (prop) <= 100)
23593 ascent = height * NUMVAL (prop) / 100.0;
23594 else if (!NILP (prop)
23595 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
23596 ascent = min (max (0, (int)tem), height);
23597 else
23598 ascent = (height * FONT_BASE (font)) / FONT_HEIGHT (font);
23599 }
23600 else
23601 #endif /* HAVE_WINDOW_SYSTEM */
23602 height = 1;
23603
23604 if (width > 0 && it->line_wrap != TRUNCATE
23605 && it->current_x + width > it->last_visible_x)
23606 {
23607 width = it->last_visible_x - it->current_x;
23608 #ifdef HAVE_WINDOW_SYSTEM
23609 /* Subtact one more pixel from the stretch width, but only on
23610 GUI frames, since on a TTY each glyph is one "pixel" wide. */
23611 width -= FRAME_WINDOW_P (it->f);
23612 #endif
23613 }
23614
23615 if (width > 0 && height > 0 && it->glyph_row)
23616 {
23617 Lisp_Object o_object = it->object;
23618 Lisp_Object object = it->stack[it->sp - 1].string;
23619 int n = width;
23620
23621 if (!STRINGP (object))
23622 object = it->w->buffer;
23623 #ifdef HAVE_WINDOW_SYSTEM
23624 if (FRAME_WINDOW_P (it->f))
23625 append_stretch_glyph (it, object, width, height, ascent);
23626 else
23627 #endif
23628 {
23629 it->object = object;
23630 it->char_to_display = ' ';
23631 it->pixel_width = it->len = 1;
23632 while (n--)
23633 tty_append_glyph (it);
23634 it->object = o_object;
23635 }
23636 }
23637
23638 it->pixel_width = width;
23639 #ifdef HAVE_WINDOW_SYSTEM
23640 if (FRAME_WINDOW_P (it->f))
23641 {
23642 it->ascent = it->phys_ascent = ascent;
23643 it->descent = it->phys_descent = height - it->ascent;
23644 it->nglyphs = width > 0 && height > 0 ? 1 : 0;
23645 take_vertical_position_into_account (it);
23646 }
23647 else
23648 #endif
23649 it->nglyphs = width;
23650 }
23651
23652 #ifdef HAVE_WINDOW_SYSTEM
23653
23654 /* Calculate line-height and line-spacing properties.
23655 An integer value specifies explicit pixel value.
23656 A float value specifies relative value to current face height.
23657 A cons (float . face-name) specifies relative value to
23658 height of specified face font.
23659
23660 Returns height in pixels, or nil. */
23661
23662
23663 static Lisp_Object
23664 calc_line_height_property (struct it *it, Lisp_Object val, struct font *font,
23665 int boff, int override)
23666 {
23667 Lisp_Object face_name = Qnil;
23668 int ascent, descent, height;
23669
23670 if (NILP (val) || INTEGERP (val) || (override && EQ (val, Qt)))
23671 return val;
23672
23673 if (CONSP (val))
23674 {
23675 face_name = XCAR (val);
23676 val = XCDR (val);
23677 if (!NUMBERP (val))
23678 val = make_number (1);
23679 if (NILP (face_name))
23680 {
23681 height = it->ascent + it->descent;
23682 goto scale;
23683 }
23684 }
23685
23686 if (NILP (face_name))
23687 {
23688 font = FRAME_FONT (it->f);
23689 boff = FRAME_BASELINE_OFFSET (it->f);
23690 }
23691 else if (EQ (face_name, Qt))
23692 {
23693 override = 0;
23694 }
23695 else
23696 {
23697 int face_id;
23698 struct face *face;
23699
23700 face_id = lookup_named_face (it->f, face_name, 0);
23701 if (face_id < 0)
23702 return make_number (-1);
23703
23704 face = FACE_FROM_ID (it->f, face_id);
23705 font = face->font;
23706 if (font == NULL)
23707 return make_number (-1);
23708 boff = font->baseline_offset;
23709 if (font->vertical_centering)
23710 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
23711 }
23712
23713 ascent = FONT_BASE (font) + boff;
23714 descent = FONT_DESCENT (font) - boff;
23715
23716 if (override)
23717 {
23718 it->override_ascent = ascent;
23719 it->override_descent = descent;
23720 it->override_boff = boff;
23721 }
23722
23723 height = ascent + descent;
23724
23725 scale:
23726 if (FLOATP (val))
23727 height = (int)(XFLOAT_DATA (val) * height);
23728 else if (INTEGERP (val))
23729 height *= XINT (val);
23730
23731 return make_number (height);
23732 }
23733
23734
23735 /* Append a glyph for a glyphless character to IT->glyph_row. FACE_ID
23736 is a face ID to be used for the glyph. FOR_NO_FONT is nonzero if
23737 and only if this is for a character for which no font was found.
23738
23739 If the display method (it->glyphless_method) is
23740 GLYPHLESS_DISPLAY_ACRONYM or GLYPHLESS_DISPLAY_HEX_CODE, LEN is a
23741 length of the acronym or the hexadecimal string, UPPER_XOFF and
23742 UPPER_YOFF are pixel offsets for the upper part of the string,
23743 LOWER_XOFF and LOWER_YOFF are for the lower part.
23744
23745 For the other display methods, LEN through LOWER_YOFF are zero. */
23746
23747 static void
23748 append_glyphless_glyph (struct it *it, int face_id, int for_no_font, int len,
23749 short upper_xoff, short upper_yoff,
23750 short lower_xoff, short lower_yoff)
23751 {
23752 struct glyph *glyph;
23753 enum glyph_row_area area = it->area;
23754
23755 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
23756 if (glyph < it->glyph_row->glyphs[area + 1])
23757 {
23758 /* If the glyph row is reversed, we need to prepend the glyph
23759 rather than append it. */
23760 if (it->glyph_row->reversed_p && area == TEXT_AREA)
23761 {
23762 struct glyph *g;
23763
23764 /* Make room for the additional glyph. */
23765 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
23766 g[1] = *g;
23767 glyph = it->glyph_row->glyphs[area];
23768 }
23769 glyph->charpos = CHARPOS (it->position);
23770 glyph->object = it->object;
23771 glyph->pixel_width = it->pixel_width;
23772 glyph->ascent = it->ascent;
23773 glyph->descent = it->descent;
23774 glyph->voffset = it->voffset;
23775 glyph->type = GLYPHLESS_GLYPH;
23776 glyph->u.glyphless.method = it->glyphless_method;
23777 glyph->u.glyphless.for_no_font = for_no_font;
23778 glyph->u.glyphless.len = len;
23779 glyph->u.glyphless.ch = it->c;
23780 glyph->slice.glyphless.upper_xoff = upper_xoff;
23781 glyph->slice.glyphless.upper_yoff = upper_yoff;
23782 glyph->slice.glyphless.lower_xoff = lower_xoff;
23783 glyph->slice.glyphless.lower_yoff = lower_yoff;
23784 glyph->avoid_cursor_p = it->avoid_cursor_p;
23785 glyph->multibyte_p = it->multibyte_p;
23786 glyph->left_box_line_p = it->start_of_box_run_p;
23787 glyph->right_box_line_p = it->end_of_box_run_p;
23788 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
23789 || it->phys_descent > it->descent);
23790 glyph->padding_p = 0;
23791 glyph->glyph_not_available_p = 0;
23792 glyph->face_id = face_id;
23793 glyph->font_type = FONT_TYPE_UNKNOWN;
23794 if (it->bidi_p)
23795 {
23796 glyph->resolved_level = it->bidi_it.resolved_level;
23797 if ((it->bidi_it.type & 7) != it->bidi_it.type)
23798 abort ();
23799 glyph->bidi_type = it->bidi_it.type;
23800 }
23801 ++it->glyph_row->used[area];
23802 }
23803 else
23804 IT_EXPAND_MATRIX_WIDTH (it, area);
23805 }
23806
23807
23808 /* Produce a glyph for a glyphless character for iterator IT.
23809 IT->glyphless_method specifies which method to use for displaying
23810 the character. See the description of enum
23811 glyphless_display_method in dispextern.h for the detail.
23812
23813 FOR_NO_FONT is nonzero if and only if this is for a character for
23814 which no font was found. ACRONYM, if non-nil, is an acronym string
23815 for the character. */
23816
23817 static void
23818 produce_glyphless_glyph (struct it *it, int for_no_font, Lisp_Object acronym)
23819 {
23820 int face_id;
23821 struct face *face;
23822 struct font *font;
23823 int base_width, base_height, width, height;
23824 short upper_xoff, upper_yoff, lower_xoff, lower_yoff;
23825 int len;
23826
23827 /* Get the metrics of the base font. We always refer to the current
23828 ASCII face. */
23829 face = FACE_FROM_ID (it->f, it->face_id)->ascii_face;
23830 font = face->font ? face->font : FRAME_FONT (it->f);
23831 it->ascent = FONT_BASE (font) + font->baseline_offset;
23832 it->descent = FONT_DESCENT (font) - font->baseline_offset;
23833 base_height = it->ascent + it->descent;
23834 base_width = font->average_width;
23835
23836 /* Get a face ID for the glyph by utilizing a cache (the same way as
23837 done for `escape-glyph' in get_next_display_element). */
23838 if (it->f == last_glyphless_glyph_frame
23839 && it->face_id == last_glyphless_glyph_face_id)
23840 {
23841 face_id = last_glyphless_glyph_merged_face_id;
23842 }
23843 else
23844 {
23845 /* Merge the `glyphless-char' face into the current face. */
23846 face_id = merge_faces (it->f, Qglyphless_char, 0, it->face_id);
23847 last_glyphless_glyph_frame = it->f;
23848 last_glyphless_glyph_face_id = it->face_id;
23849 last_glyphless_glyph_merged_face_id = face_id;
23850 }
23851
23852 if (it->glyphless_method == GLYPHLESS_DISPLAY_THIN_SPACE)
23853 {
23854 it->pixel_width = THIN_SPACE_WIDTH;
23855 len = 0;
23856 upper_xoff = upper_yoff = lower_xoff = lower_yoff = 0;
23857 }
23858 else if (it->glyphless_method == GLYPHLESS_DISPLAY_EMPTY_BOX)
23859 {
23860 width = CHAR_WIDTH (it->c);
23861 if (width == 0)
23862 width = 1;
23863 else if (width > 4)
23864 width = 4;
23865 it->pixel_width = base_width * width;
23866 len = 0;
23867 upper_xoff = upper_yoff = lower_xoff = lower_yoff = 0;
23868 }
23869 else
23870 {
23871 char buf[7];
23872 const char *str;
23873 unsigned int code[6];
23874 int upper_len;
23875 int ascent, descent;
23876 struct font_metrics metrics_upper, metrics_lower;
23877
23878 face = FACE_FROM_ID (it->f, face_id);
23879 font = face->font ? face->font : FRAME_FONT (it->f);
23880 PREPARE_FACE_FOR_DISPLAY (it->f, face);
23881
23882 if (it->glyphless_method == GLYPHLESS_DISPLAY_ACRONYM)
23883 {
23884 if (! STRINGP (acronym) && CHAR_TABLE_P (Vglyphless_char_display))
23885 acronym = CHAR_TABLE_REF (Vglyphless_char_display, it->c);
23886 if (CONSP (acronym))
23887 acronym = XCAR (acronym);
23888 str = STRINGP (acronym) ? SSDATA (acronym) : "";
23889 }
23890 else
23891 {
23892 xassert (it->glyphless_method == GLYPHLESS_DISPLAY_HEX_CODE);
23893 sprintf (buf, "%0*X", it->c < 0x10000 ? 4 : 6, it->c);
23894 str = buf;
23895 }
23896 for (len = 0; str[len] && ASCII_BYTE_P (str[len]); len++)
23897 code[len] = font->driver->encode_char (font, str[len]);
23898 upper_len = (len + 1) / 2;
23899 font->driver->text_extents (font, code, upper_len,
23900 &metrics_upper);
23901 font->driver->text_extents (font, code + upper_len, len - upper_len,
23902 &metrics_lower);
23903
23904
23905
23906 /* +4 is for vertical bars of a box plus 1-pixel spaces at both side. */
23907 width = max (metrics_upper.width, metrics_lower.width) + 4;
23908 upper_xoff = upper_yoff = 2; /* the typical case */
23909 if (base_width >= width)
23910 {
23911 /* Align the upper to the left, the lower to the right. */
23912 it->pixel_width = base_width;
23913 lower_xoff = base_width - 2 - metrics_lower.width;
23914 }
23915 else
23916 {
23917 /* Center the shorter one. */
23918 it->pixel_width = width;
23919 if (metrics_upper.width >= metrics_lower.width)
23920 lower_xoff = (width - metrics_lower.width) / 2;
23921 else
23922 {
23923 /* FIXME: This code doesn't look right. It formerly was
23924 missing the "lower_xoff = 0;", which couldn't have
23925 been right since it left lower_xoff uninitialized. */
23926 lower_xoff = 0;
23927 upper_xoff = (width - metrics_upper.width) / 2;
23928 }
23929 }
23930
23931 /* +5 is for horizontal bars of a box plus 1-pixel spaces at
23932 top, bottom, and between upper and lower strings. */
23933 height = (metrics_upper.ascent + metrics_upper.descent
23934 + metrics_lower.ascent + metrics_lower.descent) + 5;
23935 /* Center vertically.
23936 H:base_height, D:base_descent
23937 h:height, ld:lower_descent, la:lower_ascent, ud:upper_descent
23938
23939 ascent = - (D - H/2 - h/2 + 1); "+ 1" for rounding up
23940 descent = D - H/2 + h/2;
23941 lower_yoff = descent - 2 - ld;
23942 upper_yoff = lower_yoff - la - 1 - ud; */
23943 ascent = - (it->descent - (base_height + height + 1) / 2);
23944 descent = it->descent - (base_height - height) / 2;
23945 lower_yoff = descent - 2 - metrics_lower.descent;
23946 upper_yoff = (lower_yoff - metrics_lower.ascent - 1
23947 - metrics_upper.descent);
23948 /* Don't make the height shorter than the base height. */
23949 if (height > base_height)
23950 {
23951 it->ascent = ascent;
23952 it->descent = descent;
23953 }
23954 }
23955
23956 it->phys_ascent = it->ascent;
23957 it->phys_descent = it->descent;
23958 if (it->glyph_row)
23959 append_glyphless_glyph (it, face_id, for_no_font, len,
23960 upper_xoff, upper_yoff,
23961 lower_xoff, lower_yoff);
23962 it->nglyphs = 1;
23963 take_vertical_position_into_account (it);
23964 }
23965
23966
23967 /* RIF:
23968 Produce glyphs/get display metrics for the display element IT is
23969 loaded with. See the description of struct it in dispextern.h
23970 for an overview of struct it. */
23971
23972 void
23973 x_produce_glyphs (struct it *it)
23974 {
23975 int extra_line_spacing = it->extra_line_spacing;
23976
23977 it->glyph_not_available_p = 0;
23978
23979 if (it->what == IT_CHARACTER)
23980 {
23981 XChar2b char2b;
23982 struct face *face = FACE_FROM_ID (it->f, it->face_id);
23983 struct font *font = face->font;
23984 struct font_metrics *pcm = NULL;
23985 int boff; /* baseline offset */
23986
23987 if (font == NULL)
23988 {
23989 /* When no suitable font is found, display this character by
23990 the method specified in the first extra slot of
23991 Vglyphless_char_display. */
23992 Lisp_Object acronym = lookup_glyphless_char_display (-1, it);
23993
23994 xassert (it->what == IT_GLYPHLESS);
23995 produce_glyphless_glyph (it, 1, STRINGP (acronym) ? acronym : Qnil);
23996 goto done;
23997 }
23998
23999 boff = font->baseline_offset;
24000 if (font->vertical_centering)
24001 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
24002
24003 if (it->char_to_display != '\n' && it->char_to_display != '\t')
24004 {
24005 int stretched_p;
24006
24007 it->nglyphs = 1;
24008
24009 if (it->override_ascent >= 0)
24010 {
24011 it->ascent = it->override_ascent;
24012 it->descent = it->override_descent;
24013 boff = it->override_boff;
24014 }
24015 else
24016 {
24017 it->ascent = FONT_BASE (font) + boff;
24018 it->descent = FONT_DESCENT (font) - boff;
24019 }
24020
24021 if (get_char_glyph_code (it->char_to_display, font, &char2b))
24022 {
24023 pcm = get_per_char_metric (font, &char2b);
24024 if (pcm->width == 0
24025 && pcm->rbearing == 0 && pcm->lbearing == 0)
24026 pcm = NULL;
24027 }
24028
24029 if (pcm)
24030 {
24031 it->phys_ascent = pcm->ascent + boff;
24032 it->phys_descent = pcm->descent - boff;
24033 it->pixel_width = pcm->width;
24034 }
24035 else
24036 {
24037 it->glyph_not_available_p = 1;
24038 it->phys_ascent = it->ascent;
24039 it->phys_descent = it->descent;
24040 it->pixel_width = font->space_width;
24041 }
24042
24043 if (it->constrain_row_ascent_descent_p)
24044 {
24045 if (it->descent > it->max_descent)
24046 {
24047 it->ascent += it->descent - it->max_descent;
24048 it->descent = it->max_descent;
24049 }
24050 if (it->ascent > it->max_ascent)
24051 {
24052 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
24053 it->ascent = it->max_ascent;
24054 }
24055 it->phys_ascent = min (it->phys_ascent, it->ascent);
24056 it->phys_descent = min (it->phys_descent, it->descent);
24057 extra_line_spacing = 0;
24058 }
24059
24060 /* If this is a space inside a region of text with
24061 `space-width' property, change its width. */
24062 stretched_p = it->char_to_display == ' ' && !NILP (it->space_width);
24063 if (stretched_p)
24064 it->pixel_width *= XFLOATINT (it->space_width);
24065
24066 /* If face has a box, add the box thickness to the character
24067 height. If character has a box line to the left and/or
24068 right, add the box line width to the character's width. */
24069 if (face->box != FACE_NO_BOX)
24070 {
24071 int thick = face->box_line_width;
24072
24073 if (thick > 0)
24074 {
24075 it->ascent += thick;
24076 it->descent += thick;
24077 }
24078 else
24079 thick = -thick;
24080
24081 if (it->start_of_box_run_p)
24082 it->pixel_width += thick;
24083 if (it->end_of_box_run_p)
24084 it->pixel_width += thick;
24085 }
24086
24087 /* If face has an overline, add the height of the overline
24088 (1 pixel) and a 1 pixel margin to the character height. */
24089 if (face->overline_p)
24090 it->ascent += overline_margin;
24091
24092 if (it->constrain_row_ascent_descent_p)
24093 {
24094 if (it->ascent > it->max_ascent)
24095 it->ascent = it->max_ascent;
24096 if (it->descent > it->max_descent)
24097 it->descent = it->max_descent;
24098 }
24099
24100 take_vertical_position_into_account (it);
24101
24102 /* If we have to actually produce glyphs, do it. */
24103 if (it->glyph_row)
24104 {
24105 if (stretched_p)
24106 {
24107 /* Translate a space with a `space-width' property
24108 into a stretch glyph. */
24109 int ascent = (((it->ascent + it->descent) * FONT_BASE (font))
24110 / FONT_HEIGHT (font));
24111 append_stretch_glyph (it, it->object, it->pixel_width,
24112 it->ascent + it->descent, ascent);
24113 }
24114 else
24115 append_glyph (it);
24116
24117 /* If characters with lbearing or rbearing are displayed
24118 in this line, record that fact in a flag of the
24119 glyph row. This is used to optimize X output code. */
24120 if (pcm && (pcm->lbearing < 0 || pcm->rbearing > pcm->width))
24121 it->glyph_row->contains_overlapping_glyphs_p = 1;
24122 }
24123 if (! stretched_p && it->pixel_width == 0)
24124 /* We assure that all visible glyphs have at least 1-pixel
24125 width. */
24126 it->pixel_width = 1;
24127 }
24128 else if (it->char_to_display == '\n')
24129 {
24130 /* A newline has no width, but we need the height of the
24131 line. But if previous part of the line sets a height,
24132 don't increase that height */
24133
24134 Lisp_Object height;
24135 Lisp_Object total_height = Qnil;
24136
24137 it->override_ascent = -1;
24138 it->pixel_width = 0;
24139 it->nglyphs = 0;
24140
24141 height = get_it_property (it, Qline_height);
24142 /* Split (line-height total-height) list */
24143 if (CONSP (height)
24144 && CONSP (XCDR (height))
24145 && NILP (XCDR (XCDR (height))))
24146 {
24147 total_height = XCAR (XCDR (height));
24148 height = XCAR (height);
24149 }
24150 height = calc_line_height_property (it, height, font, boff, 1);
24151
24152 if (it->override_ascent >= 0)
24153 {
24154 it->ascent = it->override_ascent;
24155 it->descent = it->override_descent;
24156 boff = it->override_boff;
24157 }
24158 else
24159 {
24160 it->ascent = FONT_BASE (font) + boff;
24161 it->descent = FONT_DESCENT (font) - boff;
24162 }
24163
24164 if (EQ (height, Qt))
24165 {
24166 if (it->descent > it->max_descent)
24167 {
24168 it->ascent += it->descent - it->max_descent;
24169 it->descent = it->max_descent;
24170 }
24171 if (it->ascent > it->max_ascent)
24172 {
24173 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
24174 it->ascent = it->max_ascent;
24175 }
24176 it->phys_ascent = min (it->phys_ascent, it->ascent);
24177 it->phys_descent = min (it->phys_descent, it->descent);
24178 it->constrain_row_ascent_descent_p = 1;
24179 extra_line_spacing = 0;
24180 }
24181 else
24182 {
24183 Lisp_Object spacing;
24184
24185 it->phys_ascent = it->ascent;
24186 it->phys_descent = it->descent;
24187
24188 if ((it->max_ascent > 0 || it->max_descent > 0)
24189 && face->box != FACE_NO_BOX
24190 && face->box_line_width > 0)
24191 {
24192 it->ascent += face->box_line_width;
24193 it->descent += face->box_line_width;
24194 }
24195 if (!NILP (height)
24196 && XINT (height) > it->ascent + it->descent)
24197 it->ascent = XINT (height) - it->descent;
24198
24199 if (!NILP (total_height))
24200 spacing = calc_line_height_property (it, total_height, font, boff, 0);
24201 else
24202 {
24203 spacing = get_it_property (it, Qline_spacing);
24204 spacing = calc_line_height_property (it, spacing, font, boff, 0);
24205 }
24206 if (INTEGERP (spacing))
24207 {
24208 extra_line_spacing = XINT (spacing);
24209 if (!NILP (total_height))
24210 extra_line_spacing -= (it->phys_ascent + it->phys_descent);
24211 }
24212 }
24213 }
24214 else /* i.e. (it->char_to_display == '\t') */
24215 {
24216 if (font->space_width > 0)
24217 {
24218 int tab_width = it->tab_width * font->space_width;
24219 int x = it->current_x + it->continuation_lines_width;
24220 int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width;
24221
24222 /* If the distance from the current position to the next tab
24223 stop is less than a space character width, use the
24224 tab stop after that. */
24225 if (next_tab_x - x < font->space_width)
24226 next_tab_x += tab_width;
24227
24228 it->pixel_width = next_tab_x - x;
24229 it->nglyphs = 1;
24230 it->ascent = it->phys_ascent = FONT_BASE (font) + boff;
24231 it->descent = it->phys_descent = FONT_DESCENT (font) - boff;
24232
24233 if (it->glyph_row)
24234 {
24235 append_stretch_glyph (it, it->object, it->pixel_width,
24236 it->ascent + it->descent, it->ascent);
24237 }
24238 }
24239 else
24240 {
24241 it->pixel_width = 0;
24242 it->nglyphs = 1;
24243 }
24244 }
24245 }
24246 else if (it->what == IT_COMPOSITION && it->cmp_it.ch < 0)
24247 {
24248 /* A static composition.
24249
24250 Note: A composition is represented as one glyph in the
24251 glyph matrix. There are no padding glyphs.
24252
24253 Important note: pixel_width, ascent, and descent are the
24254 values of what is drawn by draw_glyphs (i.e. the values of
24255 the overall glyphs composed). */
24256 struct face *face = FACE_FROM_ID (it->f, it->face_id);
24257 int boff; /* baseline offset */
24258 struct composition *cmp = composition_table[it->cmp_it.id];
24259 int glyph_len = cmp->glyph_len;
24260 struct font *font = face->font;
24261
24262 it->nglyphs = 1;
24263
24264 /* If we have not yet calculated pixel size data of glyphs of
24265 the composition for the current face font, calculate them
24266 now. Theoretically, we have to check all fonts for the
24267 glyphs, but that requires much time and memory space. So,
24268 here we check only the font of the first glyph. This may
24269 lead to incorrect display, but it's very rare, and C-l
24270 (recenter-top-bottom) can correct the display anyway. */
24271 if (! cmp->font || cmp->font != font)
24272 {
24273 /* Ascent and descent of the font of the first character
24274 of this composition (adjusted by baseline offset).
24275 Ascent and descent of overall glyphs should not be less
24276 than these, respectively. */
24277 int font_ascent, font_descent, font_height;
24278 /* Bounding box of the overall glyphs. */
24279 int leftmost, rightmost, lowest, highest;
24280 int lbearing, rbearing;
24281 int i, width, ascent, descent;
24282 int left_padded = 0, right_padded = 0;
24283 int c IF_LINT (= 0); /* cmp->glyph_len can't be zero; see Bug#8512 */
24284 XChar2b char2b;
24285 struct font_metrics *pcm;
24286 int font_not_found_p;
24287 EMACS_INT pos;
24288
24289 for (glyph_len = cmp->glyph_len; glyph_len > 0; glyph_len--)
24290 if ((c = COMPOSITION_GLYPH (cmp, glyph_len - 1)) != '\t')
24291 break;
24292 if (glyph_len < cmp->glyph_len)
24293 right_padded = 1;
24294 for (i = 0; i < glyph_len; i++)
24295 {
24296 if ((c = COMPOSITION_GLYPH (cmp, i)) != '\t')
24297 break;
24298 cmp->offsets[i * 2] = cmp->offsets[i * 2 + 1] = 0;
24299 }
24300 if (i > 0)
24301 left_padded = 1;
24302
24303 pos = (STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
24304 : IT_CHARPOS (*it));
24305 /* If no suitable font is found, use the default font. */
24306 font_not_found_p = font == NULL;
24307 if (font_not_found_p)
24308 {
24309 face = face->ascii_face;
24310 font = face->font;
24311 }
24312 boff = font->baseline_offset;
24313 if (font->vertical_centering)
24314 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
24315 font_ascent = FONT_BASE (font) + boff;
24316 font_descent = FONT_DESCENT (font) - boff;
24317 font_height = FONT_HEIGHT (font);
24318
24319 cmp->font = (void *) font;
24320
24321 pcm = NULL;
24322 if (! font_not_found_p)
24323 {
24324 get_char_face_and_encoding (it->f, c, it->face_id,
24325 &char2b, 0);
24326 pcm = get_per_char_metric (font, &char2b);
24327 }
24328
24329 /* Initialize the bounding box. */
24330 if (pcm)
24331 {
24332 width = pcm->width;
24333 ascent = pcm->ascent;
24334 descent = pcm->descent;
24335 lbearing = pcm->lbearing;
24336 rbearing = pcm->rbearing;
24337 }
24338 else
24339 {
24340 width = font->space_width;
24341 ascent = FONT_BASE (font);
24342 descent = FONT_DESCENT (font);
24343 lbearing = 0;
24344 rbearing = width;
24345 }
24346
24347 rightmost = width;
24348 leftmost = 0;
24349 lowest = - descent + boff;
24350 highest = ascent + boff;
24351
24352 if (! font_not_found_p
24353 && font->default_ascent
24354 && CHAR_TABLE_P (Vuse_default_ascent)
24355 && !NILP (Faref (Vuse_default_ascent,
24356 make_number (it->char_to_display))))
24357 highest = font->default_ascent + boff;
24358
24359 /* Draw the first glyph at the normal position. It may be
24360 shifted to right later if some other glyphs are drawn
24361 at the left. */
24362 cmp->offsets[i * 2] = 0;
24363 cmp->offsets[i * 2 + 1] = boff;
24364 cmp->lbearing = lbearing;
24365 cmp->rbearing = rbearing;
24366
24367 /* Set cmp->offsets for the remaining glyphs. */
24368 for (i++; i < glyph_len; i++)
24369 {
24370 int left, right, btm, top;
24371 int ch = COMPOSITION_GLYPH (cmp, i);
24372 int face_id;
24373 struct face *this_face;
24374
24375 if (ch == '\t')
24376 ch = ' ';
24377 face_id = FACE_FOR_CHAR (it->f, face, ch, pos, it->string);
24378 this_face = FACE_FROM_ID (it->f, face_id);
24379 font = this_face->font;
24380
24381 if (font == NULL)
24382 pcm = NULL;
24383 else
24384 {
24385 get_char_face_and_encoding (it->f, ch, face_id,
24386 &char2b, 0);
24387 pcm = get_per_char_metric (font, &char2b);
24388 }
24389 if (! pcm)
24390 cmp->offsets[i * 2] = cmp->offsets[i * 2 + 1] = 0;
24391 else
24392 {
24393 width = pcm->width;
24394 ascent = pcm->ascent;
24395 descent = pcm->descent;
24396 lbearing = pcm->lbearing;
24397 rbearing = pcm->rbearing;
24398 if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS)
24399 {
24400 /* Relative composition with or without
24401 alternate chars. */
24402 left = (leftmost + rightmost - width) / 2;
24403 btm = - descent + boff;
24404 if (font->relative_compose
24405 && (! CHAR_TABLE_P (Vignore_relative_composition)
24406 || NILP (Faref (Vignore_relative_composition,
24407 make_number (ch)))))
24408 {
24409
24410 if (- descent >= font->relative_compose)
24411 /* One extra pixel between two glyphs. */
24412 btm = highest + 1;
24413 else if (ascent <= 0)
24414 /* One extra pixel between two glyphs. */
24415 btm = lowest - 1 - ascent - descent;
24416 }
24417 }
24418 else
24419 {
24420 /* A composition rule is specified by an integer
24421 value that encodes global and new reference
24422 points (GREF and NREF). GREF and NREF are
24423 specified by numbers as below:
24424
24425 0---1---2 -- ascent
24426 | |
24427 | |
24428 | |
24429 9--10--11 -- center
24430 | |
24431 ---3---4---5--- baseline
24432 | |
24433 6---7---8 -- descent
24434 */
24435 int rule = COMPOSITION_RULE (cmp, i);
24436 int gref, nref, grefx, grefy, nrefx, nrefy, xoff, yoff;
24437
24438 COMPOSITION_DECODE_RULE (rule, gref, nref, xoff, yoff);
24439 grefx = gref % 3, nrefx = nref % 3;
24440 grefy = gref / 3, nrefy = nref / 3;
24441 if (xoff)
24442 xoff = font_height * (xoff - 128) / 256;
24443 if (yoff)
24444 yoff = font_height * (yoff - 128) / 256;
24445
24446 left = (leftmost
24447 + grefx * (rightmost - leftmost) / 2
24448 - nrefx * width / 2
24449 + xoff);
24450
24451 btm = ((grefy == 0 ? highest
24452 : grefy == 1 ? 0
24453 : grefy == 2 ? lowest
24454 : (highest + lowest) / 2)
24455 - (nrefy == 0 ? ascent + descent
24456 : nrefy == 1 ? descent - boff
24457 : nrefy == 2 ? 0
24458 : (ascent + descent) / 2)
24459 + yoff);
24460 }
24461
24462 cmp->offsets[i * 2] = left;
24463 cmp->offsets[i * 2 + 1] = btm + descent;
24464
24465 /* Update the bounding box of the overall glyphs. */
24466 if (width > 0)
24467 {
24468 right = left + width;
24469 if (left < leftmost)
24470 leftmost = left;
24471 if (right > rightmost)
24472 rightmost = right;
24473 }
24474 top = btm + descent + ascent;
24475 if (top > highest)
24476 highest = top;
24477 if (btm < lowest)
24478 lowest = btm;
24479
24480 if (cmp->lbearing > left + lbearing)
24481 cmp->lbearing = left + lbearing;
24482 if (cmp->rbearing < left + rbearing)
24483 cmp->rbearing = left + rbearing;
24484 }
24485 }
24486
24487 /* If there are glyphs whose x-offsets are negative,
24488 shift all glyphs to the right and make all x-offsets
24489 non-negative. */
24490 if (leftmost < 0)
24491 {
24492 for (i = 0; i < cmp->glyph_len; i++)
24493 cmp->offsets[i * 2] -= leftmost;
24494 rightmost -= leftmost;
24495 cmp->lbearing -= leftmost;
24496 cmp->rbearing -= leftmost;
24497 }
24498
24499 if (left_padded && cmp->lbearing < 0)
24500 {
24501 for (i = 0; i < cmp->glyph_len; i++)
24502 cmp->offsets[i * 2] -= cmp->lbearing;
24503 rightmost -= cmp->lbearing;
24504 cmp->rbearing -= cmp->lbearing;
24505 cmp->lbearing = 0;
24506 }
24507 if (right_padded && rightmost < cmp->rbearing)
24508 {
24509 rightmost = cmp->rbearing;
24510 }
24511
24512 cmp->pixel_width = rightmost;
24513 cmp->ascent = highest;
24514 cmp->descent = - lowest;
24515 if (cmp->ascent < font_ascent)
24516 cmp->ascent = font_ascent;
24517 if (cmp->descent < font_descent)
24518 cmp->descent = font_descent;
24519 }
24520
24521 if (it->glyph_row
24522 && (cmp->lbearing < 0
24523 || cmp->rbearing > cmp->pixel_width))
24524 it->glyph_row->contains_overlapping_glyphs_p = 1;
24525
24526 it->pixel_width = cmp->pixel_width;
24527 it->ascent = it->phys_ascent = cmp->ascent;
24528 it->descent = it->phys_descent = cmp->descent;
24529 if (face->box != FACE_NO_BOX)
24530 {
24531 int thick = face->box_line_width;
24532
24533 if (thick > 0)
24534 {
24535 it->ascent += thick;
24536 it->descent += thick;
24537 }
24538 else
24539 thick = - thick;
24540
24541 if (it->start_of_box_run_p)
24542 it->pixel_width += thick;
24543 if (it->end_of_box_run_p)
24544 it->pixel_width += thick;
24545 }
24546
24547 /* If face has an overline, add the height of the overline
24548 (1 pixel) and a 1 pixel margin to the character height. */
24549 if (face->overline_p)
24550 it->ascent += overline_margin;
24551
24552 take_vertical_position_into_account (it);
24553 if (it->ascent < 0)
24554 it->ascent = 0;
24555 if (it->descent < 0)
24556 it->descent = 0;
24557
24558 if (it->glyph_row)
24559 append_composite_glyph (it);
24560 }
24561 else if (it->what == IT_COMPOSITION)
24562 {
24563 /* A dynamic (automatic) composition. */
24564 struct face *face = FACE_FROM_ID (it->f, it->face_id);
24565 Lisp_Object gstring;
24566 struct font_metrics metrics;
24567
24568 it->nglyphs = 1;
24569
24570 gstring = composition_gstring_from_id (it->cmp_it.id);
24571 it->pixel_width
24572 = composition_gstring_width (gstring, it->cmp_it.from, it->cmp_it.to,
24573 &metrics);
24574 if (it->glyph_row
24575 && (metrics.lbearing < 0 || metrics.rbearing > metrics.width))
24576 it->glyph_row->contains_overlapping_glyphs_p = 1;
24577 it->ascent = it->phys_ascent = metrics.ascent;
24578 it->descent = it->phys_descent = metrics.descent;
24579 if (face->box != FACE_NO_BOX)
24580 {
24581 int thick = face->box_line_width;
24582
24583 if (thick > 0)
24584 {
24585 it->ascent += thick;
24586 it->descent += thick;
24587 }
24588 else
24589 thick = - thick;
24590
24591 if (it->start_of_box_run_p)
24592 it->pixel_width += thick;
24593 if (it->end_of_box_run_p)
24594 it->pixel_width += thick;
24595 }
24596 /* If face has an overline, add the height of the overline
24597 (1 pixel) and a 1 pixel margin to the character height. */
24598 if (face->overline_p)
24599 it->ascent += overline_margin;
24600 take_vertical_position_into_account (it);
24601 if (it->ascent < 0)
24602 it->ascent = 0;
24603 if (it->descent < 0)
24604 it->descent = 0;
24605
24606 if (it->glyph_row)
24607 append_composite_glyph (it);
24608 }
24609 else if (it->what == IT_GLYPHLESS)
24610 produce_glyphless_glyph (it, 0, Qnil);
24611 else if (it->what == IT_IMAGE)
24612 produce_image_glyph (it);
24613 else if (it->what == IT_STRETCH)
24614 produce_stretch_glyph (it);
24615
24616 done:
24617 /* Accumulate dimensions. Note: can't assume that it->descent > 0
24618 because this isn't true for images with `:ascent 100'. */
24619 xassert (it->ascent >= 0 && it->descent >= 0);
24620 if (it->area == TEXT_AREA)
24621 it->current_x += it->pixel_width;
24622
24623 if (extra_line_spacing > 0)
24624 {
24625 it->descent += extra_line_spacing;
24626 if (extra_line_spacing > it->max_extra_line_spacing)
24627 it->max_extra_line_spacing = extra_line_spacing;
24628 }
24629
24630 it->max_ascent = max (it->max_ascent, it->ascent);
24631 it->max_descent = max (it->max_descent, it->descent);
24632 it->max_phys_ascent = max (it->max_phys_ascent, it->phys_ascent);
24633 it->max_phys_descent = max (it->max_phys_descent, it->phys_descent);
24634 }
24635
24636 /* EXPORT for RIF:
24637 Output LEN glyphs starting at START at the nominal cursor position.
24638 Advance the nominal cursor over the text. The global variable
24639 updated_window contains the window being updated, updated_row is
24640 the glyph row being updated, and updated_area is the area of that
24641 row being updated. */
24642
24643 void
24644 x_write_glyphs (struct glyph *start, int len)
24645 {
24646 int x, hpos;
24647
24648 xassert (updated_window && updated_row);
24649 BLOCK_INPUT;
24650
24651 /* Write glyphs. */
24652
24653 hpos = start - updated_row->glyphs[updated_area];
24654 x = draw_glyphs (updated_window, output_cursor.x,
24655 updated_row, updated_area,
24656 hpos, hpos + len,
24657 DRAW_NORMAL_TEXT, 0);
24658
24659 /* Invalidate old phys cursor if the glyph at its hpos is redrawn. */
24660 if (updated_area == TEXT_AREA
24661 && updated_window->phys_cursor_on_p
24662 && updated_window->phys_cursor.vpos == output_cursor.vpos
24663 && updated_window->phys_cursor.hpos >= hpos
24664 && updated_window->phys_cursor.hpos < hpos + len)
24665 updated_window->phys_cursor_on_p = 0;
24666
24667 UNBLOCK_INPUT;
24668
24669 /* Advance the output cursor. */
24670 output_cursor.hpos += len;
24671 output_cursor.x = x;
24672 }
24673
24674
24675 /* EXPORT for RIF:
24676 Insert LEN glyphs from START at the nominal cursor position. */
24677
24678 void
24679 x_insert_glyphs (struct glyph *start, int len)
24680 {
24681 struct frame *f;
24682 struct window *w;
24683 int line_height, shift_by_width, shifted_region_width;
24684 struct glyph_row *row;
24685 struct glyph *glyph;
24686 int frame_x, frame_y;
24687 EMACS_INT hpos;
24688
24689 xassert (updated_window && updated_row);
24690 BLOCK_INPUT;
24691 w = updated_window;
24692 f = XFRAME (WINDOW_FRAME (w));
24693
24694 /* Get the height of the line we are in. */
24695 row = updated_row;
24696 line_height = row->height;
24697
24698 /* Get the width of the glyphs to insert. */
24699 shift_by_width = 0;
24700 for (glyph = start; glyph < start + len; ++glyph)
24701 shift_by_width += glyph->pixel_width;
24702
24703 /* Get the width of the region to shift right. */
24704 shifted_region_width = (window_box_width (w, updated_area)
24705 - output_cursor.x
24706 - shift_by_width);
24707
24708 /* Shift right. */
24709 frame_x = window_box_left (w, updated_area) + output_cursor.x;
24710 frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, output_cursor.y);
24711
24712 FRAME_RIF (f)->shift_glyphs_for_insert (f, frame_x, frame_y, shifted_region_width,
24713 line_height, shift_by_width);
24714
24715 /* Write the glyphs. */
24716 hpos = start - row->glyphs[updated_area];
24717 draw_glyphs (w, output_cursor.x, row, updated_area,
24718 hpos, hpos + len,
24719 DRAW_NORMAL_TEXT, 0);
24720
24721 /* Advance the output cursor. */
24722 output_cursor.hpos += len;
24723 output_cursor.x += shift_by_width;
24724 UNBLOCK_INPUT;
24725 }
24726
24727
24728 /* EXPORT for RIF:
24729 Erase the current text line from the nominal cursor position
24730 (inclusive) to pixel column TO_X (exclusive). The idea is that
24731 everything from TO_X onward is already erased.
24732
24733 TO_X is a pixel position relative to updated_area of
24734 updated_window. TO_X == -1 means clear to the end of this area. */
24735
24736 void
24737 x_clear_end_of_line (int to_x)
24738 {
24739 struct frame *f;
24740 struct window *w = updated_window;
24741 int max_x, min_y, max_y;
24742 int from_x, from_y, to_y;
24743
24744 xassert (updated_window && updated_row);
24745 f = XFRAME (w->frame);
24746
24747 if (updated_row->full_width_p)
24748 max_x = WINDOW_TOTAL_WIDTH (w);
24749 else
24750 max_x = window_box_width (w, updated_area);
24751 max_y = window_text_bottom_y (w);
24752
24753 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
24754 of window. For TO_X > 0, truncate to end of drawing area. */
24755 if (to_x == 0)
24756 return;
24757 else if (to_x < 0)
24758 to_x = max_x;
24759 else
24760 to_x = min (to_x, max_x);
24761
24762 to_y = min (max_y, output_cursor.y + updated_row->height);
24763
24764 /* Notice if the cursor will be cleared by this operation. */
24765 if (!updated_row->full_width_p)
24766 notice_overwritten_cursor (w, updated_area,
24767 output_cursor.x, -1,
24768 updated_row->y,
24769 MATRIX_ROW_BOTTOM_Y (updated_row));
24770
24771 from_x = output_cursor.x;
24772
24773 /* Translate to frame coordinates. */
24774 if (updated_row->full_width_p)
24775 {
24776 from_x = WINDOW_TO_FRAME_PIXEL_X (w, from_x);
24777 to_x = WINDOW_TO_FRAME_PIXEL_X (w, to_x);
24778 }
24779 else
24780 {
24781 int area_left = window_box_left (w, updated_area);
24782 from_x += area_left;
24783 to_x += area_left;
24784 }
24785
24786 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
24787 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, max (min_y, output_cursor.y));
24788 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, to_y);
24789
24790 /* Prevent inadvertently clearing to end of the X window. */
24791 if (to_x > from_x && to_y > from_y)
24792 {
24793 BLOCK_INPUT;
24794 FRAME_RIF (f)->clear_frame_area (f, from_x, from_y,
24795 to_x - from_x, to_y - from_y);
24796 UNBLOCK_INPUT;
24797 }
24798 }
24799
24800 #endif /* HAVE_WINDOW_SYSTEM */
24801
24802
24803 \f
24804 /***********************************************************************
24805 Cursor types
24806 ***********************************************************************/
24807
24808 /* Value is the internal representation of the specified cursor type
24809 ARG. If type is BAR_CURSOR, return in *WIDTH the specified width
24810 of the bar cursor. */
24811
24812 static enum text_cursor_kinds
24813 get_specified_cursor_type (Lisp_Object arg, int *width)
24814 {
24815 enum text_cursor_kinds type;
24816
24817 if (NILP (arg))
24818 return NO_CURSOR;
24819
24820 if (EQ (arg, Qbox))
24821 return FILLED_BOX_CURSOR;
24822
24823 if (EQ (arg, Qhollow))
24824 return HOLLOW_BOX_CURSOR;
24825
24826 if (EQ (arg, Qbar))
24827 {
24828 *width = 2;
24829 return BAR_CURSOR;
24830 }
24831
24832 if (CONSP (arg)
24833 && EQ (XCAR (arg), Qbar)
24834 && INTEGERP (XCDR (arg))
24835 && XINT (XCDR (arg)) >= 0)
24836 {
24837 *width = XINT (XCDR (arg));
24838 return BAR_CURSOR;
24839 }
24840
24841 if (EQ (arg, Qhbar))
24842 {
24843 *width = 2;
24844 return HBAR_CURSOR;
24845 }
24846
24847 if (CONSP (arg)
24848 && EQ (XCAR (arg), Qhbar)
24849 && INTEGERP (XCDR (arg))
24850 && XINT (XCDR (arg)) >= 0)
24851 {
24852 *width = XINT (XCDR (arg));
24853 return HBAR_CURSOR;
24854 }
24855
24856 /* Treat anything unknown as "hollow box cursor".
24857 It was bad to signal an error; people have trouble fixing
24858 .Xdefaults with Emacs, when it has something bad in it. */
24859 type = HOLLOW_BOX_CURSOR;
24860
24861 return type;
24862 }
24863
24864 /* Set the default cursor types for specified frame. */
24865 void
24866 set_frame_cursor_types (struct frame *f, Lisp_Object arg)
24867 {
24868 int width = 1;
24869 Lisp_Object tem;
24870
24871 FRAME_DESIRED_CURSOR (f) = get_specified_cursor_type (arg, &width);
24872 FRAME_CURSOR_WIDTH (f) = width;
24873
24874 /* By default, set up the blink-off state depending on the on-state. */
24875
24876 tem = Fassoc (arg, Vblink_cursor_alist);
24877 if (!NILP (tem))
24878 {
24879 FRAME_BLINK_OFF_CURSOR (f)
24880 = get_specified_cursor_type (XCDR (tem), &width);
24881 FRAME_BLINK_OFF_CURSOR_WIDTH (f) = width;
24882 }
24883 else
24884 FRAME_BLINK_OFF_CURSOR (f) = DEFAULT_CURSOR;
24885 }
24886
24887
24888 #ifdef HAVE_WINDOW_SYSTEM
24889
24890 /* Return the cursor we want to be displayed in window W. Return
24891 width of bar/hbar cursor through WIDTH arg. Return with
24892 ACTIVE_CURSOR arg set to 1 if cursor in window W is `active'
24893 (i.e. if the `system caret' should track this cursor).
24894
24895 In a mini-buffer window, we want the cursor only to appear if we
24896 are reading input from this window. For the selected window, we
24897 want the cursor type given by the frame parameter or buffer local
24898 setting of cursor-type. If explicitly marked off, draw no cursor.
24899 In all other cases, we want a hollow box cursor. */
24900
24901 static enum text_cursor_kinds
24902 get_window_cursor_type (struct window *w, struct glyph *glyph, int *width,
24903 int *active_cursor)
24904 {
24905 struct frame *f = XFRAME (w->frame);
24906 struct buffer *b = XBUFFER (w->buffer);
24907 int cursor_type = DEFAULT_CURSOR;
24908 Lisp_Object alt_cursor;
24909 int non_selected = 0;
24910
24911 *active_cursor = 1;
24912
24913 /* Echo area */
24914 if (cursor_in_echo_area
24915 && FRAME_HAS_MINIBUF_P (f)
24916 && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
24917 {
24918 if (w == XWINDOW (echo_area_window))
24919 {
24920 if (EQ (BVAR (b, cursor_type), Qt) || NILP (BVAR (b, cursor_type)))
24921 {
24922 *width = FRAME_CURSOR_WIDTH (f);
24923 return FRAME_DESIRED_CURSOR (f);
24924 }
24925 else
24926 return get_specified_cursor_type (BVAR (b, cursor_type), width);
24927 }
24928
24929 *active_cursor = 0;
24930 non_selected = 1;
24931 }
24932
24933 /* Detect a nonselected window or nonselected frame. */
24934 else if (w != XWINDOW (f->selected_window)
24935 || f != FRAME_X_DISPLAY_INFO (f)->x_highlight_frame)
24936 {
24937 *active_cursor = 0;
24938
24939 if (MINI_WINDOW_P (w) && minibuf_level == 0)
24940 return NO_CURSOR;
24941
24942 non_selected = 1;
24943 }
24944
24945 /* Never display a cursor in a window in which cursor-type is nil. */
24946 if (NILP (BVAR (b, cursor_type)))
24947 return NO_CURSOR;
24948
24949 /* Get the normal cursor type for this window. */
24950 if (EQ (BVAR (b, cursor_type), Qt))
24951 {
24952 cursor_type = FRAME_DESIRED_CURSOR (f);
24953 *width = FRAME_CURSOR_WIDTH (f);
24954 }
24955 else
24956 cursor_type = get_specified_cursor_type (BVAR (b, cursor_type), width);
24957
24958 /* Use cursor-in-non-selected-windows instead
24959 for non-selected window or frame. */
24960 if (non_selected)
24961 {
24962 alt_cursor = BVAR (b, cursor_in_non_selected_windows);
24963 if (!EQ (Qt, alt_cursor))
24964 return get_specified_cursor_type (alt_cursor, width);
24965 /* t means modify the normal cursor type. */
24966 if (cursor_type == FILLED_BOX_CURSOR)
24967 cursor_type = HOLLOW_BOX_CURSOR;
24968 else if (cursor_type == BAR_CURSOR && *width > 1)
24969 --*width;
24970 return cursor_type;
24971 }
24972
24973 /* Use normal cursor if not blinked off. */
24974 if (!w->cursor_off_p)
24975 {
24976 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
24977 {
24978 if (cursor_type == FILLED_BOX_CURSOR)
24979 {
24980 /* Using a block cursor on large images can be very annoying.
24981 So use a hollow cursor for "large" images.
24982 If image is not transparent (no mask), also use hollow cursor. */
24983 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
24984 if (img != NULL && IMAGEP (img->spec))
24985 {
24986 /* Arbitrarily, interpret "Large" as >32x32 and >NxN
24987 where N = size of default frame font size.
24988 This should cover most of the "tiny" icons people may use. */
24989 if (!img->mask
24990 || img->width > max (32, WINDOW_FRAME_COLUMN_WIDTH (w))
24991 || img->height > max (32, WINDOW_FRAME_LINE_HEIGHT (w)))
24992 cursor_type = HOLLOW_BOX_CURSOR;
24993 }
24994 }
24995 else if (cursor_type != NO_CURSOR)
24996 {
24997 /* Display current only supports BOX and HOLLOW cursors for images.
24998 So for now, unconditionally use a HOLLOW cursor when cursor is
24999 not a solid box cursor. */
25000 cursor_type = HOLLOW_BOX_CURSOR;
25001 }
25002 }
25003 return cursor_type;
25004 }
25005
25006 /* Cursor is blinked off, so determine how to "toggle" it. */
25007
25008 /* First look for an entry matching the buffer's cursor-type in blink-cursor-alist. */
25009 if ((alt_cursor = Fassoc (BVAR (b, cursor_type), Vblink_cursor_alist), !NILP (alt_cursor)))
25010 return get_specified_cursor_type (XCDR (alt_cursor), width);
25011
25012 /* Then see if frame has specified a specific blink off cursor type. */
25013 if (FRAME_BLINK_OFF_CURSOR (f) != DEFAULT_CURSOR)
25014 {
25015 *width = FRAME_BLINK_OFF_CURSOR_WIDTH (f);
25016 return FRAME_BLINK_OFF_CURSOR (f);
25017 }
25018
25019 #if 0
25020 /* Some people liked having a permanently visible blinking cursor,
25021 while others had very strong opinions against it. So it was
25022 decided to remove it. KFS 2003-09-03 */
25023
25024 /* Finally perform built-in cursor blinking:
25025 filled box <-> hollow box
25026 wide [h]bar <-> narrow [h]bar
25027 narrow [h]bar <-> no cursor
25028 other type <-> no cursor */
25029
25030 if (cursor_type == FILLED_BOX_CURSOR)
25031 return HOLLOW_BOX_CURSOR;
25032
25033 if ((cursor_type == BAR_CURSOR || cursor_type == HBAR_CURSOR) && *width > 1)
25034 {
25035 *width = 1;
25036 return cursor_type;
25037 }
25038 #endif
25039
25040 return NO_CURSOR;
25041 }
25042
25043
25044 /* Notice when the text cursor of window W has been completely
25045 overwritten by a drawing operation that outputs glyphs in AREA
25046 starting at X0 and ending at X1 in the line starting at Y0 and
25047 ending at Y1. X coordinates are area-relative. X1 < 0 means all
25048 the rest of the line after X0 has been written. Y coordinates
25049 are window-relative. */
25050
25051 static void
25052 notice_overwritten_cursor (struct window *w, enum glyph_row_area area,
25053 int x0, int x1, int y0, int y1)
25054 {
25055 int cx0, cx1, cy0, cy1;
25056 struct glyph_row *row;
25057
25058 if (!w->phys_cursor_on_p)
25059 return;
25060 if (area != TEXT_AREA)
25061 return;
25062
25063 if (w->phys_cursor.vpos < 0
25064 || w->phys_cursor.vpos >= w->current_matrix->nrows
25065 || (row = w->current_matrix->rows + w->phys_cursor.vpos,
25066 !(row->enabled_p && row->displays_text_p)))
25067 return;
25068
25069 if (row->cursor_in_fringe_p)
25070 {
25071 row->cursor_in_fringe_p = 0;
25072 draw_fringe_bitmap (w, row, row->reversed_p);
25073 w->phys_cursor_on_p = 0;
25074 return;
25075 }
25076
25077 cx0 = w->phys_cursor.x;
25078 cx1 = cx0 + w->phys_cursor_width;
25079 if (x0 > cx0 || (x1 >= 0 && x1 < cx1))
25080 return;
25081
25082 /* The cursor image will be completely removed from the
25083 screen if the output area intersects the cursor area in
25084 y-direction. When we draw in [y0 y1[, and some part of
25085 the cursor is at y < y0, that part must have been drawn
25086 before. When scrolling, the cursor is erased before
25087 actually scrolling, so we don't come here. When not
25088 scrolling, the rows above the old cursor row must have
25089 changed, and in this case these rows must have written
25090 over the cursor image.
25091
25092 Likewise if part of the cursor is below y1, with the
25093 exception of the cursor being in the first blank row at
25094 the buffer and window end because update_text_area
25095 doesn't draw that row. (Except when it does, but
25096 that's handled in update_text_area.) */
25097
25098 cy0 = w->phys_cursor.y;
25099 cy1 = cy0 + w->phys_cursor_height;
25100 if ((y0 < cy0 || y0 >= cy1) && (y1 <= cy0 || y1 >= cy1))
25101 return;
25102
25103 w->phys_cursor_on_p = 0;
25104 }
25105
25106 #endif /* HAVE_WINDOW_SYSTEM */
25107
25108 \f
25109 /************************************************************************
25110 Mouse Face
25111 ************************************************************************/
25112
25113 #ifdef HAVE_WINDOW_SYSTEM
25114
25115 /* EXPORT for RIF:
25116 Fix the display of area AREA of overlapping row ROW in window W
25117 with respect to the overlapping part OVERLAPS. */
25118
25119 void
25120 x_fix_overlapping_area (struct window *w, struct glyph_row *row,
25121 enum glyph_row_area area, int overlaps)
25122 {
25123 int i, x;
25124
25125 BLOCK_INPUT;
25126
25127 x = 0;
25128 for (i = 0; i < row->used[area];)
25129 {
25130 if (row->glyphs[area][i].overlaps_vertically_p)
25131 {
25132 int start = i, start_x = x;
25133
25134 do
25135 {
25136 x += row->glyphs[area][i].pixel_width;
25137 ++i;
25138 }
25139 while (i < row->used[area]
25140 && row->glyphs[area][i].overlaps_vertically_p);
25141
25142 draw_glyphs (w, start_x, row, area,
25143 start, i,
25144 DRAW_NORMAL_TEXT, overlaps);
25145 }
25146 else
25147 {
25148 x += row->glyphs[area][i].pixel_width;
25149 ++i;
25150 }
25151 }
25152
25153 UNBLOCK_INPUT;
25154 }
25155
25156
25157 /* EXPORT:
25158 Draw the cursor glyph of window W in glyph row ROW. See the
25159 comment of draw_glyphs for the meaning of HL. */
25160
25161 void
25162 draw_phys_cursor_glyph (struct window *w, struct glyph_row *row,
25163 enum draw_glyphs_face hl)
25164 {
25165 /* If cursor hpos is out of bounds, don't draw garbage. This can
25166 happen in mini-buffer windows when switching between echo area
25167 glyphs and mini-buffer. */
25168 if ((row->reversed_p
25169 ? (w->phys_cursor.hpos >= 0)
25170 : (w->phys_cursor.hpos < row->used[TEXT_AREA])))
25171 {
25172 int on_p = w->phys_cursor_on_p;
25173 int x1;
25174 x1 = draw_glyphs (w, w->phys_cursor.x, row, TEXT_AREA,
25175 w->phys_cursor.hpos, w->phys_cursor.hpos + 1,
25176 hl, 0);
25177 w->phys_cursor_on_p = on_p;
25178
25179 if (hl == DRAW_CURSOR)
25180 w->phys_cursor_width = x1 - w->phys_cursor.x;
25181 /* When we erase the cursor, and ROW is overlapped by other
25182 rows, make sure that these overlapping parts of other rows
25183 are redrawn. */
25184 else if (hl == DRAW_NORMAL_TEXT && row->overlapped_p)
25185 {
25186 w->phys_cursor_width = x1 - w->phys_cursor.x;
25187
25188 if (row > w->current_matrix->rows
25189 && MATRIX_ROW_OVERLAPS_SUCC_P (row - 1))
25190 x_fix_overlapping_area (w, row - 1, TEXT_AREA,
25191 OVERLAPS_ERASED_CURSOR);
25192
25193 if (MATRIX_ROW_BOTTOM_Y (row) < window_text_bottom_y (w)
25194 && MATRIX_ROW_OVERLAPS_PRED_P (row + 1))
25195 x_fix_overlapping_area (w, row + 1, TEXT_AREA,
25196 OVERLAPS_ERASED_CURSOR);
25197 }
25198 }
25199 }
25200
25201
25202 /* EXPORT:
25203 Erase the image of a cursor of window W from the screen. */
25204
25205 void
25206 erase_phys_cursor (struct window *w)
25207 {
25208 struct frame *f = XFRAME (w->frame);
25209 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
25210 int hpos = w->phys_cursor.hpos;
25211 int vpos = w->phys_cursor.vpos;
25212 int mouse_face_here_p = 0;
25213 struct glyph_matrix *active_glyphs = w->current_matrix;
25214 struct glyph_row *cursor_row;
25215 struct glyph *cursor_glyph;
25216 enum draw_glyphs_face hl;
25217
25218 /* No cursor displayed or row invalidated => nothing to do on the
25219 screen. */
25220 if (w->phys_cursor_type == NO_CURSOR)
25221 goto mark_cursor_off;
25222
25223 /* VPOS >= active_glyphs->nrows means that window has been resized.
25224 Don't bother to erase the cursor. */
25225 if (vpos >= active_glyphs->nrows)
25226 goto mark_cursor_off;
25227
25228 /* If row containing cursor is marked invalid, there is nothing we
25229 can do. */
25230 cursor_row = MATRIX_ROW (active_glyphs, vpos);
25231 if (!cursor_row->enabled_p)
25232 goto mark_cursor_off;
25233
25234 /* If line spacing is > 0, old cursor may only be partially visible in
25235 window after split-window. So adjust visible height. */
25236 cursor_row->visible_height = min (cursor_row->visible_height,
25237 window_text_bottom_y (w) - cursor_row->y);
25238
25239 /* If row is completely invisible, don't attempt to delete a cursor which
25240 isn't there. This can happen if cursor is at top of a window, and
25241 we switch to a buffer with a header line in that window. */
25242 if (cursor_row->visible_height <= 0)
25243 goto mark_cursor_off;
25244
25245 /* If cursor is in the fringe, erase by drawing actual bitmap there. */
25246 if (cursor_row->cursor_in_fringe_p)
25247 {
25248 cursor_row->cursor_in_fringe_p = 0;
25249 draw_fringe_bitmap (w, cursor_row, cursor_row->reversed_p);
25250 goto mark_cursor_off;
25251 }
25252
25253 /* This can happen when the new row is shorter than the old one.
25254 In this case, either draw_glyphs or clear_end_of_line
25255 should have cleared the cursor. Note that we wouldn't be
25256 able to erase the cursor in this case because we don't have a
25257 cursor glyph at hand. */
25258 if ((cursor_row->reversed_p
25259 ? (w->phys_cursor.hpos < 0)
25260 : (w->phys_cursor.hpos >= cursor_row->used[TEXT_AREA])))
25261 goto mark_cursor_off;
25262
25263 /* If the cursor is in the mouse face area, redisplay that when
25264 we clear the cursor. */
25265 if (! NILP (hlinfo->mouse_face_window)
25266 && coords_in_mouse_face_p (w, hpos, vpos)
25267 /* Don't redraw the cursor's spot in mouse face if it is at the
25268 end of a line (on a newline). The cursor appears there, but
25269 mouse highlighting does not. */
25270 && cursor_row->used[TEXT_AREA] > hpos && hpos >= 0)
25271 mouse_face_here_p = 1;
25272
25273 /* Maybe clear the display under the cursor. */
25274 if (w->phys_cursor_type == HOLLOW_BOX_CURSOR)
25275 {
25276 int x, y, left_x;
25277 int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
25278 int width;
25279
25280 cursor_glyph = get_phys_cursor_glyph (w);
25281 if (cursor_glyph == NULL)
25282 goto mark_cursor_off;
25283
25284 width = cursor_glyph->pixel_width;
25285 left_x = window_box_left_offset (w, TEXT_AREA);
25286 x = w->phys_cursor.x;
25287 if (x < left_x)
25288 width -= left_x - x;
25289 width = min (width, window_box_width (w, TEXT_AREA) - x);
25290 y = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, cursor_row->y));
25291 x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, max (x, left_x));
25292
25293 if (width > 0)
25294 FRAME_RIF (f)->clear_frame_area (f, x, y, width, cursor_row->visible_height);
25295 }
25296
25297 /* Erase the cursor by redrawing the character underneath it. */
25298 if (mouse_face_here_p)
25299 hl = DRAW_MOUSE_FACE;
25300 else
25301 hl = DRAW_NORMAL_TEXT;
25302 draw_phys_cursor_glyph (w, cursor_row, hl);
25303
25304 mark_cursor_off:
25305 w->phys_cursor_on_p = 0;
25306 w->phys_cursor_type = NO_CURSOR;
25307 }
25308
25309
25310 /* EXPORT:
25311 Display or clear cursor of window W. If ON is zero, clear the
25312 cursor. If it is non-zero, display the cursor. If ON is nonzero,
25313 where to put the cursor is specified by HPOS, VPOS, X and Y. */
25314
25315 void
25316 display_and_set_cursor (struct window *w, int on,
25317 int hpos, int vpos, int x, int y)
25318 {
25319 struct frame *f = XFRAME (w->frame);
25320 int new_cursor_type;
25321 int new_cursor_width;
25322 int active_cursor;
25323 struct glyph_row *glyph_row;
25324 struct glyph *glyph;
25325
25326 /* This is pointless on invisible frames, and dangerous on garbaged
25327 windows and frames; in the latter case, the frame or window may
25328 be in the midst of changing its size, and x and y may be off the
25329 window. */
25330 if (! FRAME_VISIBLE_P (f)
25331 || FRAME_GARBAGED_P (f)
25332 || vpos >= w->current_matrix->nrows
25333 || hpos >= w->current_matrix->matrix_w)
25334 return;
25335
25336 /* If cursor is off and we want it off, return quickly. */
25337 if (!on && !w->phys_cursor_on_p)
25338 return;
25339
25340 glyph_row = MATRIX_ROW (w->current_matrix, vpos);
25341 /* If cursor row is not enabled, we don't really know where to
25342 display the cursor. */
25343 if (!glyph_row->enabled_p)
25344 {
25345 w->phys_cursor_on_p = 0;
25346 return;
25347 }
25348
25349 glyph = NULL;
25350 if (!glyph_row->exact_window_width_line_p
25351 || (0 <= hpos && hpos < glyph_row->used[TEXT_AREA]))
25352 glyph = glyph_row->glyphs[TEXT_AREA] + hpos;
25353
25354 xassert (interrupt_input_blocked);
25355
25356 /* Set new_cursor_type to the cursor we want to be displayed. */
25357 new_cursor_type = get_window_cursor_type (w, glyph,
25358 &new_cursor_width, &active_cursor);
25359
25360 /* If cursor is currently being shown and we don't want it to be or
25361 it is in the wrong place, or the cursor type is not what we want,
25362 erase it. */
25363 if (w->phys_cursor_on_p
25364 && (!on
25365 || w->phys_cursor.x != x
25366 || w->phys_cursor.y != y
25367 || new_cursor_type != w->phys_cursor_type
25368 || ((new_cursor_type == BAR_CURSOR || new_cursor_type == HBAR_CURSOR)
25369 && new_cursor_width != w->phys_cursor_width)))
25370 erase_phys_cursor (w);
25371
25372 /* Don't check phys_cursor_on_p here because that flag is only set
25373 to zero in some cases where we know that the cursor has been
25374 completely erased, to avoid the extra work of erasing the cursor
25375 twice. In other words, phys_cursor_on_p can be 1 and the cursor
25376 still not be visible, or it has only been partly erased. */
25377 if (on)
25378 {
25379 w->phys_cursor_ascent = glyph_row->ascent;
25380 w->phys_cursor_height = glyph_row->height;
25381
25382 /* Set phys_cursor_.* before x_draw_.* is called because some
25383 of them may need the information. */
25384 w->phys_cursor.x = x;
25385 w->phys_cursor.y = glyph_row->y;
25386 w->phys_cursor.hpos = hpos;
25387 w->phys_cursor.vpos = vpos;
25388 }
25389
25390 FRAME_RIF (f)->draw_window_cursor (w, glyph_row, x, y,
25391 new_cursor_type, new_cursor_width,
25392 on, active_cursor);
25393 }
25394
25395
25396 /* Switch the display of W's cursor on or off, according to the value
25397 of ON. */
25398
25399 static void
25400 update_window_cursor (struct window *w, int on)
25401 {
25402 /* Don't update cursor in windows whose frame is in the process
25403 of being deleted. */
25404 if (w->current_matrix)
25405 {
25406 BLOCK_INPUT;
25407 display_and_set_cursor (w, on, w->phys_cursor.hpos, w->phys_cursor.vpos,
25408 w->phys_cursor.x, w->phys_cursor.y);
25409 UNBLOCK_INPUT;
25410 }
25411 }
25412
25413
25414 /* Call update_window_cursor with parameter ON_P on all leaf windows
25415 in the window tree rooted at W. */
25416
25417 static void
25418 update_cursor_in_window_tree (struct window *w, int on_p)
25419 {
25420 while (w)
25421 {
25422 if (!NILP (w->hchild))
25423 update_cursor_in_window_tree (XWINDOW (w->hchild), on_p);
25424 else if (!NILP (w->vchild))
25425 update_cursor_in_window_tree (XWINDOW (w->vchild), on_p);
25426 else
25427 update_window_cursor (w, on_p);
25428
25429 w = NILP (w->next) ? 0 : XWINDOW (w->next);
25430 }
25431 }
25432
25433
25434 /* EXPORT:
25435 Display the cursor on window W, or clear it, according to ON_P.
25436 Don't change the cursor's position. */
25437
25438 void
25439 x_update_cursor (struct frame *f, int on_p)
25440 {
25441 update_cursor_in_window_tree (XWINDOW (f->root_window), on_p);
25442 }
25443
25444
25445 /* EXPORT:
25446 Clear the cursor of window W to background color, and mark the
25447 cursor as not shown. This is used when the text where the cursor
25448 is about to be rewritten. */
25449
25450 void
25451 x_clear_cursor (struct window *w)
25452 {
25453 if (FRAME_VISIBLE_P (XFRAME (w->frame)) && w->phys_cursor_on_p)
25454 update_window_cursor (w, 0);
25455 }
25456
25457 #endif /* HAVE_WINDOW_SYSTEM */
25458
25459 /* Implementation of draw_row_with_mouse_face for GUI sessions, GPM,
25460 and MSDOS. */
25461 static void
25462 draw_row_with_mouse_face (struct window *w, int start_x, struct glyph_row *row,
25463 int start_hpos, int end_hpos,
25464 enum draw_glyphs_face draw)
25465 {
25466 #ifdef HAVE_WINDOW_SYSTEM
25467 if (FRAME_WINDOW_P (XFRAME (w->frame)))
25468 {
25469 draw_glyphs (w, start_x, row, TEXT_AREA, start_hpos, end_hpos, draw, 0);
25470 return;
25471 }
25472 #endif
25473 #if defined (HAVE_GPM) || defined (MSDOS)
25474 tty_draw_row_with_mouse_face (w, row, start_hpos, end_hpos, draw);
25475 #endif
25476 }
25477
25478 /* Display the active region described by mouse_face_* according to DRAW. */
25479
25480 static void
25481 show_mouse_face (Mouse_HLInfo *hlinfo, enum draw_glyphs_face draw)
25482 {
25483 struct window *w = XWINDOW (hlinfo->mouse_face_window);
25484 struct frame *f = XFRAME (WINDOW_FRAME (w));
25485
25486 if (/* If window is in the process of being destroyed, don't bother
25487 to do anything. */
25488 w->current_matrix != NULL
25489 /* Don't update mouse highlight if hidden */
25490 && (draw != DRAW_MOUSE_FACE || !hlinfo->mouse_face_hidden)
25491 /* Recognize when we are called to operate on rows that don't exist
25492 anymore. This can happen when a window is split. */
25493 && hlinfo->mouse_face_end_row < w->current_matrix->nrows)
25494 {
25495 int phys_cursor_on_p = w->phys_cursor_on_p;
25496 struct glyph_row *row, *first, *last;
25497
25498 first = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_beg_row);
25499 last = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_end_row);
25500
25501 for (row = first; row <= last && row->enabled_p; ++row)
25502 {
25503 int start_hpos, end_hpos, start_x;
25504
25505 /* For all but the first row, the highlight starts at column 0. */
25506 if (row == first)
25507 {
25508 /* R2L rows have BEG and END in reversed order, but the
25509 screen drawing geometry is always left to right. So
25510 we need to mirror the beginning and end of the
25511 highlighted area in R2L rows. */
25512 if (!row->reversed_p)
25513 {
25514 start_hpos = hlinfo->mouse_face_beg_col;
25515 start_x = hlinfo->mouse_face_beg_x;
25516 }
25517 else if (row == last)
25518 {
25519 start_hpos = hlinfo->mouse_face_end_col;
25520 start_x = hlinfo->mouse_face_end_x;
25521 }
25522 else
25523 {
25524 start_hpos = 0;
25525 start_x = 0;
25526 }
25527 }
25528 else if (row->reversed_p && row == last)
25529 {
25530 start_hpos = hlinfo->mouse_face_end_col;
25531 start_x = hlinfo->mouse_face_end_x;
25532 }
25533 else
25534 {
25535 start_hpos = 0;
25536 start_x = 0;
25537 }
25538
25539 if (row == last)
25540 {
25541 if (!row->reversed_p)
25542 end_hpos = hlinfo->mouse_face_end_col;
25543 else if (row == first)
25544 end_hpos = hlinfo->mouse_face_beg_col;
25545 else
25546 {
25547 end_hpos = row->used[TEXT_AREA];
25548 if (draw == DRAW_NORMAL_TEXT)
25549 row->fill_line_p = 1; /* Clear to end of line */
25550 }
25551 }
25552 else if (row->reversed_p && row == first)
25553 end_hpos = hlinfo->mouse_face_beg_col;
25554 else
25555 {
25556 end_hpos = row->used[TEXT_AREA];
25557 if (draw == DRAW_NORMAL_TEXT)
25558 row->fill_line_p = 1; /* Clear to end of line */
25559 }
25560
25561 if (end_hpos > start_hpos)
25562 {
25563 draw_row_with_mouse_face (w, start_x, row,
25564 start_hpos, end_hpos, draw);
25565
25566 row->mouse_face_p
25567 = draw == DRAW_MOUSE_FACE || draw == DRAW_IMAGE_RAISED;
25568 }
25569 }
25570
25571 #ifdef HAVE_WINDOW_SYSTEM
25572 /* When we've written over the cursor, arrange for it to
25573 be displayed again. */
25574 if (FRAME_WINDOW_P (f)
25575 && phys_cursor_on_p && !w->phys_cursor_on_p)
25576 {
25577 BLOCK_INPUT;
25578 display_and_set_cursor (w, 1,
25579 w->phys_cursor.hpos, w->phys_cursor.vpos,
25580 w->phys_cursor.x, w->phys_cursor.y);
25581 UNBLOCK_INPUT;
25582 }
25583 #endif /* HAVE_WINDOW_SYSTEM */
25584 }
25585
25586 #ifdef HAVE_WINDOW_SYSTEM
25587 /* Change the mouse cursor. */
25588 if (FRAME_WINDOW_P (f))
25589 {
25590 if (draw == DRAW_NORMAL_TEXT
25591 && !EQ (hlinfo->mouse_face_window, f->tool_bar_window))
25592 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->text_cursor);
25593 else if (draw == DRAW_MOUSE_FACE)
25594 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->hand_cursor);
25595 else
25596 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->nontext_cursor);
25597 }
25598 #endif /* HAVE_WINDOW_SYSTEM */
25599 }
25600
25601 /* EXPORT:
25602 Clear out the mouse-highlighted active region.
25603 Redraw it un-highlighted first. Value is non-zero if mouse
25604 face was actually drawn unhighlighted. */
25605
25606 int
25607 clear_mouse_face (Mouse_HLInfo *hlinfo)
25608 {
25609 int cleared = 0;
25610
25611 if (!hlinfo->mouse_face_hidden && !NILP (hlinfo->mouse_face_window))
25612 {
25613 show_mouse_face (hlinfo, DRAW_NORMAL_TEXT);
25614 cleared = 1;
25615 }
25616
25617 hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
25618 hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
25619 hlinfo->mouse_face_window = Qnil;
25620 hlinfo->mouse_face_overlay = Qnil;
25621 return cleared;
25622 }
25623
25624 /* Return non-zero if the coordinates HPOS and VPOS on windows W are
25625 within the mouse face on that window. */
25626 static int
25627 coords_in_mouse_face_p (struct window *w, int hpos, int vpos)
25628 {
25629 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame));
25630
25631 /* Quickly resolve the easy cases. */
25632 if (!(WINDOWP (hlinfo->mouse_face_window)
25633 && XWINDOW (hlinfo->mouse_face_window) == w))
25634 return 0;
25635 if (vpos < hlinfo->mouse_face_beg_row
25636 || vpos > hlinfo->mouse_face_end_row)
25637 return 0;
25638 if (vpos > hlinfo->mouse_face_beg_row
25639 && vpos < hlinfo->mouse_face_end_row)
25640 return 1;
25641
25642 if (!MATRIX_ROW (w->current_matrix, vpos)->reversed_p)
25643 {
25644 if (hlinfo->mouse_face_beg_row == hlinfo->mouse_face_end_row)
25645 {
25646 if (hlinfo->mouse_face_beg_col <= hpos && hpos < hlinfo->mouse_face_end_col)
25647 return 1;
25648 }
25649 else if ((vpos == hlinfo->mouse_face_beg_row
25650 && hpos >= hlinfo->mouse_face_beg_col)
25651 || (vpos == hlinfo->mouse_face_end_row
25652 && hpos < hlinfo->mouse_face_end_col))
25653 return 1;
25654 }
25655 else
25656 {
25657 if (hlinfo->mouse_face_beg_row == hlinfo->mouse_face_end_row)
25658 {
25659 if (hlinfo->mouse_face_end_col < hpos && hpos <= hlinfo->mouse_face_beg_col)
25660 return 1;
25661 }
25662 else if ((vpos == hlinfo->mouse_face_beg_row
25663 && hpos <= hlinfo->mouse_face_beg_col)
25664 || (vpos == hlinfo->mouse_face_end_row
25665 && hpos > hlinfo->mouse_face_end_col))
25666 return 1;
25667 }
25668 return 0;
25669 }
25670
25671
25672 /* EXPORT:
25673 Non-zero if physical cursor of window W is within mouse face. */
25674
25675 int
25676 cursor_in_mouse_face_p (struct window *w)
25677 {
25678 return coords_in_mouse_face_p (w, w->phys_cursor.hpos, w->phys_cursor.vpos);
25679 }
25680
25681
25682 \f
25683 /* Find the glyph rows START_ROW and END_ROW of window W that display
25684 characters between buffer positions START_CHARPOS and END_CHARPOS
25685 (excluding END_CHARPOS). This is similar to row_containing_pos,
25686 but is more accurate when bidi reordering makes buffer positions
25687 change non-linearly with glyph rows. */
25688 static void
25689 rows_from_pos_range (struct window *w,
25690 EMACS_INT start_charpos, EMACS_INT end_charpos,
25691 struct glyph_row **start, struct glyph_row **end)
25692 {
25693 struct glyph_row *first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
25694 int last_y = window_text_bottom_y (w);
25695 struct glyph_row *row;
25696
25697 *start = NULL;
25698 *end = NULL;
25699
25700 while (!first->enabled_p
25701 && first < MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w))
25702 first++;
25703
25704 /* Find the START row. */
25705 for (row = first;
25706 row->enabled_p && MATRIX_ROW_BOTTOM_Y (row) <= last_y;
25707 row++)
25708 {
25709 /* A row can potentially be the START row if the range of the
25710 characters it displays intersects the range
25711 [START_CHARPOS..END_CHARPOS). */
25712 if (! ((start_charpos < MATRIX_ROW_START_CHARPOS (row)
25713 && end_charpos < MATRIX_ROW_START_CHARPOS (row))
25714 /* See the commentary in row_containing_pos, for the
25715 explanation of the complicated way to check whether
25716 some position is beyond the end of the characters
25717 displayed by a row. */
25718 || ((start_charpos > MATRIX_ROW_END_CHARPOS (row)
25719 || (start_charpos == MATRIX_ROW_END_CHARPOS (row)
25720 && !row->ends_at_zv_p
25721 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
25722 && (end_charpos > MATRIX_ROW_END_CHARPOS (row)
25723 || (end_charpos == MATRIX_ROW_END_CHARPOS (row)
25724 && !row->ends_at_zv_p
25725 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))))))
25726 {
25727 /* Found a candidate row. Now make sure at least one of the
25728 glyphs it displays has a charpos from the range
25729 [START_CHARPOS..END_CHARPOS).
25730
25731 This is not obvious because bidi reordering could make
25732 buffer positions of a row be 1,2,3,102,101,100, and if we
25733 want to highlight characters in [50..60), we don't want
25734 this row, even though [50..60) does intersect [1..103),
25735 the range of character positions given by the row's start
25736 and end positions. */
25737 struct glyph *g = row->glyphs[TEXT_AREA];
25738 struct glyph *e = g + row->used[TEXT_AREA];
25739
25740 while (g < e)
25741 {
25742 if ((BUFFERP (g->object) || INTEGERP (g->object))
25743 && start_charpos <= g->charpos && g->charpos < end_charpos)
25744 *start = row;
25745 g++;
25746 }
25747 if (*start)
25748 break;
25749 }
25750 }
25751
25752 /* Find the END row. */
25753 if (!*start
25754 /* If the last row is partially visible, start looking for END
25755 from that row, instead of starting from FIRST. */
25756 && !(row->enabled_p
25757 && row->y < last_y && MATRIX_ROW_BOTTOM_Y (row) > last_y))
25758 row = first;
25759 for ( ; row->enabled_p && MATRIX_ROW_BOTTOM_Y (row) <= last_y; row++)
25760 {
25761 struct glyph_row *next = row + 1;
25762
25763 if (!next->enabled_p
25764 || next >= MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w)
25765 /* The first row >= START whose range of displayed characters
25766 does NOT intersect the range [START_CHARPOS..END_CHARPOS]
25767 is the row END + 1. */
25768 || (start_charpos < MATRIX_ROW_START_CHARPOS (next)
25769 && end_charpos < MATRIX_ROW_START_CHARPOS (next))
25770 || ((start_charpos > MATRIX_ROW_END_CHARPOS (next)
25771 || (start_charpos == MATRIX_ROW_END_CHARPOS (next)
25772 && !next->ends_at_zv_p
25773 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (next)))
25774 && (end_charpos > MATRIX_ROW_END_CHARPOS (next)
25775 || (end_charpos == MATRIX_ROW_END_CHARPOS (next)
25776 && !next->ends_at_zv_p
25777 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (next)))))
25778 {
25779 *end = row;
25780 break;
25781 }
25782 else
25783 {
25784 /* If the next row's edges intersect [START_CHARPOS..END_CHARPOS],
25785 but none of the characters it displays are in the range, it is
25786 also END + 1. */
25787 struct glyph *g = next->glyphs[TEXT_AREA];
25788 struct glyph *e = g + next->used[TEXT_AREA];
25789
25790 while (g < e)
25791 {
25792 if ((BUFFERP (g->object) || INTEGERP (g->object))
25793 && start_charpos <= g->charpos && g->charpos < end_charpos)
25794 break;
25795 g++;
25796 }
25797 if (g == e)
25798 {
25799 *end = row;
25800 break;
25801 }
25802 }
25803 }
25804 }
25805
25806 /* This function sets the mouse_face_* elements of HLINFO, assuming
25807 the mouse cursor is on a glyph with buffer charpos MOUSE_CHARPOS in
25808 window WINDOW. START_CHARPOS and END_CHARPOS are buffer positions
25809 for the overlay or run of text properties specifying the mouse
25810 face. BEFORE_STRING and AFTER_STRING, if non-nil, are a
25811 before-string and after-string that must also be highlighted.
25812 COVER_STRING, if non-nil, is a display string that may cover some
25813 or all of the highlighted text. */
25814
25815 static void
25816 mouse_face_from_buffer_pos (Lisp_Object window,
25817 Mouse_HLInfo *hlinfo,
25818 EMACS_INT mouse_charpos,
25819 EMACS_INT start_charpos,
25820 EMACS_INT end_charpos,
25821 Lisp_Object before_string,
25822 Lisp_Object after_string,
25823 Lisp_Object cover_string)
25824 {
25825 struct window *w = XWINDOW (window);
25826 struct glyph_row *first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
25827 struct glyph_row *r1, *r2;
25828 struct glyph *glyph, *end;
25829 EMACS_INT ignore, pos;
25830 int x;
25831
25832 xassert (NILP (cover_string) || STRINGP (cover_string));
25833 xassert (NILP (before_string) || STRINGP (before_string));
25834 xassert (NILP (after_string) || STRINGP (after_string));
25835
25836 /* Find the rows corresponding to START_CHARPOS and END_CHARPOS. */
25837 rows_from_pos_range (w, start_charpos, end_charpos, &r1, &r2);
25838 if (r1 == NULL)
25839 r1 = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
25840 /* If the before-string or display-string contains newlines,
25841 rows_from_pos_range skips to its last row. Move back. */
25842 if (!NILP (before_string) || !NILP (cover_string))
25843 {
25844 struct glyph_row *prev;
25845 while ((prev = r1 - 1, prev >= first)
25846 && MATRIX_ROW_END_CHARPOS (prev) == start_charpos
25847 && prev->used[TEXT_AREA] > 0)
25848 {
25849 struct glyph *beg = prev->glyphs[TEXT_AREA];
25850 glyph = beg + prev->used[TEXT_AREA];
25851 while (--glyph >= beg && INTEGERP (glyph->object));
25852 if (glyph < beg
25853 || !(EQ (glyph->object, before_string)
25854 || EQ (glyph->object, cover_string)))
25855 break;
25856 r1 = prev;
25857 }
25858 }
25859 if (r2 == NULL)
25860 {
25861 r2 = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
25862 hlinfo->mouse_face_past_end = 1;
25863 }
25864 else if (!NILP (after_string))
25865 {
25866 /* If the after-string has newlines, advance to its last row. */
25867 struct glyph_row *next;
25868 struct glyph_row *last
25869 = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
25870
25871 for (next = r2 + 1;
25872 next <= last
25873 && next->used[TEXT_AREA] > 0
25874 && EQ (next->glyphs[TEXT_AREA]->object, after_string);
25875 ++next)
25876 r2 = next;
25877 }
25878 /* The rest of the display engine assumes that mouse_face_beg_row is
25879 either above below mouse_face_end_row or identical to it. But
25880 with bidi-reordered continued lines, the row for START_CHARPOS
25881 could be below the row for END_CHARPOS. If so, swap the rows and
25882 store them in correct order. */
25883 if (r1->y > r2->y)
25884 {
25885 struct glyph_row *tem = r2;
25886
25887 r2 = r1;
25888 r1 = tem;
25889 }
25890
25891 hlinfo->mouse_face_beg_y = r1->y;
25892 hlinfo->mouse_face_beg_row = MATRIX_ROW_VPOS (r1, w->current_matrix);
25893 hlinfo->mouse_face_end_y = r2->y;
25894 hlinfo->mouse_face_end_row = MATRIX_ROW_VPOS (r2, w->current_matrix);
25895
25896 /* For a bidi-reordered row, the positions of BEFORE_STRING,
25897 AFTER_STRING, COVER_STRING, START_CHARPOS, and END_CHARPOS
25898 could be anywhere in the row and in any order. The strategy
25899 below is to find the leftmost and the rightmost glyph that
25900 belongs to either of these 3 strings, or whose position is
25901 between START_CHARPOS and END_CHARPOS, and highlight all the
25902 glyphs between those two. This may cover more than just the text
25903 between START_CHARPOS and END_CHARPOS if the range of characters
25904 strides the bidi level boundary, e.g. if the beginning is in R2L
25905 text while the end is in L2R text or vice versa. */
25906 if (!r1->reversed_p)
25907 {
25908 /* This row is in a left to right paragraph. Scan it left to
25909 right. */
25910 glyph = r1->glyphs[TEXT_AREA];
25911 end = glyph + r1->used[TEXT_AREA];
25912 x = r1->x;
25913
25914 /* Skip truncation glyphs at the start of the glyph row. */
25915 if (r1->displays_text_p)
25916 for (; glyph < end
25917 && INTEGERP (glyph->object)
25918 && glyph->charpos < 0;
25919 ++glyph)
25920 x += glyph->pixel_width;
25921
25922 /* Scan the glyph row, looking for BEFORE_STRING, AFTER_STRING,
25923 or COVER_STRING, and the first glyph from buffer whose
25924 position is between START_CHARPOS and END_CHARPOS. */
25925 for (; glyph < end
25926 && !INTEGERP (glyph->object)
25927 && !EQ (glyph->object, cover_string)
25928 && !(BUFFERP (glyph->object)
25929 && (glyph->charpos >= start_charpos
25930 && glyph->charpos < end_charpos));
25931 ++glyph)
25932 {
25933 /* BEFORE_STRING or AFTER_STRING are only relevant if they
25934 are present at buffer positions between START_CHARPOS and
25935 END_CHARPOS, or if they come from an overlay. */
25936 if (EQ (glyph->object, before_string))
25937 {
25938 pos = string_buffer_position (before_string,
25939 start_charpos);
25940 /* If pos == 0, it means before_string came from an
25941 overlay, not from a buffer position. */
25942 if (!pos || (pos >= start_charpos && pos < end_charpos))
25943 break;
25944 }
25945 else if (EQ (glyph->object, after_string))
25946 {
25947 pos = string_buffer_position (after_string, end_charpos);
25948 if (!pos || (pos >= start_charpos && pos < end_charpos))
25949 break;
25950 }
25951 x += glyph->pixel_width;
25952 }
25953 hlinfo->mouse_face_beg_x = x;
25954 hlinfo->mouse_face_beg_col = glyph - r1->glyphs[TEXT_AREA];
25955 }
25956 else
25957 {
25958 /* This row is in a right to left paragraph. Scan it right to
25959 left. */
25960 struct glyph *g;
25961
25962 end = r1->glyphs[TEXT_AREA] - 1;
25963 glyph = end + r1->used[TEXT_AREA];
25964
25965 /* Skip truncation glyphs at the start of the glyph row. */
25966 if (r1->displays_text_p)
25967 for (; glyph > end
25968 && INTEGERP (glyph->object)
25969 && glyph->charpos < 0;
25970 --glyph)
25971 ;
25972
25973 /* Scan the glyph row, looking for BEFORE_STRING, AFTER_STRING,
25974 or COVER_STRING, and the first glyph from buffer whose
25975 position is between START_CHARPOS and END_CHARPOS. */
25976 for (; glyph > end
25977 && !INTEGERP (glyph->object)
25978 && !EQ (glyph->object, cover_string)
25979 && !(BUFFERP (glyph->object)
25980 && (glyph->charpos >= start_charpos
25981 && glyph->charpos < end_charpos));
25982 --glyph)
25983 {
25984 /* BEFORE_STRING or AFTER_STRING are only relevant if they
25985 are present at buffer positions between START_CHARPOS and
25986 END_CHARPOS, or if they come from an overlay. */
25987 if (EQ (glyph->object, before_string))
25988 {
25989 pos = string_buffer_position (before_string, start_charpos);
25990 /* If pos == 0, it means before_string came from an
25991 overlay, not from a buffer position. */
25992 if (!pos || (pos >= start_charpos && pos < end_charpos))
25993 break;
25994 }
25995 else if (EQ (glyph->object, after_string))
25996 {
25997 pos = string_buffer_position (after_string, end_charpos);
25998 if (!pos || (pos >= start_charpos && pos < end_charpos))
25999 break;
26000 }
26001 }
26002
26003 glyph++; /* first glyph to the right of the highlighted area */
26004 for (g = r1->glyphs[TEXT_AREA], x = r1->x; g < glyph; g++)
26005 x += g->pixel_width;
26006 hlinfo->mouse_face_beg_x = x;
26007 hlinfo->mouse_face_beg_col = glyph - r1->glyphs[TEXT_AREA];
26008 }
26009
26010 /* If the highlight ends in a different row, compute GLYPH and END
26011 for the end row. Otherwise, reuse the values computed above for
26012 the row where the highlight begins. */
26013 if (r2 != r1)
26014 {
26015 if (!r2->reversed_p)
26016 {
26017 glyph = r2->glyphs[TEXT_AREA];
26018 end = glyph + r2->used[TEXT_AREA];
26019 x = r2->x;
26020 }
26021 else
26022 {
26023 end = r2->glyphs[TEXT_AREA] - 1;
26024 glyph = end + r2->used[TEXT_AREA];
26025 }
26026 }
26027
26028 if (!r2->reversed_p)
26029 {
26030 /* Skip truncation and continuation glyphs near the end of the
26031 row, and also blanks and stretch glyphs inserted by
26032 extend_face_to_end_of_line. */
26033 while (end > glyph
26034 && INTEGERP ((end - 1)->object)
26035 && (end - 1)->charpos <= 0)
26036 --end;
26037 /* Scan the rest of the glyph row from the end, looking for the
26038 first glyph that comes from BEFORE_STRING, AFTER_STRING, or
26039 COVER_STRING, or whose position is between START_CHARPOS
26040 and END_CHARPOS */
26041 for (--end;
26042 end > glyph
26043 && !INTEGERP (end->object)
26044 && !EQ (end->object, cover_string)
26045 && !(BUFFERP (end->object)
26046 && (end->charpos >= start_charpos
26047 && end->charpos < end_charpos));
26048 --end)
26049 {
26050 /* BEFORE_STRING or AFTER_STRING are only relevant if they
26051 are present at buffer positions between START_CHARPOS and
26052 END_CHARPOS, or if they come from an overlay. */
26053 if (EQ (end->object, before_string))
26054 {
26055 pos = string_buffer_position (before_string, start_charpos);
26056 if (!pos || (pos >= start_charpos && pos < end_charpos))
26057 break;
26058 }
26059 else if (EQ (end->object, after_string))
26060 {
26061 pos = string_buffer_position (after_string, end_charpos);
26062 if (!pos || (pos >= start_charpos && pos < end_charpos))
26063 break;
26064 }
26065 }
26066 /* Find the X coordinate of the last glyph to be highlighted. */
26067 for (; glyph <= end; ++glyph)
26068 x += glyph->pixel_width;
26069
26070 hlinfo->mouse_face_end_x = x;
26071 hlinfo->mouse_face_end_col = glyph - r2->glyphs[TEXT_AREA];
26072 }
26073 else
26074 {
26075 /* Skip truncation and continuation glyphs near the end of the
26076 row, and also blanks and stretch glyphs inserted by
26077 extend_face_to_end_of_line. */
26078 x = r2->x;
26079 end++;
26080 while (end < glyph
26081 && INTEGERP (end->object)
26082 && end->charpos <= 0)
26083 {
26084 x += end->pixel_width;
26085 ++end;
26086 }
26087 /* Scan the rest of the glyph row from the end, looking for the
26088 first glyph that comes from BEFORE_STRING, AFTER_STRING, or
26089 COVER_STRING, or whose position is between START_CHARPOS
26090 and END_CHARPOS */
26091 for ( ;
26092 end < glyph
26093 && !INTEGERP (end->object)
26094 && !EQ (end->object, cover_string)
26095 && !(BUFFERP (end->object)
26096 && (end->charpos >= start_charpos
26097 && end->charpos < end_charpos));
26098 ++end)
26099 {
26100 /* BEFORE_STRING or AFTER_STRING are only relevant if they
26101 are present at buffer positions between START_CHARPOS and
26102 END_CHARPOS, or if they come from an overlay. */
26103 if (EQ (end->object, before_string))
26104 {
26105 pos = string_buffer_position (before_string, start_charpos);
26106 if (!pos || (pos >= start_charpos && pos < end_charpos))
26107 break;
26108 }
26109 else if (EQ (end->object, after_string))
26110 {
26111 pos = string_buffer_position (after_string, end_charpos);
26112 if (!pos || (pos >= start_charpos && pos < end_charpos))
26113 break;
26114 }
26115 x += end->pixel_width;
26116 }
26117 hlinfo->mouse_face_end_x = x;
26118 hlinfo->mouse_face_end_col = end - r2->glyphs[TEXT_AREA];
26119 }
26120
26121 hlinfo->mouse_face_window = window;
26122 hlinfo->mouse_face_face_id
26123 = face_at_buffer_position (w, mouse_charpos, 0, 0, &ignore,
26124 mouse_charpos + 1,
26125 !hlinfo->mouse_face_hidden, -1);
26126 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
26127 }
26128
26129 /* The following function is not used anymore (replaced with
26130 mouse_face_from_string_pos), but I leave it here for the time
26131 being, in case someone would. */
26132
26133 #if 0 /* not used */
26134
26135 /* Find the position of the glyph for position POS in OBJECT in
26136 window W's current matrix, and return in *X, *Y the pixel
26137 coordinates, and return in *HPOS, *VPOS the column/row of the glyph.
26138
26139 RIGHT_P non-zero means return the position of the right edge of the
26140 glyph, RIGHT_P zero means return the left edge position.
26141
26142 If no glyph for POS exists in the matrix, return the position of
26143 the glyph with the next smaller position that is in the matrix, if
26144 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS
26145 exists in the matrix, return the position of the glyph with the
26146 next larger position in OBJECT.
26147
26148 Value is non-zero if a glyph was found. */
26149
26150 static int
26151 fast_find_string_pos (struct window *w, EMACS_INT pos, Lisp_Object object,
26152 int *hpos, int *vpos, int *x, int *y, int right_p)
26153 {
26154 int yb = window_text_bottom_y (w);
26155 struct glyph_row *r;
26156 struct glyph *best_glyph = NULL;
26157 struct glyph_row *best_row = NULL;
26158 int best_x = 0;
26159
26160 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
26161 r->enabled_p && r->y < yb;
26162 ++r)
26163 {
26164 struct glyph *g = r->glyphs[TEXT_AREA];
26165 struct glyph *e = g + r->used[TEXT_AREA];
26166 int gx;
26167
26168 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
26169 if (EQ (g->object, object))
26170 {
26171 if (g->charpos == pos)
26172 {
26173 best_glyph = g;
26174 best_x = gx;
26175 best_row = r;
26176 goto found;
26177 }
26178 else if (best_glyph == NULL
26179 || ((eabs (g->charpos - pos)
26180 < eabs (best_glyph->charpos - pos))
26181 && (right_p
26182 ? g->charpos < pos
26183 : g->charpos > pos)))
26184 {
26185 best_glyph = g;
26186 best_x = gx;
26187 best_row = r;
26188 }
26189 }
26190 }
26191
26192 found:
26193
26194 if (best_glyph)
26195 {
26196 *x = best_x;
26197 *hpos = best_glyph - best_row->glyphs[TEXT_AREA];
26198
26199 if (right_p)
26200 {
26201 *x += best_glyph->pixel_width;
26202 ++*hpos;
26203 }
26204
26205 *y = best_row->y;
26206 *vpos = best_row - w->current_matrix->rows;
26207 }
26208
26209 return best_glyph != NULL;
26210 }
26211 #endif /* not used */
26212
26213 /* Find the positions of the first and the last glyphs in window W's
26214 current matrix that occlude positions [STARTPOS..ENDPOS] in OBJECT
26215 (assumed to be a string), and return in HLINFO's mouse_face_*
26216 members the pixel and column/row coordinates of those glyphs. */
26217
26218 static void
26219 mouse_face_from_string_pos (struct window *w, Mouse_HLInfo *hlinfo,
26220 Lisp_Object object,
26221 EMACS_INT startpos, EMACS_INT endpos)
26222 {
26223 int yb = window_text_bottom_y (w);
26224 struct glyph_row *r;
26225 struct glyph *g, *e;
26226 int gx;
26227 int found = 0;
26228
26229 /* Find the glyph row with at least one position in the range
26230 [STARTPOS..ENDPOS], and the first glyph in that row whose
26231 position belongs to that range. */
26232 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
26233 r->enabled_p && r->y < yb;
26234 ++r)
26235 {
26236 if (!r->reversed_p)
26237 {
26238 g = r->glyphs[TEXT_AREA];
26239 e = g + r->used[TEXT_AREA];
26240 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
26241 if (EQ (g->object, object)
26242 && startpos <= g->charpos && g->charpos <= endpos)
26243 {
26244 hlinfo->mouse_face_beg_row = r - w->current_matrix->rows;
26245 hlinfo->mouse_face_beg_y = r->y;
26246 hlinfo->mouse_face_beg_col = g - r->glyphs[TEXT_AREA];
26247 hlinfo->mouse_face_beg_x = gx;
26248 found = 1;
26249 break;
26250 }
26251 }
26252 else
26253 {
26254 struct glyph *g1;
26255
26256 e = r->glyphs[TEXT_AREA];
26257 g = e + r->used[TEXT_AREA];
26258 for ( ; g > e; --g)
26259 if (EQ ((g-1)->object, object)
26260 && startpos <= (g-1)->charpos && (g-1)->charpos <= endpos)
26261 {
26262 hlinfo->mouse_face_beg_row = r - w->current_matrix->rows;
26263 hlinfo->mouse_face_beg_y = r->y;
26264 hlinfo->mouse_face_beg_col = g - r->glyphs[TEXT_AREA];
26265 for (gx = r->x, g1 = r->glyphs[TEXT_AREA]; g1 < g; ++g1)
26266 gx += g1->pixel_width;
26267 hlinfo->mouse_face_beg_x = gx;
26268 found = 1;
26269 break;
26270 }
26271 }
26272 if (found)
26273 break;
26274 }
26275
26276 if (!found)
26277 return;
26278
26279 /* Starting with the next row, look for the first row which does NOT
26280 include any glyphs whose positions are in the range. */
26281 for (++r; r->enabled_p && r->y < yb; ++r)
26282 {
26283 g = r->glyphs[TEXT_AREA];
26284 e = g + r->used[TEXT_AREA];
26285 found = 0;
26286 for ( ; g < e; ++g)
26287 if (EQ (g->object, object)
26288 && startpos <= g->charpos && g->charpos <= endpos)
26289 {
26290 found = 1;
26291 break;
26292 }
26293 if (!found)
26294 break;
26295 }
26296
26297 /* The highlighted region ends on the previous row. */
26298 r--;
26299
26300 /* Set the end row and its vertical pixel coordinate. */
26301 hlinfo->mouse_face_end_row = r - w->current_matrix->rows;
26302 hlinfo->mouse_face_end_y = r->y;
26303
26304 /* Compute and set the end column and the end column's horizontal
26305 pixel coordinate. */
26306 if (!r->reversed_p)
26307 {
26308 g = r->glyphs[TEXT_AREA];
26309 e = g + r->used[TEXT_AREA];
26310 for ( ; e > g; --e)
26311 if (EQ ((e-1)->object, object)
26312 && startpos <= (e-1)->charpos && (e-1)->charpos <= endpos)
26313 break;
26314 hlinfo->mouse_face_end_col = e - g;
26315
26316 for (gx = r->x; g < e; ++g)
26317 gx += g->pixel_width;
26318 hlinfo->mouse_face_end_x = gx;
26319 }
26320 else
26321 {
26322 e = r->glyphs[TEXT_AREA];
26323 g = e + r->used[TEXT_AREA];
26324 for (gx = r->x ; e < g; ++e)
26325 {
26326 if (EQ (e->object, object)
26327 && startpos <= e->charpos && e->charpos <= endpos)
26328 break;
26329 gx += e->pixel_width;
26330 }
26331 hlinfo->mouse_face_end_col = e - r->glyphs[TEXT_AREA];
26332 hlinfo->mouse_face_end_x = gx;
26333 }
26334 }
26335
26336 #ifdef HAVE_WINDOW_SYSTEM
26337
26338 /* See if position X, Y is within a hot-spot of an image. */
26339
26340 static int
26341 on_hot_spot_p (Lisp_Object hot_spot, int x, int y)
26342 {
26343 if (!CONSP (hot_spot))
26344 return 0;
26345
26346 if (EQ (XCAR (hot_spot), Qrect))
26347 {
26348 /* CDR is (Top-Left . Bottom-Right) = ((x0 . y0) . (x1 . y1)) */
26349 Lisp_Object rect = XCDR (hot_spot);
26350 Lisp_Object tem;
26351 if (!CONSP (rect))
26352 return 0;
26353 if (!CONSP (XCAR (rect)))
26354 return 0;
26355 if (!CONSP (XCDR (rect)))
26356 return 0;
26357 if (!(tem = XCAR (XCAR (rect)), INTEGERP (tem) && x >= XINT (tem)))
26358 return 0;
26359 if (!(tem = XCDR (XCAR (rect)), INTEGERP (tem) && y >= XINT (tem)))
26360 return 0;
26361 if (!(tem = XCAR (XCDR (rect)), INTEGERP (tem) && x <= XINT (tem)))
26362 return 0;
26363 if (!(tem = XCDR (XCDR (rect)), INTEGERP (tem) && y <= XINT (tem)))
26364 return 0;
26365 return 1;
26366 }
26367 else if (EQ (XCAR (hot_spot), Qcircle))
26368 {
26369 /* CDR is (Center . Radius) = ((x0 . y0) . r) */
26370 Lisp_Object circ = XCDR (hot_spot);
26371 Lisp_Object lr, lx0, ly0;
26372 if (CONSP (circ)
26373 && CONSP (XCAR (circ))
26374 && (lr = XCDR (circ), INTEGERP (lr) || FLOATP (lr))
26375 && (lx0 = XCAR (XCAR (circ)), INTEGERP (lx0))
26376 && (ly0 = XCDR (XCAR (circ)), INTEGERP (ly0)))
26377 {
26378 double r = XFLOATINT (lr);
26379 double dx = XINT (lx0) - x;
26380 double dy = XINT (ly0) - y;
26381 return (dx * dx + dy * dy <= r * r);
26382 }
26383 }
26384 else if (EQ (XCAR (hot_spot), Qpoly))
26385 {
26386 /* CDR is [x0 y0 x1 y1 x2 y2 ...x(n-1) y(n-1)] */
26387 if (VECTORP (XCDR (hot_spot)))
26388 {
26389 struct Lisp_Vector *v = XVECTOR (XCDR (hot_spot));
26390 Lisp_Object *poly = v->contents;
26391 int n = v->header.size;
26392 int i;
26393 int inside = 0;
26394 Lisp_Object lx, ly;
26395 int x0, y0;
26396
26397 /* Need an even number of coordinates, and at least 3 edges. */
26398 if (n < 6 || n & 1)
26399 return 0;
26400
26401 /* Count edge segments intersecting line from (X,Y) to (X,infinity).
26402 If count is odd, we are inside polygon. Pixels on edges
26403 may or may not be included depending on actual geometry of the
26404 polygon. */
26405 if ((lx = poly[n-2], !INTEGERP (lx))
26406 || (ly = poly[n-1], !INTEGERP (lx)))
26407 return 0;
26408 x0 = XINT (lx), y0 = XINT (ly);
26409 for (i = 0; i < n; i += 2)
26410 {
26411 int x1 = x0, y1 = y0;
26412 if ((lx = poly[i], !INTEGERP (lx))
26413 || (ly = poly[i+1], !INTEGERP (ly)))
26414 return 0;
26415 x0 = XINT (lx), y0 = XINT (ly);
26416
26417 /* Does this segment cross the X line? */
26418 if (x0 >= x)
26419 {
26420 if (x1 >= x)
26421 continue;
26422 }
26423 else if (x1 < x)
26424 continue;
26425 if (y > y0 && y > y1)
26426 continue;
26427 if (y < y0 + ((y1 - y0) * (x - x0)) / (x1 - x0))
26428 inside = !inside;
26429 }
26430 return inside;
26431 }
26432 }
26433 return 0;
26434 }
26435
26436 Lisp_Object
26437 find_hot_spot (Lisp_Object map, int x, int y)
26438 {
26439 while (CONSP (map))
26440 {
26441 if (CONSP (XCAR (map))
26442 && on_hot_spot_p (XCAR (XCAR (map)), x, y))
26443 return XCAR (map);
26444 map = XCDR (map);
26445 }
26446
26447 return Qnil;
26448 }
26449
26450 DEFUN ("lookup-image-map", Flookup_image_map, Slookup_image_map,
26451 3, 3, 0,
26452 doc: /* Lookup in image map MAP coordinates X and Y.
26453 An image map is an alist where each element has the format (AREA ID PLIST).
26454 An AREA is specified as either a rectangle, a circle, or a polygon:
26455 A rectangle is a cons (rect . ((x0 . y0) . (x1 . y1))) specifying the
26456 pixel coordinates of the upper left and bottom right corners.
26457 A circle is a cons (circle . ((x0 . y0) . r)) specifying the center
26458 and the radius of the circle; r may be a float or integer.
26459 A polygon is a cons (poly . [x0 y0 x1 y1 ...]) where each pair in the
26460 vector describes one corner in the polygon.
26461 Returns the alist element for the first matching AREA in MAP. */)
26462 (Lisp_Object map, Lisp_Object x, Lisp_Object y)
26463 {
26464 if (NILP (map))
26465 return Qnil;
26466
26467 CHECK_NUMBER (x);
26468 CHECK_NUMBER (y);
26469
26470 return find_hot_spot (map, XINT (x), XINT (y));
26471 }
26472
26473
26474 /* Display frame CURSOR, optionally using shape defined by POINTER. */
26475 static void
26476 define_frame_cursor1 (struct frame *f, Cursor cursor, Lisp_Object pointer)
26477 {
26478 /* Do not change cursor shape while dragging mouse. */
26479 if (!NILP (do_mouse_tracking))
26480 return;
26481
26482 if (!NILP (pointer))
26483 {
26484 if (EQ (pointer, Qarrow))
26485 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
26486 else if (EQ (pointer, Qhand))
26487 cursor = FRAME_X_OUTPUT (f)->hand_cursor;
26488 else if (EQ (pointer, Qtext))
26489 cursor = FRAME_X_OUTPUT (f)->text_cursor;
26490 else if (EQ (pointer, intern ("hdrag")))
26491 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
26492 #ifdef HAVE_X_WINDOWS
26493 else if (EQ (pointer, intern ("vdrag")))
26494 cursor = FRAME_X_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
26495 #endif
26496 else if (EQ (pointer, intern ("hourglass")))
26497 cursor = FRAME_X_OUTPUT (f)->hourglass_cursor;
26498 else if (EQ (pointer, Qmodeline))
26499 cursor = FRAME_X_OUTPUT (f)->modeline_cursor;
26500 else
26501 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
26502 }
26503
26504 if (cursor != No_Cursor)
26505 FRAME_RIF (f)->define_frame_cursor (f, cursor);
26506 }
26507
26508 #endif /* HAVE_WINDOW_SYSTEM */
26509
26510 /* Take proper action when mouse has moved to the mode or header line
26511 or marginal area AREA of window W, x-position X and y-position Y.
26512 X is relative to the start of the text display area of W, so the
26513 width of bitmap areas and scroll bars must be subtracted to get a
26514 position relative to the start of the mode line. */
26515
26516 static void
26517 note_mode_line_or_margin_highlight (Lisp_Object window, int x, int y,
26518 enum window_part area)
26519 {
26520 struct window *w = XWINDOW (window);
26521 struct frame *f = XFRAME (w->frame);
26522 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
26523 #ifdef HAVE_WINDOW_SYSTEM
26524 Display_Info *dpyinfo;
26525 #endif
26526 Cursor cursor = No_Cursor;
26527 Lisp_Object pointer = Qnil;
26528 int dx, dy, width, height;
26529 EMACS_INT charpos;
26530 Lisp_Object string, object = Qnil;
26531 Lisp_Object pos, help;
26532
26533 Lisp_Object mouse_face;
26534 int original_x_pixel = x;
26535 struct glyph * glyph = NULL, * row_start_glyph = NULL;
26536 struct glyph_row *row;
26537
26538 if (area == ON_MODE_LINE || area == ON_HEADER_LINE)
26539 {
26540 int x0;
26541 struct glyph *end;
26542
26543 /* Kludge alert: mode_line_string takes X/Y in pixels, but
26544 returns them in row/column units! */
26545 string = mode_line_string (w, area, &x, &y, &charpos,
26546 &object, &dx, &dy, &width, &height);
26547
26548 row = (area == ON_MODE_LINE
26549 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
26550 : MATRIX_HEADER_LINE_ROW (w->current_matrix));
26551
26552 /* Find the glyph under the mouse pointer. */
26553 if (row->mode_line_p && row->enabled_p)
26554 {
26555 glyph = row_start_glyph = row->glyphs[TEXT_AREA];
26556 end = glyph + row->used[TEXT_AREA];
26557
26558 for (x0 = original_x_pixel;
26559 glyph < end && x0 >= glyph->pixel_width;
26560 ++glyph)
26561 x0 -= glyph->pixel_width;
26562
26563 if (glyph >= end)
26564 glyph = NULL;
26565 }
26566 }
26567 else
26568 {
26569 x -= WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
26570 /* Kludge alert: marginal_area_string takes X/Y in pixels, but
26571 returns them in row/column units! */
26572 string = marginal_area_string (w, area, &x, &y, &charpos,
26573 &object, &dx, &dy, &width, &height);
26574 }
26575
26576 help = Qnil;
26577
26578 #ifdef HAVE_WINDOW_SYSTEM
26579 if (IMAGEP (object))
26580 {
26581 Lisp_Object image_map, hotspot;
26582 if ((image_map = Fplist_get (XCDR (object), QCmap),
26583 !NILP (image_map))
26584 && (hotspot = find_hot_spot (image_map, dx, dy),
26585 CONSP (hotspot))
26586 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
26587 {
26588 Lisp_Object plist;
26589
26590 /* Could check XCAR (hotspot) to see if we enter/leave this hot-spot.
26591 If so, we could look for mouse-enter, mouse-leave
26592 properties in PLIST (and do something...). */
26593 hotspot = XCDR (hotspot);
26594 if (CONSP (hotspot)
26595 && (plist = XCAR (hotspot), CONSP (plist)))
26596 {
26597 pointer = Fplist_get (plist, Qpointer);
26598 if (NILP (pointer))
26599 pointer = Qhand;
26600 help = Fplist_get (plist, Qhelp_echo);
26601 if (!NILP (help))
26602 {
26603 help_echo_string = help;
26604 /* Is this correct? ++kfs */
26605 XSETWINDOW (help_echo_window, w);
26606 help_echo_object = w->buffer;
26607 help_echo_pos = charpos;
26608 }
26609 }
26610 }
26611 if (NILP (pointer))
26612 pointer = Fplist_get (XCDR (object), QCpointer);
26613 }
26614 #endif /* HAVE_WINDOW_SYSTEM */
26615
26616 if (STRINGP (string))
26617 {
26618 pos = make_number (charpos);
26619 /* If we're on a string with `help-echo' text property, arrange
26620 for the help to be displayed. This is done by setting the
26621 global variable help_echo_string to the help string. */
26622 if (NILP (help))
26623 {
26624 help = Fget_text_property (pos, Qhelp_echo, string);
26625 if (!NILP (help))
26626 {
26627 help_echo_string = help;
26628 XSETWINDOW (help_echo_window, w);
26629 help_echo_object = string;
26630 help_echo_pos = charpos;
26631 }
26632 }
26633
26634 #ifdef HAVE_WINDOW_SYSTEM
26635 if (FRAME_WINDOW_P (f))
26636 {
26637 dpyinfo = FRAME_X_DISPLAY_INFO (f);
26638 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
26639 if (NILP (pointer))
26640 pointer = Fget_text_property (pos, Qpointer, string);
26641
26642 /* Change the mouse pointer according to what is under X/Y. */
26643 if (NILP (pointer)
26644 && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE)))
26645 {
26646 Lisp_Object map;
26647 map = Fget_text_property (pos, Qlocal_map, string);
26648 if (!KEYMAPP (map))
26649 map = Fget_text_property (pos, Qkeymap, string);
26650 if (!KEYMAPP (map))
26651 cursor = dpyinfo->vertical_scroll_bar_cursor;
26652 }
26653 }
26654 #endif
26655
26656 /* Change the mouse face according to what is under X/Y. */
26657 mouse_face = Fget_text_property (pos, Qmouse_face, string);
26658 if (!NILP (mouse_face)
26659 && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE))
26660 && glyph)
26661 {
26662 Lisp_Object b, e;
26663
26664 struct glyph * tmp_glyph;
26665
26666 int gpos;
26667 int gseq_length;
26668 int total_pixel_width;
26669 EMACS_INT begpos, endpos, ignore;
26670
26671 int vpos, hpos;
26672
26673 b = Fprevious_single_property_change (make_number (charpos + 1),
26674 Qmouse_face, string, Qnil);
26675 if (NILP (b))
26676 begpos = 0;
26677 else
26678 begpos = XINT (b);
26679
26680 e = Fnext_single_property_change (pos, Qmouse_face, string, Qnil);
26681 if (NILP (e))
26682 endpos = SCHARS (string);
26683 else
26684 endpos = XINT (e);
26685
26686 /* Calculate the glyph position GPOS of GLYPH in the
26687 displayed string, relative to the beginning of the
26688 highlighted part of the string.
26689
26690 Note: GPOS is different from CHARPOS. CHARPOS is the
26691 position of GLYPH in the internal string object. A mode
26692 line string format has structures which are converted to
26693 a flattened string by the Emacs Lisp interpreter. The
26694 internal string is an element of those structures. The
26695 displayed string is the flattened string. */
26696 tmp_glyph = row_start_glyph;
26697 while (tmp_glyph < glyph
26698 && (!(EQ (tmp_glyph->object, glyph->object)
26699 && begpos <= tmp_glyph->charpos
26700 && tmp_glyph->charpos < endpos)))
26701 tmp_glyph++;
26702 gpos = glyph - tmp_glyph;
26703
26704 /* Calculate the length GSEQ_LENGTH of the glyph sequence of
26705 the highlighted part of the displayed string to which
26706 GLYPH belongs. Note: GSEQ_LENGTH is different from
26707 SCHARS (STRING), because the latter returns the length of
26708 the internal string. */
26709 for (tmp_glyph = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
26710 tmp_glyph > glyph
26711 && (!(EQ (tmp_glyph->object, glyph->object)
26712 && begpos <= tmp_glyph->charpos
26713 && tmp_glyph->charpos < endpos));
26714 tmp_glyph--)
26715 ;
26716 gseq_length = gpos + (tmp_glyph - glyph) + 1;
26717
26718 /* Calculate the total pixel width of all the glyphs between
26719 the beginning of the highlighted area and GLYPH. */
26720 total_pixel_width = 0;
26721 for (tmp_glyph = glyph - gpos; tmp_glyph != glyph; tmp_glyph++)
26722 total_pixel_width += tmp_glyph->pixel_width;
26723
26724 /* Pre calculation of re-rendering position. Note: X is in
26725 column units here, after the call to mode_line_string or
26726 marginal_area_string. */
26727 hpos = x - gpos;
26728 vpos = (area == ON_MODE_LINE
26729 ? (w->current_matrix)->nrows - 1
26730 : 0);
26731
26732 /* If GLYPH's position is included in the region that is
26733 already drawn in mouse face, we have nothing to do. */
26734 if ( EQ (window, hlinfo->mouse_face_window)
26735 && (!row->reversed_p
26736 ? (hlinfo->mouse_face_beg_col <= hpos
26737 && hpos < hlinfo->mouse_face_end_col)
26738 /* In R2L rows we swap BEG and END, see below. */
26739 : (hlinfo->mouse_face_end_col <= hpos
26740 && hpos < hlinfo->mouse_face_beg_col))
26741 && hlinfo->mouse_face_beg_row == vpos )
26742 return;
26743
26744 if (clear_mouse_face (hlinfo))
26745 cursor = No_Cursor;
26746
26747 if (!row->reversed_p)
26748 {
26749 hlinfo->mouse_face_beg_col = hpos;
26750 hlinfo->mouse_face_beg_x = original_x_pixel
26751 - (total_pixel_width + dx);
26752 hlinfo->mouse_face_end_col = hpos + gseq_length;
26753 hlinfo->mouse_face_end_x = 0;
26754 }
26755 else
26756 {
26757 /* In R2L rows, show_mouse_face expects BEG and END
26758 coordinates to be swapped. */
26759 hlinfo->mouse_face_end_col = hpos;
26760 hlinfo->mouse_face_end_x = original_x_pixel
26761 - (total_pixel_width + dx);
26762 hlinfo->mouse_face_beg_col = hpos + gseq_length;
26763 hlinfo->mouse_face_beg_x = 0;
26764 }
26765
26766 hlinfo->mouse_face_beg_row = vpos;
26767 hlinfo->mouse_face_end_row = hlinfo->mouse_face_beg_row;
26768 hlinfo->mouse_face_beg_y = 0;
26769 hlinfo->mouse_face_end_y = 0;
26770 hlinfo->mouse_face_past_end = 0;
26771 hlinfo->mouse_face_window = window;
26772
26773 hlinfo->mouse_face_face_id = face_at_string_position (w, string,
26774 charpos,
26775 0, 0, 0,
26776 &ignore,
26777 glyph->face_id,
26778 1);
26779 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
26780
26781 if (NILP (pointer))
26782 pointer = Qhand;
26783 }
26784 else if ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE))
26785 clear_mouse_face (hlinfo);
26786 }
26787 #ifdef HAVE_WINDOW_SYSTEM
26788 if (FRAME_WINDOW_P (f))
26789 define_frame_cursor1 (f, cursor, pointer);
26790 #endif
26791 }
26792
26793
26794 /* EXPORT:
26795 Take proper action when the mouse has moved to position X, Y on
26796 frame F as regards highlighting characters that have mouse-face
26797 properties. Also de-highlighting chars where the mouse was before.
26798 X and Y can be negative or out of range. */
26799
26800 void
26801 note_mouse_highlight (struct frame *f, int x, int y)
26802 {
26803 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
26804 enum window_part part;
26805 Lisp_Object window;
26806 struct window *w;
26807 Cursor cursor = No_Cursor;
26808 Lisp_Object pointer = Qnil; /* Takes precedence over cursor! */
26809 struct buffer *b;
26810
26811 /* When a menu is active, don't highlight because this looks odd. */
26812 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS) || defined (MSDOS)
26813 if (popup_activated ())
26814 return;
26815 #endif
26816
26817 if (NILP (Vmouse_highlight)
26818 || !f->glyphs_initialized_p
26819 || f->pointer_invisible)
26820 return;
26821
26822 hlinfo->mouse_face_mouse_x = x;
26823 hlinfo->mouse_face_mouse_y = y;
26824 hlinfo->mouse_face_mouse_frame = f;
26825
26826 if (hlinfo->mouse_face_defer)
26827 return;
26828
26829 if (gc_in_progress)
26830 {
26831 hlinfo->mouse_face_deferred_gc = 1;
26832 return;
26833 }
26834
26835 /* Which window is that in? */
26836 window = window_from_coordinates (f, x, y, &part, 1);
26837
26838 /* If we were displaying active text in another window, clear that.
26839 Also clear if we move out of text area in same window. */
26840 if (! EQ (window, hlinfo->mouse_face_window)
26841 || (part != ON_TEXT && part != ON_MODE_LINE && part != ON_HEADER_LINE
26842 && !NILP (hlinfo->mouse_face_window)))
26843 clear_mouse_face (hlinfo);
26844
26845 /* Not on a window -> return. */
26846 if (!WINDOWP (window))
26847 return;
26848
26849 /* Reset help_echo_string. It will get recomputed below. */
26850 help_echo_string = Qnil;
26851
26852 /* Convert to window-relative pixel coordinates. */
26853 w = XWINDOW (window);
26854 frame_to_window_pixel_xy (w, &x, &y);
26855
26856 #ifdef HAVE_WINDOW_SYSTEM
26857 /* Handle tool-bar window differently since it doesn't display a
26858 buffer. */
26859 if (EQ (window, f->tool_bar_window))
26860 {
26861 note_tool_bar_highlight (f, x, y);
26862 return;
26863 }
26864 #endif
26865
26866 /* Mouse is on the mode, header line or margin? */
26867 if (part == ON_MODE_LINE || part == ON_HEADER_LINE
26868 || part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
26869 {
26870 note_mode_line_or_margin_highlight (window, x, y, part);
26871 return;
26872 }
26873
26874 #ifdef HAVE_WINDOW_SYSTEM
26875 if (part == ON_VERTICAL_BORDER)
26876 {
26877 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
26878 help_echo_string = build_string ("drag-mouse-1: resize");
26879 }
26880 else if (part == ON_LEFT_FRINGE || part == ON_RIGHT_FRINGE
26881 || part == ON_SCROLL_BAR)
26882 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
26883 else
26884 cursor = FRAME_X_OUTPUT (f)->text_cursor;
26885 #endif
26886
26887 /* Are we in a window whose display is up to date?
26888 And verify the buffer's text has not changed. */
26889 b = XBUFFER (w->buffer);
26890 if (part == ON_TEXT
26891 && EQ (w->window_end_valid, w->buffer)
26892 && XFASTINT (w->last_modified) == BUF_MODIFF (b)
26893 && XFASTINT (w->last_overlay_modified) == BUF_OVERLAY_MODIFF (b))
26894 {
26895 int hpos, vpos, dx, dy, area;
26896 EMACS_INT pos;
26897 struct glyph *glyph;
26898 Lisp_Object object;
26899 Lisp_Object mouse_face = Qnil, position;
26900 Lisp_Object *overlay_vec = NULL;
26901 ptrdiff_t i, noverlays;
26902 struct buffer *obuf;
26903 EMACS_INT obegv, ozv;
26904 int same_region;
26905
26906 /* Find the glyph under X/Y. */
26907 glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, &dx, &dy, &area);
26908
26909 #ifdef HAVE_WINDOW_SYSTEM
26910 /* Look for :pointer property on image. */
26911 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
26912 {
26913 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
26914 if (img != NULL && IMAGEP (img->spec))
26915 {
26916 Lisp_Object image_map, hotspot;
26917 if ((image_map = Fplist_get (XCDR (img->spec), QCmap),
26918 !NILP (image_map))
26919 && (hotspot = find_hot_spot (image_map,
26920 glyph->slice.img.x + dx,
26921 glyph->slice.img.y + dy),
26922 CONSP (hotspot))
26923 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
26924 {
26925 Lisp_Object plist;
26926
26927 /* Could check XCAR (hotspot) to see if we enter/leave
26928 this hot-spot.
26929 If so, we could look for mouse-enter, mouse-leave
26930 properties in PLIST (and do something...). */
26931 hotspot = XCDR (hotspot);
26932 if (CONSP (hotspot)
26933 && (plist = XCAR (hotspot), CONSP (plist)))
26934 {
26935 pointer = Fplist_get (plist, Qpointer);
26936 if (NILP (pointer))
26937 pointer = Qhand;
26938 help_echo_string = Fplist_get (plist, Qhelp_echo);
26939 if (!NILP (help_echo_string))
26940 {
26941 help_echo_window = window;
26942 help_echo_object = glyph->object;
26943 help_echo_pos = glyph->charpos;
26944 }
26945 }
26946 }
26947 if (NILP (pointer))
26948 pointer = Fplist_get (XCDR (img->spec), QCpointer);
26949 }
26950 }
26951 #endif /* HAVE_WINDOW_SYSTEM */
26952
26953 /* Clear mouse face if X/Y not over text. */
26954 if (glyph == NULL
26955 || area != TEXT_AREA
26956 || !MATRIX_ROW (w->current_matrix, vpos)->displays_text_p
26957 /* Glyph's OBJECT is an integer for glyphs inserted by the
26958 display engine for its internal purposes, like truncation
26959 and continuation glyphs and blanks beyond the end of
26960 line's text on text terminals. If we are over such a
26961 glyph, we are not over any text. */
26962 || INTEGERP (glyph->object)
26963 /* R2L rows have a stretch glyph at their front, which
26964 stands for no text, whereas L2R rows have no glyphs at
26965 all beyond the end of text. Treat such stretch glyphs
26966 like we do with NULL glyphs in L2R rows. */
26967 || (MATRIX_ROW (w->current_matrix, vpos)->reversed_p
26968 && glyph == MATRIX_ROW (w->current_matrix, vpos)->glyphs[TEXT_AREA]
26969 && glyph->type == STRETCH_GLYPH
26970 && glyph->avoid_cursor_p))
26971 {
26972 if (clear_mouse_face (hlinfo))
26973 cursor = No_Cursor;
26974 #ifdef HAVE_WINDOW_SYSTEM
26975 if (FRAME_WINDOW_P (f) && NILP (pointer))
26976 {
26977 if (area != TEXT_AREA)
26978 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
26979 else
26980 pointer = Vvoid_text_area_pointer;
26981 }
26982 #endif
26983 goto set_cursor;
26984 }
26985
26986 pos = glyph->charpos;
26987 object = glyph->object;
26988 if (!STRINGP (object) && !BUFFERP (object))
26989 goto set_cursor;
26990
26991 /* If we get an out-of-range value, return now; avoid an error. */
26992 if (BUFFERP (object) && pos > BUF_Z (b))
26993 goto set_cursor;
26994
26995 /* Make the window's buffer temporarily current for
26996 overlays_at and compute_char_face. */
26997 obuf = current_buffer;
26998 current_buffer = b;
26999 obegv = BEGV;
27000 ozv = ZV;
27001 BEGV = BEG;
27002 ZV = Z;
27003
27004 /* Is this char mouse-active or does it have help-echo? */
27005 position = make_number (pos);
27006
27007 if (BUFFERP (object))
27008 {
27009 /* Put all the overlays we want in a vector in overlay_vec. */
27010 GET_OVERLAYS_AT (pos, overlay_vec, noverlays, NULL, 0);
27011 /* Sort overlays into increasing priority order. */
27012 noverlays = sort_overlays (overlay_vec, noverlays, w);
27013 }
27014 else
27015 noverlays = 0;
27016
27017 same_region = coords_in_mouse_face_p (w, hpos, vpos);
27018
27019 if (same_region)
27020 cursor = No_Cursor;
27021
27022 /* Check mouse-face highlighting. */
27023 if (! same_region
27024 /* If there exists an overlay with mouse-face overlapping
27025 the one we are currently highlighting, we have to
27026 check if we enter the overlapping overlay, and then
27027 highlight only that. */
27028 || (OVERLAYP (hlinfo->mouse_face_overlay)
27029 && mouse_face_overlay_overlaps (hlinfo->mouse_face_overlay)))
27030 {
27031 /* Find the highest priority overlay with a mouse-face. */
27032 Lisp_Object overlay = Qnil;
27033 for (i = noverlays - 1; i >= 0 && NILP (overlay); --i)
27034 {
27035 mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face);
27036 if (!NILP (mouse_face))
27037 overlay = overlay_vec[i];
27038 }
27039
27040 /* If we're highlighting the same overlay as before, there's
27041 no need to do that again. */
27042 if (!NILP (overlay) && EQ (overlay, hlinfo->mouse_face_overlay))
27043 goto check_help_echo;
27044 hlinfo->mouse_face_overlay = overlay;
27045
27046 /* Clear the display of the old active region, if any. */
27047 if (clear_mouse_face (hlinfo))
27048 cursor = No_Cursor;
27049
27050 /* If no overlay applies, get a text property. */
27051 if (NILP (overlay))
27052 mouse_face = Fget_text_property (position, Qmouse_face, object);
27053
27054 /* Next, compute the bounds of the mouse highlighting and
27055 display it. */
27056 if (!NILP (mouse_face) && STRINGP (object))
27057 {
27058 /* The mouse-highlighting comes from a display string
27059 with a mouse-face. */
27060 Lisp_Object s, e;
27061 EMACS_INT ignore;
27062
27063 s = Fprevious_single_property_change
27064 (make_number (pos + 1), Qmouse_face, object, Qnil);
27065 e = Fnext_single_property_change
27066 (position, Qmouse_face, object, Qnil);
27067 if (NILP (s))
27068 s = make_number (0);
27069 if (NILP (e))
27070 e = make_number (SCHARS (object) - 1);
27071 mouse_face_from_string_pos (w, hlinfo, object,
27072 XINT (s), XINT (e));
27073 hlinfo->mouse_face_past_end = 0;
27074 hlinfo->mouse_face_window = window;
27075 hlinfo->mouse_face_face_id
27076 = face_at_string_position (w, object, pos, 0, 0, 0, &ignore,
27077 glyph->face_id, 1);
27078 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
27079 cursor = No_Cursor;
27080 }
27081 else
27082 {
27083 /* The mouse-highlighting, if any, comes from an overlay
27084 or text property in the buffer. */
27085 Lisp_Object buffer IF_LINT (= Qnil);
27086 Lisp_Object cover_string IF_LINT (= Qnil);
27087
27088 if (STRINGP (object))
27089 {
27090 /* If we are on a display string with no mouse-face,
27091 check if the text under it has one. */
27092 struct glyph_row *r = MATRIX_ROW (w->current_matrix, vpos);
27093 EMACS_INT start = MATRIX_ROW_START_CHARPOS (r);
27094 pos = string_buffer_position (object, start);
27095 if (pos > 0)
27096 {
27097 mouse_face = get_char_property_and_overlay
27098 (make_number (pos), Qmouse_face, w->buffer, &overlay);
27099 buffer = w->buffer;
27100 cover_string = object;
27101 }
27102 }
27103 else
27104 {
27105 buffer = object;
27106 cover_string = Qnil;
27107 }
27108
27109 if (!NILP (mouse_face))
27110 {
27111 Lisp_Object before, after;
27112 Lisp_Object before_string, after_string;
27113 /* To correctly find the limits of mouse highlight
27114 in a bidi-reordered buffer, we must not use the
27115 optimization of limiting the search in
27116 previous-single-property-change and
27117 next-single-property-change, because
27118 rows_from_pos_range needs the real start and end
27119 positions to DTRT in this case. That's because
27120 the first row visible in a window does not
27121 necessarily display the character whose position
27122 is the smallest. */
27123 Lisp_Object lim1 =
27124 NILP (BVAR (XBUFFER (buffer), bidi_display_reordering))
27125 ? Fmarker_position (w->start)
27126 : Qnil;
27127 Lisp_Object lim2 =
27128 NILP (BVAR (XBUFFER (buffer), bidi_display_reordering))
27129 ? make_number (BUF_Z (XBUFFER (buffer))
27130 - XFASTINT (w->window_end_pos))
27131 : Qnil;
27132
27133 if (NILP (overlay))
27134 {
27135 /* Handle the text property case. */
27136 before = Fprevious_single_property_change
27137 (make_number (pos + 1), Qmouse_face, buffer, lim1);
27138 after = Fnext_single_property_change
27139 (make_number (pos), Qmouse_face, buffer, lim2);
27140 before_string = after_string = Qnil;
27141 }
27142 else
27143 {
27144 /* Handle the overlay case. */
27145 before = Foverlay_start (overlay);
27146 after = Foverlay_end (overlay);
27147 before_string = Foverlay_get (overlay, Qbefore_string);
27148 after_string = Foverlay_get (overlay, Qafter_string);
27149
27150 if (!STRINGP (before_string)) before_string = Qnil;
27151 if (!STRINGP (after_string)) after_string = Qnil;
27152 }
27153
27154 mouse_face_from_buffer_pos (window, hlinfo, pos,
27155 XFASTINT (before),
27156 XFASTINT (after),
27157 before_string, after_string,
27158 cover_string);
27159 cursor = No_Cursor;
27160 }
27161 }
27162 }
27163
27164 check_help_echo:
27165
27166 /* Look for a `help-echo' property. */
27167 if (NILP (help_echo_string)) {
27168 Lisp_Object help, overlay;
27169
27170 /* Check overlays first. */
27171 help = overlay = Qnil;
27172 for (i = noverlays - 1; i >= 0 && NILP (help); --i)
27173 {
27174 overlay = overlay_vec[i];
27175 help = Foverlay_get (overlay, Qhelp_echo);
27176 }
27177
27178 if (!NILP (help))
27179 {
27180 help_echo_string = help;
27181 help_echo_window = window;
27182 help_echo_object = overlay;
27183 help_echo_pos = pos;
27184 }
27185 else
27186 {
27187 Lisp_Object obj = glyph->object;
27188 EMACS_INT charpos = glyph->charpos;
27189
27190 /* Try text properties. */
27191 if (STRINGP (obj)
27192 && charpos >= 0
27193 && charpos < SCHARS (obj))
27194 {
27195 help = Fget_text_property (make_number (charpos),
27196 Qhelp_echo, obj);
27197 if (NILP (help))
27198 {
27199 /* If the string itself doesn't specify a help-echo,
27200 see if the buffer text ``under'' it does. */
27201 struct glyph_row *r
27202 = MATRIX_ROW (w->current_matrix, vpos);
27203 EMACS_INT start = MATRIX_ROW_START_CHARPOS (r);
27204 EMACS_INT p = string_buffer_position (obj, start);
27205 if (p > 0)
27206 {
27207 help = Fget_char_property (make_number (p),
27208 Qhelp_echo, w->buffer);
27209 if (!NILP (help))
27210 {
27211 charpos = p;
27212 obj = w->buffer;
27213 }
27214 }
27215 }
27216 }
27217 else if (BUFFERP (obj)
27218 && charpos >= BEGV
27219 && charpos < ZV)
27220 help = Fget_text_property (make_number (charpos), Qhelp_echo,
27221 obj);
27222
27223 if (!NILP (help))
27224 {
27225 help_echo_string = help;
27226 help_echo_window = window;
27227 help_echo_object = obj;
27228 help_echo_pos = charpos;
27229 }
27230 }
27231 }
27232
27233 #ifdef HAVE_WINDOW_SYSTEM
27234 /* Look for a `pointer' property. */
27235 if (FRAME_WINDOW_P (f) && NILP (pointer))
27236 {
27237 /* Check overlays first. */
27238 for (i = noverlays - 1; i >= 0 && NILP (pointer); --i)
27239 pointer = Foverlay_get (overlay_vec[i], Qpointer);
27240
27241 if (NILP (pointer))
27242 {
27243 Lisp_Object obj = glyph->object;
27244 EMACS_INT charpos = glyph->charpos;
27245
27246 /* Try text properties. */
27247 if (STRINGP (obj)
27248 && charpos >= 0
27249 && charpos < SCHARS (obj))
27250 {
27251 pointer = Fget_text_property (make_number (charpos),
27252 Qpointer, obj);
27253 if (NILP (pointer))
27254 {
27255 /* If the string itself doesn't specify a pointer,
27256 see if the buffer text ``under'' it does. */
27257 struct glyph_row *r
27258 = MATRIX_ROW (w->current_matrix, vpos);
27259 EMACS_INT start = MATRIX_ROW_START_CHARPOS (r);
27260 EMACS_INT p = string_buffer_position (obj, start);
27261 if (p > 0)
27262 pointer = Fget_char_property (make_number (p),
27263 Qpointer, w->buffer);
27264 }
27265 }
27266 else if (BUFFERP (obj)
27267 && charpos >= BEGV
27268 && charpos < ZV)
27269 pointer = Fget_text_property (make_number (charpos),
27270 Qpointer, obj);
27271 }
27272 }
27273 #endif /* HAVE_WINDOW_SYSTEM */
27274
27275 BEGV = obegv;
27276 ZV = ozv;
27277 current_buffer = obuf;
27278 }
27279
27280 set_cursor:
27281
27282 #ifdef HAVE_WINDOW_SYSTEM
27283 if (FRAME_WINDOW_P (f))
27284 define_frame_cursor1 (f, cursor, pointer);
27285 #else
27286 /* This is here to prevent a compiler error, about "label at end of
27287 compound statement". */
27288 return;
27289 #endif
27290 }
27291
27292
27293 /* EXPORT for RIF:
27294 Clear any mouse-face on window W. This function is part of the
27295 redisplay interface, and is called from try_window_id and similar
27296 functions to ensure the mouse-highlight is off. */
27297
27298 void
27299 x_clear_window_mouse_face (struct window *w)
27300 {
27301 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame));
27302 Lisp_Object window;
27303
27304 BLOCK_INPUT;
27305 XSETWINDOW (window, w);
27306 if (EQ (window, hlinfo->mouse_face_window))
27307 clear_mouse_face (hlinfo);
27308 UNBLOCK_INPUT;
27309 }
27310
27311
27312 /* EXPORT:
27313 Just discard the mouse face information for frame F, if any.
27314 This is used when the size of F is changed. */
27315
27316 void
27317 cancel_mouse_face (struct frame *f)
27318 {
27319 Lisp_Object window;
27320 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
27321
27322 window = hlinfo->mouse_face_window;
27323 if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f)
27324 {
27325 hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
27326 hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
27327 hlinfo->mouse_face_window = Qnil;
27328 }
27329 }
27330
27331
27332 \f
27333 /***********************************************************************
27334 Exposure Events
27335 ***********************************************************************/
27336
27337 #ifdef HAVE_WINDOW_SYSTEM
27338
27339 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
27340 which intersects rectangle R. R is in window-relative coordinates. */
27341
27342 static void
27343 expose_area (struct window *w, struct glyph_row *row, XRectangle *r,
27344 enum glyph_row_area area)
27345 {
27346 struct glyph *first = row->glyphs[area];
27347 struct glyph *end = row->glyphs[area] + row->used[area];
27348 struct glyph *last;
27349 int first_x, start_x, x;
27350
27351 if (area == TEXT_AREA && row->fill_line_p)
27352 /* If row extends face to end of line write the whole line. */
27353 draw_glyphs (w, 0, row, area,
27354 0, row->used[area],
27355 DRAW_NORMAL_TEXT, 0);
27356 else
27357 {
27358 /* Set START_X to the window-relative start position for drawing glyphs of
27359 AREA. The first glyph of the text area can be partially visible.
27360 The first glyphs of other areas cannot. */
27361 start_x = window_box_left_offset (w, area);
27362 x = start_x;
27363 if (area == TEXT_AREA)
27364 x += row->x;
27365
27366 /* Find the first glyph that must be redrawn. */
27367 while (first < end
27368 && x + first->pixel_width < r->x)
27369 {
27370 x += first->pixel_width;
27371 ++first;
27372 }
27373
27374 /* Find the last one. */
27375 last = first;
27376 first_x = x;
27377 while (last < end
27378 && x < r->x + r->width)
27379 {
27380 x += last->pixel_width;
27381 ++last;
27382 }
27383
27384 /* Repaint. */
27385 if (last > first)
27386 draw_glyphs (w, first_x - start_x, row, area,
27387 first - row->glyphs[area], last - row->glyphs[area],
27388 DRAW_NORMAL_TEXT, 0);
27389 }
27390 }
27391
27392
27393 /* Redraw the parts of the glyph row ROW on window W intersecting
27394 rectangle R. R is in window-relative coordinates. Value is
27395 non-zero if mouse-face was overwritten. */
27396
27397 static int
27398 expose_line (struct window *w, struct glyph_row *row, XRectangle *r)
27399 {
27400 xassert (row->enabled_p);
27401
27402 if (row->mode_line_p || w->pseudo_window_p)
27403 draw_glyphs (w, 0, row, TEXT_AREA,
27404 0, row->used[TEXT_AREA],
27405 DRAW_NORMAL_TEXT, 0);
27406 else
27407 {
27408 if (row->used[LEFT_MARGIN_AREA])
27409 expose_area (w, row, r, LEFT_MARGIN_AREA);
27410 if (row->used[TEXT_AREA])
27411 expose_area (w, row, r, TEXT_AREA);
27412 if (row->used[RIGHT_MARGIN_AREA])
27413 expose_area (w, row, r, RIGHT_MARGIN_AREA);
27414 draw_row_fringe_bitmaps (w, row);
27415 }
27416
27417 return row->mouse_face_p;
27418 }
27419
27420
27421 /* Redraw those parts of glyphs rows during expose event handling that
27422 overlap other rows. Redrawing of an exposed line writes over parts
27423 of lines overlapping that exposed line; this function fixes that.
27424
27425 W is the window being exposed. FIRST_OVERLAPPING_ROW is the first
27426 row in W's current matrix that is exposed and overlaps other rows.
27427 LAST_OVERLAPPING_ROW is the last such row. */
27428
27429 static void
27430 expose_overlaps (struct window *w,
27431 struct glyph_row *first_overlapping_row,
27432 struct glyph_row *last_overlapping_row,
27433 XRectangle *r)
27434 {
27435 struct glyph_row *row;
27436
27437 for (row = first_overlapping_row; row <= last_overlapping_row; ++row)
27438 if (row->overlapping_p)
27439 {
27440 xassert (row->enabled_p && !row->mode_line_p);
27441
27442 row->clip = r;
27443 if (row->used[LEFT_MARGIN_AREA])
27444 x_fix_overlapping_area (w, row, LEFT_MARGIN_AREA, OVERLAPS_BOTH);
27445
27446 if (row->used[TEXT_AREA])
27447 x_fix_overlapping_area (w, row, TEXT_AREA, OVERLAPS_BOTH);
27448
27449 if (row->used[RIGHT_MARGIN_AREA])
27450 x_fix_overlapping_area (w, row, RIGHT_MARGIN_AREA, OVERLAPS_BOTH);
27451 row->clip = NULL;
27452 }
27453 }
27454
27455
27456 /* Return non-zero if W's cursor intersects rectangle R. */
27457
27458 static int
27459 phys_cursor_in_rect_p (struct window *w, XRectangle *r)
27460 {
27461 XRectangle cr, result;
27462 struct glyph *cursor_glyph;
27463 struct glyph_row *row;
27464
27465 if (w->phys_cursor.vpos >= 0
27466 && w->phys_cursor.vpos < w->current_matrix->nrows
27467 && (row = MATRIX_ROW (w->current_matrix, w->phys_cursor.vpos),
27468 row->enabled_p)
27469 && row->cursor_in_fringe_p)
27470 {
27471 /* Cursor is in the fringe. */
27472 cr.x = window_box_right_offset (w,
27473 (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
27474 ? RIGHT_MARGIN_AREA
27475 : TEXT_AREA));
27476 cr.y = row->y;
27477 cr.width = WINDOW_RIGHT_FRINGE_WIDTH (w);
27478 cr.height = row->height;
27479 return x_intersect_rectangles (&cr, r, &result);
27480 }
27481
27482 cursor_glyph = get_phys_cursor_glyph (w);
27483 if (cursor_glyph)
27484 {
27485 /* r is relative to W's box, but w->phys_cursor.x is relative
27486 to left edge of W's TEXT area. Adjust it. */
27487 cr.x = window_box_left_offset (w, TEXT_AREA) + w->phys_cursor.x;
27488 cr.y = w->phys_cursor.y;
27489 cr.width = cursor_glyph->pixel_width;
27490 cr.height = w->phys_cursor_height;
27491 /* ++KFS: W32 version used W32-specific IntersectRect here, but
27492 I assume the effect is the same -- and this is portable. */
27493 return x_intersect_rectangles (&cr, r, &result);
27494 }
27495 /* If we don't understand the format, pretend we're not in the hot-spot. */
27496 return 0;
27497 }
27498
27499
27500 /* EXPORT:
27501 Draw a vertical window border to the right of window W if W doesn't
27502 have vertical scroll bars. */
27503
27504 void
27505 x_draw_vertical_border (struct window *w)
27506 {
27507 struct frame *f = XFRAME (WINDOW_FRAME (w));
27508
27509 /* We could do better, if we knew what type of scroll-bar the adjacent
27510 windows (on either side) have... But we don't :-(
27511 However, I think this works ok. ++KFS 2003-04-25 */
27512
27513 /* Redraw borders between horizontally adjacent windows. Don't
27514 do it for frames with vertical scroll bars because either the
27515 right scroll bar of a window, or the left scroll bar of its
27516 neighbor will suffice as a border. */
27517 if (FRAME_HAS_VERTICAL_SCROLL_BARS (XFRAME (w->frame)))
27518 return;
27519
27520 if (!WINDOW_RIGHTMOST_P (w)
27521 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w))
27522 {
27523 int x0, x1, y0, y1;
27524
27525 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
27526 y1 -= 1;
27527
27528 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
27529 x1 -= 1;
27530
27531 FRAME_RIF (f)->draw_vertical_window_border (w, x1, y0, y1);
27532 }
27533 else if (!WINDOW_LEFTMOST_P (w)
27534 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
27535 {
27536 int x0, x1, y0, y1;
27537
27538 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
27539 y1 -= 1;
27540
27541 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
27542 x0 -= 1;
27543
27544 FRAME_RIF (f)->draw_vertical_window_border (w, x0, y0, y1);
27545 }
27546 }
27547
27548
27549 /* Redraw the part of window W intersection rectangle FR. Pixel
27550 coordinates in FR are frame-relative. Call this function with
27551 input blocked. Value is non-zero if the exposure overwrites
27552 mouse-face. */
27553
27554 static int
27555 expose_window (struct window *w, XRectangle *fr)
27556 {
27557 struct frame *f = XFRAME (w->frame);
27558 XRectangle wr, r;
27559 int mouse_face_overwritten_p = 0;
27560
27561 /* If window is not yet fully initialized, do nothing. This can
27562 happen when toolkit scroll bars are used and a window is split.
27563 Reconfiguring the scroll bar will generate an expose for a newly
27564 created window. */
27565 if (w->current_matrix == NULL)
27566 return 0;
27567
27568 /* When we're currently updating the window, display and current
27569 matrix usually don't agree. Arrange for a thorough display
27570 later. */
27571 if (w == updated_window)
27572 {
27573 SET_FRAME_GARBAGED (f);
27574 return 0;
27575 }
27576
27577 /* Frame-relative pixel rectangle of W. */
27578 wr.x = WINDOW_LEFT_EDGE_X (w);
27579 wr.y = WINDOW_TOP_EDGE_Y (w);
27580 wr.width = WINDOW_TOTAL_WIDTH (w);
27581 wr.height = WINDOW_TOTAL_HEIGHT (w);
27582
27583 if (x_intersect_rectangles (fr, &wr, &r))
27584 {
27585 int yb = window_text_bottom_y (w);
27586 struct glyph_row *row;
27587 int cursor_cleared_p, phys_cursor_on_p;
27588 struct glyph_row *first_overlapping_row, *last_overlapping_row;
27589
27590 TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n",
27591 r.x, r.y, r.width, r.height));
27592
27593 /* Convert to window coordinates. */
27594 r.x -= WINDOW_LEFT_EDGE_X (w);
27595 r.y -= WINDOW_TOP_EDGE_Y (w);
27596
27597 /* Turn off the cursor. */
27598 if (!w->pseudo_window_p
27599 && phys_cursor_in_rect_p (w, &r))
27600 {
27601 x_clear_cursor (w);
27602 cursor_cleared_p = 1;
27603 }
27604 else
27605 cursor_cleared_p = 0;
27606
27607 /* If the row containing the cursor extends face to end of line,
27608 then expose_area might overwrite the cursor outside the
27609 rectangle and thus notice_overwritten_cursor might clear
27610 w->phys_cursor_on_p. We remember the original value and
27611 check later if it is changed. */
27612 phys_cursor_on_p = w->phys_cursor_on_p;
27613
27614 /* Update lines intersecting rectangle R. */
27615 first_overlapping_row = last_overlapping_row = NULL;
27616 for (row = w->current_matrix->rows;
27617 row->enabled_p;
27618 ++row)
27619 {
27620 int y0 = row->y;
27621 int y1 = MATRIX_ROW_BOTTOM_Y (row);
27622
27623 if ((y0 >= r.y && y0 < r.y + r.height)
27624 || (y1 > r.y && y1 < r.y + r.height)
27625 || (r.y >= y0 && r.y < y1)
27626 || (r.y + r.height > y0 && r.y + r.height < y1))
27627 {
27628 /* A header line may be overlapping, but there is no need
27629 to fix overlapping areas for them. KFS 2005-02-12 */
27630 if (row->overlapping_p && !row->mode_line_p)
27631 {
27632 if (first_overlapping_row == NULL)
27633 first_overlapping_row = row;
27634 last_overlapping_row = row;
27635 }
27636
27637 row->clip = fr;
27638 if (expose_line (w, row, &r))
27639 mouse_face_overwritten_p = 1;
27640 row->clip = NULL;
27641 }
27642 else if (row->overlapping_p)
27643 {
27644 /* We must redraw a row overlapping the exposed area. */
27645 if (y0 < r.y
27646 ? y0 + row->phys_height > r.y
27647 : y0 + row->ascent - row->phys_ascent < r.y +r.height)
27648 {
27649 if (first_overlapping_row == NULL)
27650 first_overlapping_row = row;
27651 last_overlapping_row = row;
27652 }
27653 }
27654
27655 if (y1 >= yb)
27656 break;
27657 }
27658
27659 /* Display the mode line if there is one. */
27660 if (WINDOW_WANTS_MODELINE_P (w)
27661 && (row = MATRIX_MODE_LINE_ROW (w->current_matrix),
27662 row->enabled_p)
27663 && row->y < r.y + r.height)
27664 {
27665 if (expose_line (w, row, &r))
27666 mouse_face_overwritten_p = 1;
27667 }
27668
27669 if (!w->pseudo_window_p)
27670 {
27671 /* Fix the display of overlapping rows. */
27672 if (first_overlapping_row)
27673 expose_overlaps (w, first_overlapping_row, last_overlapping_row,
27674 fr);
27675
27676 /* Draw border between windows. */
27677 x_draw_vertical_border (w);
27678
27679 /* Turn the cursor on again. */
27680 if (cursor_cleared_p
27681 || (phys_cursor_on_p && !w->phys_cursor_on_p))
27682 update_window_cursor (w, 1);
27683 }
27684 }
27685
27686 return mouse_face_overwritten_p;
27687 }
27688
27689
27690
27691 /* Redraw (parts) of all windows in the window tree rooted at W that
27692 intersect R. R contains frame pixel coordinates. Value is
27693 non-zero if the exposure overwrites mouse-face. */
27694
27695 static int
27696 expose_window_tree (struct window *w, XRectangle *r)
27697 {
27698 struct frame *f = XFRAME (w->frame);
27699 int mouse_face_overwritten_p = 0;
27700
27701 while (w && !FRAME_GARBAGED_P (f))
27702 {
27703 if (!NILP (w->hchild))
27704 mouse_face_overwritten_p
27705 |= expose_window_tree (XWINDOW (w->hchild), r);
27706 else if (!NILP (w->vchild))
27707 mouse_face_overwritten_p
27708 |= expose_window_tree (XWINDOW (w->vchild), r);
27709 else
27710 mouse_face_overwritten_p |= expose_window (w, r);
27711
27712 w = NILP (w->next) ? NULL : XWINDOW (w->next);
27713 }
27714
27715 return mouse_face_overwritten_p;
27716 }
27717
27718
27719 /* EXPORT:
27720 Redisplay an exposed area of frame F. X and Y are the upper-left
27721 corner of the exposed rectangle. W and H are width and height of
27722 the exposed area. All are pixel values. W or H zero means redraw
27723 the entire frame. */
27724
27725 void
27726 expose_frame (struct frame *f, int x, int y, int w, int h)
27727 {
27728 XRectangle r;
27729 int mouse_face_overwritten_p = 0;
27730
27731 TRACE ((stderr, "expose_frame "));
27732
27733 /* No need to redraw if frame will be redrawn soon. */
27734 if (FRAME_GARBAGED_P (f))
27735 {
27736 TRACE ((stderr, " garbaged\n"));
27737 return;
27738 }
27739
27740 /* If basic faces haven't been realized yet, there is no point in
27741 trying to redraw anything. This can happen when we get an expose
27742 event while Emacs is starting, e.g. by moving another window. */
27743 if (FRAME_FACE_CACHE (f) == NULL
27744 || FRAME_FACE_CACHE (f)->used < BASIC_FACE_ID_SENTINEL)
27745 {
27746 TRACE ((stderr, " no faces\n"));
27747 return;
27748 }
27749
27750 if (w == 0 || h == 0)
27751 {
27752 r.x = r.y = 0;
27753 r.width = FRAME_COLUMN_WIDTH (f) * FRAME_COLS (f);
27754 r.height = FRAME_LINE_HEIGHT (f) * FRAME_LINES (f);
27755 }
27756 else
27757 {
27758 r.x = x;
27759 r.y = y;
27760 r.width = w;
27761 r.height = h;
27762 }
27763
27764 TRACE ((stderr, "(%d, %d, %d, %d)\n", r.x, r.y, r.width, r.height));
27765 mouse_face_overwritten_p = expose_window_tree (XWINDOW (f->root_window), &r);
27766
27767 if (WINDOWP (f->tool_bar_window))
27768 mouse_face_overwritten_p
27769 |= expose_window (XWINDOW (f->tool_bar_window), &r);
27770
27771 #ifdef HAVE_X_WINDOWS
27772 #ifndef MSDOS
27773 #ifndef USE_X_TOOLKIT
27774 if (WINDOWP (f->menu_bar_window))
27775 mouse_face_overwritten_p
27776 |= expose_window (XWINDOW (f->menu_bar_window), &r);
27777 #endif /* not USE_X_TOOLKIT */
27778 #endif
27779 #endif
27780
27781 /* Some window managers support a focus-follows-mouse style with
27782 delayed raising of frames. Imagine a partially obscured frame,
27783 and moving the mouse into partially obscured mouse-face on that
27784 frame. The visible part of the mouse-face will be highlighted,
27785 then the WM raises the obscured frame. With at least one WM, KDE
27786 2.1, Emacs is not getting any event for the raising of the frame
27787 (even tried with SubstructureRedirectMask), only Expose events.
27788 These expose events will draw text normally, i.e. not
27789 highlighted. Which means we must redo the highlight here.
27790 Subsume it under ``we love X''. --gerd 2001-08-15 */
27791 /* Included in Windows version because Windows most likely does not
27792 do the right thing if any third party tool offers
27793 focus-follows-mouse with delayed raise. --jason 2001-10-12 */
27794 if (mouse_face_overwritten_p && !FRAME_GARBAGED_P (f))
27795 {
27796 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
27797 if (f == hlinfo->mouse_face_mouse_frame)
27798 {
27799 int mouse_x = hlinfo->mouse_face_mouse_x;
27800 int mouse_y = hlinfo->mouse_face_mouse_y;
27801 clear_mouse_face (hlinfo);
27802 note_mouse_highlight (f, mouse_x, mouse_y);
27803 }
27804 }
27805 }
27806
27807
27808 /* EXPORT:
27809 Determine the intersection of two rectangles R1 and R2. Return
27810 the intersection in *RESULT. Value is non-zero if RESULT is not
27811 empty. */
27812
27813 int
27814 x_intersect_rectangles (XRectangle *r1, XRectangle *r2, XRectangle *result)
27815 {
27816 XRectangle *left, *right;
27817 XRectangle *upper, *lower;
27818 int intersection_p = 0;
27819
27820 /* Rearrange so that R1 is the left-most rectangle. */
27821 if (r1->x < r2->x)
27822 left = r1, right = r2;
27823 else
27824 left = r2, right = r1;
27825
27826 /* X0 of the intersection is right.x0, if this is inside R1,
27827 otherwise there is no intersection. */
27828 if (right->x <= left->x + left->width)
27829 {
27830 result->x = right->x;
27831
27832 /* The right end of the intersection is the minimum of
27833 the right ends of left and right. */
27834 result->width = (min (left->x + left->width, right->x + right->width)
27835 - result->x);
27836
27837 /* Same game for Y. */
27838 if (r1->y < r2->y)
27839 upper = r1, lower = r2;
27840 else
27841 upper = r2, lower = r1;
27842
27843 /* The upper end of the intersection is lower.y0, if this is inside
27844 of upper. Otherwise, there is no intersection. */
27845 if (lower->y <= upper->y + upper->height)
27846 {
27847 result->y = lower->y;
27848
27849 /* The lower end of the intersection is the minimum of the lower
27850 ends of upper and lower. */
27851 result->height = (min (lower->y + lower->height,
27852 upper->y + upper->height)
27853 - result->y);
27854 intersection_p = 1;
27855 }
27856 }
27857
27858 return intersection_p;
27859 }
27860
27861 #endif /* HAVE_WINDOW_SYSTEM */
27862
27863 \f
27864 /***********************************************************************
27865 Initialization
27866 ***********************************************************************/
27867
27868 void
27869 syms_of_xdisp (void)
27870 {
27871 Vwith_echo_area_save_vector = Qnil;
27872 staticpro (&Vwith_echo_area_save_vector);
27873
27874 Vmessage_stack = Qnil;
27875 staticpro (&Vmessage_stack);
27876
27877 DEFSYM (Qinhibit_redisplay, "inhibit-redisplay");
27878
27879 message_dolog_marker1 = Fmake_marker ();
27880 staticpro (&message_dolog_marker1);
27881 message_dolog_marker2 = Fmake_marker ();
27882 staticpro (&message_dolog_marker2);
27883 message_dolog_marker3 = Fmake_marker ();
27884 staticpro (&message_dolog_marker3);
27885
27886 #if GLYPH_DEBUG
27887 defsubr (&Sdump_frame_glyph_matrix);
27888 defsubr (&Sdump_glyph_matrix);
27889 defsubr (&Sdump_glyph_row);
27890 defsubr (&Sdump_tool_bar_row);
27891 defsubr (&Strace_redisplay);
27892 defsubr (&Strace_to_stderr);
27893 #endif
27894 #ifdef HAVE_WINDOW_SYSTEM
27895 defsubr (&Stool_bar_lines_needed);
27896 defsubr (&Slookup_image_map);
27897 #endif
27898 defsubr (&Sformat_mode_line);
27899 defsubr (&Sinvisible_p);
27900 defsubr (&Scurrent_bidi_paragraph_direction);
27901
27902 DEFSYM (Qmenu_bar_update_hook, "menu-bar-update-hook");
27903 DEFSYM (Qoverriding_terminal_local_map, "overriding-terminal-local-map");
27904 DEFSYM (Qoverriding_local_map, "overriding-local-map");
27905 DEFSYM (Qwindow_scroll_functions, "window-scroll-functions");
27906 DEFSYM (Qwindow_text_change_functions, "window-text-change-functions");
27907 DEFSYM (Qredisplay_end_trigger_functions, "redisplay-end-trigger-functions");
27908 DEFSYM (Qinhibit_point_motion_hooks, "inhibit-point-motion-hooks");
27909 DEFSYM (Qeval, "eval");
27910 DEFSYM (QCdata, ":data");
27911 DEFSYM (Qdisplay, "display");
27912 DEFSYM (Qspace_width, "space-width");
27913 DEFSYM (Qraise, "raise");
27914 DEFSYM (Qslice, "slice");
27915 DEFSYM (Qspace, "space");
27916 DEFSYM (Qmargin, "margin");
27917 DEFSYM (Qpointer, "pointer");
27918 DEFSYM (Qleft_margin, "left-margin");
27919 DEFSYM (Qright_margin, "right-margin");
27920 DEFSYM (Qcenter, "center");
27921 DEFSYM (Qline_height, "line-height");
27922 DEFSYM (QCalign_to, ":align-to");
27923 DEFSYM (QCrelative_width, ":relative-width");
27924 DEFSYM (QCrelative_height, ":relative-height");
27925 DEFSYM (QCeval, ":eval");
27926 DEFSYM (QCpropertize, ":propertize");
27927 DEFSYM (QCfile, ":file");
27928 DEFSYM (Qfontified, "fontified");
27929 DEFSYM (Qfontification_functions, "fontification-functions");
27930 DEFSYM (Qtrailing_whitespace, "trailing-whitespace");
27931 DEFSYM (Qescape_glyph, "escape-glyph");
27932 DEFSYM (Qnobreak_space, "nobreak-space");
27933 DEFSYM (Qimage, "image");
27934 DEFSYM (Qtext, "text");
27935 DEFSYM (Qboth, "both");
27936 DEFSYM (Qboth_horiz, "both-horiz");
27937 DEFSYM (Qtext_image_horiz, "text-image-horiz");
27938 DEFSYM (QCmap, ":map");
27939 DEFSYM (QCpointer, ":pointer");
27940 DEFSYM (Qrect, "rect");
27941 DEFSYM (Qcircle, "circle");
27942 DEFSYM (Qpoly, "poly");
27943 DEFSYM (Qmessage_truncate_lines, "message-truncate-lines");
27944 DEFSYM (Qgrow_only, "grow-only");
27945 DEFSYM (Qinhibit_menubar_update, "inhibit-menubar-update");
27946 DEFSYM (Qinhibit_eval_during_redisplay, "inhibit-eval-during-redisplay");
27947 DEFSYM (Qposition, "position");
27948 DEFSYM (Qbuffer_position, "buffer-position");
27949 DEFSYM (Qobject, "object");
27950 DEFSYM (Qbar, "bar");
27951 DEFSYM (Qhbar, "hbar");
27952 DEFSYM (Qbox, "box");
27953 DEFSYM (Qhollow, "hollow");
27954 DEFSYM (Qhand, "hand");
27955 DEFSYM (Qarrow, "arrow");
27956 DEFSYM (Qtext, "text");
27957 DEFSYM (Qinhibit_free_realized_faces, "inhibit-free-realized-faces");
27958
27959 list_of_error = Fcons (Fcons (intern_c_string ("error"),
27960 Fcons (intern_c_string ("void-variable"), Qnil)),
27961 Qnil);
27962 staticpro (&list_of_error);
27963
27964 DEFSYM (Qlast_arrow_position, "last-arrow-position");
27965 DEFSYM (Qlast_arrow_string, "last-arrow-string");
27966 DEFSYM (Qoverlay_arrow_string, "overlay-arrow-string");
27967 DEFSYM (Qoverlay_arrow_bitmap, "overlay-arrow-bitmap");
27968
27969 echo_buffer[0] = echo_buffer[1] = Qnil;
27970 staticpro (&echo_buffer[0]);
27971 staticpro (&echo_buffer[1]);
27972
27973 echo_area_buffer[0] = echo_area_buffer[1] = Qnil;
27974 staticpro (&echo_area_buffer[0]);
27975 staticpro (&echo_area_buffer[1]);
27976
27977 Vmessages_buffer_name = make_pure_c_string ("*Messages*");
27978 staticpro (&Vmessages_buffer_name);
27979
27980 mode_line_proptrans_alist = Qnil;
27981 staticpro (&mode_line_proptrans_alist);
27982 mode_line_string_list = Qnil;
27983 staticpro (&mode_line_string_list);
27984 mode_line_string_face = Qnil;
27985 staticpro (&mode_line_string_face);
27986 mode_line_string_face_prop = Qnil;
27987 staticpro (&mode_line_string_face_prop);
27988 Vmode_line_unwind_vector = Qnil;
27989 staticpro (&Vmode_line_unwind_vector);
27990
27991 help_echo_string = Qnil;
27992 staticpro (&help_echo_string);
27993 help_echo_object = Qnil;
27994 staticpro (&help_echo_object);
27995 help_echo_window = Qnil;
27996 staticpro (&help_echo_window);
27997 previous_help_echo_string = Qnil;
27998 staticpro (&previous_help_echo_string);
27999 help_echo_pos = -1;
28000
28001 DEFSYM (Qright_to_left, "right-to-left");
28002 DEFSYM (Qleft_to_right, "left-to-right");
28003
28004 #ifdef HAVE_WINDOW_SYSTEM
28005 DEFVAR_BOOL ("x-stretch-cursor", x_stretch_cursor_p,
28006 doc: /* *Non-nil means draw block cursor as wide as the glyph under it.
28007 For example, if a block cursor is over a tab, it will be drawn as
28008 wide as that tab on the display. */);
28009 x_stretch_cursor_p = 0;
28010 #endif
28011
28012 DEFVAR_LISP ("show-trailing-whitespace", Vshow_trailing_whitespace,
28013 doc: /* *Non-nil means highlight trailing whitespace.
28014 The face used for trailing whitespace is `trailing-whitespace'. */);
28015 Vshow_trailing_whitespace = Qnil;
28016
28017 DEFVAR_LISP ("nobreak-char-display", Vnobreak_char_display,
28018 doc: /* Control highlighting of non-ASCII space and hyphen chars.
28019 If the value is t, Emacs highlights non-ASCII chars which have the
28020 same appearance as an ASCII space or hyphen, using the `nobreak-space'
28021 or `escape-glyph' face respectively.
28022
28023 U+00A0 (no-break space), U+00AD (soft hyphen), U+2010 (hyphen), and
28024 U+2011 (non-breaking hyphen) are affected.
28025
28026 Any other non-nil value means to display these characters as a escape
28027 glyph followed by an ordinary space or hyphen.
28028
28029 A value of nil means no special handling of these characters. */);
28030 Vnobreak_char_display = Qt;
28031
28032 DEFVAR_LISP ("void-text-area-pointer", Vvoid_text_area_pointer,
28033 doc: /* *The pointer shape to show in void text areas.
28034 A value of nil means to show the text pointer. Other options are `arrow',
28035 `text', `hand', `vdrag', `hdrag', `modeline', and `hourglass'. */);
28036 Vvoid_text_area_pointer = Qarrow;
28037
28038 DEFVAR_LISP ("inhibit-redisplay", Vinhibit_redisplay,
28039 doc: /* Non-nil means don't actually do any redisplay.
28040 This is used for internal purposes. */);
28041 Vinhibit_redisplay = Qnil;
28042
28043 DEFVAR_LISP ("global-mode-string", Vglobal_mode_string,
28044 doc: /* String (or mode line construct) included (normally) in `mode-line-format'. */);
28045 Vglobal_mode_string = Qnil;
28046
28047 DEFVAR_LISP ("overlay-arrow-position", Voverlay_arrow_position,
28048 doc: /* Marker for where to display an arrow on top of the buffer text.
28049 This must be the beginning of a line in order to work.
28050 See also `overlay-arrow-string'. */);
28051 Voverlay_arrow_position = Qnil;
28052
28053 DEFVAR_LISP ("overlay-arrow-string", Voverlay_arrow_string,
28054 doc: /* String to display as an arrow in non-window frames.
28055 See also `overlay-arrow-position'. */);
28056 Voverlay_arrow_string = make_pure_c_string ("=>");
28057
28058 DEFVAR_LISP ("overlay-arrow-variable-list", Voverlay_arrow_variable_list,
28059 doc: /* List of variables (symbols) which hold markers for overlay arrows.
28060 The symbols on this list are examined during redisplay to determine
28061 where to display overlay arrows. */);
28062 Voverlay_arrow_variable_list
28063 = Fcons (intern_c_string ("overlay-arrow-position"), Qnil);
28064
28065 DEFVAR_INT ("scroll-step", emacs_scroll_step,
28066 doc: /* *The number of lines to try scrolling a window by when point moves out.
28067 If that fails to bring point back on frame, point is centered instead.
28068 If this is zero, point is always centered after it moves off frame.
28069 If you want scrolling to always be a line at a time, you should set
28070 `scroll-conservatively' to a large value rather than set this to 1. */);
28071
28072 DEFVAR_INT ("scroll-conservatively", scroll_conservatively,
28073 doc: /* *Scroll up to this many lines, to bring point back on screen.
28074 If point moves off-screen, redisplay will scroll by up to
28075 `scroll-conservatively' lines in order to bring point just barely
28076 onto the screen again. If that cannot be done, then redisplay
28077 recenters point as usual.
28078
28079 If the value is greater than 100, redisplay will never recenter point,
28080 but will always scroll just enough text to bring point into view, even
28081 if you move far away.
28082
28083 A value of zero means always recenter point if it moves off screen. */);
28084 scroll_conservatively = 0;
28085
28086 DEFVAR_INT ("scroll-margin", scroll_margin,
28087 doc: /* *Number of lines of margin at the top and bottom of a window.
28088 Recenter the window whenever point gets within this many lines
28089 of the top or bottom of the window. */);
28090 scroll_margin = 0;
28091
28092 DEFVAR_LISP ("display-pixels-per-inch", Vdisplay_pixels_per_inch,
28093 doc: /* Pixels per inch value for non-window system displays.
28094 Value is a number or a cons (WIDTH-DPI . HEIGHT-DPI). */);
28095 Vdisplay_pixels_per_inch = make_float (72.0);
28096
28097 #if GLYPH_DEBUG
28098 DEFVAR_INT ("debug-end-pos", debug_end_pos, doc: /* Don't ask. */);
28099 #endif
28100
28101 DEFVAR_LISP ("truncate-partial-width-windows",
28102 Vtruncate_partial_width_windows,
28103 doc: /* Non-nil means truncate lines in windows narrower than the frame.
28104 For an integer value, truncate lines in each window narrower than the
28105 full frame width, provided the window width is less than that integer;
28106 otherwise, respect the value of `truncate-lines'.
28107
28108 For any other non-nil value, truncate lines in all windows that do
28109 not span the full frame width.
28110
28111 A value of nil means to respect the value of `truncate-lines'.
28112
28113 If `word-wrap' is enabled, you might want to reduce this. */);
28114 Vtruncate_partial_width_windows = make_number (50);
28115
28116 DEFVAR_BOOL ("mode-line-inverse-video", mode_line_inverse_video,
28117 doc: /* When nil, display the mode-line/header-line/menu-bar in the default face.
28118 Any other value means to use the appropriate face, `mode-line',
28119 `header-line', or `menu' respectively. */);
28120 mode_line_inverse_video = 1;
28121
28122 DEFVAR_LISP ("line-number-display-limit", Vline_number_display_limit,
28123 doc: /* *Maximum buffer size for which line number should be displayed.
28124 If the buffer is bigger than this, the line number does not appear
28125 in the mode line. A value of nil means no limit. */);
28126 Vline_number_display_limit = Qnil;
28127
28128 DEFVAR_INT ("line-number-display-limit-width",
28129 line_number_display_limit_width,
28130 doc: /* *Maximum line width (in characters) for line number display.
28131 If the average length of the lines near point is bigger than this, then the
28132 line number may be omitted from the mode line. */);
28133 line_number_display_limit_width = 200;
28134
28135 DEFVAR_BOOL ("highlight-nonselected-windows", highlight_nonselected_windows,
28136 doc: /* *Non-nil means highlight region even in nonselected windows. */);
28137 highlight_nonselected_windows = 0;
28138
28139 DEFVAR_BOOL ("multiple-frames", multiple_frames,
28140 doc: /* Non-nil if more than one frame is visible on this display.
28141 Minibuffer-only frames don't count, but iconified frames do.
28142 This variable is not guaranteed to be accurate except while processing
28143 `frame-title-format' and `icon-title-format'. */);
28144
28145 DEFVAR_LISP ("frame-title-format", Vframe_title_format,
28146 doc: /* Template for displaying the title bar of visible frames.
28147 \(Assuming the window manager supports this feature.)
28148
28149 This variable has the same structure as `mode-line-format', except that
28150 the %c and %l constructs are ignored. It is used only on frames for
28151 which no explicit name has been set \(see `modify-frame-parameters'). */);
28152
28153 DEFVAR_LISP ("icon-title-format", Vicon_title_format,
28154 doc: /* Template for displaying the title bar of an iconified frame.
28155 \(Assuming the window manager supports this feature.)
28156 This variable has the same structure as `mode-line-format' (which see),
28157 and is used only on frames for which no explicit name has been set
28158 \(see `modify-frame-parameters'). */);
28159 Vicon_title_format
28160 = Vframe_title_format
28161 = pure_cons (intern_c_string ("multiple-frames"),
28162 pure_cons (make_pure_c_string ("%b"),
28163 pure_cons (pure_cons (empty_unibyte_string,
28164 pure_cons (intern_c_string ("invocation-name"),
28165 pure_cons (make_pure_c_string ("@"),
28166 pure_cons (intern_c_string ("system-name"),
28167 Qnil)))),
28168 Qnil)));
28169
28170 DEFVAR_LISP ("message-log-max", Vmessage_log_max,
28171 doc: /* Maximum number of lines to keep in the message log buffer.
28172 If nil, disable message logging. If t, log messages but don't truncate
28173 the buffer when it becomes large. */);
28174 Vmessage_log_max = make_number (100);
28175
28176 DEFVAR_LISP ("window-size-change-functions", Vwindow_size_change_functions,
28177 doc: /* Functions called before redisplay, if window sizes have changed.
28178 The value should be a list of functions that take one argument.
28179 Just before redisplay, for each frame, if any of its windows have changed
28180 size since the last redisplay, or have been split or deleted,
28181 all the functions in the list are called, with the frame as argument. */);
28182 Vwindow_size_change_functions = Qnil;
28183
28184 DEFVAR_LISP ("window-scroll-functions", Vwindow_scroll_functions,
28185 doc: /* List of functions to call before redisplaying a window with scrolling.
28186 Each function is called with two arguments, the window and its new
28187 display-start position. Note that these functions are also called by
28188 `set-window-buffer'. Also note that the value of `window-end' is not
28189 valid when these functions are called. */);
28190 Vwindow_scroll_functions = Qnil;
28191
28192 DEFVAR_LISP ("window-text-change-functions",
28193 Vwindow_text_change_functions,
28194 doc: /* Functions to call in redisplay when text in the window might change. */);
28195 Vwindow_text_change_functions = Qnil;
28196
28197 DEFVAR_LISP ("redisplay-end-trigger-functions", Vredisplay_end_trigger_functions,
28198 doc: /* Functions called when redisplay of a window reaches the end trigger.
28199 Each function is called with two arguments, the window and the end trigger value.
28200 See `set-window-redisplay-end-trigger'. */);
28201 Vredisplay_end_trigger_functions = Qnil;
28202
28203 DEFVAR_LISP ("mouse-autoselect-window", Vmouse_autoselect_window,
28204 doc: /* *Non-nil means autoselect window with mouse pointer.
28205 If nil, do not autoselect windows.
28206 A positive number means delay autoselection by that many seconds: a
28207 window is autoselected only after the mouse has remained in that
28208 window for the duration of the delay.
28209 A negative number has a similar effect, but causes windows to be
28210 autoselected only after the mouse has stopped moving. \(Because of
28211 the way Emacs compares mouse events, you will occasionally wait twice
28212 that time before the window gets selected.\)
28213 Any other value means to autoselect window instantaneously when the
28214 mouse pointer enters it.
28215
28216 Autoselection selects the minibuffer only if it is active, and never
28217 unselects the minibuffer if it is active.
28218
28219 When customizing this variable make sure that the actual value of
28220 `focus-follows-mouse' matches the behavior of your window manager. */);
28221 Vmouse_autoselect_window = Qnil;
28222
28223 DEFVAR_LISP ("auto-resize-tool-bars", Vauto_resize_tool_bars,
28224 doc: /* *Non-nil means automatically resize tool-bars.
28225 This dynamically changes the tool-bar's height to the minimum height
28226 that is needed to make all tool-bar items visible.
28227 If value is `grow-only', the tool-bar's height is only increased
28228 automatically; to decrease the tool-bar height, use \\[recenter]. */);
28229 Vauto_resize_tool_bars = Qt;
28230
28231 DEFVAR_BOOL ("auto-raise-tool-bar-buttons", auto_raise_tool_bar_buttons_p,
28232 doc: /* *Non-nil means raise tool-bar buttons when the mouse moves over them. */);
28233 auto_raise_tool_bar_buttons_p = 1;
28234
28235 DEFVAR_BOOL ("make-cursor-line-fully-visible", make_cursor_line_fully_visible_p,
28236 doc: /* *Non-nil means to scroll (recenter) cursor line if it is not fully visible. */);
28237 make_cursor_line_fully_visible_p = 1;
28238
28239 DEFVAR_LISP ("tool-bar-border", Vtool_bar_border,
28240 doc: /* *Border below tool-bar in pixels.
28241 If an integer, use it as the height of the border.
28242 If it is one of `internal-border-width' or `border-width', use the
28243 value of the corresponding frame parameter.
28244 Otherwise, no border is added below the tool-bar. */);
28245 Vtool_bar_border = Qinternal_border_width;
28246
28247 DEFVAR_LISP ("tool-bar-button-margin", Vtool_bar_button_margin,
28248 doc: /* *Margin around tool-bar buttons in pixels.
28249 If an integer, use that for both horizontal and vertical margins.
28250 Otherwise, value should be a pair of integers `(HORZ . VERT)' with
28251 HORZ specifying the horizontal margin, and VERT specifying the
28252 vertical margin. */);
28253 Vtool_bar_button_margin = make_number (DEFAULT_TOOL_BAR_BUTTON_MARGIN);
28254
28255 DEFVAR_INT ("tool-bar-button-relief", tool_bar_button_relief,
28256 doc: /* *Relief thickness of tool-bar buttons. */);
28257 tool_bar_button_relief = DEFAULT_TOOL_BAR_BUTTON_RELIEF;
28258
28259 DEFVAR_LISP ("tool-bar-style", Vtool_bar_style,
28260 doc: /* Tool bar style to use.
28261 It can be one of
28262 image - show images only
28263 text - show text only
28264 both - show both, text below image
28265 both-horiz - show text to the right of the image
28266 text-image-horiz - show text to the left of the image
28267 any other - use system default or image if no system default. */);
28268 Vtool_bar_style = Qnil;
28269
28270 DEFVAR_INT ("tool-bar-max-label-size", tool_bar_max_label_size,
28271 doc: /* *Maximum number of characters a label can have to be shown.
28272 The tool bar style must also show labels for this to have any effect, see
28273 `tool-bar-style'. */);
28274 tool_bar_max_label_size = DEFAULT_TOOL_BAR_LABEL_SIZE;
28275
28276 DEFVAR_LISP ("fontification-functions", Vfontification_functions,
28277 doc: /* List of functions to call to fontify regions of text.
28278 Each function is called with one argument POS. Functions must
28279 fontify a region starting at POS in the current buffer, and give
28280 fontified regions the property `fontified'. */);
28281 Vfontification_functions = Qnil;
28282 Fmake_variable_buffer_local (Qfontification_functions);
28283
28284 DEFVAR_BOOL ("unibyte-display-via-language-environment",
28285 unibyte_display_via_language_environment,
28286 doc: /* *Non-nil means display unibyte text according to language environment.
28287 Specifically, this means that raw bytes in the range 160-255 decimal
28288 are displayed by converting them to the equivalent multibyte characters
28289 according to the current language environment. As a result, they are
28290 displayed according to the current fontset.
28291
28292 Note that this variable affects only how these bytes are displayed,
28293 but does not change the fact they are interpreted as raw bytes. */);
28294 unibyte_display_via_language_environment = 0;
28295
28296 DEFVAR_LISP ("max-mini-window-height", Vmax_mini_window_height,
28297 doc: /* *Maximum height for resizing mini-windows (the minibuffer and the echo area).
28298 If a float, it specifies a fraction of the mini-window frame's height.
28299 If an integer, it specifies a number of lines. */);
28300 Vmax_mini_window_height = make_float (0.25);
28301
28302 DEFVAR_LISP ("resize-mini-windows", Vresize_mini_windows,
28303 doc: /* How to resize mini-windows (the minibuffer and the echo area).
28304 A value of nil means don't automatically resize mini-windows.
28305 A value of t means resize them to fit the text displayed in them.
28306 A value of `grow-only', the default, means let mini-windows grow only;
28307 they return to their normal size when the minibuffer is closed, or the
28308 echo area becomes empty. */);
28309 Vresize_mini_windows = Qgrow_only;
28310
28311 DEFVAR_LISP ("blink-cursor-alist", Vblink_cursor_alist,
28312 doc: /* Alist specifying how to blink the cursor off.
28313 Each element has the form (ON-STATE . OFF-STATE). Whenever the
28314 `cursor-type' frame-parameter or variable equals ON-STATE,
28315 comparing using `equal', Emacs uses OFF-STATE to specify
28316 how to blink it off. ON-STATE and OFF-STATE are values for
28317 the `cursor-type' frame parameter.
28318
28319 If a frame's ON-STATE has no entry in this list,
28320 the frame's other specifications determine how to blink the cursor off. */);
28321 Vblink_cursor_alist = Qnil;
28322
28323 DEFVAR_BOOL ("auto-hscroll-mode", automatic_hscrolling_p,
28324 doc: /* Allow or disallow automatic horizontal scrolling of windows.
28325 If non-nil, windows are automatically scrolled horizontally to make
28326 point visible. */);
28327 automatic_hscrolling_p = 1;
28328 DEFSYM (Qauto_hscroll_mode, "auto-hscroll-mode");
28329
28330 DEFVAR_INT ("hscroll-margin", hscroll_margin,
28331 doc: /* *How many columns away from the window edge point is allowed to get
28332 before automatic hscrolling will horizontally scroll the window. */);
28333 hscroll_margin = 5;
28334
28335 DEFVAR_LISP ("hscroll-step", Vhscroll_step,
28336 doc: /* *How many columns to scroll the window when point gets too close to the edge.
28337 When point is less than `hscroll-margin' columns from the window
28338 edge, automatic hscrolling will scroll the window by the amount of columns
28339 determined by this variable. If its value is a positive integer, scroll that
28340 many columns. If it's a positive floating-point number, it specifies the
28341 fraction of the window's width to scroll. If it's nil or zero, point will be
28342 centered horizontally after the scroll. Any other value, including negative
28343 numbers, are treated as if the value were zero.
28344
28345 Automatic hscrolling always moves point outside the scroll margin, so if
28346 point was more than scroll step columns inside the margin, the window will
28347 scroll more than the value given by the scroll step.
28348
28349 Note that the lower bound for automatic hscrolling specified by `scroll-left'
28350 and `scroll-right' overrides this variable's effect. */);
28351 Vhscroll_step = make_number (0);
28352
28353 DEFVAR_BOOL ("message-truncate-lines", message_truncate_lines,
28354 doc: /* If non-nil, messages are truncated instead of resizing the echo area.
28355 Bind this around calls to `message' to let it take effect. */);
28356 message_truncate_lines = 0;
28357
28358 DEFVAR_LISP ("menu-bar-update-hook", Vmenu_bar_update_hook,
28359 doc: /* Normal hook run to update the menu bar definitions.
28360 Redisplay runs this hook before it redisplays the menu bar.
28361 This is used to update submenus such as Buffers,
28362 whose contents depend on various data. */);
28363 Vmenu_bar_update_hook = Qnil;
28364
28365 DEFVAR_LISP ("menu-updating-frame", Vmenu_updating_frame,
28366 doc: /* Frame for which we are updating a menu.
28367 The enable predicate for a menu binding should check this variable. */);
28368 Vmenu_updating_frame = Qnil;
28369
28370 DEFVAR_BOOL ("inhibit-menubar-update", inhibit_menubar_update,
28371 doc: /* Non-nil means don't update menu bars. Internal use only. */);
28372 inhibit_menubar_update = 0;
28373
28374 DEFVAR_LISP ("wrap-prefix", Vwrap_prefix,
28375 doc: /* Prefix prepended to all continuation lines at display time.
28376 The value may be a string, an image, or a stretch-glyph; it is
28377 interpreted in the same way as the value of a `display' text property.
28378
28379 This variable is overridden by any `wrap-prefix' text or overlay
28380 property.
28381
28382 To add a prefix to non-continuation lines, use `line-prefix'. */);
28383 Vwrap_prefix = Qnil;
28384 DEFSYM (Qwrap_prefix, "wrap-prefix");
28385 Fmake_variable_buffer_local (Qwrap_prefix);
28386
28387 DEFVAR_LISP ("line-prefix", Vline_prefix,
28388 doc: /* Prefix prepended to all non-continuation lines at display time.
28389 The value may be a string, an image, or a stretch-glyph; it is
28390 interpreted in the same way as the value of a `display' text property.
28391
28392 This variable is overridden by any `line-prefix' text or overlay
28393 property.
28394
28395 To add a prefix to continuation lines, use `wrap-prefix'. */);
28396 Vline_prefix = Qnil;
28397 DEFSYM (Qline_prefix, "line-prefix");
28398 Fmake_variable_buffer_local (Qline_prefix);
28399
28400 DEFVAR_BOOL ("inhibit-eval-during-redisplay", inhibit_eval_during_redisplay,
28401 doc: /* Non-nil means don't eval Lisp during redisplay. */);
28402 inhibit_eval_during_redisplay = 0;
28403
28404 DEFVAR_BOOL ("inhibit-free-realized-faces", inhibit_free_realized_faces,
28405 doc: /* Non-nil means don't free realized faces. Internal use only. */);
28406 inhibit_free_realized_faces = 0;
28407
28408 #if GLYPH_DEBUG
28409 DEFVAR_BOOL ("inhibit-try-window-id", inhibit_try_window_id,
28410 doc: /* Inhibit try_window_id display optimization. */);
28411 inhibit_try_window_id = 0;
28412
28413 DEFVAR_BOOL ("inhibit-try-window-reusing", inhibit_try_window_reusing,
28414 doc: /* Inhibit try_window_reusing display optimization. */);
28415 inhibit_try_window_reusing = 0;
28416
28417 DEFVAR_BOOL ("inhibit-try-cursor-movement", inhibit_try_cursor_movement,
28418 doc: /* Inhibit try_cursor_movement display optimization. */);
28419 inhibit_try_cursor_movement = 0;
28420 #endif /* GLYPH_DEBUG */
28421
28422 DEFVAR_INT ("overline-margin", overline_margin,
28423 doc: /* *Space between overline and text, in pixels.
28424 The default value is 2: the height of the overline (1 pixel) plus 1 pixel
28425 margin to the caracter height. */);
28426 overline_margin = 2;
28427
28428 DEFVAR_INT ("underline-minimum-offset",
28429 underline_minimum_offset,
28430 doc: /* Minimum distance between baseline and underline.
28431 This can improve legibility of underlined text at small font sizes,
28432 particularly when using variable `x-use-underline-position-properties'
28433 with fonts that specify an UNDERLINE_POSITION relatively close to the
28434 baseline. The default value is 1. */);
28435 underline_minimum_offset = 1;
28436
28437 DEFVAR_BOOL ("display-hourglass", display_hourglass_p,
28438 doc: /* Non-nil means show an hourglass pointer, when Emacs is busy.
28439 This feature only works when on a window system that can change
28440 cursor shapes. */);
28441 display_hourglass_p = 1;
28442
28443 DEFVAR_LISP ("hourglass-delay", Vhourglass_delay,
28444 doc: /* *Seconds to wait before displaying an hourglass pointer when Emacs is busy. */);
28445 Vhourglass_delay = make_number (DEFAULT_HOURGLASS_DELAY);
28446
28447 hourglass_atimer = NULL;
28448 hourglass_shown_p = 0;
28449
28450 DEFSYM (Qglyphless_char, "glyphless-char");
28451 DEFSYM (Qhex_code, "hex-code");
28452 DEFSYM (Qempty_box, "empty-box");
28453 DEFSYM (Qthin_space, "thin-space");
28454 DEFSYM (Qzero_width, "zero-width");
28455
28456 DEFSYM (Qglyphless_char_display, "glyphless-char-display");
28457 /* Intern this now in case it isn't already done.
28458 Setting this variable twice is harmless.
28459 But don't staticpro it here--that is done in alloc.c. */
28460 Qchar_table_extra_slots = intern_c_string ("char-table-extra-slots");
28461 Fput (Qglyphless_char_display, Qchar_table_extra_slots, make_number (1));
28462
28463 DEFVAR_LISP ("glyphless-char-display", Vglyphless_char_display,
28464 doc: /* Char-table defining glyphless characters.
28465 Each element, if non-nil, should be one of the following:
28466 an ASCII acronym string: display this string in a box
28467 `hex-code': display the hexadecimal code of a character in a box
28468 `empty-box': display as an empty box
28469 `thin-space': display as 1-pixel width space
28470 `zero-width': don't display
28471 An element may also be a cons cell (GRAPHICAL . TEXT), which specifies the
28472 display method for graphical terminals and text terminals respectively.
28473 GRAPHICAL and TEXT should each have one of the values listed above.
28474
28475 The char-table has one extra slot to control the display of a character for
28476 which no font is found. This slot only takes effect on graphical terminals.
28477 Its value should be an ASCII acronym string, `hex-code', `empty-box', or
28478 `thin-space'. The default is `empty-box'. */);
28479 Vglyphless_char_display = Fmake_char_table (Qglyphless_char_display, Qnil);
28480 Fset_char_table_extra_slot (Vglyphless_char_display, make_number (0),
28481 Qempty_box);
28482 }
28483
28484
28485 /* Initialize this module when Emacs starts. */
28486
28487 void
28488 init_xdisp (void)
28489 {
28490 current_header_line_height = current_mode_line_height = -1;
28491
28492 CHARPOS (this_line_start_pos) = 0;
28493
28494 if (!noninteractive)
28495 {
28496 struct window *m = XWINDOW (minibuf_window);
28497 Lisp_Object frame = m->frame;
28498 struct frame *f = XFRAME (frame);
28499 Lisp_Object root = FRAME_ROOT_WINDOW (f);
28500 struct window *r = XWINDOW (root);
28501 int i;
28502
28503 echo_area_window = minibuf_window;
28504
28505 XSETFASTINT (r->top_line, FRAME_TOP_MARGIN (f));
28506 XSETFASTINT (r->total_lines, FRAME_LINES (f) - 1 - FRAME_TOP_MARGIN (f));
28507 XSETFASTINT (r->total_cols, FRAME_COLS (f));
28508 XSETFASTINT (m->top_line, FRAME_LINES (f) - 1);
28509 XSETFASTINT (m->total_lines, 1);
28510 XSETFASTINT (m->total_cols, FRAME_COLS (f));
28511
28512 scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs;
28513 scratch_glyph_row.glyphs[TEXT_AREA + 1]
28514 = scratch_glyphs + MAX_SCRATCH_GLYPHS;
28515
28516 /* The default ellipsis glyphs `...'. */
28517 for (i = 0; i < 3; ++i)
28518 default_invis_vector[i] = make_number ('.');
28519 }
28520
28521 {
28522 /* Allocate the buffer for frame titles.
28523 Also used for `format-mode-line'. */
28524 int size = 100;
28525 mode_line_noprop_buf = (char *) xmalloc (size);
28526 mode_line_noprop_buf_end = mode_line_noprop_buf + size;
28527 mode_line_noprop_ptr = mode_line_noprop_buf;
28528 mode_line_target = MODE_LINE_DISPLAY;
28529 }
28530
28531 help_echo_showing_p = 0;
28532 }
28533
28534 /* Since w32 does not support atimers, it defines its own implementation of
28535 the following three functions in w32fns.c. */
28536 #ifndef WINDOWSNT
28537
28538 /* Platform-independent portion of hourglass implementation. */
28539
28540 /* Return non-zero if houglass timer has been started or hourglass is shown. */
28541 int
28542 hourglass_started (void)
28543 {
28544 return hourglass_shown_p || hourglass_atimer != NULL;
28545 }
28546
28547 /* Cancel a currently active hourglass timer, and start a new one. */
28548 void
28549 start_hourglass (void)
28550 {
28551 #if defined (HAVE_WINDOW_SYSTEM)
28552 EMACS_TIME delay;
28553 int secs, usecs = 0;
28554
28555 cancel_hourglass ();
28556
28557 if (INTEGERP (Vhourglass_delay)
28558 && XINT (Vhourglass_delay) > 0)
28559 secs = XFASTINT (Vhourglass_delay);
28560 else if (FLOATP (Vhourglass_delay)
28561 && XFLOAT_DATA (Vhourglass_delay) > 0)
28562 {
28563 Lisp_Object tem;
28564 tem = Ftruncate (Vhourglass_delay, Qnil);
28565 secs = XFASTINT (tem);
28566 usecs = (XFLOAT_DATA (Vhourglass_delay) - secs) * 1000000;
28567 }
28568 else
28569 secs = DEFAULT_HOURGLASS_DELAY;
28570
28571 EMACS_SET_SECS_USECS (delay, secs, usecs);
28572 hourglass_atimer = start_atimer (ATIMER_RELATIVE, delay,
28573 show_hourglass, NULL);
28574 #endif
28575 }
28576
28577
28578 /* Cancel the hourglass cursor timer if active, hide a busy cursor if
28579 shown. */
28580 void
28581 cancel_hourglass (void)
28582 {
28583 #if defined (HAVE_WINDOW_SYSTEM)
28584 if (hourglass_atimer)
28585 {
28586 cancel_atimer (hourglass_atimer);
28587 hourglass_atimer = NULL;
28588 }
28589
28590 if (hourglass_shown_p)
28591 hide_hourglass ();
28592 #endif
28593 }
28594 #endif /* ! WINDOWSNT */