Fix random crashes while scrolling backwards.
[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 /* If we hit the beginning of the displayed portion
14833 without finding the first row of a continued
14834 line, give up. */
14835 if (row <= w->current_matrix->rows)
14836 {
14837 rc = CURSOR_MOVEMENT_MUST_SCROLL;
14838 break;
14839 }
14840 xassert (row->enabled_p);
14841 --row;
14842 }
14843 }
14844 if (must_scroll)
14845 ;
14846 else if (rc != CURSOR_MOVEMENT_SUCCESS
14847 && MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row)
14848 && make_cursor_line_fully_visible_p)
14849 {
14850 if (PT == MATRIX_ROW_END_CHARPOS (row)
14851 && !row->ends_at_zv_p
14852 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
14853 rc = CURSOR_MOVEMENT_MUST_SCROLL;
14854 else if (row->height > window_box_height (w))
14855 {
14856 /* If we end up in a partially visible line, let's
14857 make it fully visible, except when it's taller
14858 than the window, in which case we can't do much
14859 about it. */
14860 *scroll_step = 1;
14861 rc = CURSOR_MOVEMENT_MUST_SCROLL;
14862 }
14863 else
14864 {
14865 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
14866 if (!cursor_row_fully_visible_p (w, 0, 1))
14867 rc = CURSOR_MOVEMENT_MUST_SCROLL;
14868 else
14869 rc = CURSOR_MOVEMENT_SUCCESS;
14870 }
14871 }
14872 else if (scroll_p)
14873 rc = CURSOR_MOVEMENT_MUST_SCROLL;
14874 else if (rc != CURSOR_MOVEMENT_SUCCESS
14875 && !NILP (BVAR (XBUFFER (w->buffer), bidi_display_reordering)))
14876 {
14877 /* With bidi-reordered rows, there could be more than
14878 one candidate row whose start and end positions
14879 occlude point. We need to let set_cursor_from_row
14880 find the best candidate. */
14881 /* FIXME: Revisit this when glyph ``spilling'' in
14882 continuation lines' rows is implemented for
14883 bidi-reordered rows. */
14884 int rv = 0;
14885
14886 do
14887 {
14888 int at_zv_p = 0, exact_match_p = 0;
14889
14890 if (MATRIX_ROW_START_CHARPOS (row) <= PT
14891 && PT <= MATRIX_ROW_END_CHARPOS (row)
14892 && cursor_row_p (row))
14893 rv |= set_cursor_from_row (w, row, w->current_matrix,
14894 0, 0, 0, 0);
14895 /* As soon as we've found the exact match for point,
14896 or the first suitable row whose ends_at_zv_p flag
14897 is set, we are done. */
14898 at_zv_p =
14899 MATRIX_ROW (w->current_matrix, w->cursor.vpos)->ends_at_zv_p;
14900 if (rv && !at_zv_p
14901 && w->cursor.hpos >= 0
14902 && w->cursor.hpos < MATRIX_ROW_USED (w->current_matrix,
14903 w->cursor.vpos))
14904 {
14905 struct glyph_row *candidate =
14906 MATRIX_ROW (w->current_matrix, w->cursor.vpos);
14907 struct glyph *g =
14908 candidate->glyphs[TEXT_AREA] + w->cursor.hpos;
14909 EMACS_INT endpos = MATRIX_ROW_END_CHARPOS (candidate);
14910
14911 exact_match_p =
14912 (BUFFERP (g->object) && g->charpos == PT)
14913 || (INTEGERP (g->object)
14914 && (g->charpos == PT
14915 || (g->charpos == 0 && endpos - 1 == PT)));
14916 }
14917 if (rv && (at_zv_p || exact_match_p))
14918 {
14919 rc = CURSOR_MOVEMENT_SUCCESS;
14920 break;
14921 }
14922 if (MATRIX_ROW_BOTTOM_Y (row) == last_y)
14923 break;
14924 ++row;
14925 }
14926 while (((MATRIX_ROW_CONTINUATION_LINE_P (row)
14927 || row->continued_p)
14928 && MATRIX_ROW_BOTTOM_Y (row) <= last_y)
14929 || (MATRIX_ROW_START_CHARPOS (row) == PT
14930 && MATRIX_ROW_BOTTOM_Y (row) < last_y));
14931 /* If we didn't find any candidate rows, or exited the
14932 loop before all the candidates were examined, signal
14933 to the caller that this method failed. */
14934 if (rc != CURSOR_MOVEMENT_SUCCESS
14935 && !(rv
14936 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
14937 && !row->continued_p))
14938 rc = CURSOR_MOVEMENT_MUST_SCROLL;
14939 else if (rv)
14940 rc = CURSOR_MOVEMENT_SUCCESS;
14941 }
14942 else
14943 {
14944 do
14945 {
14946 if (set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0))
14947 {
14948 rc = CURSOR_MOVEMENT_SUCCESS;
14949 break;
14950 }
14951 ++row;
14952 }
14953 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
14954 && MATRIX_ROW_START_CHARPOS (row) == PT
14955 && cursor_row_p (row));
14956 }
14957 }
14958 }
14959
14960 return rc;
14961 }
14962
14963 #if !defined USE_TOOLKIT_SCROLL_BARS || defined USE_GTK
14964 static
14965 #endif
14966 void
14967 set_vertical_scroll_bar (struct window *w)
14968 {
14969 EMACS_INT start, end, whole;
14970
14971 /* Calculate the start and end positions for the current window.
14972 At some point, it would be nice to choose between scrollbars
14973 which reflect the whole buffer size, with special markers
14974 indicating narrowing, and scrollbars which reflect only the
14975 visible region.
14976
14977 Note that mini-buffers sometimes aren't displaying any text. */
14978 if (!MINI_WINDOW_P (w)
14979 || (w == XWINDOW (minibuf_window)
14980 && NILP (echo_area_buffer[0])))
14981 {
14982 struct buffer *buf = XBUFFER (w->buffer);
14983 whole = BUF_ZV (buf) - BUF_BEGV (buf);
14984 start = marker_position (w->start) - BUF_BEGV (buf);
14985 /* I don't think this is guaranteed to be right. For the
14986 moment, we'll pretend it is. */
14987 end = BUF_Z (buf) - XFASTINT (w->window_end_pos) - BUF_BEGV (buf);
14988
14989 if (end < start)
14990 end = start;
14991 if (whole < (end - start))
14992 whole = end - start;
14993 }
14994 else
14995 start = end = whole = 0;
14996
14997 /* Indicate what this scroll bar ought to be displaying now. */
14998 if (FRAME_TERMINAL (XFRAME (w->frame))->set_vertical_scroll_bar_hook)
14999 (*FRAME_TERMINAL (XFRAME (w->frame))->set_vertical_scroll_bar_hook)
15000 (w, end - start, whole, start);
15001 }
15002
15003
15004 /* Redisplay leaf window WINDOW. JUST_THIS_ONE_P non-zero means only
15005 selected_window is redisplayed.
15006
15007 We can return without actually redisplaying the window if
15008 fonts_changed_p is nonzero. In that case, redisplay_internal will
15009 retry. */
15010
15011 static void
15012 redisplay_window (Lisp_Object window, int just_this_one_p)
15013 {
15014 struct window *w = XWINDOW (window);
15015 struct frame *f = XFRAME (w->frame);
15016 struct buffer *buffer = XBUFFER (w->buffer);
15017 struct buffer *old = current_buffer;
15018 struct text_pos lpoint, opoint, startp;
15019 int update_mode_line;
15020 int tem;
15021 struct it it;
15022 /* Record it now because it's overwritten. */
15023 int current_matrix_up_to_date_p = 0;
15024 int used_current_matrix_p = 0;
15025 /* This is less strict than current_matrix_up_to_date_p.
15026 It indictes that the buffer contents and narrowing are unchanged. */
15027 int buffer_unchanged_p = 0;
15028 int temp_scroll_step = 0;
15029 int count = SPECPDL_INDEX ();
15030 int rc;
15031 int centering_position = -1;
15032 int last_line_misfit = 0;
15033 EMACS_INT beg_unchanged, end_unchanged;
15034
15035 SET_TEXT_POS (lpoint, PT, PT_BYTE);
15036 opoint = lpoint;
15037
15038 /* W must be a leaf window here. */
15039 xassert (!NILP (w->buffer));
15040 #if GLYPH_DEBUG
15041 *w->desired_matrix->method = 0;
15042 #endif
15043
15044 restart:
15045 reconsider_clip_changes (w, buffer);
15046
15047 /* Has the mode line to be updated? */
15048 update_mode_line = (!NILP (w->update_mode_line)
15049 || update_mode_lines
15050 || buffer->clip_changed
15051 || buffer->prevent_redisplay_optimizations_p);
15052
15053 if (MINI_WINDOW_P (w))
15054 {
15055 if (w == XWINDOW (echo_area_window)
15056 && !NILP (echo_area_buffer[0]))
15057 {
15058 if (update_mode_line)
15059 /* We may have to update a tty frame's menu bar or a
15060 tool-bar. Example `M-x C-h C-h C-g'. */
15061 goto finish_menu_bars;
15062 else
15063 /* We've already displayed the echo area glyphs in this window. */
15064 goto finish_scroll_bars;
15065 }
15066 else if ((w != XWINDOW (minibuf_window)
15067 || minibuf_level == 0)
15068 /* When buffer is nonempty, redisplay window normally. */
15069 && BUF_Z (XBUFFER (w->buffer)) == BUF_BEG (XBUFFER (w->buffer))
15070 /* Quail displays non-mini buffers in minibuffer window.
15071 In that case, redisplay the window normally. */
15072 && !NILP (Fmemq (w->buffer, Vminibuffer_list)))
15073 {
15074 /* W is a mini-buffer window, but it's not active, so clear
15075 it. */
15076 int yb = window_text_bottom_y (w);
15077 struct glyph_row *row;
15078 int y;
15079
15080 for (y = 0, row = w->desired_matrix->rows;
15081 y < yb;
15082 y += row->height, ++row)
15083 blank_row (w, row, y);
15084 goto finish_scroll_bars;
15085 }
15086
15087 clear_glyph_matrix (w->desired_matrix);
15088 }
15089
15090 /* Otherwise set up data on this window; select its buffer and point
15091 value. */
15092 /* Really select the buffer, for the sake of buffer-local
15093 variables. */
15094 set_buffer_internal_1 (XBUFFER (w->buffer));
15095
15096 current_matrix_up_to_date_p
15097 = (!NILP (w->window_end_valid)
15098 && !current_buffer->clip_changed
15099 && !current_buffer->prevent_redisplay_optimizations_p
15100 && XFASTINT (w->last_modified) >= MODIFF
15101 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
15102
15103 /* Run the window-bottom-change-functions
15104 if it is possible that the text on the screen has changed
15105 (either due to modification of the text, or any other reason). */
15106 if (!current_matrix_up_to_date_p
15107 && !NILP (Vwindow_text_change_functions))
15108 {
15109 safe_run_hooks (Qwindow_text_change_functions);
15110 goto restart;
15111 }
15112
15113 beg_unchanged = BEG_UNCHANGED;
15114 end_unchanged = END_UNCHANGED;
15115
15116 SET_TEXT_POS (opoint, PT, PT_BYTE);
15117
15118 specbind (Qinhibit_point_motion_hooks, Qt);
15119
15120 buffer_unchanged_p
15121 = (!NILP (w->window_end_valid)
15122 && !current_buffer->clip_changed
15123 && XFASTINT (w->last_modified) >= MODIFF
15124 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
15125
15126 /* When windows_or_buffers_changed is non-zero, we can't rely on
15127 the window end being valid, so set it to nil there. */
15128 if (windows_or_buffers_changed)
15129 {
15130 /* If window starts on a continuation line, maybe adjust the
15131 window start in case the window's width changed. */
15132 if (XMARKER (w->start)->buffer == current_buffer)
15133 compute_window_start_on_continuation_line (w);
15134
15135 w->window_end_valid = Qnil;
15136 }
15137
15138 /* Some sanity checks. */
15139 CHECK_WINDOW_END (w);
15140 if (Z == Z_BYTE && CHARPOS (opoint) != BYTEPOS (opoint))
15141 abort ();
15142 if (BYTEPOS (opoint) < CHARPOS (opoint))
15143 abort ();
15144
15145 /* If %c is in mode line, update it if needed. */
15146 if (!NILP (w->column_number_displayed)
15147 /* This alternative quickly identifies a common case
15148 where no change is needed. */
15149 && !(PT == XFASTINT (w->last_point)
15150 && XFASTINT (w->last_modified) >= MODIFF
15151 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
15152 && (XFASTINT (w->column_number_displayed) != current_column ()))
15153 update_mode_line = 1;
15154
15155 /* Count number of windows showing the selected buffer. An indirect
15156 buffer counts as its base buffer. */
15157 if (!just_this_one_p)
15158 {
15159 struct buffer *current_base, *window_base;
15160 current_base = current_buffer;
15161 window_base = XBUFFER (XWINDOW (selected_window)->buffer);
15162 if (current_base->base_buffer)
15163 current_base = current_base->base_buffer;
15164 if (window_base->base_buffer)
15165 window_base = window_base->base_buffer;
15166 if (current_base == window_base)
15167 buffer_shared++;
15168 }
15169
15170 /* Point refers normally to the selected window. For any other
15171 window, set up appropriate value. */
15172 if (!EQ (window, selected_window))
15173 {
15174 EMACS_INT new_pt = XMARKER (w->pointm)->charpos;
15175 EMACS_INT new_pt_byte = marker_byte_position (w->pointm);
15176 if (new_pt < BEGV)
15177 {
15178 new_pt = BEGV;
15179 new_pt_byte = BEGV_BYTE;
15180 set_marker_both (w->pointm, Qnil, BEGV, BEGV_BYTE);
15181 }
15182 else if (new_pt > (ZV - 1))
15183 {
15184 new_pt = ZV;
15185 new_pt_byte = ZV_BYTE;
15186 set_marker_both (w->pointm, Qnil, ZV, ZV_BYTE);
15187 }
15188
15189 /* We don't use SET_PT so that the point-motion hooks don't run. */
15190 TEMP_SET_PT_BOTH (new_pt, new_pt_byte);
15191 }
15192
15193 /* If any of the character widths specified in the display table
15194 have changed, invalidate the width run cache. It's true that
15195 this may be a bit late to catch such changes, but the rest of
15196 redisplay goes (non-fatally) haywire when the display table is
15197 changed, so why should we worry about doing any better? */
15198 if (current_buffer->width_run_cache)
15199 {
15200 struct Lisp_Char_Table *disptab = buffer_display_table ();
15201
15202 if (! disptab_matches_widthtab (disptab,
15203 XVECTOR (BVAR (current_buffer, width_table))))
15204 {
15205 invalidate_region_cache (current_buffer,
15206 current_buffer->width_run_cache,
15207 BEG, Z);
15208 recompute_width_table (current_buffer, disptab);
15209 }
15210 }
15211
15212 /* If window-start is screwed up, choose a new one. */
15213 if (XMARKER (w->start)->buffer != current_buffer)
15214 goto recenter;
15215
15216 SET_TEXT_POS_FROM_MARKER (startp, w->start);
15217
15218 /* If someone specified a new starting point but did not insist,
15219 check whether it can be used. */
15220 if (!NILP (w->optional_new_start)
15221 && CHARPOS (startp) >= BEGV
15222 && CHARPOS (startp) <= ZV)
15223 {
15224 w->optional_new_start = Qnil;
15225 start_display (&it, w, startp);
15226 move_it_to (&it, PT, 0, it.last_visible_y, -1,
15227 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
15228 if (IT_CHARPOS (it) == PT)
15229 w->force_start = Qt;
15230 /* IT may overshoot PT if text at PT is invisible. */
15231 else if (IT_CHARPOS (it) > PT && CHARPOS (startp) <= PT)
15232 w->force_start = Qt;
15233 }
15234
15235 force_start:
15236
15237 /* Handle case where place to start displaying has been specified,
15238 unless the specified location is outside the accessible range. */
15239 if (!NILP (w->force_start)
15240 || w->frozen_window_start_p)
15241 {
15242 /* We set this later on if we have to adjust point. */
15243 int new_vpos = -1;
15244
15245 w->force_start = Qnil;
15246 w->vscroll = 0;
15247 w->window_end_valid = Qnil;
15248
15249 /* Forget any recorded base line for line number display. */
15250 if (!buffer_unchanged_p)
15251 w->base_line_number = Qnil;
15252
15253 /* Redisplay the mode line. Select the buffer properly for that.
15254 Also, run the hook window-scroll-functions
15255 because we have scrolled. */
15256 /* Note, we do this after clearing force_start because
15257 if there's an error, it is better to forget about force_start
15258 than to get into an infinite loop calling the hook functions
15259 and having them get more errors. */
15260 if (!update_mode_line
15261 || ! NILP (Vwindow_scroll_functions))
15262 {
15263 update_mode_line = 1;
15264 w->update_mode_line = Qt;
15265 startp = run_window_scroll_functions (window, startp);
15266 }
15267
15268 w->last_modified = make_number (0);
15269 w->last_overlay_modified = make_number (0);
15270 if (CHARPOS (startp) < BEGV)
15271 SET_TEXT_POS (startp, BEGV, BEGV_BYTE);
15272 else if (CHARPOS (startp) > ZV)
15273 SET_TEXT_POS (startp, ZV, ZV_BYTE);
15274
15275 /* Redisplay, then check if cursor has been set during the
15276 redisplay. Give up if new fonts were loaded. */
15277 /* We used to issue a CHECK_MARGINS argument to try_window here,
15278 but this causes scrolling to fail when point begins inside
15279 the scroll margin (bug#148) -- cyd */
15280 if (!try_window (window, startp, 0))
15281 {
15282 w->force_start = Qt;
15283 clear_glyph_matrix (w->desired_matrix);
15284 goto need_larger_matrices;
15285 }
15286
15287 if (w->cursor.vpos < 0 && !w->frozen_window_start_p)
15288 {
15289 /* If point does not appear, try to move point so it does
15290 appear. The desired matrix has been built above, so we
15291 can use it here. */
15292 new_vpos = window_box_height (w) / 2;
15293 }
15294
15295 if (!cursor_row_fully_visible_p (w, 0, 0))
15296 {
15297 /* Point does appear, but on a line partly visible at end of window.
15298 Move it back to a fully-visible line. */
15299 new_vpos = window_box_height (w);
15300 }
15301
15302 /* If we need to move point for either of the above reasons,
15303 now actually do it. */
15304 if (new_vpos >= 0)
15305 {
15306 struct glyph_row *row;
15307
15308 row = MATRIX_FIRST_TEXT_ROW (w->desired_matrix);
15309 while (MATRIX_ROW_BOTTOM_Y (row) < new_vpos)
15310 ++row;
15311
15312 TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row),
15313 MATRIX_ROW_START_BYTEPOS (row));
15314
15315 if (w != XWINDOW (selected_window))
15316 set_marker_both (w->pointm, Qnil, PT, PT_BYTE);
15317 else if (current_buffer == old)
15318 SET_TEXT_POS (lpoint, PT, PT_BYTE);
15319
15320 set_cursor_from_row (w, row, w->desired_matrix, 0, 0, 0, 0);
15321
15322 /* If we are highlighting the region, then we just changed
15323 the region, so redisplay to show it. */
15324 if (!NILP (Vtransient_mark_mode)
15325 && !NILP (BVAR (current_buffer, mark_active)))
15326 {
15327 clear_glyph_matrix (w->desired_matrix);
15328 if (!try_window (window, startp, 0))
15329 goto need_larger_matrices;
15330 }
15331 }
15332
15333 #if GLYPH_DEBUG
15334 debug_method_add (w, "forced window start");
15335 #endif
15336 goto done;
15337 }
15338
15339 /* Handle case where text has not changed, only point, and it has
15340 not moved off the frame, and we are not retrying after hscroll.
15341 (current_matrix_up_to_date_p is nonzero when retrying.) */
15342 if (current_matrix_up_to_date_p
15343 && (rc = try_cursor_movement (window, startp, &temp_scroll_step),
15344 rc != CURSOR_MOVEMENT_CANNOT_BE_USED))
15345 {
15346 switch (rc)
15347 {
15348 case CURSOR_MOVEMENT_SUCCESS:
15349 used_current_matrix_p = 1;
15350 goto done;
15351
15352 case CURSOR_MOVEMENT_MUST_SCROLL:
15353 goto try_to_scroll;
15354
15355 default:
15356 abort ();
15357 }
15358 }
15359 /* If current starting point was originally the beginning of a line
15360 but no longer is, find a new starting point. */
15361 else if (!NILP (w->start_at_line_beg)
15362 && !(CHARPOS (startp) <= BEGV
15363 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n'))
15364 {
15365 #if GLYPH_DEBUG
15366 debug_method_add (w, "recenter 1");
15367 #endif
15368 goto recenter;
15369 }
15370
15371 /* Try scrolling with try_window_id. Value is > 0 if update has
15372 been done, it is -1 if we know that the same window start will
15373 not work. It is 0 if unsuccessful for some other reason. */
15374 else if ((tem = try_window_id (w)) != 0)
15375 {
15376 #if GLYPH_DEBUG
15377 debug_method_add (w, "try_window_id %d", tem);
15378 #endif
15379
15380 if (fonts_changed_p)
15381 goto need_larger_matrices;
15382 if (tem > 0)
15383 goto done;
15384
15385 /* Otherwise try_window_id has returned -1 which means that we
15386 don't want the alternative below this comment to execute. */
15387 }
15388 else if (CHARPOS (startp) >= BEGV
15389 && CHARPOS (startp) <= ZV
15390 && PT >= CHARPOS (startp)
15391 && (CHARPOS (startp) < ZV
15392 /* Avoid starting at end of buffer. */
15393 || CHARPOS (startp) == BEGV
15394 || (XFASTINT (w->last_modified) >= MODIFF
15395 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)))
15396 {
15397 int d1, d2, d3, d4, d5, d6;
15398
15399 /* If first window line is a continuation line, and window start
15400 is inside the modified region, but the first change is before
15401 current window start, we must select a new window start.
15402
15403 However, if this is the result of a down-mouse event (e.g. by
15404 extending the mouse-drag-overlay), we don't want to select a
15405 new window start, since that would change the position under
15406 the mouse, resulting in an unwanted mouse-movement rather
15407 than a simple mouse-click. */
15408 if (NILP (w->start_at_line_beg)
15409 && NILP (do_mouse_tracking)
15410 && CHARPOS (startp) > BEGV
15411 && CHARPOS (startp) > BEG + beg_unchanged
15412 && CHARPOS (startp) <= Z - end_unchanged
15413 /* Even if w->start_at_line_beg is nil, a new window may
15414 start at a line_beg, since that's how set_buffer_window
15415 sets it. So, we need to check the return value of
15416 compute_window_start_on_continuation_line. (See also
15417 bug#197). */
15418 && XMARKER (w->start)->buffer == current_buffer
15419 && compute_window_start_on_continuation_line (w)
15420 /* It doesn't make sense to force the window start like we
15421 do at label force_start if it is already known that point
15422 will not be visible in the resulting window, because
15423 doing so will move point from its correct position
15424 instead of scrolling the window to bring point into view.
15425 See bug#9324. */
15426 && pos_visible_p (w, PT, &d1, &d2, &d3, &d4, &d5, &d6))
15427 {
15428 w->force_start = Qt;
15429 SET_TEXT_POS_FROM_MARKER (startp, w->start);
15430 goto force_start;
15431 }
15432
15433 #if GLYPH_DEBUG
15434 debug_method_add (w, "same window start");
15435 #endif
15436
15437 /* Try to redisplay starting at same place as before.
15438 If point has not moved off frame, accept the results. */
15439 if (!current_matrix_up_to_date_p
15440 /* Don't use try_window_reusing_current_matrix in this case
15441 because a window scroll function can have changed the
15442 buffer. */
15443 || !NILP (Vwindow_scroll_functions)
15444 || MINI_WINDOW_P (w)
15445 || !(used_current_matrix_p
15446 = try_window_reusing_current_matrix (w)))
15447 {
15448 IF_DEBUG (debug_method_add (w, "1"));
15449 if (try_window (window, startp, TRY_WINDOW_CHECK_MARGINS) < 0)
15450 /* -1 means we need to scroll.
15451 0 means we need new matrices, but fonts_changed_p
15452 is set in that case, so we will detect it below. */
15453 goto try_to_scroll;
15454 }
15455
15456 if (fonts_changed_p)
15457 goto need_larger_matrices;
15458
15459 if (w->cursor.vpos >= 0)
15460 {
15461 if (!just_this_one_p
15462 || current_buffer->clip_changed
15463 || BEG_UNCHANGED < CHARPOS (startp))
15464 /* Forget any recorded base line for line number display. */
15465 w->base_line_number = Qnil;
15466
15467 if (!cursor_row_fully_visible_p (w, 1, 0))
15468 {
15469 clear_glyph_matrix (w->desired_matrix);
15470 last_line_misfit = 1;
15471 }
15472 /* Drop through and scroll. */
15473 else
15474 goto done;
15475 }
15476 else
15477 clear_glyph_matrix (w->desired_matrix);
15478 }
15479
15480 try_to_scroll:
15481
15482 w->last_modified = make_number (0);
15483 w->last_overlay_modified = make_number (0);
15484
15485 /* Redisplay the mode line. Select the buffer properly for that. */
15486 if (!update_mode_line)
15487 {
15488 update_mode_line = 1;
15489 w->update_mode_line = Qt;
15490 }
15491
15492 /* Try to scroll by specified few lines. */
15493 if ((scroll_conservatively
15494 || emacs_scroll_step
15495 || temp_scroll_step
15496 || NUMBERP (BVAR (current_buffer, scroll_up_aggressively))
15497 || NUMBERP (BVAR (current_buffer, scroll_down_aggressively)))
15498 && CHARPOS (startp) >= BEGV
15499 && CHARPOS (startp) <= ZV)
15500 {
15501 /* The function returns -1 if new fonts were loaded, 1 if
15502 successful, 0 if not successful. */
15503 int ss = try_scrolling (window, just_this_one_p,
15504 scroll_conservatively,
15505 emacs_scroll_step,
15506 temp_scroll_step, last_line_misfit);
15507 switch (ss)
15508 {
15509 case SCROLLING_SUCCESS:
15510 goto done;
15511
15512 case SCROLLING_NEED_LARGER_MATRICES:
15513 goto need_larger_matrices;
15514
15515 case SCROLLING_FAILED:
15516 break;
15517
15518 default:
15519 abort ();
15520 }
15521 }
15522
15523 /* Finally, just choose a place to start which positions point
15524 according to user preferences. */
15525
15526 recenter:
15527
15528 #if GLYPH_DEBUG
15529 debug_method_add (w, "recenter");
15530 #endif
15531
15532 /* w->vscroll = 0; */
15533
15534 /* Forget any previously recorded base line for line number display. */
15535 if (!buffer_unchanged_p)
15536 w->base_line_number = Qnil;
15537
15538 /* Determine the window start relative to point. */
15539 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
15540 it.current_y = it.last_visible_y;
15541 if (centering_position < 0)
15542 {
15543 int margin =
15544 scroll_margin > 0
15545 ? min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4)
15546 : 0;
15547 EMACS_INT margin_pos = CHARPOS (startp);
15548 int scrolling_up;
15549 Lisp_Object aggressive;
15550
15551 /* If there is a scroll margin at the top of the window, find
15552 its character position. */
15553 if (margin
15554 /* Cannot call start_display if startp is not in the
15555 accessible region of the buffer. This can happen when we
15556 have just switched to a different buffer and/or changed
15557 its restriction. In that case, startp is initialized to
15558 the character position 1 (BEG) because we did not yet
15559 have chance to display the buffer even once. */
15560 && BEGV <= CHARPOS (startp) && CHARPOS (startp) <= ZV)
15561 {
15562 struct it it1;
15563 void *it1data = NULL;
15564
15565 SAVE_IT (it1, it, it1data);
15566 start_display (&it1, w, startp);
15567 move_it_vertically (&it1, margin);
15568 margin_pos = IT_CHARPOS (it1);
15569 RESTORE_IT (&it, &it, it1data);
15570 }
15571 scrolling_up = PT > margin_pos;
15572 aggressive =
15573 scrolling_up
15574 ? BVAR (current_buffer, scroll_up_aggressively)
15575 : BVAR (current_buffer, scroll_down_aggressively);
15576
15577 if (!MINI_WINDOW_P (w)
15578 && (scroll_conservatively > SCROLL_LIMIT || NUMBERP (aggressive)))
15579 {
15580 int pt_offset = 0;
15581
15582 /* Setting scroll-conservatively overrides
15583 scroll-*-aggressively. */
15584 if (!scroll_conservatively && NUMBERP (aggressive))
15585 {
15586 double float_amount = XFLOATINT (aggressive);
15587
15588 pt_offset = float_amount * WINDOW_BOX_TEXT_HEIGHT (w);
15589 if (pt_offset == 0 && float_amount > 0)
15590 pt_offset = 1;
15591 if (pt_offset)
15592 margin -= 1;
15593 }
15594 /* Compute how much to move the window start backward from
15595 point so that point will be displayed where the user
15596 wants it. */
15597 if (scrolling_up)
15598 {
15599 centering_position = it.last_visible_y;
15600 if (pt_offset)
15601 centering_position -= pt_offset;
15602 centering_position -=
15603 FRAME_LINE_HEIGHT (f) * (1 + margin + (last_line_misfit != 0))
15604 + WINDOW_HEADER_LINE_HEIGHT (w);
15605 /* Don't let point enter the scroll margin near top of
15606 the window. */
15607 if (centering_position < margin * FRAME_LINE_HEIGHT (f))
15608 centering_position = margin * FRAME_LINE_HEIGHT (f);
15609 }
15610 else
15611 centering_position = margin * FRAME_LINE_HEIGHT (f) + pt_offset;
15612 }
15613 else
15614 /* Set the window start half the height of the window backward
15615 from point. */
15616 centering_position = window_box_height (w) / 2;
15617 }
15618 move_it_vertically_backward (&it, centering_position);
15619
15620 xassert (IT_CHARPOS (it) >= BEGV);
15621
15622 /* The function move_it_vertically_backward may move over more
15623 than the specified y-distance. If it->w is small, e.g. a
15624 mini-buffer window, we may end up in front of the window's
15625 display area. Start displaying at the start of the line
15626 containing PT in this case. */
15627 if (it.current_y <= 0)
15628 {
15629 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
15630 move_it_vertically_backward (&it, 0);
15631 it.current_y = 0;
15632 }
15633
15634 it.current_x = it.hpos = 0;
15635
15636 /* Set the window start position here explicitly, to avoid an
15637 infinite loop in case the functions in window-scroll-functions
15638 get errors. */
15639 set_marker_both (w->start, Qnil, IT_CHARPOS (it), IT_BYTEPOS (it));
15640
15641 /* Run scroll hooks. */
15642 startp = run_window_scroll_functions (window, it.current.pos);
15643
15644 /* Redisplay the window. */
15645 if (!current_matrix_up_to_date_p
15646 || windows_or_buffers_changed
15647 || cursor_type_changed
15648 /* Don't use try_window_reusing_current_matrix in this case
15649 because it can have changed the buffer. */
15650 || !NILP (Vwindow_scroll_functions)
15651 || !just_this_one_p
15652 || MINI_WINDOW_P (w)
15653 || !(used_current_matrix_p
15654 = try_window_reusing_current_matrix (w)))
15655 try_window (window, startp, 0);
15656
15657 /* If new fonts have been loaded (due to fontsets), give up. We
15658 have to start a new redisplay since we need to re-adjust glyph
15659 matrices. */
15660 if (fonts_changed_p)
15661 goto need_larger_matrices;
15662
15663 /* If cursor did not appear assume that the middle of the window is
15664 in the first line of the window. Do it again with the next line.
15665 (Imagine a window of height 100, displaying two lines of height
15666 60. Moving back 50 from it->last_visible_y will end in the first
15667 line.) */
15668 if (w->cursor.vpos < 0)
15669 {
15670 if (!NILP (w->window_end_valid)
15671 && PT >= Z - XFASTINT (w->window_end_pos))
15672 {
15673 clear_glyph_matrix (w->desired_matrix);
15674 move_it_by_lines (&it, 1);
15675 try_window (window, it.current.pos, 0);
15676 }
15677 else if (PT < IT_CHARPOS (it))
15678 {
15679 clear_glyph_matrix (w->desired_matrix);
15680 move_it_by_lines (&it, -1);
15681 try_window (window, it.current.pos, 0);
15682 }
15683 else
15684 {
15685 /* Not much we can do about it. */
15686 }
15687 }
15688
15689 /* Consider the following case: Window starts at BEGV, there is
15690 invisible, intangible text at BEGV, so that display starts at
15691 some point START > BEGV. It can happen that we are called with
15692 PT somewhere between BEGV and START. Try to handle that case. */
15693 if (w->cursor.vpos < 0)
15694 {
15695 struct glyph_row *row = w->current_matrix->rows;
15696 if (row->mode_line_p)
15697 ++row;
15698 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
15699 }
15700
15701 if (!cursor_row_fully_visible_p (w, 0, 0))
15702 {
15703 /* If vscroll is enabled, disable it and try again. */
15704 if (w->vscroll)
15705 {
15706 w->vscroll = 0;
15707 clear_glyph_matrix (w->desired_matrix);
15708 goto recenter;
15709 }
15710
15711 /* If centering point failed to make the whole line visible,
15712 put point at the top instead. That has to make the whole line
15713 visible, if it can be done. */
15714 if (centering_position == 0)
15715 goto done;
15716
15717 clear_glyph_matrix (w->desired_matrix);
15718 centering_position = 0;
15719 goto recenter;
15720 }
15721
15722 done:
15723
15724 SET_TEXT_POS_FROM_MARKER (startp, w->start);
15725 w->start_at_line_beg = ((CHARPOS (startp) == BEGV
15726 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n')
15727 ? Qt : Qnil);
15728
15729 /* Display the mode line, if we must. */
15730 if ((update_mode_line
15731 /* If window not full width, must redo its mode line
15732 if (a) the window to its side is being redone and
15733 (b) we do a frame-based redisplay. This is a consequence
15734 of how inverted lines are drawn in frame-based redisplay. */
15735 || (!just_this_one_p
15736 && !FRAME_WINDOW_P (f)
15737 && !WINDOW_FULL_WIDTH_P (w))
15738 /* Line number to display. */
15739 || INTEGERP (w->base_line_pos)
15740 /* Column number is displayed and different from the one displayed. */
15741 || (!NILP (w->column_number_displayed)
15742 && (XFASTINT (w->column_number_displayed) != current_column ())))
15743 /* This means that the window has a mode line. */
15744 && (WINDOW_WANTS_MODELINE_P (w)
15745 || WINDOW_WANTS_HEADER_LINE_P (w)))
15746 {
15747 display_mode_lines (w);
15748
15749 /* If mode line height has changed, arrange for a thorough
15750 immediate redisplay using the correct mode line height. */
15751 if (WINDOW_WANTS_MODELINE_P (w)
15752 && CURRENT_MODE_LINE_HEIGHT (w) != DESIRED_MODE_LINE_HEIGHT (w))
15753 {
15754 fonts_changed_p = 1;
15755 MATRIX_MODE_LINE_ROW (w->current_matrix)->height
15756 = DESIRED_MODE_LINE_HEIGHT (w);
15757 }
15758
15759 /* If header line height has changed, arrange for a thorough
15760 immediate redisplay using the correct header line height. */
15761 if (WINDOW_WANTS_HEADER_LINE_P (w)
15762 && CURRENT_HEADER_LINE_HEIGHT (w) != DESIRED_HEADER_LINE_HEIGHT (w))
15763 {
15764 fonts_changed_p = 1;
15765 MATRIX_HEADER_LINE_ROW (w->current_matrix)->height
15766 = DESIRED_HEADER_LINE_HEIGHT (w);
15767 }
15768
15769 if (fonts_changed_p)
15770 goto need_larger_matrices;
15771 }
15772
15773 if (!line_number_displayed
15774 && !BUFFERP (w->base_line_pos))
15775 {
15776 w->base_line_pos = Qnil;
15777 w->base_line_number = Qnil;
15778 }
15779
15780 finish_menu_bars:
15781
15782 /* When we reach a frame's selected window, redo the frame's menu bar. */
15783 if (update_mode_line
15784 && EQ (FRAME_SELECTED_WINDOW (f), window))
15785 {
15786 int redisplay_menu_p = 0;
15787
15788 if (FRAME_WINDOW_P (f))
15789 {
15790 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
15791 || defined (HAVE_NS) || defined (USE_GTK)
15792 redisplay_menu_p = FRAME_EXTERNAL_MENU_BAR (f);
15793 #else
15794 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
15795 #endif
15796 }
15797 else
15798 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
15799
15800 if (redisplay_menu_p)
15801 display_menu_bar (w);
15802
15803 #ifdef HAVE_WINDOW_SYSTEM
15804 if (FRAME_WINDOW_P (f))
15805 {
15806 #if defined (USE_GTK) || defined (HAVE_NS)
15807 if (FRAME_EXTERNAL_TOOL_BAR (f))
15808 redisplay_tool_bar (f);
15809 #else
15810 if (WINDOWP (f->tool_bar_window)
15811 && (FRAME_TOOL_BAR_LINES (f) > 0
15812 || !NILP (Vauto_resize_tool_bars))
15813 && redisplay_tool_bar (f))
15814 ignore_mouse_drag_p = 1;
15815 #endif
15816 }
15817 #endif
15818 }
15819
15820 #ifdef HAVE_WINDOW_SYSTEM
15821 if (FRAME_WINDOW_P (f)
15822 && update_window_fringes (w, (just_this_one_p
15823 || (!used_current_matrix_p && !overlay_arrow_seen)
15824 || w->pseudo_window_p)))
15825 {
15826 update_begin (f);
15827 BLOCK_INPUT;
15828 if (draw_window_fringes (w, 1))
15829 x_draw_vertical_border (w);
15830 UNBLOCK_INPUT;
15831 update_end (f);
15832 }
15833 #endif /* HAVE_WINDOW_SYSTEM */
15834
15835 /* We go to this label, with fonts_changed_p nonzero,
15836 if it is necessary to try again using larger glyph matrices.
15837 We have to redeem the scroll bar even in this case,
15838 because the loop in redisplay_internal expects that. */
15839 need_larger_matrices:
15840 ;
15841 finish_scroll_bars:
15842
15843 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
15844 {
15845 /* Set the thumb's position and size. */
15846 set_vertical_scroll_bar (w);
15847
15848 /* Note that we actually used the scroll bar attached to this
15849 window, so it shouldn't be deleted at the end of redisplay. */
15850 if (FRAME_TERMINAL (f)->redeem_scroll_bar_hook)
15851 (*FRAME_TERMINAL (f)->redeem_scroll_bar_hook) (w);
15852 }
15853
15854 /* Restore current_buffer and value of point in it. The window
15855 update may have changed the buffer, so first make sure `opoint'
15856 is still valid (Bug#6177). */
15857 if (CHARPOS (opoint) < BEGV)
15858 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
15859 else if (CHARPOS (opoint) > ZV)
15860 TEMP_SET_PT_BOTH (Z, Z_BYTE);
15861 else
15862 TEMP_SET_PT_BOTH (CHARPOS (opoint), BYTEPOS (opoint));
15863
15864 set_buffer_internal_1 (old);
15865 /* Avoid an abort in TEMP_SET_PT_BOTH if the buffer has become
15866 shorter. This can be caused by log truncation in *Messages*. */
15867 if (CHARPOS (lpoint) <= ZV)
15868 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
15869
15870 unbind_to (count, Qnil);
15871 }
15872
15873
15874 /* Build the complete desired matrix of WINDOW with a window start
15875 buffer position POS.
15876
15877 Value is 1 if successful. It is zero if fonts were loaded during
15878 redisplay which makes re-adjusting glyph matrices necessary, and -1
15879 if point would appear in the scroll margins.
15880 (We check the former only if TRY_WINDOW_IGNORE_FONTS_CHANGE is
15881 unset in FLAGS, and the latter only if TRY_WINDOW_CHECK_MARGINS is
15882 set in FLAGS.) */
15883
15884 int
15885 try_window (Lisp_Object window, struct text_pos pos, int flags)
15886 {
15887 struct window *w = XWINDOW (window);
15888 struct it it;
15889 struct glyph_row *last_text_row = NULL;
15890 struct frame *f = XFRAME (w->frame);
15891
15892 /* Make POS the new window start. */
15893 set_marker_both (w->start, Qnil, CHARPOS (pos), BYTEPOS (pos));
15894
15895 /* Mark cursor position as unknown. No overlay arrow seen. */
15896 w->cursor.vpos = -1;
15897 overlay_arrow_seen = 0;
15898
15899 /* Initialize iterator and info to start at POS. */
15900 start_display (&it, w, pos);
15901
15902 /* Display all lines of W. */
15903 while (it.current_y < it.last_visible_y)
15904 {
15905 if (display_line (&it))
15906 last_text_row = it.glyph_row - 1;
15907 if (fonts_changed_p && !(flags & TRY_WINDOW_IGNORE_FONTS_CHANGE))
15908 return 0;
15909 }
15910
15911 /* Don't let the cursor end in the scroll margins. */
15912 if ((flags & TRY_WINDOW_CHECK_MARGINS)
15913 && !MINI_WINDOW_P (w))
15914 {
15915 int this_scroll_margin;
15916
15917 if (scroll_margin > 0)
15918 {
15919 this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
15920 this_scroll_margin *= FRAME_LINE_HEIGHT (f);
15921 }
15922 else
15923 this_scroll_margin = 0;
15924
15925 if ((w->cursor.y >= 0 /* not vscrolled */
15926 && w->cursor.y < this_scroll_margin
15927 && CHARPOS (pos) > BEGV
15928 && IT_CHARPOS (it) < ZV)
15929 /* rms: considering make_cursor_line_fully_visible_p here
15930 seems to give wrong results. We don't want to recenter
15931 when the last line is partly visible, we want to allow
15932 that case to be handled in the usual way. */
15933 || w->cursor.y > it.last_visible_y - this_scroll_margin - 1)
15934 {
15935 w->cursor.vpos = -1;
15936 clear_glyph_matrix (w->desired_matrix);
15937 return -1;
15938 }
15939 }
15940
15941 /* If bottom moved off end of frame, change mode line percentage. */
15942 if (XFASTINT (w->window_end_pos) <= 0
15943 && Z != IT_CHARPOS (it))
15944 w->update_mode_line = Qt;
15945
15946 /* Set window_end_pos to the offset of the last character displayed
15947 on the window from the end of current_buffer. Set
15948 window_end_vpos to its row number. */
15949 if (last_text_row)
15950 {
15951 xassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row));
15952 w->window_end_bytepos
15953 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
15954 w->window_end_pos
15955 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
15956 w->window_end_vpos
15957 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
15958 xassert (MATRIX_ROW (w->desired_matrix, XFASTINT (w->window_end_vpos))
15959 ->displays_text_p);
15960 }
15961 else
15962 {
15963 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
15964 w->window_end_pos = make_number (Z - ZV);
15965 w->window_end_vpos = make_number (0);
15966 }
15967
15968 /* But that is not valid info until redisplay finishes. */
15969 w->window_end_valid = Qnil;
15970 return 1;
15971 }
15972
15973
15974 \f
15975 /************************************************************************
15976 Window redisplay reusing current matrix when buffer has not changed
15977 ************************************************************************/
15978
15979 /* Try redisplay of window W showing an unchanged buffer with a
15980 different window start than the last time it was displayed by
15981 reusing its current matrix. Value is non-zero if successful.
15982 W->start is the new window start. */
15983
15984 static int
15985 try_window_reusing_current_matrix (struct window *w)
15986 {
15987 struct frame *f = XFRAME (w->frame);
15988 struct glyph_row *bottom_row;
15989 struct it it;
15990 struct run run;
15991 struct text_pos start, new_start;
15992 int nrows_scrolled, i;
15993 struct glyph_row *last_text_row;
15994 struct glyph_row *last_reused_text_row;
15995 struct glyph_row *start_row;
15996 int start_vpos, min_y, max_y;
15997
15998 #if GLYPH_DEBUG
15999 if (inhibit_try_window_reusing)
16000 return 0;
16001 #endif
16002
16003 if (/* This function doesn't handle terminal frames. */
16004 !FRAME_WINDOW_P (f)
16005 /* Don't try to reuse the display if windows have been split
16006 or such. */
16007 || windows_or_buffers_changed
16008 || cursor_type_changed)
16009 return 0;
16010
16011 /* Can't do this if region may have changed. */
16012 if ((!NILP (Vtransient_mark_mode)
16013 && !NILP (BVAR (current_buffer, mark_active)))
16014 || !NILP (w->region_showing)
16015 || !NILP (Vshow_trailing_whitespace))
16016 return 0;
16017
16018 /* If top-line visibility has changed, give up. */
16019 if (WINDOW_WANTS_HEADER_LINE_P (w)
16020 != MATRIX_HEADER_LINE_ROW (w->current_matrix)->mode_line_p)
16021 return 0;
16022
16023 /* Give up if old or new display is scrolled vertically. We could
16024 make this function handle this, but right now it doesn't. */
16025 start_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
16026 if (w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row))
16027 return 0;
16028
16029 /* The variable new_start now holds the new window start. The old
16030 start `start' can be determined from the current matrix. */
16031 SET_TEXT_POS_FROM_MARKER (new_start, w->start);
16032 start = start_row->minpos;
16033 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
16034
16035 /* Clear the desired matrix for the display below. */
16036 clear_glyph_matrix (w->desired_matrix);
16037
16038 if (CHARPOS (new_start) <= CHARPOS (start))
16039 {
16040 /* Don't use this method if the display starts with an ellipsis
16041 displayed for invisible text. It's not easy to handle that case
16042 below, and it's certainly not worth the effort since this is
16043 not a frequent case. */
16044 if (in_ellipses_for_invisible_text_p (&start_row->start, w))
16045 return 0;
16046
16047 IF_DEBUG (debug_method_add (w, "twu1"));
16048
16049 /* Display up to a row that can be reused. The variable
16050 last_text_row is set to the last row displayed that displays
16051 text. Note that it.vpos == 0 if or if not there is a
16052 header-line; it's not the same as the MATRIX_ROW_VPOS! */
16053 start_display (&it, w, new_start);
16054 w->cursor.vpos = -1;
16055 last_text_row = last_reused_text_row = NULL;
16056
16057 while (it.current_y < it.last_visible_y
16058 && !fonts_changed_p)
16059 {
16060 /* If we have reached into the characters in the START row,
16061 that means the line boundaries have changed. So we
16062 can't start copying with the row START. Maybe it will
16063 work to start copying with the following row. */
16064 while (IT_CHARPOS (it) > CHARPOS (start))
16065 {
16066 /* Advance to the next row as the "start". */
16067 start_row++;
16068 start = start_row->minpos;
16069 /* If there are no more rows to try, or just one, give up. */
16070 if (start_row == MATRIX_MODE_LINE_ROW (w->current_matrix) - 1
16071 || w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row)
16072 || CHARPOS (start) == ZV)
16073 {
16074 clear_glyph_matrix (w->desired_matrix);
16075 return 0;
16076 }
16077
16078 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
16079 }
16080 /* If we have reached alignment, we can copy the rest of the
16081 rows. */
16082 if (IT_CHARPOS (it) == CHARPOS (start)
16083 /* Don't accept "alignment" inside a display vector,
16084 since start_row could have started in the middle of
16085 that same display vector (thus their character
16086 positions match), and we have no way of telling if
16087 that is the case. */
16088 && it.current.dpvec_index < 0)
16089 break;
16090
16091 if (display_line (&it))
16092 last_text_row = it.glyph_row - 1;
16093
16094 }
16095
16096 /* A value of current_y < last_visible_y means that we stopped
16097 at the previous window start, which in turn means that we
16098 have at least one reusable row. */
16099 if (it.current_y < it.last_visible_y)
16100 {
16101 struct glyph_row *row;
16102
16103 /* IT.vpos always starts from 0; it counts text lines. */
16104 nrows_scrolled = it.vpos - (start_row - MATRIX_FIRST_TEXT_ROW (w->current_matrix));
16105
16106 /* Find PT if not already found in the lines displayed. */
16107 if (w->cursor.vpos < 0)
16108 {
16109 int dy = it.current_y - start_row->y;
16110
16111 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
16112 row = row_containing_pos (w, PT, row, NULL, dy);
16113 if (row)
16114 set_cursor_from_row (w, row, w->current_matrix, 0, 0,
16115 dy, nrows_scrolled);
16116 else
16117 {
16118 clear_glyph_matrix (w->desired_matrix);
16119 return 0;
16120 }
16121 }
16122
16123 /* Scroll the display. Do it before the current matrix is
16124 changed. The problem here is that update has not yet
16125 run, i.e. part of the current matrix is not up to date.
16126 scroll_run_hook will clear the cursor, and use the
16127 current matrix to get the height of the row the cursor is
16128 in. */
16129 run.current_y = start_row->y;
16130 run.desired_y = it.current_y;
16131 run.height = it.last_visible_y - it.current_y;
16132
16133 if (run.height > 0 && run.current_y != run.desired_y)
16134 {
16135 update_begin (f);
16136 FRAME_RIF (f)->update_window_begin_hook (w);
16137 FRAME_RIF (f)->clear_window_mouse_face (w);
16138 FRAME_RIF (f)->scroll_run_hook (w, &run);
16139 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
16140 update_end (f);
16141 }
16142
16143 /* Shift current matrix down by nrows_scrolled lines. */
16144 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
16145 rotate_matrix (w->current_matrix,
16146 start_vpos,
16147 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
16148 nrows_scrolled);
16149
16150 /* Disable lines that must be updated. */
16151 for (i = 0; i < nrows_scrolled; ++i)
16152 (start_row + i)->enabled_p = 0;
16153
16154 /* Re-compute Y positions. */
16155 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
16156 max_y = it.last_visible_y;
16157 for (row = start_row + nrows_scrolled;
16158 row < bottom_row;
16159 ++row)
16160 {
16161 row->y = it.current_y;
16162 row->visible_height = row->height;
16163
16164 if (row->y < min_y)
16165 row->visible_height -= min_y - row->y;
16166 if (row->y + row->height > max_y)
16167 row->visible_height -= row->y + row->height - max_y;
16168 if (row->fringe_bitmap_periodic_p)
16169 row->redraw_fringe_bitmaps_p = 1;
16170
16171 it.current_y += row->height;
16172
16173 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
16174 last_reused_text_row = row;
16175 if (MATRIX_ROW_BOTTOM_Y (row) >= it.last_visible_y)
16176 break;
16177 }
16178
16179 /* Disable lines in the current matrix which are now
16180 below the window. */
16181 for (++row; row < bottom_row; ++row)
16182 row->enabled_p = row->mode_line_p = 0;
16183 }
16184
16185 /* Update window_end_pos etc.; last_reused_text_row is the last
16186 reused row from the current matrix containing text, if any.
16187 The value of last_text_row is the last displayed line
16188 containing text. */
16189 if (last_reused_text_row)
16190 {
16191 w->window_end_bytepos
16192 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_reused_text_row);
16193 w->window_end_pos
16194 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_reused_text_row));
16195 w->window_end_vpos
16196 = make_number (MATRIX_ROW_VPOS (last_reused_text_row,
16197 w->current_matrix));
16198 }
16199 else if (last_text_row)
16200 {
16201 w->window_end_bytepos
16202 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
16203 w->window_end_pos
16204 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
16205 w->window_end_vpos
16206 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
16207 }
16208 else
16209 {
16210 /* This window must be completely empty. */
16211 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
16212 w->window_end_pos = make_number (Z - ZV);
16213 w->window_end_vpos = make_number (0);
16214 }
16215 w->window_end_valid = Qnil;
16216
16217 /* Update hint: don't try scrolling again in update_window. */
16218 w->desired_matrix->no_scrolling_p = 1;
16219
16220 #if GLYPH_DEBUG
16221 debug_method_add (w, "try_window_reusing_current_matrix 1");
16222 #endif
16223 return 1;
16224 }
16225 else if (CHARPOS (new_start) > CHARPOS (start))
16226 {
16227 struct glyph_row *pt_row, *row;
16228 struct glyph_row *first_reusable_row;
16229 struct glyph_row *first_row_to_display;
16230 int dy;
16231 int yb = window_text_bottom_y (w);
16232
16233 /* Find the row starting at new_start, if there is one. Don't
16234 reuse a partially visible line at the end. */
16235 first_reusable_row = start_row;
16236 while (first_reusable_row->enabled_p
16237 && MATRIX_ROW_BOTTOM_Y (first_reusable_row) < yb
16238 && (MATRIX_ROW_START_CHARPOS (first_reusable_row)
16239 < CHARPOS (new_start)))
16240 ++first_reusable_row;
16241
16242 /* Give up if there is no row to reuse. */
16243 if (MATRIX_ROW_BOTTOM_Y (first_reusable_row) >= yb
16244 || !first_reusable_row->enabled_p
16245 || (MATRIX_ROW_START_CHARPOS (first_reusable_row)
16246 != CHARPOS (new_start)))
16247 return 0;
16248
16249 /* We can reuse fully visible rows beginning with
16250 first_reusable_row to the end of the window. Set
16251 first_row_to_display to the first row that cannot be reused.
16252 Set pt_row to the row containing point, if there is any. */
16253 pt_row = NULL;
16254 for (first_row_to_display = first_reusable_row;
16255 MATRIX_ROW_BOTTOM_Y (first_row_to_display) < yb;
16256 ++first_row_to_display)
16257 {
16258 if (PT >= MATRIX_ROW_START_CHARPOS (first_row_to_display)
16259 && PT < MATRIX_ROW_END_CHARPOS (first_row_to_display))
16260 pt_row = first_row_to_display;
16261 }
16262
16263 /* Start displaying at the start of first_row_to_display. */
16264 xassert (first_row_to_display->y < yb);
16265 init_to_row_start (&it, w, first_row_to_display);
16266
16267 nrows_scrolled = (MATRIX_ROW_VPOS (first_reusable_row, w->current_matrix)
16268 - start_vpos);
16269 it.vpos = (MATRIX_ROW_VPOS (first_row_to_display, w->current_matrix)
16270 - nrows_scrolled);
16271 it.current_y = (first_row_to_display->y - first_reusable_row->y
16272 + WINDOW_HEADER_LINE_HEIGHT (w));
16273
16274 /* Display lines beginning with first_row_to_display in the
16275 desired matrix. Set last_text_row to the last row displayed
16276 that displays text. */
16277 it.glyph_row = MATRIX_ROW (w->desired_matrix, it.vpos);
16278 if (pt_row == NULL)
16279 w->cursor.vpos = -1;
16280 last_text_row = NULL;
16281 while (it.current_y < it.last_visible_y && !fonts_changed_p)
16282 if (display_line (&it))
16283 last_text_row = it.glyph_row - 1;
16284
16285 /* If point is in a reused row, adjust y and vpos of the cursor
16286 position. */
16287 if (pt_row)
16288 {
16289 w->cursor.vpos -= nrows_scrolled;
16290 w->cursor.y -= first_reusable_row->y - start_row->y;
16291 }
16292
16293 /* Give up if point isn't in a row displayed or reused. (This
16294 also handles the case where w->cursor.vpos < nrows_scrolled
16295 after the calls to display_line, which can happen with scroll
16296 margins. See bug#1295.) */
16297 if (w->cursor.vpos < 0)
16298 {
16299 clear_glyph_matrix (w->desired_matrix);
16300 return 0;
16301 }
16302
16303 /* Scroll the display. */
16304 run.current_y = first_reusable_row->y;
16305 run.desired_y = WINDOW_HEADER_LINE_HEIGHT (w);
16306 run.height = it.last_visible_y - run.current_y;
16307 dy = run.current_y - run.desired_y;
16308
16309 if (run.height)
16310 {
16311 update_begin (f);
16312 FRAME_RIF (f)->update_window_begin_hook (w);
16313 FRAME_RIF (f)->clear_window_mouse_face (w);
16314 FRAME_RIF (f)->scroll_run_hook (w, &run);
16315 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
16316 update_end (f);
16317 }
16318
16319 /* Adjust Y positions of reused rows. */
16320 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
16321 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
16322 max_y = it.last_visible_y;
16323 for (row = first_reusable_row; row < first_row_to_display; ++row)
16324 {
16325 row->y -= dy;
16326 row->visible_height = row->height;
16327 if (row->y < min_y)
16328 row->visible_height -= min_y - row->y;
16329 if (row->y + row->height > max_y)
16330 row->visible_height -= row->y + row->height - max_y;
16331 if (row->fringe_bitmap_periodic_p)
16332 row->redraw_fringe_bitmaps_p = 1;
16333 }
16334
16335 /* Scroll the current matrix. */
16336 xassert (nrows_scrolled > 0);
16337 rotate_matrix (w->current_matrix,
16338 start_vpos,
16339 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
16340 -nrows_scrolled);
16341
16342 /* Disable rows not reused. */
16343 for (row -= nrows_scrolled; row < bottom_row; ++row)
16344 row->enabled_p = 0;
16345
16346 /* Point may have moved to a different line, so we cannot assume that
16347 the previous cursor position is valid; locate the correct row. */
16348 if (pt_row)
16349 {
16350 for (row = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
16351 row < bottom_row && PT >= MATRIX_ROW_END_CHARPOS (row);
16352 row++)
16353 {
16354 w->cursor.vpos++;
16355 w->cursor.y = row->y;
16356 }
16357 if (row < bottom_row)
16358 {
16359 struct glyph *glyph = row->glyphs[TEXT_AREA] + w->cursor.hpos;
16360 struct glyph *end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
16361
16362 /* Can't use this optimization with bidi-reordered glyph
16363 rows, unless cursor is already at point. */
16364 if (!NILP (BVAR (XBUFFER (w->buffer), bidi_display_reordering)))
16365 {
16366 if (!(w->cursor.hpos >= 0
16367 && w->cursor.hpos < row->used[TEXT_AREA]
16368 && BUFFERP (glyph->object)
16369 && glyph->charpos == PT))
16370 return 0;
16371 }
16372 else
16373 for (; glyph < end
16374 && (!BUFFERP (glyph->object)
16375 || glyph->charpos < PT);
16376 glyph++)
16377 {
16378 w->cursor.hpos++;
16379 w->cursor.x += glyph->pixel_width;
16380 }
16381 }
16382 }
16383
16384 /* Adjust window end. A null value of last_text_row means that
16385 the window end is in reused rows which in turn means that
16386 only its vpos can have changed. */
16387 if (last_text_row)
16388 {
16389 w->window_end_bytepos
16390 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
16391 w->window_end_pos
16392 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
16393 w->window_end_vpos
16394 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
16395 }
16396 else
16397 {
16398 w->window_end_vpos
16399 = make_number (XFASTINT (w->window_end_vpos) - nrows_scrolled);
16400 }
16401
16402 w->window_end_valid = Qnil;
16403 w->desired_matrix->no_scrolling_p = 1;
16404
16405 #if GLYPH_DEBUG
16406 debug_method_add (w, "try_window_reusing_current_matrix 2");
16407 #endif
16408 return 1;
16409 }
16410
16411 return 0;
16412 }
16413
16414
16415 \f
16416 /************************************************************************
16417 Window redisplay reusing current matrix when buffer has changed
16418 ************************************************************************/
16419
16420 static struct glyph_row *find_last_unchanged_at_beg_row (struct window *);
16421 static struct glyph_row *find_first_unchanged_at_end_row (struct window *,
16422 EMACS_INT *, EMACS_INT *);
16423 static struct glyph_row *
16424 find_last_row_displaying_text (struct glyph_matrix *, struct it *,
16425 struct glyph_row *);
16426
16427
16428 /* Return the last row in MATRIX displaying text. If row START is
16429 non-null, start searching with that row. IT gives the dimensions
16430 of the display. Value is null if matrix is empty; otherwise it is
16431 a pointer to the row found. */
16432
16433 static struct glyph_row *
16434 find_last_row_displaying_text (struct glyph_matrix *matrix, struct it *it,
16435 struct glyph_row *start)
16436 {
16437 struct glyph_row *row, *row_found;
16438
16439 /* Set row_found to the last row in IT->w's current matrix
16440 displaying text. The loop looks funny but think of partially
16441 visible lines. */
16442 row_found = NULL;
16443 row = start ? start : MATRIX_FIRST_TEXT_ROW (matrix);
16444 while (MATRIX_ROW_DISPLAYS_TEXT_P (row))
16445 {
16446 xassert (row->enabled_p);
16447 row_found = row;
16448 if (MATRIX_ROW_BOTTOM_Y (row) >= it->last_visible_y)
16449 break;
16450 ++row;
16451 }
16452
16453 return row_found;
16454 }
16455
16456
16457 /* Return the last row in the current matrix of W that is not affected
16458 by changes at the start of current_buffer that occurred since W's
16459 current matrix was built. Value is null if no such row exists.
16460
16461 BEG_UNCHANGED us the number of characters unchanged at the start of
16462 current_buffer. BEG + BEG_UNCHANGED is the buffer position of the
16463 first changed character in current_buffer. Characters at positions <
16464 BEG + BEG_UNCHANGED are at the same buffer positions as they were
16465 when the current matrix was built. */
16466
16467 static struct glyph_row *
16468 find_last_unchanged_at_beg_row (struct window *w)
16469 {
16470 EMACS_INT first_changed_pos = BEG + BEG_UNCHANGED;
16471 struct glyph_row *row;
16472 struct glyph_row *row_found = NULL;
16473 int yb = window_text_bottom_y (w);
16474
16475 /* Find the last row displaying unchanged text. */
16476 for (row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
16477 MATRIX_ROW_DISPLAYS_TEXT_P (row)
16478 && MATRIX_ROW_START_CHARPOS (row) < first_changed_pos;
16479 ++row)
16480 {
16481 if (/* If row ends before first_changed_pos, it is unchanged,
16482 except in some case. */
16483 MATRIX_ROW_END_CHARPOS (row) <= first_changed_pos
16484 /* When row ends in ZV and we write at ZV it is not
16485 unchanged. */
16486 && !row->ends_at_zv_p
16487 /* When first_changed_pos is the end of a continued line,
16488 row is not unchanged because it may be no longer
16489 continued. */
16490 && !(MATRIX_ROW_END_CHARPOS (row) == first_changed_pos
16491 && (row->continued_p
16492 || row->exact_window_width_line_p)))
16493 row_found = row;
16494
16495 /* Stop if last visible row. */
16496 if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
16497 break;
16498 }
16499
16500 return row_found;
16501 }
16502
16503
16504 /* Find the first glyph row in the current matrix of W that is not
16505 affected by changes at the end of current_buffer since the
16506 time W's current matrix was built.
16507
16508 Return in *DELTA the number of chars by which buffer positions in
16509 unchanged text at the end of current_buffer must be adjusted.
16510
16511 Return in *DELTA_BYTES the corresponding number of bytes.
16512
16513 Value is null if no such row exists, i.e. all rows are affected by
16514 changes. */
16515
16516 static struct glyph_row *
16517 find_first_unchanged_at_end_row (struct window *w,
16518 EMACS_INT *delta, EMACS_INT *delta_bytes)
16519 {
16520 struct glyph_row *row;
16521 struct glyph_row *row_found = NULL;
16522
16523 *delta = *delta_bytes = 0;
16524
16525 /* Display must not have been paused, otherwise the current matrix
16526 is not up to date. */
16527 eassert (!NILP (w->window_end_valid));
16528
16529 /* A value of window_end_pos >= END_UNCHANGED means that the window
16530 end is in the range of changed text. If so, there is no
16531 unchanged row at the end of W's current matrix. */
16532 if (XFASTINT (w->window_end_pos) >= END_UNCHANGED)
16533 return NULL;
16534
16535 /* Set row to the last row in W's current matrix displaying text. */
16536 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
16537
16538 /* If matrix is entirely empty, no unchanged row exists. */
16539 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
16540 {
16541 /* The value of row is the last glyph row in the matrix having a
16542 meaningful buffer position in it. The end position of row
16543 corresponds to window_end_pos. This allows us to translate
16544 buffer positions in the current matrix to current buffer
16545 positions for characters not in changed text. */
16546 EMACS_INT Z_old =
16547 MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
16548 EMACS_INT Z_BYTE_old =
16549 MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
16550 EMACS_INT last_unchanged_pos, last_unchanged_pos_old;
16551 struct glyph_row *first_text_row
16552 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
16553
16554 *delta = Z - Z_old;
16555 *delta_bytes = Z_BYTE - Z_BYTE_old;
16556
16557 /* Set last_unchanged_pos to the buffer position of the last
16558 character in the buffer that has not been changed. Z is the
16559 index + 1 of the last character in current_buffer, i.e. by
16560 subtracting END_UNCHANGED we get the index of the last
16561 unchanged character, and we have to add BEG to get its buffer
16562 position. */
16563 last_unchanged_pos = Z - END_UNCHANGED + BEG;
16564 last_unchanged_pos_old = last_unchanged_pos - *delta;
16565
16566 /* Search backward from ROW for a row displaying a line that
16567 starts at a minimum position >= last_unchanged_pos_old. */
16568 for (; row > first_text_row; --row)
16569 {
16570 /* This used to abort, but it can happen.
16571 It is ok to just stop the search instead here. KFS. */
16572 if (!row->enabled_p || !MATRIX_ROW_DISPLAYS_TEXT_P (row))
16573 break;
16574
16575 if (MATRIX_ROW_START_CHARPOS (row) >= last_unchanged_pos_old)
16576 row_found = row;
16577 }
16578 }
16579
16580 eassert (!row_found || MATRIX_ROW_DISPLAYS_TEXT_P (row_found));
16581
16582 return row_found;
16583 }
16584
16585
16586 /* Make sure that glyph rows in the current matrix of window W
16587 reference the same glyph memory as corresponding rows in the
16588 frame's frame matrix. This function is called after scrolling W's
16589 current matrix on a terminal frame in try_window_id and
16590 try_window_reusing_current_matrix. */
16591
16592 static void
16593 sync_frame_with_window_matrix_rows (struct window *w)
16594 {
16595 struct frame *f = XFRAME (w->frame);
16596 struct glyph_row *window_row, *window_row_end, *frame_row;
16597
16598 /* Preconditions: W must be a leaf window and full-width. Its frame
16599 must have a frame matrix. */
16600 xassert (NILP (w->hchild) && NILP (w->vchild));
16601 xassert (WINDOW_FULL_WIDTH_P (w));
16602 xassert (!FRAME_WINDOW_P (f));
16603
16604 /* If W is a full-width window, glyph pointers in W's current matrix
16605 have, by definition, to be the same as glyph pointers in the
16606 corresponding frame matrix. Note that frame matrices have no
16607 marginal areas (see build_frame_matrix). */
16608 window_row = w->current_matrix->rows;
16609 window_row_end = window_row + w->current_matrix->nrows;
16610 frame_row = f->current_matrix->rows + WINDOW_TOP_EDGE_LINE (w);
16611 while (window_row < window_row_end)
16612 {
16613 struct glyph *start = window_row->glyphs[LEFT_MARGIN_AREA];
16614 struct glyph *end = window_row->glyphs[LAST_AREA];
16615
16616 frame_row->glyphs[LEFT_MARGIN_AREA] = start;
16617 frame_row->glyphs[TEXT_AREA] = start;
16618 frame_row->glyphs[RIGHT_MARGIN_AREA] = end;
16619 frame_row->glyphs[LAST_AREA] = end;
16620
16621 /* Disable frame rows whose corresponding window rows have
16622 been disabled in try_window_id. */
16623 if (!window_row->enabled_p)
16624 frame_row->enabled_p = 0;
16625
16626 ++window_row, ++frame_row;
16627 }
16628 }
16629
16630
16631 /* Find the glyph row in window W containing CHARPOS. Consider all
16632 rows between START and END (not inclusive). END null means search
16633 all rows to the end of the display area of W. Value is the row
16634 containing CHARPOS or null. */
16635
16636 struct glyph_row *
16637 row_containing_pos (struct window *w, EMACS_INT charpos,
16638 struct glyph_row *start, struct glyph_row *end, int dy)
16639 {
16640 struct glyph_row *row = start;
16641 struct glyph_row *best_row = NULL;
16642 EMACS_INT mindif = BUF_ZV (XBUFFER (w->buffer)) + 1;
16643 int last_y;
16644
16645 /* If we happen to start on a header-line, skip that. */
16646 if (row->mode_line_p)
16647 ++row;
16648
16649 if ((end && row >= end) || !row->enabled_p)
16650 return NULL;
16651
16652 last_y = window_text_bottom_y (w) - dy;
16653
16654 while (1)
16655 {
16656 /* Give up if we have gone too far. */
16657 if (end && row >= end)
16658 return NULL;
16659 /* This formerly returned if they were equal.
16660 I think that both quantities are of a "last plus one" type;
16661 if so, when they are equal, the row is within the screen. -- rms. */
16662 if (MATRIX_ROW_BOTTOM_Y (row) > last_y)
16663 return NULL;
16664
16665 /* If it is in this row, return this row. */
16666 if (! (MATRIX_ROW_END_CHARPOS (row) < charpos
16667 || (MATRIX_ROW_END_CHARPOS (row) == charpos
16668 /* The end position of a row equals the start
16669 position of the next row. If CHARPOS is there, we
16670 would rather display it in the next line, except
16671 when this line ends in ZV. */
16672 && !row->ends_at_zv_p
16673 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
16674 && charpos >= MATRIX_ROW_START_CHARPOS (row))
16675 {
16676 struct glyph *g;
16677
16678 if (NILP (BVAR (XBUFFER (w->buffer), bidi_display_reordering))
16679 || (!best_row && !row->continued_p))
16680 return row;
16681 /* In bidi-reordered rows, there could be several rows
16682 occluding point, all of them belonging to the same
16683 continued line. We need to find the row which fits
16684 CHARPOS the best. */
16685 for (g = row->glyphs[TEXT_AREA];
16686 g < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
16687 g++)
16688 {
16689 if (!STRINGP (g->object))
16690 {
16691 if (g->charpos > 0 && eabs (g->charpos - charpos) < mindif)
16692 {
16693 mindif = eabs (g->charpos - charpos);
16694 best_row = row;
16695 /* Exact match always wins. */
16696 if (mindif == 0)
16697 return best_row;
16698 }
16699 }
16700 }
16701 }
16702 else if (best_row && !row->continued_p)
16703 return best_row;
16704 ++row;
16705 }
16706 }
16707
16708
16709 /* Try to redisplay window W by reusing its existing display. W's
16710 current matrix must be up to date when this function is called,
16711 i.e. window_end_valid must not be nil.
16712
16713 Value is
16714
16715 1 if display has been updated
16716 0 if otherwise unsuccessful
16717 -1 if redisplay with same window start is known not to succeed
16718
16719 The following steps are performed:
16720
16721 1. Find the last row in the current matrix of W that is not
16722 affected by changes at the start of current_buffer. If no such row
16723 is found, give up.
16724
16725 2. Find the first row in W's current matrix that is not affected by
16726 changes at the end of current_buffer. Maybe there is no such row.
16727
16728 3. Display lines beginning with the row + 1 found in step 1 to the
16729 row found in step 2 or, if step 2 didn't find a row, to the end of
16730 the window.
16731
16732 4. If cursor is not known to appear on the window, give up.
16733
16734 5. If display stopped at the row found in step 2, scroll the
16735 display and current matrix as needed.
16736
16737 6. Maybe display some lines at the end of W, if we must. This can
16738 happen under various circumstances, like a partially visible line
16739 becoming fully visible, or because newly displayed lines are displayed
16740 in smaller font sizes.
16741
16742 7. Update W's window end information. */
16743
16744 static int
16745 try_window_id (struct window *w)
16746 {
16747 struct frame *f = XFRAME (w->frame);
16748 struct glyph_matrix *current_matrix = w->current_matrix;
16749 struct glyph_matrix *desired_matrix = w->desired_matrix;
16750 struct glyph_row *last_unchanged_at_beg_row;
16751 struct glyph_row *first_unchanged_at_end_row;
16752 struct glyph_row *row;
16753 struct glyph_row *bottom_row;
16754 int bottom_vpos;
16755 struct it it;
16756 EMACS_INT delta = 0, delta_bytes = 0, stop_pos;
16757 int dvpos, dy;
16758 struct text_pos start_pos;
16759 struct run run;
16760 int first_unchanged_at_end_vpos = 0;
16761 struct glyph_row *last_text_row, *last_text_row_at_end;
16762 struct text_pos start;
16763 EMACS_INT first_changed_charpos, last_changed_charpos;
16764
16765 #if GLYPH_DEBUG
16766 if (inhibit_try_window_id)
16767 return 0;
16768 #endif
16769
16770 /* This is handy for debugging. */
16771 #if 0
16772 #define GIVE_UP(X) \
16773 do { \
16774 fprintf (stderr, "try_window_id give up %d\n", (X)); \
16775 return 0; \
16776 } while (0)
16777 #else
16778 #define GIVE_UP(X) return 0
16779 #endif
16780
16781 SET_TEXT_POS_FROM_MARKER (start, w->start);
16782
16783 /* Don't use this for mini-windows because these can show
16784 messages and mini-buffers, and we don't handle that here. */
16785 if (MINI_WINDOW_P (w))
16786 GIVE_UP (1);
16787
16788 /* This flag is used to prevent redisplay optimizations. */
16789 if (windows_or_buffers_changed || cursor_type_changed)
16790 GIVE_UP (2);
16791
16792 /* Verify that narrowing has not changed.
16793 Also verify that we were not told to prevent redisplay optimizations.
16794 It would be nice to further
16795 reduce the number of cases where this prevents try_window_id. */
16796 if (current_buffer->clip_changed
16797 || current_buffer->prevent_redisplay_optimizations_p)
16798 GIVE_UP (3);
16799
16800 /* Window must either use window-based redisplay or be full width. */
16801 if (!FRAME_WINDOW_P (f)
16802 && (!FRAME_LINE_INS_DEL_OK (f)
16803 || !WINDOW_FULL_WIDTH_P (w)))
16804 GIVE_UP (4);
16805
16806 /* Give up if point is known NOT to appear in W. */
16807 if (PT < CHARPOS (start))
16808 GIVE_UP (5);
16809
16810 /* Another way to prevent redisplay optimizations. */
16811 if (XFASTINT (w->last_modified) == 0)
16812 GIVE_UP (6);
16813
16814 /* Verify that window is not hscrolled. */
16815 if (XFASTINT (w->hscroll) != 0)
16816 GIVE_UP (7);
16817
16818 /* Verify that display wasn't paused. */
16819 if (NILP (w->window_end_valid))
16820 GIVE_UP (8);
16821
16822 /* Can't use this if highlighting a region because a cursor movement
16823 will do more than just set the cursor. */
16824 if (!NILP (Vtransient_mark_mode)
16825 && !NILP (BVAR (current_buffer, mark_active)))
16826 GIVE_UP (9);
16827
16828 /* Likewise if highlighting trailing whitespace. */
16829 if (!NILP (Vshow_trailing_whitespace))
16830 GIVE_UP (11);
16831
16832 /* Likewise if showing a region. */
16833 if (!NILP (w->region_showing))
16834 GIVE_UP (10);
16835
16836 /* Can't use this if overlay arrow position and/or string have
16837 changed. */
16838 if (overlay_arrows_changed_p ())
16839 GIVE_UP (12);
16840
16841 /* When word-wrap is on, adding a space to the first word of a
16842 wrapped line can change the wrap position, altering the line
16843 above it. It might be worthwhile to handle this more
16844 intelligently, but for now just redisplay from scratch. */
16845 if (!NILP (BVAR (XBUFFER (w->buffer), word_wrap)))
16846 GIVE_UP (21);
16847
16848 /* Under bidi reordering, adding or deleting a character in the
16849 beginning of a paragraph, before the first strong directional
16850 character, can change the base direction of the paragraph (unless
16851 the buffer specifies a fixed paragraph direction), which will
16852 require to redisplay the whole paragraph. It might be worthwhile
16853 to find the paragraph limits and widen the range of redisplayed
16854 lines to that, but for now just give up this optimization and
16855 redisplay from scratch. */
16856 if (!NILP (BVAR (XBUFFER (w->buffer), bidi_display_reordering))
16857 && NILP (BVAR (XBUFFER (w->buffer), bidi_paragraph_direction)))
16858 GIVE_UP (22);
16859
16860 /* Make sure beg_unchanged and end_unchanged are up to date. Do it
16861 only if buffer has really changed. The reason is that the gap is
16862 initially at Z for freshly visited files. The code below would
16863 set end_unchanged to 0 in that case. */
16864 if (MODIFF > SAVE_MODIFF
16865 /* This seems to happen sometimes after saving a buffer. */
16866 || BEG_UNCHANGED + END_UNCHANGED > Z_BYTE)
16867 {
16868 if (GPT - BEG < BEG_UNCHANGED)
16869 BEG_UNCHANGED = GPT - BEG;
16870 if (Z - GPT < END_UNCHANGED)
16871 END_UNCHANGED = Z - GPT;
16872 }
16873
16874 /* The position of the first and last character that has been changed. */
16875 first_changed_charpos = BEG + BEG_UNCHANGED;
16876 last_changed_charpos = Z - END_UNCHANGED;
16877
16878 /* If window starts after a line end, and the last change is in
16879 front of that newline, then changes don't affect the display.
16880 This case happens with stealth-fontification. Note that although
16881 the display is unchanged, glyph positions in the matrix have to
16882 be adjusted, of course. */
16883 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
16884 if (MATRIX_ROW_DISPLAYS_TEXT_P (row)
16885 && ((last_changed_charpos < CHARPOS (start)
16886 && CHARPOS (start) == BEGV)
16887 || (last_changed_charpos < CHARPOS (start) - 1
16888 && FETCH_BYTE (BYTEPOS (start) - 1) == '\n')))
16889 {
16890 EMACS_INT Z_old, Z_delta, Z_BYTE_old, Z_delta_bytes;
16891 struct glyph_row *r0;
16892
16893 /* Compute how many chars/bytes have been added to or removed
16894 from the buffer. */
16895 Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
16896 Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
16897 Z_delta = Z - Z_old;
16898 Z_delta_bytes = Z_BYTE - Z_BYTE_old;
16899
16900 /* Give up if PT is not in the window. Note that it already has
16901 been checked at the start of try_window_id that PT is not in
16902 front of the window start. */
16903 if (PT >= MATRIX_ROW_END_CHARPOS (row) + Z_delta)
16904 GIVE_UP (13);
16905
16906 /* If window start is unchanged, we can reuse the whole matrix
16907 as is, after adjusting glyph positions. No need to compute
16908 the window end again, since its offset from Z hasn't changed. */
16909 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
16910 if (CHARPOS (start) == MATRIX_ROW_START_CHARPOS (r0) + Z_delta
16911 && BYTEPOS (start) == MATRIX_ROW_START_BYTEPOS (r0) + Z_delta_bytes
16912 /* PT must not be in a partially visible line. */
16913 && !(PT >= MATRIX_ROW_START_CHARPOS (row) + Z_delta
16914 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
16915 {
16916 /* Adjust positions in the glyph matrix. */
16917 if (Z_delta || Z_delta_bytes)
16918 {
16919 struct glyph_row *r1
16920 = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
16921 increment_matrix_positions (w->current_matrix,
16922 MATRIX_ROW_VPOS (r0, current_matrix),
16923 MATRIX_ROW_VPOS (r1, current_matrix),
16924 Z_delta, Z_delta_bytes);
16925 }
16926
16927 /* Set the cursor. */
16928 row = row_containing_pos (w, PT, r0, NULL, 0);
16929 if (row)
16930 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
16931 else
16932 abort ();
16933 return 1;
16934 }
16935 }
16936
16937 /* Handle the case that changes are all below what is displayed in
16938 the window, and that PT is in the window. This shortcut cannot
16939 be taken if ZV is visible in the window, and text has been added
16940 there that is visible in the window. */
16941 if (first_changed_charpos >= MATRIX_ROW_END_CHARPOS (row)
16942 /* ZV is not visible in the window, or there are no
16943 changes at ZV, actually. */
16944 && (current_matrix->zv > MATRIX_ROW_END_CHARPOS (row)
16945 || first_changed_charpos == last_changed_charpos))
16946 {
16947 struct glyph_row *r0;
16948
16949 /* Give up if PT is not in the window. Note that it already has
16950 been checked at the start of try_window_id that PT is not in
16951 front of the window start. */
16952 if (PT >= MATRIX_ROW_END_CHARPOS (row))
16953 GIVE_UP (14);
16954
16955 /* If window start is unchanged, we can reuse the whole matrix
16956 as is, without changing glyph positions since no text has
16957 been added/removed in front of the window end. */
16958 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
16959 if (TEXT_POS_EQUAL_P (start, r0->minpos)
16960 /* PT must not be in a partially visible line. */
16961 && !(PT >= MATRIX_ROW_START_CHARPOS (row)
16962 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
16963 {
16964 /* We have to compute the window end anew since text
16965 could have been added/removed after it. */
16966 w->window_end_pos
16967 = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
16968 w->window_end_bytepos
16969 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
16970
16971 /* Set the cursor. */
16972 row = row_containing_pos (w, PT, r0, NULL, 0);
16973 if (row)
16974 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
16975 else
16976 abort ();
16977 return 2;
16978 }
16979 }
16980
16981 /* Give up if window start is in the changed area.
16982
16983 The condition used to read
16984
16985 (BEG_UNCHANGED + END_UNCHANGED != Z - BEG && ...)
16986
16987 but why that was tested escapes me at the moment. */
16988 if (CHARPOS (start) >= first_changed_charpos
16989 && CHARPOS (start) <= last_changed_charpos)
16990 GIVE_UP (15);
16991
16992 /* Check that window start agrees with the start of the first glyph
16993 row in its current matrix. Check this after we know the window
16994 start is not in changed text, otherwise positions would not be
16995 comparable. */
16996 row = MATRIX_FIRST_TEXT_ROW (current_matrix);
16997 if (!TEXT_POS_EQUAL_P (start, row->minpos))
16998 GIVE_UP (16);
16999
17000 /* Give up if the window ends in strings. Overlay strings
17001 at the end are difficult to handle, so don't try. */
17002 row = MATRIX_ROW (current_matrix, XFASTINT (w->window_end_vpos));
17003 if (MATRIX_ROW_START_CHARPOS (row) == MATRIX_ROW_END_CHARPOS (row))
17004 GIVE_UP (20);
17005
17006 /* Compute the position at which we have to start displaying new
17007 lines. Some of the lines at the top of the window might be
17008 reusable because they are not displaying changed text. Find the
17009 last row in W's current matrix not affected by changes at the
17010 start of current_buffer. Value is null if changes start in the
17011 first line of window. */
17012 last_unchanged_at_beg_row = find_last_unchanged_at_beg_row (w);
17013 if (last_unchanged_at_beg_row)
17014 {
17015 /* Avoid starting to display in the moddle of a character, a TAB
17016 for instance. This is easier than to set up the iterator
17017 exactly, and it's not a frequent case, so the additional
17018 effort wouldn't really pay off. */
17019 while ((MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row)
17020 || last_unchanged_at_beg_row->ends_in_newline_from_string_p)
17021 && last_unchanged_at_beg_row > w->current_matrix->rows)
17022 --last_unchanged_at_beg_row;
17023
17024 if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row))
17025 GIVE_UP (17);
17026
17027 if (init_to_row_end (&it, w, last_unchanged_at_beg_row) == 0)
17028 GIVE_UP (18);
17029 start_pos = it.current.pos;
17030
17031 /* Start displaying new lines in the desired matrix at the same
17032 vpos we would use in the current matrix, i.e. below
17033 last_unchanged_at_beg_row. */
17034 it.vpos = 1 + MATRIX_ROW_VPOS (last_unchanged_at_beg_row,
17035 current_matrix);
17036 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
17037 it.current_y = MATRIX_ROW_BOTTOM_Y (last_unchanged_at_beg_row);
17038
17039 xassert (it.hpos == 0 && it.current_x == 0);
17040 }
17041 else
17042 {
17043 /* There are no reusable lines at the start of the window.
17044 Start displaying in the first text line. */
17045 start_display (&it, w, start);
17046 it.vpos = it.first_vpos;
17047 start_pos = it.current.pos;
17048 }
17049
17050 /* Find the first row that is not affected by changes at the end of
17051 the buffer. Value will be null if there is no unchanged row, in
17052 which case we must redisplay to the end of the window. delta
17053 will be set to the value by which buffer positions beginning with
17054 first_unchanged_at_end_row have to be adjusted due to text
17055 changes. */
17056 first_unchanged_at_end_row
17057 = find_first_unchanged_at_end_row (w, &delta, &delta_bytes);
17058 IF_DEBUG (debug_delta = delta);
17059 IF_DEBUG (debug_delta_bytes = delta_bytes);
17060
17061 /* Set stop_pos to the buffer position up to which we will have to
17062 display new lines. If first_unchanged_at_end_row != NULL, this
17063 is the buffer position of the start of the line displayed in that
17064 row. For first_unchanged_at_end_row == NULL, use 0 to indicate
17065 that we don't stop at a buffer position. */
17066 stop_pos = 0;
17067 if (first_unchanged_at_end_row)
17068 {
17069 xassert (last_unchanged_at_beg_row == NULL
17070 || first_unchanged_at_end_row >= last_unchanged_at_beg_row);
17071
17072 /* If this is a continuation line, move forward to the next one
17073 that isn't. Changes in lines above affect this line.
17074 Caution: this may move first_unchanged_at_end_row to a row
17075 not displaying text. */
17076 while (MATRIX_ROW_CONTINUATION_LINE_P (first_unchanged_at_end_row)
17077 && MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
17078 && (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
17079 < it.last_visible_y))
17080 ++first_unchanged_at_end_row;
17081
17082 if (!MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
17083 || (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
17084 >= it.last_visible_y))
17085 first_unchanged_at_end_row = NULL;
17086 else
17087 {
17088 stop_pos = (MATRIX_ROW_START_CHARPOS (first_unchanged_at_end_row)
17089 + delta);
17090 first_unchanged_at_end_vpos
17091 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, current_matrix);
17092 xassert (stop_pos >= Z - END_UNCHANGED);
17093 }
17094 }
17095 else if (last_unchanged_at_beg_row == NULL)
17096 GIVE_UP (19);
17097
17098
17099 #if GLYPH_DEBUG
17100
17101 /* Either there is no unchanged row at the end, or the one we have
17102 now displays text. This is a necessary condition for the window
17103 end pos calculation at the end of this function. */
17104 xassert (first_unchanged_at_end_row == NULL
17105 || MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
17106
17107 debug_last_unchanged_at_beg_vpos
17108 = (last_unchanged_at_beg_row
17109 ? MATRIX_ROW_VPOS (last_unchanged_at_beg_row, current_matrix)
17110 : -1);
17111 debug_first_unchanged_at_end_vpos = first_unchanged_at_end_vpos;
17112
17113 #endif /* GLYPH_DEBUG != 0 */
17114
17115
17116 /* Display new lines. Set last_text_row to the last new line
17117 displayed which has text on it, i.e. might end up as being the
17118 line where the window_end_vpos is. */
17119 w->cursor.vpos = -1;
17120 last_text_row = NULL;
17121 overlay_arrow_seen = 0;
17122 while (it.current_y < it.last_visible_y
17123 && !fonts_changed_p
17124 && (first_unchanged_at_end_row == NULL
17125 || IT_CHARPOS (it) < stop_pos))
17126 {
17127 if (display_line (&it))
17128 last_text_row = it.glyph_row - 1;
17129 }
17130
17131 if (fonts_changed_p)
17132 return -1;
17133
17134
17135 /* Compute differences in buffer positions, y-positions etc. for
17136 lines reused at the bottom of the window. Compute what we can
17137 scroll. */
17138 if (first_unchanged_at_end_row
17139 /* No lines reused because we displayed everything up to the
17140 bottom of the window. */
17141 && it.current_y < it.last_visible_y)
17142 {
17143 dvpos = (it.vpos
17144 - MATRIX_ROW_VPOS (first_unchanged_at_end_row,
17145 current_matrix));
17146 dy = it.current_y - first_unchanged_at_end_row->y;
17147 run.current_y = first_unchanged_at_end_row->y;
17148 run.desired_y = run.current_y + dy;
17149 run.height = it.last_visible_y - max (run.current_y, run.desired_y);
17150 }
17151 else
17152 {
17153 delta = delta_bytes = dvpos = dy
17154 = run.current_y = run.desired_y = run.height = 0;
17155 first_unchanged_at_end_row = NULL;
17156 }
17157 IF_DEBUG (debug_dvpos = dvpos; debug_dy = dy);
17158
17159
17160 /* Find the cursor if not already found. We have to decide whether
17161 PT will appear on this window (it sometimes doesn't, but this is
17162 not a very frequent case.) This decision has to be made before
17163 the current matrix is altered. A value of cursor.vpos < 0 means
17164 that PT is either in one of the lines beginning at
17165 first_unchanged_at_end_row or below the window. Don't care for
17166 lines that might be displayed later at the window end; as
17167 mentioned, this is not a frequent case. */
17168 if (w->cursor.vpos < 0)
17169 {
17170 /* Cursor in unchanged rows at the top? */
17171 if (PT < CHARPOS (start_pos)
17172 && last_unchanged_at_beg_row)
17173 {
17174 row = row_containing_pos (w, PT,
17175 MATRIX_FIRST_TEXT_ROW (w->current_matrix),
17176 last_unchanged_at_beg_row + 1, 0);
17177 if (row)
17178 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
17179 }
17180
17181 /* Start from first_unchanged_at_end_row looking for PT. */
17182 else if (first_unchanged_at_end_row)
17183 {
17184 row = row_containing_pos (w, PT - delta,
17185 first_unchanged_at_end_row, NULL, 0);
17186 if (row)
17187 set_cursor_from_row (w, row, w->current_matrix, delta,
17188 delta_bytes, dy, dvpos);
17189 }
17190
17191 /* Give up if cursor was not found. */
17192 if (w->cursor.vpos < 0)
17193 {
17194 clear_glyph_matrix (w->desired_matrix);
17195 return -1;
17196 }
17197 }
17198
17199 /* Don't let the cursor end in the scroll margins. */
17200 {
17201 int this_scroll_margin, cursor_height;
17202
17203 this_scroll_margin =
17204 max (0, min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4));
17205 this_scroll_margin *= FRAME_LINE_HEIGHT (it.f);
17206 cursor_height = MATRIX_ROW (w->desired_matrix, w->cursor.vpos)->height;
17207
17208 if ((w->cursor.y < this_scroll_margin
17209 && CHARPOS (start) > BEGV)
17210 /* Old redisplay didn't take scroll margin into account at the bottom,
17211 but then global-hl-line-mode doesn't scroll. KFS 2004-06-14 */
17212 || (w->cursor.y + (make_cursor_line_fully_visible_p
17213 ? cursor_height + this_scroll_margin
17214 : 1)) > it.last_visible_y)
17215 {
17216 w->cursor.vpos = -1;
17217 clear_glyph_matrix (w->desired_matrix);
17218 return -1;
17219 }
17220 }
17221
17222 /* Scroll the display. Do it before changing the current matrix so
17223 that xterm.c doesn't get confused about where the cursor glyph is
17224 found. */
17225 if (dy && run.height)
17226 {
17227 update_begin (f);
17228
17229 if (FRAME_WINDOW_P (f))
17230 {
17231 FRAME_RIF (f)->update_window_begin_hook (w);
17232 FRAME_RIF (f)->clear_window_mouse_face (w);
17233 FRAME_RIF (f)->scroll_run_hook (w, &run);
17234 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
17235 }
17236 else
17237 {
17238 /* Terminal frame. In this case, dvpos gives the number of
17239 lines to scroll by; dvpos < 0 means scroll up. */
17240 int from_vpos
17241 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, w->current_matrix);
17242 int from = WINDOW_TOP_EDGE_LINE (w) + from_vpos;
17243 int end = (WINDOW_TOP_EDGE_LINE (w)
17244 + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0)
17245 + window_internal_height (w));
17246
17247 #if defined (HAVE_GPM) || defined (MSDOS)
17248 x_clear_window_mouse_face (w);
17249 #endif
17250 /* Perform the operation on the screen. */
17251 if (dvpos > 0)
17252 {
17253 /* Scroll last_unchanged_at_beg_row to the end of the
17254 window down dvpos lines. */
17255 set_terminal_window (f, end);
17256
17257 /* On dumb terminals delete dvpos lines at the end
17258 before inserting dvpos empty lines. */
17259 if (!FRAME_SCROLL_REGION_OK (f))
17260 ins_del_lines (f, end - dvpos, -dvpos);
17261
17262 /* Insert dvpos empty lines in front of
17263 last_unchanged_at_beg_row. */
17264 ins_del_lines (f, from, dvpos);
17265 }
17266 else if (dvpos < 0)
17267 {
17268 /* Scroll up last_unchanged_at_beg_vpos to the end of
17269 the window to last_unchanged_at_beg_vpos - |dvpos|. */
17270 set_terminal_window (f, end);
17271
17272 /* Delete dvpos lines in front of
17273 last_unchanged_at_beg_vpos. ins_del_lines will set
17274 the cursor to the given vpos and emit |dvpos| delete
17275 line sequences. */
17276 ins_del_lines (f, from + dvpos, dvpos);
17277
17278 /* On a dumb terminal insert dvpos empty lines at the
17279 end. */
17280 if (!FRAME_SCROLL_REGION_OK (f))
17281 ins_del_lines (f, end + dvpos, -dvpos);
17282 }
17283
17284 set_terminal_window (f, 0);
17285 }
17286
17287 update_end (f);
17288 }
17289
17290 /* Shift reused rows of the current matrix to the right position.
17291 BOTTOM_ROW is the last + 1 row in the current matrix reserved for
17292 text. */
17293 bottom_row = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
17294 bottom_vpos = MATRIX_ROW_VPOS (bottom_row, current_matrix);
17295 if (dvpos < 0)
17296 {
17297 rotate_matrix (current_matrix, first_unchanged_at_end_vpos + dvpos,
17298 bottom_vpos, dvpos);
17299 enable_glyph_matrix_rows (current_matrix, bottom_vpos + dvpos,
17300 bottom_vpos, 0);
17301 }
17302 else if (dvpos > 0)
17303 {
17304 rotate_matrix (current_matrix, first_unchanged_at_end_vpos,
17305 bottom_vpos, dvpos);
17306 enable_glyph_matrix_rows (current_matrix, first_unchanged_at_end_vpos,
17307 first_unchanged_at_end_vpos + dvpos, 0);
17308 }
17309
17310 /* For frame-based redisplay, make sure that current frame and window
17311 matrix are in sync with respect to glyph memory. */
17312 if (!FRAME_WINDOW_P (f))
17313 sync_frame_with_window_matrix_rows (w);
17314
17315 /* Adjust buffer positions in reused rows. */
17316 if (delta || delta_bytes)
17317 increment_matrix_positions (current_matrix,
17318 first_unchanged_at_end_vpos + dvpos,
17319 bottom_vpos, delta, delta_bytes);
17320
17321 /* Adjust Y positions. */
17322 if (dy)
17323 shift_glyph_matrix (w, current_matrix,
17324 first_unchanged_at_end_vpos + dvpos,
17325 bottom_vpos, dy);
17326
17327 if (first_unchanged_at_end_row)
17328 {
17329 first_unchanged_at_end_row += dvpos;
17330 if (first_unchanged_at_end_row->y >= it.last_visible_y
17331 || !MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row))
17332 first_unchanged_at_end_row = NULL;
17333 }
17334
17335 /* If scrolling up, there may be some lines to display at the end of
17336 the window. */
17337 last_text_row_at_end = NULL;
17338 if (dy < 0)
17339 {
17340 /* Scrolling up can leave for example a partially visible line
17341 at the end of the window to be redisplayed. */
17342 /* Set last_row to the glyph row in the current matrix where the
17343 window end line is found. It has been moved up or down in
17344 the matrix by dvpos. */
17345 int last_vpos = XFASTINT (w->window_end_vpos) + dvpos;
17346 struct glyph_row *last_row = MATRIX_ROW (current_matrix, last_vpos);
17347
17348 /* If last_row is the window end line, it should display text. */
17349 xassert (last_row->displays_text_p);
17350
17351 /* If window end line was partially visible before, begin
17352 displaying at that line. Otherwise begin displaying with the
17353 line following it. */
17354 if (MATRIX_ROW_BOTTOM_Y (last_row) - dy >= it.last_visible_y)
17355 {
17356 init_to_row_start (&it, w, last_row);
17357 it.vpos = last_vpos;
17358 it.current_y = last_row->y;
17359 }
17360 else
17361 {
17362 init_to_row_end (&it, w, last_row);
17363 it.vpos = 1 + last_vpos;
17364 it.current_y = MATRIX_ROW_BOTTOM_Y (last_row);
17365 ++last_row;
17366 }
17367
17368 /* We may start in a continuation line. If so, we have to
17369 get the right continuation_lines_width and current_x. */
17370 it.continuation_lines_width = last_row->continuation_lines_width;
17371 it.hpos = it.current_x = 0;
17372
17373 /* Display the rest of the lines at the window end. */
17374 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
17375 while (it.current_y < it.last_visible_y
17376 && !fonts_changed_p)
17377 {
17378 /* Is it always sure that the display agrees with lines in
17379 the current matrix? I don't think so, so we mark rows
17380 displayed invalid in the current matrix by setting their
17381 enabled_p flag to zero. */
17382 MATRIX_ROW (w->current_matrix, it.vpos)->enabled_p = 0;
17383 if (display_line (&it))
17384 last_text_row_at_end = it.glyph_row - 1;
17385 }
17386 }
17387
17388 /* Update window_end_pos and window_end_vpos. */
17389 if (first_unchanged_at_end_row
17390 && !last_text_row_at_end)
17391 {
17392 /* Window end line if one of the preserved rows from the current
17393 matrix. Set row to the last row displaying text in current
17394 matrix starting at first_unchanged_at_end_row, after
17395 scrolling. */
17396 xassert (first_unchanged_at_end_row->displays_text_p);
17397 row = find_last_row_displaying_text (w->current_matrix, &it,
17398 first_unchanged_at_end_row);
17399 xassert (row && MATRIX_ROW_DISPLAYS_TEXT_P (row));
17400
17401 w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
17402 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
17403 w->window_end_vpos
17404 = make_number (MATRIX_ROW_VPOS (row, w->current_matrix));
17405 xassert (w->window_end_bytepos >= 0);
17406 IF_DEBUG (debug_method_add (w, "A"));
17407 }
17408 else if (last_text_row_at_end)
17409 {
17410 w->window_end_pos
17411 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row_at_end));
17412 w->window_end_bytepos
17413 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row_at_end);
17414 w->window_end_vpos
17415 = make_number (MATRIX_ROW_VPOS (last_text_row_at_end, desired_matrix));
17416 xassert (w->window_end_bytepos >= 0);
17417 IF_DEBUG (debug_method_add (w, "B"));
17418 }
17419 else if (last_text_row)
17420 {
17421 /* We have displayed either to the end of the window or at the
17422 end of the window, i.e. the last row with text is to be found
17423 in the desired matrix. */
17424 w->window_end_pos
17425 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
17426 w->window_end_bytepos
17427 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
17428 w->window_end_vpos
17429 = make_number (MATRIX_ROW_VPOS (last_text_row, desired_matrix));
17430 xassert (w->window_end_bytepos >= 0);
17431 }
17432 else if (first_unchanged_at_end_row == NULL
17433 && last_text_row == NULL
17434 && last_text_row_at_end == NULL)
17435 {
17436 /* Displayed to end of window, but no line containing text was
17437 displayed. Lines were deleted at the end of the window. */
17438 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
17439 int vpos = XFASTINT (w->window_end_vpos);
17440 struct glyph_row *current_row = current_matrix->rows + vpos;
17441 struct glyph_row *desired_row = desired_matrix->rows + vpos;
17442
17443 for (row = NULL;
17444 row == NULL && vpos >= first_vpos;
17445 --vpos, --current_row, --desired_row)
17446 {
17447 if (desired_row->enabled_p)
17448 {
17449 if (desired_row->displays_text_p)
17450 row = desired_row;
17451 }
17452 else if (current_row->displays_text_p)
17453 row = current_row;
17454 }
17455
17456 xassert (row != NULL);
17457 w->window_end_vpos = make_number (vpos + 1);
17458 w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
17459 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
17460 xassert (w->window_end_bytepos >= 0);
17461 IF_DEBUG (debug_method_add (w, "C"));
17462 }
17463 else
17464 abort ();
17465
17466 IF_DEBUG (debug_end_pos = XFASTINT (w->window_end_pos);
17467 debug_end_vpos = XFASTINT (w->window_end_vpos));
17468
17469 /* Record that display has not been completed. */
17470 w->window_end_valid = Qnil;
17471 w->desired_matrix->no_scrolling_p = 1;
17472 return 3;
17473
17474 #undef GIVE_UP
17475 }
17476
17477
17478 \f
17479 /***********************************************************************
17480 More debugging support
17481 ***********************************************************************/
17482
17483 #if GLYPH_DEBUG
17484
17485 void dump_glyph_row (struct glyph_row *, int, int) EXTERNALLY_VISIBLE;
17486 void dump_glyph_matrix (struct glyph_matrix *, int) EXTERNALLY_VISIBLE;
17487 void dump_glyph (struct glyph_row *, struct glyph *, int) EXTERNALLY_VISIBLE;
17488
17489
17490 /* Dump the contents of glyph matrix MATRIX on stderr.
17491
17492 GLYPHS 0 means don't show glyph contents.
17493 GLYPHS 1 means show glyphs in short form
17494 GLYPHS > 1 means show glyphs in long form. */
17495
17496 void
17497 dump_glyph_matrix (struct glyph_matrix *matrix, int glyphs)
17498 {
17499 int i;
17500 for (i = 0; i < matrix->nrows; ++i)
17501 dump_glyph_row (MATRIX_ROW (matrix, i), i, glyphs);
17502 }
17503
17504
17505 /* Dump contents of glyph GLYPH to stderr. ROW and AREA are
17506 the glyph row and area where the glyph comes from. */
17507
17508 void
17509 dump_glyph (struct glyph_row *row, struct glyph *glyph, int area)
17510 {
17511 if (glyph->type == CHAR_GLYPH)
17512 {
17513 fprintf (stderr,
17514 " %5td %4c %6"pI"d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
17515 glyph - row->glyphs[TEXT_AREA],
17516 'C',
17517 glyph->charpos,
17518 (BUFFERP (glyph->object)
17519 ? 'B'
17520 : (STRINGP (glyph->object)
17521 ? 'S'
17522 : '-')),
17523 glyph->pixel_width,
17524 glyph->u.ch,
17525 (glyph->u.ch < 0x80 && glyph->u.ch >= ' '
17526 ? glyph->u.ch
17527 : '.'),
17528 glyph->face_id,
17529 glyph->left_box_line_p,
17530 glyph->right_box_line_p);
17531 }
17532 else if (glyph->type == STRETCH_GLYPH)
17533 {
17534 fprintf (stderr,
17535 " %5td %4c %6"pI"d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
17536 glyph - row->glyphs[TEXT_AREA],
17537 'S',
17538 glyph->charpos,
17539 (BUFFERP (glyph->object)
17540 ? 'B'
17541 : (STRINGP (glyph->object)
17542 ? 'S'
17543 : '-')),
17544 glyph->pixel_width,
17545 0,
17546 '.',
17547 glyph->face_id,
17548 glyph->left_box_line_p,
17549 glyph->right_box_line_p);
17550 }
17551 else if (glyph->type == IMAGE_GLYPH)
17552 {
17553 fprintf (stderr,
17554 " %5td %4c %6"pI"d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
17555 glyph - row->glyphs[TEXT_AREA],
17556 'I',
17557 glyph->charpos,
17558 (BUFFERP (glyph->object)
17559 ? 'B'
17560 : (STRINGP (glyph->object)
17561 ? 'S'
17562 : '-')),
17563 glyph->pixel_width,
17564 glyph->u.img_id,
17565 '.',
17566 glyph->face_id,
17567 glyph->left_box_line_p,
17568 glyph->right_box_line_p);
17569 }
17570 else if (glyph->type == COMPOSITE_GLYPH)
17571 {
17572 fprintf (stderr,
17573 " %5td %4c %6"pI"d %c %3d 0x%05x",
17574 glyph - row->glyphs[TEXT_AREA],
17575 '+',
17576 glyph->charpos,
17577 (BUFFERP (glyph->object)
17578 ? 'B'
17579 : (STRINGP (glyph->object)
17580 ? 'S'
17581 : '-')),
17582 glyph->pixel_width,
17583 glyph->u.cmp.id);
17584 if (glyph->u.cmp.automatic)
17585 fprintf (stderr,
17586 "[%d-%d]",
17587 glyph->slice.cmp.from, glyph->slice.cmp.to);
17588 fprintf (stderr, " . %4d %1.1d%1.1d\n",
17589 glyph->face_id,
17590 glyph->left_box_line_p,
17591 glyph->right_box_line_p);
17592 }
17593 }
17594
17595
17596 /* Dump the contents of glyph row at VPOS in MATRIX to stderr.
17597 GLYPHS 0 means don't show glyph contents.
17598 GLYPHS 1 means show glyphs in short form
17599 GLYPHS > 1 means show glyphs in long form. */
17600
17601 void
17602 dump_glyph_row (struct glyph_row *row, int vpos, int glyphs)
17603 {
17604 if (glyphs != 1)
17605 {
17606 fprintf (stderr, "Row Start End Used oE><\\CTZFesm X Y W H V A P\n");
17607 fprintf (stderr, "======================================================================\n");
17608
17609 fprintf (stderr, "%3d %5"pI"d %5"pI"d %4d %1.1d%1.1d%1.1d%1.1d\
17610 %1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d %4d %4d %4d %4d %4d %4d %4d\n",
17611 vpos,
17612 MATRIX_ROW_START_CHARPOS (row),
17613 MATRIX_ROW_END_CHARPOS (row),
17614 row->used[TEXT_AREA],
17615 row->contains_overlapping_glyphs_p,
17616 row->enabled_p,
17617 row->truncated_on_left_p,
17618 row->truncated_on_right_p,
17619 row->continued_p,
17620 MATRIX_ROW_CONTINUATION_LINE_P (row),
17621 row->displays_text_p,
17622 row->ends_at_zv_p,
17623 row->fill_line_p,
17624 row->ends_in_middle_of_char_p,
17625 row->starts_in_middle_of_char_p,
17626 row->mouse_face_p,
17627 row->x,
17628 row->y,
17629 row->pixel_width,
17630 row->height,
17631 row->visible_height,
17632 row->ascent,
17633 row->phys_ascent);
17634 fprintf (stderr, "%9d %5d\t%5d\n", row->start.overlay_string_index,
17635 row->end.overlay_string_index,
17636 row->continuation_lines_width);
17637 fprintf (stderr, "%9"pI"d %5"pI"d\n",
17638 CHARPOS (row->start.string_pos),
17639 CHARPOS (row->end.string_pos));
17640 fprintf (stderr, "%9d %5d\n", row->start.dpvec_index,
17641 row->end.dpvec_index);
17642 }
17643
17644 if (glyphs > 1)
17645 {
17646 int area;
17647
17648 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
17649 {
17650 struct glyph *glyph = row->glyphs[area];
17651 struct glyph *glyph_end = glyph + row->used[area];
17652
17653 /* Glyph for a line end in text. */
17654 if (area == TEXT_AREA && glyph == glyph_end && glyph->charpos > 0)
17655 ++glyph_end;
17656
17657 if (glyph < glyph_end)
17658 fprintf (stderr, " Glyph Type Pos O W Code C Face LR\n");
17659
17660 for (; glyph < glyph_end; ++glyph)
17661 dump_glyph (row, glyph, area);
17662 }
17663 }
17664 else if (glyphs == 1)
17665 {
17666 int area;
17667
17668 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
17669 {
17670 char *s = (char *) alloca (row->used[area] + 1);
17671 int i;
17672
17673 for (i = 0; i < row->used[area]; ++i)
17674 {
17675 struct glyph *glyph = row->glyphs[area] + i;
17676 if (glyph->type == CHAR_GLYPH
17677 && glyph->u.ch < 0x80
17678 && glyph->u.ch >= ' ')
17679 s[i] = glyph->u.ch;
17680 else
17681 s[i] = '.';
17682 }
17683
17684 s[i] = '\0';
17685 fprintf (stderr, "%3d: (%d) '%s'\n", vpos, row->enabled_p, s);
17686 }
17687 }
17688 }
17689
17690
17691 DEFUN ("dump-glyph-matrix", Fdump_glyph_matrix,
17692 Sdump_glyph_matrix, 0, 1, "p",
17693 doc: /* Dump the current matrix of the selected window to stderr.
17694 Shows contents of glyph row structures. With non-nil
17695 parameter GLYPHS, dump glyphs as well. If GLYPHS is 1 show
17696 glyphs in short form, otherwise show glyphs in long form. */)
17697 (Lisp_Object glyphs)
17698 {
17699 struct window *w = XWINDOW (selected_window);
17700 struct buffer *buffer = XBUFFER (w->buffer);
17701
17702 fprintf (stderr, "PT = %"pI"d, BEGV = %"pI"d. ZV = %"pI"d\n",
17703 BUF_PT (buffer), BUF_BEGV (buffer), BUF_ZV (buffer));
17704 fprintf (stderr, "Cursor x = %d, y = %d, hpos = %d, vpos = %d\n",
17705 w->cursor.x, w->cursor.y, w->cursor.hpos, w->cursor.vpos);
17706 fprintf (stderr, "=============================================\n");
17707 dump_glyph_matrix (w->current_matrix,
17708 NILP (glyphs) ? 0 : XINT (glyphs));
17709 return Qnil;
17710 }
17711
17712
17713 DEFUN ("dump-frame-glyph-matrix", Fdump_frame_glyph_matrix,
17714 Sdump_frame_glyph_matrix, 0, 0, "", doc: /* */)
17715 (void)
17716 {
17717 struct frame *f = XFRAME (selected_frame);
17718 dump_glyph_matrix (f->current_matrix, 1);
17719 return Qnil;
17720 }
17721
17722
17723 DEFUN ("dump-glyph-row", Fdump_glyph_row, Sdump_glyph_row, 1, 2, "",
17724 doc: /* Dump glyph row ROW to stderr.
17725 GLYPH 0 means don't dump glyphs.
17726 GLYPH 1 means dump glyphs in short form.
17727 GLYPH > 1 or omitted means dump glyphs in long form. */)
17728 (Lisp_Object row, Lisp_Object glyphs)
17729 {
17730 struct glyph_matrix *matrix;
17731 int vpos;
17732
17733 CHECK_NUMBER (row);
17734 matrix = XWINDOW (selected_window)->current_matrix;
17735 vpos = XINT (row);
17736 if (vpos >= 0 && vpos < matrix->nrows)
17737 dump_glyph_row (MATRIX_ROW (matrix, vpos),
17738 vpos,
17739 INTEGERP (glyphs) ? XINT (glyphs) : 2);
17740 return Qnil;
17741 }
17742
17743
17744 DEFUN ("dump-tool-bar-row", Fdump_tool_bar_row, Sdump_tool_bar_row, 1, 2, "",
17745 doc: /* Dump glyph row ROW of the tool-bar of the current frame to stderr.
17746 GLYPH 0 means don't dump glyphs.
17747 GLYPH 1 means dump glyphs in short form.
17748 GLYPH > 1 or omitted means dump glyphs in long form. */)
17749 (Lisp_Object row, Lisp_Object glyphs)
17750 {
17751 struct frame *sf = SELECTED_FRAME ();
17752 struct glyph_matrix *m = XWINDOW (sf->tool_bar_window)->current_matrix;
17753 int vpos;
17754
17755 CHECK_NUMBER (row);
17756 vpos = XINT (row);
17757 if (vpos >= 0 && vpos < m->nrows)
17758 dump_glyph_row (MATRIX_ROW (m, vpos), vpos,
17759 INTEGERP (glyphs) ? XINT (glyphs) : 2);
17760 return Qnil;
17761 }
17762
17763
17764 DEFUN ("trace-redisplay", Ftrace_redisplay, Strace_redisplay, 0, 1, "P",
17765 doc: /* Toggle tracing of redisplay.
17766 With ARG, turn tracing on if and only if ARG is positive. */)
17767 (Lisp_Object arg)
17768 {
17769 if (NILP (arg))
17770 trace_redisplay_p = !trace_redisplay_p;
17771 else
17772 {
17773 arg = Fprefix_numeric_value (arg);
17774 trace_redisplay_p = XINT (arg) > 0;
17775 }
17776
17777 return Qnil;
17778 }
17779
17780
17781 DEFUN ("trace-to-stderr", Ftrace_to_stderr, Strace_to_stderr, 1, MANY, "",
17782 doc: /* Like `format', but print result to stderr.
17783 usage: (trace-to-stderr STRING &rest OBJECTS) */)
17784 (ptrdiff_t nargs, Lisp_Object *args)
17785 {
17786 Lisp_Object s = Fformat (nargs, args);
17787 fprintf (stderr, "%s", SDATA (s));
17788 return Qnil;
17789 }
17790
17791 #endif /* GLYPH_DEBUG */
17792
17793
17794 \f
17795 /***********************************************************************
17796 Building Desired Matrix Rows
17797 ***********************************************************************/
17798
17799 /* Return a temporary glyph row holding the glyphs of an overlay arrow.
17800 Used for non-window-redisplay windows, and for windows w/o left fringe. */
17801
17802 static struct glyph_row *
17803 get_overlay_arrow_glyph_row (struct window *w, Lisp_Object overlay_arrow_string)
17804 {
17805 struct frame *f = XFRAME (WINDOW_FRAME (w));
17806 struct buffer *buffer = XBUFFER (w->buffer);
17807 struct buffer *old = current_buffer;
17808 const unsigned char *arrow_string = SDATA (overlay_arrow_string);
17809 int arrow_len = SCHARS (overlay_arrow_string);
17810 const unsigned char *arrow_end = arrow_string + arrow_len;
17811 const unsigned char *p;
17812 struct it it;
17813 int multibyte_p;
17814 int n_glyphs_before;
17815
17816 set_buffer_temp (buffer);
17817 init_iterator (&it, w, -1, -1, &scratch_glyph_row, DEFAULT_FACE_ID);
17818 it.glyph_row->used[TEXT_AREA] = 0;
17819 SET_TEXT_POS (it.position, 0, 0);
17820
17821 multibyte_p = !NILP (BVAR (buffer, enable_multibyte_characters));
17822 p = arrow_string;
17823 while (p < arrow_end)
17824 {
17825 Lisp_Object face, ilisp;
17826
17827 /* Get the next character. */
17828 if (multibyte_p)
17829 it.c = it.char_to_display = string_char_and_length (p, &it.len);
17830 else
17831 {
17832 it.c = it.char_to_display = *p, it.len = 1;
17833 if (! ASCII_CHAR_P (it.c))
17834 it.char_to_display = BYTE8_TO_CHAR (it.c);
17835 }
17836 p += it.len;
17837
17838 /* Get its face. */
17839 ilisp = make_number (p - arrow_string);
17840 face = Fget_text_property (ilisp, Qface, overlay_arrow_string);
17841 it.face_id = compute_char_face (f, it.char_to_display, face);
17842
17843 /* Compute its width, get its glyphs. */
17844 n_glyphs_before = it.glyph_row->used[TEXT_AREA];
17845 SET_TEXT_POS (it.position, -1, -1);
17846 PRODUCE_GLYPHS (&it);
17847
17848 /* If this character doesn't fit any more in the line, we have
17849 to remove some glyphs. */
17850 if (it.current_x > it.last_visible_x)
17851 {
17852 it.glyph_row->used[TEXT_AREA] = n_glyphs_before;
17853 break;
17854 }
17855 }
17856
17857 set_buffer_temp (old);
17858 return it.glyph_row;
17859 }
17860
17861
17862 /* Insert truncation glyphs at the start of IT->glyph_row. Truncation
17863 glyphs are only inserted for terminal frames since we can't really
17864 win with truncation glyphs when partially visible glyphs are
17865 involved. Which glyphs to insert is determined by
17866 produce_special_glyphs. */
17867
17868 static void
17869 insert_left_trunc_glyphs (struct it *it)
17870 {
17871 struct it truncate_it;
17872 struct glyph *from, *end, *to, *toend;
17873
17874 xassert (!FRAME_WINDOW_P (it->f));
17875
17876 /* Get the truncation glyphs. */
17877 truncate_it = *it;
17878 truncate_it.current_x = 0;
17879 truncate_it.face_id = DEFAULT_FACE_ID;
17880 truncate_it.glyph_row = &scratch_glyph_row;
17881 truncate_it.glyph_row->used[TEXT_AREA] = 0;
17882 CHARPOS (truncate_it.position) = BYTEPOS (truncate_it.position) = -1;
17883 truncate_it.object = make_number (0);
17884 produce_special_glyphs (&truncate_it, IT_TRUNCATION);
17885
17886 /* Overwrite glyphs from IT with truncation glyphs. */
17887 if (!it->glyph_row->reversed_p)
17888 {
17889 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
17890 end = from + truncate_it.glyph_row->used[TEXT_AREA];
17891 to = it->glyph_row->glyphs[TEXT_AREA];
17892 toend = to + it->glyph_row->used[TEXT_AREA];
17893
17894 while (from < end)
17895 *to++ = *from++;
17896
17897 /* There may be padding glyphs left over. Overwrite them too. */
17898 while (to < toend && CHAR_GLYPH_PADDING_P (*to))
17899 {
17900 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
17901 while (from < end)
17902 *to++ = *from++;
17903 }
17904
17905 if (to > toend)
17906 it->glyph_row->used[TEXT_AREA] = to - it->glyph_row->glyphs[TEXT_AREA];
17907 }
17908 else
17909 {
17910 /* In R2L rows, overwrite the last (rightmost) glyphs, and do
17911 that back to front. */
17912 end = truncate_it.glyph_row->glyphs[TEXT_AREA];
17913 from = end + truncate_it.glyph_row->used[TEXT_AREA] - 1;
17914 toend = it->glyph_row->glyphs[TEXT_AREA];
17915 to = toend + it->glyph_row->used[TEXT_AREA] - 1;
17916
17917 while (from >= end && to >= toend)
17918 *to-- = *from--;
17919 while (to >= toend && CHAR_GLYPH_PADDING_P (*to))
17920 {
17921 from =
17922 truncate_it.glyph_row->glyphs[TEXT_AREA]
17923 + truncate_it.glyph_row->used[TEXT_AREA] - 1;
17924 while (from >= end && to >= toend)
17925 *to-- = *from--;
17926 }
17927 if (from >= end)
17928 {
17929 /* Need to free some room before prepending additional
17930 glyphs. */
17931 int move_by = from - end + 1;
17932 struct glyph *g0 = it->glyph_row->glyphs[TEXT_AREA];
17933 struct glyph *g = g0 + it->glyph_row->used[TEXT_AREA] - 1;
17934
17935 for ( ; g >= g0; g--)
17936 g[move_by] = *g;
17937 while (from >= end)
17938 *to-- = *from--;
17939 it->glyph_row->used[TEXT_AREA] += move_by;
17940 }
17941 }
17942 }
17943
17944
17945 /* Compute the pixel height and width of IT->glyph_row.
17946
17947 Most of the time, ascent and height of a display line will be equal
17948 to the max_ascent and max_height values of the display iterator
17949 structure. This is not the case if
17950
17951 1. We hit ZV without displaying anything. In this case, max_ascent
17952 and max_height will be zero.
17953
17954 2. We have some glyphs that don't contribute to the line height.
17955 (The glyph row flag contributes_to_line_height_p is for future
17956 pixmap extensions).
17957
17958 The first case is easily covered by using default values because in
17959 these cases, the line height does not really matter, except that it
17960 must not be zero. */
17961
17962 static void
17963 compute_line_metrics (struct it *it)
17964 {
17965 struct glyph_row *row = it->glyph_row;
17966
17967 if (FRAME_WINDOW_P (it->f))
17968 {
17969 int i, min_y, max_y;
17970
17971 /* The line may consist of one space only, that was added to
17972 place the cursor on it. If so, the row's height hasn't been
17973 computed yet. */
17974 if (row->height == 0)
17975 {
17976 if (it->max_ascent + it->max_descent == 0)
17977 it->max_descent = it->max_phys_descent = FRAME_LINE_HEIGHT (it->f);
17978 row->ascent = it->max_ascent;
17979 row->height = it->max_ascent + it->max_descent;
17980 row->phys_ascent = it->max_phys_ascent;
17981 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
17982 row->extra_line_spacing = it->max_extra_line_spacing;
17983 }
17984
17985 /* Compute the width of this line. */
17986 row->pixel_width = row->x;
17987 for (i = 0; i < row->used[TEXT_AREA]; ++i)
17988 row->pixel_width += row->glyphs[TEXT_AREA][i].pixel_width;
17989
17990 xassert (row->pixel_width >= 0);
17991 xassert (row->ascent >= 0 && row->height > 0);
17992
17993 row->overlapping_p = (MATRIX_ROW_OVERLAPS_SUCC_P (row)
17994 || MATRIX_ROW_OVERLAPS_PRED_P (row));
17995
17996 /* If first line's physical ascent is larger than its logical
17997 ascent, use the physical ascent, and make the row taller.
17998 This makes accented characters fully visible. */
17999 if (row == MATRIX_FIRST_TEXT_ROW (it->w->desired_matrix)
18000 && row->phys_ascent > row->ascent)
18001 {
18002 row->height += row->phys_ascent - row->ascent;
18003 row->ascent = row->phys_ascent;
18004 }
18005
18006 /* Compute how much of the line is visible. */
18007 row->visible_height = row->height;
18008
18009 min_y = WINDOW_HEADER_LINE_HEIGHT (it->w);
18010 max_y = WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w);
18011
18012 if (row->y < min_y)
18013 row->visible_height -= min_y - row->y;
18014 if (row->y + row->height > max_y)
18015 row->visible_height -= row->y + row->height - max_y;
18016 }
18017 else
18018 {
18019 row->pixel_width = row->used[TEXT_AREA];
18020 if (row->continued_p)
18021 row->pixel_width -= it->continuation_pixel_width;
18022 else if (row->truncated_on_right_p)
18023 row->pixel_width -= it->truncation_pixel_width;
18024 row->ascent = row->phys_ascent = 0;
18025 row->height = row->phys_height = row->visible_height = 1;
18026 row->extra_line_spacing = 0;
18027 }
18028
18029 /* Compute a hash code for this row. */
18030 {
18031 int area, i;
18032 row->hash = 0;
18033 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
18034 for (i = 0; i < row->used[area]; ++i)
18035 row->hash = ((((row->hash << 4) + (row->hash >> 24)) & 0x0fffffff)
18036 + row->glyphs[area][i].u.val
18037 + row->glyphs[area][i].face_id
18038 + row->glyphs[area][i].padding_p
18039 + (row->glyphs[area][i].type << 2));
18040 }
18041
18042 it->max_ascent = it->max_descent = 0;
18043 it->max_phys_ascent = it->max_phys_descent = 0;
18044 }
18045
18046
18047 /* Append one space to the glyph row of iterator IT if doing a
18048 window-based redisplay. The space has the same face as
18049 IT->face_id. Value is non-zero if a space was added.
18050
18051 This function is called to make sure that there is always one glyph
18052 at the end of a glyph row that the cursor can be set on under
18053 window-systems. (If there weren't such a glyph we would not know
18054 how wide and tall a box cursor should be displayed).
18055
18056 At the same time this space let's a nicely handle clearing to the
18057 end of the line if the row ends in italic text. */
18058
18059 static int
18060 append_space_for_newline (struct it *it, int default_face_p)
18061 {
18062 if (FRAME_WINDOW_P (it->f))
18063 {
18064 int n = it->glyph_row->used[TEXT_AREA];
18065
18066 if (it->glyph_row->glyphs[TEXT_AREA] + n
18067 < it->glyph_row->glyphs[1 + TEXT_AREA])
18068 {
18069 /* Save some values that must not be changed.
18070 Must save IT->c and IT->len because otherwise
18071 ITERATOR_AT_END_P wouldn't work anymore after
18072 append_space_for_newline has been called. */
18073 enum display_element_type saved_what = it->what;
18074 int saved_c = it->c, saved_len = it->len;
18075 int saved_char_to_display = it->char_to_display;
18076 int saved_x = it->current_x;
18077 int saved_face_id = it->face_id;
18078 struct text_pos saved_pos;
18079 Lisp_Object saved_object;
18080 struct face *face;
18081
18082 saved_object = it->object;
18083 saved_pos = it->position;
18084
18085 it->what = IT_CHARACTER;
18086 memset (&it->position, 0, sizeof it->position);
18087 it->object = make_number (0);
18088 it->c = it->char_to_display = ' ';
18089 it->len = 1;
18090
18091 if (default_face_p)
18092 it->face_id = DEFAULT_FACE_ID;
18093 else if (it->face_before_selective_p)
18094 it->face_id = it->saved_face_id;
18095 face = FACE_FROM_ID (it->f, it->face_id);
18096 it->face_id = FACE_FOR_CHAR (it->f, face, 0, -1, Qnil);
18097
18098 PRODUCE_GLYPHS (it);
18099
18100 it->override_ascent = -1;
18101 it->constrain_row_ascent_descent_p = 0;
18102 it->current_x = saved_x;
18103 it->object = saved_object;
18104 it->position = saved_pos;
18105 it->what = saved_what;
18106 it->face_id = saved_face_id;
18107 it->len = saved_len;
18108 it->c = saved_c;
18109 it->char_to_display = saved_char_to_display;
18110 return 1;
18111 }
18112 }
18113
18114 return 0;
18115 }
18116
18117
18118 /* Extend the face of the last glyph in the text area of IT->glyph_row
18119 to the end of the display line. Called from display_line. If the
18120 glyph row is empty, add a space glyph to it so that we know the
18121 face to draw. Set the glyph row flag fill_line_p. If the glyph
18122 row is R2L, prepend a stretch glyph to cover the empty space to the
18123 left of the leftmost glyph. */
18124
18125 static void
18126 extend_face_to_end_of_line (struct it *it)
18127 {
18128 struct face *face;
18129 struct frame *f = it->f;
18130
18131 /* If line is already filled, do nothing. Non window-system frames
18132 get a grace of one more ``pixel'' because their characters are
18133 1-``pixel'' wide, so they hit the equality too early. This grace
18134 is needed only for R2L rows that are not continued, to produce
18135 one extra blank where we could display the cursor. */
18136 if (it->current_x >= it->last_visible_x
18137 + (!FRAME_WINDOW_P (f)
18138 && it->glyph_row->reversed_p
18139 && !it->glyph_row->continued_p))
18140 return;
18141
18142 /* Face extension extends the background and box of IT->face_id
18143 to the end of the line. If the background equals the background
18144 of the frame, we don't have to do anything. */
18145 if (it->face_before_selective_p)
18146 face = FACE_FROM_ID (f, it->saved_face_id);
18147 else
18148 face = FACE_FROM_ID (f, it->face_id);
18149
18150 if (FRAME_WINDOW_P (f)
18151 && it->glyph_row->displays_text_p
18152 && face->box == FACE_NO_BOX
18153 && face->background == FRAME_BACKGROUND_PIXEL (f)
18154 && !face->stipple
18155 && !it->glyph_row->reversed_p)
18156 return;
18157
18158 /* Set the glyph row flag indicating that the face of the last glyph
18159 in the text area has to be drawn to the end of the text area. */
18160 it->glyph_row->fill_line_p = 1;
18161
18162 /* If current character of IT is not ASCII, make sure we have the
18163 ASCII face. This will be automatically undone the next time
18164 get_next_display_element returns a multibyte character. Note
18165 that the character will always be single byte in unibyte
18166 text. */
18167 if (!ASCII_CHAR_P (it->c))
18168 {
18169 it->face_id = FACE_FOR_CHAR (f, face, 0, -1, Qnil);
18170 }
18171
18172 if (FRAME_WINDOW_P (f))
18173 {
18174 /* If the row is empty, add a space with the current face of IT,
18175 so that we know which face to draw. */
18176 if (it->glyph_row->used[TEXT_AREA] == 0)
18177 {
18178 it->glyph_row->glyphs[TEXT_AREA][0] = space_glyph;
18179 it->glyph_row->glyphs[TEXT_AREA][0].face_id = it->face_id;
18180 it->glyph_row->used[TEXT_AREA] = 1;
18181 }
18182 #ifdef HAVE_WINDOW_SYSTEM
18183 if (it->glyph_row->reversed_p)
18184 {
18185 /* Prepend a stretch glyph to the row, such that the
18186 rightmost glyph will be drawn flushed all the way to the
18187 right margin of the window. The stretch glyph that will
18188 occupy the empty space, if any, to the left of the
18189 glyphs. */
18190 struct font *font = face->font ? face->font : FRAME_FONT (f);
18191 struct glyph *row_start = it->glyph_row->glyphs[TEXT_AREA];
18192 struct glyph *row_end = row_start + it->glyph_row->used[TEXT_AREA];
18193 struct glyph *g;
18194 int row_width, stretch_ascent, stretch_width;
18195 struct text_pos saved_pos;
18196 int saved_face_id, saved_avoid_cursor;
18197
18198 for (row_width = 0, g = row_start; g < row_end; g++)
18199 row_width += g->pixel_width;
18200 stretch_width = window_box_width (it->w, TEXT_AREA) - row_width;
18201 if (stretch_width > 0)
18202 {
18203 stretch_ascent =
18204 (((it->ascent + it->descent)
18205 * FONT_BASE (font)) / FONT_HEIGHT (font));
18206 saved_pos = it->position;
18207 memset (&it->position, 0, sizeof it->position);
18208 saved_avoid_cursor = it->avoid_cursor_p;
18209 it->avoid_cursor_p = 1;
18210 saved_face_id = it->face_id;
18211 /* The last row's stretch glyph should get the default
18212 face, to avoid painting the rest of the window with
18213 the region face, if the region ends at ZV. */
18214 if (it->glyph_row->ends_at_zv_p)
18215 it->face_id = DEFAULT_FACE_ID;
18216 else
18217 it->face_id = face->id;
18218 append_stretch_glyph (it, make_number (0), stretch_width,
18219 it->ascent + it->descent, stretch_ascent);
18220 it->position = saved_pos;
18221 it->avoid_cursor_p = saved_avoid_cursor;
18222 it->face_id = saved_face_id;
18223 }
18224 }
18225 #endif /* HAVE_WINDOW_SYSTEM */
18226 }
18227 else
18228 {
18229 /* Save some values that must not be changed. */
18230 int saved_x = it->current_x;
18231 struct text_pos saved_pos;
18232 Lisp_Object saved_object;
18233 enum display_element_type saved_what = it->what;
18234 int saved_face_id = it->face_id;
18235
18236 saved_object = it->object;
18237 saved_pos = it->position;
18238
18239 it->what = IT_CHARACTER;
18240 memset (&it->position, 0, sizeof it->position);
18241 it->object = make_number (0);
18242 it->c = it->char_to_display = ' ';
18243 it->len = 1;
18244 /* The last row's blank glyphs should get the default face, to
18245 avoid painting the rest of the window with the region face,
18246 if the region ends at ZV. */
18247 if (it->glyph_row->ends_at_zv_p)
18248 it->face_id = DEFAULT_FACE_ID;
18249 else
18250 it->face_id = face->id;
18251
18252 PRODUCE_GLYPHS (it);
18253
18254 while (it->current_x <= it->last_visible_x)
18255 PRODUCE_GLYPHS (it);
18256
18257 /* Don't count these blanks really. It would let us insert a left
18258 truncation glyph below and make us set the cursor on them, maybe. */
18259 it->current_x = saved_x;
18260 it->object = saved_object;
18261 it->position = saved_pos;
18262 it->what = saved_what;
18263 it->face_id = saved_face_id;
18264 }
18265 }
18266
18267
18268 /* Value is non-zero if text starting at CHARPOS in current_buffer is
18269 trailing whitespace. */
18270
18271 static int
18272 trailing_whitespace_p (EMACS_INT charpos)
18273 {
18274 EMACS_INT bytepos = CHAR_TO_BYTE (charpos);
18275 int c = 0;
18276
18277 while (bytepos < ZV_BYTE
18278 && (c = FETCH_CHAR (bytepos),
18279 c == ' ' || c == '\t'))
18280 ++bytepos;
18281
18282 if (bytepos >= ZV_BYTE || c == '\n' || c == '\r')
18283 {
18284 if (bytepos != PT_BYTE)
18285 return 1;
18286 }
18287 return 0;
18288 }
18289
18290
18291 /* Highlight trailing whitespace, if any, in ROW. */
18292
18293 static void
18294 highlight_trailing_whitespace (struct frame *f, struct glyph_row *row)
18295 {
18296 int used = row->used[TEXT_AREA];
18297
18298 if (used)
18299 {
18300 struct glyph *start = row->glyphs[TEXT_AREA];
18301 struct glyph *glyph = start + used - 1;
18302
18303 if (row->reversed_p)
18304 {
18305 /* Right-to-left rows need to be processed in the opposite
18306 direction, so swap the edge pointers. */
18307 glyph = start;
18308 start = row->glyphs[TEXT_AREA] + used - 1;
18309 }
18310
18311 /* Skip over glyphs inserted to display the cursor at the
18312 end of a line, for extending the face of the last glyph
18313 to the end of the line on terminals, and for truncation
18314 and continuation glyphs. */
18315 if (!row->reversed_p)
18316 {
18317 while (glyph >= start
18318 && glyph->type == CHAR_GLYPH
18319 && INTEGERP (glyph->object))
18320 --glyph;
18321 }
18322 else
18323 {
18324 while (glyph <= start
18325 && glyph->type == CHAR_GLYPH
18326 && INTEGERP (glyph->object))
18327 ++glyph;
18328 }
18329
18330 /* If last glyph is a space or stretch, and it's trailing
18331 whitespace, set the face of all trailing whitespace glyphs in
18332 IT->glyph_row to `trailing-whitespace'. */
18333 if ((row->reversed_p ? glyph <= start : glyph >= start)
18334 && BUFFERP (glyph->object)
18335 && (glyph->type == STRETCH_GLYPH
18336 || (glyph->type == CHAR_GLYPH
18337 && glyph->u.ch == ' '))
18338 && trailing_whitespace_p (glyph->charpos))
18339 {
18340 int face_id = lookup_named_face (f, Qtrailing_whitespace, 0);
18341 if (face_id < 0)
18342 return;
18343
18344 if (!row->reversed_p)
18345 {
18346 while (glyph >= start
18347 && BUFFERP (glyph->object)
18348 && (glyph->type == STRETCH_GLYPH
18349 || (glyph->type == CHAR_GLYPH
18350 && glyph->u.ch == ' ')))
18351 (glyph--)->face_id = face_id;
18352 }
18353 else
18354 {
18355 while (glyph <= start
18356 && BUFFERP (glyph->object)
18357 && (glyph->type == STRETCH_GLYPH
18358 || (glyph->type == CHAR_GLYPH
18359 && glyph->u.ch == ' ')))
18360 (glyph++)->face_id = face_id;
18361 }
18362 }
18363 }
18364 }
18365
18366
18367 /* Value is non-zero if glyph row ROW should be
18368 used to hold the cursor. */
18369
18370 static int
18371 cursor_row_p (struct glyph_row *row)
18372 {
18373 int result = 1;
18374
18375 if (PT == CHARPOS (row->end.pos)
18376 || PT == MATRIX_ROW_END_CHARPOS (row))
18377 {
18378 /* Suppose the row ends on a string.
18379 Unless the row is continued, that means it ends on a newline
18380 in the string. If it's anything other than a display string
18381 (e.g. a before-string from an overlay), we don't want the
18382 cursor there. (This heuristic seems to give the optimal
18383 behavior for the various types of multi-line strings.) */
18384 if (CHARPOS (row->end.string_pos) >= 0)
18385 {
18386 if (row->continued_p)
18387 result = 1;
18388 else
18389 {
18390 /* Check for `display' property. */
18391 struct glyph *beg = row->glyphs[TEXT_AREA];
18392 struct glyph *end = beg + row->used[TEXT_AREA] - 1;
18393 struct glyph *glyph;
18394
18395 result = 0;
18396 for (glyph = end; glyph >= beg; --glyph)
18397 if (STRINGP (glyph->object))
18398 {
18399 Lisp_Object prop
18400 = Fget_char_property (make_number (PT),
18401 Qdisplay, Qnil);
18402 result =
18403 (!NILP (prop)
18404 && display_prop_string_p (prop, glyph->object));
18405 break;
18406 }
18407 }
18408 }
18409 else if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
18410 {
18411 /* If the row ends in middle of a real character,
18412 and the line is continued, we want the cursor here.
18413 That's because CHARPOS (ROW->end.pos) would equal
18414 PT if PT is before the character. */
18415 if (!row->ends_in_ellipsis_p)
18416 result = row->continued_p;
18417 else
18418 /* If the row ends in an ellipsis, then
18419 CHARPOS (ROW->end.pos) will equal point after the
18420 invisible text. We want that position to be displayed
18421 after the ellipsis. */
18422 result = 0;
18423 }
18424 /* If the row ends at ZV, display the cursor at the end of that
18425 row instead of at the start of the row below. */
18426 else if (row->ends_at_zv_p)
18427 result = 1;
18428 else
18429 result = 0;
18430 }
18431
18432 return result;
18433 }
18434
18435 \f
18436
18437 /* Push the property PROP so that it will be rendered at the current
18438 position in IT. Return 1 if PROP was successfully pushed, 0
18439 otherwise. Called from handle_line_prefix to handle the
18440 `line-prefix' and `wrap-prefix' properties. */
18441
18442 static int
18443 push_display_prop (struct it *it, Lisp_Object prop)
18444 {
18445 struct text_pos pos =
18446 STRINGP (it->string) ? it->current.string_pos : it->current.pos;
18447
18448 xassert (it->method == GET_FROM_BUFFER
18449 || it->method == GET_FROM_DISPLAY_VECTOR
18450 || it->method == GET_FROM_STRING);
18451
18452 /* We need to save the current buffer/string position, so it will be
18453 restored by pop_it, because iterate_out_of_display_property
18454 depends on that being set correctly, but some situations leave
18455 it->position not yet set when this function is called. */
18456 push_it (it, &pos);
18457
18458 if (STRINGP (prop))
18459 {
18460 if (SCHARS (prop) == 0)
18461 {
18462 pop_it (it);
18463 return 0;
18464 }
18465
18466 it->string = prop;
18467 it->multibyte_p = STRING_MULTIBYTE (it->string);
18468 it->current.overlay_string_index = -1;
18469 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
18470 it->end_charpos = it->string_nchars = SCHARS (it->string);
18471 it->method = GET_FROM_STRING;
18472 it->stop_charpos = 0;
18473 it->prev_stop = 0;
18474 it->base_level_stop = 0;
18475
18476 /* Force paragraph direction to be that of the parent
18477 buffer/string. */
18478 if (it->bidi_p && it->bidi_it.paragraph_dir == R2L)
18479 it->paragraph_embedding = it->bidi_it.paragraph_dir;
18480 else
18481 it->paragraph_embedding = L2R;
18482
18483 /* Set up the bidi iterator for this display string. */
18484 if (it->bidi_p)
18485 {
18486 it->bidi_it.string.lstring = it->string;
18487 it->bidi_it.string.s = NULL;
18488 it->bidi_it.string.schars = it->end_charpos;
18489 it->bidi_it.string.bufpos = IT_CHARPOS (*it);
18490 it->bidi_it.string.from_disp_str = it->string_from_display_prop_p;
18491 it->bidi_it.string.unibyte = !it->multibyte_p;
18492 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
18493 }
18494 }
18495 else if (CONSP (prop) && EQ (XCAR (prop), Qspace))
18496 {
18497 it->method = GET_FROM_STRETCH;
18498 it->object = prop;
18499 }
18500 #ifdef HAVE_WINDOW_SYSTEM
18501 else if (IMAGEP (prop))
18502 {
18503 it->what = IT_IMAGE;
18504 it->image_id = lookup_image (it->f, prop);
18505 it->method = GET_FROM_IMAGE;
18506 }
18507 #endif /* HAVE_WINDOW_SYSTEM */
18508 else
18509 {
18510 pop_it (it); /* bogus display property, give up */
18511 return 0;
18512 }
18513
18514 return 1;
18515 }
18516
18517 /* Return the character-property PROP at the current position in IT. */
18518
18519 static Lisp_Object
18520 get_it_property (struct it *it, Lisp_Object prop)
18521 {
18522 Lisp_Object position;
18523
18524 if (STRINGP (it->object))
18525 position = make_number (IT_STRING_CHARPOS (*it));
18526 else if (BUFFERP (it->object))
18527 position = make_number (IT_CHARPOS (*it));
18528 else
18529 return Qnil;
18530
18531 return Fget_char_property (position, prop, it->object);
18532 }
18533
18534 /* See if there's a line- or wrap-prefix, and if so, push it on IT. */
18535
18536 static void
18537 handle_line_prefix (struct it *it)
18538 {
18539 Lisp_Object prefix;
18540
18541 if (it->continuation_lines_width > 0)
18542 {
18543 prefix = get_it_property (it, Qwrap_prefix);
18544 if (NILP (prefix))
18545 prefix = Vwrap_prefix;
18546 }
18547 else
18548 {
18549 prefix = get_it_property (it, Qline_prefix);
18550 if (NILP (prefix))
18551 prefix = Vline_prefix;
18552 }
18553 if (! NILP (prefix) && push_display_prop (it, prefix))
18554 {
18555 /* If the prefix is wider than the window, and we try to wrap
18556 it, it would acquire its own wrap prefix, and so on till the
18557 iterator stack overflows. So, don't wrap the prefix. */
18558 it->line_wrap = TRUNCATE;
18559 it->avoid_cursor_p = 1;
18560 }
18561 }
18562
18563 \f
18564
18565 /* Remove N glyphs at the start of a reversed IT->glyph_row. Called
18566 only for R2L lines from display_line and display_string, when they
18567 decide that too many glyphs were produced by PRODUCE_GLYPHS, and
18568 the line/string needs to be continued on the next glyph row. */
18569 static void
18570 unproduce_glyphs (struct it *it, int n)
18571 {
18572 struct glyph *glyph, *end;
18573
18574 xassert (it->glyph_row);
18575 xassert (it->glyph_row->reversed_p);
18576 xassert (it->area == TEXT_AREA);
18577 xassert (n <= it->glyph_row->used[TEXT_AREA]);
18578
18579 if (n > it->glyph_row->used[TEXT_AREA])
18580 n = it->glyph_row->used[TEXT_AREA];
18581 glyph = it->glyph_row->glyphs[TEXT_AREA] + n;
18582 end = it->glyph_row->glyphs[TEXT_AREA] + it->glyph_row->used[TEXT_AREA];
18583 for ( ; glyph < end; glyph++)
18584 glyph[-n] = *glyph;
18585 }
18586
18587 /* Find the positions in a bidi-reordered ROW to serve as ROW->minpos
18588 and ROW->maxpos. */
18589 static void
18590 find_row_edges (struct it *it, struct glyph_row *row,
18591 EMACS_INT min_pos, EMACS_INT min_bpos,
18592 EMACS_INT max_pos, EMACS_INT max_bpos)
18593 {
18594 /* FIXME: Revisit this when glyph ``spilling'' in continuation
18595 lines' rows is implemented for bidi-reordered rows. */
18596
18597 /* ROW->minpos is the value of min_pos, the minimal buffer position
18598 we have in ROW, or ROW->start.pos if that is smaller. */
18599 if (min_pos <= ZV && min_pos < row->start.pos.charpos)
18600 SET_TEXT_POS (row->minpos, min_pos, min_bpos);
18601 else
18602 /* We didn't find buffer positions smaller than ROW->start, or
18603 didn't find _any_ valid buffer positions in any of the glyphs,
18604 so we must trust the iterator's computed positions. */
18605 row->minpos = row->start.pos;
18606 if (max_pos <= 0)
18607 {
18608 max_pos = CHARPOS (it->current.pos);
18609 max_bpos = BYTEPOS (it->current.pos);
18610 }
18611
18612 /* Here are the various use-cases for ending the row, and the
18613 corresponding values for ROW->maxpos:
18614
18615 Line ends in a newline from buffer eol_pos + 1
18616 Line is continued from buffer max_pos + 1
18617 Line is truncated on right it->current.pos
18618 Line ends in a newline from string max_pos + 1(*)
18619 (*) + 1 only when line ends in a forward scan
18620 Line is continued from string max_pos
18621 Line is continued from display vector max_pos
18622 Line is entirely from a string min_pos == max_pos
18623 Line is entirely from a display vector min_pos == max_pos
18624 Line that ends at ZV ZV
18625
18626 If you discover other use-cases, please add them here as
18627 appropriate. */
18628 if (row->ends_at_zv_p)
18629 row->maxpos = it->current.pos;
18630 else if (row->used[TEXT_AREA])
18631 {
18632 int seen_this_string = 0;
18633 struct glyph_row *r1 = row - 1;
18634
18635 /* Did we see the same display string on the previous row? */
18636 if (STRINGP (it->object)
18637 /* this is not the first row */
18638 && row > it->w->desired_matrix->rows
18639 /* previous row is not the header line */
18640 && !r1->mode_line_p
18641 /* previous row also ends in a newline from a string */
18642 && r1->ends_in_newline_from_string_p)
18643 {
18644 struct glyph *start, *end;
18645
18646 /* Search for the last glyph of the previous row that came
18647 from buffer or string. Depending on whether the row is
18648 L2R or R2L, we need to process it front to back or the
18649 other way round. */
18650 if (!r1->reversed_p)
18651 {
18652 start = r1->glyphs[TEXT_AREA];
18653 end = start + r1->used[TEXT_AREA];
18654 /* Glyphs inserted by redisplay have an integer (zero)
18655 as their object. */
18656 while (end > start
18657 && INTEGERP ((end - 1)->object)
18658 && (end - 1)->charpos <= 0)
18659 --end;
18660 if (end > start)
18661 {
18662 if (EQ ((end - 1)->object, it->object))
18663 seen_this_string = 1;
18664 }
18665 else
18666 /* If all the glyphs of the previous row were inserted
18667 by redisplay, it means the previous row was
18668 produced from a single newline, which is only
18669 possible if that newline came from the same string
18670 as the one which produced this ROW. */
18671 seen_this_string = 1;
18672 }
18673 else
18674 {
18675 end = r1->glyphs[TEXT_AREA] - 1;
18676 start = end + r1->used[TEXT_AREA];
18677 while (end < start
18678 && INTEGERP ((end + 1)->object)
18679 && (end + 1)->charpos <= 0)
18680 ++end;
18681 if (end < start)
18682 {
18683 if (EQ ((end + 1)->object, it->object))
18684 seen_this_string = 1;
18685 }
18686 else
18687 seen_this_string = 1;
18688 }
18689 }
18690 /* Take note of each display string that covers a newline only
18691 once, the first time we see it. This is for when a display
18692 string includes more than one newline in it. */
18693 if (row->ends_in_newline_from_string_p && !seen_this_string)
18694 {
18695 /* If we were scanning the buffer forward when we displayed
18696 the string, we want to account for at least one buffer
18697 position that belongs to this row (position covered by
18698 the display string), so that cursor positioning will
18699 consider this row as a candidate when point is at the end
18700 of the visual line represented by this row. This is not
18701 required when scanning back, because max_pos will already
18702 have a much larger value. */
18703 if (CHARPOS (row->end.pos) > max_pos)
18704 INC_BOTH (max_pos, max_bpos);
18705 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
18706 }
18707 else if (CHARPOS (it->eol_pos) > 0)
18708 SET_TEXT_POS (row->maxpos,
18709 CHARPOS (it->eol_pos) + 1, BYTEPOS (it->eol_pos) + 1);
18710 else if (row->continued_p)
18711 {
18712 /* If max_pos is different from IT's current position, it
18713 means IT->method does not belong to the display element
18714 at max_pos. However, it also means that the display
18715 element at max_pos was displayed in its entirety on this
18716 line, which is equivalent to saying that the next line
18717 starts at the next buffer position. */
18718 if (IT_CHARPOS (*it) == max_pos && it->method != GET_FROM_BUFFER)
18719 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
18720 else
18721 {
18722 INC_BOTH (max_pos, max_bpos);
18723 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
18724 }
18725 }
18726 else if (row->truncated_on_right_p)
18727 /* display_line already called reseat_at_next_visible_line_start,
18728 which puts the iterator at the beginning of the next line, in
18729 the logical order. */
18730 row->maxpos = it->current.pos;
18731 else if (max_pos == min_pos && it->method != GET_FROM_BUFFER)
18732 /* A line that is entirely from a string/image/stretch... */
18733 row->maxpos = row->minpos;
18734 else
18735 abort ();
18736 }
18737 else
18738 row->maxpos = it->current.pos;
18739 }
18740
18741 /* Construct the glyph row IT->glyph_row in the desired matrix of
18742 IT->w from text at the current position of IT. See dispextern.h
18743 for an overview of struct it. Value is non-zero if
18744 IT->glyph_row displays text, as opposed to a line displaying ZV
18745 only. */
18746
18747 static int
18748 display_line (struct it *it)
18749 {
18750 struct glyph_row *row = it->glyph_row;
18751 Lisp_Object overlay_arrow_string;
18752 struct it wrap_it;
18753 void *wrap_data = NULL;
18754 int may_wrap = 0, wrap_x IF_LINT (= 0);
18755 int wrap_row_used = -1;
18756 int wrap_row_ascent IF_LINT (= 0), wrap_row_height IF_LINT (= 0);
18757 int wrap_row_phys_ascent IF_LINT (= 0), wrap_row_phys_height IF_LINT (= 0);
18758 int wrap_row_extra_line_spacing IF_LINT (= 0);
18759 EMACS_INT wrap_row_min_pos IF_LINT (= 0), wrap_row_min_bpos IF_LINT (= 0);
18760 EMACS_INT wrap_row_max_pos IF_LINT (= 0), wrap_row_max_bpos IF_LINT (= 0);
18761 int cvpos;
18762 EMACS_INT min_pos = ZV + 1, max_pos = 0;
18763 EMACS_INT min_bpos IF_LINT (= 0), max_bpos IF_LINT (= 0);
18764
18765 /* We always start displaying at hpos zero even if hscrolled. */
18766 xassert (it->hpos == 0 && it->current_x == 0);
18767
18768 if (MATRIX_ROW_VPOS (row, it->w->desired_matrix)
18769 >= it->w->desired_matrix->nrows)
18770 {
18771 it->w->nrows_scale_factor++;
18772 fonts_changed_p = 1;
18773 return 0;
18774 }
18775
18776 /* Is IT->w showing the region? */
18777 it->w->region_showing = it->region_beg_charpos > 0 ? Qt : Qnil;
18778
18779 /* Clear the result glyph row and enable it. */
18780 prepare_desired_row (row);
18781
18782 row->y = it->current_y;
18783 row->start = it->start;
18784 row->continuation_lines_width = it->continuation_lines_width;
18785 row->displays_text_p = 1;
18786 row->starts_in_middle_of_char_p = it->starts_in_middle_of_char_p;
18787 it->starts_in_middle_of_char_p = 0;
18788
18789 /* Arrange the overlays nicely for our purposes. Usually, we call
18790 display_line on only one line at a time, in which case this
18791 can't really hurt too much, or we call it on lines which appear
18792 one after another in the buffer, in which case all calls to
18793 recenter_overlay_lists but the first will be pretty cheap. */
18794 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
18795
18796 /* Move over display elements that are not visible because we are
18797 hscrolled. This may stop at an x-position < IT->first_visible_x
18798 if the first glyph is partially visible or if we hit a line end. */
18799 if (it->current_x < it->first_visible_x)
18800 {
18801 this_line_min_pos = row->start.pos;
18802 move_it_in_display_line_to (it, ZV, it->first_visible_x,
18803 MOVE_TO_POS | MOVE_TO_X);
18804 /* Record the smallest positions seen while we moved over
18805 display elements that are not visible. This is needed by
18806 redisplay_internal for optimizing the case where the cursor
18807 stays inside the same line. The rest of this function only
18808 considers positions that are actually displayed, so
18809 RECORD_MAX_MIN_POS will not otherwise record positions that
18810 are hscrolled to the left of the left edge of the window. */
18811 min_pos = CHARPOS (this_line_min_pos);
18812 min_bpos = BYTEPOS (this_line_min_pos);
18813 }
18814 else
18815 {
18816 /* We only do this when not calling `move_it_in_display_line_to'
18817 above, because move_it_in_display_line_to calls
18818 handle_line_prefix itself. */
18819 handle_line_prefix (it);
18820 }
18821
18822 /* Get the initial row height. This is either the height of the
18823 text hscrolled, if there is any, or zero. */
18824 row->ascent = it->max_ascent;
18825 row->height = it->max_ascent + it->max_descent;
18826 row->phys_ascent = it->max_phys_ascent;
18827 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
18828 row->extra_line_spacing = it->max_extra_line_spacing;
18829
18830 /* Utility macro to record max and min buffer positions seen until now. */
18831 #define RECORD_MAX_MIN_POS(IT) \
18832 do \
18833 { \
18834 int composition_p = (IT)->what == IT_COMPOSITION; \
18835 EMACS_INT current_pos = \
18836 composition_p ? (IT)->cmp_it.charpos \
18837 : IT_CHARPOS (*(IT)); \
18838 EMACS_INT current_bpos = \
18839 composition_p ? CHAR_TO_BYTE (current_pos) \
18840 : IT_BYTEPOS (*(IT)); \
18841 if (current_pos < min_pos) \
18842 { \
18843 min_pos = current_pos; \
18844 min_bpos = current_bpos; \
18845 } \
18846 if (IT_CHARPOS (*it) > max_pos) \
18847 { \
18848 max_pos = IT_CHARPOS (*it); \
18849 max_bpos = IT_BYTEPOS (*it); \
18850 } \
18851 } \
18852 while (0)
18853
18854 /* Loop generating characters. The loop is left with IT on the next
18855 character to display. */
18856 while (1)
18857 {
18858 int n_glyphs_before, hpos_before, x_before;
18859 int x, nglyphs;
18860 int ascent = 0, descent = 0, phys_ascent = 0, phys_descent = 0;
18861
18862 /* Retrieve the next thing to display. Value is zero if end of
18863 buffer reached. */
18864 if (!get_next_display_element (it))
18865 {
18866 /* Maybe add a space at the end of this line that is used to
18867 display the cursor there under X. Set the charpos of the
18868 first glyph of blank lines not corresponding to any text
18869 to -1. */
18870 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
18871 row->exact_window_width_line_p = 1;
18872 else if ((append_space_for_newline (it, 1) && row->used[TEXT_AREA] == 1)
18873 || row->used[TEXT_AREA] == 0)
18874 {
18875 row->glyphs[TEXT_AREA]->charpos = -1;
18876 row->displays_text_p = 0;
18877
18878 if (!NILP (BVAR (XBUFFER (it->w->buffer), indicate_empty_lines))
18879 && (!MINI_WINDOW_P (it->w)
18880 || (minibuf_level && EQ (it->window, minibuf_window))))
18881 row->indicate_empty_line_p = 1;
18882 }
18883
18884 it->continuation_lines_width = 0;
18885 row->ends_at_zv_p = 1;
18886 /* A row that displays right-to-left text must always have
18887 its last face extended all the way to the end of line,
18888 even if this row ends in ZV, because we still write to
18889 the screen left to right. */
18890 if (row->reversed_p)
18891 extend_face_to_end_of_line (it);
18892 break;
18893 }
18894
18895 /* Now, get the metrics of what we want to display. This also
18896 generates glyphs in `row' (which is IT->glyph_row). */
18897 n_glyphs_before = row->used[TEXT_AREA];
18898 x = it->current_x;
18899
18900 /* Remember the line height so far in case the next element doesn't
18901 fit on the line. */
18902 if (it->line_wrap != TRUNCATE)
18903 {
18904 ascent = it->max_ascent;
18905 descent = it->max_descent;
18906 phys_ascent = it->max_phys_ascent;
18907 phys_descent = it->max_phys_descent;
18908
18909 if (it->line_wrap == WORD_WRAP && it->area == TEXT_AREA)
18910 {
18911 if (IT_DISPLAYING_WHITESPACE (it))
18912 may_wrap = 1;
18913 else if (may_wrap)
18914 {
18915 SAVE_IT (wrap_it, *it, wrap_data);
18916 wrap_x = x;
18917 wrap_row_used = row->used[TEXT_AREA];
18918 wrap_row_ascent = row->ascent;
18919 wrap_row_height = row->height;
18920 wrap_row_phys_ascent = row->phys_ascent;
18921 wrap_row_phys_height = row->phys_height;
18922 wrap_row_extra_line_spacing = row->extra_line_spacing;
18923 wrap_row_min_pos = min_pos;
18924 wrap_row_min_bpos = min_bpos;
18925 wrap_row_max_pos = max_pos;
18926 wrap_row_max_bpos = max_bpos;
18927 may_wrap = 0;
18928 }
18929 }
18930 }
18931
18932 PRODUCE_GLYPHS (it);
18933
18934 /* If this display element was in marginal areas, continue with
18935 the next one. */
18936 if (it->area != TEXT_AREA)
18937 {
18938 row->ascent = max (row->ascent, it->max_ascent);
18939 row->height = max (row->height, it->max_ascent + it->max_descent);
18940 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
18941 row->phys_height = max (row->phys_height,
18942 it->max_phys_ascent + it->max_phys_descent);
18943 row->extra_line_spacing = max (row->extra_line_spacing,
18944 it->max_extra_line_spacing);
18945 set_iterator_to_next (it, 1);
18946 continue;
18947 }
18948
18949 /* Does the display element fit on the line? If we truncate
18950 lines, we should draw past the right edge of the window. If
18951 we don't truncate, we want to stop so that we can display the
18952 continuation glyph before the right margin. If lines are
18953 continued, there are two possible strategies for characters
18954 resulting in more than 1 glyph (e.g. tabs): Display as many
18955 glyphs as possible in this line and leave the rest for the
18956 continuation line, or display the whole element in the next
18957 line. Original redisplay did the former, so we do it also. */
18958 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
18959 hpos_before = it->hpos;
18960 x_before = x;
18961
18962 if (/* Not a newline. */
18963 nglyphs > 0
18964 /* Glyphs produced fit entirely in the line. */
18965 && it->current_x < it->last_visible_x)
18966 {
18967 it->hpos += nglyphs;
18968 row->ascent = max (row->ascent, it->max_ascent);
18969 row->height = max (row->height, it->max_ascent + it->max_descent);
18970 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
18971 row->phys_height = max (row->phys_height,
18972 it->max_phys_ascent + it->max_phys_descent);
18973 row->extra_line_spacing = max (row->extra_line_spacing,
18974 it->max_extra_line_spacing);
18975 if (it->current_x - it->pixel_width < it->first_visible_x)
18976 row->x = x - it->first_visible_x;
18977 /* Record the maximum and minimum buffer positions seen so
18978 far in glyphs that will be displayed by this row. */
18979 if (it->bidi_p)
18980 RECORD_MAX_MIN_POS (it);
18981 }
18982 else
18983 {
18984 int i, new_x;
18985 struct glyph *glyph;
18986
18987 for (i = 0; i < nglyphs; ++i, x = new_x)
18988 {
18989 glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
18990 new_x = x + glyph->pixel_width;
18991
18992 if (/* Lines are continued. */
18993 it->line_wrap != TRUNCATE
18994 && (/* Glyph doesn't fit on the line. */
18995 new_x > it->last_visible_x
18996 /* Or it fits exactly on a window system frame. */
18997 || (new_x == it->last_visible_x
18998 && FRAME_WINDOW_P (it->f))))
18999 {
19000 /* End of a continued line. */
19001
19002 if (it->hpos == 0
19003 || (new_x == it->last_visible_x
19004 && FRAME_WINDOW_P (it->f)))
19005 {
19006 /* Current glyph is the only one on the line or
19007 fits exactly on the line. We must continue
19008 the line because we can't draw the cursor
19009 after the glyph. */
19010 row->continued_p = 1;
19011 it->current_x = new_x;
19012 it->continuation_lines_width += new_x;
19013 ++it->hpos;
19014 if (i == nglyphs - 1)
19015 {
19016 /* If line-wrap is on, check if a previous
19017 wrap point was found. */
19018 if (wrap_row_used > 0
19019 /* Even if there is a previous wrap
19020 point, continue the line here as
19021 usual, if (i) the previous character
19022 was a space or tab AND (ii) the
19023 current character is not. */
19024 && (!may_wrap
19025 || IT_DISPLAYING_WHITESPACE (it)))
19026 goto back_to_wrap;
19027
19028 /* Record the maximum and minimum buffer
19029 positions seen so far in glyphs that will be
19030 displayed by this row. */
19031 if (it->bidi_p)
19032 RECORD_MAX_MIN_POS (it);
19033 set_iterator_to_next (it, 1);
19034 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
19035 {
19036 if (!get_next_display_element (it))
19037 {
19038 row->exact_window_width_line_p = 1;
19039 it->continuation_lines_width = 0;
19040 row->continued_p = 0;
19041 row->ends_at_zv_p = 1;
19042 }
19043 else if (ITERATOR_AT_END_OF_LINE_P (it))
19044 {
19045 row->continued_p = 0;
19046 row->exact_window_width_line_p = 1;
19047 }
19048 }
19049 }
19050 else if (it->bidi_p)
19051 RECORD_MAX_MIN_POS (it);
19052 }
19053 else if (CHAR_GLYPH_PADDING_P (*glyph)
19054 && !FRAME_WINDOW_P (it->f))
19055 {
19056 /* A padding glyph that doesn't fit on this line.
19057 This means the whole character doesn't fit
19058 on the line. */
19059 if (row->reversed_p)
19060 unproduce_glyphs (it, row->used[TEXT_AREA]
19061 - n_glyphs_before);
19062 row->used[TEXT_AREA] = n_glyphs_before;
19063
19064 /* Fill the rest of the row with continuation
19065 glyphs like in 20.x. */
19066 while (row->glyphs[TEXT_AREA] + row->used[TEXT_AREA]
19067 < row->glyphs[1 + TEXT_AREA])
19068 produce_special_glyphs (it, IT_CONTINUATION);
19069
19070 row->continued_p = 1;
19071 it->current_x = x_before;
19072 it->continuation_lines_width += x_before;
19073
19074 /* Restore the height to what it was before the
19075 element not fitting on the line. */
19076 it->max_ascent = ascent;
19077 it->max_descent = descent;
19078 it->max_phys_ascent = phys_ascent;
19079 it->max_phys_descent = phys_descent;
19080 }
19081 else if (wrap_row_used > 0)
19082 {
19083 back_to_wrap:
19084 if (row->reversed_p)
19085 unproduce_glyphs (it,
19086 row->used[TEXT_AREA] - wrap_row_used);
19087 RESTORE_IT (it, &wrap_it, wrap_data);
19088 it->continuation_lines_width += wrap_x;
19089 row->used[TEXT_AREA] = wrap_row_used;
19090 row->ascent = wrap_row_ascent;
19091 row->height = wrap_row_height;
19092 row->phys_ascent = wrap_row_phys_ascent;
19093 row->phys_height = wrap_row_phys_height;
19094 row->extra_line_spacing = wrap_row_extra_line_spacing;
19095 min_pos = wrap_row_min_pos;
19096 min_bpos = wrap_row_min_bpos;
19097 max_pos = wrap_row_max_pos;
19098 max_bpos = wrap_row_max_bpos;
19099 row->continued_p = 1;
19100 row->ends_at_zv_p = 0;
19101 row->exact_window_width_line_p = 0;
19102 it->continuation_lines_width += x;
19103
19104 /* Make sure that a non-default face is extended
19105 up to the right margin of the window. */
19106 extend_face_to_end_of_line (it);
19107 }
19108 else if (it->c == '\t' && FRAME_WINDOW_P (it->f))
19109 {
19110 /* A TAB that extends past the right edge of the
19111 window. This produces a single glyph on
19112 window system frames. We leave the glyph in
19113 this row and let it fill the row, but don't
19114 consume the TAB. */
19115 it->continuation_lines_width += it->last_visible_x;
19116 row->ends_in_middle_of_char_p = 1;
19117 row->continued_p = 1;
19118 glyph->pixel_width = it->last_visible_x - x;
19119 it->starts_in_middle_of_char_p = 1;
19120 }
19121 else
19122 {
19123 /* Something other than a TAB that draws past
19124 the right edge of the window. Restore
19125 positions to values before the element. */
19126 if (row->reversed_p)
19127 unproduce_glyphs (it, row->used[TEXT_AREA]
19128 - (n_glyphs_before + i));
19129 row->used[TEXT_AREA] = n_glyphs_before + i;
19130
19131 /* Display continuation glyphs. */
19132 if (!FRAME_WINDOW_P (it->f))
19133 produce_special_glyphs (it, IT_CONTINUATION);
19134 row->continued_p = 1;
19135
19136 it->current_x = x_before;
19137 it->continuation_lines_width += x;
19138 extend_face_to_end_of_line (it);
19139
19140 if (nglyphs > 1 && i > 0)
19141 {
19142 row->ends_in_middle_of_char_p = 1;
19143 it->starts_in_middle_of_char_p = 1;
19144 }
19145
19146 /* Restore the height to what it was before the
19147 element not fitting on the line. */
19148 it->max_ascent = ascent;
19149 it->max_descent = descent;
19150 it->max_phys_ascent = phys_ascent;
19151 it->max_phys_descent = phys_descent;
19152 }
19153
19154 break;
19155 }
19156 else if (new_x > it->first_visible_x)
19157 {
19158 /* Increment number of glyphs actually displayed. */
19159 ++it->hpos;
19160
19161 /* Record the maximum and minimum buffer positions
19162 seen so far in glyphs that will be displayed by
19163 this row. */
19164 if (it->bidi_p)
19165 RECORD_MAX_MIN_POS (it);
19166
19167 if (x < it->first_visible_x)
19168 /* Glyph is partially visible, i.e. row starts at
19169 negative X position. */
19170 row->x = x - it->first_visible_x;
19171 }
19172 else
19173 {
19174 /* Glyph is completely off the left margin of the
19175 window. This should not happen because of the
19176 move_it_in_display_line at the start of this
19177 function, unless the text display area of the
19178 window is empty. */
19179 xassert (it->first_visible_x <= it->last_visible_x);
19180 }
19181 }
19182 /* Even if this display element produced no glyphs at all,
19183 we want to record its position. */
19184 if (it->bidi_p && nglyphs == 0)
19185 RECORD_MAX_MIN_POS (it);
19186
19187 row->ascent = max (row->ascent, it->max_ascent);
19188 row->height = max (row->height, it->max_ascent + it->max_descent);
19189 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
19190 row->phys_height = max (row->phys_height,
19191 it->max_phys_ascent + it->max_phys_descent);
19192 row->extra_line_spacing = max (row->extra_line_spacing,
19193 it->max_extra_line_spacing);
19194
19195 /* End of this display line if row is continued. */
19196 if (row->continued_p || row->ends_at_zv_p)
19197 break;
19198 }
19199
19200 at_end_of_line:
19201 /* Is this a line end? If yes, we're also done, after making
19202 sure that a non-default face is extended up to the right
19203 margin of the window. */
19204 if (ITERATOR_AT_END_OF_LINE_P (it))
19205 {
19206 int used_before = row->used[TEXT_AREA];
19207
19208 row->ends_in_newline_from_string_p = STRINGP (it->object);
19209
19210 /* Add a space at the end of the line that is used to
19211 display the cursor there. */
19212 if (!IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
19213 append_space_for_newline (it, 0);
19214
19215 /* Extend the face to the end of the line. */
19216 extend_face_to_end_of_line (it);
19217
19218 /* Make sure we have the position. */
19219 if (used_before == 0)
19220 row->glyphs[TEXT_AREA]->charpos = CHARPOS (it->position);
19221
19222 /* Record the position of the newline, for use in
19223 find_row_edges. */
19224 it->eol_pos = it->current.pos;
19225
19226 /* Consume the line end. This skips over invisible lines. */
19227 set_iterator_to_next (it, 1);
19228 it->continuation_lines_width = 0;
19229 break;
19230 }
19231
19232 /* Proceed with next display element. Note that this skips
19233 over lines invisible because of selective display. */
19234 set_iterator_to_next (it, 1);
19235
19236 /* If we truncate lines, we are done when the last displayed
19237 glyphs reach past the right margin of the window. */
19238 if (it->line_wrap == TRUNCATE
19239 && (FRAME_WINDOW_P (it->f)
19240 ? (it->current_x >= it->last_visible_x)
19241 : (it->current_x > it->last_visible_x)))
19242 {
19243 /* Maybe add truncation glyphs. */
19244 if (!FRAME_WINDOW_P (it->f))
19245 {
19246 int i, n;
19247
19248 if (!row->reversed_p)
19249 {
19250 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
19251 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
19252 break;
19253 }
19254 else
19255 {
19256 for (i = 0; i < row->used[TEXT_AREA]; i++)
19257 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
19258 break;
19259 /* Remove any padding glyphs at the front of ROW, to
19260 make room for the truncation glyphs we will be
19261 adding below. The loop below always inserts at
19262 least one truncation glyph, so also remove the
19263 last glyph added to ROW. */
19264 unproduce_glyphs (it, i + 1);
19265 /* Adjust i for the loop below. */
19266 i = row->used[TEXT_AREA] - (i + 1);
19267 }
19268
19269 for (n = row->used[TEXT_AREA]; i < n; ++i)
19270 {
19271 row->used[TEXT_AREA] = i;
19272 produce_special_glyphs (it, IT_TRUNCATION);
19273 }
19274 }
19275 else if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
19276 {
19277 /* Don't truncate if we can overflow newline into fringe. */
19278 if (!get_next_display_element (it))
19279 {
19280 it->continuation_lines_width = 0;
19281 row->ends_at_zv_p = 1;
19282 row->exact_window_width_line_p = 1;
19283 break;
19284 }
19285 if (ITERATOR_AT_END_OF_LINE_P (it))
19286 {
19287 row->exact_window_width_line_p = 1;
19288 goto at_end_of_line;
19289 }
19290 }
19291
19292 row->truncated_on_right_p = 1;
19293 it->continuation_lines_width = 0;
19294 reseat_at_next_visible_line_start (it, 0);
19295 row->ends_at_zv_p = FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n';
19296 it->hpos = hpos_before;
19297 it->current_x = x_before;
19298 break;
19299 }
19300 }
19301
19302 if (wrap_data)
19303 bidi_unshelve_cache (wrap_data, 1);
19304
19305 /* If line is not empty and hscrolled, maybe insert truncation glyphs
19306 at the left window margin. */
19307 if (it->first_visible_x
19308 && IT_CHARPOS (*it) != CHARPOS (row->start.pos))
19309 {
19310 if (!FRAME_WINDOW_P (it->f))
19311 insert_left_trunc_glyphs (it);
19312 row->truncated_on_left_p = 1;
19313 }
19314
19315 /* Remember the position at which this line ends.
19316
19317 BIDI Note: any code that needs MATRIX_ROW_START/END_CHARPOS
19318 cannot be before the call to find_row_edges below, since that is
19319 where these positions are determined. */
19320 row->end = it->current;
19321 if (!it->bidi_p)
19322 {
19323 row->minpos = row->start.pos;
19324 row->maxpos = row->end.pos;
19325 }
19326 else
19327 {
19328 /* ROW->minpos and ROW->maxpos must be the smallest and
19329 `1 + the largest' buffer positions in ROW. But if ROW was
19330 bidi-reordered, these two positions can be anywhere in the
19331 row, so we must determine them now. */
19332 find_row_edges (it, row, min_pos, min_bpos, max_pos, max_bpos);
19333 }
19334
19335 /* If the start of this line is the overlay arrow-position, then
19336 mark this glyph row as the one containing the overlay arrow.
19337 This is clearly a mess with variable size fonts. It would be
19338 better to let it be displayed like cursors under X. */
19339 if ((row->displays_text_p || !overlay_arrow_seen)
19340 && (overlay_arrow_string = overlay_arrow_at_row (it, row),
19341 !NILP (overlay_arrow_string)))
19342 {
19343 /* Overlay arrow in window redisplay is a fringe bitmap. */
19344 if (STRINGP (overlay_arrow_string))
19345 {
19346 struct glyph_row *arrow_row
19347 = get_overlay_arrow_glyph_row (it->w, overlay_arrow_string);
19348 struct glyph *glyph = arrow_row->glyphs[TEXT_AREA];
19349 struct glyph *arrow_end = glyph + arrow_row->used[TEXT_AREA];
19350 struct glyph *p = row->glyphs[TEXT_AREA];
19351 struct glyph *p2, *end;
19352
19353 /* Copy the arrow glyphs. */
19354 while (glyph < arrow_end)
19355 *p++ = *glyph++;
19356
19357 /* Throw away padding glyphs. */
19358 p2 = p;
19359 end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
19360 while (p2 < end && CHAR_GLYPH_PADDING_P (*p2))
19361 ++p2;
19362 if (p2 > p)
19363 {
19364 while (p2 < end)
19365 *p++ = *p2++;
19366 row->used[TEXT_AREA] = p2 - row->glyphs[TEXT_AREA];
19367 }
19368 }
19369 else
19370 {
19371 xassert (INTEGERP (overlay_arrow_string));
19372 row->overlay_arrow_bitmap = XINT (overlay_arrow_string);
19373 }
19374 overlay_arrow_seen = 1;
19375 }
19376
19377 /* Compute pixel dimensions of this line. */
19378 compute_line_metrics (it);
19379
19380 /* Record whether this row ends inside an ellipsis. */
19381 row->ends_in_ellipsis_p
19382 = (it->method == GET_FROM_DISPLAY_VECTOR
19383 && it->ellipsis_p);
19384
19385 /* Save fringe bitmaps in this row. */
19386 row->left_user_fringe_bitmap = it->left_user_fringe_bitmap;
19387 row->left_user_fringe_face_id = it->left_user_fringe_face_id;
19388 row->right_user_fringe_bitmap = it->right_user_fringe_bitmap;
19389 row->right_user_fringe_face_id = it->right_user_fringe_face_id;
19390
19391 it->left_user_fringe_bitmap = 0;
19392 it->left_user_fringe_face_id = 0;
19393 it->right_user_fringe_bitmap = 0;
19394 it->right_user_fringe_face_id = 0;
19395
19396 /* Maybe set the cursor. */
19397 cvpos = it->w->cursor.vpos;
19398 if ((cvpos < 0
19399 /* In bidi-reordered rows, keep checking for proper cursor
19400 position even if one has been found already, because buffer
19401 positions in such rows change non-linearly with ROW->VPOS,
19402 when a line is continued. One exception: when we are at ZV,
19403 display cursor on the first suitable glyph row, since all
19404 the empty rows after that also have their position set to ZV. */
19405 /* FIXME: Revisit this when glyph ``spilling'' in continuation
19406 lines' rows is implemented for bidi-reordered rows. */
19407 || (it->bidi_p
19408 && !MATRIX_ROW (it->w->desired_matrix, cvpos)->ends_at_zv_p))
19409 && PT >= MATRIX_ROW_START_CHARPOS (row)
19410 && PT <= MATRIX_ROW_END_CHARPOS (row)
19411 && cursor_row_p (row))
19412 set_cursor_from_row (it->w, row, it->w->desired_matrix, 0, 0, 0, 0);
19413
19414 /* Highlight trailing whitespace. */
19415 if (!NILP (Vshow_trailing_whitespace))
19416 highlight_trailing_whitespace (it->f, it->glyph_row);
19417
19418 /* Prepare for the next line. This line starts horizontally at (X
19419 HPOS) = (0 0). Vertical positions are incremented. As a
19420 convenience for the caller, IT->glyph_row is set to the next
19421 row to be used. */
19422 it->current_x = it->hpos = 0;
19423 it->current_y += row->height;
19424 SET_TEXT_POS (it->eol_pos, 0, 0);
19425 ++it->vpos;
19426 ++it->glyph_row;
19427 /* The next row should by default use the same value of the
19428 reversed_p flag as this one. set_iterator_to_next decides when
19429 it's a new paragraph, and PRODUCE_GLYPHS recomputes the value of
19430 the flag accordingly. */
19431 if (it->glyph_row < MATRIX_BOTTOM_TEXT_ROW (it->w->desired_matrix, it->w))
19432 it->glyph_row->reversed_p = row->reversed_p;
19433 it->start = row->end;
19434 return row->displays_text_p;
19435
19436 #undef RECORD_MAX_MIN_POS
19437 }
19438
19439 DEFUN ("current-bidi-paragraph-direction", Fcurrent_bidi_paragraph_direction,
19440 Scurrent_bidi_paragraph_direction, 0, 1, 0,
19441 doc: /* Return paragraph direction at point in BUFFER.
19442 Value is either `left-to-right' or `right-to-left'.
19443 If BUFFER is omitted or nil, it defaults to the current buffer.
19444
19445 Paragraph direction determines how the text in the paragraph is displayed.
19446 In left-to-right paragraphs, text begins at the left margin of the window
19447 and the reading direction is generally left to right. In right-to-left
19448 paragraphs, text begins at the right margin and is read from right to left.
19449
19450 See also `bidi-paragraph-direction'. */)
19451 (Lisp_Object buffer)
19452 {
19453 struct buffer *buf = current_buffer;
19454 struct buffer *old = buf;
19455
19456 if (! NILP (buffer))
19457 {
19458 CHECK_BUFFER (buffer);
19459 buf = XBUFFER (buffer);
19460 }
19461
19462 if (NILP (BVAR (buf, bidi_display_reordering))
19463 || NILP (BVAR (buf, enable_multibyte_characters)))
19464 return Qleft_to_right;
19465 else if (!NILP (BVAR (buf, bidi_paragraph_direction)))
19466 return BVAR (buf, bidi_paragraph_direction);
19467 else
19468 {
19469 /* Determine the direction from buffer text. We could try to
19470 use current_matrix if it is up to date, but this seems fast
19471 enough as it is. */
19472 struct bidi_it itb;
19473 EMACS_INT pos = BUF_PT (buf);
19474 EMACS_INT bytepos = BUF_PT_BYTE (buf);
19475 int c;
19476 void *itb_data = bidi_shelve_cache ();
19477
19478 set_buffer_temp (buf);
19479 /* bidi_paragraph_init finds the base direction of the paragraph
19480 by searching forward from paragraph start. We need the base
19481 direction of the current or _previous_ paragraph, so we need
19482 to make sure we are within that paragraph. To that end, find
19483 the previous non-empty line. */
19484 if (pos >= ZV && pos > BEGV)
19485 {
19486 pos--;
19487 bytepos = CHAR_TO_BYTE (pos);
19488 }
19489 if (fast_looking_at (build_string ("[\f\t ]*\n"),
19490 pos, bytepos, ZV, ZV_BYTE, Qnil) > 0)
19491 {
19492 while ((c = FETCH_BYTE (bytepos)) == '\n'
19493 || c == ' ' || c == '\t' || c == '\f')
19494 {
19495 if (bytepos <= BEGV_BYTE)
19496 break;
19497 bytepos--;
19498 pos--;
19499 }
19500 while (!CHAR_HEAD_P (FETCH_BYTE (bytepos)))
19501 bytepos--;
19502 }
19503 bidi_init_it (pos, bytepos, FRAME_WINDOW_P (SELECTED_FRAME ()), &itb);
19504 itb.paragraph_dir = NEUTRAL_DIR;
19505 itb.string.s = NULL;
19506 itb.string.lstring = Qnil;
19507 itb.string.bufpos = 0;
19508 itb.string.unibyte = 0;
19509 bidi_paragraph_init (NEUTRAL_DIR, &itb, 1);
19510 bidi_unshelve_cache (itb_data, 0);
19511 set_buffer_temp (old);
19512 switch (itb.paragraph_dir)
19513 {
19514 case L2R:
19515 return Qleft_to_right;
19516 break;
19517 case R2L:
19518 return Qright_to_left;
19519 break;
19520 default:
19521 abort ();
19522 }
19523 }
19524 }
19525
19526
19527 \f
19528 /***********************************************************************
19529 Menu Bar
19530 ***********************************************************************/
19531
19532 /* Redisplay the menu bar in the frame for window W.
19533
19534 The menu bar of X frames that don't have X toolkit support is
19535 displayed in a special window W->frame->menu_bar_window.
19536
19537 The menu bar of terminal frames is treated specially as far as
19538 glyph matrices are concerned. Menu bar lines are not part of
19539 windows, so the update is done directly on the frame matrix rows
19540 for the menu bar. */
19541
19542 static void
19543 display_menu_bar (struct window *w)
19544 {
19545 struct frame *f = XFRAME (WINDOW_FRAME (w));
19546 struct it it;
19547 Lisp_Object items;
19548 int i;
19549
19550 /* Don't do all this for graphical frames. */
19551 #ifdef HAVE_NTGUI
19552 if (FRAME_W32_P (f))
19553 return;
19554 #endif
19555 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
19556 if (FRAME_X_P (f))
19557 return;
19558 #endif
19559
19560 #ifdef HAVE_NS
19561 if (FRAME_NS_P (f))
19562 return;
19563 #endif /* HAVE_NS */
19564
19565 #ifdef USE_X_TOOLKIT
19566 xassert (!FRAME_WINDOW_P (f));
19567 init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MENU_FACE_ID);
19568 it.first_visible_x = 0;
19569 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
19570 #else /* not USE_X_TOOLKIT */
19571 if (FRAME_WINDOW_P (f))
19572 {
19573 /* Menu bar lines are displayed in the desired matrix of the
19574 dummy window menu_bar_window. */
19575 struct window *menu_w;
19576 xassert (WINDOWP (f->menu_bar_window));
19577 menu_w = XWINDOW (f->menu_bar_window);
19578 init_iterator (&it, menu_w, -1, -1, menu_w->desired_matrix->rows,
19579 MENU_FACE_ID);
19580 it.first_visible_x = 0;
19581 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
19582 }
19583 else
19584 {
19585 /* This is a TTY frame, i.e. character hpos/vpos are used as
19586 pixel x/y. */
19587 init_iterator (&it, w, -1, -1, f->desired_matrix->rows,
19588 MENU_FACE_ID);
19589 it.first_visible_x = 0;
19590 it.last_visible_x = FRAME_COLS (f);
19591 }
19592 #endif /* not USE_X_TOOLKIT */
19593
19594 /* FIXME: This should be controlled by a user option. See the
19595 comments in redisplay_tool_bar and display_mode_line about
19596 this. */
19597 it.paragraph_embedding = L2R;
19598
19599 if (! mode_line_inverse_video)
19600 /* Force the menu-bar to be displayed in the default face. */
19601 it.base_face_id = it.face_id = DEFAULT_FACE_ID;
19602
19603 /* Clear all rows of the menu bar. */
19604 for (i = 0; i < FRAME_MENU_BAR_LINES (f); ++i)
19605 {
19606 struct glyph_row *row = it.glyph_row + i;
19607 clear_glyph_row (row);
19608 row->enabled_p = 1;
19609 row->full_width_p = 1;
19610 }
19611
19612 /* Display all items of the menu bar. */
19613 items = FRAME_MENU_BAR_ITEMS (it.f);
19614 for (i = 0; i < ASIZE (items); i += 4)
19615 {
19616 Lisp_Object string;
19617
19618 /* Stop at nil string. */
19619 string = AREF (items, i + 1);
19620 if (NILP (string))
19621 break;
19622
19623 /* Remember where item was displayed. */
19624 ASET (items, i + 3, make_number (it.hpos));
19625
19626 /* Display the item, pad with one space. */
19627 if (it.current_x < it.last_visible_x)
19628 display_string (NULL, string, Qnil, 0, 0, &it,
19629 SCHARS (string) + 1, 0, 0, -1);
19630 }
19631
19632 /* Fill out the line with spaces. */
19633 if (it.current_x < it.last_visible_x)
19634 display_string ("", Qnil, Qnil, 0, 0, &it, -1, 0, 0, -1);
19635
19636 /* Compute the total height of the lines. */
19637 compute_line_metrics (&it);
19638 }
19639
19640
19641 \f
19642 /***********************************************************************
19643 Mode Line
19644 ***********************************************************************/
19645
19646 /* Redisplay mode lines in the window tree whose root is WINDOW. If
19647 FORCE is non-zero, redisplay mode lines unconditionally.
19648 Otherwise, redisplay only mode lines that are garbaged. Value is
19649 the number of windows whose mode lines were redisplayed. */
19650
19651 static int
19652 redisplay_mode_lines (Lisp_Object window, int force)
19653 {
19654 int nwindows = 0;
19655
19656 while (!NILP (window))
19657 {
19658 struct window *w = XWINDOW (window);
19659
19660 if (WINDOWP (w->hchild))
19661 nwindows += redisplay_mode_lines (w->hchild, force);
19662 else if (WINDOWP (w->vchild))
19663 nwindows += redisplay_mode_lines (w->vchild, force);
19664 else if (force
19665 || FRAME_GARBAGED_P (XFRAME (w->frame))
19666 || !MATRIX_MODE_LINE_ROW (w->current_matrix)->enabled_p)
19667 {
19668 struct text_pos lpoint;
19669 struct buffer *old = current_buffer;
19670
19671 /* Set the window's buffer for the mode line display. */
19672 SET_TEXT_POS (lpoint, PT, PT_BYTE);
19673 set_buffer_internal_1 (XBUFFER (w->buffer));
19674
19675 /* Point refers normally to the selected window. For any
19676 other window, set up appropriate value. */
19677 if (!EQ (window, selected_window))
19678 {
19679 struct text_pos pt;
19680
19681 SET_TEXT_POS_FROM_MARKER (pt, w->pointm);
19682 if (CHARPOS (pt) < BEGV)
19683 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
19684 else if (CHARPOS (pt) > (ZV - 1))
19685 TEMP_SET_PT_BOTH (ZV, ZV_BYTE);
19686 else
19687 TEMP_SET_PT_BOTH (CHARPOS (pt), BYTEPOS (pt));
19688 }
19689
19690 /* Display mode lines. */
19691 clear_glyph_matrix (w->desired_matrix);
19692 if (display_mode_lines (w))
19693 {
19694 ++nwindows;
19695 w->must_be_updated_p = 1;
19696 }
19697
19698 /* Restore old settings. */
19699 set_buffer_internal_1 (old);
19700 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
19701 }
19702
19703 window = w->next;
19704 }
19705
19706 return nwindows;
19707 }
19708
19709
19710 /* Display the mode and/or header line of window W. Value is the
19711 sum number of mode lines and header lines displayed. */
19712
19713 static int
19714 display_mode_lines (struct window *w)
19715 {
19716 Lisp_Object old_selected_window, old_selected_frame;
19717 int n = 0;
19718
19719 old_selected_frame = selected_frame;
19720 selected_frame = w->frame;
19721 old_selected_window = selected_window;
19722 XSETWINDOW (selected_window, w);
19723
19724 /* These will be set while the mode line specs are processed. */
19725 line_number_displayed = 0;
19726 w->column_number_displayed = Qnil;
19727
19728 if (WINDOW_WANTS_MODELINE_P (w))
19729 {
19730 struct window *sel_w = XWINDOW (old_selected_window);
19731
19732 /* Select mode line face based on the real selected window. */
19733 display_mode_line (w, CURRENT_MODE_LINE_FACE_ID_3 (sel_w, sel_w, w),
19734 BVAR (current_buffer, mode_line_format));
19735 ++n;
19736 }
19737
19738 if (WINDOW_WANTS_HEADER_LINE_P (w))
19739 {
19740 display_mode_line (w, HEADER_LINE_FACE_ID,
19741 BVAR (current_buffer, header_line_format));
19742 ++n;
19743 }
19744
19745 selected_frame = old_selected_frame;
19746 selected_window = old_selected_window;
19747 return n;
19748 }
19749
19750
19751 /* Display mode or header line of window W. FACE_ID specifies which
19752 line to display; it is either MODE_LINE_FACE_ID or
19753 HEADER_LINE_FACE_ID. FORMAT is the mode/header line format to
19754 display. Value is the pixel height of the mode/header line
19755 displayed. */
19756
19757 static int
19758 display_mode_line (struct window *w, enum face_id face_id, Lisp_Object format)
19759 {
19760 struct it it;
19761 struct face *face;
19762 int count = SPECPDL_INDEX ();
19763
19764 init_iterator (&it, w, -1, -1, NULL, face_id);
19765 /* Don't extend on a previously drawn mode-line.
19766 This may happen if called from pos_visible_p. */
19767 it.glyph_row->enabled_p = 0;
19768 prepare_desired_row (it.glyph_row);
19769
19770 it.glyph_row->mode_line_p = 1;
19771
19772 if (! mode_line_inverse_video)
19773 /* Force the mode-line to be displayed in the default face. */
19774 it.base_face_id = it.face_id = DEFAULT_FACE_ID;
19775
19776 /* FIXME: This should be controlled by a user option. But
19777 supporting such an option is not trivial, since the mode line is
19778 made up of many separate strings. */
19779 it.paragraph_embedding = L2R;
19780
19781 record_unwind_protect (unwind_format_mode_line,
19782 format_mode_line_unwind_data (NULL, Qnil, 0));
19783
19784 mode_line_target = MODE_LINE_DISPLAY;
19785
19786 /* Temporarily make frame's keyboard the current kboard so that
19787 kboard-local variables in the mode_line_format will get the right
19788 values. */
19789 push_kboard (FRAME_KBOARD (it.f));
19790 record_unwind_save_match_data ();
19791 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
19792 pop_kboard ();
19793
19794 unbind_to (count, Qnil);
19795
19796 /* Fill up with spaces. */
19797 display_string (" ", Qnil, Qnil, 0, 0, &it, 10000, -1, -1, 0);
19798
19799 compute_line_metrics (&it);
19800 it.glyph_row->full_width_p = 1;
19801 it.glyph_row->continued_p = 0;
19802 it.glyph_row->truncated_on_left_p = 0;
19803 it.glyph_row->truncated_on_right_p = 0;
19804
19805 /* Make a 3D mode-line have a shadow at its right end. */
19806 face = FACE_FROM_ID (it.f, face_id);
19807 extend_face_to_end_of_line (&it);
19808 if (face->box != FACE_NO_BOX)
19809 {
19810 struct glyph *last = (it.glyph_row->glyphs[TEXT_AREA]
19811 + it.glyph_row->used[TEXT_AREA] - 1);
19812 last->right_box_line_p = 1;
19813 }
19814
19815 return it.glyph_row->height;
19816 }
19817
19818 /* Move element ELT in LIST to the front of LIST.
19819 Return the updated list. */
19820
19821 static Lisp_Object
19822 move_elt_to_front (Lisp_Object elt, Lisp_Object list)
19823 {
19824 register Lisp_Object tail, prev;
19825 register Lisp_Object tem;
19826
19827 tail = list;
19828 prev = Qnil;
19829 while (CONSP (tail))
19830 {
19831 tem = XCAR (tail);
19832
19833 if (EQ (elt, tem))
19834 {
19835 /* Splice out the link TAIL. */
19836 if (NILP (prev))
19837 list = XCDR (tail);
19838 else
19839 Fsetcdr (prev, XCDR (tail));
19840
19841 /* Now make it the first. */
19842 Fsetcdr (tail, list);
19843 return tail;
19844 }
19845 else
19846 prev = tail;
19847 tail = XCDR (tail);
19848 QUIT;
19849 }
19850
19851 /* Not found--return unchanged LIST. */
19852 return list;
19853 }
19854
19855 /* Contribute ELT to the mode line for window IT->w. How it
19856 translates into text depends on its data type.
19857
19858 IT describes the display environment in which we display, as usual.
19859
19860 DEPTH is the depth in recursion. It is used to prevent
19861 infinite recursion here.
19862
19863 FIELD_WIDTH is the number of characters the display of ELT should
19864 occupy in the mode line, and PRECISION is the maximum number of
19865 characters to display from ELT's representation. See
19866 display_string for details.
19867
19868 Returns the hpos of the end of the text generated by ELT.
19869
19870 PROPS is a property list to add to any string we encounter.
19871
19872 If RISKY is nonzero, remove (disregard) any properties in any string
19873 we encounter, and ignore :eval and :propertize.
19874
19875 The global variable `mode_line_target' determines whether the
19876 output is passed to `store_mode_line_noprop',
19877 `store_mode_line_string', or `display_string'. */
19878
19879 static int
19880 display_mode_element (struct it *it, int depth, int field_width, int precision,
19881 Lisp_Object elt, Lisp_Object props, int risky)
19882 {
19883 int n = 0, field, prec;
19884 int literal = 0;
19885
19886 tail_recurse:
19887 if (depth > 100)
19888 elt = build_string ("*too-deep*");
19889
19890 depth++;
19891
19892 switch (SWITCH_ENUM_CAST (XTYPE (elt)))
19893 {
19894 case Lisp_String:
19895 {
19896 /* A string: output it and check for %-constructs within it. */
19897 unsigned char c;
19898 EMACS_INT offset = 0;
19899
19900 if (SCHARS (elt) > 0
19901 && (!NILP (props) || risky))
19902 {
19903 Lisp_Object oprops, aelt;
19904 oprops = Ftext_properties_at (make_number (0), elt);
19905
19906 /* If the starting string's properties are not what
19907 we want, translate the string. Also, if the string
19908 is risky, do that anyway. */
19909
19910 if (NILP (Fequal (props, oprops)) || risky)
19911 {
19912 /* If the starting string has properties,
19913 merge the specified ones onto the existing ones. */
19914 if (! NILP (oprops) && !risky)
19915 {
19916 Lisp_Object tem;
19917
19918 oprops = Fcopy_sequence (oprops);
19919 tem = props;
19920 while (CONSP (tem))
19921 {
19922 oprops = Fplist_put (oprops, XCAR (tem),
19923 XCAR (XCDR (tem)));
19924 tem = XCDR (XCDR (tem));
19925 }
19926 props = oprops;
19927 }
19928
19929 aelt = Fassoc (elt, mode_line_proptrans_alist);
19930 if (! NILP (aelt) && !NILP (Fequal (props, XCDR (aelt))))
19931 {
19932 /* AELT is what we want. Move it to the front
19933 without consing. */
19934 elt = XCAR (aelt);
19935 mode_line_proptrans_alist
19936 = move_elt_to_front (aelt, mode_line_proptrans_alist);
19937 }
19938 else
19939 {
19940 Lisp_Object tem;
19941
19942 /* If AELT has the wrong props, it is useless.
19943 so get rid of it. */
19944 if (! NILP (aelt))
19945 mode_line_proptrans_alist
19946 = Fdelq (aelt, mode_line_proptrans_alist);
19947
19948 elt = Fcopy_sequence (elt);
19949 Fset_text_properties (make_number (0), Flength (elt),
19950 props, elt);
19951 /* Add this item to mode_line_proptrans_alist. */
19952 mode_line_proptrans_alist
19953 = Fcons (Fcons (elt, props),
19954 mode_line_proptrans_alist);
19955 /* Truncate mode_line_proptrans_alist
19956 to at most 50 elements. */
19957 tem = Fnthcdr (make_number (50),
19958 mode_line_proptrans_alist);
19959 if (! NILP (tem))
19960 XSETCDR (tem, Qnil);
19961 }
19962 }
19963 }
19964
19965 offset = 0;
19966
19967 if (literal)
19968 {
19969 prec = precision - n;
19970 switch (mode_line_target)
19971 {
19972 case MODE_LINE_NOPROP:
19973 case MODE_LINE_TITLE:
19974 n += store_mode_line_noprop (SSDATA (elt), -1, prec);
19975 break;
19976 case MODE_LINE_STRING:
19977 n += store_mode_line_string (NULL, elt, 1, 0, prec, Qnil);
19978 break;
19979 case MODE_LINE_DISPLAY:
19980 n += display_string (NULL, elt, Qnil, 0, 0, it,
19981 0, prec, 0, STRING_MULTIBYTE (elt));
19982 break;
19983 }
19984
19985 break;
19986 }
19987
19988 /* Handle the non-literal case. */
19989
19990 while ((precision <= 0 || n < precision)
19991 && SREF (elt, offset) != 0
19992 && (mode_line_target != MODE_LINE_DISPLAY
19993 || it->current_x < it->last_visible_x))
19994 {
19995 EMACS_INT last_offset = offset;
19996
19997 /* Advance to end of string or next format specifier. */
19998 while ((c = SREF (elt, offset++)) != '\0' && c != '%')
19999 ;
20000
20001 if (offset - 1 != last_offset)
20002 {
20003 EMACS_INT nchars, nbytes;
20004
20005 /* Output to end of string or up to '%'. Field width
20006 is length of string. Don't output more than
20007 PRECISION allows us. */
20008 offset--;
20009
20010 prec = c_string_width (SDATA (elt) + last_offset,
20011 offset - last_offset, precision - n,
20012 &nchars, &nbytes);
20013
20014 switch (mode_line_target)
20015 {
20016 case MODE_LINE_NOPROP:
20017 case MODE_LINE_TITLE:
20018 n += store_mode_line_noprop (SSDATA (elt) + last_offset, 0, prec);
20019 break;
20020 case MODE_LINE_STRING:
20021 {
20022 EMACS_INT bytepos = last_offset;
20023 EMACS_INT charpos = string_byte_to_char (elt, bytepos);
20024 EMACS_INT endpos = (precision <= 0
20025 ? string_byte_to_char (elt, offset)
20026 : charpos + nchars);
20027
20028 n += store_mode_line_string (NULL,
20029 Fsubstring (elt, make_number (charpos),
20030 make_number (endpos)),
20031 0, 0, 0, Qnil);
20032 }
20033 break;
20034 case MODE_LINE_DISPLAY:
20035 {
20036 EMACS_INT bytepos = last_offset;
20037 EMACS_INT charpos = string_byte_to_char (elt, bytepos);
20038
20039 if (precision <= 0)
20040 nchars = string_byte_to_char (elt, offset) - charpos;
20041 n += display_string (NULL, elt, Qnil, 0, charpos,
20042 it, 0, nchars, 0,
20043 STRING_MULTIBYTE (elt));
20044 }
20045 break;
20046 }
20047 }
20048 else /* c == '%' */
20049 {
20050 EMACS_INT percent_position = offset;
20051
20052 /* Get the specified minimum width. Zero means
20053 don't pad. */
20054 field = 0;
20055 while ((c = SREF (elt, offset++)) >= '0' && c <= '9')
20056 field = field * 10 + c - '0';
20057
20058 /* Don't pad beyond the total padding allowed. */
20059 if (field_width - n > 0 && field > field_width - n)
20060 field = field_width - n;
20061
20062 /* Note that either PRECISION <= 0 or N < PRECISION. */
20063 prec = precision - n;
20064
20065 if (c == 'M')
20066 n += display_mode_element (it, depth, field, prec,
20067 Vglobal_mode_string, props,
20068 risky);
20069 else if (c != 0)
20070 {
20071 int multibyte;
20072 EMACS_INT bytepos, charpos;
20073 const char *spec;
20074 Lisp_Object string;
20075
20076 bytepos = percent_position;
20077 charpos = (STRING_MULTIBYTE (elt)
20078 ? string_byte_to_char (elt, bytepos)
20079 : bytepos);
20080 spec = decode_mode_spec (it->w, c, field, &string);
20081 multibyte = STRINGP (string) && STRING_MULTIBYTE (string);
20082
20083 switch (mode_line_target)
20084 {
20085 case MODE_LINE_NOPROP:
20086 case MODE_LINE_TITLE:
20087 n += store_mode_line_noprop (spec, field, prec);
20088 break;
20089 case MODE_LINE_STRING:
20090 {
20091 Lisp_Object tem = build_string (spec);
20092 props = Ftext_properties_at (make_number (charpos), elt);
20093 /* Should only keep face property in props */
20094 n += store_mode_line_string (NULL, tem, 0, field, prec, props);
20095 }
20096 break;
20097 case MODE_LINE_DISPLAY:
20098 {
20099 int nglyphs_before, nwritten;
20100
20101 nglyphs_before = it->glyph_row->used[TEXT_AREA];
20102 nwritten = display_string (spec, string, elt,
20103 charpos, 0, it,
20104 field, prec, 0,
20105 multibyte);
20106
20107 /* Assign to the glyphs written above the
20108 string where the `%x' came from, position
20109 of the `%'. */
20110 if (nwritten > 0)
20111 {
20112 struct glyph *glyph
20113 = (it->glyph_row->glyphs[TEXT_AREA]
20114 + nglyphs_before);
20115 int i;
20116
20117 for (i = 0; i < nwritten; ++i)
20118 {
20119 glyph[i].object = elt;
20120 glyph[i].charpos = charpos;
20121 }
20122
20123 n += nwritten;
20124 }
20125 }
20126 break;
20127 }
20128 }
20129 else /* c == 0 */
20130 break;
20131 }
20132 }
20133 }
20134 break;
20135
20136 case Lisp_Symbol:
20137 /* A symbol: process the value of the symbol recursively
20138 as if it appeared here directly. Avoid error if symbol void.
20139 Special case: if value of symbol is a string, output the string
20140 literally. */
20141 {
20142 register Lisp_Object tem;
20143
20144 /* If the variable is not marked as risky to set
20145 then its contents are risky to use. */
20146 if (NILP (Fget (elt, Qrisky_local_variable)))
20147 risky = 1;
20148
20149 tem = Fboundp (elt);
20150 if (!NILP (tem))
20151 {
20152 tem = Fsymbol_value (elt);
20153 /* If value is a string, output that string literally:
20154 don't check for % within it. */
20155 if (STRINGP (tem))
20156 literal = 1;
20157
20158 if (!EQ (tem, elt))
20159 {
20160 /* Give up right away for nil or t. */
20161 elt = tem;
20162 goto tail_recurse;
20163 }
20164 }
20165 }
20166 break;
20167
20168 case Lisp_Cons:
20169 {
20170 register Lisp_Object car, tem;
20171
20172 /* A cons cell: five distinct cases.
20173 If first element is :eval or :propertize, do something special.
20174 If first element is a string or a cons, process all the elements
20175 and effectively concatenate them.
20176 If first element is a negative number, truncate displaying cdr to
20177 at most that many characters. If positive, pad (with spaces)
20178 to at least that many characters.
20179 If first element is a symbol, process the cadr or caddr recursively
20180 according to whether the symbol's value is non-nil or nil. */
20181 car = XCAR (elt);
20182 if (EQ (car, QCeval))
20183 {
20184 /* An element of the form (:eval FORM) means evaluate FORM
20185 and use the result as mode line elements. */
20186
20187 if (risky)
20188 break;
20189
20190 if (CONSP (XCDR (elt)))
20191 {
20192 Lisp_Object spec;
20193 spec = safe_eval (XCAR (XCDR (elt)));
20194 n += display_mode_element (it, depth, field_width - n,
20195 precision - n, spec, props,
20196 risky);
20197 }
20198 }
20199 else if (EQ (car, QCpropertize))
20200 {
20201 /* An element of the form (:propertize ELT PROPS...)
20202 means display ELT but applying properties PROPS. */
20203
20204 if (risky)
20205 break;
20206
20207 if (CONSP (XCDR (elt)))
20208 n += display_mode_element (it, depth, field_width - n,
20209 precision - n, XCAR (XCDR (elt)),
20210 XCDR (XCDR (elt)), risky);
20211 }
20212 else if (SYMBOLP (car))
20213 {
20214 tem = Fboundp (car);
20215 elt = XCDR (elt);
20216 if (!CONSP (elt))
20217 goto invalid;
20218 /* elt is now the cdr, and we know it is a cons cell.
20219 Use its car if CAR has a non-nil value. */
20220 if (!NILP (tem))
20221 {
20222 tem = Fsymbol_value (car);
20223 if (!NILP (tem))
20224 {
20225 elt = XCAR (elt);
20226 goto tail_recurse;
20227 }
20228 }
20229 /* Symbol's value is nil (or symbol is unbound)
20230 Get the cddr of the original list
20231 and if possible find the caddr and use that. */
20232 elt = XCDR (elt);
20233 if (NILP (elt))
20234 break;
20235 else if (!CONSP (elt))
20236 goto invalid;
20237 elt = XCAR (elt);
20238 goto tail_recurse;
20239 }
20240 else if (INTEGERP (car))
20241 {
20242 register int lim = XINT (car);
20243 elt = XCDR (elt);
20244 if (lim < 0)
20245 {
20246 /* Negative int means reduce maximum width. */
20247 if (precision <= 0)
20248 precision = -lim;
20249 else
20250 precision = min (precision, -lim);
20251 }
20252 else if (lim > 0)
20253 {
20254 /* Padding specified. Don't let it be more than
20255 current maximum. */
20256 if (precision > 0)
20257 lim = min (precision, lim);
20258
20259 /* If that's more padding than already wanted, queue it.
20260 But don't reduce padding already specified even if
20261 that is beyond the current truncation point. */
20262 field_width = max (lim, field_width);
20263 }
20264 goto tail_recurse;
20265 }
20266 else if (STRINGP (car) || CONSP (car))
20267 {
20268 Lisp_Object halftail = elt;
20269 int len = 0;
20270
20271 while (CONSP (elt)
20272 && (precision <= 0 || n < precision))
20273 {
20274 n += display_mode_element (it, depth,
20275 /* Do padding only after the last
20276 element in the list. */
20277 (! CONSP (XCDR (elt))
20278 ? field_width - n
20279 : 0),
20280 precision - n, XCAR (elt),
20281 props, risky);
20282 elt = XCDR (elt);
20283 len++;
20284 if ((len & 1) == 0)
20285 halftail = XCDR (halftail);
20286 /* Check for cycle. */
20287 if (EQ (halftail, elt))
20288 break;
20289 }
20290 }
20291 }
20292 break;
20293
20294 default:
20295 invalid:
20296 elt = build_string ("*invalid*");
20297 goto tail_recurse;
20298 }
20299
20300 /* Pad to FIELD_WIDTH. */
20301 if (field_width > 0 && n < field_width)
20302 {
20303 switch (mode_line_target)
20304 {
20305 case MODE_LINE_NOPROP:
20306 case MODE_LINE_TITLE:
20307 n += store_mode_line_noprop ("", field_width - n, 0);
20308 break;
20309 case MODE_LINE_STRING:
20310 n += store_mode_line_string ("", Qnil, 0, field_width - n, 0, Qnil);
20311 break;
20312 case MODE_LINE_DISPLAY:
20313 n += display_string ("", Qnil, Qnil, 0, 0, it, field_width - n,
20314 0, 0, 0);
20315 break;
20316 }
20317 }
20318
20319 return n;
20320 }
20321
20322 /* Store a mode-line string element in mode_line_string_list.
20323
20324 If STRING is non-null, display that C string. Otherwise, the Lisp
20325 string LISP_STRING is displayed.
20326
20327 FIELD_WIDTH is the minimum number of output glyphs to produce.
20328 If STRING has fewer characters than FIELD_WIDTH, pad to the right
20329 with spaces. FIELD_WIDTH <= 0 means don't pad.
20330
20331 PRECISION is the maximum number of characters to output from
20332 STRING. PRECISION <= 0 means don't truncate the string.
20333
20334 If COPY_STRING is non-zero, make a copy of LISP_STRING before adding
20335 properties to the string.
20336
20337 PROPS are the properties to add to the string.
20338 The mode_line_string_face face property is always added to the string.
20339 */
20340
20341 static int
20342 store_mode_line_string (const char *string, Lisp_Object lisp_string, int copy_string,
20343 int field_width, int precision, Lisp_Object props)
20344 {
20345 EMACS_INT len;
20346 int n = 0;
20347
20348 if (string != NULL)
20349 {
20350 len = strlen (string);
20351 if (precision > 0 && len > precision)
20352 len = precision;
20353 lisp_string = make_string (string, len);
20354 if (NILP (props))
20355 props = mode_line_string_face_prop;
20356 else if (!NILP (mode_line_string_face))
20357 {
20358 Lisp_Object face = Fplist_get (props, Qface);
20359 props = Fcopy_sequence (props);
20360 if (NILP (face))
20361 face = mode_line_string_face;
20362 else
20363 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
20364 props = Fplist_put (props, Qface, face);
20365 }
20366 Fadd_text_properties (make_number (0), make_number (len),
20367 props, lisp_string);
20368 }
20369 else
20370 {
20371 len = XFASTINT (Flength (lisp_string));
20372 if (precision > 0 && len > precision)
20373 {
20374 len = precision;
20375 lisp_string = Fsubstring (lisp_string, make_number (0), make_number (len));
20376 precision = -1;
20377 }
20378 if (!NILP (mode_line_string_face))
20379 {
20380 Lisp_Object face;
20381 if (NILP (props))
20382 props = Ftext_properties_at (make_number (0), lisp_string);
20383 face = Fplist_get (props, Qface);
20384 if (NILP (face))
20385 face = mode_line_string_face;
20386 else
20387 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
20388 props = Fcons (Qface, Fcons (face, Qnil));
20389 if (copy_string)
20390 lisp_string = Fcopy_sequence (lisp_string);
20391 }
20392 if (!NILP (props))
20393 Fadd_text_properties (make_number (0), make_number (len),
20394 props, lisp_string);
20395 }
20396
20397 if (len > 0)
20398 {
20399 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
20400 n += len;
20401 }
20402
20403 if (field_width > len)
20404 {
20405 field_width -= len;
20406 lisp_string = Fmake_string (make_number (field_width), make_number (' '));
20407 if (!NILP (props))
20408 Fadd_text_properties (make_number (0), make_number (field_width),
20409 props, lisp_string);
20410 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
20411 n += field_width;
20412 }
20413
20414 return n;
20415 }
20416
20417
20418 DEFUN ("format-mode-line", Fformat_mode_line, Sformat_mode_line,
20419 1, 4, 0,
20420 doc: /* Format a string out of a mode line format specification.
20421 First arg FORMAT specifies the mode line format (see `mode-line-format'
20422 for details) to use.
20423
20424 By default, the format is evaluated for the currently selected window.
20425
20426 Optional second arg FACE specifies the face property to put on all
20427 characters for which no face is specified. The value nil means the
20428 default face. The value t means whatever face the window's mode line
20429 currently uses (either `mode-line' or `mode-line-inactive',
20430 depending on whether the window is the selected window or not).
20431 An integer value means the value string has no text
20432 properties.
20433
20434 Optional third and fourth args WINDOW and BUFFER specify the window
20435 and buffer to use as the context for the formatting (defaults
20436 are the selected window and the WINDOW's buffer). */)
20437 (Lisp_Object format, Lisp_Object face,
20438 Lisp_Object window, Lisp_Object buffer)
20439 {
20440 struct it it;
20441 int len;
20442 struct window *w;
20443 struct buffer *old_buffer = NULL;
20444 int face_id;
20445 int no_props = INTEGERP (face);
20446 int count = SPECPDL_INDEX ();
20447 Lisp_Object str;
20448 int string_start = 0;
20449
20450 if (NILP (window))
20451 window = selected_window;
20452 CHECK_WINDOW (window);
20453 w = XWINDOW (window);
20454
20455 if (NILP (buffer))
20456 buffer = w->buffer;
20457 CHECK_BUFFER (buffer);
20458
20459 /* Make formatting the modeline a non-op when noninteractive, otherwise
20460 there will be problems later caused by a partially initialized frame. */
20461 if (NILP (format) || noninteractive)
20462 return empty_unibyte_string;
20463
20464 if (no_props)
20465 face = Qnil;
20466
20467 face_id = (NILP (face) || EQ (face, Qdefault)) ? DEFAULT_FACE_ID
20468 : EQ (face, Qt) ? (EQ (window, selected_window)
20469 ? MODE_LINE_FACE_ID : MODE_LINE_INACTIVE_FACE_ID)
20470 : EQ (face, Qmode_line) ? MODE_LINE_FACE_ID
20471 : EQ (face, Qmode_line_inactive) ? MODE_LINE_INACTIVE_FACE_ID
20472 : EQ (face, Qheader_line) ? HEADER_LINE_FACE_ID
20473 : EQ (face, Qtool_bar) ? TOOL_BAR_FACE_ID
20474 : DEFAULT_FACE_ID;
20475
20476 if (XBUFFER (buffer) != current_buffer)
20477 old_buffer = current_buffer;
20478
20479 /* Save things including mode_line_proptrans_alist,
20480 and set that to nil so that we don't alter the outer value. */
20481 record_unwind_protect (unwind_format_mode_line,
20482 format_mode_line_unwind_data
20483 (old_buffer, selected_window, 1));
20484 mode_line_proptrans_alist = Qnil;
20485
20486 Fselect_window (window, Qt);
20487 if (old_buffer)
20488 set_buffer_internal_1 (XBUFFER (buffer));
20489
20490 init_iterator (&it, w, -1, -1, NULL, face_id);
20491
20492 if (no_props)
20493 {
20494 mode_line_target = MODE_LINE_NOPROP;
20495 mode_line_string_face_prop = Qnil;
20496 mode_line_string_list = Qnil;
20497 string_start = MODE_LINE_NOPROP_LEN (0);
20498 }
20499 else
20500 {
20501 mode_line_target = MODE_LINE_STRING;
20502 mode_line_string_list = Qnil;
20503 mode_line_string_face = face;
20504 mode_line_string_face_prop
20505 = (NILP (face) ? Qnil : Fcons (Qface, Fcons (face, Qnil)));
20506 }
20507
20508 push_kboard (FRAME_KBOARD (it.f));
20509 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
20510 pop_kboard ();
20511
20512 if (no_props)
20513 {
20514 len = MODE_LINE_NOPROP_LEN (string_start);
20515 str = make_string (mode_line_noprop_buf + string_start, len);
20516 }
20517 else
20518 {
20519 mode_line_string_list = Fnreverse (mode_line_string_list);
20520 str = Fmapconcat (intern ("identity"), mode_line_string_list,
20521 empty_unibyte_string);
20522 }
20523
20524 unbind_to (count, Qnil);
20525 return str;
20526 }
20527
20528 /* Write a null-terminated, right justified decimal representation of
20529 the positive integer D to BUF using a minimal field width WIDTH. */
20530
20531 static void
20532 pint2str (register char *buf, register int width, register EMACS_INT d)
20533 {
20534 register char *p = buf;
20535
20536 if (d <= 0)
20537 *p++ = '0';
20538 else
20539 {
20540 while (d > 0)
20541 {
20542 *p++ = d % 10 + '0';
20543 d /= 10;
20544 }
20545 }
20546
20547 for (width -= (int) (p - buf); width > 0; --width)
20548 *p++ = ' ';
20549 *p-- = '\0';
20550 while (p > buf)
20551 {
20552 d = *buf;
20553 *buf++ = *p;
20554 *p-- = d;
20555 }
20556 }
20557
20558 /* Write a null-terminated, right justified decimal and "human
20559 readable" representation of the nonnegative integer D to BUF using
20560 a minimal field width WIDTH. D should be smaller than 999.5e24. */
20561
20562 static const char power_letter[] =
20563 {
20564 0, /* no letter */
20565 'k', /* kilo */
20566 'M', /* mega */
20567 'G', /* giga */
20568 'T', /* tera */
20569 'P', /* peta */
20570 'E', /* exa */
20571 'Z', /* zetta */
20572 'Y' /* yotta */
20573 };
20574
20575 static void
20576 pint2hrstr (char *buf, int width, EMACS_INT d)
20577 {
20578 /* We aim to represent the nonnegative integer D as
20579 QUOTIENT.TENTHS * 10 ^ (3 * EXPONENT). */
20580 EMACS_INT quotient = d;
20581 int remainder = 0;
20582 /* -1 means: do not use TENTHS. */
20583 int tenths = -1;
20584 int exponent = 0;
20585
20586 /* Length of QUOTIENT.TENTHS as a string. */
20587 int length;
20588
20589 char * psuffix;
20590 char * p;
20591
20592 if (1000 <= quotient)
20593 {
20594 /* Scale to the appropriate EXPONENT. */
20595 do
20596 {
20597 remainder = quotient % 1000;
20598 quotient /= 1000;
20599 exponent++;
20600 }
20601 while (1000 <= quotient);
20602
20603 /* Round to nearest and decide whether to use TENTHS or not. */
20604 if (quotient <= 9)
20605 {
20606 tenths = remainder / 100;
20607 if (50 <= remainder % 100)
20608 {
20609 if (tenths < 9)
20610 tenths++;
20611 else
20612 {
20613 quotient++;
20614 if (quotient == 10)
20615 tenths = -1;
20616 else
20617 tenths = 0;
20618 }
20619 }
20620 }
20621 else
20622 if (500 <= remainder)
20623 {
20624 if (quotient < 999)
20625 quotient++;
20626 else
20627 {
20628 quotient = 1;
20629 exponent++;
20630 tenths = 0;
20631 }
20632 }
20633 }
20634
20635 /* Calculate the LENGTH of QUOTIENT.TENTHS as a string. */
20636 if (tenths == -1 && quotient <= 99)
20637 if (quotient <= 9)
20638 length = 1;
20639 else
20640 length = 2;
20641 else
20642 length = 3;
20643 p = psuffix = buf + max (width, length);
20644
20645 /* Print EXPONENT. */
20646 *psuffix++ = power_letter[exponent];
20647 *psuffix = '\0';
20648
20649 /* Print TENTHS. */
20650 if (tenths >= 0)
20651 {
20652 *--p = '0' + tenths;
20653 *--p = '.';
20654 }
20655
20656 /* Print QUOTIENT. */
20657 do
20658 {
20659 int digit = quotient % 10;
20660 *--p = '0' + digit;
20661 }
20662 while ((quotient /= 10) != 0);
20663
20664 /* Print leading spaces. */
20665 while (buf < p)
20666 *--p = ' ';
20667 }
20668
20669 /* Set a mnemonic character for coding_system (Lisp symbol) in BUF.
20670 If EOL_FLAG is 1, set also a mnemonic character for end-of-line
20671 type of CODING_SYSTEM. Return updated pointer into BUF. */
20672
20673 static unsigned char invalid_eol_type[] = "(*invalid*)";
20674
20675 static char *
20676 decode_mode_spec_coding (Lisp_Object coding_system, register char *buf, int eol_flag)
20677 {
20678 Lisp_Object val;
20679 int multibyte = !NILP (BVAR (current_buffer, enable_multibyte_characters));
20680 const unsigned char *eol_str;
20681 int eol_str_len;
20682 /* The EOL conversion we are using. */
20683 Lisp_Object eoltype;
20684
20685 val = CODING_SYSTEM_SPEC (coding_system);
20686 eoltype = Qnil;
20687
20688 if (!VECTORP (val)) /* Not yet decided. */
20689 {
20690 if (multibyte)
20691 *buf++ = '-';
20692 if (eol_flag)
20693 eoltype = eol_mnemonic_undecided;
20694 /* Don't mention EOL conversion if it isn't decided. */
20695 }
20696 else
20697 {
20698 Lisp_Object attrs;
20699 Lisp_Object eolvalue;
20700
20701 attrs = AREF (val, 0);
20702 eolvalue = AREF (val, 2);
20703
20704 if (multibyte)
20705 *buf++ = XFASTINT (CODING_ATTR_MNEMONIC (attrs));
20706
20707 if (eol_flag)
20708 {
20709 /* The EOL conversion that is normal on this system. */
20710
20711 if (NILP (eolvalue)) /* Not yet decided. */
20712 eoltype = eol_mnemonic_undecided;
20713 else if (VECTORP (eolvalue)) /* Not yet decided. */
20714 eoltype = eol_mnemonic_undecided;
20715 else /* eolvalue is Qunix, Qdos, or Qmac. */
20716 eoltype = (EQ (eolvalue, Qunix)
20717 ? eol_mnemonic_unix
20718 : (EQ (eolvalue, Qdos) == 1
20719 ? eol_mnemonic_dos : eol_mnemonic_mac));
20720 }
20721 }
20722
20723 if (eol_flag)
20724 {
20725 /* Mention the EOL conversion if it is not the usual one. */
20726 if (STRINGP (eoltype))
20727 {
20728 eol_str = SDATA (eoltype);
20729 eol_str_len = SBYTES (eoltype);
20730 }
20731 else if (CHARACTERP (eoltype))
20732 {
20733 unsigned char *tmp = (unsigned char *) alloca (MAX_MULTIBYTE_LENGTH);
20734 int c = XFASTINT (eoltype);
20735 eol_str_len = CHAR_STRING (c, tmp);
20736 eol_str = tmp;
20737 }
20738 else
20739 {
20740 eol_str = invalid_eol_type;
20741 eol_str_len = sizeof (invalid_eol_type) - 1;
20742 }
20743 memcpy (buf, eol_str, eol_str_len);
20744 buf += eol_str_len;
20745 }
20746
20747 return buf;
20748 }
20749
20750 /* Return a string for the output of a mode line %-spec for window W,
20751 generated by character C. FIELD_WIDTH > 0 means pad the string
20752 returned with spaces to that value. Return a Lisp string in
20753 *STRING if the resulting string is taken from that Lisp string.
20754
20755 Note we operate on the current buffer for most purposes,
20756 the exception being w->base_line_pos. */
20757
20758 static char lots_of_dashes[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
20759
20760 static const char *
20761 decode_mode_spec (struct window *w, register int c, int field_width,
20762 Lisp_Object *string)
20763 {
20764 Lisp_Object obj;
20765 struct frame *f = XFRAME (WINDOW_FRAME (w));
20766 char *decode_mode_spec_buf = f->decode_mode_spec_buffer;
20767 struct buffer *b = current_buffer;
20768
20769 obj = Qnil;
20770 *string = Qnil;
20771
20772 switch (c)
20773 {
20774 case '*':
20775 if (!NILP (BVAR (b, read_only)))
20776 return "%";
20777 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
20778 return "*";
20779 return "-";
20780
20781 case '+':
20782 /* This differs from %* only for a modified read-only buffer. */
20783 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
20784 return "*";
20785 if (!NILP (BVAR (b, read_only)))
20786 return "%";
20787 return "-";
20788
20789 case '&':
20790 /* This differs from %* in ignoring read-only-ness. */
20791 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
20792 return "*";
20793 return "-";
20794
20795 case '%':
20796 return "%";
20797
20798 case '[':
20799 {
20800 int i;
20801 char *p;
20802
20803 if (command_loop_level > 5)
20804 return "[[[... ";
20805 p = decode_mode_spec_buf;
20806 for (i = 0; i < command_loop_level; i++)
20807 *p++ = '[';
20808 *p = 0;
20809 return decode_mode_spec_buf;
20810 }
20811
20812 case ']':
20813 {
20814 int i;
20815 char *p;
20816
20817 if (command_loop_level > 5)
20818 return " ...]]]";
20819 p = decode_mode_spec_buf;
20820 for (i = 0; i < command_loop_level; i++)
20821 *p++ = ']';
20822 *p = 0;
20823 return decode_mode_spec_buf;
20824 }
20825
20826 case '-':
20827 {
20828 register int i;
20829
20830 /* Let lots_of_dashes be a string of infinite length. */
20831 if (mode_line_target == MODE_LINE_NOPROP ||
20832 mode_line_target == MODE_LINE_STRING)
20833 return "--";
20834 if (field_width <= 0
20835 || field_width > sizeof (lots_of_dashes))
20836 {
20837 for (i = 0; i < FRAME_MESSAGE_BUF_SIZE (f) - 1; ++i)
20838 decode_mode_spec_buf[i] = '-';
20839 decode_mode_spec_buf[i] = '\0';
20840 return decode_mode_spec_buf;
20841 }
20842 else
20843 return lots_of_dashes;
20844 }
20845
20846 case 'b':
20847 obj = BVAR (b, name);
20848 break;
20849
20850 case 'c':
20851 /* %c and %l are ignored in `frame-title-format'.
20852 (In redisplay_internal, the frame title is drawn _before_ the
20853 windows are updated, so the stuff which depends on actual
20854 window contents (such as %l) may fail to render properly, or
20855 even crash emacs.) */
20856 if (mode_line_target == MODE_LINE_TITLE)
20857 return "";
20858 else
20859 {
20860 EMACS_INT col = current_column ();
20861 w->column_number_displayed = make_number (col);
20862 pint2str (decode_mode_spec_buf, field_width, col);
20863 return decode_mode_spec_buf;
20864 }
20865
20866 case 'e':
20867 #ifndef SYSTEM_MALLOC
20868 {
20869 if (NILP (Vmemory_full))
20870 return "";
20871 else
20872 return "!MEM FULL! ";
20873 }
20874 #else
20875 return "";
20876 #endif
20877
20878 case 'F':
20879 /* %F displays the frame name. */
20880 if (!NILP (f->title))
20881 return SSDATA (f->title);
20882 if (f->explicit_name || ! FRAME_WINDOW_P (f))
20883 return SSDATA (f->name);
20884 return "Emacs";
20885
20886 case 'f':
20887 obj = BVAR (b, filename);
20888 break;
20889
20890 case 'i':
20891 {
20892 EMACS_INT size = ZV - BEGV;
20893 pint2str (decode_mode_spec_buf, field_width, size);
20894 return decode_mode_spec_buf;
20895 }
20896
20897 case 'I':
20898 {
20899 EMACS_INT size = ZV - BEGV;
20900 pint2hrstr (decode_mode_spec_buf, field_width, size);
20901 return decode_mode_spec_buf;
20902 }
20903
20904 case 'l':
20905 {
20906 EMACS_INT startpos, startpos_byte, line, linepos, linepos_byte;
20907 EMACS_INT topline, nlines, height;
20908 EMACS_INT junk;
20909
20910 /* %c and %l are ignored in `frame-title-format'. */
20911 if (mode_line_target == MODE_LINE_TITLE)
20912 return "";
20913
20914 startpos = XMARKER (w->start)->charpos;
20915 startpos_byte = marker_byte_position (w->start);
20916 height = WINDOW_TOTAL_LINES (w);
20917
20918 /* If we decided that this buffer isn't suitable for line numbers,
20919 don't forget that too fast. */
20920 if (EQ (w->base_line_pos, w->buffer))
20921 goto no_value;
20922 /* But do forget it, if the window shows a different buffer now. */
20923 else if (BUFFERP (w->base_line_pos))
20924 w->base_line_pos = Qnil;
20925
20926 /* If the buffer is very big, don't waste time. */
20927 if (INTEGERP (Vline_number_display_limit)
20928 && BUF_ZV (b) - BUF_BEGV (b) > XINT (Vline_number_display_limit))
20929 {
20930 w->base_line_pos = Qnil;
20931 w->base_line_number = Qnil;
20932 goto no_value;
20933 }
20934
20935 if (INTEGERP (w->base_line_number)
20936 && INTEGERP (w->base_line_pos)
20937 && XFASTINT (w->base_line_pos) <= startpos)
20938 {
20939 line = XFASTINT (w->base_line_number);
20940 linepos = XFASTINT (w->base_line_pos);
20941 linepos_byte = buf_charpos_to_bytepos (b, linepos);
20942 }
20943 else
20944 {
20945 line = 1;
20946 linepos = BUF_BEGV (b);
20947 linepos_byte = BUF_BEGV_BYTE (b);
20948 }
20949
20950 /* Count lines from base line to window start position. */
20951 nlines = display_count_lines (linepos_byte,
20952 startpos_byte,
20953 startpos, &junk);
20954
20955 topline = nlines + line;
20956
20957 /* Determine a new base line, if the old one is too close
20958 or too far away, or if we did not have one.
20959 "Too close" means it's plausible a scroll-down would
20960 go back past it. */
20961 if (startpos == BUF_BEGV (b))
20962 {
20963 w->base_line_number = make_number (topline);
20964 w->base_line_pos = make_number (BUF_BEGV (b));
20965 }
20966 else if (nlines < height + 25 || nlines > height * 3 + 50
20967 || linepos == BUF_BEGV (b))
20968 {
20969 EMACS_INT limit = BUF_BEGV (b);
20970 EMACS_INT limit_byte = BUF_BEGV_BYTE (b);
20971 EMACS_INT position;
20972 EMACS_INT distance =
20973 (height * 2 + 30) * line_number_display_limit_width;
20974
20975 if (startpos - distance > limit)
20976 {
20977 limit = startpos - distance;
20978 limit_byte = CHAR_TO_BYTE (limit);
20979 }
20980
20981 nlines = display_count_lines (startpos_byte,
20982 limit_byte,
20983 - (height * 2 + 30),
20984 &position);
20985 /* If we couldn't find the lines we wanted within
20986 line_number_display_limit_width chars per line,
20987 give up on line numbers for this window. */
20988 if (position == limit_byte && limit == startpos - distance)
20989 {
20990 w->base_line_pos = w->buffer;
20991 w->base_line_number = Qnil;
20992 goto no_value;
20993 }
20994
20995 w->base_line_number = make_number (topline - nlines);
20996 w->base_line_pos = make_number (BYTE_TO_CHAR (position));
20997 }
20998
20999 /* Now count lines from the start pos to point. */
21000 nlines = display_count_lines (startpos_byte,
21001 PT_BYTE, PT, &junk);
21002
21003 /* Record that we did display the line number. */
21004 line_number_displayed = 1;
21005
21006 /* Make the string to show. */
21007 pint2str (decode_mode_spec_buf, field_width, topline + nlines);
21008 return decode_mode_spec_buf;
21009 no_value:
21010 {
21011 char* p = decode_mode_spec_buf;
21012 int pad = field_width - 2;
21013 while (pad-- > 0)
21014 *p++ = ' ';
21015 *p++ = '?';
21016 *p++ = '?';
21017 *p = '\0';
21018 return decode_mode_spec_buf;
21019 }
21020 }
21021 break;
21022
21023 case 'm':
21024 obj = BVAR (b, mode_name);
21025 break;
21026
21027 case 'n':
21028 if (BUF_BEGV (b) > BUF_BEG (b) || BUF_ZV (b) < BUF_Z (b))
21029 return " Narrow";
21030 break;
21031
21032 case 'p':
21033 {
21034 EMACS_INT pos = marker_position (w->start);
21035 EMACS_INT total = BUF_ZV (b) - BUF_BEGV (b);
21036
21037 if (XFASTINT (w->window_end_pos) <= BUF_Z (b) - BUF_ZV (b))
21038 {
21039 if (pos <= BUF_BEGV (b))
21040 return "All";
21041 else
21042 return "Bottom";
21043 }
21044 else if (pos <= BUF_BEGV (b))
21045 return "Top";
21046 else
21047 {
21048 if (total > 1000000)
21049 /* Do it differently for a large value, to avoid overflow. */
21050 total = ((pos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
21051 else
21052 total = ((pos - BUF_BEGV (b)) * 100 + total - 1) / total;
21053 /* We can't normally display a 3-digit number,
21054 so get us a 2-digit number that is close. */
21055 if (total == 100)
21056 total = 99;
21057 sprintf (decode_mode_spec_buf, "%2"pI"d%%", total);
21058 return decode_mode_spec_buf;
21059 }
21060 }
21061
21062 /* Display percentage of size above the bottom of the screen. */
21063 case 'P':
21064 {
21065 EMACS_INT toppos = marker_position (w->start);
21066 EMACS_INT botpos = BUF_Z (b) - XFASTINT (w->window_end_pos);
21067 EMACS_INT total = BUF_ZV (b) - BUF_BEGV (b);
21068
21069 if (botpos >= BUF_ZV (b))
21070 {
21071 if (toppos <= BUF_BEGV (b))
21072 return "All";
21073 else
21074 return "Bottom";
21075 }
21076 else
21077 {
21078 if (total > 1000000)
21079 /* Do it differently for a large value, to avoid overflow. */
21080 total = ((botpos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
21081 else
21082 total = ((botpos - BUF_BEGV (b)) * 100 + total - 1) / total;
21083 /* We can't normally display a 3-digit number,
21084 so get us a 2-digit number that is close. */
21085 if (total == 100)
21086 total = 99;
21087 if (toppos <= BUF_BEGV (b))
21088 sprintf (decode_mode_spec_buf, "Top%2"pI"d%%", total);
21089 else
21090 sprintf (decode_mode_spec_buf, "%2"pI"d%%", total);
21091 return decode_mode_spec_buf;
21092 }
21093 }
21094
21095 case 's':
21096 /* status of process */
21097 obj = Fget_buffer_process (Fcurrent_buffer ());
21098 if (NILP (obj))
21099 return "no process";
21100 #ifndef MSDOS
21101 obj = Fsymbol_name (Fprocess_status (obj));
21102 #endif
21103 break;
21104
21105 case '@':
21106 {
21107 int count = inhibit_garbage_collection ();
21108 Lisp_Object val = call1 (intern ("file-remote-p"),
21109 BVAR (current_buffer, directory));
21110 unbind_to (count, Qnil);
21111
21112 if (NILP (val))
21113 return "-";
21114 else
21115 return "@";
21116 }
21117
21118 case 't': /* indicate TEXT or BINARY */
21119 return "T";
21120
21121 case 'z':
21122 /* coding-system (not including end-of-line format) */
21123 case 'Z':
21124 /* coding-system (including end-of-line type) */
21125 {
21126 int eol_flag = (c == 'Z');
21127 char *p = decode_mode_spec_buf;
21128
21129 if (! FRAME_WINDOW_P (f))
21130 {
21131 /* No need to mention EOL here--the terminal never needs
21132 to do EOL conversion. */
21133 p = decode_mode_spec_coding (CODING_ID_NAME
21134 (FRAME_KEYBOARD_CODING (f)->id),
21135 p, 0);
21136 p = decode_mode_spec_coding (CODING_ID_NAME
21137 (FRAME_TERMINAL_CODING (f)->id),
21138 p, 0);
21139 }
21140 p = decode_mode_spec_coding (BVAR (b, buffer_file_coding_system),
21141 p, eol_flag);
21142
21143 #if 0 /* This proves to be annoying; I think we can do without. -- rms. */
21144 #ifdef subprocesses
21145 obj = Fget_buffer_process (Fcurrent_buffer ());
21146 if (PROCESSP (obj))
21147 {
21148 p = decode_mode_spec_coding (XPROCESS (obj)->decode_coding_system,
21149 p, eol_flag);
21150 p = decode_mode_spec_coding (XPROCESS (obj)->encode_coding_system,
21151 p, eol_flag);
21152 }
21153 #endif /* subprocesses */
21154 #endif /* 0 */
21155 *p = 0;
21156 return decode_mode_spec_buf;
21157 }
21158 }
21159
21160 if (STRINGP (obj))
21161 {
21162 *string = obj;
21163 return SSDATA (obj);
21164 }
21165 else
21166 return "";
21167 }
21168
21169
21170 /* Count up to COUNT lines starting from START_BYTE.
21171 But don't go beyond LIMIT_BYTE.
21172 Return the number of lines thus found (always nonnegative).
21173
21174 Set *BYTE_POS_PTR to 1 if we found COUNT lines, 0 if we hit LIMIT. */
21175
21176 static EMACS_INT
21177 display_count_lines (EMACS_INT start_byte,
21178 EMACS_INT limit_byte, EMACS_INT count,
21179 EMACS_INT *byte_pos_ptr)
21180 {
21181 register unsigned char *cursor;
21182 unsigned char *base;
21183
21184 register EMACS_INT ceiling;
21185 register unsigned char *ceiling_addr;
21186 EMACS_INT orig_count = count;
21187
21188 /* If we are not in selective display mode,
21189 check only for newlines. */
21190 int selective_display = (!NILP (BVAR (current_buffer, selective_display))
21191 && !INTEGERP (BVAR (current_buffer, selective_display)));
21192
21193 if (count > 0)
21194 {
21195 while (start_byte < limit_byte)
21196 {
21197 ceiling = BUFFER_CEILING_OF (start_byte);
21198 ceiling = min (limit_byte - 1, ceiling);
21199 ceiling_addr = BYTE_POS_ADDR (ceiling) + 1;
21200 base = (cursor = BYTE_POS_ADDR (start_byte));
21201 while (1)
21202 {
21203 if (selective_display)
21204 while (*cursor != '\n' && *cursor != 015 && ++cursor != ceiling_addr)
21205 ;
21206 else
21207 while (*cursor != '\n' && ++cursor != ceiling_addr)
21208 ;
21209
21210 if (cursor != ceiling_addr)
21211 {
21212 if (--count == 0)
21213 {
21214 start_byte += cursor - base + 1;
21215 *byte_pos_ptr = start_byte;
21216 return orig_count;
21217 }
21218 else
21219 if (++cursor == ceiling_addr)
21220 break;
21221 }
21222 else
21223 break;
21224 }
21225 start_byte += cursor - base;
21226 }
21227 }
21228 else
21229 {
21230 while (start_byte > limit_byte)
21231 {
21232 ceiling = BUFFER_FLOOR_OF (start_byte - 1);
21233 ceiling = max (limit_byte, ceiling);
21234 ceiling_addr = BYTE_POS_ADDR (ceiling) - 1;
21235 base = (cursor = BYTE_POS_ADDR (start_byte - 1) + 1);
21236 while (1)
21237 {
21238 if (selective_display)
21239 while (--cursor != ceiling_addr
21240 && *cursor != '\n' && *cursor != 015)
21241 ;
21242 else
21243 while (--cursor != ceiling_addr && *cursor != '\n')
21244 ;
21245
21246 if (cursor != ceiling_addr)
21247 {
21248 if (++count == 0)
21249 {
21250 start_byte += cursor - base + 1;
21251 *byte_pos_ptr = start_byte;
21252 /* When scanning backwards, we should
21253 not count the newline posterior to which we stop. */
21254 return - orig_count - 1;
21255 }
21256 }
21257 else
21258 break;
21259 }
21260 /* Here we add 1 to compensate for the last decrement
21261 of CURSOR, which took it past the valid range. */
21262 start_byte += cursor - base + 1;
21263 }
21264 }
21265
21266 *byte_pos_ptr = limit_byte;
21267
21268 if (count < 0)
21269 return - orig_count + count;
21270 return orig_count - count;
21271
21272 }
21273
21274
21275 \f
21276 /***********************************************************************
21277 Displaying strings
21278 ***********************************************************************/
21279
21280 /* Display a NUL-terminated string, starting with index START.
21281
21282 If STRING is non-null, display that C string. Otherwise, the Lisp
21283 string LISP_STRING is displayed. There's a case that STRING is
21284 non-null and LISP_STRING is not nil. It means STRING is a string
21285 data of LISP_STRING. In that case, we display LISP_STRING while
21286 ignoring its text properties.
21287
21288 If FACE_STRING is not nil, FACE_STRING_POS is a position in
21289 FACE_STRING. Display STRING or LISP_STRING with the face at
21290 FACE_STRING_POS in FACE_STRING:
21291
21292 Display the string in the environment given by IT, but use the
21293 standard display table, temporarily.
21294
21295 FIELD_WIDTH is the minimum number of output glyphs to produce.
21296 If STRING has fewer characters than FIELD_WIDTH, pad to the right
21297 with spaces. If STRING has more characters, more than FIELD_WIDTH
21298 glyphs will be produced. FIELD_WIDTH <= 0 means don't pad.
21299
21300 PRECISION is the maximum number of characters to output from
21301 STRING. PRECISION < 0 means don't truncate the string.
21302
21303 This is roughly equivalent to printf format specifiers:
21304
21305 FIELD_WIDTH PRECISION PRINTF
21306 ----------------------------------------
21307 -1 -1 %s
21308 -1 10 %.10s
21309 10 -1 %10s
21310 20 10 %20.10s
21311
21312 MULTIBYTE zero means do not display multibyte chars, > 0 means do
21313 display them, and < 0 means obey the current buffer's value of
21314 enable_multibyte_characters.
21315
21316 Value is the number of columns displayed. */
21317
21318 static int
21319 display_string (const char *string, Lisp_Object lisp_string, Lisp_Object face_string,
21320 EMACS_INT face_string_pos, EMACS_INT start, struct it *it,
21321 int field_width, int precision, int max_x, int multibyte)
21322 {
21323 int hpos_at_start = it->hpos;
21324 int saved_face_id = it->face_id;
21325 struct glyph_row *row = it->glyph_row;
21326 EMACS_INT it_charpos;
21327
21328 /* Initialize the iterator IT for iteration over STRING beginning
21329 with index START. */
21330 reseat_to_string (it, NILP (lisp_string) ? string : NULL, lisp_string, start,
21331 precision, field_width, multibyte);
21332 if (string && STRINGP (lisp_string))
21333 /* LISP_STRING is the one returned by decode_mode_spec. We should
21334 ignore its text properties. */
21335 it->stop_charpos = it->end_charpos;
21336
21337 /* If displaying STRING, set up the face of the iterator from
21338 FACE_STRING, if that's given. */
21339 if (STRINGP (face_string))
21340 {
21341 EMACS_INT endptr;
21342 struct face *face;
21343
21344 it->face_id
21345 = face_at_string_position (it->w, face_string, face_string_pos,
21346 0, it->region_beg_charpos,
21347 it->region_end_charpos,
21348 &endptr, it->base_face_id, 0);
21349 face = FACE_FROM_ID (it->f, it->face_id);
21350 it->face_box_p = face->box != FACE_NO_BOX;
21351 }
21352
21353 /* Set max_x to the maximum allowed X position. Don't let it go
21354 beyond the right edge of the window. */
21355 if (max_x <= 0)
21356 max_x = it->last_visible_x;
21357 else
21358 max_x = min (max_x, it->last_visible_x);
21359
21360 /* Skip over display elements that are not visible. because IT->w is
21361 hscrolled. */
21362 if (it->current_x < it->first_visible_x)
21363 move_it_in_display_line_to (it, 100000, it->first_visible_x,
21364 MOVE_TO_POS | MOVE_TO_X);
21365
21366 row->ascent = it->max_ascent;
21367 row->height = it->max_ascent + it->max_descent;
21368 row->phys_ascent = it->max_phys_ascent;
21369 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
21370 row->extra_line_spacing = it->max_extra_line_spacing;
21371
21372 if (STRINGP (it->string))
21373 it_charpos = IT_STRING_CHARPOS (*it);
21374 else
21375 it_charpos = IT_CHARPOS (*it);
21376
21377 /* This condition is for the case that we are called with current_x
21378 past last_visible_x. */
21379 while (it->current_x < max_x)
21380 {
21381 int x_before, x, n_glyphs_before, i, nglyphs;
21382
21383 /* Get the next display element. */
21384 if (!get_next_display_element (it))
21385 break;
21386
21387 /* Produce glyphs. */
21388 x_before = it->current_x;
21389 n_glyphs_before = row->used[TEXT_AREA];
21390 PRODUCE_GLYPHS (it);
21391
21392 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
21393 i = 0;
21394 x = x_before;
21395 while (i < nglyphs)
21396 {
21397 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
21398
21399 if (it->line_wrap != TRUNCATE
21400 && x + glyph->pixel_width > max_x)
21401 {
21402 /* End of continued line or max_x reached. */
21403 if (CHAR_GLYPH_PADDING_P (*glyph))
21404 {
21405 /* A wide character is unbreakable. */
21406 if (row->reversed_p)
21407 unproduce_glyphs (it, row->used[TEXT_AREA]
21408 - n_glyphs_before);
21409 row->used[TEXT_AREA] = n_glyphs_before;
21410 it->current_x = x_before;
21411 }
21412 else
21413 {
21414 if (row->reversed_p)
21415 unproduce_glyphs (it, row->used[TEXT_AREA]
21416 - (n_glyphs_before + i));
21417 row->used[TEXT_AREA] = n_glyphs_before + i;
21418 it->current_x = x;
21419 }
21420 break;
21421 }
21422 else if (x + glyph->pixel_width >= it->first_visible_x)
21423 {
21424 /* Glyph is at least partially visible. */
21425 ++it->hpos;
21426 if (x < it->first_visible_x)
21427 row->x = x - it->first_visible_x;
21428 }
21429 else
21430 {
21431 /* Glyph is off the left margin of the display area.
21432 Should not happen. */
21433 abort ();
21434 }
21435
21436 row->ascent = max (row->ascent, it->max_ascent);
21437 row->height = max (row->height, it->max_ascent + it->max_descent);
21438 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
21439 row->phys_height = max (row->phys_height,
21440 it->max_phys_ascent + it->max_phys_descent);
21441 row->extra_line_spacing = max (row->extra_line_spacing,
21442 it->max_extra_line_spacing);
21443 x += glyph->pixel_width;
21444 ++i;
21445 }
21446
21447 /* Stop if max_x reached. */
21448 if (i < nglyphs)
21449 break;
21450
21451 /* Stop at line ends. */
21452 if (ITERATOR_AT_END_OF_LINE_P (it))
21453 {
21454 it->continuation_lines_width = 0;
21455 break;
21456 }
21457
21458 set_iterator_to_next (it, 1);
21459 if (STRINGP (it->string))
21460 it_charpos = IT_STRING_CHARPOS (*it);
21461 else
21462 it_charpos = IT_CHARPOS (*it);
21463
21464 /* Stop if truncating at the right edge. */
21465 if (it->line_wrap == TRUNCATE
21466 && it->current_x >= it->last_visible_x)
21467 {
21468 /* Add truncation mark, but don't do it if the line is
21469 truncated at a padding space. */
21470 if (it_charpos < it->string_nchars)
21471 {
21472 if (!FRAME_WINDOW_P (it->f))
21473 {
21474 int ii, n;
21475
21476 if (it->current_x > it->last_visible_x)
21477 {
21478 if (!row->reversed_p)
21479 {
21480 for (ii = row->used[TEXT_AREA] - 1; ii > 0; --ii)
21481 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][ii]))
21482 break;
21483 }
21484 else
21485 {
21486 for (ii = 0; ii < row->used[TEXT_AREA]; ii++)
21487 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][ii]))
21488 break;
21489 unproduce_glyphs (it, ii + 1);
21490 ii = row->used[TEXT_AREA] - (ii + 1);
21491 }
21492 for (n = row->used[TEXT_AREA]; ii < n; ++ii)
21493 {
21494 row->used[TEXT_AREA] = ii;
21495 produce_special_glyphs (it, IT_TRUNCATION);
21496 }
21497 }
21498 produce_special_glyphs (it, IT_TRUNCATION);
21499 }
21500 row->truncated_on_right_p = 1;
21501 }
21502 break;
21503 }
21504 }
21505
21506 /* Maybe insert a truncation at the left. */
21507 if (it->first_visible_x
21508 && it_charpos > 0)
21509 {
21510 if (!FRAME_WINDOW_P (it->f))
21511 insert_left_trunc_glyphs (it);
21512 row->truncated_on_left_p = 1;
21513 }
21514
21515 it->face_id = saved_face_id;
21516
21517 /* Value is number of columns displayed. */
21518 return it->hpos - hpos_at_start;
21519 }
21520
21521
21522 \f
21523 /* This is like a combination of memq and assq. Return 1/2 if PROPVAL
21524 appears as an element of LIST or as the car of an element of LIST.
21525 If PROPVAL is a list, compare each element against LIST in that
21526 way, and return 1/2 if any element of PROPVAL is found in LIST.
21527 Otherwise return 0. This function cannot quit.
21528 The return value is 2 if the text is invisible but with an ellipsis
21529 and 1 if it's invisible and without an ellipsis. */
21530
21531 int
21532 invisible_p (register Lisp_Object propval, Lisp_Object list)
21533 {
21534 register Lisp_Object tail, proptail;
21535
21536 for (tail = list; CONSP (tail); tail = XCDR (tail))
21537 {
21538 register Lisp_Object tem;
21539 tem = XCAR (tail);
21540 if (EQ (propval, tem))
21541 return 1;
21542 if (CONSP (tem) && EQ (propval, XCAR (tem)))
21543 return NILP (XCDR (tem)) ? 1 : 2;
21544 }
21545
21546 if (CONSP (propval))
21547 {
21548 for (proptail = propval; CONSP (proptail); proptail = XCDR (proptail))
21549 {
21550 Lisp_Object propelt;
21551 propelt = XCAR (proptail);
21552 for (tail = list; CONSP (tail); tail = XCDR (tail))
21553 {
21554 register Lisp_Object tem;
21555 tem = XCAR (tail);
21556 if (EQ (propelt, tem))
21557 return 1;
21558 if (CONSP (tem) && EQ (propelt, XCAR (tem)))
21559 return NILP (XCDR (tem)) ? 1 : 2;
21560 }
21561 }
21562 }
21563
21564 return 0;
21565 }
21566
21567 DEFUN ("invisible-p", Finvisible_p, Sinvisible_p, 1, 1, 0,
21568 doc: /* Non-nil if the property makes the text invisible.
21569 POS-OR-PROP can be a marker or number, in which case it is taken to be
21570 a position in the current buffer and the value of the `invisible' property
21571 is checked; or it can be some other value, which is then presumed to be the
21572 value of the `invisible' property of the text of interest.
21573 The non-nil value returned can be t for truly invisible text or something
21574 else if the text is replaced by an ellipsis. */)
21575 (Lisp_Object pos_or_prop)
21576 {
21577 Lisp_Object prop
21578 = (NATNUMP (pos_or_prop) || MARKERP (pos_or_prop)
21579 ? Fget_char_property (pos_or_prop, Qinvisible, Qnil)
21580 : pos_or_prop);
21581 int invis = TEXT_PROP_MEANS_INVISIBLE (prop);
21582 return (invis == 0 ? Qnil
21583 : invis == 1 ? Qt
21584 : make_number (invis));
21585 }
21586
21587 /* Calculate a width or height in pixels from a specification using
21588 the following elements:
21589
21590 SPEC ::=
21591 NUM - a (fractional) multiple of the default font width/height
21592 (NUM) - specifies exactly NUM pixels
21593 UNIT - a fixed number of pixels, see below.
21594 ELEMENT - size of a display element in pixels, see below.
21595 (NUM . SPEC) - equals NUM * SPEC
21596 (+ SPEC SPEC ...) - add pixel values
21597 (- SPEC SPEC ...) - subtract pixel values
21598 (- SPEC) - negate pixel value
21599
21600 NUM ::=
21601 INT or FLOAT - a number constant
21602 SYMBOL - use symbol's (buffer local) variable binding.
21603
21604 UNIT ::=
21605 in - pixels per inch *)
21606 mm - pixels per 1/1000 meter *)
21607 cm - pixels per 1/100 meter *)
21608 width - width of current font in pixels.
21609 height - height of current font in pixels.
21610
21611 *) using the ratio(s) defined in display-pixels-per-inch.
21612
21613 ELEMENT ::=
21614
21615 left-fringe - left fringe width in pixels
21616 right-fringe - right fringe width in pixels
21617
21618 left-margin - left margin width in pixels
21619 right-margin - right margin width in pixels
21620
21621 scroll-bar - scroll-bar area width in pixels
21622
21623 Examples:
21624
21625 Pixels corresponding to 5 inches:
21626 (5 . in)
21627
21628 Total width of non-text areas on left side of window (if scroll-bar is on left):
21629 '(space :width (+ left-fringe left-margin scroll-bar))
21630
21631 Align to first text column (in header line):
21632 '(space :align-to 0)
21633
21634 Align to middle of text area minus half the width of variable `my-image'
21635 containing a loaded image:
21636 '(space :align-to (0.5 . (- text my-image)))
21637
21638 Width of left margin minus width of 1 character in the default font:
21639 '(space :width (- left-margin 1))
21640
21641 Width of left margin minus width of 2 characters in the current font:
21642 '(space :width (- left-margin (2 . width)))
21643
21644 Center 1 character over left-margin (in header line):
21645 '(space :align-to (+ left-margin (0.5 . left-margin) -0.5))
21646
21647 Different ways to express width of left fringe plus left margin minus one pixel:
21648 '(space :width (- (+ left-fringe left-margin) (1)))
21649 '(space :width (+ left-fringe left-margin (- (1))))
21650 '(space :width (+ left-fringe left-margin (-1)))
21651
21652 */
21653
21654 #define NUMVAL(X) \
21655 ((INTEGERP (X) || FLOATP (X)) \
21656 ? XFLOATINT (X) \
21657 : - 1)
21658
21659 static int
21660 calc_pixel_width_or_height (double *res, struct it *it, Lisp_Object prop,
21661 struct font *font, int width_p, int *align_to)
21662 {
21663 double pixels;
21664
21665 #define OK_PIXELS(val) ((*res = (double)(val)), 1)
21666 #define OK_ALIGN_TO(val) ((*align_to = (int)(val)), 1)
21667
21668 if (NILP (prop))
21669 return OK_PIXELS (0);
21670
21671 xassert (FRAME_LIVE_P (it->f));
21672
21673 if (SYMBOLP (prop))
21674 {
21675 if (SCHARS (SYMBOL_NAME (prop)) == 2)
21676 {
21677 char *unit = SSDATA (SYMBOL_NAME (prop));
21678
21679 if (unit[0] == 'i' && unit[1] == 'n')
21680 pixels = 1.0;
21681 else if (unit[0] == 'm' && unit[1] == 'm')
21682 pixels = 25.4;
21683 else if (unit[0] == 'c' && unit[1] == 'm')
21684 pixels = 2.54;
21685 else
21686 pixels = 0;
21687 if (pixels > 0)
21688 {
21689 double ppi;
21690 #ifdef HAVE_WINDOW_SYSTEM
21691 if (FRAME_WINDOW_P (it->f)
21692 && (ppi = (width_p
21693 ? FRAME_X_DISPLAY_INFO (it->f)->resx
21694 : FRAME_X_DISPLAY_INFO (it->f)->resy),
21695 ppi > 0))
21696 return OK_PIXELS (ppi / pixels);
21697 #endif
21698
21699 if ((ppi = NUMVAL (Vdisplay_pixels_per_inch), ppi > 0)
21700 || (CONSP (Vdisplay_pixels_per_inch)
21701 && (ppi = (width_p
21702 ? NUMVAL (XCAR (Vdisplay_pixels_per_inch))
21703 : NUMVAL (XCDR (Vdisplay_pixels_per_inch))),
21704 ppi > 0)))
21705 return OK_PIXELS (ppi / pixels);
21706
21707 return 0;
21708 }
21709 }
21710
21711 #ifdef HAVE_WINDOW_SYSTEM
21712 if (EQ (prop, Qheight))
21713 return OK_PIXELS (font ? FONT_HEIGHT (font) : FRAME_LINE_HEIGHT (it->f));
21714 if (EQ (prop, Qwidth))
21715 return OK_PIXELS (font ? FONT_WIDTH (font) : FRAME_COLUMN_WIDTH (it->f));
21716 #else
21717 if (EQ (prop, Qheight) || EQ (prop, Qwidth))
21718 return OK_PIXELS (1);
21719 #endif
21720
21721 if (EQ (prop, Qtext))
21722 return OK_PIXELS (width_p
21723 ? window_box_width (it->w, TEXT_AREA)
21724 : WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w));
21725
21726 if (align_to && *align_to < 0)
21727 {
21728 *res = 0;
21729 if (EQ (prop, Qleft))
21730 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA));
21731 if (EQ (prop, Qright))
21732 return OK_ALIGN_TO (window_box_right_offset (it->w, TEXT_AREA));
21733 if (EQ (prop, Qcenter))
21734 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA)
21735 + window_box_width (it->w, TEXT_AREA) / 2);
21736 if (EQ (prop, Qleft_fringe))
21737 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
21738 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (it->w)
21739 : window_box_right_offset (it->w, LEFT_MARGIN_AREA));
21740 if (EQ (prop, Qright_fringe))
21741 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
21742 ? window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
21743 : window_box_right_offset (it->w, TEXT_AREA));
21744 if (EQ (prop, Qleft_margin))
21745 return OK_ALIGN_TO (window_box_left_offset (it->w, LEFT_MARGIN_AREA));
21746 if (EQ (prop, Qright_margin))
21747 return OK_ALIGN_TO (window_box_left_offset (it->w, RIGHT_MARGIN_AREA));
21748 if (EQ (prop, Qscroll_bar))
21749 return OK_ALIGN_TO (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (it->w)
21750 ? 0
21751 : (window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
21752 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
21753 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
21754 : 0)));
21755 }
21756 else
21757 {
21758 if (EQ (prop, Qleft_fringe))
21759 return OK_PIXELS (WINDOW_LEFT_FRINGE_WIDTH (it->w));
21760 if (EQ (prop, Qright_fringe))
21761 return OK_PIXELS (WINDOW_RIGHT_FRINGE_WIDTH (it->w));
21762 if (EQ (prop, Qleft_margin))
21763 return OK_PIXELS (WINDOW_LEFT_MARGIN_WIDTH (it->w));
21764 if (EQ (prop, Qright_margin))
21765 return OK_PIXELS (WINDOW_RIGHT_MARGIN_WIDTH (it->w));
21766 if (EQ (prop, Qscroll_bar))
21767 return OK_PIXELS (WINDOW_SCROLL_BAR_AREA_WIDTH (it->w));
21768 }
21769
21770 prop = Fbuffer_local_value (prop, it->w->buffer);
21771 }
21772
21773 if (INTEGERP (prop) || FLOATP (prop))
21774 {
21775 int base_unit = (width_p
21776 ? FRAME_COLUMN_WIDTH (it->f)
21777 : FRAME_LINE_HEIGHT (it->f));
21778 return OK_PIXELS (XFLOATINT (prop) * base_unit);
21779 }
21780
21781 if (CONSP (prop))
21782 {
21783 Lisp_Object car = XCAR (prop);
21784 Lisp_Object cdr = XCDR (prop);
21785
21786 if (SYMBOLP (car))
21787 {
21788 #ifdef HAVE_WINDOW_SYSTEM
21789 if (FRAME_WINDOW_P (it->f)
21790 && valid_image_p (prop))
21791 {
21792 ptrdiff_t id = lookup_image (it->f, prop);
21793 struct image *img = IMAGE_FROM_ID (it->f, id);
21794
21795 return OK_PIXELS (width_p ? img->width : img->height);
21796 }
21797 #endif
21798 if (EQ (car, Qplus) || EQ (car, Qminus))
21799 {
21800 int first = 1;
21801 double px;
21802
21803 pixels = 0;
21804 while (CONSP (cdr))
21805 {
21806 if (!calc_pixel_width_or_height (&px, it, XCAR (cdr),
21807 font, width_p, align_to))
21808 return 0;
21809 if (first)
21810 pixels = (EQ (car, Qplus) ? px : -px), first = 0;
21811 else
21812 pixels += px;
21813 cdr = XCDR (cdr);
21814 }
21815 if (EQ (car, Qminus))
21816 pixels = -pixels;
21817 return OK_PIXELS (pixels);
21818 }
21819
21820 car = Fbuffer_local_value (car, it->w->buffer);
21821 }
21822
21823 if (INTEGERP (car) || FLOATP (car))
21824 {
21825 double fact;
21826 pixels = XFLOATINT (car);
21827 if (NILP (cdr))
21828 return OK_PIXELS (pixels);
21829 if (calc_pixel_width_or_height (&fact, it, cdr,
21830 font, width_p, align_to))
21831 return OK_PIXELS (pixels * fact);
21832 return 0;
21833 }
21834
21835 return 0;
21836 }
21837
21838 return 0;
21839 }
21840
21841 \f
21842 /***********************************************************************
21843 Glyph Display
21844 ***********************************************************************/
21845
21846 #ifdef HAVE_WINDOW_SYSTEM
21847
21848 #if GLYPH_DEBUG
21849
21850 void
21851 dump_glyph_string (struct glyph_string *s)
21852 {
21853 fprintf (stderr, "glyph string\n");
21854 fprintf (stderr, " x, y, w, h = %d, %d, %d, %d\n",
21855 s->x, s->y, s->width, s->height);
21856 fprintf (stderr, " ybase = %d\n", s->ybase);
21857 fprintf (stderr, " hl = %d\n", s->hl);
21858 fprintf (stderr, " left overhang = %d, right = %d\n",
21859 s->left_overhang, s->right_overhang);
21860 fprintf (stderr, " nchars = %d\n", s->nchars);
21861 fprintf (stderr, " extends to end of line = %d\n",
21862 s->extends_to_end_of_line_p);
21863 fprintf (stderr, " font height = %d\n", FONT_HEIGHT (s->font));
21864 fprintf (stderr, " bg width = %d\n", s->background_width);
21865 }
21866
21867 #endif /* GLYPH_DEBUG */
21868
21869 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
21870 of XChar2b structures for S; it can't be allocated in
21871 init_glyph_string because it must be allocated via `alloca'. W
21872 is the window on which S is drawn. ROW and AREA are the glyph row
21873 and area within the row from which S is constructed. START is the
21874 index of the first glyph structure covered by S. HL is a
21875 face-override for drawing S. */
21876
21877 #ifdef HAVE_NTGUI
21878 #define OPTIONAL_HDC(hdc) HDC hdc,
21879 #define DECLARE_HDC(hdc) HDC hdc;
21880 #define ALLOCATE_HDC(hdc, f) hdc = get_frame_dc ((f))
21881 #define RELEASE_HDC(hdc, f) release_frame_dc ((f), (hdc))
21882 #endif
21883
21884 #ifndef OPTIONAL_HDC
21885 #define OPTIONAL_HDC(hdc)
21886 #define DECLARE_HDC(hdc)
21887 #define ALLOCATE_HDC(hdc, f)
21888 #define RELEASE_HDC(hdc, f)
21889 #endif
21890
21891 static void
21892 init_glyph_string (struct glyph_string *s,
21893 OPTIONAL_HDC (hdc)
21894 XChar2b *char2b, struct window *w, struct glyph_row *row,
21895 enum glyph_row_area area, int start, enum draw_glyphs_face hl)
21896 {
21897 memset (s, 0, sizeof *s);
21898 s->w = w;
21899 s->f = XFRAME (w->frame);
21900 #ifdef HAVE_NTGUI
21901 s->hdc = hdc;
21902 #endif
21903 s->display = FRAME_X_DISPLAY (s->f);
21904 s->window = FRAME_X_WINDOW (s->f);
21905 s->char2b = char2b;
21906 s->hl = hl;
21907 s->row = row;
21908 s->area = area;
21909 s->first_glyph = row->glyphs[area] + start;
21910 s->height = row->height;
21911 s->y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
21912 s->ybase = s->y + row->ascent;
21913 }
21914
21915
21916 /* Append the list of glyph strings with head H and tail T to the list
21917 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
21918
21919 static inline void
21920 append_glyph_string_lists (struct glyph_string **head, struct glyph_string **tail,
21921 struct glyph_string *h, struct glyph_string *t)
21922 {
21923 if (h)
21924 {
21925 if (*head)
21926 (*tail)->next = h;
21927 else
21928 *head = h;
21929 h->prev = *tail;
21930 *tail = t;
21931 }
21932 }
21933
21934
21935 /* Prepend the list of glyph strings with head H and tail T to the
21936 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
21937 result. */
21938
21939 static inline void
21940 prepend_glyph_string_lists (struct glyph_string **head, struct glyph_string **tail,
21941 struct glyph_string *h, struct glyph_string *t)
21942 {
21943 if (h)
21944 {
21945 if (*head)
21946 (*head)->prev = t;
21947 else
21948 *tail = t;
21949 t->next = *head;
21950 *head = h;
21951 }
21952 }
21953
21954
21955 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
21956 Set *HEAD and *TAIL to the resulting list. */
21957
21958 static inline void
21959 append_glyph_string (struct glyph_string **head, struct glyph_string **tail,
21960 struct glyph_string *s)
21961 {
21962 s->next = s->prev = NULL;
21963 append_glyph_string_lists (head, tail, s, s);
21964 }
21965
21966
21967 /* Get face and two-byte form of character C in face FACE_ID on frame F.
21968 The encoding of C is returned in *CHAR2B. DISPLAY_P non-zero means
21969 make sure that X resources for the face returned are allocated.
21970 Value is a pointer to a realized face that is ready for display if
21971 DISPLAY_P is non-zero. */
21972
21973 static inline struct face *
21974 get_char_face_and_encoding (struct frame *f, int c, int face_id,
21975 XChar2b *char2b, int display_p)
21976 {
21977 struct face *face = FACE_FROM_ID (f, face_id);
21978
21979 if (face->font)
21980 {
21981 unsigned code = face->font->driver->encode_char (face->font, c);
21982
21983 if (code != FONT_INVALID_CODE)
21984 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
21985 else
21986 STORE_XCHAR2B (char2b, 0, 0);
21987 }
21988
21989 /* Make sure X resources of the face are allocated. */
21990 #ifdef HAVE_X_WINDOWS
21991 if (display_p)
21992 #endif
21993 {
21994 xassert (face != NULL);
21995 PREPARE_FACE_FOR_DISPLAY (f, face);
21996 }
21997
21998 return face;
21999 }
22000
22001
22002 /* Get face and two-byte form of character glyph GLYPH on frame F.
22003 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
22004 a pointer to a realized face that is ready for display. */
22005
22006 static inline struct face *
22007 get_glyph_face_and_encoding (struct frame *f, struct glyph *glyph,
22008 XChar2b *char2b, int *two_byte_p)
22009 {
22010 struct face *face;
22011
22012 xassert (glyph->type == CHAR_GLYPH);
22013 face = FACE_FROM_ID (f, glyph->face_id);
22014
22015 if (two_byte_p)
22016 *two_byte_p = 0;
22017
22018 if (face->font)
22019 {
22020 unsigned code;
22021
22022 if (CHAR_BYTE8_P (glyph->u.ch))
22023 code = CHAR_TO_BYTE8 (glyph->u.ch);
22024 else
22025 code = face->font->driver->encode_char (face->font, glyph->u.ch);
22026
22027 if (code != FONT_INVALID_CODE)
22028 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
22029 else
22030 STORE_XCHAR2B (char2b, 0, 0);
22031 }
22032
22033 /* Make sure X resources of the face are allocated. */
22034 xassert (face != NULL);
22035 PREPARE_FACE_FOR_DISPLAY (f, face);
22036 return face;
22037 }
22038
22039
22040 /* Get glyph code of character C in FONT in the two-byte form CHAR2B.
22041 Retunr 1 if FONT has a glyph for C, otherwise return 0. */
22042
22043 static inline int
22044 get_char_glyph_code (int c, struct font *font, XChar2b *char2b)
22045 {
22046 unsigned code;
22047
22048 if (CHAR_BYTE8_P (c))
22049 code = CHAR_TO_BYTE8 (c);
22050 else
22051 code = font->driver->encode_char (font, c);
22052
22053 if (code == FONT_INVALID_CODE)
22054 return 0;
22055 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
22056 return 1;
22057 }
22058
22059
22060 /* Fill glyph string S with composition components specified by S->cmp.
22061
22062 BASE_FACE is the base face of the composition.
22063 S->cmp_from is the index of the first component for S.
22064
22065 OVERLAPS non-zero means S should draw the foreground only, and use
22066 its physical height for clipping. See also draw_glyphs.
22067
22068 Value is the index of a component not in S. */
22069
22070 static int
22071 fill_composite_glyph_string (struct glyph_string *s, struct face *base_face,
22072 int overlaps)
22073 {
22074 int i;
22075 /* For all glyphs of this composition, starting at the offset
22076 S->cmp_from, until we reach the end of the definition or encounter a
22077 glyph that requires the different face, add it to S. */
22078 struct face *face;
22079
22080 xassert (s);
22081
22082 s->for_overlaps = overlaps;
22083 s->face = NULL;
22084 s->font = NULL;
22085 for (i = s->cmp_from; i < s->cmp->glyph_len; i++)
22086 {
22087 int c = COMPOSITION_GLYPH (s->cmp, i);
22088
22089 /* TAB in a composition means display glyphs with padding space
22090 on the left or right. */
22091 if (c != '\t')
22092 {
22093 int face_id = FACE_FOR_CHAR (s->f, base_face->ascii_face, c,
22094 -1, Qnil);
22095
22096 face = get_char_face_and_encoding (s->f, c, face_id,
22097 s->char2b + i, 1);
22098 if (face)
22099 {
22100 if (! s->face)
22101 {
22102 s->face = face;
22103 s->font = s->face->font;
22104 }
22105 else if (s->face != face)
22106 break;
22107 }
22108 }
22109 ++s->nchars;
22110 }
22111 s->cmp_to = i;
22112
22113 /* All glyph strings for the same composition has the same width,
22114 i.e. the width set for the first component of the composition. */
22115 s->width = s->first_glyph->pixel_width;
22116
22117 /* If the specified font could not be loaded, use the frame's
22118 default font, but record the fact that we couldn't load it in
22119 the glyph string so that we can draw rectangles for the
22120 characters of the glyph string. */
22121 if (s->font == NULL)
22122 {
22123 s->font_not_found_p = 1;
22124 s->font = FRAME_FONT (s->f);
22125 }
22126
22127 /* Adjust base line for subscript/superscript text. */
22128 s->ybase += s->first_glyph->voffset;
22129
22130 /* This glyph string must always be drawn with 16-bit functions. */
22131 s->two_byte_p = 1;
22132
22133 return s->cmp_to;
22134 }
22135
22136 static int
22137 fill_gstring_glyph_string (struct glyph_string *s, int face_id,
22138 int start, int end, int overlaps)
22139 {
22140 struct glyph *glyph, *last;
22141 Lisp_Object lgstring;
22142 int i;
22143
22144 s->for_overlaps = overlaps;
22145 glyph = s->row->glyphs[s->area] + start;
22146 last = s->row->glyphs[s->area] + end;
22147 s->cmp_id = glyph->u.cmp.id;
22148 s->cmp_from = glyph->slice.cmp.from;
22149 s->cmp_to = glyph->slice.cmp.to + 1;
22150 s->face = FACE_FROM_ID (s->f, face_id);
22151 lgstring = composition_gstring_from_id (s->cmp_id);
22152 s->font = XFONT_OBJECT (LGSTRING_FONT (lgstring));
22153 glyph++;
22154 while (glyph < last
22155 && glyph->u.cmp.automatic
22156 && glyph->u.cmp.id == s->cmp_id
22157 && s->cmp_to == glyph->slice.cmp.from)
22158 s->cmp_to = (glyph++)->slice.cmp.to + 1;
22159
22160 for (i = s->cmp_from; i < s->cmp_to; i++)
22161 {
22162 Lisp_Object lglyph = LGSTRING_GLYPH (lgstring, i);
22163 unsigned code = LGLYPH_CODE (lglyph);
22164
22165 STORE_XCHAR2B ((s->char2b + i), code >> 8, code & 0xFF);
22166 }
22167 s->width = composition_gstring_width (lgstring, s->cmp_from, s->cmp_to, NULL);
22168 return glyph - s->row->glyphs[s->area];
22169 }
22170
22171
22172 /* Fill glyph string S from a sequence glyphs for glyphless characters.
22173 See the comment of fill_glyph_string for arguments.
22174 Value is the index of the first glyph not in S. */
22175
22176
22177 static int
22178 fill_glyphless_glyph_string (struct glyph_string *s, int face_id,
22179 int start, int end, int overlaps)
22180 {
22181 struct glyph *glyph, *last;
22182 int voffset;
22183
22184 xassert (s->first_glyph->type == GLYPHLESS_GLYPH);
22185 s->for_overlaps = overlaps;
22186 glyph = s->row->glyphs[s->area] + start;
22187 last = s->row->glyphs[s->area] + end;
22188 voffset = glyph->voffset;
22189 s->face = FACE_FROM_ID (s->f, face_id);
22190 s->font = s->face->font;
22191 s->nchars = 1;
22192 s->width = glyph->pixel_width;
22193 glyph++;
22194 while (glyph < last
22195 && glyph->type == GLYPHLESS_GLYPH
22196 && glyph->voffset == voffset
22197 && glyph->face_id == face_id)
22198 {
22199 s->nchars++;
22200 s->width += glyph->pixel_width;
22201 glyph++;
22202 }
22203 s->ybase += voffset;
22204 return glyph - s->row->glyphs[s->area];
22205 }
22206
22207
22208 /* Fill glyph string S from a sequence of character glyphs.
22209
22210 FACE_ID is the face id of the string. START is the index of the
22211 first glyph to consider, END is the index of the last + 1.
22212 OVERLAPS non-zero means S should draw the foreground only, and use
22213 its physical height for clipping. See also draw_glyphs.
22214
22215 Value is the index of the first glyph not in S. */
22216
22217 static int
22218 fill_glyph_string (struct glyph_string *s, int face_id,
22219 int start, int end, int overlaps)
22220 {
22221 struct glyph *glyph, *last;
22222 int voffset;
22223 int glyph_not_available_p;
22224
22225 xassert (s->f == XFRAME (s->w->frame));
22226 xassert (s->nchars == 0);
22227 xassert (start >= 0 && end > start);
22228
22229 s->for_overlaps = overlaps;
22230 glyph = s->row->glyphs[s->area] + start;
22231 last = s->row->glyphs[s->area] + end;
22232 voffset = glyph->voffset;
22233 s->padding_p = glyph->padding_p;
22234 glyph_not_available_p = glyph->glyph_not_available_p;
22235
22236 while (glyph < last
22237 && glyph->type == CHAR_GLYPH
22238 && glyph->voffset == voffset
22239 /* Same face id implies same font, nowadays. */
22240 && glyph->face_id == face_id
22241 && glyph->glyph_not_available_p == glyph_not_available_p)
22242 {
22243 int two_byte_p;
22244
22245 s->face = get_glyph_face_and_encoding (s->f, glyph,
22246 s->char2b + s->nchars,
22247 &two_byte_p);
22248 s->two_byte_p = two_byte_p;
22249 ++s->nchars;
22250 xassert (s->nchars <= end - start);
22251 s->width += glyph->pixel_width;
22252 if (glyph++->padding_p != s->padding_p)
22253 break;
22254 }
22255
22256 s->font = s->face->font;
22257
22258 /* If the specified font could not be loaded, use the frame's font,
22259 but record the fact that we couldn't load it in
22260 S->font_not_found_p so that we can draw rectangles for the
22261 characters of the glyph string. */
22262 if (s->font == NULL || glyph_not_available_p)
22263 {
22264 s->font_not_found_p = 1;
22265 s->font = FRAME_FONT (s->f);
22266 }
22267
22268 /* Adjust base line for subscript/superscript text. */
22269 s->ybase += voffset;
22270
22271 xassert (s->face && s->face->gc);
22272 return glyph - s->row->glyphs[s->area];
22273 }
22274
22275
22276 /* Fill glyph string S from image glyph S->first_glyph. */
22277
22278 static void
22279 fill_image_glyph_string (struct glyph_string *s)
22280 {
22281 xassert (s->first_glyph->type == IMAGE_GLYPH);
22282 s->img = IMAGE_FROM_ID (s->f, s->first_glyph->u.img_id);
22283 xassert (s->img);
22284 s->slice = s->first_glyph->slice.img;
22285 s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
22286 s->font = s->face->font;
22287 s->width = s->first_glyph->pixel_width;
22288
22289 /* Adjust base line for subscript/superscript text. */
22290 s->ybase += s->first_glyph->voffset;
22291 }
22292
22293
22294 /* Fill glyph string S from a sequence of stretch glyphs.
22295
22296 START is the index of the first glyph to consider,
22297 END is the index of the last + 1.
22298
22299 Value is the index of the first glyph not in S. */
22300
22301 static int
22302 fill_stretch_glyph_string (struct glyph_string *s, int start, int end)
22303 {
22304 struct glyph *glyph, *last;
22305 int voffset, face_id;
22306
22307 xassert (s->first_glyph->type == STRETCH_GLYPH);
22308
22309 glyph = s->row->glyphs[s->area] + start;
22310 last = s->row->glyphs[s->area] + end;
22311 face_id = glyph->face_id;
22312 s->face = FACE_FROM_ID (s->f, face_id);
22313 s->font = s->face->font;
22314 s->width = glyph->pixel_width;
22315 s->nchars = 1;
22316 voffset = glyph->voffset;
22317
22318 for (++glyph;
22319 (glyph < last
22320 && glyph->type == STRETCH_GLYPH
22321 && glyph->voffset == voffset
22322 && glyph->face_id == face_id);
22323 ++glyph)
22324 s->width += glyph->pixel_width;
22325
22326 /* Adjust base line for subscript/superscript text. */
22327 s->ybase += voffset;
22328
22329 /* The case that face->gc == 0 is handled when drawing the glyph
22330 string by calling PREPARE_FACE_FOR_DISPLAY. */
22331 xassert (s->face);
22332 return glyph - s->row->glyphs[s->area];
22333 }
22334
22335 static struct font_metrics *
22336 get_per_char_metric (struct font *font, XChar2b *char2b)
22337 {
22338 static struct font_metrics metrics;
22339 unsigned code = (XCHAR2B_BYTE1 (char2b) << 8) | XCHAR2B_BYTE2 (char2b);
22340
22341 if (! font || code == FONT_INVALID_CODE)
22342 return NULL;
22343 font->driver->text_extents (font, &code, 1, &metrics);
22344 return &metrics;
22345 }
22346
22347 /* EXPORT for RIF:
22348 Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
22349 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
22350 assumed to be zero. */
22351
22352 void
22353 x_get_glyph_overhangs (struct glyph *glyph, struct frame *f, int *left, int *right)
22354 {
22355 *left = *right = 0;
22356
22357 if (glyph->type == CHAR_GLYPH)
22358 {
22359 struct face *face;
22360 XChar2b char2b;
22361 struct font_metrics *pcm;
22362
22363 face = get_glyph_face_and_encoding (f, glyph, &char2b, NULL);
22364 if (face->font && (pcm = get_per_char_metric (face->font, &char2b)))
22365 {
22366 if (pcm->rbearing > pcm->width)
22367 *right = pcm->rbearing - pcm->width;
22368 if (pcm->lbearing < 0)
22369 *left = -pcm->lbearing;
22370 }
22371 }
22372 else if (glyph->type == COMPOSITE_GLYPH)
22373 {
22374 if (! glyph->u.cmp.automatic)
22375 {
22376 struct composition *cmp = composition_table[glyph->u.cmp.id];
22377
22378 if (cmp->rbearing > cmp->pixel_width)
22379 *right = cmp->rbearing - cmp->pixel_width;
22380 if (cmp->lbearing < 0)
22381 *left = - cmp->lbearing;
22382 }
22383 else
22384 {
22385 Lisp_Object gstring = composition_gstring_from_id (glyph->u.cmp.id);
22386 struct font_metrics metrics;
22387
22388 composition_gstring_width (gstring, glyph->slice.cmp.from,
22389 glyph->slice.cmp.to + 1, &metrics);
22390 if (metrics.rbearing > metrics.width)
22391 *right = metrics.rbearing - metrics.width;
22392 if (metrics.lbearing < 0)
22393 *left = - metrics.lbearing;
22394 }
22395 }
22396 }
22397
22398
22399 /* Return the index of the first glyph preceding glyph string S that
22400 is overwritten by S because of S's left overhang. Value is -1
22401 if no glyphs are overwritten. */
22402
22403 static int
22404 left_overwritten (struct glyph_string *s)
22405 {
22406 int k;
22407
22408 if (s->left_overhang)
22409 {
22410 int x = 0, i;
22411 struct glyph *glyphs = s->row->glyphs[s->area];
22412 int first = s->first_glyph - glyphs;
22413
22414 for (i = first - 1; i >= 0 && x > -s->left_overhang; --i)
22415 x -= glyphs[i].pixel_width;
22416
22417 k = i + 1;
22418 }
22419 else
22420 k = -1;
22421
22422 return k;
22423 }
22424
22425
22426 /* Return the index of the first glyph preceding glyph string S that
22427 is overwriting S because of its right overhang. Value is -1 if no
22428 glyph in front of S overwrites S. */
22429
22430 static int
22431 left_overwriting (struct glyph_string *s)
22432 {
22433 int i, k, x;
22434 struct glyph *glyphs = s->row->glyphs[s->area];
22435 int first = s->first_glyph - glyphs;
22436
22437 k = -1;
22438 x = 0;
22439 for (i = first - 1; i >= 0; --i)
22440 {
22441 int left, right;
22442 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
22443 if (x + right > 0)
22444 k = i;
22445 x -= glyphs[i].pixel_width;
22446 }
22447
22448 return k;
22449 }
22450
22451
22452 /* Return the index of the last glyph following glyph string S that is
22453 overwritten by S because of S's right overhang. Value is -1 if
22454 no such glyph is found. */
22455
22456 static int
22457 right_overwritten (struct glyph_string *s)
22458 {
22459 int k = -1;
22460
22461 if (s->right_overhang)
22462 {
22463 int x = 0, i;
22464 struct glyph *glyphs = s->row->glyphs[s->area];
22465 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
22466 int end = s->row->used[s->area];
22467
22468 for (i = first; i < end && s->right_overhang > x; ++i)
22469 x += glyphs[i].pixel_width;
22470
22471 k = i;
22472 }
22473
22474 return k;
22475 }
22476
22477
22478 /* Return the index of the last glyph following glyph string S that
22479 overwrites S because of its left overhang. Value is negative
22480 if no such glyph is found. */
22481
22482 static int
22483 right_overwriting (struct glyph_string *s)
22484 {
22485 int i, k, x;
22486 int end = s->row->used[s->area];
22487 struct glyph *glyphs = s->row->glyphs[s->area];
22488 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
22489
22490 k = -1;
22491 x = 0;
22492 for (i = first; i < end; ++i)
22493 {
22494 int left, right;
22495 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
22496 if (x - left < 0)
22497 k = i;
22498 x += glyphs[i].pixel_width;
22499 }
22500
22501 return k;
22502 }
22503
22504
22505 /* Set background width of glyph string S. START is the index of the
22506 first glyph following S. LAST_X is the right-most x-position + 1
22507 in the drawing area. */
22508
22509 static inline void
22510 set_glyph_string_background_width (struct glyph_string *s, int start, int last_x)
22511 {
22512 /* If the face of this glyph string has to be drawn to the end of
22513 the drawing area, set S->extends_to_end_of_line_p. */
22514
22515 if (start == s->row->used[s->area]
22516 && s->area == TEXT_AREA
22517 && ((s->row->fill_line_p
22518 && (s->hl == DRAW_NORMAL_TEXT
22519 || s->hl == DRAW_IMAGE_RAISED
22520 || s->hl == DRAW_IMAGE_SUNKEN))
22521 || s->hl == DRAW_MOUSE_FACE))
22522 s->extends_to_end_of_line_p = 1;
22523
22524 /* If S extends its face to the end of the line, set its
22525 background_width to the distance to the right edge of the drawing
22526 area. */
22527 if (s->extends_to_end_of_line_p)
22528 s->background_width = last_x - s->x + 1;
22529 else
22530 s->background_width = s->width;
22531 }
22532
22533
22534 /* Compute overhangs and x-positions for glyph string S and its
22535 predecessors, or successors. X is the starting x-position for S.
22536 BACKWARD_P non-zero means process predecessors. */
22537
22538 static void
22539 compute_overhangs_and_x (struct glyph_string *s, int x, int backward_p)
22540 {
22541 if (backward_p)
22542 {
22543 while (s)
22544 {
22545 if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
22546 FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
22547 x -= s->width;
22548 s->x = x;
22549 s = s->prev;
22550 }
22551 }
22552 else
22553 {
22554 while (s)
22555 {
22556 if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
22557 FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
22558 s->x = x;
22559 x += s->width;
22560 s = s->next;
22561 }
22562 }
22563 }
22564
22565
22566
22567 /* The following macros are only called from draw_glyphs below.
22568 They reference the following parameters of that function directly:
22569 `w', `row', `area', and `overlap_p'
22570 as well as the following local variables:
22571 `s', `f', and `hdc' (in W32) */
22572
22573 #ifdef HAVE_NTGUI
22574 /* On W32, silently add local `hdc' variable to argument list of
22575 init_glyph_string. */
22576 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
22577 init_glyph_string (s, hdc, char2b, w, row, area, start, hl)
22578 #else
22579 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
22580 init_glyph_string (s, char2b, w, row, area, start, hl)
22581 #endif
22582
22583 /* Add a glyph string for a stretch glyph to the list of strings
22584 between HEAD and TAIL. START is the index of the stretch glyph in
22585 row area AREA of glyph row ROW. END is the index of the last glyph
22586 in that glyph row area. X is the current output position assigned
22587 to the new glyph string constructed. HL overrides that face of the
22588 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
22589 is the right-most x-position of the drawing area. */
22590
22591 /* SunOS 4 bundled cc, barfed on continuations in the arg lists here
22592 and below -- keep them on one line. */
22593 #define BUILD_STRETCH_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
22594 do \
22595 { \
22596 s = (struct glyph_string *) alloca (sizeof *s); \
22597 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
22598 START = fill_stretch_glyph_string (s, START, END); \
22599 append_glyph_string (&HEAD, &TAIL, s); \
22600 s->x = (X); \
22601 } \
22602 while (0)
22603
22604
22605 /* Add a glyph string for an image glyph to the list of strings
22606 between HEAD and TAIL. START is the index of the image glyph in
22607 row area AREA of glyph row ROW. END is the index of the last glyph
22608 in that glyph row area. X is the current output position assigned
22609 to the new glyph string constructed. HL overrides that face of the
22610 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
22611 is the right-most x-position of the drawing area. */
22612
22613 #define BUILD_IMAGE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
22614 do \
22615 { \
22616 s = (struct glyph_string *) alloca (sizeof *s); \
22617 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
22618 fill_image_glyph_string (s); \
22619 append_glyph_string (&HEAD, &TAIL, s); \
22620 ++START; \
22621 s->x = (X); \
22622 } \
22623 while (0)
22624
22625
22626 /* Add a glyph string for a sequence of character glyphs to the list
22627 of strings between HEAD and TAIL. START is the index of the first
22628 glyph in row area AREA of glyph row ROW that is part of the new
22629 glyph string. END is the index of the last glyph in that glyph row
22630 area. X is the current output position assigned to the new glyph
22631 string constructed. HL overrides that face of the glyph; e.g. it
22632 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
22633 right-most x-position of the drawing area. */
22634
22635 #define BUILD_CHAR_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
22636 do \
22637 { \
22638 int face_id; \
22639 XChar2b *char2b; \
22640 \
22641 face_id = (row)->glyphs[area][START].face_id; \
22642 \
22643 s = (struct glyph_string *) alloca (sizeof *s); \
22644 char2b = (XChar2b *) alloca ((END - START) * sizeof *char2b); \
22645 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
22646 append_glyph_string (&HEAD, &TAIL, s); \
22647 s->x = (X); \
22648 START = fill_glyph_string (s, face_id, START, END, overlaps); \
22649 } \
22650 while (0)
22651
22652
22653 /* Add a glyph string for a composite sequence to the list of strings
22654 between HEAD and TAIL. START is the index of the first glyph in
22655 row area AREA of glyph row ROW that is part of the new glyph
22656 string. END is the index of the last glyph in that glyph row area.
22657 X is the current output position assigned to the new glyph string
22658 constructed. HL overrides that face of the glyph; e.g. it is
22659 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
22660 x-position of the drawing area. */
22661
22662 #define BUILD_COMPOSITE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
22663 do { \
22664 int face_id = (row)->glyphs[area][START].face_id; \
22665 struct face *base_face = FACE_FROM_ID (f, face_id); \
22666 ptrdiff_t cmp_id = (row)->glyphs[area][START].u.cmp.id; \
22667 struct composition *cmp = composition_table[cmp_id]; \
22668 XChar2b *char2b; \
22669 struct glyph_string *first_s IF_LINT (= NULL); \
22670 int n; \
22671 \
22672 char2b = (XChar2b *) alloca ((sizeof *char2b) * cmp->glyph_len); \
22673 \
22674 /* Make glyph_strings for each glyph sequence that is drawable by \
22675 the same face, and append them to HEAD/TAIL. */ \
22676 for (n = 0; n < cmp->glyph_len;) \
22677 { \
22678 s = (struct glyph_string *) alloca (sizeof *s); \
22679 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
22680 append_glyph_string (&(HEAD), &(TAIL), s); \
22681 s->cmp = cmp; \
22682 s->cmp_from = n; \
22683 s->x = (X); \
22684 if (n == 0) \
22685 first_s = s; \
22686 n = fill_composite_glyph_string (s, base_face, overlaps); \
22687 } \
22688 \
22689 ++START; \
22690 s = first_s; \
22691 } while (0)
22692
22693
22694 /* Add a glyph string for a glyph-string sequence to the list of strings
22695 between HEAD and TAIL. */
22696
22697 #define BUILD_GSTRING_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
22698 do { \
22699 int face_id; \
22700 XChar2b *char2b; \
22701 Lisp_Object gstring; \
22702 \
22703 face_id = (row)->glyphs[area][START].face_id; \
22704 gstring = (composition_gstring_from_id \
22705 ((row)->glyphs[area][START].u.cmp.id)); \
22706 s = (struct glyph_string *) alloca (sizeof *s); \
22707 char2b = (XChar2b *) alloca ((sizeof *char2b) \
22708 * LGSTRING_GLYPH_LEN (gstring)); \
22709 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
22710 append_glyph_string (&(HEAD), &(TAIL), s); \
22711 s->x = (X); \
22712 START = fill_gstring_glyph_string (s, face_id, START, END, overlaps); \
22713 } while (0)
22714
22715
22716 /* Add a glyph string for a sequence of glyphless character's glyphs
22717 to the list of strings between HEAD and TAIL. The meanings of
22718 arguments are the same as those of BUILD_CHAR_GLYPH_STRINGS. */
22719
22720 #define BUILD_GLYPHLESS_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
22721 do \
22722 { \
22723 int face_id; \
22724 \
22725 face_id = (row)->glyphs[area][START].face_id; \
22726 \
22727 s = (struct glyph_string *) alloca (sizeof *s); \
22728 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
22729 append_glyph_string (&HEAD, &TAIL, s); \
22730 s->x = (X); \
22731 START = fill_glyphless_glyph_string (s, face_id, START, END, \
22732 overlaps); \
22733 } \
22734 while (0)
22735
22736
22737 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
22738 of AREA of glyph row ROW on window W between indices START and END.
22739 HL overrides the face for drawing glyph strings, e.g. it is
22740 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
22741 x-positions of the drawing area.
22742
22743 This is an ugly monster macro construct because we must use alloca
22744 to allocate glyph strings (because draw_glyphs can be called
22745 asynchronously). */
22746
22747 #define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
22748 do \
22749 { \
22750 HEAD = TAIL = NULL; \
22751 while (START < END) \
22752 { \
22753 struct glyph *first_glyph = (row)->glyphs[area] + START; \
22754 switch (first_glyph->type) \
22755 { \
22756 case CHAR_GLYPH: \
22757 BUILD_CHAR_GLYPH_STRINGS (START, END, HEAD, TAIL, \
22758 HL, X, LAST_X); \
22759 break; \
22760 \
22761 case COMPOSITE_GLYPH: \
22762 if (first_glyph->u.cmp.automatic) \
22763 BUILD_GSTRING_GLYPH_STRING (START, END, HEAD, TAIL, \
22764 HL, X, LAST_X); \
22765 else \
22766 BUILD_COMPOSITE_GLYPH_STRING (START, END, HEAD, TAIL, \
22767 HL, X, LAST_X); \
22768 break; \
22769 \
22770 case STRETCH_GLYPH: \
22771 BUILD_STRETCH_GLYPH_STRING (START, END, HEAD, TAIL, \
22772 HL, X, LAST_X); \
22773 break; \
22774 \
22775 case IMAGE_GLYPH: \
22776 BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL, \
22777 HL, X, LAST_X); \
22778 break; \
22779 \
22780 case GLYPHLESS_GLYPH: \
22781 BUILD_GLYPHLESS_GLYPH_STRING (START, END, HEAD, TAIL, \
22782 HL, X, LAST_X); \
22783 break; \
22784 \
22785 default: \
22786 abort (); \
22787 } \
22788 \
22789 if (s) \
22790 { \
22791 set_glyph_string_background_width (s, START, LAST_X); \
22792 (X) += s->width; \
22793 } \
22794 } \
22795 } while (0)
22796
22797
22798 /* Draw glyphs between START and END in AREA of ROW on window W,
22799 starting at x-position X. X is relative to AREA in W. HL is a
22800 face-override with the following meaning:
22801
22802 DRAW_NORMAL_TEXT draw normally
22803 DRAW_CURSOR draw in cursor face
22804 DRAW_MOUSE_FACE draw in mouse face.
22805 DRAW_INVERSE_VIDEO draw in mode line face
22806 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
22807 DRAW_IMAGE_RAISED draw an image with a raised relief around it
22808
22809 If OVERLAPS is non-zero, draw only the foreground of characters and
22810 clip to the physical height of ROW. Non-zero value also defines
22811 the overlapping part to be drawn:
22812
22813 OVERLAPS_PRED overlap with preceding rows
22814 OVERLAPS_SUCC overlap with succeeding rows
22815 OVERLAPS_BOTH overlap with both preceding/succeeding rows
22816 OVERLAPS_ERASED_CURSOR overlap with erased cursor area
22817
22818 Value is the x-position reached, relative to AREA of W. */
22819
22820 static int
22821 draw_glyphs (struct window *w, int x, struct glyph_row *row,
22822 enum glyph_row_area area, EMACS_INT start, EMACS_INT end,
22823 enum draw_glyphs_face hl, int overlaps)
22824 {
22825 struct glyph_string *head, *tail;
22826 struct glyph_string *s;
22827 struct glyph_string *clip_head = NULL, *clip_tail = NULL;
22828 int i, j, x_reached, last_x, area_left = 0;
22829 struct frame *f = XFRAME (WINDOW_FRAME (w));
22830 DECLARE_HDC (hdc);
22831
22832 ALLOCATE_HDC (hdc, f);
22833
22834 /* Let's rather be paranoid than getting a SEGV. */
22835 end = min (end, row->used[area]);
22836 start = max (0, start);
22837 start = min (end, start);
22838
22839 /* Translate X to frame coordinates. Set last_x to the right
22840 end of the drawing area. */
22841 if (row->full_width_p)
22842 {
22843 /* X is relative to the left edge of W, without scroll bars
22844 or fringes. */
22845 area_left = WINDOW_LEFT_EDGE_X (w);
22846 last_x = WINDOW_LEFT_EDGE_X (w) + WINDOW_TOTAL_WIDTH (w);
22847 }
22848 else
22849 {
22850 area_left = window_box_left (w, area);
22851 last_x = area_left + window_box_width (w, area);
22852 }
22853 x += area_left;
22854
22855 /* Build a doubly-linked list of glyph_string structures between
22856 head and tail from what we have to draw. Note that the macro
22857 BUILD_GLYPH_STRINGS will modify its start parameter. That's
22858 the reason we use a separate variable `i'. */
22859 i = start;
22860 BUILD_GLYPH_STRINGS (i, end, head, tail, hl, x, last_x);
22861 if (tail)
22862 x_reached = tail->x + tail->background_width;
22863 else
22864 x_reached = x;
22865
22866 /* If there are any glyphs with lbearing < 0 or rbearing > width in
22867 the row, redraw some glyphs in front or following the glyph
22868 strings built above. */
22869 if (head && !overlaps && row->contains_overlapping_glyphs_p)
22870 {
22871 struct glyph_string *h, *t;
22872 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
22873 int mouse_beg_col IF_LINT (= 0), mouse_end_col IF_LINT (= 0);
22874 int check_mouse_face = 0;
22875 int dummy_x = 0;
22876
22877 /* If mouse highlighting is on, we may need to draw adjacent
22878 glyphs using mouse-face highlighting. */
22879 if (area == TEXT_AREA && row->mouse_face_p)
22880 {
22881 struct glyph_row *mouse_beg_row, *mouse_end_row;
22882
22883 mouse_beg_row = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_beg_row);
22884 mouse_end_row = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_end_row);
22885
22886 if (row >= mouse_beg_row && row <= mouse_end_row)
22887 {
22888 check_mouse_face = 1;
22889 mouse_beg_col = (row == mouse_beg_row)
22890 ? hlinfo->mouse_face_beg_col : 0;
22891 mouse_end_col = (row == mouse_end_row)
22892 ? hlinfo->mouse_face_end_col
22893 : row->used[TEXT_AREA];
22894 }
22895 }
22896
22897 /* Compute overhangs for all glyph strings. */
22898 if (FRAME_RIF (f)->compute_glyph_string_overhangs)
22899 for (s = head; s; s = s->next)
22900 FRAME_RIF (f)->compute_glyph_string_overhangs (s);
22901
22902 /* Prepend glyph strings for glyphs in front of the first glyph
22903 string that are overwritten because of the first glyph
22904 string's left overhang. The background of all strings
22905 prepended must be drawn because the first glyph string
22906 draws over it. */
22907 i = left_overwritten (head);
22908 if (i >= 0)
22909 {
22910 enum draw_glyphs_face overlap_hl;
22911
22912 /* If this row contains mouse highlighting, attempt to draw
22913 the overlapped glyphs with the correct highlight. This
22914 code fails if the overlap encompasses more than one glyph
22915 and mouse-highlight spans only some of these glyphs.
22916 However, making it work perfectly involves a lot more
22917 code, and I don't know if the pathological case occurs in
22918 practice, so we'll stick to this for now. --- cyd */
22919 if (check_mouse_face
22920 && mouse_beg_col < start && mouse_end_col > i)
22921 overlap_hl = DRAW_MOUSE_FACE;
22922 else
22923 overlap_hl = DRAW_NORMAL_TEXT;
22924
22925 j = i;
22926 BUILD_GLYPH_STRINGS (j, start, h, t,
22927 overlap_hl, dummy_x, last_x);
22928 start = i;
22929 compute_overhangs_and_x (t, head->x, 1);
22930 prepend_glyph_string_lists (&head, &tail, h, t);
22931 clip_head = head;
22932 }
22933
22934 /* Prepend glyph strings for glyphs in front of the first glyph
22935 string that overwrite that glyph string because of their
22936 right overhang. For these strings, only the foreground must
22937 be drawn, because it draws over the glyph string at `head'.
22938 The background must not be drawn because this would overwrite
22939 right overhangs of preceding glyphs for which no glyph
22940 strings exist. */
22941 i = left_overwriting (head);
22942 if (i >= 0)
22943 {
22944 enum draw_glyphs_face overlap_hl;
22945
22946 if (check_mouse_face
22947 && mouse_beg_col < start && mouse_end_col > i)
22948 overlap_hl = DRAW_MOUSE_FACE;
22949 else
22950 overlap_hl = DRAW_NORMAL_TEXT;
22951
22952 clip_head = head;
22953 BUILD_GLYPH_STRINGS (i, start, h, t,
22954 overlap_hl, dummy_x, last_x);
22955 for (s = h; s; s = s->next)
22956 s->background_filled_p = 1;
22957 compute_overhangs_and_x (t, head->x, 1);
22958 prepend_glyph_string_lists (&head, &tail, h, t);
22959 }
22960
22961 /* Append glyphs strings for glyphs following the last glyph
22962 string tail that are overwritten by tail. The background of
22963 these strings has to be drawn because tail's foreground draws
22964 over it. */
22965 i = right_overwritten (tail);
22966 if (i >= 0)
22967 {
22968 enum draw_glyphs_face overlap_hl;
22969
22970 if (check_mouse_face
22971 && mouse_beg_col < i && mouse_end_col > end)
22972 overlap_hl = DRAW_MOUSE_FACE;
22973 else
22974 overlap_hl = DRAW_NORMAL_TEXT;
22975
22976 BUILD_GLYPH_STRINGS (end, i, h, t,
22977 overlap_hl, x, last_x);
22978 /* Because BUILD_GLYPH_STRINGS updates the first argument,
22979 we don't have `end = i;' here. */
22980 compute_overhangs_and_x (h, tail->x + tail->width, 0);
22981 append_glyph_string_lists (&head, &tail, h, t);
22982 clip_tail = tail;
22983 }
22984
22985 /* Append glyph strings for glyphs following the last glyph
22986 string tail that overwrite tail. The foreground of such
22987 glyphs has to be drawn because it writes into the background
22988 of tail. The background must not be drawn because it could
22989 paint over the foreground of following glyphs. */
22990 i = right_overwriting (tail);
22991 if (i >= 0)
22992 {
22993 enum draw_glyphs_face overlap_hl;
22994 if (check_mouse_face
22995 && mouse_beg_col < i && mouse_end_col > end)
22996 overlap_hl = DRAW_MOUSE_FACE;
22997 else
22998 overlap_hl = DRAW_NORMAL_TEXT;
22999
23000 clip_tail = tail;
23001 i++; /* We must include the Ith glyph. */
23002 BUILD_GLYPH_STRINGS (end, i, h, t,
23003 overlap_hl, x, last_x);
23004 for (s = h; s; s = s->next)
23005 s->background_filled_p = 1;
23006 compute_overhangs_and_x (h, tail->x + tail->width, 0);
23007 append_glyph_string_lists (&head, &tail, h, t);
23008 }
23009 if (clip_head || clip_tail)
23010 for (s = head; s; s = s->next)
23011 {
23012 s->clip_head = clip_head;
23013 s->clip_tail = clip_tail;
23014 }
23015 }
23016
23017 /* Draw all strings. */
23018 for (s = head; s; s = s->next)
23019 FRAME_RIF (f)->draw_glyph_string (s);
23020
23021 #ifndef HAVE_NS
23022 /* When focus a sole frame and move horizontally, this sets on_p to 0
23023 causing a failure to erase prev cursor position. */
23024 if (area == TEXT_AREA
23025 && !row->full_width_p
23026 /* When drawing overlapping rows, only the glyph strings'
23027 foreground is drawn, which doesn't erase a cursor
23028 completely. */
23029 && !overlaps)
23030 {
23031 int x0 = clip_head ? clip_head->x : (head ? head->x : x);
23032 int x1 = (clip_tail ? clip_tail->x + clip_tail->background_width
23033 : (tail ? tail->x + tail->background_width : x));
23034 x0 -= area_left;
23035 x1 -= area_left;
23036
23037 notice_overwritten_cursor (w, TEXT_AREA, x0, x1,
23038 row->y, MATRIX_ROW_BOTTOM_Y (row));
23039 }
23040 #endif
23041
23042 /* Value is the x-position up to which drawn, relative to AREA of W.
23043 This doesn't include parts drawn because of overhangs. */
23044 if (row->full_width_p)
23045 x_reached = FRAME_TO_WINDOW_PIXEL_X (w, x_reached);
23046 else
23047 x_reached -= area_left;
23048
23049 RELEASE_HDC (hdc, f);
23050
23051 return x_reached;
23052 }
23053
23054 /* Expand row matrix if too narrow. Don't expand if area
23055 is not present. */
23056
23057 #define IT_EXPAND_MATRIX_WIDTH(it, area) \
23058 { \
23059 if (!fonts_changed_p \
23060 && (it->glyph_row->glyphs[area] \
23061 < it->glyph_row->glyphs[area + 1])) \
23062 { \
23063 it->w->ncols_scale_factor++; \
23064 fonts_changed_p = 1; \
23065 } \
23066 }
23067
23068 /* Store one glyph for IT->char_to_display in IT->glyph_row.
23069 Called from x_produce_glyphs when IT->glyph_row is non-null. */
23070
23071 static inline void
23072 append_glyph (struct it *it)
23073 {
23074 struct glyph *glyph;
23075 enum glyph_row_area area = it->area;
23076
23077 xassert (it->glyph_row);
23078 xassert (it->char_to_display != '\n' && it->char_to_display != '\t');
23079
23080 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
23081 if (glyph < it->glyph_row->glyphs[area + 1])
23082 {
23083 /* If the glyph row is reversed, we need to prepend the glyph
23084 rather than append it. */
23085 if (it->glyph_row->reversed_p && area == TEXT_AREA)
23086 {
23087 struct glyph *g;
23088
23089 /* Make room for the additional glyph. */
23090 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
23091 g[1] = *g;
23092 glyph = it->glyph_row->glyphs[area];
23093 }
23094 glyph->charpos = CHARPOS (it->position);
23095 glyph->object = it->object;
23096 if (it->pixel_width > 0)
23097 {
23098 glyph->pixel_width = it->pixel_width;
23099 glyph->padding_p = 0;
23100 }
23101 else
23102 {
23103 /* Assure at least 1-pixel width. Otherwise, cursor can't
23104 be displayed correctly. */
23105 glyph->pixel_width = 1;
23106 glyph->padding_p = 1;
23107 }
23108 glyph->ascent = it->ascent;
23109 glyph->descent = it->descent;
23110 glyph->voffset = it->voffset;
23111 glyph->type = CHAR_GLYPH;
23112 glyph->avoid_cursor_p = it->avoid_cursor_p;
23113 glyph->multibyte_p = it->multibyte_p;
23114 glyph->left_box_line_p = it->start_of_box_run_p;
23115 glyph->right_box_line_p = it->end_of_box_run_p;
23116 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
23117 || it->phys_descent > it->descent);
23118 glyph->glyph_not_available_p = it->glyph_not_available_p;
23119 glyph->face_id = it->face_id;
23120 glyph->u.ch = it->char_to_display;
23121 glyph->slice.img = null_glyph_slice;
23122 glyph->font_type = FONT_TYPE_UNKNOWN;
23123 if (it->bidi_p)
23124 {
23125 glyph->resolved_level = it->bidi_it.resolved_level;
23126 if ((it->bidi_it.type & 7) != it->bidi_it.type)
23127 abort ();
23128 glyph->bidi_type = it->bidi_it.type;
23129 }
23130 else
23131 {
23132 glyph->resolved_level = 0;
23133 glyph->bidi_type = UNKNOWN_BT;
23134 }
23135 ++it->glyph_row->used[area];
23136 }
23137 else
23138 IT_EXPAND_MATRIX_WIDTH (it, area);
23139 }
23140
23141 /* Store one glyph for the composition IT->cmp_it.id in
23142 IT->glyph_row. Called from x_produce_glyphs when IT->glyph_row is
23143 non-null. */
23144
23145 static inline void
23146 append_composite_glyph (struct it *it)
23147 {
23148 struct glyph *glyph;
23149 enum glyph_row_area area = it->area;
23150
23151 xassert (it->glyph_row);
23152
23153 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
23154 if (glyph < it->glyph_row->glyphs[area + 1])
23155 {
23156 /* If the glyph row is reversed, we need to prepend the glyph
23157 rather than append it. */
23158 if (it->glyph_row->reversed_p && it->area == TEXT_AREA)
23159 {
23160 struct glyph *g;
23161
23162 /* Make room for the new glyph. */
23163 for (g = glyph - 1; g >= it->glyph_row->glyphs[it->area]; g--)
23164 g[1] = *g;
23165 glyph = it->glyph_row->glyphs[it->area];
23166 }
23167 glyph->charpos = it->cmp_it.charpos;
23168 glyph->object = it->object;
23169 glyph->pixel_width = it->pixel_width;
23170 glyph->ascent = it->ascent;
23171 glyph->descent = it->descent;
23172 glyph->voffset = it->voffset;
23173 glyph->type = COMPOSITE_GLYPH;
23174 if (it->cmp_it.ch < 0)
23175 {
23176 glyph->u.cmp.automatic = 0;
23177 glyph->u.cmp.id = it->cmp_it.id;
23178 glyph->slice.cmp.from = glyph->slice.cmp.to = 0;
23179 }
23180 else
23181 {
23182 glyph->u.cmp.automatic = 1;
23183 glyph->u.cmp.id = it->cmp_it.id;
23184 glyph->slice.cmp.from = it->cmp_it.from;
23185 glyph->slice.cmp.to = it->cmp_it.to - 1;
23186 }
23187 glyph->avoid_cursor_p = it->avoid_cursor_p;
23188 glyph->multibyte_p = it->multibyte_p;
23189 glyph->left_box_line_p = it->start_of_box_run_p;
23190 glyph->right_box_line_p = it->end_of_box_run_p;
23191 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
23192 || it->phys_descent > it->descent);
23193 glyph->padding_p = 0;
23194 glyph->glyph_not_available_p = 0;
23195 glyph->face_id = it->face_id;
23196 glyph->font_type = FONT_TYPE_UNKNOWN;
23197 if (it->bidi_p)
23198 {
23199 glyph->resolved_level = it->bidi_it.resolved_level;
23200 if ((it->bidi_it.type & 7) != it->bidi_it.type)
23201 abort ();
23202 glyph->bidi_type = it->bidi_it.type;
23203 }
23204 ++it->glyph_row->used[area];
23205 }
23206 else
23207 IT_EXPAND_MATRIX_WIDTH (it, area);
23208 }
23209
23210
23211 /* Change IT->ascent and IT->height according to the setting of
23212 IT->voffset. */
23213
23214 static inline void
23215 take_vertical_position_into_account (struct it *it)
23216 {
23217 if (it->voffset)
23218 {
23219 if (it->voffset < 0)
23220 /* Increase the ascent so that we can display the text higher
23221 in the line. */
23222 it->ascent -= it->voffset;
23223 else
23224 /* Increase the descent so that we can display the text lower
23225 in the line. */
23226 it->descent += it->voffset;
23227 }
23228 }
23229
23230
23231 /* Produce glyphs/get display metrics for the image IT is loaded with.
23232 See the description of struct display_iterator in dispextern.h for
23233 an overview of struct display_iterator. */
23234
23235 static void
23236 produce_image_glyph (struct it *it)
23237 {
23238 struct image *img;
23239 struct face *face;
23240 int glyph_ascent, crop;
23241 struct glyph_slice slice;
23242
23243 xassert (it->what == IT_IMAGE);
23244
23245 face = FACE_FROM_ID (it->f, it->face_id);
23246 xassert (face);
23247 /* Make sure X resources of the face is loaded. */
23248 PREPARE_FACE_FOR_DISPLAY (it->f, face);
23249
23250 if (it->image_id < 0)
23251 {
23252 /* Fringe bitmap. */
23253 it->ascent = it->phys_ascent = 0;
23254 it->descent = it->phys_descent = 0;
23255 it->pixel_width = 0;
23256 it->nglyphs = 0;
23257 return;
23258 }
23259
23260 img = IMAGE_FROM_ID (it->f, it->image_id);
23261 xassert (img);
23262 /* Make sure X resources of the image is loaded. */
23263 prepare_image_for_display (it->f, img);
23264
23265 slice.x = slice.y = 0;
23266 slice.width = img->width;
23267 slice.height = img->height;
23268
23269 if (INTEGERP (it->slice.x))
23270 slice.x = XINT (it->slice.x);
23271 else if (FLOATP (it->slice.x))
23272 slice.x = XFLOAT_DATA (it->slice.x) * img->width;
23273
23274 if (INTEGERP (it->slice.y))
23275 slice.y = XINT (it->slice.y);
23276 else if (FLOATP (it->slice.y))
23277 slice.y = XFLOAT_DATA (it->slice.y) * img->height;
23278
23279 if (INTEGERP (it->slice.width))
23280 slice.width = XINT (it->slice.width);
23281 else if (FLOATP (it->slice.width))
23282 slice.width = XFLOAT_DATA (it->slice.width) * img->width;
23283
23284 if (INTEGERP (it->slice.height))
23285 slice.height = XINT (it->slice.height);
23286 else if (FLOATP (it->slice.height))
23287 slice.height = XFLOAT_DATA (it->slice.height) * img->height;
23288
23289 if (slice.x >= img->width)
23290 slice.x = img->width;
23291 if (slice.y >= img->height)
23292 slice.y = img->height;
23293 if (slice.x + slice.width >= img->width)
23294 slice.width = img->width - slice.x;
23295 if (slice.y + slice.height > img->height)
23296 slice.height = img->height - slice.y;
23297
23298 if (slice.width == 0 || slice.height == 0)
23299 return;
23300
23301 it->ascent = it->phys_ascent = glyph_ascent = image_ascent (img, face, &slice);
23302
23303 it->descent = slice.height - glyph_ascent;
23304 if (slice.y == 0)
23305 it->descent += img->vmargin;
23306 if (slice.y + slice.height == img->height)
23307 it->descent += img->vmargin;
23308 it->phys_descent = it->descent;
23309
23310 it->pixel_width = slice.width;
23311 if (slice.x == 0)
23312 it->pixel_width += img->hmargin;
23313 if (slice.x + slice.width == img->width)
23314 it->pixel_width += img->hmargin;
23315
23316 /* It's quite possible for images to have an ascent greater than
23317 their height, so don't get confused in that case. */
23318 if (it->descent < 0)
23319 it->descent = 0;
23320
23321 it->nglyphs = 1;
23322
23323 if (face->box != FACE_NO_BOX)
23324 {
23325 if (face->box_line_width > 0)
23326 {
23327 if (slice.y == 0)
23328 it->ascent += face->box_line_width;
23329 if (slice.y + slice.height == img->height)
23330 it->descent += face->box_line_width;
23331 }
23332
23333 if (it->start_of_box_run_p && slice.x == 0)
23334 it->pixel_width += eabs (face->box_line_width);
23335 if (it->end_of_box_run_p && slice.x + slice.width == img->width)
23336 it->pixel_width += eabs (face->box_line_width);
23337 }
23338
23339 take_vertical_position_into_account (it);
23340
23341 /* Automatically crop wide image glyphs at right edge so we can
23342 draw the cursor on same display row. */
23343 if ((crop = it->pixel_width - (it->last_visible_x - it->current_x), crop > 0)
23344 && (it->hpos == 0 || it->pixel_width > it->last_visible_x / 4))
23345 {
23346 it->pixel_width -= crop;
23347 slice.width -= crop;
23348 }
23349
23350 if (it->glyph_row)
23351 {
23352 struct glyph *glyph;
23353 enum glyph_row_area area = it->area;
23354
23355 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
23356 if (glyph < it->glyph_row->glyphs[area + 1])
23357 {
23358 glyph->charpos = CHARPOS (it->position);
23359 glyph->object = it->object;
23360 glyph->pixel_width = it->pixel_width;
23361 glyph->ascent = glyph_ascent;
23362 glyph->descent = it->descent;
23363 glyph->voffset = it->voffset;
23364 glyph->type = IMAGE_GLYPH;
23365 glyph->avoid_cursor_p = it->avoid_cursor_p;
23366 glyph->multibyte_p = it->multibyte_p;
23367 glyph->left_box_line_p = it->start_of_box_run_p;
23368 glyph->right_box_line_p = it->end_of_box_run_p;
23369 glyph->overlaps_vertically_p = 0;
23370 glyph->padding_p = 0;
23371 glyph->glyph_not_available_p = 0;
23372 glyph->face_id = it->face_id;
23373 glyph->u.img_id = img->id;
23374 glyph->slice.img = slice;
23375 glyph->font_type = FONT_TYPE_UNKNOWN;
23376 if (it->bidi_p)
23377 {
23378 glyph->resolved_level = it->bidi_it.resolved_level;
23379 if ((it->bidi_it.type & 7) != it->bidi_it.type)
23380 abort ();
23381 glyph->bidi_type = it->bidi_it.type;
23382 }
23383 ++it->glyph_row->used[area];
23384 }
23385 else
23386 IT_EXPAND_MATRIX_WIDTH (it, area);
23387 }
23388 }
23389
23390
23391 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
23392 of the glyph, WIDTH and HEIGHT are the width and height of the
23393 stretch. ASCENT is the ascent of the glyph (0 <= ASCENT <= HEIGHT). */
23394
23395 static void
23396 append_stretch_glyph (struct it *it, Lisp_Object object,
23397 int width, int height, int ascent)
23398 {
23399 struct glyph *glyph;
23400 enum glyph_row_area area = it->area;
23401
23402 xassert (ascent >= 0 && ascent <= height);
23403
23404 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
23405 if (glyph < it->glyph_row->glyphs[area + 1])
23406 {
23407 /* If the glyph row is reversed, we need to prepend the glyph
23408 rather than append it. */
23409 if (it->glyph_row->reversed_p && area == TEXT_AREA)
23410 {
23411 struct glyph *g;
23412
23413 /* Make room for the additional glyph. */
23414 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
23415 g[1] = *g;
23416 glyph = it->glyph_row->glyphs[area];
23417 }
23418 glyph->charpos = CHARPOS (it->position);
23419 glyph->object = object;
23420 glyph->pixel_width = width;
23421 glyph->ascent = ascent;
23422 glyph->descent = height - ascent;
23423 glyph->voffset = it->voffset;
23424 glyph->type = STRETCH_GLYPH;
23425 glyph->avoid_cursor_p = it->avoid_cursor_p;
23426 glyph->multibyte_p = it->multibyte_p;
23427 glyph->left_box_line_p = it->start_of_box_run_p;
23428 glyph->right_box_line_p = it->end_of_box_run_p;
23429 glyph->overlaps_vertically_p = 0;
23430 glyph->padding_p = 0;
23431 glyph->glyph_not_available_p = 0;
23432 glyph->face_id = it->face_id;
23433 glyph->u.stretch.ascent = ascent;
23434 glyph->u.stretch.height = height;
23435 glyph->slice.img = null_glyph_slice;
23436 glyph->font_type = FONT_TYPE_UNKNOWN;
23437 if (it->bidi_p)
23438 {
23439 glyph->resolved_level = it->bidi_it.resolved_level;
23440 if ((it->bidi_it.type & 7) != it->bidi_it.type)
23441 abort ();
23442 glyph->bidi_type = it->bidi_it.type;
23443 }
23444 else
23445 {
23446 glyph->resolved_level = 0;
23447 glyph->bidi_type = UNKNOWN_BT;
23448 }
23449 ++it->glyph_row->used[area];
23450 }
23451 else
23452 IT_EXPAND_MATRIX_WIDTH (it, area);
23453 }
23454
23455 #endif /* HAVE_WINDOW_SYSTEM */
23456
23457 /* Produce a stretch glyph for iterator IT. IT->object is the value
23458 of the glyph property displayed. The value must be a list
23459 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
23460 being recognized:
23461
23462 1. `:width WIDTH' specifies that the space should be WIDTH *
23463 canonical char width wide. WIDTH may be an integer or floating
23464 point number.
23465
23466 2. `:relative-width FACTOR' specifies that the width of the stretch
23467 should be computed from the width of the first character having the
23468 `glyph' property, and should be FACTOR times that width.
23469
23470 3. `:align-to HPOS' specifies that the space should be wide enough
23471 to reach HPOS, a value in canonical character units.
23472
23473 Exactly one of the above pairs must be present.
23474
23475 4. `:height HEIGHT' specifies that the height of the stretch produced
23476 should be HEIGHT, measured in canonical character units.
23477
23478 5. `:relative-height FACTOR' specifies that the height of the
23479 stretch should be FACTOR times the height of the characters having
23480 the glyph property.
23481
23482 Either none or exactly one of 4 or 5 must be present.
23483
23484 6. `:ascent ASCENT' specifies that ASCENT percent of the height
23485 of the stretch should be used for the ascent of the stretch.
23486 ASCENT must be in the range 0 <= ASCENT <= 100. */
23487
23488 void
23489 produce_stretch_glyph (struct it *it)
23490 {
23491 /* (space :width WIDTH :height HEIGHT ...) */
23492 Lisp_Object prop, plist;
23493 int width = 0, height = 0, align_to = -1;
23494 int zero_width_ok_p = 0;
23495 int ascent = 0;
23496 double tem;
23497 struct face *face = NULL;
23498 struct font *font = NULL;
23499
23500 #ifdef HAVE_WINDOW_SYSTEM
23501 int zero_height_ok_p = 0;
23502
23503 if (FRAME_WINDOW_P (it->f))
23504 {
23505 face = FACE_FROM_ID (it->f, it->face_id);
23506 font = face->font ? face->font : FRAME_FONT (it->f);
23507 PREPARE_FACE_FOR_DISPLAY (it->f, face);
23508 }
23509 #endif
23510
23511 /* List should start with `space'. */
23512 xassert (CONSP (it->object) && EQ (XCAR (it->object), Qspace));
23513 plist = XCDR (it->object);
23514
23515 /* Compute the width of the stretch. */
23516 if ((prop = Fplist_get (plist, QCwidth), !NILP (prop))
23517 && calc_pixel_width_or_height (&tem, it, prop, font, 1, 0))
23518 {
23519 /* Absolute width `:width WIDTH' specified and valid. */
23520 zero_width_ok_p = 1;
23521 width = (int)tem;
23522 }
23523 #ifdef HAVE_WINDOW_SYSTEM
23524 else if (FRAME_WINDOW_P (it->f)
23525 && (prop = Fplist_get (plist, QCrelative_width), NUMVAL (prop) > 0))
23526 {
23527 /* Relative width `:relative-width FACTOR' specified and valid.
23528 Compute the width of the characters having the `glyph'
23529 property. */
23530 struct it it2;
23531 unsigned char *p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
23532
23533 it2 = *it;
23534 if (it->multibyte_p)
23535 it2.c = it2.char_to_display = STRING_CHAR_AND_LENGTH (p, it2.len);
23536 else
23537 {
23538 it2.c = it2.char_to_display = *p, it2.len = 1;
23539 if (! ASCII_CHAR_P (it2.c))
23540 it2.char_to_display = BYTE8_TO_CHAR (it2.c);
23541 }
23542
23543 it2.glyph_row = NULL;
23544 it2.what = IT_CHARACTER;
23545 x_produce_glyphs (&it2);
23546 width = NUMVAL (prop) * it2.pixel_width;
23547 }
23548 #endif /* HAVE_WINDOW_SYSTEM */
23549 else if ((prop = Fplist_get (plist, QCalign_to), !NILP (prop))
23550 && calc_pixel_width_or_height (&tem, it, prop, font, 1, &align_to))
23551 {
23552 if (it->glyph_row == NULL || !it->glyph_row->mode_line_p)
23553 align_to = (align_to < 0
23554 ? 0
23555 : align_to - window_box_left_offset (it->w, TEXT_AREA));
23556 else if (align_to < 0)
23557 align_to = window_box_left_offset (it->w, TEXT_AREA);
23558 width = max (0, (int)tem + align_to - it->current_x);
23559 zero_width_ok_p = 1;
23560 }
23561 else
23562 /* Nothing specified -> width defaults to canonical char width. */
23563 width = FRAME_COLUMN_WIDTH (it->f);
23564
23565 if (width <= 0 && (width < 0 || !zero_width_ok_p))
23566 width = 1;
23567
23568 #ifdef HAVE_WINDOW_SYSTEM
23569 /* Compute height. */
23570 if (FRAME_WINDOW_P (it->f))
23571 {
23572 if ((prop = Fplist_get (plist, QCheight), !NILP (prop))
23573 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
23574 {
23575 height = (int)tem;
23576 zero_height_ok_p = 1;
23577 }
23578 else if (prop = Fplist_get (plist, QCrelative_height),
23579 NUMVAL (prop) > 0)
23580 height = FONT_HEIGHT (font) * NUMVAL (prop);
23581 else
23582 height = FONT_HEIGHT (font);
23583
23584 if (height <= 0 && (height < 0 || !zero_height_ok_p))
23585 height = 1;
23586
23587 /* Compute percentage of height used for ascent. If
23588 `:ascent ASCENT' is present and valid, use that. Otherwise,
23589 derive the ascent from the font in use. */
23590 if (prop = Fplist_get (plist, QCascent),
23591 NUMVAL (prop) > 0 && NUMVAL (prop) <= 100)
23592 ascent = height * NUMVAL (prop) / 100.0;
23593 else if (!NILP (prop)
23594 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
23595 ascent = min (max (0, (int)tem), height);
23596 else
23597 ascent = (height * FONT_BASE (font)) / FONT_HEIGHT (font);
23598 }
23599 else
23600 #endif /* HAVE_WINDOW_SYSTEM */
23601 height = 1;
23602
23603 if (width > 0 && it->line_wrap != TRUNCATE
23604 && it->current_x + width > it->last_visible_x)
23605 {
23606 width = it->last_visible_x - it->current_x;
23607 #ifdef HAVE_WINDOW_SYSTEM
23608 /* Subtact one more pixel from the stretch width, but only on
23609 GUI frames, since on a TTY each glyph is one "pixel" wide. */
23610 width -= FRAME_WINDOW_P (it->f);
23611 #endif
23612 }
23613
23614 if (width > 0 && height > 0 && it->glyph_row)
23615 {
23616 Lisp_Object o_object = it->object;
23617 Lisp_Object object = it->stack[it->sp - 1].string;
23618 int n = width;
23619
23620 if (!STRINGP (object))
23621 object = it->w->buffer;
23622 #ifdef HAVE_WINDOW_SYSTEM
23623 if (FRAME_WINDOW_P (it->f))
23624 append_stretch_glyph (it, object, width, height, ascent);
23625 else
23626 #endif
23627 {
23628 it->object = object;
23629 it->char_to_display = ' ';
23630 it->pixel_width = it->len = 1;
23631 while (n--)
23632 tty_append_glyph (it);
23633 it->object = o_object;
23634 }
23635 }
23636
23637 it->pixel_width = width;
23638 #ifdef HAVE_WINDOW_SYSTEM
23639 if (FRAME_WINDOW_P (it->f))
23640 {
23641 it->ascent = it->phys_ascent = ascent;
23642 it->descent = it->phys_descent = height - it->ascent;
23643 it->nglyphs = width > 0 && height > 0 ? 1 : 0;
23644 take_vertical_position_into_account (it);
23645 }
23646 else
23647 #endif
23648 it->nglyphs = width;
23649 }
23650
23651 #ifdef HAVE_WINDOW_SYSTEM
23652
23653 /* Calculate line-height and line-spacing properties.
23654 An integer value specifies explicit pixel value.
23655 A float value specifies relative value to current face height.
23656 A cons (float . face-name) specifies relative value to
23657 height of specified face font.
23658
23659 Returns height in pixels, or nil. */
23660
23661
23662 static Lisp_Object
23663 calc_line_height_property (struct it *it, Lisp_Object val, struct font *font,
23664 int boff, int override)
23665 {
23666 Lisp_Object face_name = Qnil;
23667 int ascent, descent, height;
23668
23669 if (NILP (val) || INTEGERP (val) || (override && EQ (val, Qt)))
23670 return val;
23671
23672 if (CONSP (val))
23673 {
23674 face_name = XCAR (val);
23675 val = XCDR (val);
23676 if (!NUMBERP (val))
23677 val = make_number (1);
23678 if (NILP (face_name))
23679 {
23680 height = it->ascent + it->descent;
23681 goto scale;
23682 }
23683 }
23684
23685 if (NILP (face_name))
23686 {
23687 font = FRAME_FONT (it->f);
23688 boff = FRAME_BASELINE_OFFSET (it->f);
23689 }
23690 else if (EQ (face_name, Qt))
23691 {
23692 override = 0;
23693 }
23694 else
23695 {
23696 int face_id;
23697 struct face *face;
23698
23699 face_id = lookup_named_face (it->f, face_name, 0);
23700 if (face_id < 0)
23701 return make_number (-1);
23702
23703 face = FACE_FROM_ID (it->f, face_id);
23704 font = face->font;
23705 if (font == NULL)
23706 return make_number (-1);
23707 boff = font->baseline_offset;
23708 if (font->vertical_centering)
23709 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
23710 }
23711
23712 ascent = FONT_BASE (font) + boff;
23713 descent = FONT_DESCENT (font) - boff;
23714
23715 if (override)
23716 {
23717 it->override_ascent = ascent;
23718 it->override_descent = descent;
23719 it->override_boff = boff;
23720 }
23721
23722 height = ascent + descent;
23723
23724 scale:
23725 if (FLOATP (val))
23726 height = (int)(XFLOAT_DATA (val) * height);
23727 else if (INTEGERP (val))
23728 height *= XINT (val);
23729
23730 return make_number (height);
23731 }
23732
23733
23734 /* Append a glyph for a glyphless character to IT->glyph_row. FACE_ID
23735 is a face ID to be used for the glyph. FOR_NO_FONT is nonzero if
23736 and only if this is for a character for which no font was found.
23737
23738 If the display method (it->glyphless_method) is
23739 GLYPHLESS_DISPLAY_ACRONYM or GLYPHLESS_DISPLAY_HEX_CODE, LEN is a
23740 length of the acronym or the hexadecimal string, UPPER_XOFF and
23741 UPPER_YOFF are pixel offsets for the upper part of the string,
23742 LOWER_XOFF and LOWER_YOFF are for the lower part.
23743
23744 For the other display methods, LEN through LOWER_YOFF are zero. */
23745
23746 static void
23747 append_glyphless_glyph (struct it *it, int face_id, int for_no_font, int len,
23748 short upper_xoff, short upper_yoff,
23749 short lower_xoff, short lower_yoff)
23750 {
23751 struct glyph *glyph;
23752 enum glyph_row_area area = it->area;
23753
23754 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
23755 if (glyph < it->glyph_row->glyphs[area + 1])
23756 {
23757 /* If the glyph row is reversed, we need to prepend the glyph
23758 rather than append it. */
23759 if (it->glyph_row->reversed_p && area == TEXT_AREA)
23760 {
23761 struct glyph *g;
23762
23763 /* Make room for the additional glyph. */
23764 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
23765 g[1] = *g;
23766 glyph = it->glyph_row->glyphs[area];
23767 }
23768 glyph->charpos = CHARPOS (it->position);
23769 glyph->object = it->object;
23770 glyph->pixel_width = it->pixel_width;
23771 glyph->ascent = it->ascent;
23772 glyph->descent = it->descent;
23773 glyph->voffset = it->voffset;
23774 glyph->type = GLYPHLESS_GLYPH;
23775 glyph->u.glyphless.method = it->glyphless_method;
23776 glyph->u.glyphless.for_no_font = for_no_font;
23777 glyph->u.glyphless.len = len;
23778 glyph->u.glyphless.ch = it->c;
23779 glyph->slice.glyphless.upper_xoff = upper_xoff;
23780 glyph->slice.glyphless.upper_yoff = upper_yoff;
23781 glyph->slice.glyphless.lower_xoff = lower_xoff;
23782 glyph->slice.glyphless.lower_yoff = lower_yoff;
23783 glyph->avoid_cursor_p = it->avoid_cursor_p;
23784 glyph->multibyte_p = it->multibyte_p;
23785 glyph->left_box_line_p = it->start_of_box_run_p;
23786 glyph->right_box_line_p = it->end_of_box_run_p;
23787 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
23788 || it->phys_descent > it->descent);
23789 glyph->padding_p = 0;
23790 glyph->glyph_not_available_p = 0;
23791 glyph->face_id = face_id;
23792 glyph->font_type = FONT_TYPE_UNKNOWN;
23793 if (it->bidi_p)
23794 {
23795 glyph->resolved_level = it->bidi_it.resolved_level;
23796 if ((it->bidi_it.type & 7) != it->bidi_it.type)
23797 abort ();
23798 glyph->bidi_type = it->bidi_it.type;
23799 }
23800 ++it->glyph_row->used[area];
23801 }
23802 else
23803 IT_EXPAND_MATRIX_WIDTH (it, area);
23804 }
23805
23806
23807 /* Produce a glyph for a glyphless character for iterator IT.
23808 IT->glyphless_method specifies which method to use for displaying
23809 the character. See the description of enum
23810 glyphless_display_method in dispextern.h for the detail.
23811
23812 FOR_NO_FONT is nonzero if and only if this is for a character for
23813 which no font was found. ACRONYM, if non-nil, is an acronym string
23814 for the character. */
23815
23816 static void
23817 produce_glyphless_glyph (struct it *it, int for_no_font, Lisp_Object acronym)
23818 {
23819 int face_id;
23820 struct face *face;
23821 struct font *font;
23822 int base_width, base_height, width, height;
23823 short upper_xoff, upper_yoff, lower_xoff, lower_yoff;
23824 int len;
23825
23826 /* Get the metrics of the base font. We always refer to the current
23827 ASCII face. */
23828 face = FACE_FROM_ID (it->f, it->face_id)->ascii_face;
23829 font = face->font ? face->font : FRAME_FONT (it->f);
23830 it->ascent = FONT_BASE (font) + font->baseline_offset;
23831 it->descent = FONT_DESCENT (font) - font->baseline_offset;
23832 base_height = it->ascent + it->descent;
23833 base_width = font->average_width;
23834
23835 /* Get a face ID for the glyph by utilizing a cache (the same way as
23836 done for `escape-glyph' in get_next_display_element). */
23837 if (it->f == last_glyphless_glyph_frame
23838 && it->face_id == last_glyphless_glyph_face_id)
23839 {
23840 face_id = last_glyphless_glyph_merged_face_id;
23841 }
23842 else
23843 {
23844 /* Merge the `glyphless-char' face into the current face. */
23845 face_id = merge_faces (it->f, Qglyphless_char, 0, it->face_id);
23846 last_glyphless_glyph_frame = it->f;
23847 last_glyphless_glyph_face_id = it->face_id;
23848 last_glyphless_glyph_merged_face_id = face_id;
23849 }
23850
23851 if (it->glyphless_method == GLYPHLESS_DISPLAY_THIN_SPACE)
23852 {
23853 it->pixel_width = THIN_SPACE_WIDTH;
23854 len = 0;
23855 upper_xoff = upper_yoff = lower_xoff = lower_yoff = 0;
23856 }
23857 else if (it->glyphless_method == GLYPHLESS_DISPLAY_EMPTY_BOX)
23858 {
23859 width = CHAR_WIDTH (it->c);
23860 if (width == 0)
23861 width = 1;
23862 else if (width > 4)
23863 width = 4;
23864 it->pixel_width = base_width * width;
23865 len = 0;
23866 upper_xoff = upper_yoff = lower_xoff = lower_yoff = 0;
23867 }
23868 else
23869 {
23870 char buf[7];
23871 const char *str;
23872 unsigned int code[6];
23873 int upper_len;
23874 int ascent, descent;
23875 struct font_metrics metrics_upper, metrics_lower;
23876
23877 face = FACE_FROM_ID (it->f, face_id);
23878 font = face->font ? face->font : FRAME_FONT (it->f);
23879 PREPARE_FACE_FOR_DISPLAY (it->f, face);
23880
23881 if (it->glyphless_method == GLYPHLESS_DISPLAY_ACRONYM)
23882 {
23883 if (! STRINGP (acronym) && CHAR_TABLE_P (Vglyphless_char_display))
23884 acronym = CHAR_TABLE_REF (Vglyphless_char_display, it->c);
23885 if (CONSP (acronym))
23886 acronym = XCAR (acronym);
23887 str = STRINGP (acronym) ? SSDATA (acronym) : "";
23888 }
23889 else
23890 {
23891 xassert (it->glyphless_method == GLYPHLESS_DISPLAY_HEX_CODE);
23892 sprintf (buf, "%0*X", it->c < 0x10000 ? 4 : 6, it->c);
23893 str = buf;
23894 }
23895 for (len = 0; str[len] && ASCII_BYTE_P (str[len]); len++)
23896 code[len] = font->driver->encode_char (font, str[len]);
23897 upper_len = (len + 1) / 2;
23898 font->driver->text_extents (font, code, upper_len,
23899 &metrics_upper);
23900 font->driver->text_extents (font, code + upper_len, len - upper_len,
23901 &metrics_lower);
23902
23903
23904
23905 /* +4 is for vertical bars of a box plus 1-pixel spaces at both side. */
23906 width = max (metrics_upper.width, metrics_lower.width) + 4;
23907 upper_xoff = upper_yoff = 2; /* the typical case */
23908 if (base_width >= width)
23909 {
23910 /* Align the upper to the left, the lower to the right. */
23911 it->pixel_width = base_width;
23912 lower_xoff = base_width - 2 - metrics_lower.width;
23913 }
23914 else
23915 {
23916 /* Center the shorter one. */
23917 it->pixel_width = width;
23918 if (metrics_upper.width >= metrics_lower.width)
23919 lower_xoff = (width - metrics_lower.width) / 2;
23920 else
23921 {
23922 /* FIXME: This code doesn't look right. It formerly was
23923 missing the "lower_xoff = 0;", which couldn't have
23924 been right since it left lower_xoff uninitialized. */
23925 lower_xoff = 0;
23926 upper_xoff = (width - metrics_upper.width) / 2;
23927 }
23928 }
23929
23930 /* +5 is for horizontal bars of a box plus 1-pixel spaces at
23931 top, bottom, and between upper and lower strings. */
23932 height = (metrics_upper.ascent + metrics_upper.descent
23933 + metrics_lower.ascent + metrics_lower.descent) + 5;
23934 /* Center vertically.
23935 H:base_height, D:base_descent
23936 h:height, ld:lower_descent, la:lower_ascent, ud:upper_descent
23937
23938 ascent = - (D - H/2 - h/2 + 1); "+ 1" for rounding up
23939 descent = D - H/2 + h/2;
23940 lower_yoff = descent - 2 - ld;
23941 upper_yoff = lower_yoff - la - 1 - ud; */
23942 ascent = - (it->descent - (base_height + height + 1) / 2);
23943 descent = it->descent - (base_height - height) / 2;
23944 lower_yoff = descent - 2 - metrics_lower.descent;
23945 upper_yoff = (lower_yoff - metrics_lower.ascent - 1
23946 - metrics_upper.descent);
23947 /* Don't make the height shorter than the base height. */
23948 if (height > base_height)
23949 {
23950 it->ascent = ascent;
23951 it->descent = descent;
23952 }
23953 }
23954
23955 it->phys_ascent = it->ascent;
23956 it->phys_descent = it->descent;
23957 if (it->glyph_row)
23958 append_glyphless_glyph (it, face_id, for_no_font, len,
23959 upper_xoff, upper_yoff,
23960 lower_xoff, lower_yoff);
23961 it->nglyphs = 1;
23962 take_vertical_position_into_account (it);
23963 }
23964
23965
23966 /* RIF:
23967 Produce glyphs/get display metrics for the display element IT is
23968 loaded with. See the description of struct it in dispextern.h
23969 for an overview of struct it. */
23970
23971 void
23972 x_produce_glyphs (struct it *it)
23973 {
23974 int extra_line_spacing = it->extra_line_spacing;
23975
23976 it->glyph_not_available_p = 0;
23977
23978 if (it->what == IT_CHARACTER)
23979 {
23980 XChar2b char2b;
23981 struct face *face = FACE_FROM_ID (it->f, it->face_id);
23982 struct font *font = face->font;
23983 struct font_metrics *pcm = NULL;
23984 int boff; /* baseline offset */
23985
23986 if (font == NULL)
23987 {
23988 /* When no suitable font is found, display this character by
23989 the method specified in the first extra slot of
23990 Vglyphless_char_display. */
23991 Lisp_Object acronym = lookup_glyphless_char_display (-1, it);
23992
23993 xassert (it->what == IT_GLYPHLESS);
23994 produce_glyphless_glyph (it, 1, STRINGP (acronym) ? acronym : Qnil);
23995 goto done;
23996 }
23997
23998 boff = font->baseline_offset;
23999 if (font->vertical_centering)
24000 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
24001
24002 if (it->char_to_display != '\n' && it->char_to_display != '\t')
24003 {
24004 int stretched_p;
24005
24006 it->nglyphs = 1;
24007
24008 if (it->override_ascent >= 0)
24009 {
24010 it->ascent = it->override_ascent;
24011 it->descent = it->override_descent;
24012 boff = it->override_boff;
24013 }
24014 else
24015 {
24016 it->ascent = FONT_BASE (font) + boff;
24017 it->descent = FONT_DESCENT (font) - boff;
24018 }
24019
24020 if (get_char_glyph_code (it->char_to_display, font, &char2b))
24021 {
24022 pcm = get_per_char_metric (font, &char2b);
24023 if (pcm->width == 0
24024 && pcm->rbearing == 0 && pcm->lbearing == 0)
24025 pcm = NULL;
24026 }
24027
24028 if (pcm)
24029 {
24030 it->phys_ascent = pcm->ascent + boff;
24031 it->phys_descent = pcm->descent - boff;
24032 it->pixel_width = pcm->width;
24033 }
24034 else
24035 {
24036 it->glyph_not_available_p = 1;
24037 it->phys_ascent = it->ascent;
24038 it->phys_descent = it->descent;
24039 it->pixel_width = font->space_width;
24040 }
24041
24042 if (it->constrain_row_ascent_descent_p)
24043 {
24044 if (it->descent > it->max_descent)
24045 {
24046 it->ascent += it->descent - it->max_descent;
24047 it->descent = it->max_descent;
24048 }
24049 if (it->ascent > it->max_ascent)
24050 {
24051 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
24052 it->ascent = it->max_ascent;
24053 }
24054 it->phys_ascent = min (it->phys_ascent, it->ascent);
24055 it->phys_descent = min (it->phys_descent, it->descent);
24056 extra_line_spacing = 0;
24057 }
24058
24059 /* If this is a space inside a region of text with
24060 `space-width' property, change its width. */
24061 stretched_p = it->char_to_display == ' ' && !NILP (it->space_width);
24062 if (stretched_p)
24063 it->pixel_width *= XFLOATINT (it->space_width);
24064
24065 /* If face has a box, add the box thickness to the character
24066 height. If character has a box line to the left and/or
24067 right, add the box line width to the character's width. */
24068 if (face->box != FACE_NO_BOX)
24069 {
24070 int thick = face->box_line_width;
24071
24072 if (thick > 0)
24073 {
24074 it->ascent += thick;
24075 it->descent += thick;
24076 }
24077 else
24078 thick = -thick;
24079
24080 if (it->start_of_box_run_p)
24081 it->pixel_width += thick;
24082 if (it->end_of_box_run_p)
24083 it->pixel_width += thick;
24084 }
24085
24086 /* If face has an overline, add the height of the overline
24087 (1 pixel) and a 1 pixel margin to the character height. */
24088 if (face->overline_p)
24089 it->ascent += overline_margin;
24090
24091 if (it->constrain_row_ascent_descent_p)
24092 {
24093 if (it->ascent > it->max_ascent)
24094 it->ascent = it->max_ascent;
24095 if (it->descent > it->max_descent)
24096 it->descent = it->max_descent;
24097 }
24098
24099 take_vertical_position_into_account (it);
24100
24101 /* If we have to actually produce glyphs, do it. */
24102 if (it->glyph_row)
24103 {
24104 if (stretched_p)
24105 {
24106 /* Translate a space with a `space-width' property
24107 into a stretch glyph. */
24108 int ascent = (((it->ascent + it->descent) * FONT_BASE (font))
24109 / FONT_HEIGHT (font));
24110 append_stretch_glyph (it, it->object, it->pixel_width,
24111 it->ascent + it->descent, ascent);
24112 }
24113 else
24114 append_glyph (it);
24115
24116 /* If characters with lbearing or rbearing are displayed
24117 in this line, record that fact in a flag of the
24118 glyph row. This is used to optimize X output code. */
24119 if (pcm && (pcm->lbearing < 0 || pcm->rbearing > pcm->width))
24120 it->glyph_row->contains_overlapping_glyphs_p = 1;
24121 }
24122 if (! stretched_p && it->pixel_width == 0)
24123 /* We assure that all visible glyphs have at least 1-pixel
24124 width. */
24125 it->pixel_width = 1;
24126 }
24127 else if (it->char_to_display == '\n')
24128 {
24129 /* A newline has no width, but we need the height of the
24130 line. But if previous part of the line sets a height,
24131 don't increase that height */
24132
24133 Lisp_Object height;
24134 Lisp_Object total_height = Qnil;
24135
24136 it->override_ascent = -1;
24137 it->pixel_width = 0;
24138 it->nglyphs = 0;
24139
24140 height = get_it_property (it, Qline_height);
24141 /* Split (line-height total-height) list */
24142 if (CONSP (height)
24143 && CONSP (XCDR (height))
24144 && NILP (XCDR (XCDR (height))))
24145 {
24146 total_height = XCAR (XCDR (height));
24147 height = XCAR (height);
24148 }
24149 height = calc_line_height_property (it, height, font, boff, 1);
24150
24151 if (it->override_ascent >= 0)
24152 {
24153 it->ascent = it->override_ascent;
24154 it->descent = it->override_descent;
24155 boff = it->override_boff;
24156 }
24157 else
24158 {
24159 it->ascent = FONT_BASE (font) + boff;
24160 it->descent = FONT_DESCENT (font) - boff;
24161 }
24162
24163 if (EQ (height, Qt))
24164 {
24165 if (it->descent > it->max_descent)
24166 {
24167 it->ascent += it->descent - it->max_descent;
24168 it->descent = it->max_descent;
24169 }
24170 if (it->ascent > it->max_ascent)
24171 {
24172 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
24173 it->ascent = it->max_ascent;
24174 }
24175 it->phys_ascent = min (it->phys_ascent, it->ascent);
24176 it->phys_descent = min (it->phys_descent, it->descent);
24177 it->constrain_row_ascent_descent_p = 1;
24178 extra_line_spacing = 0;
24179 }
24180 else
24181 {
24182 Lisp_Object spacing;
24183
24184 it->phys_ascent = it->ascent;
24185 it->phys_descent = it->descent;
24186
24187 if ((it->max_ascent > 0 || it->max_descent > 0)
24188 && face->box != FACE_NO_BOX
24189 && face->box_line_width > 0)
24190 {
24191 it->ascent += face->box_line_width;
24192 it->descent += face->box_line_width;
24193 }
24194 if (!NILP (height)
24195 && XINT (height) > it->ascent + it->descent)
24196 it->ascent = XINT (height) - it->descent;
24197
24198 if (!NILP (total_height))
24199 spacing = calc_line_height_property (it, total_height, font, boff, 0);
24200 else
24201 {
24202 spacing = get_it_property (it, Qline_spacing);
24203 spacing = calc_line_height_property (it, spacing, font, boff, 0);
24204 }
24205 if (INTEGERP (spacing))
24206 {
24207 extra_line_spacing = XINT (spacing);
24208 if (!NILP (total_height))
24209 extra_line_spacing -= (it->phys_ascent + it->phys_descent);
24210 }
24211 }
24212 }
24213 else /* i.e. (it->char_to_display == '\t') */
24214 {
24215 if (font->space_width > 0)
24216 {
24217 int tab_width = it->tab_width * font->space_width;
24218 int x = it->current_x + it->continuation_lines_width;
24219 int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width;
24220
24221 /* If the distance from the current position to the next tab
24222 stop is less than a space character width, use the
24223 tab stop after that. */
24224 if (next_tab_x - x < font->space_width)
24225 next_tab_x += tab_width;
24226
24227 it->pixel_width = next_tab_x - x;
24228 it->nglyphs = 1;
24229 it->ascent = it->phys_ascent = FONT_BASE (font) + boff;
24230 it->descent = it->phys_descent = FONT_DESCENT (font) - boff;
24231
24232 if (it->glyph_row)
24233 {
24234 append_stretch_glyph (it, it->object, it->pixel_width,
24235 it->ascent + it->descent, it->ascent);
24236 }
24237 }
24238 else
24239 {
24240 it->pixel_width = 0;
24241 it->nglyphs = 1;
24242 }
24243 }
24244 }
24245 else if (it->what == IT_COMPOSITION && it->cmp_it.ch < 0)
24246 {
24247 /* A static composition.
24248
24249 Note: A composition is represented as one glyph in the
24250 glyph matrix. There are no padding glyphs.
24251
24252 Important note: pixel_width, ascent, and descent are the
24253 values of what is drawn by draw_glyphs (i.e. the values of
24254 the overall glyphs composed). */
24255 struct face *face = FACE_FROM_ID (it->f, it->face_id);
24256 int boff; /* baseline offset */
24257 struct composition *cmp = composition_table[it->cmp_it.id];
24258 int glyph_len = cmp->glyph_len;
24259 struct font *font = face->font;
24260
24261 it->nglyphs = 1;
24262
24263 /* If we have not yet calculated pixel size data of glyphs of
24264 the composition for the current face font, calculate them
24265 now. Theoretically, we have to check all fonts for the
24266 glyphs, but that requires much time and memory space. So,
24267 here we check only the font of the first glyph. This may
24268 lead to incorrect display, but it's very rare, and C-l
24269 (recenter-top-bottom) can correct the display anyway. */
24270 if (! cmp->font || cmp->font != font)
24271 {
24272 /* Ascent and descent of the font of the first character
24273 of this composition (adjusted by baseline offset).
24274 Ascent and descent of overall glyphs should not be less
24275 than these, respectively. */
24276 int font_ascent, font_descent, font_height;
24277 /* Bounding box of the overall glyphs. */
24278 int leftmost, rightmost, lowest, highest;
24279 int lbearing, rbearing;
24280 int i, width, ascent, descent;
24281 int left_padded = 0, right_padded = 0;
24282 int c IF_LINT (= 0); /* cmp->glyph_len can't be zero; see Bug#8512 */
24283 XChar2b char2b;
24284 struct font_metrics *pcm;
24285 int font_not_found_p;
24286 EMACS_INT pos;
24287
24288 for (glyph_len = cmp->glyph_len; glyph_len > 0; glyph_len--)
24289 if ((c = COMPOSITION_GLYPH (cmp, glyph_len - 1)) != '\t')
24290 break;
24291 if (glyph_len < cmp->glyph_len)
24292 right_padded = 1;
24293 for (i = 0; i < glyph_len; i++)
24294 {
24295 if ((c = COMPOSITION_GLYPH (cmp, i)) != '\t')
24296 break;
24297 cmp->offsets[i * 2] = cmp->offsets[i * 2 + 1] = 0;
24298 }
24299 if (i > 0)
24300 left_padded = 1;
24301
24302 pos = (STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
24303 : IT_CHARPOS (*it));
24304 /* If no suitable font is found, use the default font. */
24305 font_not_found_p = font == NULL;
24306 if (font_not_found_p)
24307 {
24308 face = face->ascii_face;
24309 font = face->font;
24310 }
24311 boff = font->baseline_offset;
24312 if (font->vertical_centering)
24313 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
24314 font_ascent = FONT_BASE (font) + boff;
24315 font_descent = FONT_DESCENT (font) - boff;
24316 font_height = FONT_HEIGHT (font);
24317
24318 cmp->font = (void *) font;
24319
24320 pcm = NULL;
24321 if (! font_not_found_p)
24322 {
24323 get_char_face_and_encoding (it->f, c, it->face_id,
24324 &char2b, 0);
24325 pcm = get_per_char_metric (font, &char2b);
24326 }
24327
24328 /* Initialize the bounding box. */
24329 if (pcm)
24330 {
24331 width = pcm->width;
24332 ascent = pcm->ascent;
24333 descent = pcm->descent;
24334 lbearing = pcm->lbearing;
24335 rbearing = pcm->rbearing;
24336 }
24337 else
24338 {
24339 width = font->space_width;
24340 ascent = FONT_BASE (font);
24341 descent = FONT_DESCENT (font);
24342 lbearing = 0;
24343 rbearing = width;
24344 }
24345
24346 rightmost = width;
24347 leftmost = 0;
24348 lowest = - descent + boff;
24349 highest = ascent + boff;
24350
24351 if (! font_not_found_p
24352 && font->default_ascent
24353 && CHAR_TABLE_P (Vuse_default_ascent)
24354 && !NILP (Faref (Vuse_default_ascent,
24355 make_number (it->char_to_display))))
24356 highest = font->default_ascent + boff;
24357
24358 /* Draw the first glyph at the normal position. It may be
24359 shifted to right later if some other glyphs are drawn
24360 at the left. */
24361 cmp->offsets[i * 2] = 0;
24362 cmp->offsets[i * 2 + 1] = boff;
24363 cmp->lbearing = lbearing;
24364 cmp->rbearing = rbearing;
24365
24366 /* Set cmp->offsets for the remaining glyphs. */
24367 for (i++; i < glyph_len; i++)
24368 {
24369 int left, right, btm, top;
24370 int ch = COMPOSITION_GLYPH (cmp, i);
24371 int face_id;
24372 struct face *this_face;
24373
24374 if (ch == '\t')
24375 ch = ' ';
24376 face_id = FACE_FOR_CHAR (it->f, face, ch, pos, it->string);
24377 this_face = FACE_FROM_ID (it->f, face_id);
24378 font = this_face->font;
24379
24380 if (font == NULL)
24381 pcm = NULL;
24382 else
24383 {
24384 get_char_face_and_encoding (it->f, ch, face_id,
24385 &char2b, 0);
24386 pcm = get_per_char_metric (font, &char2b);
24387 }
24388 if (! pcm)
24389 cmp->offsets[i * 2] = cmp->offsets[i * 2 + 1] = 0;
24390 else
24391 {
24392 width = pcm->width;
24393 ascent = pcm->ascent;
24394 descent = pcm->descent;
24395 lbearing = pcm->lbearing;
24396 rbearing = pcm->rbearing;
24397 if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS)
24398 {
24399 /* Relative composition with or without
24400 alternate chars. */
24401 left = (leftmost + rightmost - width) / 2;
24402 btm = - descent + boff;
24403 if (font->relative_compose
24404 && (! CHAR_TABLE_P (Vignore_relative_composition)
24405 || NILP (Faref (Vignore_relative_composition,
24406 make_number (ch)))))
24407 {
24408
24409 if (- descent >= font->relative_compose)
24410 /* One extra pixel between two glyphs. */
24411 btm = highest + 1;
24412 else if (ascent <= 0)
24413 /* One extra pixel between two glyphs. */
24414 btm = lowest - 1 - ascent - descent;
24415 }
24416 }
24417 else
24418 {
24419 /* A composition rule is specified by an integer
24420 value that encodes global and new reference
24421 points (GREF and NREF). GREF and NREF are
24422 specified by numbers as below:
24423
24424 0---1---2 -- ascent
24425 | |
24426 | |
24427 | |
24428 9--10--11 -- center
24429 | |
24430 ---3---4---5--- baseline
24431 | |
24432 6---7---8 -- descent
24433 */
24434 int rule = COMPOSITION_RULE (cmp, i);
24435 int gref, nref, grefx, grefy, nrefx, nrefy, xoff, yoff;
24436
24437 COMPOSITION_DECODE_RULE (rule, gref, nref, xoff, yoff);
24438 grefx = gref % 3, nrefx = nref % 3;
24439 grefy = gref / 3, nrefy = nref / 3;
24440 if (xoff)
24441 xoff = font_height * (xoff - 128) / 256;
24442 if (yoff)
24443 yoff = font_height * (yoff - 128) / 256;
24444
24445 left = (leftmost
24446 + grefx * (rightmost - leftmost) / 2
24447 - nrefx * width / 2
24448 + xoff);
24449
24450 btm = ((grefy == 0 ? highest
24451 : grefy == 1 ? 0
24452 : grefy == 2 ? lowest
24453 : (highest + lowest) / 2)
24454 - (nrefy == 0 ? ascent + descent
24455 : nrefy == 1 ? descent - boff
24456 : nrefy == 2 ? 0
24457 : (ascent + descent) / 2)
24458 + yoff);
24459 }
24460
24461 cmp->offsets[i * 2] = left;
24462 cmp->offsets[i * 2 + 1] = btm + descent;
24463
24464 /* Update the bounding box of the overall glyphs. */
24465 if (width > 0)
24466 {
24467 right = left + width;
24468 if (left < leftmost)
24469 leftmost = left;
24470 if (right > rightmost)
24471 rightmost = right;
24472 }
24473 top = btm + descent + ascent;
24474 if (top > highest)
24475 highest = top;
24476 if (btm < lowest)
24477 lowest = btm;
24478
24479 if (cmp->lbearing > left + lbearing)
24480 cmp->lbearing = left + lbearing;
24481 if (cmp->rbearing < left + rbearing)
24482 cmp->rbearing = left + rbearing;
24483 }
24484 }
24485
24486 /* If there are glyphs whose x-offsets are negative,
24487 shift all glyphs to the right and make all x-offsets
24488 non-negative. */
24489 if (leftmost < 0)
24490 {
24491 for (i = 0; i < cmp->glyph_len; i++)
24492 cmp->offsets[i * 2] -= leftmost;
24493 rightmost -= leftmost;
24494 cmp->lbearing -= leftmost;
24495 cmp->rbearing -= leftmost;
24496 }
24497
24498 if (left_padded && cmp->lbearing < 0)
24499 {
24500 for (i = 0; i < cmp->glyph_len; i++)
24501 cmp->offsets[i * 2] -= cmp->lbearing;
24502 rightmost -= cmp->lbearing;
24503 cmp->rbearing -= cmp->lbearing;
24504 cmp->lbearing = 0;
24505 }
24506 if (right_padded && rightmost < cmp->rbearing)
24507 {
24508 rightmost = cmp->rbearing;
24509 }
24510
24511 cmp->pixel_width = rightmost;
24512 cmp->ascent = highest;
24513 cmp->descent = - lowest;
24514 if (cmp->ascent < font_ascent)
24515 cmp->ascent = font_ascent;
24516 if (cmp->descent < font_descent)
24517 cmp->descent = font_descent;
24518 }
24519
24520 if (it->glyph_row
24521 && (cmp->lbearing < 0
24522 || cmp->rbearing > cmp->pixel_width))
24523 it->glyph_row->contains_overlapping_glyphs_p = 1;
24524
24525 it->pixel_width = cmp->pixel_width;
24526 it->ascent = it->phys_ascent = cmp->ascent;
24527 it->descent = it->phys_descent = cmp->descent;
24528 if (face->box != FACE_NO_BOX)
24529 {
24530 int thick = face->box_line_width;
24531
24532 if (thick > 0)
24533 {
24534 it->ascent += thick;
24535 it->descent += thick;
24536 }
24537 else
24538 thick = - thick;
24539
24540 if (it->start_of_box_run_p)
24541 it->pixel_width += thick;
24542 if (it->end_of_box_run_p)
24543 it->pixel_width += thick;
24544 }
24545
24546 /* If face has an overline, add the height of the overline
24547 (1 pixel) and a 1 pixel margin to the character height. */
24548 if (face->overline_p)
24549 it->ascent += overline_margin;
24550
24551 take_vertical_position_into_account (it);
24552 if (it->ascent < 0)
24553 it->ascent = 0;
24554 if (it->descent < 0)
24555 it->descent = 0;
24556
24557 if (it->glyph_row)
24558 append_composite_glyph (it);
24559 }
24560 else if (it->what == IT_COMPOSITION)
24561 {
24562 /* A dynamic (automatic) composition. */
24563 struct face *face = FACE_FROM_ID (it->f, it->face_id);
24564 Lisp_Object gstring;
24565 struct font_metrics metrics;
24566
24567 it->nglyphs = 1;
24568
24569 gstring = composition_gstring_from_id (it->cmp_it.id);
24570 it->pixel_width
24571 = composition_gstring_width (gstring, it->cmp_it.from, it->cmp_it.to,
24572 &metrics);
24573 if (it->glyph_row
24574 && (metrics.lbearing < 0 || metrics.rbearing > metrics.width))
24575 it->glyph_row->contains_overlapping_glyphs_p = 1;
24576 it->ascent = it->phys_ascent = metrics.ascent;
24577 it->descent = it->phys_descent = metrics.descent;
24578 if (face->box != FACE_NO_BOX)
24579 {
24580 int thick = face->box_line_width;
24581
24582 if (thick > 0)
24583 {
24584 it->ascent += thick;
24585 it->descent += thick;
24586 }
24587 else
24588 thick = - thick;
24589
24590 if (it->start_of_box_run_p)
24591 it->pixel_width += thick;
24592 if (it->end_of_box_run_p)
24593 it->pixel_width += thick;
24594 }
24595 /* If face has an overline, add the height of the overline
24596 (1 pixel) and a 1 pixel margin to the character height. */
24597 if (face->overline_p)
24598 it->ascent += overline_margin;
24599 take_vertical_position_into_account (it);
24600 if (it->ascent < 0)
24601 it->ascent = 0;
24602 if (it->descent < 0)
24603 it->descent = 0;
24604
24605 if (it->glyph_row)
24606 append_composite_glyph (it);
24607 }
24608 else if (it->what == IT_GLYPHLESS)
24609 produce_glyphless_glyph (it, 0, Qnil);
24610 else if (it->what == IT_IMAGE)
24611 produce_image_glyph (it);
24612 else if (it->what == IT_STRETCH)
24613 produce_stretch_glyph (it);
24614
24615 done:
24616 /* Accumulate dimensions. Note: can't assume that it->descent > 0
24617 because this isn't true for images with `:ascent 100'. */
24618 xassert (it->ascent >= 0 && it->descent >= 0);
24619 if (it->area == TEXT_AREA)
24620 it->current_x += it->pixel_width;
24621
24622 if (extra_line_spacing > 0)
24623 {
24624 it->descent += extra_line_spacing;
24625 if (extra_line_spacing > it->max_extra_line_spacing)
24626 it->max_extra_line_spacing = extra_line_spacing;
24627 }
24628
24629 it->max_ascent = max (it->max_ascent, it->ascent);
24630 it->max_descent = max (it->max_descent, it->descent);
24631 it->max_phys_ascent = max (it->max_phys_ascent, it->phys_ascent);
24632 it->max_phys_descent = max (it->max_phys_descent, it->phys_descent);
24633 }
24634
24635 /* EXPORT for RIF:
24636 Output LEN glyphs starting at START at the nominal cursor position.
24637 Advance the nominal cursor over the text. The global variable
24638 updated_window contains the window being updated, updated_row is
24639 the glyph row being updated, and updated_area is the area of that
24640 row being updated. */
24641
24642 void
24643 x_write_glyphs (struct glyph *start, int len)
24644 {
24645 int x, hpos;
24646
24647 xassert (updated_window && updated_row);
24648 BLOCK_INPUT;
24649
24650 /* Write glyphs. */
24651
24652 hpos = start - updated_row->glyphs[updated_area];
24653 x = draw_glyphs (updated_window, output_cursor.x,
24654 updated_row, updated_area,
24655 hpos, hpos + len,
24656 DRAW_NORMAL_TEXT, 0);
24657
24658 /* Invalidate old phys cursor if the glyph at its hpos is redrawn. */
24659 if (updated_area == TEXT_AREA
24660 && updated_window->phys_cursor_on_p
24661 && updated_window->phys_cursor.vpos == output_cursor.vpos
24662 && updated_window->phys_cursor.hpos >= hpos
24663 && updated_window->phys_cursor.hpos < hpos + len)
24664 updated_window->phys_cursor_on_p = 0;
24665
24666 UNBLOCK_INPUT;
24667
24668 /* Advance the output cursor. */
24669 output_cursor.hpos += len;
24670 output_cursor.x = x;
24671 }
24672
24673
24674 /* EXPORT for RIF:
24675 Insert LEN glyphs from START at the nominal cursor position. */
24676
24677 void
24678 x_insert_glyphs (struct glyph *start, int len)
24679 {
24680 struct frame *f;
24681 struct window *w;
24682 int line_height, shift_by_width, shifted_region_width;
24683 struct glyph_row *row;
24684 struct glyph *glyph;
24685 int frame_x, frame_y;
24686 EMACS_INT hpos;
24687
24688 xassert (updated_window && updated_row);
24689 BLOCK_INPUT;
24690 w = updated_window;
24691 f = XFRAME (WINDOW_FRAME (w));
24692
24693 /* Get the height of the line we are in. */
24694 row = updated_row;
24695 line_height = row->height;
24696
24697 /* Get the width of the glyphs to insert. */
24698 shift_by_width = 0;
24699 for (glyph = start; glyph < start + len; ++glyph)
24700 shift_by_width += glyph->pixel_width;
24701
24702 /* Get the width of the region to shift right. */
24703 shifted_region_width = (window_box_width (w, updated_area)
24704 - output_cursor.x
24705 - shift_by_width);
24706
24707 /* Shift right. */
24708 frame_x = window_box_left (w, updated_area) + output_cursor.x;
24709 frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, output_cursor.y);
24710
24711 FRAME_RIF (f)->shift_glyphs_for_insert (f, frame_x, frame_y, shifted_region_width,
24712 line_height, shift_by_width);
24713
24714 /* Write the glyphs. */
24715 hpos = start - row->glyphs[updated_area];
24716 draw_glyphs (w, output_cursor.x, row, updated_area,
24717 hpos, hpos + len,
24718 DRAW_NORMAL_TEXT, 0);
24719
24720 /* Advance the output cursor. */
24721 output_cursor.hpos += len;
24722 output_cursor.x += shift_by_width;
24723 UNBLOCK_INPUT;
24724 }
24725
24726
24727 /* EXPORT for RIF:
24728 Erase the current text line from the nominal cursor position
24729 (inclusive) to pixel column TO_X (exclusive). The idea is that
24730 everything from TO_X onward is already erased.
24731
24732 TO_X is a pixel position relative to updated_area of
24733 updated_window. TO_X == -1 means clear to the end of this area. */
24734
24735 void
24736 x_clear_end_of_line (int to_x)
24737 {
24738 struct frame *f;
24739 struct window *w = updated_window;
24740 int max_x, min_y, max_y;
24741 int from_x, from_y, to_y;
24742
24743 xassert (updated_window && updated_row);
24744 f = XFRAME (w->frame);
24745
24746 if (updated_row->full_width_p)
24747 max_x = WINDOW_TOTAL_WIDTH (w);
24748 else
24749 max_x = window_box_width (w, updated_area);
24750 max_y = window_text_bottom_y (w);
24751
24752 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
24753 of window. For TO_X > 0, truncate to end of drawing area. */
24754 if (to_x == 0)
24755 return;
24756 else if (to_x < 0)
24757 to_x = max_x;
24758 else
24759 to_x = min (to_x, max_x);
24760
24761 to_y = min (max_y, output_cursor.y + updated_row->height);
24762
24763 /* Notice if the cursor will be cleared by this operation. */
24764 if (!updated_row->full_width_p)
24765 notice_overwritten_cursor (w, updated_area,
24766 output_cursor.x, -1,
24767 updated_row->y,
24768 MATRIX_ROW_BOTTOM_Y (updated_row));
24769
24770 from_x = output_cursor.x;
24771
24772 /* Translate to frame coordinates. */
24773 if (updated_row->full_width_p)
24774 {
24775 from_x = WINDOW_TO_FRAME_PIXEL_X (w, from_x);
24776 to_x = WINDOW_TO_FRAME_PIXEL_X (w, to_x);
24777 }
24778 else
24779 {
24780 int area_left = window_box_left (w, updated_area);
24781 from_x += area_left;
24782 to_x += area_left;
24783 }
24784
24785 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
24786 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, max (min_y, output_cursor.y));
24787 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, to_y);
24788
24789 /* Prevent inadvertently clearing to end of the X window. */
24790 if (to_x > from_x && to_y > from_y)
24791 {
24792 BLOCK_INPUT;
24793 FRAME_RIF (f)->clear_frame_area (f, from_x, from_y,
24794 to_x - from_x, to_y - from_y);
24795 UNBLOCK_INPUT;
24796 }
24797 }
24798
24799 #endif /* HAVE_WINDOW_SYSTEM */
24800
24801
24802 \f
24803 /***********************************************************************
24804 Cursor types
24805 ***********************************************************************/
24806
24807 /* Value is the internal representation of the specified cursor type
24808 ARG. If type is BAR_CURSOR, return in *WIDTH the specified width
24809 of the bar cursor. */
24810
24811 static enum text_cursor_kinds
24812 get_specified_cursor_type (Lisp_Object arg, int *width)
24813 {
24814 enum text_cursor_kinds type;
24815
24816 if (NILP (arg))
24817 return NO_CURSOR;
24818
24819 if (EQ (arg, Qbox))
24820 return FILLED_BOX_CURSOR;
24821
24822 if (EQ (arg, Qhollow))
24823 return HOLLOW_BOX_CURSOR;
24824
24825 if (EQ (arg, Qbar))
24826 {
24827 *width = 2;
24828 return BAR_CURSOR;
24829 }
24830
24831 if (CONSP (arg)
24832 && EQ (XCAR (arg), Qbar)
24833 && INTEGERP (XCDR (arg))
24834 && XINT (XCDR (arg)) >= 0)
24835 {
24836 *width = XINT (XCDR (arg));
24837 return BAR_CURSOR;
24838 }
24839
24840 if (EQ (arg, Qhbar))
24841 {
24842 *width = 2;
24843 return HBAR_CURSOR;
24844 }
24845
24846 if (CONSP (arg)
24847 && EQ (XCAR (arg), Qhbar)
24848 && INTEGERP (XCDR (arg))
24849 && XINT (XCDR (arg)) >= 0)
24850 {
24851 *width = XINT (XCDR (arg));
24852 return HBAR_CURSOR;
24853 }
24854
24855 /* Treat anything unknown as "hollow box cursor".
24856 It was bad to signal an error; people have trouble fixing
24857 .Xdefaults with Emacs, when it has something bad in it. */
24858 type = HOLLOW_BOX_CURSOR;
24859
24860 return type;
24861 }
24862
24863 /* Set the default cursor types for specified frame. */
24864 void
24865 set_frame_cursor_types (struct frame *f, Lisp_Object arg)
24866 {
24867 int width = 1;
24868 Lisp_Object tem;
24869
24870 FRAME_DESIRED_CURSOR (f) = get_specified_cursor_type (arg, &width);
24871 FRAME_CURSOR_WIDTH (f) = width;
24872
24873 /* By default, set up the blink-off state depending on the on-state. */
24874
24875 tem = Fassoc (arg, Vblink_cursor_alist);
24876 if (!NILP (tem))
24877 {
24878 FRAME_BLINK_OFF_CURSOR (f)
24879 = get_specified_cursor_type (XCDR (tem), &width);
24880 FRAME_BLINK_OFF_CURSOR_WIDTH (f) = width;
24881 }
24882 else
24883 FRAME_BLINK_OFF_CURSOR (f) = DEFAULT_CURSOR;
24884 }
24885
24886
24887 #ifdef HAVE_WINDOW_SYSTEM
24888
24889 /* Return the cursor we want to be displayed in window W. Return
24890 width of bar/hbar cursor through WIDTH arg. Return with
24891 ACTIVE_CURSOR arg set to 1 if cursor in window W is `active'
24892 (i.e. if the `system caret' should track this cursor).
24893
24894 In a mini-buffer window, we want the cursor only to appear if we
24895 are reading input from this window. For the selected window, we
24896 want the cursor type given by the frame parameter or buffer local
24897 setting of cursor-type. If explicitly marked off, draw no cursor.
24898 In all other cases, we want a hollow box cursor. */
24899
24900 static enum text_cursor_kinds
24901 get_window_cursor_type (struct window *w, struct glyph *glyph, int *width,
24902 int *active_cursor)
24903 {
24904 struct frame *f = XFRAME (w->frame);
24905 struct buffer *b = XBUFFER (w->buffer);
24906 int cursor_type = DEFAULT_CURSOR;
24907 Lisp_Object alt_cursor;
24908 int non_selected = 0;
24909
24910 *active_cursor = 1;
24911
24912 /* Echo area */
24913 if (cursor_in_echo_area
24914 && FRAME_HAS_MINIBUF_P (f)
24915 && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
24916 {
24917 if (w == XWINDOW (echo_area_window))
24918 {
24919 if (EQ (BVAR (b, cursor_type), Qt) || NILP (BVAR (b, cursor_type)))
24920 {
24921 *width = FRAME_CURSOR_WIDTH (f);
24922 return FRAME_DESIRED_CURSOR (f);
24923 }
24924 else
24925 return get_specified_cursor_type (BVAR (b, cursor_type), width);
24926 }
24927
24928 *active_cursor = 0;
24929 non_selected = 1;
24930 }
24931
24932 /* Detect a nonselected window or nonselected frame. */
24933 else if (w != XWINDOW (f->selected_window)
24934 || f != FRAME_X_DISPLAY_INFO (f)->x_highlight_frame)
24935 {
24936 *active_cursor = 0;
24937
24938 if (MINI_WINDOW_P (w) && minibuf_level == 0)
24939 return NO_CURSOR;
24940
24941 non_selected = 1;
24942 }
24943
24944 /* Never display a cursor in a window in which cursor-type is nil. */
24945 if (NILP (BVAR (b, cursor_type)))
24946 return NO_CURSOR;
24947
24948 /* Get the normal cursor type for this window. */
24949 if (EQ (BVAR (b, cursor_type), Qt))
24950 {
24951 cursor_type = FRAME_DESIRED_CURSOR (f);
24952 *width = FRAME_CURSOR_WIDTH (f);
24953 }
24954 else
24955 cursor_type = get_specified_cursor_type (BVAR (b, cursor_type), width);
24956
24957 /* Use cursor-in-non-selected-windows instead
24958 for non-selected window or frame. */
24959 if (non_selected)
24960 {
24961 alt_cursor = BVAR (b, cursor_in_non_selected_windows);
24962 if (!EQ (Qt, alt_cursor))
24963 return get_specified_cursor_type (alt_cursor, width);
24964 /* t means modify the normal cursor type. */
24965 if (cursor_type == FILLED_BOX_CURSOR)
24966 cursor_type = HOLLOW_BOX_CURSOR;
24967 else if (cursor_type == BAR_CURSOR && *width > 1)
24968 --*width;
24969 return cursor_type;
24970 }
24971
24972 /* Use normal cursor if not blinked off. */
24973 if (!w->cursor_off_p)
24974 {
24975 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
24976 {
24977 if (cursor_type == FILLED_BOX_CURSOR)
24978 {
24979 /* Using a block cursor on large images can be very annoying.
24980 So use a hollow cursor for "large" images.
24981 If image is not transparent (no mask), also use hollow cursor. */
24982 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
24983 if (img != NULL && IMAGEP (img->spec))
24984 {
24985 /* Arbitrarily, interpret "Large" as >32x32 and >NxN
24986 where N = size of default frame font size.
24987 This should cover most of the "tiny" icons people may use. */
24988 if (!img->mask
24989 || img->width > max (32, WINDOW_FRAME_COLUMN_WIDTH (w))
24990 || img->height > max (32, WINDOW_FRAME_LINE_HEIGHT (w)))
24991 cursor_type = HOLLOW_BOX_CURSOR;
24992 }
24993 }
24994 else if (cursor_type != NO_CURSOR)
24995 {
24996 /* Display current only supports BOX and HOLLOW cursors for images.
24997 So for now, unconditionally use a HOLLOW cursor when cursor is
24998 not a solid box cursor. */
24999 cursor_type = HOLLOW_BOX_CURSOR;
25000 }
25001 }
25002 return cursor_type;
25003 }
25004
25005 /* Cursor is blinked off, so determine how to "toggle" it. */
25006
25007 /* First look for an entry matching the buffer's cursor-type in blink-cursor-alist. */
25008 if ((alt_cursor = Fassoc (BVAR (b, cursor_type), Vblink_cursor_alist), !NILP (alt_cursor)))
25009 return get_specified_cursor_type (XCDR (alt_cursor), width);
25010
25011 /* Then see if frame has specified a specific blink off cursor type. */
25012 if (FRAME_BLINK_OFF_CURSOR (f) != DEFAULT_CURSOR)
25013 {
25014 *width = FRAME_BLINK_OFF_CURSOR_WIDTH (f);
25015 return FRAME_BLINK_OFF_CURSOR (f);
25016 }
25017
25018 #if 0
25019 /* Some people liked having a permanently visible blinking cursor,
25020 while others had very strong opinions against it. So it was
25021 decided to remove it. KFS 2003-09-03 */
25022
25023 /* Finally perform built-in cursor blinking:
25024 filled box <-> hollow box
25025 wide [h]bar <-> narrow [h]bar
25026 narrow [h]bar <-> no cursor
25027 other type <-> no cursor */
25028
25029 if (cursor_type == FILLED_BOX_CURSOR)
25030 return HOLLOW_BOX_CURSOR;
25031
25032 if ((cursor_type == BAR_CURSOR || cursor_type == HBAR_CURSOR) && *width > 1)
25033 {
25034 *width = 1;
25035 return cursor_type;
25036 }
25037 #endif
25038
25039 return NO_CURSOR;
25040 }
25041
25042
25043 /* Notice when the text cursor of window W has been completely
25044 overwritten by a drawing operation that outputs glyphs in AREA
25045 starting at X0 and ending at X1 in the line starting at Y0 and
25046 ending at Y1. X coordinates are area-relative. X1 < 0 means all
25047 the rest of the line after X0 has been written. Y coordinates
25048 are window-relative. */
25049
25050 static void
25051 notice_overwritten_cursor (struct window *w, enum glyph_row_area area,
25052 int x0, int x1, int y0, int y1)
25053 {
25054 int cx0, cx1, cy0, cy1;
25055 struct glyph_row *row;
25056
25057 if (!w->phys_cursor_on_p)
25058 return;
25059 if (area != TEXT_AREA)
25060 return;
25061
25062 if (w->phys_cursor.vpos < 0
25063 || w->phys_cursor.vpos >= w->current_matrix->nrows
25064 || (row = w->current_matrix->rows + w->phys_cursor.vpos,
25065 !(row->enabled_p && row->displays_text_p)))
25066 return;
25067
25068 if (row->cursor_in_fringe_p)
25069 {
25070 row->cursor_in_fringe_p = 0;
25071 draw_fringe_bitmap (w, row, row->reversed_p);
25072 w->phys_cursor_on_p = 0;
25073 return;
25074 }
25075
25076 cx0 = w->phys_cursor.x;
25077 cx1 = cx0 + w->phys_cursor_width;
25078 if (x0 > cx0 || (x1 >= 0 && x1 < cx1))
25079 return;
25080
25081 /* The cursor image will be completely removed from the
25082 screen if the output area intersects the cursor area in
25083 y-direction. When we draw in [y0 y1[, and some part of
25084 the cursor is at y < y0, that part must have been drawn
25085 before. When scrolling, the cursor is erased before
25086 actually scrolling, so we don't come here. When not
25087 scrolling, the rows above the old cursor row must have
25088 changed, and in this case these rows must have written
25089 over the cursor image.
25090
25091 Likewise if part of the cursor is below y1, with the
25092 exception of the cursor being in the first blank row at
25093 the buffer and window end because update_text_area
25094 doesn't draw that row. (Except when it does, but
25095 that's handled in update_text_area.) */
25096
25097 cy0 = w->phys_cursor.y;
25098 cy1 = cy0 + w->phys_cursor_height;
25099 if ((y0 < cy0 || y0 >= cy1) && (y1 <= cy0 || y1 >= cy1))
25100 return;
25101
25102 w->phys_cursor_on_p = 0;
25103 }
25104
25105 #endif /* HAVE_WINDOW_SYSTEM */
25106
25107 \f
25108 /************************************************************************
25109 Mouse Face
25110 ************************************************************************/
25111
25112 #ifdef HAVE_WINDOW_SYSTEM
25113
25114 /* EXPORT for RIF:
25115 Fix the display of area AREA of overlapping row ROW in window W
25116 with respect to the overlapping part OVERLAPS. */
25117
25118 void
25119 x_fix_overlapping_area (struct window *w, struct glyph_row *row,
25120 enum glyph_row_area area, int overlaps)
25121 {
25122 int i, x;
25123
25124 BLOCK_INPUT;
25125
25126 x = 0;
25127 for (i = 0; i < row->used[area];)
25128 {
25129 if (row->glyphs[area][i].overlaps_vertically_p)
25130 {
25131 int start = i, start_x = x;
25132
25133 do
25134 {
25135 x += row->glyphs[area][i].pixel_width;
25136 ++i;
25137 }
25138 while (i < row->used[area]
25139 && row->glyphs[area][i].overlaps_vertically_p);
25140
25141 draw_glyphs (w, start_x, row, area,
25142 start, i,
25143 DRAW_NORMAL_TEXT, overlaps);
25144 }
25145 else
25146 {
25147 x += row->glyphs[area][i].pixel_width;
25148 ++i;
25149 }
25150 }
25151
25152 UNBLOCK_INPUT;
25153 }
25154
25155
25156 /* EXPORT:
25157 Draw the cursor glyph of window W in glyph row ROW. See the
25158 comment of draw_glyphs for the meaning of HL. */
25159
25160 void
25161 draw_phys_cursor_glyph (struct window *w, struct glyph_row *row,
25162 enum draw_glyphs_face hl)
25163 {
25164 /* If cursor hpos is out of bounds, don't draw garbage. This can
25165 happen in mini-buffer windows when switching between echo area
25166 glyphs and mini-buffer. */
25167 if ((row->reversed_p
25168 ? (w->phys_cursor.hpos >= 0)
25169 : (w->phys_cursor.hpos < row->used[TEXT_AREA])))
25170 {
25171 int on_p = w->phys_cursor_on_p;
25172 int x1;
25173 x1 = draw_glyphs (w, w->phys_cursor.x, row, TEXT_AREA,
25174 w->phys_cursor.hpos, w->phys_cursor.hpos + 1,
25175 hl, 0);
25176 w->phys_cursor_on_p = on_p;
25177
25178 if (hl == DRAW_CURSOR)
25179 w->phys_cursor_width = x1 - w->phys_cursor.x;
25180 /* When we erase the cursor, and ROW is overlapped by other
25181 rows, make sure that these overlapping parts of other rows
25182 are redrawn. */
25183 else if (hl == DRAW_NORMAL_TEXT && row->overlapped_p)
25184 {
25185 w->phys_cursor_width = x1 - w->phys_cursor.x;
25186
25187 if (row > w->current_matrix->rows
25188 && MATRIX_ROW_OVERLAPS_SUCC_P (row - 1))
25189 x_fix_overlapping_area (w, row - 1, TEXT_AREA,
25190 OVERLAPS_ERASED_CURSOR);
25191
25192 if (MATRIX_ROW_BOTTOM_Y (row) < window_text_bottom_y (w)
25193 && MATRIX_ROW_OVERLAPS_PRED_P (row + 1))
25194 x_fix_overlapping_area (w, row + 1, TEXT_AREA,
25195 OVERLAPS_ERASED_CURSOR);
25196 }
25197 }
25198 }
25199
25200
25201 /* EXPORT:
25202 Erase the image of a cursor of window W from the screen. */
25203
25204 void
25205 erase_phys_cursor (struct window *w)
25206 {
25207 struct frame *f = XFRAME (w->frame);
25208 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
25209 int hpos = w->phys_cursor.hpos;
25210 int vpos = w->phys_cursor.vpos;
25211 int mouse_face_here_p = 0;
25212 struct glyph_matrix *active_glyphs = w->current_matrix;
25213 struct glyph_row *cursor_row;
25214 struct glyph *cursor_glyph;
25215 enum draw_glyphs_face hl;
25216
25217 /* No cursor displayed or row invalidated => nothing to do on the
25218 screen. */
25219 if (w->phys_cursor_type == NO_CURSOR)
25220 goto mark_cursor_off;
25221
25222 /* VPOS >= active_glyphs->nrows means that window has been resized.
25223 Don't bother to erase the cursor. */
25224 if (vpos >= active_glyphs->nrows)
25225 goto mark_cursor_off;
25226
25227 /* If row containing cursor is marked invalid, there is nothing we
25228 can do. */
25229 cursor_row = MATRIX_ROW (active_glyphs, vpos);
25230 if (!cursor_row->enabled_p)
25231 goto mark_cursor_off;
25232
25233 /* If line spacing is > 0, old cursor may only be partially visible in
25234 window after split-window. So adjust visible height. */
25235 cursor_row->visible_height = min (cursor_row->visible_height,
25236 window_text_bottom_y (w) - cursor_row->y);
25237
25238 /* If row is completely invisible, don't attempt to delete a cursor which
25239 isn't there. This can happen if cursor is at top of a window, and
25240 we switch to a buffer with a header line in that window. */
25241 if (cursor_row->visible_height <= 0)
25242 goto mark_cursor_off;
25243
25244 /* If cursor is in the fringe, erase by drawing actual bitmap there. */
25245 if (cursor_row->cursor_in_fringe_p)
25246 {
25247 cursor_row->cursor_in_fringe_p = 0;
25248 draw_fringe_bitmap (w, cursor_row, cursor_row->reversed_p);
25249 goto mark_cursor_off;
25250 }
25251
25252 /* This can happen when the new row is shorter than the old one.
25253 In this case, either draw_glyphs or clear_end_of_line
25254 should have cleared the cursor. Note that we wouldn't be
25255 able to erase the cursor in this case because we don't have a
25256 cursor glyph at hand. */
25257 if ((cursor_row->reversed_p
25258 ? (w->phys_cursor.hpos < 0)
25259 : (w->phys_cursor.hpos >= cursor_row->used[TEXT_AREA])))
25260 goto mark_cursor_off;
25261
25262 /* If the cursor is in the mouse face area, redisplay that when
25263 we clear the cursor. */
25264 if (! NILP (hlinfo->mouse_face_window)
25265 && coords_in_mouse_face_p (w, hpos, vpos)
25266 /* Don't redraw the cursor's spot in mouse face if it is at the
25267 end of a line (on a newline). The cursor appears there, but
25268 mouse highlighting does not. */
25269 && cursor_row->used[TEXT_AREA] > hpos && hpos >= 0)
25270 mouse_face_here_p = 1;
25271
25272 /* Maybe clear the display under the cursor. */
25273 if (w->phys_cursor_type == HOLLOW_BOX_CURSOR)
25274 {
25275 int x, y, left_x;
25276 int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
25277 int width;
25278
25279 cursor_glyph = get_phys_cursor_glyph (w);
25280 if (cursor_glyph == NULL)
25281 goto mark_cursor_off;
25282
25283 width = cursor_glyph->pixel_width;
25284 left_x = window_box_left_offset (w, TEXT_AREA);
25285 x = w->phys_cursor.x;
25286 if (x < left_x)
25287 width -= left_x - x;
25288 width = min (width, window_box_width (w, TEXT_AREA) - x);
25289 y = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, cursor_row->y));
25290 x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, max (x, left_x));
25291
25292 if (width > 0)
25293 FRAME_RIF (f)->clear_frame_area (f, x, y, width, cursor_row->visible_height);
25294 }
25295
25296 /* Erase the cursor by redrawing the character underneath it. */
25297 if (mouse_face_here_p)
25298 hl = DRAW_MOUSE_FACE;
25299 else
25300 hl = DRAW_NORMAL_TEXT;
25301 draw_phys_cursor_glyph (w, cursor_row, hl);
25302
25303 mark_cursor_off:
25304 w->phys_cursor_on_p = 0;
25305 w->phys_cursor_type = NO_CURSOR;
25306 }
25307
25308
25309 /* EXPORT:
25310 Display or clear cursor of window W. If ON is zero, clear the
25311 cursor. If it is non-zero, display the cursor. If ON is nonzero,
25312 where to put the cursor is specified by HPOS, VPOS, X and Y. */
25313
25314 void
25315 display_and_set_cursor (struct window *w, int on,
25316 int hpos, int vpos, int x, int y)
25317 {
25318 struct frame *f = XFRAME (w->frame);
25319 int new_cursor_type;
25320 int new_cursor_width;
25321 int active_cursor;
25322 struct glyph_row *glyph_row;
25323 struct glyph *glyph;
25324
25325 /* This is pointless on invisible frames, and dangerous on garbaged
25326 windows and frames; in the latter case, the frame or window may
25327 be in the midst of changing its size, and x and y may be off the
25328 window. */
25329 if (! FRAME_VISIBLE_P (f)
25330 || FRAME_GARBAGED_P (f)
25331 || vpos >= w->current_matrix->nrows
25332 || hpos >= w->current_matrix->matrix_w)
25333 return;
25334
25335 /* If cursor is off and we want it off, return quickly. */
25336 if (!on && !w->phys_cursor_on_p)
25337 return;
25338
25339 glyph_row = MATRIX_ROW (w->current_matrix, vpos);
25340 /* If cursor row is not enabled, we don't really know where to
25341 display the cursor. */
25342 if (!glyph_row->enabled_p)
25343 {
25344 w->phys_cursor_on_p = 0;
25345 return;
25346 }
25347
25348 glyph = NULL;
25349 if (!glyph_row->exact_window_width_line_p
25350 || (0 <= hpos && hpos < glyph_row->used[TEXT_AREA]))
25351 glyph = glyph_row->glyphs[TEXT_AREA] + hpos;
25352
25353 xassert (interrupt_input_blocked);
25354
25355 /* Set new_cursor_type to the cursor we want to be displayed. */
25356 new_cursor_type = get_window_cursor_type (w, glyph,
25357 &new_cursor_width, &active_cursor);
25358
25359 /* If cursor is currently being shown and we don't want it to be or
25360 it is in the wrong place, or the cursor type is not what we want,
25361 erase it. */
25362 if (w->phys_cursor_on_p
25363 && (!on
25364 || w->phys_cursor.x != x
25365 || w->phys_cursor.y != y
25366 || new_cursor_type != w->phys_cursor_type
25367 || ((new_cursor_type == BAR_CURSOR || new_cursor_type == HBAR_CURSOR)
25368 && new_cursor_width != w->phys_cursor_width)))
25369 erase_phys_cursor (w);
25370
25371 /* Don't check phys_cursor_on_p here because that flag is only set
25372 to zero in some cases where we know that the cursor has been
25373 completely erased, to avoid the extra work of erasing the cursor
25374 twice. In other words, phys_cursor_on_p can be 1 and the cursor
25375 still not be visible, or it has only been partly erased. */
25376 if (on)
25377 {
25378 w->phys_cursor_ascent = glyph_row->ascent;
25379 w->phys_cursor_height = glyph_row->height;
25380
25381 /* Set phys_cursor_.* before x_draw_.* is called because some
25382 of them may need the information. */
25383 w->phys_cursor.x = x;
25384 w->phys_cursor.y = glyph_row->y;
25385 w->phys_cursor.hpos = hpos;
25386 w->phys_cursor.vpos = vpos;
25387 }
25388
25389 FRAME_RIF (f)->draw_window_cursor (w, glyph_row, x, y,
25390 new_cursor_type, new_cursor_width,
25391 on, active_cursor);
25392 }
25393
25394
25395 /* Switch the display of W's cursor on or off, according to the value
25396 of ON. */
25397
25398 static void
25399 update_window_cursor (struct window *w, int on)
25400 {
25401 /* Don't update cursor in windows whose frame is in the process
25402 of being deleted. */
25403 if (w->current_matrix)
25404 {
25405 BLOCK_INPUT;
25406 display_and_set_cursor (w, on, w->phys_cursor.hpos, w->phys_cursor.vpos,
25407 w->phys_cursor.x, w->phys_cursor.y);
25408 UNBLOCK_INPUT;
25409 }
25410 }
25411
25412
25413 /* Call update_window_cursor with parameter ON_P on all leaf windows
25414 in the window tree rooted at W. */
25415
25416 static void
25417 update_cursor_in_window_tree (struct window *w, int on_p)
25418 {
25419 while (w)
25420 {
25421 if (!NILP (w->hchild))
25422 update_cursor_in_window_tree (XWINDOW (w->hchild), on_p);
25423 else if (!NILP (w->vchild))
25424 update_cursor_in_window_tree (XWINDOW (w->vchild), on_p);
25425 else
25426 update_window_cursor (w, on_p);
25427
25428 w = NILP (w->next) ? 0 : XWINDOW (w->next);
25429 }
25430 }
25431
25432
25433 /* EXPORT:
25434 Display the cursor on window W, or clear it, according to ON_P.
25435 Don't change the cursor's position. */
25436
25437 void
25438 x_update_cursor (struct frame *f, int on_p)
25439 {
25440 update_cursor_in_window_tree (XWINDOW (f->root_window), on_p);
25441 }
25442
25443
25444 /* EXPORT:
25445 Clear the cursor of window W to background color, and mark the
25446 cursor as not shown. This is used when the text where the cursor
25447 is about to be rewritten. */
25448
25449 void
25450 x_clear_cursor (struct window *w)
25451 {
25452 if (FRAME_VISIBLE_P (XFRAME (w->frame)) && w->phys_cursor_on_p)
25453 update_window_cursor (w, 0);
25454 }
25455
25456 #endif /* HAVE_WINDOW_SYSTEM */
25457
25458 /* Implementation of draw_row_with_mouse_face for GUI sessions, GPM,
25459 and MSDOS. */
25460 static void
25461 draw_row_with_mouse_face (struct window *w, int start_x, struct glyph_row *row,
25462 int start_hpos, int end_hpos,
25463 enum draw_glyphs_face draw)
25464 {
25465 #ifdef HAVE_WINDOW_SYSTEM
25466 if (FRAME_WINDOW_P (XFRAME (w->frame)))
25467 {
25468 draw_glyphs (w, start_x, row, TEXT_AREA, start_hpos, end_hpos, draw, 0);
25469 return;
25470 }
25471 #endif
25472 #if defined (HAVE_GPM) || defined (MSDOS)
25473 tty_draw_row_with_mouse_face (w, row, start_hpos, end_hpos, draw);
25474 #endif
25475 }
25476
25477 /* Display the active region described by mouse_face_* according to DRAW. */
25478
25479 static void
25480 show_mouse_face (Mouse_HLInfo *hlinfo, enum draw_glyphs_face draw)
25481 {
25482 struct window *w = XWINDOW (hlinfo->mouse_face_window);
25483 struct frame *f = XFRAME (WINDOW_FRAME (w));
25484
25485 if (/* If window is in the process of being destroyed, don't bother
25486 to do anything. */
25487 w->current_matrix != NULL
25488 /* Don't update mouse highlight if hidden */
25489 && (draw != DRAW_MOUSE_FACE || !hlinfo->mouse_face_hidden)
25490 /* Recognize when we are called to operate on rows that don't exist
25491 anymore. This can happen when a window is split. */
25492 && hlinfo->mouse_face_end_row < w->current_matrix->nrows)
25493 {
25494 int phys_cursor_on_p = w->phys_cursor_on_p;
25495 struct glyph_row *row, *first, *last;
25496
25497 first = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_beg_row);
25498 last = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_end_row);
25499
25500 for (row = first; row <= last && row->enabled_p; ++row)
25501 {
25502 int start_hpos, end_hpos, start_x;
25503
25504 /* For all but the first row, the highlight starts at column 0. */
25505 if (row == first)
25506 {
25507 /* R2L rows have BEG and END in reversed order, but the
25508 screen drawing geometry is always left to right. So
25509 we need to mirror the beginning and end of the
25510 highlighted area in R2L rows. */
25511 if (!row->reversed_p)
25512 {
25513 start_hpos = hlinfo->mouse_face_beg_col;
25514 start_x = hlinfo->mouse_face_beg_x;
25515 }
25516 else if (row == last)
25517 {
25518 start_hpos = hlinfo->mouse_face_end_col;
25519 start_x = hlinfo->mouse_face_end_x;
25520 }
25521 else
25522 {
25523 start_hpos = 0;
25524 start_x = 0;
25525 }
25526 }
25527 else if (row->reversed_p && row == last)
25528 {
25529 start_hpos = hlinfo->mouse_face_end_col;
25530 start_x = hlinfo->mouse_face_end_x;
25531 }
25532 else
25533 {
25534 start_hpos = 0;
25535 start_x = 0;
25536 }
25537
25538 if (row == last)
25539 {
25540 if (!row->reversed_p)
25541 end_hpos = hlinfo->mouse_face_end_col;
25542 else if (row == first)
25543 end_hpos = hlinfo->mouse_face_beg_col;
25544 else
25545 {
25546 end_hpos = row->used[TEXT_AREA];
25547 if (draw == DRAW_NORMAL_TEXT)
25548 row->fill_line_p = 1; /* Clear to end of line */
25549 }
25550 }
25551 else if (row->reversed_p && row == first)
25552 end_hpos = hlinfo->mouse_face_beg_col;
25553 else
25554 {
25555 end_hpos = row->used[TEXT_AREA];
25556 if (draw == DRAW_NORMAL_TEXT)
25557 row->fill_line_p = 1; /* Clear to end of line */
25558 }
25559
25560 if (end_hpos > start_hpos)
25561 {
25562 draw_row_with_mouse_face (w, start_x, row,
25563 start_hpos, end_hpos, draw);
25564
25565 row->mouse_face_p
25566 = draw == DRAW_MOUSE_FACE || draw == DRAW_IMAGE_RAISED;
25567 }
25568 }
25569
25570 #ifdef HAVE_WINDOW_SYSTEM
25571 /* When we've written over the cursor, arrange for it to
25572 be displayed again. */
25573 if (FRAME_WINDOW_P (f)
25574 && phys_cursor_on_p && !w->phys_cursor_on_p)
25575 {
25576 BLOCK_INPUT;
25577 display_and_set_cursor (w, 1,
25578 w->phys_cursor.hpos, w->phys_cursor.vpos,
25579 w->phys_cursor.x, w->phys_cursor.y);
25580 UNBLOCK_INPUT;
25581 }
25582 #endif /* HAVE_WINDOW_SYSTEM */
25583 }
25584
25585 #ifdef HAVE_WINDOW_SYSTEM
25586 /* Change the mouse cursor. */
25587 if (FRAME_WINDOW_P (f))
25588 {
25589 if (draw == DRAW_NORMAL_TEXT
25590 && !EQ (hlinfo->mouse_face_window, f->tool_bar_window))
25591 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->text_cursor);
25592 else if (draw == DRAW_MOUSE_FACE)
25593 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->hand_cursor);
25594 else
25595 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->nontext_cursor);
25596 }
25597 #endif /* HAVE_WINDOW_SYSTEM */
25598 }
25599
25600 /* EXPORT:
25601 Clear out the mouse-highlighted active region.
25602 Redraw it un-highlighted first. Value is non-zero if mouse
25603 face was actually drawn unhighlighted. */
25604
25605 int
25606 clear_mouse_face (Mouse_HLInfo *hlinfo)
25607 {
25608 int cleared = 0;
25609
25610 if (!hlinfo->mouse_face_hidden && !NILP (hlinfo->mouse_face_window))
25611 {
25612 show_mouse_face (hlinfo, DRAW_NORMAL_TEXT);
25613 cleared = 1;
25614 }
25615
25616 hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
25617 hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
25618 hlinfo->mouse_face_window = Qnil;
25619 hlinfo->mouse_face_overlay = Qnil;
25620 return cleared;
25621 }
25622
25623 /* Return non-zero if the coordinates HPOS and VPOS on windows W are
25624 within the mouse face on that window. */
25625 static int
25626 coords_in_mouse_face_p (struct window *w, int hpos, int vpos)
25627 {
25628 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame));
25629
25630 /* Quickly resolve the easy cases. */
25631 if (!(WINDOWP (hlinfo->mouse_face_window)
25632 && XWINDOW (hlinfo->mouse_face_window) == w))
25633 return 0;
25634 if (vpos < hlinfo->mouse_face_beg_row
25635 || vpos > hlinfo->mouse_face_end_row)
25636 return 0;
25637 if (vpos > hlinfo->mouse_face_beg_row
25638 && vpos < hlinfo->mouse_face_end_row)
25639 return 1;
25640
25641 if (!MATRIX_ROW (w->current_matrix, vpos)->reversed_p)
25642 {
25643 if (hlinfo->mouse_face_beg_row == hlinfo->mouse_face_end_row)
25644 {
25645 if (hlinfo->mouse_face_beg_col <= hpos && hpos < hlinfo->mouse_face_end_col)
25646 return 1;
25647 }
25648 else if ((vpos == hlinfo->mouse_face_beg_row
25649 && hpos >= hlinfo->mouse_face_beg_col)
25650 || (vpos == hlinfo->mouse_face_end_row
25651 && hpos < hlinfo->mouse_face_end_col))
25652 return 1;
25653 }
25654 else
25655 {
25656 if (hlinfo->mouse_face_beg_row == hlinfo->mouse_face_end_row)
25657 {
25658 if (hlinfo->mouse_face_end_col < hpos && hpos <= hlinfo->mouse_face_beg_col)
25659 return 1;
25660 }
25661 else if ((vpos == hlinfo->mouse_face_beg_row
25662 && hpos <= hlinfo->mouse_face_beg_col)
25663 || (vpos == hlinfo->mouse_face_end_row
25664 && hpos > hlinfo->mouse_face_end_col))
25665 return 1;
25666 }
25667 return 0;
25668 }
25669
25670
25671 /* EXPORT:
25672 Non-zero if physical cursor of window W is within mouse face. */
25673
25674 int
25675 cursor_in_mouse_face_p (struct window *w)
25676 {
25677 return coords_in_mouse_face_p (w, w->phys_cursor.hpos, w->phys_cursor.vpos);
25678 }
25679
25680
25681 \f
25682 /* Find the glyph rows START_ROW and END_ROW of window W that display
25683 characters between buffer positions START_CHARPOS and END_CHARPOS
25684 (excluding END_CHARPOS). This is similar to row_containing_pos,
25685 but is more accurate when bidi reordering makes buffer positions
25686 change non-linearly with glyph rows. */
25687 static void
25688 rows_from_pos_range (struct window *w,
25689 EMACS_INT start_charpos, EMACS_INT end_charpos,
25690 struct glyph_row **start, struct glyph_row **end)
25691 {
25692 struct glyph_row *first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
25693 int last_y = window_text_bottom_y (w);
25694 struct glyph_row *row;
25695
25696 *start = NULL;
25697 *end = NULL;
25698
25699 while (!first->enabled_p
25700 && first < MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w))
25701 first++;
25702
25703 /* Find the START row. */
25704 for (row = first;
25705 row->enabled_p && MATRIX_ROW_BOTTOM_Y (row) <= last_y;
25706 row++)
25707 {
25708 /* A row can potentially be the START row if the range of the
25709 characters it displays intersects the range
25710 [START_CHARPOS..END_CHARPOS). */
25711 if (! ((start_charpos < MATRIX_ROW_START_CHARPOS (row)
25712 && end_charpos < MATRIX_ROW_START_CHARPOS (row))
25713 /* See the commentary in row_containing_pos, for the
25714 explanation of the complicated way to check whether
25715 some position is beyond the end of the characters
25716 displayed by a row. */
25717 || ((start_charpos > MATRIX_ROW_END_CHARPOS (row)
25718 || (start_charpos == MATRIX_ROW_END_CHARPOS (row)
25719 && !row->ends_at_zv_p
25720 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
25721 && (end_charpos > MATRIX_ROW_END_CHARPOS (row)
25722 || (end_charpos == MATRIX_ROW_END_CHARPOS (row)
25723 && !row->ends_at_zv_p
25724 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))))))
25725 {
25726 /* Found a candidate row. Now make sure at least one of the
25727 glyphs it displays has a charpos from the range
25728 [START_CHARPOS..END_CHARPOS).
25729
25730 This is not obvious because bidi reordering could make
25731 buffer positions of a row be 1,2,3,102,101,100, and if we
25732 want to highlight characters in [50..60), we don't want
25733 this row, even though [50..60) does intersect [1..103),
25734 the range of character positions given by the row's start
25735 and end positions. */
25736 struct glyph *g = row->glyphs[TEXT_AREA];
25737 struct glyph *e = g + row->used[TEXT_AREA];
25738
25739 while (g < e)
25740 {
25741 if ((BUFFERP (g->object) || INTEGERP (g->object))
25742 && start_charpos <= g->charpos && g->charpos < end_charpos)
25743 *start = row;
25744 g++;
25745 }
25746 if (*start)
25747 break;
25748 }
25749 }
25750
25751 /* Find the END row. */
25752 if (!*start
25753 /* If the last row is partially visible, start looking for END
25754 from that row, instead of starting from FIRST. */
25755 && !(row->enabled_p
25756 && row->y < last_y && MATRIX_ROW_BOTTOM_Y (row) > last_y))
25757 row = first;
25758 for ( ; row->enabled_p && MATRIX_ROW_BOTTOM_Y (row) <= last_y; row++)
25759 {
25760 struct glyph_row *next = row + 1;
25761
25762 if (!next->enabled_p
25763 || next >= MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w)
25764 /* The first row >= START whose range of displayed characters
25765 does NOT intersect the range [START_CHARPOS..END_CHARPOS]
25766 is the row END + 1. */
25767 || (start_charpos < MATRIX_ROW_START_CHARPOS (next)
25768 && end_charpos < MATRIX_ROW_START_CHARPOS (next))
25769 || ((start_charpos > MATRIX_ROW_END_CHARPOS (next)
25770 || (start_charpos == MATRIX_ROW_END_CHARPOS (next)
25771 && !next->ends_at_zv_p
25772 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (next)))
25773 && (end_charpos > MATRIX_ROW_END_CHARPOS (next)
25774 || (end_charpos == MATRIX_ROW_END_CHARPOS (next)
25775 && !next->ends_at_zv_p
25776 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (next)))))
25777 {
25778 *end = row;
25779 break;
25780 }
25781 else
25782 {
25783 /* If the next row's edges intersect [START_CHARPOS..END_CHARPOS],
25784 but none of the characters it displays are in the range, it is
25785 also END + 1. */
25786 struct glyph *g = next->glyphs[TEXT_AREA];
25787 struct glyph *e = g + next->used[TEXT_AREA];
25788
25789 while (g < e)
25790 {
25791 if ((BUFFERP (g->object) || INTEGERP (g->object))
25792 && start_charpos <= g->charpos && g->charpos < end_charpos)
25793 break;
25794 g++;
25795 }
25796 if (g == e)
25797 {
25798 *end = row;
25799 break;
25800 }
25801 }
25802 }
25803 }
25804
25805 /* This function sets the mouse_face_* elements of HLINFO, assuming
25806 the mouse cursor is on a glyph with buffer charpos MOUSE_CHARPOS in
25807 window WINDOW. START_CHARPOS and END_CHARPOS are buffer positions
25808 for the overlay or run of text properties specifying the mouse
25809 face. BEFORE_STRING and AFTER_STRING, if non-nil, are a
25810 before-string and after-string that must also be highlighted.
25811 COVER_STRING, if non-nil, is a display string that may cover some
25812 or all of the highlighted text. */
25813
25814 static void
25815 mouse_face_from_buffer_pos (Lisp_Object window,
25816 Mouse_HLInfo *hlinfo,
25817 EMACS_INT mouse_charpos,
25818 EMACS_INT start_charpos,
25819 EMACS_INT end_charpos,
25820 Lisp_Object before_string,
25821 Lisp_Object after_string,
25822 Lisp_Object cover_string)
25823 {
25824 struct window *w = XWINDOW (window);
25825 struct glyph_row *first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
25826 struct glyph_row *r1, *r2;
25827 struct glyph *glyph, *end;
25828 EMACS_INT ignore, pos;
25829 int x;
25830
25831 xassert (NILP (cover_string) || STRINGP (cover_string));
25832 xassert (NILP (before_string) || STRINGP (before_string));
25833 xassert (NILP (after_string) || STRINGP (after_string));
25834
25835 /* Find the rows corresponding to START_CHARPOS and END_CHARPOS. */
25836 rows_from_pos_range (w, start_charpos, end_charpos, &r1, &r2);
25837 if (r1 == NULL)
25838 r1 = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
25839 /* If the before-string or display-string contains newlines,
25840 rows_from_pos_range skips to its last row. Move back. */
25841 if (!NILP (before_string) || !NILP (cover_string))
25842 {
25843 struct glyph_row *prev;
25844 while ((prev = r1 - 1, prev >= first)
25845 && MATRIX_ROW_END_CHARPOS (prev) == start_charpos
25846 && prev->used[TEXT_AREA] > 0)
25847 {
25848 struct glyph *beg = prev->glyphs[TEXT_AREA];
25849 glyph = beg + prev->used[TEXT_AREA];
25850 while (--glyph >= beg && INTEGERP (glyph->object));
25851 if (glyph < beg
25852 || !(EQ (glyph->object, before_string)
25853 || EQ (glyph->object, cover_string)))
25854 break;
25855 r1 = prev;
25856 }
25857 }
25858 if (r2 == NULL)
25859 {
25860 r2 = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
25861 hlinfo->mouse_face_past_end = 1;
25862 }
25863 else if (!NILP (after_string))
25864 {
25865 /* If the after-string has newlines, advance to its last row. */
25866 struct glyph_row *next;
25867 struct glyph_row *last
25868 = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
25869
25870 for (next = r2 + 1;
25871 next <= last
25872 && next->used[TEXT_AREA] > 0
25873 && EQ (next->glyphs[TEXT_AREA]->object, after_string);
25874 ++next)
25875 r2 = next;
25876 }
25877 /* The rest of the display engine assumes that mouse_face_beg_row is
25878 either above below mouse_face_end_row or identical to it. But
25879 with bidi-reordered continued lines, the row for START_CHARPOS
25880 could be below the row for END_CHARPOS. If so, swap the rows and
25881 store them in correct order. */
25882 if (r1->y > r2->y)
25883 {
25884 struct glyph_row *tem = r2;
25885
25886 r2 = r1;
25887 r1 = tem;
25888 }
25889
25890 hlinfo->mouse_face_beg_y = r1->y;
25891 hlinfo->mouse_face_beg_row = MATRIX_ROW_VPOS (r1, w->current_matrix);
25892 hlinfo->mouse_face_end_y = r2->y;
25893 hlinfo->mouse_face_end_row = MATRIX_ROW_VPOS (r2, w->current_matrix);
25894
25895 /* For a bidi-reordered row, the positions of BEFORE_STRING,
25896 AFTER_STRING, COVER_STRING, START_CHARPOS, and END_CHARPOS
25897 could be anywhere in the row and in any order. The strategy
25898 below is to find the leftmost and the rightmost glyph that
25899 belongs to either of these 3 strings, or whose position is
25900 between START_CHARPOS and END_CHARPOS, and highlight all the
25901 glyphs between those two. This may cover more than just the text
25902 between START_CHARPOS and END_CHARPOS if the range of characters
25903 strides the bidi level boundary, e.g. if the beginning is in R2L
25904 text while the end is in L2R text or vice versa. */
25905 if (!r1->reversed_p)
25906 {
25907 /* This row is in a left to right paragraph. Scan it left to
25908 right. */
25909 glyph = r1->glyphs[TEXT_AREA];
25910 end = glyph + r1->used[TEXT_AREA];
25911 x = r1->x;
25912
25913 /* Skip truncation glyphs at the start of the glyph row. */
25914 if (r1->displays_text_p)
25915 for (; glyph < end
25916 && INTEGERP (glyph->object)
25917 && glyph->charpos < 0;
25918 ++glyph)
25919 x += glyph->pixel_width;
25920
25921 /* Scan the glyph row, looking for BEFORE_STRING, AFTER_STRING,
25922 or COVER_STRING, and the first glyph from buffer whose
25923 position is between START_CHARPOS and END_CHARPOS. */
25924 for (; glyph < end
25925 && !INTEGERP (glyph->object)
25926 && !EQ (glyph->object, cover_string)
25927 && !(BUFFERP (glyph->object)
25928 && (glyph->charpos >= start_charpos
25929 && glyph->charpos < end_charpos));
25930 ++glyph)
25931 {
25932 /* BEFORE_STRING or AFTER_STRING are only relevant if they
25933 are present at buffer positions between START_CHARPOS and
25934 END_CHARPOS, or if they come from an overlay. */
25935 if (EQ (glyph->object, before_string))
25936 {
25937 pos = string_buffer_position (before_string,
25938 start_charpos);
25939 /* If pos == 0, it means before_string came from an
25940 overlay, not from a buffer position. */
25941 if (!pos || (pos >= start_charpos && pos < end_charpos))
25942 break;
25943 }
25944 else if (EQ (glyph->object, after_string))
25945 {
25946 pos = string_buffer_position (after_string, end_charpos);
25947 if (!pos || (pos >= start_charpos && pos < end_charpos))
25948 break;
25949 }
25950 x += glyph->pixel_width;
25951 }
25952 hlinfo->mouse_face_beg_x = x;
25953 hlinfo->mouse_face_beg_col = glyph - r1->glyphs[TEXT_AREA];
25954 }
25955 else
25956 {
25957 /* This row is in a right to left paragraph. Scan it right to
25958 left. */
25959 struct glyph *g;
25960
25961 end = r1->glyphs[TEXT_AREA] - 1;
25962 glyph = end + r1->used[TEXT_AREA];
25963
25964 /* Skip truncation glyphs at the start of the glyph row. */
25965 if (r1->displays_text_p)
25966 for (; glyph > end
25967 && INTEGERP (glyph->object)
25968 && glyph->charpos < 0;
25969 --glyph)
25970 ;
25971
25972 /* Scan the glyph row, looking for BEFORE_STRING, AFTER_STRING,
25973 or COVER_STRING, and the first glyph from buffer whose
25974 position is between START_CHARPOS and END_CHARPOS. */
25975 for (; glyph > end
25976 && !INTEGERP (glyph->object)
25977 && !EQ (glyph->object, cover_string)
25978 && !(BUFFERP (glyph->object)
25979 && (glyph->charpos >= start_charpos
25980 && glyph->charpos < end_charpos));
25981 --glyph)
25982 {
25983 /* BEFORE_STRING or AFTER_STRING are only relevant if they
25984 are present at buffer positions between START_CHARPOS and
25985 END_CHARPOS, or if they come from an overlay. */
25986 if (EQ (glyph->object, before_string))
25987 {
25988 pos = string_buffer_position (before_string, start_charpos);
25989 /* If pos == 0, it means before_string came from an
25990 overlay, not from a buffer position. */
25991 if (!pos || (pos >= start_charpos && pos < end_charpos))
25992 break;
25993 }
25994 else if (EQ (glyph->object, after_string))
25995 {
25996 pos = string_buffer_position (after_string, end_charpos);
25997 if (!pos || (pos >= start_charpos && pos < end_charpos))
25998 break;
25999 }
26000 }
26001
26002 glyph++; /* first glyph to the right of the highlighted area */
26003 for (g = r1->glyphs[TEXT_AREA], x = r1->x; g < glyph; g++)
26004 x += g->pixel_width;
26005 hlinfo->mouse_face_beg_x = x;
26006 hlinfo->mouse_face_beg_col = glyph - r1->glyphs[TEXT_AREA];
26007 }
26008
26009 /* If the highlight ends in a different row, compute GLYPH and END
26010 for the end row. Otherwise, reuse the values computed above for
26011 the row where the highlight begins. */
26012 if (r2 != r1)
26013 {
26014 if (!r2->reversed_p)
26015 {
26016 glyph = r2->glyphs[TEXT_AREA];
26017 end = glyph + r2->used[TEXT_AREA];
26018 x = r2->x;
26019 }
26020 else
26021 {
26022 end = r2->glyphs[TEXT_AREA] - 1;
26023 glyph = end + r2->used[TEXT_AREA];
26024 }
26025 }
26026
26027 if (!r2->reversed_p)
26028 {
26029 /* Skip truncation and continuation glyphs near the end of the
26030 row, and also blanks and stretch glyphs inserted by
26031 extend_face_to_end_of_line. */
26032 while (end > glyph
26033 && INTEGERP ((end - 1)->object)
26034 && (end - 1)->charpos <= 0)
26035 --end;
26036 /* Scan the rest of the glyph row from the end, looking for the
26037 first glyph that comes from BEFORE_STRING, AFTER_STRING, or
26038 COVER_STRING, or whose position is between START_CHARPOS
26039 and END_CHARPOS */
26040 for (--end;
26041 end > glyph
26042 && !INTEGERP (end->object)
26043 && !EQ (end->object, cover_string)
26044 && !(BUFFERP (end->object)
26045 && (end->charpos >= start_charpos
26046 && end->charpos < end_charpos));
26047 --end)
26048 {
26049 /* BEFORE_STRING or AFTER_STRING are only relevant if they
26050 are present at buffer positions between START_CHARPOS and
26051 END_CHARPOS, or if they come from an overlay. */
26052 if (EQ (end->object, before_string))
26053 {
26054 pos = string_buffer_position (before_string, start_charpos);
26055 if (!pos || (pos >= start_charpos && pos < end_charpos))
26056 break;
26057 }
26058 else if (EQ (end->object, after_string))
26059 {
26060 pos = string_buffer_position (after_string, end_charpos);
26061 if (!pos || (pos >= start_charpos && pos < end_charpos))
26062 break;
26063 }
26064 }
26065 /* Find the X coordinate of the last glyph to be highlighted. */
26066 for (; glyph <= end; ++glyph)
26067 x += glyph->pixel_width;
26068
26069 hlinfo->mouse_face_end_x = x;
26070 hlinfo->mouse_face_end_col = glyph - r2->glyphs[TEXT_AREA];
26071 }
26072 else
26073 {
26074 /* Skip truncation and continuation glyphs near the end of the
26075 row, and also blanks and stretch glyphs inserted by
26076 extend_face_to_end_of_line. */
26077 x = r2->x;
26078 end++;
26079 while (end < glyph
26080 && INTEGERP (end->object)
26081 && end->charpos <= 0)
26082 {
26083 x += end->pixel_width;
26084 ++end;
26085 }
26086 /* Scan the rest of the glyph row from the end, looking for the
26087 first glyph that comes from BEFORE_STRING, AFTER_STRING, or
26088 COVER_STRING, or whose position is between START_CHARPOS
26089 and END_CHARPOS */
26090 for ( ;
26091 end < glyph
26092 && !INTEGERP (end->object)
26093 && !EQ (end->object, cover_string)
26094 && !(BUFFERP (end->object)
26095 && (end->charpos >= start_charpos
26096 && end->charpos < end_charpos));
26097 ++end)
26098 {
26099 /* BEFORE_STRING or AFTER_STRING are only relevant if they
26100 are present at buffer positions between START_CHARPOS and
26101 END_CHARPOS, or if they come from an overlay. */
26102 if (EQ (end->object, before_string))
26103 {
26104 pos = string_buffer_position (before_string, start_charpos);
26105 if (!pos || (pos >= start_charpos && pos < end_charpos))
26106 break;
26107 }
26108 else if (EQ (end->object, after_string))
26109 {
26110 pos = string_buffer_position (after_string, end_charpos);
26111 if (!pos || (pos >= start_charpos && pos < end_charpos))
26112 break;
26113 }
26114 x += end->pixel_width;
26115 }
26116 hlinfo->mouse_face_end_x = x;
26117 hlinfo->mouse_face_end_col = end - r2->glyphs[TEXT_AREA];
26118 }
26119
26120 hlinfo->mouse_face_window = window;
26121 hlinfo->mouse_face_face_id
26122 = face_at_buffer_position (w, mouse_charpos, 0, 0, &ignore,
26123 mouse_charpos + 1,
26124 !hlinfo->mouse_face_hidden, -1);
26125 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
26126 }
26127
26128 /* The following function is not used anymore (replaced with
26129 mouse_face_from_string_pos), but I leave it here for the time
26130 being, in case someone would. */
26131
26132 #if 0 /* not used */
26133
26134 /* Find the position of the glyph for position POS in OBJECT in
26135 window W's current matrix, and return in *X, *Y the pixel
26136 coordinates, and return in *HPOS, *VPOS the column/row of the glyph.
26137
26138 RIGHT_P non-zero means return the position of the right edge of the
26139 glyph, RIGHT_P zero means return the left edge position.
26140
26141 If no glyph for POS exists in the matrix, return the position of
26142 the glyph with the next smaller position that is in the matrix, if
26143 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS
26144 exists in the matrix, return the position of the glyph with the
26145 next larger position in OBJECT.
26146
26147 Value is non-zero if a glyph was found. */
26148
26149 static int
26150 fast_find_string_pos (struct window *w, EMACS_INT pos, Lisp_Object object,
26151 int *hpos, int *vpos, int *x, int *y, int right_p)
26152 {
26153 int yb = window_text_bottom_y (w);
26154 struct glyph_row *r;
26155 struct glyph *best_glyph = NULL;
26156 struct glyph_row *best_row = NULL;
26157 int best_x = 0;
26158
26159 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
26160 r->enabled_p && r->y < yb;
26161 ++r)
26162 {
26163 struct glyph *g = r->glyphs[TEXT_AREA];
26164 struct glyph *e = g + r->used[TEXT_AREA];
26165 int gx;
26166
26167 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
26168 if (EQ (g->object, object))
26169 {
26170 if (g->charpos == pos)
26171 {
26172 best_glyph = g;
26173 best_x = gx;
26174 best_row = r;
26175 goto found;
26176 }
26177 else if (best_glyph == NULL
26178 || ((eabs (g->charpos - pos)
26179 < eabs (best_glyph->charpos - pos))
26180 && (right_p
26181 ? g->charpos < pos
26182 : g->charpos > pos)))
26183 {
26184 best_glyph = g;
26185 best_x = gx;
26186 best_row = r;
26187 }
26188 }
26189 }
26190
26191 found:
26192
26193 if (best_glyph)
26194 {
26195 *x = best_x;
26196 *hpos = best_glyph - best_row->glyphs[TEXT_AREA];
26197
26198 if (right_p)
26199 {
26200 *x += best_glyph->pixel_width;
26201 ++*hpos;
26202 }
26203
26204 *y = best_row->y;
26205 *vpos = best_row - w->current_matrix->rows;
26206 }
26207
26208 return best_glyph != NULL;
26209 }
26210 #endif /* not used */
26211
26212 /* Find the positions of the first and the last glyphs in window W's
26213 current matrix that occlude positions [STARTPOS..ENDPOS] in OBJECT
26214 (assumed to be a string), and return in HLINFO's mouse_face_*
26215 members the pixel and column/row coordinates of those glyphs. */
26216
26217 static void
26218 mouse_face_from_string_pos (struct window *w, Mouse_HLInfo *hlinfo,
26219 Lisp_Object object,
26220 EMACS_INT startpos, EMACS_INT endpos)
26221 {
26222 int yb = window_text_bottom_y (w);
26223 struct glyph_row *r;
26224 struct glyph *g, *e;
26225 int gx;
26226 int found = 0;
26227
26228 /* Find the glyph row with at least one position in the range
26229 [STARTPOS..ENDPOS], and the first glyph in that row whose
26230 position belongs to that range. */
26231 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
26232 r->enabled_p && r->y < yb;
26233 ++r)
26234 {
26235 if (!r->reversed_p)
26236 {
26237 g = r->glyphs[TEXT_AREA];
26238 e = g + r->used[TEXT_AREA];
26239 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
26240 if (EQ (g->object, object)
26241 && startpos <= g->charpos && g->charpos <= endpos)
26242 {
26243 hlinfo->mouse_face_beg_row = r - w->current_matrix->rows;
26244 hlinfo->mouse_face_beg_y = r->y;
26245 hlinfo->mouse_face_beg_col = g - r->glyphs[TEXT_AREA];
26246 hlinfo->mouse_face_beg_x = gx;
26247 found = 1;
26248 break;
26249 }
26250 }
26251 else
26252 {
26253 struct glyph *g1;
26254
26255 e = r->glyphs[TEXT_AREA];
26256 g = e + r->used[TEXT_AREA];
26257 for ( ; g > e; --g)
26258 if (EQ ((g-1)->object, object)
26259 && startpos <= (g-1)->charpos && (g-1)->charpos <= endpos)
26260 {
26261 hlinfo->mouse_face_beg_row = r - w->current_matrix->rows;
26262 hlinfo->mouse_face_beg_y = r->y;
26263 hlinfo->mouse_face_beg_col = g - r->glyphs[TEXT_AREA];
26264 for (gx = r->x, g1 = r->glyphs[TEXT_AREA]; g1 < g; ++g1)
26265 gx += g1->pixel_width;
26266 hlinfo->mouse_face_beg_x = gx;
26267 found = 1;
26268 break;
26269 }
26270 }
26271 if (found)
26272 break;
26273 }
26274
26275 if (!found)
26276 return;
26277
26278 /* Starting with the next row, look for the first row which does NOT
26279 include any glyphs whose positions are in the range. */
26280 for (++r; r->enabled_p && r->y < yb; ++r)
26281 {
26282 g = r->glyphs[TEXT_AREA];
26283 e = g + r->used[TEXT_AREA];
26284 found = 0;
26285 for ( ; g < e; ++g)
26286 if (EQ (g->object, object)
26287 && startpos <= g->charpos && g->charpos <= endpos)
26288 {
26289 found = 1;
26290 break;
26291 }
26292 if (!found)
26293 break;
26294 }
26295
26296 /* The highlighted region ends on the previous row. */
26297 r--;
26298
26299 /* Set the end row and its vertical pixel coordinate. */
26300 hlinfo->mouse_face_end_row = r - w->current_matrix->rows;
26301 hlinfo->mouse_face_end_y = r->y;
26302
26303 /* Compute and set the end column and the end column's horizontal
26304 pixel coordinate. */
26305 if (!r->reversed_p)
26306 {
26307 g = r->glyphs[TEXT_AREA];
26308 e = g + r->used[TEXT_AREA];
26309 for ( ; e > g; --e)
26310 if (EQ ((e-1)->object, object)
26311 && startpos <= (e-1)->charpos && (e-1)->charpos <= endpos)
26312 break;
26313 hlinfo->mouse_face_end_col = e - g;
26314
26315 for (gx = r->x; g < e; ++g)
26316 gx += g->pixel_width;
26317 hlinfo->mouse_face_end_x = gx;
26318 }
26319 else
26320 {
26321 e = r->glyphs[TEXT_AREA];
26322 g = e + r->used[TEXT_AREA];
26323 for (gx = r->x ; e < g; ++e)
26324 {
26325 if (EQ (e->object, object)
26326 && startpos <= e->charpos && e->charpos <= endpos)
26327 break;
26328 gx += e->pixel_width;
26329 }
26330 hlinfo->mouse_face_end_col = e - r->glyphs[TEXT_AREA];
26331 hlinfo->mouse_face_end_x = gx;
26332 }
26333 }
26334
26335 #ifdef HAVE_WINDOW_SYSTEM
26336
26337 /* See if position X, Y is within a hot-spot of an image. */
26338
26339 static int
26340 on_hot_spot_p (Lisp_Object hot_spot, int x, int y)
26341 {
26342 if (!CONSP (hot_spot))
26343 return 0;
26344
26345 if (EQ (XCAR (hot_spot), Qrect))
26346 {
26347 /* CDR is (Top-Left . Bottom-Right) = ((x0 . y0) . (x1 . y1)) */
26348 Lisp_Object rect = XCDR (hot_spot);
26349 Lisp_Object tem;
26350 if (!CONSP (rect))
26351 return 0;
26352 if (!CONSP (XCAR (rect)))
26353 return 0;
26354 if (!CONSP (XCDR (rect)))
26355 return 0;
26356 if (!(tem = XCAR (XCAR (rect)), INTEGERP (tem) && x >= XINT (tem)))
26357 return 0;
26358 if (!(tem = XCDR (XCAR (rect)), INTEGERP (tem) && y >= XINT (tem)))
26359 return 0;
26360 if (!(tem = XCAR (XCDR (rect)), INTEGERP (tem) && x <= XINT (tem)))
26361 return 0;
26362 if (!(tem = XCDR (XCDR (rect)), INTEGERP (tem) && y <= XINT (tem)))
26363 return 0;
26364 return 1;
26365 }
26366 else if (EQ (XCAR (hot_spot), Qcircle))
26367 {
26368 /* CDR is (Center . Radius) = ((x0 . y0) . r) */
26369 Lisp_Object circ = XCDR (hot_spot);
26370 Lisp_Object lr, lx0, ly0;
26371 if (CONSP (circ)
26372 && CONSP (XCAR (circ))
26373 && (lr = XCDR (circ), INTEGERP (lr) || FLOATP (lr))
26374 && (lx0 = XCAR (XCAR (circ)), INTEGERP (lx0))
26375 && (ly0 = XCDR (XCAR (circ)), INTEGERP (ly0)))
26376 {
26377 double r = XFLOATINT (lr);
26378 double dx = XINT (lx0) - x;
26379 double dy = XINT (ly0) - y;
26380 return (dx * dx + dy * dy <= r * r);
26381 }
26382 }
26383 else if (EQ (XCAR (hot_spot), Qpoly))
26384 {
26385 /* CDR is [x0 y0 x1 y1 x2 y2 ...x(n-1) y(n-1)] */
26386 if (VECTORP (XCDR (hot_spot)))
26387 {
26388 struct Lisp_Vector *v = XVECTOR (XCDR (hot_spot));
26389 Lisp_Object *poly = v->contents;
26390 int n = v->header.size;
26391 int i;
26392 int inside = 0;
26393 Lisp_Object lx, ly;
26394 int x0, y0;
26395
26396 /* Need an even number of coordinates, and at least 3 edges. */
26397 if (n < 6 || n & 1)
26398 return 0;
26399
26400 /* Count edge segments intersecting line from (X,Y) to (X,infinity).
26401 If count is odd, we are inside polygon. Pixels on edges
26402 may or may not be included depending on actual geometry of the
26403 polygon. */
26404 if ((lx = poly[n-2], !INTEGERP (lx))
26405 || (ly = poly[n-1], !INTEGERP (lx)))
26406 return 0;
26407 x0 = XINT (lx), y0 = XINT (ly);
26408 for (i = 0; i < n; i += 2)
26409 {
26410 int x1 = x0, y1 = y0;
26411 if ((lx = poly[i], !INTEGERP (lx))
26412 || (ly = poly[i+1], !INTEGERP (ly)))
26413 return 0;
26414 x0 = XINT (lx), y0 = XINT (ly);
26415
26416 /* Does this segment cross the X line? */
26417 if (x0 >= x)
26418 {
26419 if (x1 >= x)
26420 continue;
26421 }
26422 else if (x1 < x)
26423 continue;
26424 if (y > y0 && y > y1)
26425 continue;
26426 if (y < y0 + ((y1 - y0) * (x - x0)) / (x1 - x0))
26427 inside = !inside;
26428 }
26429 return inside;
26430 }
26431 }
26432 return 0;
26433 }
26434
26435 Lisp_Object
26436 find_hot_spot (Lisp_Object map, int x, int y)
26437 {
26438 while (CONSP (map))
26439 {
26440 if (CONSP (XCAR (map))
26441 && on_hot_spot_p (XCAR (XCAR (map)), x, y))
26442 return XCAR (map);
26443 map = XCDR (map);
26444 }
26445
26446 return Qnil;
26447 }
26448
26449 DEFUN ("lookup-image-map", Flookup_image_map, Slookup_image_map,
26450 3, 3, 0,
26451 doc: /* Lookup in image map MAP coordinates X and Y.
26452 An image map is an alist where each element has the format (AREA ID PLIST).
26453 An AREA is specified as either a rectangle, a circle, or a polygon:
26454 A rectangle is a cons (rect . ((x0 . y0) . (x1 . y1))) specifying the
26455 pixel coordinates of the upper left and bottom right corners.
26456 A circle is a cons (circle . ((x0 . y0) . r)) specifying the center
26457 and the radius of the circle; r may be a float or integer.
26458 A polygon is a cons (poly . [x0 y0 x1 y1 ...]) where each pair in the
26459 vector describes one corner in the polygon.
26460 Returns the alist element for the first matching AREA in MAP. */)
26461 (Lisp_Object map, Lisp_Object x, Lisp_Object y)
26462 {
26463 if (NILP (map))
26464 return Qnil;
26465
26466 CHECK_NUMBER (x);
26467 CHECK_NUMBER (y);
26468
26469 return find_hot_spot (map, XINT (x), XINT (y));
26470 }
26471
26472
26473 /* Display frame CURSOR, optionally using shape defined by POINTER. */
26474 static void
26475 define_frame_cursor1 (struct frame *f, Cursor cursor, Lisp_Object pointer)
26476 {
26477 /* Do not change cursor shape while dragging mouse. */
26478 if (!NILP (do_mouse_tracking))
26479 return;
26480
26481 if (!NILP (pointer))
26482 {
26483 if (EQ (pointer, Qarrow))
26484 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
26485 else if (EQ (pointer, Qhand))
26486 cursor = FRAME_X_OUTPUT (f)->hand_cursor;
26487 else if (EQ (pointer, Qtext))
26488 cursor = FRAME_X_OUTPUT (f)->text_cursor;
26489 else if (EQ (pointer, intern ("hdrag")))
26490 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
26491 #ifdef HAVE_X_WINDOWS
26492 else if (EQ (pointer, intern ("vdrag")))
26493 cursor = FRAME_X_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
26494 #endif
26495 else if (EQ (pointer, intern ("hourglass")))
26496 cursor = FRAME_X_OUTPUT (f)->hourglass_cursor;
26497 else if (EQ (pointer, Qmodeline))
26498 cursor = FRAME_X_OUTPUT (f)->modeline_cursor;
26499 else
26500 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
26501 }
26502
26503 if (cursor != No_Cursor)
26504 FRAME_RIF (f)->define_frame_cursor (f, cursor);
26505 }
26506
26507 #endif /* HAVE_WINDOW_SYSTEM */
26508
26509 /* Take proper action when mouse has moved to the mode or header line
26510 or marginal area AREA of window W, x-position X and y-position Y.
26511 X is relative to the start of the text display area of W, so the
26512 width of bitmap areas and scroll bars must be subtracted to get a
26513 position relative to the start of the mode line. */
26514
26515 static void
26516 note_mode_line_or_margin_highlight (Lisp_Object window, int x, int y,
26517 enum window_part area)
26518 {
26519 struct window *w = XWINDOW (window);
26520 struct frame *f = XFRAME (w->frame);
26521 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
26522 #ifdef HAVE_WINDOW_SYSTEM
26523 Display_Info *dpyinfo;
26524 #endif
26525 Cursor cursor = No_Cursor;
26526 Lisp_Object pointer = Qnil;
26527 int dx, dy, width, height;
26528 EMACS_INT charpos;
26529 Lisp_Object string, object = Qnil;
26530 Lisp_Object pos, help;
26531
26532 Lisp_Object mouse_face;
26533 int original_x_pixel = x;
26534 struct glyph * glyph = NULL, * row_start_glyph = NULL;
26535 struct glyph_row *row;
26536
26537 if (area == ON_MODE_LINE || area == ON_HEADER_LINE)
26538 {
26539 int x0;
26540 struct glyph *end;
26541
26542 /* Kludge alert: mode_line_string takes X/Y in pixels, but
26543 returns them in row/column units! */
26544 string = mode_line_string (w, area, &x, &y, &charpos,
26545 &object, &dx, &dy, &width, &height);
26546
26547 row = (area == ON_MODE_LINE
26548 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
26549 : MATRIX_HEADER_LINE_ROW (w->current_matrix));
26550
26551 /* Find the glyph under the mouse pointer. */
26552 if (row->mode_line_p && row->enabled_p)
26553 {
26554 glyph = row_start_glyph = row->glyphs[TEXT_AREA];
26555 end = glyph + row->used[TEXT_AREA];
26556
26557 for (x0 = original_x_pixel;
26558 glyph < end && x0 >= glyph->pixel_width;
26559 ++glyph)
26560 x0 -= glyph->pixel_width;
26561
26562 if (glyph >= end)
26563 glyph = NULL;
26564 }
26565 }
26566 else
26567 {
26568 x -= WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
26569 /* Kludge alert: marginal_area_string takes X/Y in pixels, but
26570 returns them in row/column units! */
26571 string = marginal_area_string (w, area, &x, &y, &charpos,
26572 &object, &dx, &dy, &width, &height);
26573 }
26574
26575 help = Qnil;
26576
26577 #ifdef HAVE_WINDOW_SYSTEM
26578 if (IMAGEP (object))
26579 {
26580 Lisp_Object image_map, hotspot;
26581 if ((image_map = Fplist_get (XCDR (object), QCmap),
26582 !NILP (image_map))
26583 && (hotspot = find_hot_spot (image_map, dx, dy),
26584 CONSP (hotspot))
26585 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
26586 {
26587 Lisp_Object plist;
26588
26589 /* Could check XCAR (hotspot) to see if we enter/leave this hot-spot.
26590 If so, we could look for mouse-enter, mouse-leave
26591 properties in PLIST (and do something...). */
26592 hotspot = XCDR (hotspot);
26593 if (CONSP (hotspot)
26594 && (plist = XCAR (hotspot), CONSP (plist)))
26595 {
26596 pointer = Fplist_get (plist, Qpointer);
26597 if (NILP (pointer))
26598 pointer = Qhand;
26599 help = Fplist_get (plist, Qhelp_echo);
26600 if (!NILP (help))
26601 {
26602 help_echo_string = help;
26603 /* Is this correct? ++kfs */
26604 XSETWINDOW (help_echo_window, w);
26605 help_echo_object = w->buffer;
26606 help_echo_pos = charpos;
26607 }
26608 }
26609 }
26610 if (NILP (pointer))
26611 pointer = Fplist_get (XCDR (object), QCpointer);
26612 }
26613 #endif /* HAVE_WINDOW_SYSTEM */
26614
26615 if (STRINGP (string))
26616 {
26617 pos = make_number (charpos);
26618 /* If we're on a string with `help-echo' text property, arrange
26619 for the help to be displayed. This is done by setting the
26620 global variable help_echo_string to the help string. */
26621 if (NILP (help))
26622 {
26623 help = Fget_text_property (pos, Qhelp_echo, string);
26624 if (!NILP (help))
26625 {
26626 help_echo_string = help;
26627 XSETWINDOW (help_echo_window, w);
26628 help_echo_object = string;
26629 help_echo_pos = charpos;
26630 }
26631 }
26632
26633 #ifdef HAVE_WINDOW_SYSTEM
26634 if (FRAME_WINDOW_P (f))
26635 {
26636 dpyinfo = FRAME_X_DISPLAY_INFO (f);
26637 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
26638 if (NILP (pointer))
26639 pointer = Fget_text_property (pos, Qpointer, string);
26640
26641 /* Change the mouse pointer according to what is under X/Y. */
26642 if (NILP (pointer)
26643 && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE)))
26644 {
26645 Lisp_Object map;
26646 map = Fget_text_property (pos, Qlocal_map, string);
26647 if (!KEYMAPP (map))
26648 map = Fget_text_property (pos, Qkeymap, string);
26649 if (!KEYMAPP (map))
26650 cursor = dpyinfo->vertical_scroll_bar_cursor;
26651 }
26652 }
26653 #endif
26654
26655 /* Change the mouse face according to what is under X/Y. */
26656 mouse_face = Fget_text_property (pos, Qmouse_face, string);
26657 if (!NILP (mouse_face)
26658 && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE))
26659 && glyph)
26660 {
26661 Lisp_Object b, e;
26662
26663 struct glyph * tmp_glyph;
26664
26665 int gpos;
26666 int gseq_length;
26667 int total_pixel_width;
26668 EMACS_INT begpos, endpos, ignore;
26669
26670 int vpos, hpos;
26671
26672 b = Fprevious_single_property_change (make_number (charpos + 1),
26673 Qmouse_face, string, Qnil);
26674 if (NILP (b))
26675 begpos = 0;
26676 else
26677 begpos = XINT (b);
26678
26679 e = Fnext_single_property_change (pos, Qmouse_face, string, Qnil);
26680 if (NILP (e))
26681 endpos = SCHARS (string);
26682 else
26683 endpos = XINT (e);
26684
26685 /* Calculate the glyph position GPOS of GLYPH in the
26686 displayed string, relative to the beginning of the
26687 highlighted part of the string.
26688
26689 Note: GPOS is different from CHARPOS. CHARPOS is the
26690 position of GLYPH in the internal string object. A mode
26691 line string format has structures which are converted to
26692 a flattened string by the Emacs Lisp interpreter. The
26693 internal string is an element of those structures. The
26694 displayed string is the flattened string. */
26695 tmp_glyph = row_start_glyph;
26696 while (tmp_glyph < glyph
26697 && (!(EQ (tmp_glyph->object, glyph->object)
26698 && begpos <= tmp_glyph->charpos
26699 && tmp_glyph->charpos < endpos)))
26700 tmp_glyph++;
26701 gpos = glyph - tmp_glyph;
26702
26703 /* Calculate the length GSEQ_LENGTH of the glyph sequence of
26704 the highlighted part of the displayed string to which
26705 GLYPH belongs. Note: GSEQ_LENGTH is different from
26706 SCHARS (STRING), because the latter returns the length of
26707 the internal string. */
26708 for (tmp_glyph = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
26709 tmp_glyph > glyph
26710 && (!(EQ (tmp_glyph->object, glyph->object)
26711 && begpos <= tmp_glyph->charpos
26712 && tmp_glyph->charpos < endpos));
26713 tmp_glyph--)
26714 ;
26715 gseq_length = gpos + (tmp_glyph - glyph) + 1;
26716
26717 /* Calculate the total pixel width of all the glyphs between
26718 the beginning of the highlighted area and GLYPH. */
26719 total_pixel_width = 0;
26720 for (tmp_glyph = glyph - gpos; tmp_glyph != glyph; tmp_glyph++)
26721 total_pixel_width += tmp_glyph->pixel_width;
26722
26723 /* Pre calculation of re-rendering position. Note: X is in
26724 column units here, after the call to mode_line_string or
26725 marginal_area_string. */
26726 hpos = x - gpos;
26727 vpos = (area == ON_MODE_LINE
26728 ? (w->current_matrix)->nrows - 1
26729 : 0);
26730
26731 /* If GLYPH's position is included in the region that is
26732 already drawn in mouse face, we have nothing to do. */
26733 if ( EQ (window, hlinfo->mouse_face_window)
26734 && (!row->reversed_p
26735 ? (hlinfo->mouse_face_beg_col <= hpos
26736 && hpos < hlinfo->mouse_face_end_col)
26737 /* In R2L rows we swap BEG and END, see below. */
26738 : (hlinfo->mouse_face_end_col <= hpos
26739 && hpos < hlinfo->mouse_face_beg_col))
26740 && hlinfo->mouse_face_beg_row == vpos )
26741 return;
26742
26743 if (clear_mouse_face (hlinfo))
26744 cursor = No_Cursor;
26745
26746 if (!row->reversed_p)
26747 {
26748 hlinfo->mouse_face_beg_col = hpos;
26749 hlinfo->mouse_face_beg_x = original_x_pixel
26750 - (total_pixel_width + dx);
26751 hlinfo->mouse_face_end_col = hpos + gseq_length;
26752 hlinfo->mouse_face_end_x = 0;
26753 }
26754 else
26755 {
26756 /* In R2L rows, show_mouse_face expects BEG and END
26757 coordinates to be swapped. */
26758 hlinfo->mouse_face_end_col = hpos;
26759 hlinfo->mouse_face_end_x = original_x_pixel
26760 - (total_pixel_width + dx);
26761 hlinfo->mouse_face_beg_col = hpos + gseq_length;
26762 hlinfo->mouse_face_beg_x = 0;
26763 }
26764
26765 hlinfo->mouse_face_beg_row = vpos;
26766 hlinfo->mouse_face_end_row = hlinfo->mouse_face_beg_row;
26767 hlinfo->mouse_face_beg_y = 0;
26768 hlinfo->mouse_face_end_y = 0;
26769 hlinfo->mouse_face_past_end = 0;
26770 hlinfo->mouse_face_window = window;
26771
26772 hlinfo->mouse_face_face_id = face_at_string_position (w, string,
26773 charpos,
26774 0, 0, 0,
26775 &ignore,
26776 glyph->face_id,
26777 1);
26778 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
26779
26780 if (NILP (pointer))
26781 pointer = Qhand;
26782 }
26783 else if ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE))
26784 clear_mouse_face (hlinfo);
26785 }
26786 #ifdef HAVE_WINDOW_SYSTEM
26787 if (FRAME_WINDOW_P (f))
26788 define_frame_cursor1 (f, cursor, pointer);
26789 #endif
26790 }
26791
26792
26793 /* EXPORT:
26794 Take proper action when the mouse has moved to position X, Y on
26795 frame F as regards highlighting characters that have mouse-face
26796 properties. Also de-highlighting chars where the mouse was before.
26797 X and Y can be negative or out of range. */
26798
26799 void
26800 note_mouse_highlight (struct frame *f, int x, int y)
26801 {
26802 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
26803 enum window_part part = ON_NOTHING;
26804 Lisp_Object window;
26805 struct window *w;
26806 Cursor cursor = No_Cursor;
26807 Lisp_Object pointer = Qnil; /* Takes precedence over cursor! */
26808 struct buffer *b;
26809
26810 /* When a menu is active, don't highlight because this looks odd. */
26811 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS) || defined (MSDOS)
26812 if (popup_activated ())
26813 return;
26814 #endif
26815
26816 if (NILP (Vmouse_highlight)
26817 || !f->glyphs_initialized_p
26818 || f->pointer_invisible)
26819 return;
26820
26821 hlinfo->mouse_face_mouse_x = x;
26822 hlinfo->mouse_face_mouse_y = y;
26823 hlinfo->mouse_face_mouse_frame = f;
26824
26825 if (hlinfo->mouse_face_defer)
26826 return;
26827
26828 if (gc_in_progress)
26829 {
26830 hlinfo->mouse_face_deferred_gc = 1;
26831 return;
26832 }
26833
26834 /* Which window is that in? */
26835 window = window_from_coordinates (f, x, y, &part, 1);
26836
26837 /* If displaying active text in another window, clear that. */
26838 if (! EQ (window, hlinfo->mouse_face_window)
26839 /* Also clear if we move out of text area in same window. */
26840 || (!NILP (hlinfo->mouse_face_window)
26841 && !NILP (window)
26842 && part != ON_TEXT
26843 && part != ON_MODE_LINE
26844 && part != ON_HEADER_LINE))
26845 clear_mouse_face (hlinfo);
26846
26847 /* Not on a window -> return. */
26848 if (!WINDOWP (window))
26849 return;
26850
26851 /* Reset help_echo_string. It will get recomputed below. */
26852 help_echo_string = Qnil;
26853
26854 /* Convert to window-relative pixel coordinates. */
26855 w = XWINDOW (window);
26856 frame_to_window_pixel_xy (w, &x, &y);
26857
26858 #ifdef HAVE_WINDOW_SYSTEM
26859 /* Handle tool-bar window differently since it doesn't display a
26860 buffer. */
26861 if (EQ (window, f->tool_bar_window))
26862 {
26863 note_tool_bar_highlight (f, x, y);
26864 return;
26865 }
26866 #endif
26867
26868 /* Mouse is on the mode, header line or margin? */
26869 if (part == ON_MODE_LINE || part == ON_HEADER_LINE
26870 || part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
26871 {
26872 note_mode_line_or_margin_highlight (window, x, y, part);
26873 return;
26874 }
26875
26876 #ifdef HAVE_WINDOW_SYSTEM
26877 if (part == ON_VERTICAL_BORDER)
26878 {
26879 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
26880 help_echo_string = build_string ("drag-mouse-1: resize");
26881 }
26882 else if (part == ON_LEFT_FRINGE || part == ON_RIGHT_FRINGE
26883 || part == ON_SCROLL_BAR)
26884 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
26885 else
26886 cursor = FRAME_X_OUTPUT (f)->text_cursor;
26887 #endif
26888
26889 /* Are we in a window whose display is up to date?
26890 And verify the buffer's text has not changed. */
26891 b = XBUFFER (w->buffer);
26892 if (part == ON_TEXT
26893 && EQ (w->window_end_valid, w->buffer)
26894 && XFASTINT (w->last_modified) == BUF_MODIFF (b)
26895 && XFASTINT (w->last_overlay_modified) == BUF_OVERLAY_MODIFF (b))
26896 {
26897 int hpos, vpos, dx, dy, area;
26898 EMACS_INT pos;
26899 struct glyph *glyph;
26900 Lisp_Object object;
26901 Lisp_Object mouse_face = Qnil, position;
26902 Lisp_Object *overlay_vec = NULL;
26903 ptrdiff_t i, noverlays;
26904 struct buffer *obuf;
26905 EMACS_INT obegv, ozv;
26906 int same_region;
26907
26908 /* Find the glyph under X/Y. */
26909 glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, &dx, &dy, &area);
26910
26911 #ifdef HAVE_WINDOW_SYSTEM
26912 /* Look for :pointer property on image. */
26913 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
26914 {
26915 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
26916 if (img != NULL && IMAGEP (img->spec))
26917 {
26918 Lisp_Object image_map, hotspot;
26919 if ((image_map = Fplist_get (XCDR (img->spec), QCmap),
26920 !NILP (image_map))
26921 && (hotspot = find_hot_spot (image_map,
26922 glyph->slice.img.x + dx,
26923 glyph->slice.img.y + dy),
26924 CONSP (hotspot))
26925 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
26926 {
26927 Lisp_Object plist;
26928
26929 /* Could check XCAR (hotspot) to see if we enter/leave
26930 this hot-spot.
26931 If so, we could look for mouse-enter, mouse-leave
26932 properties in PLIST (and do something...). */
26933 hotspot = XCDR (hotspot);
26934 if (CONSP (hotspot)
26935 && (plist = XCAR (hotspot), CONSP (plist)))
26936 {
26937 pointer = Fplist_get (plist, Qpointer);
26938 if (NILP (pointer))
26939 pointer = Qhand;
26940 help_echo_string = Fplist_get (plist, Qhelp_echo);
26941 if (!NILP (help_echo_string))
26942 {
26943 help_echo_window = window;
26944 help_echo_object = glyph->object;
26945 help_echo_pos = glyph->charpos;
26946 }
26947 }
26948 }
26949 if (NILP (pointer))
26950 pointer = Fplist_get (XCDR (img->spec), QCpointer);
26951 }
26952 }
26953 #endif /* HAVE_WINDOW_SYSTEM */
26954
26955 /* Clear mouse face if X/Y not over text. */
26956 if (glyph == NULL
26957 || area != TEXT_AREA
26958 || !MATRIX_ROW (w->current_matrix, vpos)->displays_text_p
26959 /* Glyph's OBJECT is an integer for glyphs inserted by the
26960 display engine for its internal purposes, like truncation
26961 and continuation glyphs and blanks beyond the end of
26962 line's text on text terminals. If we are over such a
26963 glyph, we are not over any text. */
26964 || INTEGERP (glyph->object)
26965 /* R2L rows have a stretch glyph at their front, which
26966 stands for no text, whereas L2R rows have no glyphs at
26967 all beyond the end of text. Treat such stretch glyphs
26968 like we do with NULL glyphs in L2R rows. */
26969 || (MATRIX_ROW (w->current_matrix, vpos)->reversed_p
26970 && glyph == MATRIX_ROW (w->current_matrix, vpos)->glyphs[TEXT_AREA]
26971 && glyph->type == STRETCH_GLYPH
26972 && glyph->avoid_cursor_p))
26973 {
26974 if (clear_mouse_face (hlinfo))
26975 cursor = No_Cursor;
26976 #ifdef HAVE_WINDOW_SYSTEM
26977 if (FRAME_WINDOW_P (f) && NILP (pointer))
26978 {
26979 if (area != TEXT_AREA)
26980 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
26981 else
26982 pointer = Vvoid_text_area_pointer;
26983 }
26984 #endif
26985 goto set_cursor;
26986 }
26987
26988 pos = glyph->charpos;
26989 object = glyph->object;
26990 if (!STRINGP (object) && !BUFFERP (object))
26991 goto set_cursor;
26992
26993 /* If we get an out-of-range value, return now; avoid an error. */
26994 if (BUFFERP (object) && pos > BUF_Z (b))
26995 goto set_cursor;
26996
26997 /* Make the window's buffer temporarily current for
26998 overlays_at and compute_char_face. */
26999 obuf = current_buffer;
27000 current_buffer = b;
27001 obegv = BEGV;
27002 ozv = ZV;
27003 BEGV = BEG;
27004 ZV = Z;
27005
27006 /* Is this char mouse-active or does it have help-echo? */
27007 position = make_number (pos);
27008
27009 if (BUFFERP (object))
27010 {
27011 /* Put all the overlays we want in a vector in overlay_vec. */
27012 GET_OVERLAYS_AT (pos, overlay_vec, noverlays, NULL, 0);
27013 /* Sort overlays into increasing priority order. */
27014 noverlays = sort_overlays (overlay_vec, noverlays, w);
27015 }
27016 else
27017 noverlays = 0;
27018
27019 same_region = coords_in_mouse_face_p (w, hpos, vpos);
27020
27021 if (same_region)
27022 cursor = No_Cursor;
27023
27024 /* Check mouse-face highlighting. */
27025 if (! same_region
27026 /* If there exists an overlay with mouse-face overlapping
27027 the one we are currently highlighting, we have to
27028 check if we enter the overlapping overlay, and then
27029 highlight only that. */
27030 || (OVERLAYP (hlinfo->mouse_face_overlay)
27031 && mouse_face_overlay_overlaps (hlinfo->mouse_face_overlay)))
27032 {
27033 /* Find the highest priority overlay with a mouse-face. */
27034 Lisp_Object overlay = Qnil;
27035 for (i = noverlays - 1; i >= 0 && NILP (overlay); --i)
27036 {
27037 mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face);
27038 if (!NILP (mouse_face))
27039 overlay = overlay_vec[i];
27040 }
27041
27042 /* If we're highlighting the same overlay as before, there's
27043 no need to do that again. */
27044 if (!NILP (overlay) && EQ (overlay, hlinfo->mouse_face_overlay))
27045 goto check_help_echo;
27046 hlinfo->mouse_face_overlay = overlay;
27047
27048 /* Clear the display of the old active region, if any. */
27049 if (clear_mouse_face (hlinfo))
27050 cursor = No_Cursor;
27051
27052 /* If no overlay applies, get a text property. */
27053 if (NILP (overlay))
27054 mouse_face = Fget_text_property (position, Qmouse_face, object);
27055
27056 /* Next, compute the bounds of the mouse highlighting and
27057 display it. */
27058 if (!NILP (mouse_face) && STRINGP (object))
27059 {
27060 /* The mouse-highlighting comes from a display string
27061 with a mouse-face. */
27062 Lisp_Object s, e;
27063 EMACS_INT ignore;
27064
27065 s = Fprevious_single_property_change
27066 (make_number (pos + 1), Qmouse_face, object, Qnil);
27067 e = Fnext_single_property_change
27068 (position, Qmouse_face, object, Qnil);
27069 if (NILP (s))
27070 s = make_number (0);
27071 if (NILP (e))
27072 e = make_number (SCHARS (object) - 1);
27073 mouse_face_from_string_pos (w, hlinfo, object,
27074 XINT (s), XINT (e));
27075 hlinfo->mouse_face_past_end = 0;
27076 hlinfo->mouse_face_window = window;
27077 hlinfo->mouse_face_face_id
27078 = face_at_string_position (w, object, pos, 0, 0, 0, &ignore,
27079 glyph->face_id, 1);
27080 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
27081 cursor = No_Cursor;
27082 }
27083 else
27084 {
27085 /* The mouse-highlighting, if any, comes from an overlay
27086 or text property in the buffer. */
27087 Lisp_Object buffer IF_LINT (= Qnil);
27088 Lisp_Object cover_string IF_LINT (= Qnil);
27089
27090 if (STRINGP (object))
27091 {
27092 /* If we are on a display string with no mouse-face,
27093 check if the text under it has one. */
27094 struct glyph_row *r = MATRIX_ROW (w->current_matrix, vpos);
27095 EMACS_INT start = MATRIX_ROW_START_CHARPOS (r);
27096 pos = string_buffer_position (object, start);
27097 if (pos > 0)
27098 {
27099 mouse_face = get_char_property_and_overlay
27100 (make_number (pos), Qmouse_face, w->buffer, &overlay);
27101 buffer = w->buffer;
27102 cover_string = object;
27103 }
27104 }
27105 else
27106 {
27107 buffer = object;
27108 cover_string = Qnil;
27109 }
27110
27111 if (!NILP (mouse_face))
27112 {
27113 Lisp_Object before, after;
27114 Lisp_Object before_string, after_string;
27115 /* To correctly find the limits of mouse highlight
27116 in a bidi-reordered buffer, we must not use the
27117 optimization of limiting the search in
27118 previous-single-property-change and
27119 next-single-property-change, because
27120 rows_from_pos_range needs the real start and end
27121 positions to DTRT in this case. That's because
27122 the first row visible in a window does not
27123 necessarily display the character whose position
27124 is the smallest. */
27125 Lisp_Object lim1 =
27126 NILP (BVAR (XBUFFER (buffer), bidi_display_reordering))
27127 ? Fmarker_position (w->start)
27128 : Qnil;
27129 Lisp_Object lim2 =
27130 NILP (BVAR (XBUFFER (buffer), bidi_display_reordering))
27131 ? make_number (BUF_Z (XBUFFER (buffer))
27132 - XFASTINT (w->window_end_pos))
27133 : Qnil;
27134
27135 if (NILP (overlay))
27136 {
27137 /* Handle the text property case. */
27138 before = Fprevious_single_property_change
27139 (make_number (pos + 1), Qmouse_face, buffer, lim1);
27140 after = Fnext_single_property_change
27141 (make_number (pos), Qmouse_face, buffer, lim2);
27142 before_string = after_string = Qnil;
27143 }
27144 else
27145 {
27146 /* Handle the overlay case. */
27147 before = Foverlay_start (overlay);
27148 after = Foverlay_end (overlay);
27149 before_string = Foverlay_get (overlay, Qbefore_string);
27150 after_string = Foverlay_get (overlay, Qafter_string);
27151
27152 if (!STRINGP (before_string)) before_string = Qnil;
27153 if (!STRINGP (after_string)) after_string = Qnil;
27154 }
27155
27156 mouse_face_from_buffer_pos (window, hlinfo, pos,
27157 XFASTINT (before),
27158 XFASTINT (after),
27159 before_string, after_string,
27160 cover_string);
27161 cursor = No_Cursor;
27162 }
27163 }
27164 }
27165
27166 check_help_echo:
27167
27168 /* Look for a `help-echo' property. */
27169 if (NILP (help_echo_string)) {
27170 Lisp_Object help, overlay;
27171
27172 /* Check overlays first. */
27173 help = overlay = Qnil;
27174 for (i = noverlays - 1; i >= 0 && NILP (help); --i)
27175 {
27176 overlay = overlay_vec[i];
27177 help = Foverlay_get (overlay, Qhelp_echo);
27178 }
27179
27180 if (!NILP (help))
27181 {
27182 help_echo_string = help;
27183 help_echo_window = window;
27184 help_echo_object = overlay;
27185 help_echo_pos = pos;
27186 }
27187 else
27188 {
27189 Lisp_Object obj = glyph->object;
27190 EMACS_INT charpos = glyph->charpos;
27191
27192 /* Try text properties. */
27193 if (STRINGP (obj)
27194 && charpos >= 0
27195 && charpos < SCHARS (obj))
27196 {
27197 help = Fget_text_property (make_number (charpos),
27198 Qhelp_echo, obj);
27199 if (NILP (help))
27200 {
27201 /* If the string itself doesn't specify a help-echo,
27202 see if the buffer text ``under'' it does. */
27203 struct glyph_row *r
27204 = MATRIX_ROW (w->current_matrix, vpos);
27205 EMACS_INT start = MATRIX_ROW_START_CHARPOS (r);
27206 EMACS_INT p = string_buffer_position (obj, start);
27207 if (p > 0)
27208 {
27209 help = Fget_char_property (make_number (p),
27210 Qhelp_echo, w->buffer);
27211 if (!NILP (help))
27212 {
27213 charpos = p;
27214 obj = w->buffer;
27215 }
27216 }
27217 }
27218 }
27219 else if (BUFFERP (obj)
27220 && charpos >= BEGV
27221 && charpos < ZV)
27222 help = Fget_text_property (make_number (charpos), Qhelp_echo,
27223 obj);
27224
27225 if (!NILP (help))
27226 {
27227 help_echo_string = help;
27228 help_echo_window = window;
27229 help_echo_object = obj;
27230 help_echo_pos = charpos;
27231 }
27232 }
27233 }
27234
27235 #ifdef HAVE_WINDOW_SYSTEM
27236 /* Look for a `pointer' property. */
27237 if (FRAME_WINDOW_P (f) && NILP (pointer))
27238 {
27239 /* Check overlays first. */
27240 for (i = noverlays - 1; i >= 0 && NILP (pointer); --i)
27241 pointer = Foverlay_get (overlay_vec[i], Qpointer);
27242
27243 if (NILP (pointer))
27244 {
27245 Lisp_Object obj = glyph->object;
27246 EMACS_INT charpos = glyph->charpos;
27247
27248 /* Try text properties. */
27249 if (STRINGP (obj)
27250 && charpos >= 0
27251 && charpos < SCHARS (obj))
27252 {
27253 pointer = Fget_text_property (make_number (charpos),
27254 Qpointer, obj);
27255 if (NILP (pointer))
27256 {
27257 /* If the string itself doesn't specify a pointer,
27258 see if the buffer text ``under'' it does. */
27259 struct glyph_row *r
27260 = MATRIX_ROW (w->current_matrix, vpos);
27261 EMACS_INT start = MATRIX_ROW_START_CHARPOS (r);
27262 EMACS_INT p = string_buffer_position (obj, start);
27263 if (p > 0)
27264 pointer = Fget_char_property (make_number (p),
27265 Qpointer, w->buffer);
27266 }
27267 }
27268 else if (BUFFERP (obj)
27269 && charpos >= BEGV
27270 && charpos < ZV)
27271 pointer = Fget_text_property (make_number (charpos),
27272 Qpointer, obj);
27273 }
27274 }
27275 #endif /* HAVE_WINDOW_SYSTEM */
27276
27277 BEGV = obegv;
27278 ZV = ozv;
27279 current_buffer = obuf;
27280 }
27281
27282 set_cursor:
27283
27284 #ifdef HAVE_WINDOW_SYSTEM
27285 if (FRAME_WINDOW_P (f))
27286 define_frame_cursor1 (f, cursor, pointer);
27287 #else
27288 /* This is here to prevent a compiler error, about "label at end of
27289 compound statement". */
27290 return;
27291 #endif
27292 }
27293
27294
27295 /* EXPORT for RIF:
27296 Clear any mouse-face on window W. This function is part of the
27297 redisplay interface, and is called from try_window_id and similar
27298 functions to ensure the mouse-highlight is off. */
27299
27300 void
27301 x_clear_window_mouse_face (struct window *w)
27302 {
27303 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame));
27304 Lisp_Object window;
27305
27306 BLOCK_INPUT;
27307 XSETWINDOW (window, w);
27308 if (EQ (window, hlinfo->mouse_face_window))
27309 clear_mouse_face (hlinfo);
27310 UNBLOCK_INPUT;
27311 }
27312
27313
27314 /* EXPORT:
27315 Just discard the mouse face information for frame F, if any.
27316 This is used when the size of F is changed. */
27317
27318 void
27319 cancel_mouse_face (struct frame *f)
27320 {
27321 Lisp_Object window;
27322 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
27323
27324 window = hlinfo->mouse_face_window;
27325 if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f)
27326 {
27327 hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
27328 hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
27329 hlinfo->mouse_face_window = Qnil;
27330 }
27331 }
27332
27333
27334 \f
27335 /***********************************************************************
27336 Exposure Events
27337 ***********************************************************************/
27338
27339 #ifdef HAVE_WINDOW_SYSTEM
27340
27341 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
27342 which intersects rectangle R. R is in window-relative coordinates. */
27343
27344 static void
27345 expose_area (struct window *w, struct glyph_row *row, XRectangle *r,
27346 enum glyph_row_area area)
27347 {
27348 struct glyph *first = row->glyphs[area];
27349 struct glyph *end = row->glyphs[area] + row->used[area];
27350 struct glyph *last;
27351 int first_x, start_x, x;
27352
27353 if (area == TEXT_AREA && row->fill_line_p)
27354 /* If row extends face to end of line write the whole line. */
27355 draw_glyphs (w, 0, row, area,
27356 0, row->used[area],
27357 DRAW_NORMAL_TEXT, 0);
27358 else
27359 {
27360 /* Set START_X to the window-relative start position for drawing glyphs of
27361 AREA. The first glyph of the text area can be partially visible.
27362 The first glyphs of other areas cannot. */
27363 start_x = window_box_left_offset (w, area);
27364 x = start_x;
27365 if (area == TEXT_AREA)
27366 x += row->x;
27367
27368 /* Find the first glyph that must be redrawn. */
27369 while (first < end
27370 && x + first->pixel_width < r->x)
27371 {
27372 x += first->pixel_width;
27373 ++first;
27374 }
27375
27376 /* Find the last one. */
27377 last = first;
27378 first_x = x;
27379 while (last < end
27380 && x < r->x + r->width)
27381 {
27382 x += last->pixel_width;
27383 ++last;
27384 }
27385
27386 /* Repaint. */
27387 if (last > first)
27388 draw_glyphs (w, first_x - start_x, row, area,
27389 first - row->glyphs[area], last - row->glyphs[area],
27390 DRAW_NORMAL_TEXT, 0);
27391 }
27392 }
27393
27394
27395 /* Redraw the parts of the glyph row ROW on window W intersecting
27396 rectangle R. R is in window-relative coordinates. Value is
27397 non-zero if mouse-face was overwritten. */
27398
27399 static int
27400 expose_line (struct window *w, struct glyph_row *row, XRectangle *r)
27401 {
27402 xassert (row->enabled_p);
27403
27404 if (row->mode_line_p || w->pseudo_window_p)
27405 draw_glyphs (w, 0, row, TEXT_AREA,
27406 0, row->used[TEXT_AREA],
27407 DRAW_NORMAL_TEXT, 0);
27408 else
27409 {
27410 if (row->used[LEFT_MARGIN_AREA])
27411 expose_area (w, row, r, LEFT_MARGIN_AREA);
27412 if (row->used[TEXT_AREA])
27413 expose_area (w, row, r, TEXT_AREA);
27414 if (row->used[RIGHT_MARGIN_AREA])
27415 expose_area (w, row, r, RIGHT_MARGIN_AREA);
27416 draw_row_fringe_bitmaps (w, row);
27417 }
27418
27419 return row->mouse_face_p;
27420 }
27421
27422
27423 /* Redraw those parts of glyphs rows during expose event handling that
27424 overlap other rows. Redrawing of an exposed line writes over parts
27425 of lines overlapping that exposed line; this function fixes that.
27426
27427 W is the window being exposed. FIRST_OVERLAPPING_ROW is the first
27428 row in W's current matrix that is exposed and overlaps other rows.
27429 LAST_OVERLAPPING_ROW is the last such row. */
27430
27431 static void
27432 expose_overlaps (struct window *w,
27433 struct glyph_row *first_overlapping_row,
27434 struct glyph_row *last_overlapping_row,
27435 XRectangle *r)
27436 {
27437 struct glyph_row *row;
27438
27439 for (row = first_overlapping_row; row <= last_overlapping_row; ++row)
27440 if (row->overlapping_p)
27441 {
27442 xassert (row->enabled_p && !row->mode_line_p);
27443
27444 row->clip = r;
27445 if (row->used[LEFT_MARGIN_AREA])
27446 x_fix_overlapping_area (w, row, LEFT_MARGIN_AREA, OVERLAPS_BOTH);
27447
27448 if (row->used[TEXT_AREA])
27449 x_fix_overlapping_area (w, row, TEXT_AREA, OVERLAPS_BOTH);
27450
27451 if (row->used[RIGHT_MARGIN_AREA])
27452 x_fix_overlapping_area (w, row, RIGHT_MARGIN_AREA, OVERLAPS_BOTH);
27453 row->clip = NULL;
27454 }
27455 }
27456
27457
27458 /* Return non-zero if W's cursor intersects rectangle R. */
27459
27460 static int
27461 phys_cursor_in_rect_p (struct window *w, XRectangle *r)
27462 {
27463 XRectangle cr, result;
27464 struct glyph *cursor_glyph;
27465 struct glyph_row *row;
27466
27467 if (w->phys_cursor.vpos >= 0
27468 && w->phys_cursor.vpos < w->current_matrix->nrows
27469 && (row = MATRIX_ROW (w->current_matrix, w->phys_cursor.vpos),
27470 row->enabled_p)
27471 && row->cursor_in_fringe_p)
27472 {
27473 /* Cursor is in the fringe. */
27474 cr.x = window_box_right_offset (w,
27475 (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
27476 ? RIGHT_MARGIN_AREA
27477 : TEXT_AREA));
27478 cr.y = row->y;
27479 cr.width = WINDOW_RIGHT_FRINGE_WIDTH (w);
27480 cr.height = row->height;
27481 return x_intersect_rectangles (&cr, r, &result);
27482 }
27483
27484 cursor_glyph = get_phys_cursor_glyph (w);
27485 if (cursor_glyph)
27486 {
27487 /* r is relative to W's box, but w->phys_cursor.x is relative
27488 to left edge of W's TEXT area. Adjust it. */
27489 cr.x = window_box_left_offset (w, TEXT_AREA) + w->phys_cursor.x;
27490 cr.y = w->phys_cursor.y;
27491 cr.width = cursor_glyph->pixel_width;
27492 cr.height = w->phys_cursor_height;
27493 /* ++KFS: W32 version used W32-specific IntersectRect here, but
27494 I assume the effect is the same -- and this is portable. */
27495 return x_intersect_rectangles (&cr, r, &result);
27496 }
27497 /* If we don't understand the format, pretend we're not in the hot-spot. */
27498 return 0;
27499 }
27500
27501
27502 /* EXPORT:
27503 Draw a vertical window border to the right of window W if W doesn't
27504 have vertical scroll bars. */
27505
27506 void
27507 x_draw_vertical_border (struct window *w)
27508 {
27509 struct frame *f = XFRAME (WINDOW_FRAME (w));
27510
27511 /* We could do better, if we knew what type of scroll-bar the adjacent
27512 windows (on either side) have... But we don't :-(
27513 However, I think this works ok. ++KFS 2003-04-25 */
27514
27515 /* Redraw borders between horizontally adjacent windows. Don't
27516 do it for frames with vertical scroll bars because either the
27517 right scroll bar of a window, or the left scroll bar of its
27518 neighbor will suffice as a border. */
27519 if (FRAME_HAS_VERTICAL_SCROLL_BARS (XFRAME (w->frame)))
27520 return;
27521
27522 if (!WINDOW_RIGHTMOST_P (w)
27523 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w))
27524 {
27525 int x0, x1, y0, y1;
27526
27527 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
27528 y1 -= 1;
27529
27530 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
27531 x1 -= 1;
27532
27533 FRAME_RIF (f)->draw_vertical_window_border (w, x1, y0, y1);
27534 }
27535 else if (!WINDOW_LEFTMOST_P (w)
27536 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
27537 {
27538 int x0, x1, y0, y1;
27539
27540 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
27541 y1 -= 1;
27542
27543 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
27544 x0 -= 1;
27545
27546 FRAME_RIF (f)->draw_vertical_window_border (w, x0, y0, y1);
27547 }
27548 }
27549
27550
27551 /* Redraw the part of window W intersection rectangle FR. Pixel
27552 coordinates in FR are frame-relative. Call this function with
27553 input blocked. Value is non-zero if the exposure overwrites
27554 mouse-face. */
27555
27556 static int
27557 expose_window (struct window *w, XRectangle *fr)
27558 {
27559 struct frame *f = XFRAME (w->frame);
27560 XRectangle wr, r;
27561 int mouse_face_overwritten_p = 0;
27562
27563 /* If window is not yet fully initialized, do nothing. This can
27564 happen when toolkit scroll bars are used and a window is split.
27565 Reconfiguring the scroll bar will generate an expose for a newly
27566 created window. */
27567 if (w->current_matrix == NULL)
27568 return 0;
27569
27570 /* When we're currently updating the window, display and current
27571 matrix usually don't agree. Arrange for a thorough display
27572 later. */
27573 if (w == updated_window)
27574 {
27575 SET_FRAME_GARBAGED (f);
27576 return 0;
27577 }
27578
27579 /* Frame-relative pixel rectangle of W. */
27580 wr.x = WINDOW_LEFT_EDGE_X (w);
27581 wr.y = WINDOW_TOP_EDGE_Y (w);
27582 wr.width = WINDOW_TOTAL_WIDTH (w);
27583 wr.height = WINDOW_TOTAL_HEIGHT (w);
27584
27585 if (x_intersect_rectangles (fr, &wr, &r))
27586 {
27587 int yb = window_text_bottom_y (w);
27588 struct glyph_row *row;
27589 int cursor_cleared_p, phys_cursor_on_p;
27590 struct glyph_row *first_overlapping_row, *last_overlapping_row;
27591
27592 TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n",
27593 r.x, r.y, r.width, r.height));
27594
27595 /* Convert to window coordinates. */
27596 r.x -= WINDOW_LEFT_EDGE_X (w);
27597 r.y -= WINDOW_TOP_EDGE_Y (w);
27598
27599 /* Turn off the cursor. */
27600 if (!w->pseudo_window_p
27601 && phys_cursor_in_rect_p (w, &r))
27602 {
27603 x_clear_cursor (w);
27604 cursor_cleared_p = 1;
27605 }
27606 else
27607 cursor_cleared_p = 0;
27608
27609 /* If the row containing the cursor extends face to end of line,
27610 then expose_area might overwrite the cursor outside the
27611 rectangle and thus notice_overwritten_cursor might clear
27612 w->phys_cursor_on_p. We remember the original value and
27613 check later if it is changed. */
27614 phys_cursor_on_p = w->phys_cursor_on_p;
27615
27616 /* Update lines intersecting rectangle R. */
27617 first_overlapping_row = last_overlapping_row = NULL;
27618 for (row = w->current_matrix->rows;
27619 row->enabled_p;
27620 ++row)
27621 {
27622 int y0 = row->y;
27623 int y1 = MATRIX_ROW_BOTTOM_Y (row);
27624
27625 if ((y0 >= r.y && y0 < r.y + r.height)
27626 || (y1 > r.y && y1 < r.y + r.height)
27627 || (r.y >= y0 && r.y < y1)
27628 || (r.y + r.height > y0 && r.y + r.height < y1))
27629 {
27630 /* A header line may be overlapping, but there is no need
27631 to fix overlapping areas for them. KFS 2005-02-12 */
27632 if (row->overlapping_p && !row->mode_line_p)
27633 {
27634 if (first_overlapping_row == NULL)
27635 first_overlapping_row = row;
27636 last_overlapping_row = row;
27637 }
27638
27639 row->clip = fr;
27640 if (expose_line (w, row, &r))
27641 mouse_face_overwritten_p = 1;
27642 row->clip = NULL;
27643 }
27644 else if (row->overlapping_p)
27645 {
27646 /* We must redraw a row overlapping the exposed area. */
27647 if (y0 < r.y
27648 ? y0 + row->phys_height > r.y
27649 : y0 + row->ascent - row->phys_ascent < r.y +r.height)
27650 {
27651 if (first_overlapping_row == NULL)
27652 first_overlapping_row = row;
27653 last_overlapping_row = row;
27654 }
27655 }
27656
27657 if (y1 >= yb)
27658 break;
27659 }
27660
27661 /* Display the mode line if there is one. */
27662 if (WINDOW_WANTS_MODELINE_P (w)
27663 && (row = MATRIX_MODE_LINE_ROW (w->current_matrix),
27664 row->enabled_p)
27665 && row->y < r.y + r.height)
27666 {
27667 if (expose_line (w, row, &r))
27668 mouse_face_overwritten_p = 1;
27669 }
27670
27671 if (!w->pseudo_window_p)
27672 {
27673 /* Fix the display of overlapping rows. */
27674 if (first_overlapping_row)
27675 expose_overlaps (w, first_overlapping_row, last_overlapping_row,
27676 fr);
27677
27678 /* Draw border between windows. */
27679 x_draw_vertical_border (w);
27680
27681 /* Turn the cursor on again. */
27682 if (cursor_cleared_p
27683 || (phys_cursor_on_p && !w->phys_cursor_on_p))
27684 update_window_cursor (w, 1);
27685 }
27686 }
27687
27688 return mouse_face_overwritten_p;
27689 }
27690
27691
27692
27693 /* Redraw (parts) of all windows in the window tree rooted at W that
27694 intersect R. R contains frame pixel coordinates. Value is
27695 non-zero if the exposure overwrites mouse-face. */
27696
27697 static int
27698 expose_window_tree (struct window *w, XRectangle *r)
27699 {
27700 struct frame *f = XFRAME (w->frame);
27701 int mouse_face_overwritten_p = 0;
27702
27703 while (w && !FRAME_GARBAGED_P (f))
27704 {
27705 if (!NILP (w->hchild))
27706 mouse_face_overwritten_p
27707 |= expose_window_tree (XWINDOW (w->hchild), r);
27708 else if (!NILP (w->vchild))
27709 mouse_face_overwritten_p
27710 |= expose_window_tree (XWINDOW (w->vchild), r);
27711 else
27712 mouse_face_overwritten_p |= expose_window (w, r);
27713
27714 w = NILP (w->next) ? NULL : XWINDOW (w->next);
27715 }
27716
27717 return mouse_face_overwritten_p;
27718 }
27719
27720
27721 /* EXPORT:
27722 Redisplay an exposed area of frame F. X and Y are the upper-left
27723 corner of the exposed rectangle. W and H are width and height of
27724 the exposed area. All are pixel values. W or H zero means redraw
27725 the entire frame. */
27726
27727 void
27728 expose_frame (struct frame *f, int x, int y, int w, int h)
27729 {
27730 XRectangle r;
27731 int mouse_face_overwritten_p = 0;
27732
27733 TRACE ((stderr, "expose_frame "));
27734
27735 /* No need to redraw if frame will be redrawn soon. */
27736 if (FRAME_GARBAGED_P (f))
27737 {
27738 TRACE ((stderr, " garbaged\n"));
27739 return;
27740 }
27741
27742 /* If basic faces haven't been realized yet, there is no point in
27743 trying to redraw anything. This can happen when we get an expose
27744 event while Emacs is starting, e.g. by moving another window. */
27745 if (FRAME_FACE_CACHE (f) == NULL
27746 || FRAME_FACE_CACHE (f)->used < BASIC_FACE_ID_SENTINEL)
27747 {
27748 TRACE ((stderr, " no faces\n"));
27749 return;
27750 }
27751
27752 if (w == 0 || h == 0)
27753 {
27754 r.x = r.y = 0;
27755 r.width = FRAME_COLUMN_WIDTH (f) * FRAME_COLS (f);
27756 r.height = FRAME_LINE_HEIGHT (f) * FRAME_LINES (f);
27757 }
27758 else
27759 {
27760 r.x = x;
27761 r.y = y;
27762 r.width = w;
27763 r.height = h;
27764 }
27765
27766 TRACE ((stderr, "(%d, %d, %d, %d)\n", r.x, r.y, r.width, r.height));
27767 mouse_face_overwritten_p = expose_window_tree (XWINDOW (f->root_window), &r);
27768
27769 if (WINDOWP (f->tool_bar_window))
27770 mouse_face_overwritten_p
27771 |= expose_window (XWINDOW (f->tool_bar_window), &r);
27772
27773 #ifdef HAVE_X_WINDOWS
27774 #ifndef MSDOS
27775 #ifndef USE_X_TOOLKIT
27776 if (WINDOWP (f->menu_bar_window))
27777 mouse_face_overwritten_p
27778 |= expose_window (XWINDOW (f->menu_bar_window), &r);
27779 #endif /* not USE_X_TOOLKIT */
27780 #endif
27781 #endif
27782
27783 /* Some window managers support a focus-follows-mouse style with
27784 delayed raising of frames. Imagine a partially obscured frame,
27785 and moving the mouse into partially obscured mouse-face on that
27786 frame. The visible part of the mouse-face will be highlighted,
27787 then the WM raises the obscured frame. With at least one WM, KDE
27788 2.1, Emacs is not getting any event for the raising of the frame
27789 (even tried with SubstructureRedirectMask), only Expose events.
27790 These expose events will draw text normally, i.e. not
27791 highlighted. Which means we must redo the highlight here.
27792 Subsume it under ``we love X''. --gerd 2001-08-15 */
27793 /* Included in Windows version because Windows most likely does not
27794 do the right thing if any third party tool offers
27795 focus-follows-mouse with delayed raise. --jason 2001-10-12 */
27796 if (mouse_face_overwritten_p && !FRAME_GARBAGED_P (f))
27797 {
27798 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
27799 if (f == hlinfo->mouse_face_mouse_frame)
27800 {
27801 int mouse_x = hlinfo->mouse_face_mouse_x;
27802 int mouse_y = hlinfo->mouse_face_mouse_y;
27803 clear_mouse_face (hlinfo);
27804 note_mouse_highlight (f, mouse_x, mouse_y);
27805 }
27806 }
27807 }
27808
27809
27810 /* EXPORT:
27811 Determine the intersection of two rectangles R1 and R2. Return
27812 the intersection in *RESULT. Value is non-zero if RESULT is not
27813 empty. */
27814
27815 int
27816 x_intersect_rectangles (XRectangle *r1, XRectangle *r2, XRectangle *result)
27817 {
27818 XRectangle *left, *right;
27819 XRectangle *upper, *lower;
27820 int intersection_p = 0;
27821
27822 /* Rearrange so that R1 is the left-most rectangle. */
27823 if (r1->x < r2->x)
27824 left = r1, right = r2;
27825 else
27826 left = r2, right = r1;
27827
27828 /* X0 of the intersection is right.x0, if this is inside R1,
27829 otherwise there is no intersection. */
27830 if (right->x <= left->x + left->width)
27831 {
27832 result->x = right->x;
27833
27834 /* The right end of the intersection is the minimum of
27835 the right ends of left and right. */
27836 result->width = (min (left->x + left->width, right->x + right->width)
27837 - result->x);
27838
27839 /* Same game for Y. */
27840 if (r1->y < r2->y)
27841 upper = r1, lower = r2;
27842 else
27843 upper = r2, lower = r1;
27844
27845 /* The upper end of the intersection is lower.y0, if this is inside
27846 of upper. Otherwise, there is no intersection. */
27847 if (lower->y <= upper->y + upper->height)
27848 {
27849 result->y = lower->y;
27850
27851 /* The lower end of the intersection is the minimum of the lower
27852 ends of upper and lower. */
27853 result->height = (min (lower->y + lower->height,
27854 upper->y + upper->height)
27855 - result->y);
27856 intersection_p = 1;
27857 }
27858 }
27859
27860 return intersection_p;
27861 }
27862
27863 #endif /* HAVE_WINDOW_SYSTEM */
27864
27865 \f
27866 /***********************************************************************
27867 Initialization
27868 ***********************************************************************/
27869
27870 void
27871 syms_of_xdisp (void)
27872 {
27873 Vwith_echo_area_save_vector = Qnil;
27874 staticpro (&Vwith_echo_area_save_vector);
27875
27876 Vmessage_stack = Qnil;
27877 staticpro (&Vmessage_stack);
27878
27879 DEFSYM (Qinhibit_redisplay, "inhibit-redisplay");
27880
27881 message_dolog_marker1 = Fmake_marker ();
27882 staticpro (&message_dolog_marker1);
27883 message_dolog_marker2 = Fmake_marker ();
27884 staticpro (&message_dolog_marker2);
27885 message_dolog_marker3 = Fmake_marker ();
27886 staticpro (&message_dolog_marker3);
27887
27888 #if GLYPH_DEBUG
27889 defsubr (&Sdump_frame_glyph_matrix);
27890 defsubr (&Sdump_glyph_matrix);
27891 defsubr (&Sdump_glyph_row);
27892 defsubr (&Sdump_tool_bar_row);
27893 defsubr (&Strace_redisplay);
27894 defsubr (&Strace_to_stderr);
27895 #endif
27896 #ifdef HAVE_WINDOW_SYSTEM
27897 defsubr (&Stool_bar_lines_needed);
27898 defsubr (&Slookup_image_map);
27899 #endif
27900 defsubr (&Sformat_mode_line);
27901 defsubr (&Sinvisible_p);
27902 defsubr (&Scurrent_bidi_paragraph_direction);
27903
27904 DEFSYM (Qmenu_bar_update_hook, "menu-bar-update-hook");
27905 DEFSYM (Qoverriding_terminal_local_map, "overriding-terminal-local-map");
27906 DEFSYM (Qoverriding_local_map, "overriding-local-map");
27907 DEFSYM (Qwindow_scroll_functions, "window-scroll-functions");
27908 DEFSYM (Qwindow_text_change_functions, "window-text-change-functions");
27909 DEFSYM (Qredisplay_end_trigger_functions, "redisplay-end-trigger-functions");
27910 DEFSYM (Qinhibit_point_motion_hooks, "inhibit-point-motion-hooks");
27911 DEFSYM (Qeval, "eval");
27912 DEFSYM (QCdata, ":data");
27913 DEFSYM (Qdisplay, "display");
27914 DEFSYM (Qspace_width, "space-width");
27915 DEFSYM (Qraise, "raise");
27916 DEFSYM (Qslice, "slice");
27917 DEFSYM (Qspace, "space");
27918 DEFSYM (Qmargin, "margin");
27919 DEFSYM (Qpointer, "pointer");
27920 DEFSYM (Qleft_margin, "left-margin");
27921 DEFSYM (Qright_margin, "right-margin");
27922 DEFSYM (Qcenter, "center");
27923 DEFSYM (Qline_height, "line-height");
27924 DEFSYM (QCalign_to, ":align-to");
27925 DEFSYM (QCrelative_width, ":relative-width");
27926 DEFSYM (QCrelative_height, ":relative-height");
27927 DEFSYM (QCeval, ":eval");
27928 DEFSYM (QCpropertize, ":propertize");
27929 DEFSYM (QCfile, ":file");
27930 DEFSYM (Qfontified, "fontified");
27931 DEFSYM (Qfontification_functions, "fontification-functions");
27932 DEFSYM (Qtrailing_whitespace, "trailing-whitespace");
27933 DEFSYM (Qescape_glyph, "escape-glyph");
27934 DEFSYM (Qnobreak_space, "nobreak-space");
27935 DEFSYM (Qimage, "image");
27936 DEFSYM (Qtext, "text");
27937 DEFSYM (Qboth, "both");
27938 DEFSYM (Qboth_horiz, "both-horiz");
27939 DEFSYM (Qtext_image_horiz, "text-image-horiz");
27940 DEFSYM (QCmap, ":map");
27941 DEFSYM (QCpointer, ":pointer");
27942 DEFSYM (Qrect, "rect");
27943 DEFSYM (Qcircle, "circle");
27944 DEFSYM (Qpoly, "poly");
27945 DEFSYM (Qmessage_truncate_lines, "message-truncate-lines");
27946 DEFSYM (Qgrow_only, "grow-only");
27947 DEFSYM (Qinhibit_menubar_update, "inhibit-menubar-update");
27948 DEFSYM (Qinhibit_eval_during_redisplay, "inhibit-eval-during-redisplay");
27949 DEFSYM (Qposition, "position");
27950 DEFSYM (Qbuffer_position, "buffer-position");
27951 DEFSYM (Qobject, "object");
27952 DEFSYM (Qbar, "bar");
27953 DEFSYM (Qhbar, "hbar");
27954 DEFSYM (Qbox, "box");
27955 DEFSYM (Qhollow, "hollow");
27956 DEFSYM (Qhand, "hand");
27957 DEFSYM (Qarrow, "arrow");
27958 DEFSYM (Qtext, "text");
27959 DEFSYM (Qinhibit_free_realized_faces, "inhibit-free-realized-faces");
27960
27961 list_of_error = Fcons (Fcons (intern_c_string ("error"),
27962 Fcons (intern_c_string ("void-variable"), Qnil)),
27963 Qnil);
27964 staticpro (&list_of_error);
27965
27966 DEFSYM (Qlast_arrow_position, "last-arrow-position");
27967 DEFSYM (Qlast_arrow_string, "last-arrow-string");
27968 DEFSYM (Qoverlay_arrow_string, "overlay-arrow-string");
27969 DEFSYM (Qoverlay_arrow_bitmap, "overlay-arrow-bitmap");
27970
27971 echo_buffer[0] = echo_buffer[1] = Qnil;
27972 staticpro (&echo_buffer[0]);
27973 staticpro (&echo_buffer[1]);
27974
27975 echo_area_buffer[0] = echo_area_buffer[1] = Qnil;
27976 staticpro (&echo_area_buffer[0]);
27977 staticpro (&echo_area_buffer[1]);
27978
27979 Vmessages_buffer_name = make_pure_c_string ("*Messages*");
27980 staticpro (&Vmessages_buffer_name);
27981
27982 mode_line_proptrans_alist = Qnil;
27983 staticpro (&mode_line_proptrans_alist);
27984 mode_line_string_list = Qnil;
27985 staticpro (&mode_line_string_list);
27986 mode_line_string_face = Qnil;
27987 staticpro (&mode_line_string_face);
27988 mode_line_string_face_prop = Qnil;
27989 staticpro (&mode_line_string_face_prop);
27990 Vmode_line_unwind_vector = Qnil;
27991 staticpro (&Vmode_line_unwind_vector);
27992
27993 help_echo_string = Qnil;
27994 staticpro (&help_echo_string);
27995 help_echo_object = Qnil;
27996 staticpro (&help_echo_object);
27997 help_echo_window = Qnil;
27998 staticpro (&help_echo_window);
27999 previous_help_echo_string = Qnil;
28000 staticpro (&previous_help_echo_string);
28001 help_echo_pos = -1;
28002
28003 DEFSYM (Qright_to_left, "right-to-left");
28004 DEFSYM (Qleft_to_right, "left-to-right");
28005
28006 #ifdef HAVE_WINDOW_SYSTEM
28007 DEFVAR_BOOL ("x-stretch-cursor", x_stretch_cursor_p,
28008 doc: /* *Non-nil means draw block cursor as wide as the glyph under it.
28009 For example, if a block cursor is over a tab, it will be drawn as
28010 wide as that tab on the display. */);
28011 x_stretch_cursor_p = 0;
28012 #endif
28013
28014 DEFVAR_LISP ("show-trailing-whitespace", Vshow_trailing_whitespace,
28015 doc: /* *Non-nil means highlight trailing whitespace.
28016 The face used for trailing whitespace is `trailing-whitespace'. */);
28017 Vshow_trailing_whitespace = Qnil;
28018
28019 DEFVAR_LISP ("nobreak-char-display", Vnobreak_char_display,
28020 doc: /* Control highlighting of non-ASCII space and hyphen chars.
28021 If the value is t, Emacs highlights non-ASCII chars which have the
28022 same appearance as an ASCII space or hyphen, using the `nobreak-space'
28023 or `escape-glyph' face respectively.
28024
28025 U+00A0 (no-break space), U+00AD (soft hyphen), U+2010 (hyphen), and
28026 U+2011 (non-breaking hyphen) are affected.
28027
28028 Any other non-nil value means to display these characters as a escape
28029 glyph followed by an ordinary space or hyphen.
28030
28031 A value of nil means no special handling of these characters. */);
28032 Vnobreak_char_display = Qt;
28033
28034 DEFVAR_LISP ("void-text-area-pointer", Vvoid_text_area_pointer,
28035 doc: /* *The pointer shape to show in void text areas.
28036 A value of nil means to show the text pointer. Other options are `arrow',
28037 `text', `hand', `vdrag', `hdrag', `modeline', and `hourglass'. */);
28038 Vvoid_text_area_pointer = Qarrow;
28039
28040 DEFVAR_LISP ("inhibit-redisplay", Vinhibit_redisplay,
28041 doc: /* Non-nil means don't actually do any redisplay.
28042 This is used for internal purposes. */);
28043 Vinhibit_redisplay = Qnil;
28044
28045 DEFVAR_LISP ("global-mode-string", Vglobal_mode_string,
28046 doc: /* String (or mode line construct) included (normally) in `mode-line-format'. */);
28047 Vglobal_mode_string = Qnil;
28048
28049 DEFVAR_LISP ("overlay-arrow-position", Voverlay_arrow_position,
28050 doc: /* Marker for where to display an arrow on top of the buffer text.
28051 This must be the beginning of a line in order to work.
28052 See also `overlay-arrow-string'. */);
28053 Voverlay_arrow_position = Qnil;
28054
28055 DEFVAR_LISP ("overlay-arrow-string", Voverlay_arrow_string,
28056 doc: /* String to display as an arrow in non-window frames.
28057 See also `overlay-arrow-position'. */);
28058 Voverlay_arrow_string = make_pure_c_string ("=>");
28059
28060 DEFVAR_LISP ("overlay-arrow-variable-list", Voverlay_arrow_variable_list,
28061 doc: /* List of variables (symbols) which hold markers for overlay arrows.
28062 The symbols on this list are examined during redisplay to determine
28063 where to display overlay arrows. */);
28064 Voverlay_arrow_variable_list
28065 = Fcons (intern_c_string ("overlay-arrow-position"), Qnil);
28066
28067 DEFVAR_INT ("scroll-step", emacs_scroll_step,
28068 doc: /* *The number of lines to try scrolling a window by when point moves out.
28069 If that fails to bring point back on frame, point is centered instead.
28070 If this is zero, point is always centered after it moves off frame.
28071 If you want scrolling to always be a line at a time, you should set
28072 `scroll-conservatively' to a large value rather than set this to 1. */);
28073
28074 DEFVAR_INT ("scroll-conservatively", scroll_conservatively,
28075 doc: /* *Scroll up to this many lines, to bring point back on screen.
28076 If point moves off-screen, redisplay will scroll by up to
28077 `scroll-conservatively' lines in order to bring point just barely
28078 onto the screen again. If that cannot be done, then redisplay
28079 recenters point as usual.
28080
28081 If the value is greater than 100, redisplay will never recenter point,
28082 but will always scroll just enough text to bring point into view, even
28083 if you move far away.
28084
28085 A value of zero means always recenter point if it moves off screen. */);
28086 scroll_conservatively = 0;
28087
28088 DEFVAR_INT ("scroll-margin", scroll_margin,
28089 doc: /* *Number of lines of margin at the top and bottom of a window.
28090 Recenter the window whenever point gets within this many lines
28091 of the top or bottom of the window. */);
28092 scroll_margin = 0;
28093
28094 DEFVAR_LISP ("display-pixels-per-inch", Vdisplay_pixels_per_inch,
28095 doc: /* Pixels per inch value for non-window system displays.
28096 Value is a number or a cons (WIDTH-DPI . HEIGHT-DPI). */);
28097 Vdisplay_pixels_per_inch = make_float (72.0);
28098
28099 #if GLYPH_DEBUG
28100 DEFVAR_INT ("debug-end-pos", debug_end_pos, doc: /* Don't ask. */);
28101 #endif
28102
28103 DEFVAR_LISP ("truncate-partial-width-windows",
28104 Vtruncate_partial_width_windows,
28105 doc: /* Non-nil means truncate lines in windows narrower than the frame.
28106 For an integer value, truncate lines in each window narrower than the
28107 full frame width, provided the window width is less than that integer;
28108 otherwise, respect the value of `truncate-lines'.
28109
28110 For any other non-nil value, truncate lines in all windows that do
28111 not span the full frame width.
28112
28113 A value of nil means to respect the value of `truncate-lines'.
28114
28115 If `word-wrap' is enabled, you might want to reduce this. */);
28116 Vtruncate_partial_width_windows = make_number (50);
28117
28118 DEFVAR_BOOL ("mode-line-inverse-video", mode_line_inverse_video,
28119 doc: /* When nil, display the mode-line/header-line/menu-bar in the default face.
28120 Any other value means to use the appropriate face, `mode-line',
28121 `header-line', or `menu' respectively. */);
28122 mode_line_inverse_video = 1;
28123
28124 DEFVAR_LISP ("line-number-display-limit", Vline_number_display_limit,
28125 doc: /* *Maximum buffer size for which line number should be displayed.
28126 If the buffer is bigger than this, the line number does not appear
28127 in the mode line. A value of nil means no limit. */);
28128 Vline_number_display_limit = Qnil;
28129
28130 DEFVAR_INT ("line-number-display-limit-width",
28131 line_number_display_limit_width,
28132 doc: /* *Maximum line width (in characters) for line number display.
28133 If the average length of the lines near point is bigger than this, then the
28134 line number may be omitted from the mode line. */);
28135 line_number_display_limit_width = 200;
28136
28137 DEFVAR_BOOL ("highlight-nonselected-windows", highlight_nonselected_windows,
28138 doc: /* *Non-nil means highlight region even in nonselected windows. */);
28139 highlight_nonselected_windows = 0;
28140
28141 DEFVAR_BOOL ("multiple-frames", multiple_frames,
28142 doc: /* Non-nil if more than one frame is visible on this display.
28143 Minibuffer-only frames don't count, but iconified frames do.
28144 This variable is not guaranteed to be accurate except while processing
28145 `frame-title-format' and `icon-title-format'. */);
28146
28147 DEFVAR_LISP ("frame-title-format", Vframe_title_format,
28148 doc: /* Template for displaying the title bar of visible frames.
28149 \(Assuming the window manager supports this feature.)
28150
28151 This variable has the same structure as `mode-line-format', except that
28152 the %c and %l constructs are ignored. It is used only on frames for
28153 which no explicit name has been set \(see `modify-frame-parameters'). */);
28154
28155 DEFVAR_LISP ("icon-title-format", Vicon_title_format,
28156 doc: /* Template for displaying the title bar of an iconified frame.
28157 \(Assuming the window manager supports this feature.)
28158 This variable has the same structure as `mode-line-format' (which see),
28159 and is used only on frames for which no explicit name has been set
28160 \(see `modify-frame-parameters'). */);
28161 Vicon_title_format
28162 = Vframe_title_format
28163 = pure_cons (intern_c_string ("multiple-frames"),
28164 pure_cons (make_pure_c_string ("%b"),
28165 pure_cons (pure_cons (empty_unibyte_string,
28166 pure_cons (intern_c_string ("invocation-name"),
28167 pure_cons (make_pure_c_string ("@"),
28168 pure_cons (intern_c_string ("system-name"),
28169 Qnil)))),
28170 Qnil)));
28171
28172 DEFVAR_LISP ("message-log-max", Vmessage_log_max,
28173 doc: /* Maximum number of lines to keep in the message log buffer.
28174 If nil, disable message logging. If t, log messages but don't truncate
28175 the buffer when it becomes large. */);
28176 Vmessage_log_max = make_number (100);
28177
28178 DEFVAR_LISP ("window-size-change-functions", Vwindow_size_change_functions,
28179 doc: /* Functions called before redisplay, if window sizes have changed.
28180 The value should be a list of functions that take one argument.
28181 Just before redisplay, for each frame, if any of its windows have changed
28182 size since the last redisplay, or have been split or deleted,
28183 all the functions in the list are called, with the frame as argument. */);
28184 Vwindow_size_change_functions = Qnil;
28185
28186 DEFVAR_LISP ("window-scroll-functions", Vwindow_scroll_functions,
28187 doc: /* List of functions to call before redisplaying a window with scrolling.
28188 Each function is called with two arguments, the window and its new
28189 display-start position. Note that these functions are also called by
28190 `set-window-buffer'. Also note that the value of `window-end' is not
28191 valid when these functions are called. */);
28192 Vwindow_scroll_functions = Qnil;
28193
28194 DEFVAR_LISP ("window-text-change-functions",
28195 Vwindow_text_change_functions,
28196 doc: /* Functions to call in redisplay when text in the window might change. */);
28197 Vwindow_text_change_functions = Qnil;
28198
28199 DEFVAR_LISP ("redisplay-end-trigger-functions", Vredisplay_end_trigger_functions,
28200 doc: /* Functions called when redisplay of a window reaches the end trigger.
28201 Each function is called with two arguments, the window and the end trigger value.
28202 See `set-window-redisplay-end-trigger'. */);
28203 Vredisplay_end_trigger_functions = Qnil;
28204
28205 DEFVAR_LISP ("mouse-autoselect-window", Vmouse_autoselect_window,
28206 doc: /* *Non-nil means autoselect window with mouse pointer.
28207 If nil, do not autoselect windows.
28208 A positive number means delay autoselection by that many seconds: a
28209 window is autoselected only after the mouse has remained in that
28210 window for the duration of the delay.
28211 A negative number has a similar effect, but causes windows to be
28212 autoselected only after the mouse has stopped moving. \(Because of
28213 the way Emacs compares mouse events, you will occasionally wait twice
28214 that time before the window gets selected.\)
28215 Any other value means to autoselect window instantaneously when the
28216 mouse pointer enters it.
28217
28218 Autoselection selects the minibuffer only if it is active, and never
28219 unselects the minibuffer if it is active.
28220
28221 When customizing this variable make sure that the actual value of
28222 `focus-follows-mouse' matches the behavior of your window manager. */);
28223 Vmouse_autoselect_window = Qnil;
28224
28225 DEFVAR_LISP ("auto-resize-tool-bars", Vauto_resize_tool_bars,
28226 doc: /* *Non-nil means automatically resize tool-bars.
28227 This dynamically changes the tool-bar's height to the minimum height
28228 that is needed to make all tool-bar items visible.
28229 If value is `grow-only', the tool-bar's height is only increased
28230 automatically; to decrease the tool-bar height, use \\[recenter]. */);
28231 Vauto_resize_tool_bars = Qt;
28232
28233 DEFVAR_BOOL ("auto-raise-tool-bar-buttons", auto_raise_tool_bar_buttons_p,
28234 doc: /* *Non-nil means raise tool-bar buttons when the mouse moves over them. */);
28235 auto_raise_tool_bar_buttons_p = 1;
28236
28237 DEFVAR_BOOL ("make-cursor-line-fully-visible", make_cursor_line_fully_visible_p,
28238 doc: /* *Non-nil means to scroll (recenter) cursor line if it is not fully visible. */);
28239 make_cursor_line_fully_visible_p = 1;
28240
28241 DEFVAR_LISP ("tool-bar-border", Vtool_bar_border,
28242 doc: /* *Border below tool-bar in pixels.
28243 If an integer, use it as the height of the border.
28244 If it is one of `internal-border-width' or `border-width', use the
28245 value of the corresponding frame parameter.
28246 Otherwise, no border is added below the tool-bar. */);
28247 Vtool_bar_border = Qinternal_border_width;
28248
28249 DEFVAR_LISP ("tool-bar-button-margin", Vtool_bar_button_margin,
28250 doc: /* *Margin around tool-bar buttons in pixels.
28251 If an integer, use that for both horizontal and vertical margins.
28252 Otherwise, value should be a pair of integers `(HORZ . VERT)' with
28253 HORZ specifying the horizontal margin, and VERT specifying the
28254 vertical margin. */);
28255 Vtool_bar_button_margin = make_number (DEFAULT_TOOL_BAR_BUTTON_MARGIN);
28256
28257 DEFVAR_INT ("tool-bar-button-relief", tool_bar_button_relief,
28258 doc: /* *Relief thickness of tool-bar buttons. */);
28259 tool_bar_button_relief = DEFAULT_TOOL_BAR_BUTTON_RELIEF;
28260
28261 DEFVAR_LISP ("tool-bar-style", Vtool_bar_style,
28262 doc: /* Tool bar style to use.
28263 It can be one of
28264 image - show images only
28265 text - show text only
28266 both - show both, text below image
28267 both-horiz - show text to the right of the image
28268 text-image-horiz - show text to the left of the image
28269 any other - use system default or image if no system default. */);
28270 Vtool_bar_style = Qnil;
28271
28272 DEFVAR_INT ("tool-bar-max-label-size", tool_bar_max_label_size,
28273 doc: /* *Maximum number of characters a label can have to be shown.
28274 The tool bar style must also show labels for this to have any effect, see
28275 `tool-bar-style'. */);
28276 tool_bar_max_label_size = DEFAULT_TOOL_BAR_LABEL_SIZE;
28277
28278 DEFVAR_LISP ("fontification-functions", Vfontification_functions,
28279 doc: /* List of functions to call to fontify regions of text.
28280 Each function is called with one argument POS. Functions must
28281 fontify a region starting at POS in the current buffer, and give
28282 fontified regions the property `fontified'. */);
28283 Vfontification_functions = Qnil;
28284 Fmake_variable_buffer_local (Qfontification_functions);
28285
28286 DEFVAR_BOOL ("unibyte-display-via-language-environment",
28287 unibyte_display_via_language_environment,
28288 doc: /* *Non-nil means display unibyte text according to language environment.
28289 Specifically, this means that raw bytes in the range 160-255 decimal
28290 are displayed by converting them to the equivalent multibyte characters
28291 according to the current language environment. As a result, they are
28292 displayed according to the current fontset.
28293
28294 Note that this variable affects only how these bytes are displayed,
28295 but does not change the fact they are interpreted as raw bytes. */);
28296 unibyte_display_via_language_environment = 0;
28297
28298 DEFVAR_LISP ("max-mini-window-height", Vmax_mini_window_height,
28299 doc: /* *Maximum height for resizing mini-windows (the minibuffer and the echo area).
28300 If a float, it specifies a fraction of the mini-window frame's height.
28301 If an integer, it specifies a number of lines. */);
28302 Vmax_mini_window_height = make_float (0.25);
28303
28304 DEFVAR_LISP ("resize-mini-windows", Vresize_mini_windows,
28305 doc: /* How to resize mini-windows (the minibuffer and the echo area).
28306 A value of nil means don't automatically resize mini-windows.
28307 A value of t means resize them to fit the text displayed in them.
28308 A value of `grow-only', the default, means let mini-windows grow only;
28309 they return to their normal size when the minibuffer is closed, or the
28310 echo area becomes empty. */);
28311 Vresize_mini_windows = Qgrow_only;
28312
28313 DEFVAR_LISP ("blink-cursor-alist", Vblink_cursor_alist,
28314 doc: /* Alist specifying how to blink the cursor off.
28315 Each element has the form (ON-STATE . OFF-STATE). Whenever the
28316 `cursor-type' frame-parameter or variable equals ON-STATE,
28317 comparing using `equal', Emacs uses OFF-STATE to specify
28318 how to blink it off. ON-STATE and OFF-STATE are values for
28319 the `cursor-type' frame parameter.
28320
28321 If a frame's ON-STATE has no entry in this list,
28322 the frame's other specifications determine how to blink the cursor off. */);
28323 Vblink_cursor_alist = Qnil;
28324
28325 DEFVAR_BOOL ("auto-hscroll-mode", automatic_hscrolling_p,
28326 doc: /* Allow or disallow automatic horizontal scrolling of windows.
28327 If non-nil, windows are automatically scrolled horizontally to make
28328 point visible. */);
28329 automatic_hscrolling_p = 1;
28330 DEFSYM (Qauto_hscroll_mode, "auto-hscroll-mode");
28331
28332 DEFVAR_INT ("hscroll-margin", hscroll_margin,
28333 doc: /* *How many columns away from the window edge point is allowed to get
28334 before automatic hscrolling will horizontally scroll the window. */);
28335 hscroll_margin = 5;
28336
28337 DEFVAR_LISP ("hscroll-step", Vhscroll_step,
28338 doc: /* *How many columns to scroll the window when point gets too close to the edge.
28339 When point is less than `hscroll-margin' columns from the window
28340 edge, automatic hscrolling will scroll the window by the amount of columns
28341 determined by this variable. If its value is a positive integer, scroll that
28342 many columns. If it's a positive floating-point number, it specifies the
28343 fraction of the window's width to scroll. If it's nil or zero, point will be
28344 centered horizontally after the scroll. Any other value, including negative
28345 numbers, are treated as if the value were zero.
28346
28347 Automatic hscrolling always moves point outside the scroll margin, so if
28348 point was more than scroll step columns inside the margin, the window will
28349 scroll more than the value given by the scroll step.
28350
28351 Note that the lower bound for automatic hscrolling specified by `scroll-left'
28352 and `scroll-right' overrides this variable's effect. */);
28353 Vhscroll_step = make_number (0);
28354
28355 DEFVAR_BOOL ("message-truncate-lines", message_truncate_lines,
28356 doc: /* If non-nil, messages are truncated instead of resizing the echo area.
28357 Bind this around calls to `message' to let it take effect. */);
28358 message_truncate_lines = 0;
28359
28360 DEFVAR_LISP ("menu-bar-update-hook", Vmenu_bar_update_hook,
28361 doc: /* Normal hook run to update the menu bar definitions.
28362 Redisplay runs this hook before it redisplays the menu bar.
28363 This is used to update submenus such as Buffers,
28364 whose contents depend on various data. */);
28365 Vmenu_bar_update_hook = Qnil;
28366
28367 DEFVAR_LISP ("menu-updating-frame", Vmenu_updating_frame,
28368 doc: /* Frame for which we are updating a menu.
28369 The enable predicate for a menu binding should check this variable. */);
28370 Vmenu_updating_frame = Qnil;
28371
28372 DEFVAR_BOOL ("inhibit-menubar-update", inhibit_menubar_update,
28373 doc: /* Non-nil means don't update menu bars. Internal use only. */);
28374 inhibit_menubar_update = 0;
28375
28376 DEFVAR_LISP ("wrap-prefix", Vwrap_prefix,
28377 doc: /* Prefix prepended to all continuation lines at display time.
28378 The value may be a string, an image, or a stretch-glyph; it is
28379 interpreted in the same way as the value of a `display' text property.
28380
28381 This variable is overridden by any `wrap-prefix' text or overlay
28382 property.
28383
28384 To add a prefix to non-continuation lines, use `line-prefix'. */);
28385 Vwrap_prefix = Qnil;
28386 DEFSYM (Qwrap_prefix, "wrap-prefix");
28387 Fmake_variable_buffer_local (Qwrap_prefix);
28388
28389 DEFVAR_LISP ("line-prefix", Vline_prefix,
28390 doc: /* Prefix prepended to all non-continuation lines at display time.
28391 The value may be a string, an image, or a stretch-glyph; it is
28392 interpreted in the same way as the value of a `display' text property.
28393
28394 This variable is overridden by any `line-prefix' text or overlay
28395 property.
28396
28397 To add a prefix to continuation lines, use `wrap-prefix'. */);
28398 Vline_prefix = Qnil;
28399 DEFSYM (Qline_prefix, "line-prefix");
28400 Fmake_variable_buffer_local (Qline_prefix);
28401
28402 DEFVAR_BOOL ("inhibit-eval-during-redisplay", inhibit_eval_during_redisplay,
28403 doc: /* Non-nil means don't eval Lisp during redisplay. */);
28404 inhibit_eval_during_redisplay = 0;
28405
28406 DEFVAR_BOOL ("inhibit-free-realized-faces", inhibit_free_realized_faces,
28407 doc: /* Non-nil means don't free realized faces. Internal use only. */);
28408 inhibit_free_realized_faces = 0;
28409
28410 #if GLYPH_DEBUG
28411 DEFVAR_BOOL ("inhibit-try-window-id", inhibit_try_window_id,
28412 doc: /* Inhibit try_window_id display optimization. */);
28413 inhibit_try_window_id = 0;
28414
28415 DEFVAR_BOOL ("inhibit-try-window-reusing", inhibit_try_window_reusing,
28416 doc: /* Inhibit try_window_reusing display optimization. */);
28417 inhibit_try_window_reusing = 0;
28418
28419 DEFVAR_BOOL ("inhibit-try-cursor-movement", inhibit_try_cursor_movement,
28420 doc: /* Inhibit try_cursor_movement display optimization. */);
28421 inhibit_try_cursor_movement = 0;
28422 #endif /* GLYPH_DEBUG */
28423
28424 DEFVAR_INT ("overline-margin", overline_margin,
28425 doc: /* *Space between overline and text, in pixels.
28426 The default value is 2: the height of the overline (1 pixel) plus 1 pixel
28427 margin to the caracter height. */);
28428 overline_margin = 2;
28429
28430 DEFVAR_INT ("underline-minimum-offset",
28431 underline_minimum_offset,
28432 doc: /* Minimum distance between baseline and underline.
28433 This can improve legibility of underlined text at small font sizes,
28434 particularly when using variable `x-use-underline-position-properties'
28435 with fonts that specify an UNDERLINE_POSITION relatively close to the
28436 baseline. The default value is 1. */);
28437 underline_minimum_offset = 1;
28438
28439 DEFVAR_BOOL ("display-hourglass", display_hourglass_p,
28440 doc: /* Non-nil means show an hourglass pointer, when Emacs is busy.
28441 This feature only works when on a window system that can change
28442 cursor shapes. */);
28443 display_hourglass_p = 1;
28444
28445 DEFVAR_LISP ("hourglass-delay", Vhourglass_delay,
28446 doc: /* *Seconds to wait before displaying an hourglass pointer when Emacs is busy. */);
28447 Vhourglass_delay = make_number (DEFAULT_HOURGLASS_DELAY);
28448
28449 hourglass_atimer = NULL;
28450 hourglass_shown_p = 0;
28451
28452 DEFSYM (Qglyphless_char, "glyphless-char");
28453 DEFSYM (Qhex_code, "hex-code");
28454 DEFSYM (Qempty_box, "empty-box");
28455 DEFSYM (Qthin_space, "thin-space");
28456 DEFSYM (Qzero_width, "zero-width");
28457
28458 DEFSYM (Qglyphless_char_display, "glyphless-char-display");
28459 /* Intern this now in case it isn't already done.
28460 Setting this variable twice is harmless.
28461 But don't staticpro it here--that is done in alloc.c. */
28462 Qchar_table_extra_slots = intern_c_string ("char-table-extra-slots");
28463 Fput (Qglyphless_char_display, Qchar_table_extra_slots, make_number (1));
28464
28465 DEFVAR_LISP ("glyphless-char-display", Vglyphless_char_display,
28466 doc: /* Char-table defining glyphless characters.
28467 Each element, if non-nil, should be one of the following:
28468 an ASCII acronym string: display this string in a box
28469 `hex-code': display the hexadecimal code of a character in a box
28470 `empty-box': display as an empty box
28471 `thin-space': display as 1-pixel width space
28472 `zero-width': don't display
28473 An element may also be a cons cell (GRAPHICAL . TEXT), which specifies the
28474 display method for graphical terminals and text terminals respectively.
28475 GRAPHICAL and TEXT should each have one of the values listed above.
28476
28477 The char-table has one extra slot to control the display of a character for
28478 which no font is found. This slot only takes effect on graphical terminals.
28479 Its value should be an ASCII acronym string, `hex-code', `empty-box', or
28480 `thin-space'. The default is `empty-box'. */);
28481 Vglyphless_char_display = Fmake_char_table (Qglyphless_char_display, Qnil);
28482 Fset_char_table_extra_slot (Vglyphless_char_display, make_number (0),
28483 Qempty_box);
28484 }
28485
28486
28487 /* Initialize this module when Emacs starts. */
28488
28489 void
28490 init_xdisp (void)
28491 {
28492 current_header_line_height = current_mode_line_height = -1;
28493
28494 CHARPOS (this_line_start_pos) = 0;
28495
28496 if (!noninteractive)
28497 {
28498 struct window *m = XWINDOW (minibuf_window);
28499 Lisp_Object frame = m->frame;
28500 struct frame *f = XFRAME (frame);
28501 Lisp_Object root = FRAME_ROOT_WINDOW (f);
28502 struct window *r = XWINDOW (root);
28503 int i;
28504
28505 echo_area_window = minibuf_window;
28506
28507 XSETFASTINT (r->top_line, FRAME_TOP_MARGIN (f));
28508 XSETFASTINT (r->total_lines, FRAME_LINES (f) - 1 - FRAME_TOP_MARGIN (f));
28509 XSETFASTINT (r->total_cols, FRAME_COLS (f));
28510 XSETFASTINT (m->top_line, FRAME_LINES (f) - 1);
28511 XSETFASTINT (m->total_lines, 1);
28512 XSETFASTINT (m->total_cols, FRAME_COLS (f));
28513
28514 scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs;
28515 scratch_glyph_row.glyphs[TEXT_AREA + 1]
28516 = scratch_glyphs + MAX_SCRATCH_GLYPHS;
28517
28518 /* The default ellipsis glyphs `...'. */
28519 for (i = 0; i < 3; ++i)
28520 default_invis_vector[i] = make_number ('.');
28521 }
28522
28523 {
28524 /* Allocate the buffer for frame titles.
28525 Also used for `format-mode-line'. */
28526 int size = 100;
28527 mode_line_noprop_buf = (char *) xmalloc (size);
28528 mode_line_noprop_buf_end = mode_line_noprop_buf + size;
28529 mode_line_noprop_ptr = mode_line_noprop_buf;
28530 mode_line_target = MODE_LINE_DISPLAY;
28531 }
28532
28533 help_echo_showing_p = 0;
28534 }
28535
28536 /* Since w32 does not support atimers, it defines its own implementation of
28537 the following three functions in w32fns.c. */
28538 #ifndef WINDOWSNT
28539
28540 /* Platform-independent portion of hourglass implementation. */
28541
28542 /* Return non-zero if houglass timer has been started or hourglass is shown. */
28543 int
28544 hourglass_started (void)
28545 {
28546 return hourglass_shown_p || hourglass_atimer != NULL;
28547 }
28548
28549 /* Cancel a currently active hourglass timer, and start a new one. */
28550 void
28551 start_hourglass (void)
28552 {
28553 #if defined (HAVE_WINDOW_SYSTEM)
28554 EMACS_TIME delay;
28555 int secs, usecs = 0;
28556
28557 cancel_hourglass ();
28558
28559 if (INTEGERP (Vhourglass_delay)
28560 && XINT (Vhourglass_delay) > 0)
28561 secs = XFASTINT (Vhourglass_delay);
28562 else if (FLOATP (Vhourglass_delay)
28563 && XFLOAT_DATA (Vhourglass_delay) > 0)
28564 {
28565 Lisp_Object tem;
28566 tem = Ftruncate (Vhourglass_delay, Qnil);
28567 secs = XFASTINT (tem);
28568 usecs = (XFLOAT_DATA (Vhourglass_delay) - secs) * 1000000;
28569 }
28570 else
28571 secs = DEFAULT_HOURGLASS_DELAY;
28572
28573 EMACS_SET_SECS_USECS (delay, secs, usecs);
28574 hourglass_atimer = start_atimer (ATIMER_RELATIVE, delay,
28575 show_hourglass, NULL);
28576 #endif
28577 }
28578
28579
28580 /* Cancel the hourglass cursor timer if active, hide a busy cursor if
28581 shown. */
28582 void
28583 cancel_hourglass (void)
28584 {
28585 #if defined (HAVE_WINDOW_SYSTEM)
28586 if (hourglass_atimer)
28587 {
28588 cancel_atimer (hourglass_atimer);
28589 hourglass_atimer = NULL;
28590 }
28591
28592 if (hourglass_shown_p)
28593 hide_hourglass ();
28594 #endif
28595 }
28596 #endif /* ! WINDOWSNT */