src/xdisp.c (compute_display_string_pos): Fix bogus parentheses.
[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 Calls to get_next_display_element fill the iterator structure with
134 relevant information about the next thing to display. Calls to
135 set_iterator_to_next move the iterator to the next thing.
136
137 Besides this, an iterator also contains information about the
138 display environment in which glyphs for display elements are to be
139 produced. It has fields for the width and height of the display,
140 the information whether long lines are truncated or continued, a
141 current X and Y position, and lots of other stuff you can better
142 see in dispextern.h.
143
144 Glyphs in a desired matrix are normally constructed in a loop
145 calling get_next_display_element and then PRODUCE_GLYPHS. The call
146 to PRODUCE_GLYPHS will fill the iterator structure with pixel
147 information about the element being displayed and at the same time
148 produce glyphs for it. If the display element fits on the line
149 being displayed, set_iterator_to_next is called next, otherwise the
150 glyphs produced are discarded. The function display_line is the
151 workhorse of filling glyph rows in the desired matrix with glyphs.
152 In addition to producing glyphs, it also handles line truncation
153 and continuation, word wrap, and cursor positioning (for the
154 latter, see also set_cursor_from_row).
155
156 Frame matrices.
157
158 That just couldn't be all, could it? What about terminal types not
159 supporting operations on sub-windows of the screen? To update the
160 display on such a terminal, window-based glyph matrices are not
161 well suited. To be able to reuse part of the display (scrolling
162 lines up and down), we must instead have a view of the whole
163 screen. This is what `frame matrices' are for. They are a trick.
164
165 Frames on terminals like above have a glyph pool. Windows on such
166 a frame sub-allocate their glyph memory from their frame's glyph
167 pool. The frame itself is given its own glyph matrices. By
168 coincidence---or maybe something else---rows in window glyph
169 matrices are slices of corresponding rows in frame matrices. Thus
170 writing to window matrices implicitly updates a frame matrix which
171 provides us with the view of the whole screen that we originally
172 wanted to have without having to move many bytes around. To be
173 honest, there is a little bit more done, but not much more. If you
174 plan to extend that code, take a look at dispnew.c. The function
175 build_frame_matrix is a good starting point.
176
177 Bidirectional display.
178
179 Bidirectional display adds quite some hair to this already complex
180 design. The good news are that a large portion of that hairy stuff
181 is hidden in bidi.c behind only 3 interfaces. bidi.c implements a
182 reordering engine which is called by set_iterator_to_next and
183 returns the next character to display in the visual order. See
184 commentary on bidi.c for more details. As far as redisplay is
185 concerned, the effect of calling bidi_move_to_visually_next, the
186 main interface of the reordering engine, is that the iterator gets
187 magically placed on the buffer or string position that is to be
188 displayed next. In other words, a linear iteration through the
189 buffer/string is replaced with a non-linear one. All the rest of
190 the redisplay is oblivious to the bidi reordering.
191
192 Well, almost oblivious---there are still complications, most of
193 them due to the fact that buffer and string positions no longer
194 change monotonously with glyph indices in a glyph row. Moreover,
195 for continued lines, the buffer positions may not even be
196 monotonously changing with vertical positions. Also, accounting
197 for face changes, overlays, etc. becomes more complex because
198 non-linear iteration could potentially skip many positions with
199 changes, and then cross them again on the way back...
200
201 One other prominent effect of bidirectional display is that some
202 paragraphs of text need to be displayed starting at the right
203 margin of the window---the so-called right-to-left, or R2L
204 paragraphs. R2L paragraphs are displayed with R2L glyph rows,
205 which have their reversed_p flag set. The bidi reordering engine
206 produces characters in such rows starting from the character which
207 should be the rightmost on display. PRODUCE_GLYPHS then reverses
208 the order, when it fills up the glyph row whose reversed_p flag is
209 set, by prepending each new glyph to what is already there, instead
210 of appending it. When the glyph row is complete, the function
211 extend_face_to_end_of_line fills the empty space to the left of the
212 leftmost character with special glyphs, which will display as,
213 well, empty. On text terminals, these special glyphs are simply
214 blank characters. On graphics terminals, there's a single stretch
215 glyph of a suitably computed width. Both the blanks and the
216 stretch glyph are given the face of the background of the line.
217 This way, the terminal-specific back-end can still draw the glyphs
218 left to right, even for R2L lines.
219
220 Bidirectional display and character compositions
221
222 Some scripts cannot be displayed by drawing each character
223 individually, because adjacent characters change each other's shape
224 on display. For example, Arabic and Indic scripts belong to this
225 category.
226
227 Emacs display supports this by providing "character compositions",
228 most of which is implemented in composite.c. During the buffer
229 scan that delivers characters to PRODUCE_GLYPHS, if the next
230 character to be delivered is a composed character, the iteration
231 calls composition_reseat_it and next_element_from_composition. If
232 they succeed to compose the character with one or more of the
233 following characters, the whole sequence of characters that where
234 composed is recorded in the `struct composition_it' object that is
235 part of the buffer iterator. The composed sequence could produce
236 one or more font glyphs (called "grapheme clusters") on the screen.
237 Each of these grapheme clusters is then delivered to PRODUCE_GLYPHS
238 in the direction corresponding to the current bidi scan direction
239 (recorded in the scan_dir member of the `struct bidi_it' object
240 that is part of the buffer iterator). In particular, if the bidi
241 iterator currently scans the buffer backwards, the grapheme
242 clusters are delivered back to front. This reorders the grapheme
243 clusters as appropriate for the current bidi context. Note that
244 this means that the grapheme clusters are always stored in the
245 LGSTRING object (see composite.c) in the logical order.
246
247 Moving an iterator in bidirectional text
248 without producing glyphs
249
250 Note one important detail mentioned above: that the bidi reordering
251 engine, driven by the iterator, produces characters in R2L rows
252 starting at the character that will be the rightmost on display.
253 As far as the iterator is concerned, the geometry of such rows is
254 still left to right, i.e. the iterator "thinks" the first character
255 is at the leftmost pixel position. The iterator does not know that
256 PRODUCE_GLYPHS reverses the order of the glyphs that the iterator
257 delivers. This is important when functions from the the move_it_*
258 family are used to get to certain screen position or to match
259 screen coordinates with buffer coordinates: these functions use the
260 iterator geometry, which is left to right even in R2L paragraphs.
261 This works well with most callers of move_it_*, because they need
262 to get to a specific column, and columns are still numbered in the
263 reading order, i.e. the rightmost character in a R2L paragraph is
264 still column zero. But some callers do not get well with this; a
265 notable example is mouse clicks that need to find the character
266 that corresponds to certain pixel coordinates. See
267 buffer_posn_from_coords in dispnew.c for how this is handled. */
268
269 #include <config.h>
270 #include <stdio.h>
271 #include <limits.h>
272 #include <setjmp.h>
273
274 #include "lisp.h"
275 #include "keyboard.h"
276 #include "frame.h"
277 #include "window.h"
278 #include "termchar.h"
279 #include "dispextern.h"
280 #include "buffer.h"
281 #include "character.h"
282 #include "charset.h"
283 #include "indent.h"
284 #include "commands.h"
285 #include "keymap.h"
286 #include "macros.h"
287 #include "disptab.h"
288 #include "termhooks.h"
289 #include "termopts.h"
290 #include "intervals.h"
291 #include "coding.h"
292 #include "process.h"
293 #include "region-cache.h"
294 #include "font.h"
295 #include "fontset.h"
296 #include "blockinput.h"
297
298 #ifdef HAVE_X_WINDOWS
299 #include "xterm.h"
300 #endif
301 #ifdef WINDOWSNT
302 #include "w32term.h"
303 #endif
304 #ifdef HAVE_NS
305 #include "nsterm.h"
306 #endif
307 #ifdef USE_GTK
308 #include "gtkutil.h"
309 #endif
310
311 #include "font.h"
312
313 #ifndef FRAME_X_OUTPUT
314 #define FRAME_X_OUTPUT(f) ((f)->output_data.x)
315 #endif
316
317 #define INFINITY 10000000
318
319 Lisp_Object Qoverriding_local_map, Qoverriding_terminal_local_map;
320 Lisp_Object Qwindow_scroll_functions;
321 static Lisp_Object Qwindow_text_change_functions;
322 static Lisp_Object Qredisplay_end_trigger_functions;
323 Lisp_Object Qinhibit_point_motion_hooks;
324 static Lisp_Object QCeval, QCpropertize;
325 Lisp_Object QCfile, QCdata;
326 static Lisp_Object Qfontified;
327 static Lisp_Object Qgrow_only;
328 static Lisp_Object Qinhibit_eval_during_redisplay;
329 static Lisp_Object Qbuffer_position, Qposition, Qobject;
330 static Lisp_Object Qright_to_left, Qleft_to_right;
331
332 /* Cursor shapes */
333 Lisp_Object Qbar, Qhbar, Qbox, Qhollow;
334
335 /* Pointer shapes */
336 static Lisp_Object Qarrow, Qhand;
337 Lisp_Object Qtext;
338
339 /* Holds the list (error). */
340 static Lisp_Object list_of_error;
341
342 static Lisp_Object Qfontification_functions;
343
344 static Lisp_Object Qwrap_prefix;
345 static Lisp_Object Qline_prefix;
346
347 /* Non-nil means don't actually do any redisplay. */
348
349 Lisp_Object Qinhibit_redisplay;
350
351 /* Names of text properties relevant for redisplay. */
352
353 Lisp_Object Qdisplay;
354
355 Lisp_Object Qspace, QCalign_to;
356 static Lisp_Object QCrelative_width, QCrelative_height;
357 Lisp_Object Qleft_margin, Qright_margin;
358 static Lisp_Object Qspace_width, Qraise;
359 static Lisp_Object Qslice;
360 Lisp_Object Qcenter;
361 static Lisp_Object Qmargin, Qpointer;
362 static Lisp_Object Qline_height;
363
364 #ifdef HAVE_WINDOW_SYSTEM
365
366 /* Test if overflow newline into fringe. Called with iterator IT
367 at or past right window margin, and with IT->current_x set. */
368
369 #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(IT) \
370 (!NILP (Voverflow_newline_into_fringe) \
371 && FRAME_WINDOW_P ((IT)->f) \
372 && ((IT)->bidi_it.paragraph_dir == R2L \
373 ? (WINDOW_LEFT_FRINGE_WIDTH ((IT)->w) > 0) \
374 : (WINDOW_RIGHT_FRINGE_WIDTH ((IT)->w) > 0)) \
375 && (IT)->current_x == (IT)->last_visible_x \
376 && (IT)->line_wrap != WORD_WRAP)
377
378 #else /* !HAVE_WINDOW_SYSTEM */
379 #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(it) 0
380 #endif /* HAVE_WINDOW_SYSTEM */
381
382 /* Test if the display element loaded in IT is a space or tab
383 character. This is used to determine word wrapping. */
384
385 #define IT_DISPLAYING_WHITESPACE(it) \
386 (it->what == IT_CHARACTER && (it->c == ' ' || it->c == '\t'))
387
388 /* Name of the face used to highlight trailing whitespace. */
389
390 static Lisp_Object Qtrailing_whitespace;
391
392 /* Name and number of the face used to highlight escape glyphs. */
393
394 static Lisp_Object Qescape_glyph;
395
396 /* Name and number of the face used to highlight non-breaking spaces. */
397
398 static Lisp_Object Qnobreak_space;
399
400 /* The symbol `image' which is the car of the lists used to represent
401 images in Lisp. Also a tool bar style. */
402
403 Lisp_Object Qimage;
404
405 /* The image map types. */
406 Lisp_Object QCmap;
407 static Lisp_Object QCpointer;
408 static Lisp_Object Qrect, Qcircle, Qpoly;
409
410 /* Tool bar styles */
411 Lisp_Object Qboth, Qboth_horiz, Qtext_image_horiz;
412
413 /* Non-zero means print newline to stdout before next mini-buffer
414 message. */
415
416 int noninteractive_need_newline;
417
418 /* Non-zero means print newline to message log before next message. */
419
420 static int message_log_need_newline;
421
422 /* Three markers that message_dolog uses.
423 It could allocate them itself, but that causes trouble
424 in handling memory-full errors. */
425 static Lisp_Object message_dolog_marker1;
426 static Lisp_Object message_dolog_marker2;
427 static Lisp_Object message_dolog_marker3;
428 \f
429 /* The buffer position of the first character appearing entirely or
430 partially on the line of the selected window which contains the
431 cursor; <= 0 if not known. Set by set_cursor_from_row, used for
432 redisplay optimization in redisplay_internal. */
433
434 static struct text_pos this_line_start_pos;
435
436 /* Number of characters past the end of the line above, including the
437 terminating newline. */
438
439 static struct text_pos this_line_end_pos;
440
441 /* The vertical positions and the height of this line. */
442
443 static int this_line_vpos;
444 static int this_line_y;
445 static int this_line_pixel_height;
446
447 /* X position at which this display line starts. Usually zero;
448 negative if first character is partially visible. */
449
450 static int this_line_start_x;
451
452 /* The smallest character position seen by move_it_* functions as they
453 move across display lines. Used to set MATRIX_ROW_START_CHARPOS of
454 hscrolled lines, see display_line. */
455
456 static struct text_pos this_line_min_pos;
457
458 /* Buffer that this_line_.* variables are referring to. */
459
460 static struct buffer *this_line_buffer;
461
462
463 /* Values of those variables at last redisplay are stored as
464 properties on `overlay-arrow-position' symbol. However, if
465 Voverlay_arrow_position is a marker, last-arrow-position is its
466 numerical position. */
467
468 static Lisp_Object Qlast_arrow_position, Qlast_arrow_string;
469
470 /* Alternative overlay-arrow-string and overlay-arrow-bitmap
471 properties on a symbol in overlay-arrow-variable-list. */
472
473 static Lisp_Object Qoverlay_arrow_string, Qoverlay_arrow_bitmap;
474
475 Lisp_Object Qmenu_bar_update_hook;
476
477 /* Nonzero if an overlay arrow has been displayed in this window. */
478
479 static int overlay_arrow_seen;
480
481 /* Number of windows showing the buffer of the selected window (or
482 another buffer with the same base buffer). keyboard.c refers to
483 this. */
484
485 int buffer_shared;
486
487 /* Vector containing glyphs for an ellipsis `...'. */
488
489 static Lisp_Object default_invis_vector[3];
490
491 /* This is the window where the echo area message was displayed. It
492 is always a mini-buffer window, but it may not be the same window
493 currently active as a mini-buffer. */
494
495 Lisp_Object echo_area_window;
496
497 /* List of pairs (MESSAGE . MULTIBYTE). The function save_message
498 pushes the current message and the value of
499 message_enable_multibyte on the stack, the function restore_message
500 pops the stack and displays MESSAGE again. */
501
502 static Lisp_Object Vmessage_stack;
503
504 /* Nonzero means multibyte characters were enabled when the echo area
505 message was specified. */
506
507 static int message_enable_multibyte;
508
509 /* Nonzero if we should redraw the mode lines on the next redisplay. */
510
511 int update_mode_lines;
512
513 /* Nonzero if window sizes or contents have changed since last
514 redisplay that finished. */
515
516 int windows_or_buffers_changed;
517
518 /* Nonzero means a frame's cursor type has been changed. */
519
520 int cursor_type_changed;
521
522 /* Nonzero after display_mode_line if %l was used and it displayed a
523 line number. */
524
525 static int line_number_displayed;
526
527 /* The name of the *Messages* buffer, a string. */
528
529 static Lisp_Object Vmessages_buffer_name;
530
531 /* Current, index 0, and last displayed echo area message. Either
532 buffers from echo_buffers, or nil to indicate no message. */
533
534 Lisp_Object echo_area_buffer[2];
535
536 /* The buffers referenced from echo_area_buffer. */
537
538 static Lisp_Object echo_buffer[2];
539
540 /* A vector saved used in with_area_buffer to reduce consing. */
541
542 static Lisp_Object Vwith_echo_area_save_vector;
543
544 /* Non-zero means display_echo_area should display the last echo area
545 message again. Set by redisplay_preserve_echo_area. */
546
547 static int display_last_displayed_message_p;
548
549 /* Nonzero if echo area is being used by print; zero if being used by
550 message. */
551
552 static int message_buf_print;
553
554 /* The symbol `inhibit-menubar-update' and its DEFVAR_BOOL variable. */
555
556 static Lisp_Object Qinhibit_menubar_update;
557 static Lisp_Object Qmessage_truncate_lines;
558
559 /* Set to 1 in clear_message to make redisplay_internal aware
560 of an emptied echo area. */
561
562 static int message_cleared_p;
563
564 /* A scratch glyph row with contents used for generating truncation
565 glyphs. Also used in direct_output_for_insert. */
566
567 #define MAX_SCRATCH_GLYPHS 100
568 static struct glyph_row scratch_glyph_row;
569 static struct glyph scratch_glyphs[MAX_SCRATCH_GLYPHS];
570
571 /* Ascent and height of the last line processed by move_it_to. */
572
573 static int last_max_ascent, last_height;
574
575 /* Non-zero if there's a help-echo in the echo area. */
576
577 int help_echo_showing_p;
578
579 /* If >= 0, computed, exact values of mode-line and header-line height
580 to use in the macros CURRENT_MODE_LINE_HEIGHT and
581 CURRENT_HEADER_LINE_HEIGHT. */
582
583 int current_mode_line_height, current_header_line_height;
584
585 /* The maximum distance to look ahead for text properties. Values
586 that are too small let us call compute_char_face and similar
587 functions too often which is expensive. Values that are too large
588 let us call compute_char_face and alike too often because we
589 might not be interested in text properties that far away. */
590
591 #define TEXT_PROP_DISTANCE_LIMIT 100
592
593 #if GLYPH_DEBUG
594
595 /* Non-zero means print traces of redisplay if compiled with
596 GLYPH_DEBUG != 0. */
597
598 int trace_redisplay_p;
599
600 #endif /* GLYPH_DEBUG */
601
602 #ifdef DEBUG_TRACE_MOVE
603 /* Non-zero means trace with TRACE_MOVE to stderr. */
604 int trace_move;
605
606 #define TRACE_MOVE(x) if (trace_move) fprintf x; else (void) 0
607 #else
608 #define TRACE_MOVE(x) (void) 0
609 #endif
610
611 static Lisp_Object Qauto_hscroll_mode;
612
613 /* Buffer being redisplayed -- for redisplay_window_error. */
614
615 static struct buffer *displayed_buffer;
616
617 /* Value returned from text property handlers (see below). */
618
619 enum prop_handled
620 {
621 HANDLED_NORMALLY,
622 HANDLED_RECOMPUTE_PROPS,
623 HANDLED_OVERLAY_STRING_CONSUMED,
624 HANDLED_RETURN
625 };
626
627 /* A description of text properties that redisplay is interested
628 in. */
629
630 struct props
631 {
632 /* The name of the property. */
633 Lisp_Object *name;
634
635 /* A unique index for the property. */
636 enum prop_idx idx;
637
638 /* A handler function called to set up iterator IT from the property
639 at IT's current position. Value is used to steer handle_stop. */
640 enum prop_handled (*handler) (struct it *it);
641 };
642
643 static enum prop_handled handle_face_prop (struct it *);
644 static enum prop_handled handle_invisible_prop (struct it *);
645 static enum prop_handled handle_display_prop (struct it *);
646 static enum prop_handled handle_composition_prop (struct it *);
647 static enum prop_handled handle_overlay_change (struct it *);
648 static enum prop_handled handle_fontified_prop (struct it *);
649
650 /* Properties handled by iterators. */
651
652 static struct props it_props[] =
653 {
654 {&Qfontified, FONTIFIED_PROP_IDX, handle_fontified_prop},
655 /* Handle `face' before `display' because some sub-properties of
656 `display' need to know the face. */
657 {&Qface, FACE_PROP_IDX, handle_face_prop},
658 {&Qdisplay, DISPLAY_PROP_IDX, handle_display_prop},
659 {&Qinvisible, INVISIBLE_PROP_IDX, handle_invisible_prop},
660 {&Qcomposition, COMPOSITION_PROP_IDX, handle_composition_prop},
661 {NULL, 0, NULL}
662 };
663
664 /* Value is the position described by X. If X is a marker, value is
665 the marker_position of X. Otherwise, value is X. */
666
667 #define COERCE_MARKER(X) (MARKERP ((X)) ? Fmarker_position (X) : (X))
668
669 /* Enumeration returned by some move_it_.* functions internally. */
670
671 enum move_it_result
672 {
673 /* Not used. Undefined value. */
674 MOVE_UNDEFINED,
675
676 /* Move ended at the requested buffer position or ZV. */
677 MOVE_POS_MATCH_OR_ZV,
678
679 /* Move ended at the requested X pixel position. */
680 MOVE_X_REACHED,
681
682 /* Move within a line ended at the end of a line that must be
683 continued. */
684 MOVE_LINE_CONTINUED,
685
686 /* Move within a line ended at the end of a line that would
687 be displayed truncated. */
688 MOVE_LINE_TRUNCATED,
689
690 /* Move within a line ended at a line end. */
691 MOVE_NEWLINE_OR_CR
692 };
693
694 /* This counter is used to clear the face cache every once in a while
695 in redisplay_internal. It is incremented for each redisplay.
696 Every CLEAR_FACE_CACHE_COUNT full redisplays, the face cache is
697 cleared. */
698
699 #define CLEAR_FACE_CACHE_COUNT 500
700 static int clear_face_cache_count;
701
702 /* Similarly for the image cache. */
703
704 #ifdef HAVE_WINDOW_SYSTEM
705 #define CLEAR_IMAGE_CACHE_COUNT 101
706 static int clear_image_cache_count;
707
708 /* Null glyph slice */
709 static struct glyph_slice null_glyph_slice = { 0, 0, 0, 0 };
710 #endif
711
712 /* Non-zero while redisplay_internal is in progress. */
713
714 int redisplaying_p;
715
716 static Lisp_Object Qinhibit_free_realized_faces;
717
718 /* If a string, XTread_socket generates an event to display that string.
719 (The display is done in read_char.) */
720
721 Lisp_Object help_echo_string;
722 Lisp_Object help_echo_window;
723 Lisp_Object help_echo_object;
724 EMACS_INT help_echo_pos;
725
726 /* Temporary variable for XTread_socket. */
727
728 Lisp_Object previous_help_echo_string;
729
730 /* Platform-independent portion of hourglass implementation. */
731
732 /* Non-zero means an hourglass cursor is currently shown. */
733 int hourglass_shown_p;
734
735 /* If non-null, an asynchronous timer that, when it expires, displays
736 an hourglass cursor on all frames. */
737 struct atimer *hourglass_atimer;
738
739 /* Name of the face used to display glyphless characters. */
740 Lisp_Object Qglyphless_char;
741
742 /* Symbol for the purpose of Vglyphless_char_display. */
743 static Lisp_Object Qglyphless_char_display;
744
745 /* Method symbols for Vglyphless_char_display. */
746 static Lisp_Object Qhex_code, Qempty_box, Qthin_space, Qzero_width;
747
748 /* Default pixel width of `thin-space' display method. */
749 #define THIN_SPACE_WIDTH 1
750
751 /* Default number of seconds to wait before displaying an hourglass
752 cursor. */
753 #define DEFAULT_HOURGLASS_DELAY 1
754
755 \f
756 /* Function prototypes. */
757
758 static void setup_for_ellipsis (struct it *, int);
759 static void set_iterator_to_next (struct it *, int);
760 static void mark_window_display_accurate_1 (struct window *, int);
761 static int single_display_spec_string_p (Lisp_Object, Lisp_Object);
762 static int display_prop_string_p (Lisp_Object, Lisp_Object);
763 static int cursor_row_p (struct glyph_row *);
764 static int redisplay_mode_lines (Lisp_Object, int);
765 static char *decode_mode_spec_coding (Lisp_Object, char *, int);
766
767 static Lisp_Object get_it_property (struct it *it, Lisp_Object prop);
768
769 static void handle_line_prefix (struct it *);
770
771 static void pint2str (char *, int, EMACS_INT);
772 static void pint2hrstr (char *, int, EMACS_INT);
773 static struct text_pos run_window_scroll_functions (Lisp_Object,
774 struct text_pos);
775 static void reconsider_clip_changes (struct window *, struct buffer *);
776 static int text_outside_line_unchanged_p (struct window *,
777 EMACS_INT, EMACS_INT);
778 static void store_mode_line_noprop_char (char);
779 static int store_mode_line_noprop (const char *, int, int);
780 static void handle_stop (struct it *);
781 static void handle_stop_backwards (struct it *, EMACS_INT);
782 static int single_display_spec_intangible_p (Lisp_Object);
783 static void vmessage (const char *, va_list) ATTRIBUTE_FORMAT_PRINTF (1, 0);
784 static void ensure_echo_area_buffers (void);
785 static Lisp_Object unwind_with_echo_area_buffer (Lisp_Object);
786 static Lisp_Object with_echo_area_buffer_unwind_data (struct window *);
787 static int with_echo_area_buffer (struct window *, int,
788 int (*) (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT),
789 EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT);
790 static void clear_garbaged_frames (void);
791 static int current_message_1 (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT);
792 static void pop_message (void);
793 static int truncate_message_1 (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT);
794 static void set_message (const char *, Lisp_Object, EMACS_INT, int);
795 static int set_message_1 (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT);
796 static int display_echo_area (struct window *);
797 static int display_echo_area_1 (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT);
798 static int resize_mini_window_1 (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT);
799 static Lisp_Object unwind_redisplay (Lisp_Object);
800 static int string_char_and_length (const unsigned char *, int *);
801 static struct text_pos display_prop_end (struct it *, Lisp_Object,
802 struct text_pos);
803 static int compute_window_start_on_continuation_line (struct window *);
804 static Lisp_Object safe_eval_handler (Lisp_Object);
805 static void insert_left_trunc_glyphs (struct it *);
806 static struct glyph_row *get_overlay_arrow_glyph_row (struct window *,
807 Lisp_Object);
808 static void extend_face_to_end_of_line (struct it *);
809 static int append_space_for_newline (struct it *, int);
810 static int cursor_row_fully_visible_p (struct window *, int, int);
811 static int try_scrolling (Lisp_Object, int, EMACS_INT, EMACS_INT, int, int);
812 static int try_cursor_movement (Lisp_Object, struct text_pos, int *);
813 static int trailing_whitespace_p (EMACS_INT);
814 static unsigned long int message_log_check_duplicate (EMACS_INT, EMACS_INT);
815 static void push_it (struct it *, struct text_pos *);
816 static void pop_it (struct it *);
817 static void sync_frame_with_window_matrix_rows (struct window *);
818 static void select_frame_for_redisplay (Lisp_Object);
819 static void redisplay_internal (void);
820 static int echo_area_display (int);
821 static void redisplay_windows (Lisp_Object);
822 static void redisplay_window (Lisp_Object, int);
823 static Lisp_Object redisplay_window_error (Lisp_Object);
824 static Lisp_Object redisplay_window_0 (Lisp_Object);
825 static Lisp_Object redisplay_window_1 (Lisp_Object);
826 static int set_cursor_from_row (struct window *, struct glyph_row *,
827 struct glyph_matrix *, EMACS_INT, EMACS_INT,
828 int, int);
829 static int update_menu_bar (struct frame *, int, int);
830 static int try_window_reusing_current_matrix (struct window *);
831 static int try_window_id (struct window *);
832 static int display_line (struct it *);
833 static int display_mode_lines (struct window *);
834 static int display_mode_line (struct window *, enum face_id, Lisp_Object);
835 static int display_mode_element (struct it *, int, int, int, Lisp_Object, Lisp_Object, int);
836 static int store_mode_line_string (const char *, Lisp_Object, int, int, int, Lisp_Object);
837 static const char *decode_mode_spec (struct window *, int, int, Lisp_Object *);
838 static void display_menu_bar (struct window *);
839 static EMACS_INT display_count_lines (EMACS_INT, EMACS_INT, EMACS_INT,
840 EMACS_INT *);
841 static int display_string (const char *, Lisp_Object, Lisp_Object,
842 EMACS_INT, EMACS_INT, struct it *, int, int, int, int);
843 static void compute_line_metrics (struct it *);
844 static void run_redisplay_end_trigger_hook (struct it *);
845 static int get_overlay_strings (struct it *, EMACS_INT);
846 static int get_overlay_strings_1 (struct it *, EMACS_INT, int);
847 static void next_overlay_string (struct it *);
848 static void reseat (struct it *, struct text_pos, int);
849 static void reseat_1 (struct it *, struct text_pos, int);
850 static void back_to_previous_visible_line_start (struct it *);
851 void reseat_at_previous_visible_line_start (struct it *);
852 static void reseat_at_next_visible_line_start (struct it *, int);
853 static int next_element_from_ellipsis (struct it *);
854 static int next_element_from_display_vector (struct it *);
855 static int next_element_from_string (struct it *);
856 static int next_element_from_c_string (struct it *);
857 static int next_element_from_buffer (struct it *);
858 static int next_element_from_composition (struct it *);
859 static int next_element_from_image (struct it *);
860 static int next_element_from_stretch (struct it *);
861 static void load_overlay_strings (struct it *, EMACS_INT);
862 static int init_from_display_pos (struct it *, struct window *,
863 struct display_pos *);
864 static void reseat_to_string (struct it *, const char *,
865 Lisp_Object, EMACS_INT, EMACS_INT, int, int);
866 static int get_next_display_element (struct it *);
867 static enum move_it_result
868 move_it_in_display_line_to (struct it *, EMACS_INT, int,
869 enum move_operation_enum);
870 void move_it_vertically_backward (struct it *, int);
871 static void init_to_row_start (struct it *, struct window *,
872 struct glyph_row *);
873 static int init_to_row_end (struct it *, struct window *,
874 struct glyph_row *);
875 static void back_to_previous_line_start (struct it *);
876 static int forward_to_next_line_start (struct it *, int *);
877 static struct text_pos string_pos_nchars_ahead (struct text_pos,
878 Lisp_Object, EMACS_INT);
879 static struct text_pos string_pos (EMACS_INT, Lisp_Object);
880 static struct text_pos c_string_pos (EMACS_INT, const char *, int);
881 static EMACS_INT number_of_chars (const char *, int);
882 static void compute_stop_pos (struct it *);
883 static void compute_string_pos (struct text_pos *, struct text_pos,
884 Lisp_Object);
885 static int face_before_or_after_it_pos (struct it *, int);
886 static EMACS_INT next_overlay_change (EMACS_INT);
887 static int handle_display_spec (struct it *, Lisp_Object, Lisp_Object,
888 Lisp_Object, struct text_pos *, EMACS_INT, int);
889 static int handle_single_display_spec (struct it *, Lisp_Object,
890 Lisp_Object, Lisp_Object,
891 struct text_pos *, EMACS_INT, int, int);
892 static int underlying_face_id (struct it *);
893 static int in_ellipses_for_invisible_text_p (struct display_pos *,
894 struct window *);
895
896 #define face_before_it_pos(IT) face_before_or_after_it_pos ((IT), 1)
897 #define face_after_it_pos(IT) face_before_or_after_it_pos ((IT), 0)
898
899 #ifdef HAVE_WINDOW_SYSTEM
900
901 static void x_consider_frame_title (Lisp_Object);
902 static int tool_bar_lines_needed (struct frame *, int *);
903 static void update_tool_bar (struct frame *, int);
904 static void build_desired_tool_bar_string (struct frame *f);
905 static int redisplay_tool_bar (struct frame *);
906 static void display_tool_bar_line (struct it *, int);
907 static void notice_overwritten_cursor (struct window *,
908 enum glyph_row_area,
909 int, int, int, int);
910 static void append_stretch_glyph (struct it *, Lisp_Object,
911 int, int, int);
912
913
914 #endif /* HAVE_WINDOW_SYSTEM */
915
916 static void show_mouse_face (Mouse_HLInfo *, enum draw_glyphs_face);
917 static int coords_in_mouse_face_p (struct window *, int, int);
918
919
920 \f
921 /***********************************************************************
922 Window display dimensions
923 ***********************************************************************/
924
925 /* Return the bottom boundary y-position for text lines in window W.
926 This is the first y position at which a line cannot start.
927 It is relative to the top of the window.
928
929 This is the height of W minus the height of a mode line, if any. */
930
931 INLINE int
932 window_text_bottom_y (struct window *w)
933 {
934 int height = WINDOW_TOTAL_HEIGHT (w);
935
936 if (WINDOW_WANTS_MODELINE_P (w))
937 height -= CURRENT_MODE_LINE_HEIGHT (w);
938 return height;
939 }
940
941 /* Return the pixel width of display area AREA of window W. AREA < 0
942 means return the total width of W, not including fringes to
943 the left and right of the window. */
944
945 INLINE int
946 window_box_width (struct window *w, int area)
947 {
948 int cols = XFASTINT (w->total_cols);
949 int pixels = 0;
950
951 if (!w->pseudo_window_p)
952 {
953 cols -= WINDOW_SCROLL_BAR_COLS (w);
954
955 if (area == TEXT_AREA)
956 {
957 if (INTEGERP (w->left_margin_cols))
958 cols -= XFASTINT (w->left_margin_cols);
959 if (INTEGERP (w->right_margin_cols))
960 cols -= XFASTINT (w->right_margin_cols);
961 pixels = -WINDOW_TOTAL_FRINGE_WIDTH (w);
962 }
963 else if (area == LEFT_MARGIN_AREA)
964 {
965 cols = (INTEGERP (w->left_margin_cols)
966 ? XFASTINT (w->left_margin_cols) : 0);
967 pixels = 0;
968 }
969 else if (area == RIGHT_MARGIN_AREA)
970 {
971 cols = (INTEGERP (w->right_margin_cols)
972 ? XFASTINT (w->right_margin_cols) : 0);
973 pixels = 0;
974 }
975 }
976
977 return cols * WINDOW_FRAME_COLUMN_WIDTH (w) + pixels;
978 }
979
980
981 /* Return the pixel height of the display area of window W, not
982 including mode lines of W, if any. */
983
984 INLINE int
985 window_box_height (struct window *w)
986 {
987 struct frame *f = XFRAME (w->frame);
988 int height = WINDOW_TOTAL_HEIGHT (w);
989
990 xassert (height >= 0);
991
992 /* Note: the code below that determines the mode-line/header-line
993 height is essentially the same as that contained in the macro
994 CURRENT_{MODE,HEADER}_LINE_HEIGHT, except that it checks whether
995 the appropriate glyph row has its `mode_line_p' flag set,
996 and if it doesn't, uses estimate_mode_line_height instead. */
997
998 if (WINDOW_WANTS_MODELINE_P (w))
999 {
1000 struct glyph_row *ml_row
1001 = (w->current_matrix && w->current_matrix->rows
1002 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
1003 : 0);
1004 if (ml_row && ml_row->mode_line_p)
1005 height -= ml_row->height;
1006 else
1007 height -= estimate_mode_line_height (f, CURRENT_MODE_LINE_FACE_ID (w));
1008 }
1009
1010 if (WINDOW_WANTS_HEADER_LINE_P (w))
1011 {
1012 struct glyph_row *hl_row
1013 = (w->current_matrix && w->current_matrix->rows
1014 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
1015 : 0);
1016 if (hl_row && hl_row->mode_line_p)
1017 height -= hl_row->height;
1018 else
1019 height -= estimate_mode_line_height (f, HEADER_LINE_FACE_ID);
1020 }
1021
1022 /* With a very small font and a mode-line that's taller than
1023 default, we might end up with a negative height. */
1024 return max (0, height);
1025 }
1026
1027 /* Return the window-relative coordinate of the left edge of display
1028 area AREA of window W. AREA < 0 means return the left edge of the
1029 whole window, to the right of the left fringe of W. */
1030
1031 INLINE int
1032 window_box_left_offset (struct window *w, int area)
1033 {
1034 int x;
1035
1036 if (w->pseudo_window_p)
1037 return 0;
1038
1039 x = WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
1040
1041 if (area == TEXT_AREA)
1042 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1043 + window_box_width (w, LEFT_MARGIN_AREA));
1044 else if (area == RIGHT_MARGIN_AREA)
1045 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1046 + window_box_width (w, LEFT_MARGIN_AREA)
1047 + window_box_width (w, TEXT_AREA)
1048 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
1049 ? 0
1050 : WINDOW_RIGHT_FRINGE_WIDTH (w)));
1051 else if (area == LEFT_MARGIN_AREA
1052 && WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w))
1053 x += WINDOW_LEFT_FRINGE_WIDTH (w);
1054
1055 return x;
1056 }
1057
1058
1059 /* Return the window-relative coordinate of the right edge of display
1060 area AREA of window W. AREA < 0 means return the right edge of the
1061 whole window, to the left of the right fringe of W. */
1062
1063 INLINE int
1064 window_box_right_offset (struct window *w, int area)
1065 {
1066 return window_box_left_offset (w, area) + window_box_width (w, area);
1067 }
1068
1069 /* Return the frame-relative coordinate of the left edge of display
1070 area AREA of window W. AREA < 0 means return the left edge of the
1071 whole window, to the right of the left fringe of W. */
1072
1073 INLINE int
1074 window_box_left (struct window *w, int area)
1075 {
1076 struct frame *f = XFRAME (w->frame);
1077 int x;
1078
1079 if (w->pseudo_window_p)
1080 return FRAME_INTERNAL_BORDER_WIDTH (f);
1081
1082 x = (WINDOW_LEFT_EDGE_X (w)
1083 + window_box_left_offset (w, area));
1084
1085 return x;
1086 }
1087
1088
1089 /* Return the frame-relative coordinate of the right edge of display
1090 area AREA of window W. AREA < 0 means return the right edge of the
1091 whole window, to the left of the right fringe of W. */
1092
1093 INLINE int
1094 window_box_right (struct window *w, int area)
1095 {
1096 return window_box_left (w, area) + window_box_width (w, area);
1097 }
1098
1099 /* Get the bounding box of the display area AREA of window W, without
1100 mode lines, in frame-relative coordinates. AREA < 0 means the
1101 whole window, not including the left and right fringes of
1102 the window. Return in *BOX_X and *BOX_Y the frame-relative pixel
1103 coordinates of the upper-left corner of the box. Return in
1104 *BOX_WIDTH, and *BOX_HEIGHT the pixel width and height of the box. */
1105
1106 INLINE void
1107 window_box (struct window *w, int area, int *box_x, int *box_y,
1108 int *box_width, int *box_height)
1109 {
1110 if (box_width)
1111 *box_width = window_box_width (w, area);
1112 if (box_height)
1113 *box_height = window_box_height (w);
1114 if (box_x)
1115 *box_x = window_box_left (w, area);
1116 if (box_y)
1117 {
1118 *box_y = WINDOW_TOP_EDGE_Y (w);
1119 if (WINDOW_WANTS_HEADER_LINE_P (w))
1120 *box_y += CURRENT_HEADER_LINE_HEIGHT (w);
1121 }
1122 }
1123
1124
1125 /* Get the bounding box of the display area AREA of window W, without
1126 mode lines. AREA < 0 means the whole window, not including the
1127 left and right fringe of the window. Return in *TOP_LEFT_X
1128 and TOP_LEFT_Y the frame-relative pixel coordinates of the
1129 upper-left corner of the box. Return in *BOTTOM_RIGHT_X, and
1130 *BOTTOM_RIGHT_Y the coordinates of the bottom-right corner of the
1131 box. */
1132
1133 static INLINE void
1134 window_box_edges (struct window *w, int area, int *top_left_x, int *top_left_y,
1135 int *bottom_right_x, int *bottom_right_y)
1136 {
1137 window_box (w, area, top_left_x, top_left_y, bottom_right_x,
1138 bottom_right_y);
1139 *bottom_right_x += *top_left_x;
1140 *bottom_right_y += *top_left_y;
1141 }
1142
1143
1144 \f
1145 /***********************************************************************
1146 Utilities
1147 ***********************************************************************/
1148
1149 /* Return the bottom y-position of the line the iterator IT is in.
1150 This can modify IT's settings. */
1151
1152 int
1153 line_bottom_y (struct it *it)
1154 {
1155 int line_height = it->max_ascent + it->max_descent;
1156 int line_top_y = it->current_y;
1157
1158 if (line_height == 0)
1159 {
1160 if (last_height)
1161 line_height = last_height;
1162 else if (IT_CHARPOS (*it) < ZV)
1163 {
1164 move_it_by_lines (it, 1);
1165 line_height = (it->max_ascent || it->max_descent
1166 ? it->max_ascent + it->max_descent
1167 : last_height);
1168 }
1169 else
1170 {
1171 struct glyph_row *row = it->glyph_row;
1172
1173 /* Use the default character height. */
1174 it->glyph_row = NULL;
1175 it->what = IT_CHARACTER;
1176 it->c = ' ';
1177 it->len = 1;
1178 PRODUCE_GLYPHS (it);
1179 line_height = it->ascent + it->descent;
1180 it->glyph_row = row;
1181 }
1182 }
1183
1184 return line_top_y + line_height;
1185 }
1186
1187
1188 /* Return 1 if position CHARPOS is visible in window W.
1189 CHARPOS < 0 means return info about WINDOW_END position.
1190 If visible, set *X and *Y to pixel coordinates of top left corner.
1191 Set *RTOP and *RBOT to pixel height of an invisible area of glyph at POS.
1192 Set *ROWH and *VPOS to row's visible height and VPOS (row number). */
1193
1194 int
1195 pos_visible_p (struct window *w, EMACS_INT charpos, int *x, int *y,
1196 int *rtop, int *rbot, int *rowh, int *vpos)
1197 {
1198 struct it it;
1199 struct text_pos top;
1200 int visible_p = 0;
1201 struct buffer *old_buffer = NULL;
1202
1203 if (FRAME_INITIAL_P (XFRAME (WINDOW_FRAME (w))))
1204 return visible_p;
1205
1206 if (XBUFFER (w->buffer) != current_buffer)
1207 {
1208 old_buffer = current_buffer;
1209 set_buffer_internal_1 (XBUFFER (w->buffer));
1210 }
1211
1212 SET_TEXT_POS_FROM_MARKER (top, w->start);
1213
1214 /* Compute exact mode line heights. */
1215 if (WINDOW_WANTS_MODELINE_P (w))
1216 current_mode_line_height
1217 = display_mode_line (w, CURRENT_MODE_LINE_FACE_ID (w),
1218 BVAR (current_buffer, mode_line_format));
1219
1220 if (WINDOW_WANTS_HEADER_LINE_P (w))
1221 current_header_line_height
1222 = display_mode_line (w, HEADER_LINE_FACE_ID,
1223 BVAR (current_buffer, header_line_format));
1224
1225 start_display (&it, w, top);
1226 move_it_to (&it, charpos, -1, it.last_visible_y-1, -1,
1227 (charpos >= 0 ? MOVE_TO_POS : 0) | MOVE_TO_Y);
1228
1229 if (charpos >= 0 && IT_CHARPOS (it) >= charpos)
1230 {
1231 /* We have reached CHARPOS, or passed it. How the call to
1232 move_it_to can overshoot: (i) If CHARPOS is on invisible
1233 text, move_it_to stops at the end of the invisible text,
1234 after CHARPOS. (ii) If CHARPOS is in a display vector,
1235 move_it_to stops on its last glyph. */
1236 int top_x = it.current_x;
1237 int top_y = it.current_y;
1238 enum it_method it_method = it.method;
1239 /* Calling line_bottom_y may change it.method, it.position, etc. */
1240 int bottom_y = (last_height = 0, line_bottom_y (&it));
1241 int window_top_y = WINDOW_HEADER_LINE_HEIGHT (w);
1242
1243 if (top_y < window_top_y)
1244 visible_p = bottom_y > window_top_y;
1245 else if (top_y < it.last_visible_y)
1246 visible_p = 1;
1247 if (visible_p)
1248 {
1249 if (it_method == GET_FROM_DISPLAY_VECTOR)
1250 {
1251 /* We stopped on the last glyph of a display vector.
1252 Try and recompute. Hack alert! */
1253 if (charpos < 2 || top.charpos >= charpos)
1254 top_x = it.glyph_row->x;
1255 else
1256 {
1257 struct it it2;
1258 start_display (&it2, w, top);
1259 move_it_to (&it2, charpos - 1, -1, -1, -1, MOVE_TO_POS);
1260 get_next_display_element (&it2);
1261 PRODUCE_GLYPHS (&it2);
1262 if (ITERATOR_AT_END_OF_LINE_P (&it2)
1263 || it2.current_x > it2.last_visible_x)
1264 top_x = it.glyph_row->x;
1265 else
1266 {
1267 top_x = it2.current_x;
1268 top_y = it2.current_y;
1269 }
1270 }
1271 }
1272
1273 *x = top_x;
1274 *y = max (top_y + max (0, it.max_ascent - it.ascent), window_top_y);
1275 *rtop = max (0, window_top_y - top_y);
1276 *rbot = max (0, bottom_y - it.last_visible_y);
1277 *rowh = max (0, (min (bottom_y, it.last_visible_y)
1278 - max (top_y, window_top_y)));
1279 *vpos = it.vpos;
1280 }
1281 }
1282 else
1283 {
1284 struct it it2;
1285
1286 it2 = it;
1287 if (IT_CHARPOS (it) < ZV && FETCH_BYTE (IT_BYTEPOS (it)) != '\n')
1288 move_it_by_lines (&it, 1);
1289 if (charpos < IT_CHARPOS (it)
1290 || (it.what == IT_EOB && charpos == IT_CHARPOS (it)))
1291 {
1292 visible_p = 1;
1293 move_it_to (&it2, charpos, -1, -1, -1, MOVE_TO_POS);
1294 *x = it2.current_x;
1295 *y = it2.current_y + it2.max_ascent - it2.ascent;
1296 *rtop = max (0, -it2.current_y);
1297 *rbot = max (0, ((it2.current_y + it2.max_ascent + it2.max_descent)
1298 - it.last_visible_y));
1299 *rowh = max (0, (min (it2.current_y + it2.max_ascent + it2.max_descent,
1300 it.last_visible_y)
1301 - max (it2.current_y,
1302 WINDOW_HEADER_LINE_HEIGHT (w))));
1303 *vpos = it2.vpos;
1304 }
1305 }
1306
1307 if (old_buffer)
1308 set_buffer_internal_1 (old_buffer);
1309
1310 current_header_line_height = current_mode_line_height = -1;
1311
1312 if (visible_p && XFASTINT (w->hscroll) > 0)
1313 *x -= XFASTINT (w->hscroll) * WINDOW_FRAME_COLUMN_WIDTH (w);
1314
1315 #if 0
1316 /* Debugging code. */
1317 if (visible_p)
1318 fprintf (stderr, "+pv pt=%d vs=%d --> x=%d y=%d rt=%d rb=%d rh=%d vp=%d\n",
1319 charpos, w->vscroll, *x, *y, *rtop, *rbot, *rowh, *vpos);
1320 else
1321 fprintf (stderr, "-pv pt=%d vs=%d\n", charpos, w->vscroll);
1322 #endif
1323
1324 return visible_p;
1325 }
1326
1327
1328 /* Return the next character from STR. Return in *LEN the length of
1329 the character. This is like STRING_CHAR_AND_LENGTH but never
1330 returns an invalid character. If we find one, we return a `?', but
1331 with the length of the invalid character. */
1332
1333 static INLINE int
1334 string_char_and_length (const unsigned char *str, int *len)
1335 {
1336 int c;
1337
1338 c = STRING_CHAR_AND_LENGTH (str, *len);
1339 if (!CHAR_VALID_P (c, 1))
1340 /* We may not change the length here because other places in Emacs
1341 don't use this function, i.e. they silently accept invalid
1342 characters. */
1343 c = '?';
1344
1345 return c;
1346 }
1347
1348
1349
1350 /* Given a position POS containing a valid character and byte position
1351 in STRING, return the position NCHARS ahead (NCHARS >= 0). */
1352
1353 static struct text_pos
1354 string_pos_nchars_ahead (struct text_pos pos, Lisp_Object string, EMACS_INT nchars)
1355 {
1356 xassert (STRINGP (string) && nchars >= 0);
1357
1358 if (STRING_MULTIBYTE (string))
1359 {
1360 const unsigned char *p = SDATA (string) + BYTEPOS (pos);
1361 int len;
1362
1363 while (nchars--)
1364 {
1365 string_char_and_length (p, &len);
1366 p += len;
1367 CHARPOS (pos) += 1;
1368 BYTEPOS (pos) += len;
1369 }
1370 }
1371 else
1372 SET_TEXT_POS (pos, CHARPOS (pos) + nchars, BYTEPOS (pos) + nchars);
1373
1374 return pos;
1375 }
1376
1377
1378 /* Value is the text position, i.e. character and byte position,
1379 for character position CHARPOS in STRING. */
1380
1381 static INLINE struct text_pos
1382 string_pos (EMACS_INT charpos, Lisp_Object string)
1383 {
1384 struct text_pos pos;
1385 xassert (STRINGP (string));
1386 xassert (charpos >= 0);
1387 SET_TEXT_POS (pos, charpos, string_char_to_byte (string, charpos));
1388 return pos;
1389 }
1390
1391
1392 /* Value is a text position, i.e. character and byte position, for
1393 character position CHARPOS in C string S. MULTIBYTE_P non-zero
1394 means recognize multibyte characters. */
1395
1396 static struct text_pos
1397 c_string_pos (EMACS_INT charpos, const char *s, int multibyte_p)
1398 {
1399 struct text_pos pos;
1400
1401 xassert (s != NULL);
1402 xassert (charpos >= 0);
1403
1404 if (multibyte_p)
1405 {
1406 int len;
1407
1408 SET_TEXT_POS (pos, 0, 0);
1409 while (charpos--)
1410 {
1411 string_char_and_length ((const unsigned char *) s, &len);
1412 s += len;
1413 CHARPOS (pos) += 1;
1414 BYTEPOS (pos) += len;
1415 }
1416 }
1417 else
1418 SET_TEXT_POS (pos, charpos, charpos);
1419
1420 return pos;
1421 }
1422
1423
1424 /* Value is the number of characters in C string S. MULTIBYTE_P
1425 non-zero means recognize multibyte characters. */
1426
1427 static EMACS_INT
1428 number_of_chars (const char *s, int multibyte_p)
1429 {
1430 EMACS_INT nchars;
1431
1432 if (multibyte_p)
1433 {
1434 EMACS_INT rest = strlen (s);
1435 int len;
1436 const unsigned char *p = (const unsigned char *) s;
1437
1438 for (nchars = 0; rest > 0; ++nchars)
1439 {
1440 string_char_and_length (p, &len);
1441 rest -= len, p += len;
1442 }
1443 }
1444 else
1445 nchars = strlen (s);
1446
1447 return nchars;
1448 }
1449
1450
1451 /* Compute byte position NEWPOS->bytepos corresponding to
1452 NEWPOS->charpos. POS is a known position in string STRING.
1453 NEWPOS->charpos must be >= POS.charpos. */
1454
1455 static void
1456 compute_string_pos (struct text_pos *newpos, struct text_pos pos, Lisp_Object string)
1457 {
1458 xassert (STRINGP (string));
1459 xassert (CHARPOS (*newpos) >= CHARPOS (pos));
1460
1461 if (STRING_MULTIBYTE (string))
1462 *newpos = string_pos_nchars_ahead (pos, string,
1463 CHARPOS (*newpos) - CHARPOS (pos));
1464 else
1465 BYTEPOS (*newpos) = CHARPOS (*newpos);
1466 }
1467
1468 /* EXPORT:
1469 Return an estimation of the pixel height of mode or header lines on
1470 frame F. FACE_ID specifies what line's height to estimate. */
1471
1472 int
1473 estimate_mode_line_height (struct frame *f, enum face_id face_id)
1474 {
1475 #ifdef HAVE_WINDOW_SYSTEM
1476 if (FRAME_WINDOW_P (f))
1477 {
1478 int height = FONT_HEIGHT (FRAME_FONT (f));
1479
1480 /* This function is called so early when Emacs starts that the face
1481 cache and mode line face are not yet initialized. */
1482 if (FRAME_FACE_CACHE (f))
1483 {
1484 struct face *face = FACE_FROM_ID (f, face_id);
1485 if (face)
1486 {
1487 if (face->font)
1488 height = FONT_HEIGHT (face->font);
1489 if (face->box_line_width > 0)
1490 height += 2 * face->box_line_width;
1491 }
1492 }
1493
1494 return height;
1495 }
1496 #endif
1497
1498 return 1;
1499 }
1500
1501 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
1502 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
1503 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
1504 not force the value into range. */
1505
1506 void
1507 pixel_to_glyph_coords (FRAME_PTR f, register int pix_x, register int pix_y,
1508 int *x, int *y, NativeRectangle *bounds, int noclip)
1509 {
1510
1511 #ifdef HAVE_WINDOW_SYSTEM
1512 if (FRAME_WINDOW_P (f))
1513 {
1514 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to round down
1515 even for negative values. */
1516 if (pix_x < 0)
1517 pix_x -= FRAME_COLUMN_WIDTH (f) - 1;
1518 if (pix_y < 0)
1519 pix_y -= FRAME_LINE_HEIGHT (f) - 1;
1520
1521 pix_x = FRAME_PIXEL_X_TO_COL (f, pix_x);
1522 pix_y = FRAME_PIXEL_Y_TO_LINE (f, pix_y);
1523
1524 if (bounds)
1525 STORE_NATIVE_RECT (*bounds,
1526 FRAME_COL_TO_PIXEL_X (f, pix_x),
1527 FRAME_LINE_TO_PIXEL_Y (f, pix_y),
1528 FRAME_COLUMN_WIDTH (f) - 1,
1529 FRAME_LINE_HEIGHT (f) - 1);
1530
1531 if (!noclip)
1532 {
1533 if (pix_x < 0)
1534 pix_x = 0;
1535 else if (pix_x > FRAME_TOTAL_COLS (f))
1536 pix_x = FRAME_TOTAL_COLS (f);
1537
1538 if (pix_y < 0)
1539 pix_y = 0;
1540 else if (pix_y > FRAME_LINES (f))
1541 pix_y = FRAME_LINES (f);
1542 }
1543 }
1544 #endif
1545
1546 *x = pix_x;
1547 *y = pix_y;
1548 }
1549
1550
1551 /* Find the glyph under window-relative coordinates X/Y in window W.
1552 Consider only glyphs from buffer text, i.e. no glyphs from overlay
1553 strings. Return in *HPOS and *VPOS the row and column number of
1554 the glyph found. Return in *AREA the glyph area containing X.
1555 Value is a pointer to the glyph found or null if X/Y is not on
1556 text, or we can't tell because W's current matrix is not up to
1557 date. */
1558
1559 static
1560 struct glyph *
1561 x_y_to_hpos_vpos (struct window *w, int x, int y, int *hpos, int *vpos,
1562 int *dx, int *dy, int *area)
1563 {
1564 struct glyph *glyph, *end;
1565 struct glyph_row *row = NULL;
1566 int x0, i;
1567
1568 /* Find row containing Y. Give up if some row is not enabled. */
1569 for (i = 0; i < w->current_matrix->nrows; ++i)
1570 {
1571 row = MATRIX_ROW (w->current_matrix, i);
1572 if (!row->enabled_p)
1573 return NULL;
1574 if (y >= row->y && y < MATRIX_ROW_BOTTOM_Y (row))
1575 break;
1576 }
1577
1578 *vpos = i;
1579 *hpos = 0;
1580
1581 /* Give up if Y is not in the window. */
1582 if (i == w->current_matrix->nrows)
1583 return NULL;
1584
1585 /* Get the glyph area containing X. */
1586 if (w->pseudo_window_p)
1587 {
1588 *area = TEXT_AREA;
1589 x0 = 0;
1590 }
1591 else
1592 {
1593 if (x < window_box_left_offset (w, TEXT_AREA))
1594 {
1595 *area = LEFT_MARGIN_AREA;
1596 x0 = window_box_left_offset (w, LEFT_MARGIN_AREA);
1597 }
1598 else if (x < window_box_right_offset (w, TEXT_AREA))
1599 {
1600 *area = TEXT_AREA;
1601 x0 = window_box_left_offset (w, TEXT_AREA) + min (row->x, 0);
1602 }
1603 else
1604 {
1605 *area = RIGHT_MARGIN_AREA;
1606 x0 = window_box_left_offset (w, RIGHT_MARGIN_AREA);
1607 }
1608 }
1609
1610 /* Find glyph containing X. */
1611 glyph = row->glyphs[*area];
1612 end = glyph + row->used[*area];
1613 x -= x0;
1614 while (glyph < end && x >= glyph->pixel_width)
1615 {
1616 x -= glyph->pixel_width;
1617 ++glyph;
1618 }
1619
1620 if (glyph == end)
1621 return NULL;
1622
1623 if (dx)
1624 {
1625 *dx = x;
1626 *dy = y - (row->y + row->ascent - glyph->ascent);
1627 }
1628
1629 *hpos = glyph - row->glyphs[*area];
1630 return glyph;
1631 }
1632
1633 /* Convert frame-relative x/y to coordinates relative to window W.
1634 Takes pseudo-windows into account. */
1635
1636 static void
1637 frame_to_window_pixel_xy (struct window *w, int *x, int *y)
1638 {
1639 if (w->pseudo_window_p)
1640 {
1641 /* A pseudo-window is always full-width, and starts at the
1642 left edge of the frame, plus a frame border. */
1643 struct frame *f = XFRAME (w->frame);
1644 *x -= FRAME_INTERNAL_BORDER_WIDTH (f);
1645 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1646 }
1647 else
1648 {
1649 *x -= WINDOW_LEFT_EDGE_X (w);
1650 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1651 }
1652 }
1653
1654 #ifdef HAVE_WINDOW_SYSTEM
1655
1656 /* EXPORT:
1657 Return in RECTS[] at most N clipping rectangles for glyph string S.
1658 Return the number of stored rectangles. */
1659
1660 int
1661 get_glyph_string_clip_rects (struct glyph_string *s, NativeRectangle *rects, int n)
1662 {
1663 XRectangle r;
1664
1665 if (n <= 0)
1666 return 0;
1667
1668 if (s->row->full_width_p)
1669 {
1670 /* Draw full-width. X coordinates are relative to S->w->left_col. */
1671 r.x = WINDOW_LEFT_EDGE_X (s->w);
1672 r.width = WINDOW_TOTAL_WIDTH (s->w);
1673
1674 /* Unless displaying a mode or menu bar line, which are always
1675 fully visible, clip to the visible part of the row. */
1676 if (s->w->pseudo_window_p)
1677 r.height = s->row->visible_height;
1678 else
1679 r.height = s->height;
1680 }
1681 else
1682 {
1683 /* This is a text line that may be partially visible. */
1684 r.x = window_box_left (s->w, s->area);
1685 r.width = window_box_width (s->w, s->area);
1686 r.height = s->row->visible_height;
1687 }
1688
1689 if (s->clip_head)
1690 if (r.x < s->clip_head->x)
1691 {
1692 if (r.width >= s->clip_head->x - r.x)
1693 r.width -= s->clip_head->x - r.x;
1694 else
1695 r.width = 0;
1696 r.x = s->clip_head->x;
1697 }
1698 if (s->clip_tail)
1699 if (r.x + r.width > s->clip_tail->x + s->clip_tail->background_width)
1700 {
1701 if (s->clip_tail->x + s->clip_tail->background_width >= r.x)
1702 r.width = s->clip_tail->x + s->clip_tail->background_width - r.x;
1703 else
1704 r.width = 0;
1705 }
1706
1707 /* If S draws overlapping rows, it's sufficient to use the top and
1708 bottom of the window for clipping because this glyph string
1709 intentionally draws over other lines. */
1710 if (s->for_overlaps)
1711 {
1712 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
1713 r.height = window_text_bottom_y (s->w) - r.y;
1714
1715 /* Alas, the above simple strategy does not work for the
1716 environments with anti-aliased text: if the same text is
1717 drawn onto the same place multiple times, it gets thicker.
1718 If the overlap we are processing is for the erased cursor, we
1719 take the intersection with the rectagle of the cursor. */
1720 if (s->for_overlaps & OVERLAPS_ERASED_CURSOR)
1721 {
1722 XRectangle rc, r_save = r;
1723
1724 rc.x = WINDOW_TEXT_TO_FRAME_PIXEL_X (s->w, s->w->phys_cursor.x);
1725 rc.y = s->w->phys_cursor.y;
1726 rc.width = s->w->phys_cursor_width;
1727 rc.height = s->w->phys_cursor_height;
1728
1729 x_intersect_rectangles (&r_save, &rc, &r);
1730 }
1731 }
1732 else
1733 {
1734 /* Don't use S->y for clipping because it doesn't take partially
1735 visible lines into account. For example, it can be negative for
1736 partially visible lines at the top of a window. */
1737 if (!s->row->full_width_p
1738 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s->w, s->row))
1739 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
1740 else
1741 r.y = max (0, s->row->y);
1742 }
1743
1744 r.y = WINDOW_TO_FRAME_PIXEL_Y (s->w, r.y);
1745
1746 /* If drawing the cursor, don't let glyph draw outside its
1747 advertised boundaries. Cleartype does this under some circumstances. */
1748 if (s->hl == DRAW_CURSOR)
1749 {
1750 struct glyph *glyph = s->first_glyph;
1751 int height, max_y;
1752
1753 if (s->x > r.x)
1754 {
1755 r.width -= s->x - r.x;
1756 r.x = s->x;
1757 }
1758 r.width = min (r.width, glyph->pixel_width);
1759
1760 /* If r.y is below window bottom, ensure that we still see a cursor. */
1761 height = min (glyph->ascent + glyph->descent,
1762 min (FRAME_LINE_HEIGHT (s->f), s->row->visible_height));
1763 max_y = window_text_bottom_y (s->w) - height;
1764 max_y = WINDOW_TO_FRAME_PIXEL_Y (s->w, max_y);
1765 if (s->ybase - glyph->ascent > max_y)
1766 {
1767 r.y = max_y;
1768 r.height = height;
1769 }
1770 else
1771 {
1772 /* Don't draw cursor glyph taller than our actual glyph. */
1773 height = max (FRAME_LINE_HEIGHT (s->f), glyph->ascent + glyph->descent);
1774 if (height < r.height)
1775 {
1776 max_y = r.y + r.height;
1777 r.y = min (max_y, max (r.y, s->ybase + glyph->descent - height));
1778 r.height = min (max_y - r.y, height);
1779 }
1780 }
1781 }
1782
1783 if (s->row->clip)
1784 {
1785 XRectangle r_save = r;
1786
1787 if (! x_intersect_rectangles (&r_save, s->row->clip, &r))
1788 r.width = 0;
1789 }
1790
1791 if ((s->for_overlaps & OVERLAPS_BOTH) == 0
1792 || ((s->for_overlaps & OVERLAPS_BOTH) == OVERLAPS_BOTH && n == 1))
1793 {
1794 #ifdef CONVERT_FROM_XRECT
1795 CONVERT_FROM_XRECT (r, *rects);
1796 #else
1797 *rects = r;
1798 #endif
1799 return 1;
1800 }
1801 else
1802 {
1803 /* If we are processing overlapping and allowed to return
1804 multiple clipping rectangles, we exclude the row of the glyph
1805 string from the clipping rectangle. This is to avoid drawing
1806 the same text on the environment with anti-aliasing. */
1807 #ifdef CONVERT_FROM_XRECT
1808 XRectangle rs[2];
1809 #else
1810 XRectangle *rs = rects;
1811 #endif
1812 int i = 0, row_y = WINDOW_TO_FRAME_PIXEL_Y (s->w, s->row->y);
1813
1814 if (s->for_overlaps & OVERLAPS_PRED)
1815 {
1816 rs[i] = r;
1817 if (r.y + r.height > row_y)
1818 {
1819 if (r.y < row_y)
1820 rs[i].height = row_y - r.y;
1821 else
1822 rs[i].height = 0;
1823 }
1824 i++;
1825 }
1826 if (s->for_overlaps & OVERLAPS_SUCC)
1827 {
1828 rs[i] = r;
1829 if (r.y < row_y + s->row->visible_height)
1830 {
1831 if (r.y + r.height > row_y + s->row->visible_height)
1832 {
1833 rs[i].y = row_y + s->row->visible_height;
1834 rs[i].height = r.y + r.height - rs[i].y;
1835 }
1836 else
1837 rs[i].height = 0;
1838 }
1839 i++;
1840 }
1841
1842 n = i;
1843 #ifdef CONVERT_FROM_XRECT
1844 for (i = 0; i < n; i++)
1845 CONVERT_FROM_XRECT (rs[i], rects[i]);
1846 #endif
1847 return n;
1848 }
1849 }
1850
1851 /* EXPORT:
1852 Return in *NR the clipping rectangle for glyph string S. */
1853
1854 void
1855 get_glyph_string_clip_rect (struct glyph_string *s, NativeRectangle *nr)
1856 {
1857 get_glyph_string_clip_rects (s, nr, 1);
1858 }
1859
1860
1861 /* EXPORT:
1862 Return the position and height of the phys cursor in window W.
1863 Set w->phys_cursor_width to width of phys cursor.
1864 */
1865
1866 void
1867 get_phys_cursor_geometry (struct window *w, struct glyph_row *row,
1868 struct glyph *glyph, int *xp, int *yp, int *heightp)
1869 {
1870 struct frame *f = XFRAME (WINDOW_FRAME (w));
1871 int x, y, wd, h, h0, y0;
1872
1873 /* Compute the width of the rectangle to draw. If on a stretch
1874 glyph, and `x-stretch-block-cursor' is nil, don't draw a
1875 rectangle as wide as the glyph, but use a canonical character
1876 width instead. */
1877 wd = glyph->pixel_width - 1;
1878 #if defined(HAVE_NTGUI) || defined(HAVE_NS)
1879 wd++; /* Why? */
1880 #endif
1881
1882 x = w->phys_cursor.x;
1883 if (x < 0)
1884 {
1885 wd += x;
1886 x = 0;
1887 }
1888
1889 if (glyph->type == STRETCH_GLYPH
1890 && !x_stretch_cursor_p)
1891 wd = min (FRAME_COLUMN_WIDTH (f), wd);
1892 w->phys_cursor_width = wd;
1893
1894 y = w->phys_cursor.y + row->ascent - glyph->ascent;
1895
1896 /* If y is below window bottom, ensure that we still see a cursor. */
1897 h0 = min (FRAME_LINE_HEIGHT (f), row->visible_height);
1898
1899 h = max (h0, glyph->ascent + glyph->descent);
1900 h0 = min (h0, glyph->ascent + glyph->descent);
1901
1902 y0 = WINDOW_HEADER_LINE_HEIGHT (w);
1903 if (y < y0)
1904 {
1905 h = max (h - (y0 - y) + 1, h0);
1906 y = y0 - 1;
1907 }
1908 else
1909 {
1910 y0 = window_text_bottom_y (w) - h0;
1911 if (y > y0)
1912 {
1913 h += y - y0;
1914 y = y0;
1915 }
1916 }
1917
1918 *xp = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, x);
1919 *yp = WINDOW_TO_FRAME_PIXEL_Y (w, y);
1920 *heightp = h;
1921 }
1922
1923 /*
1924 * Remember which glyph the mouse is over.
1925 */
1926
1927 void
1928 remember_mouse_glyph (struct frame *f, int gx, int gy, NativeRectangle *rect)
1929 {
1930 Lisp_Object window;
1931 struct window *w;
1932 struct glyph_row *r, *gr, *end_row;
1933 enum window_part part;
1934 enum glyph_row_area area;
1935 int x, y, width, height;
1936
1937 /* Try to determine frame pixel position and size of the glyph under
1938 frame pixel coordinates X/Y on frame F. */
1939
1940 if (!f->glyphs_initialized_p
1941 || (window = window_from_coordinates (f, gx, gy, &part, 0),
1942 NILP (window)))
1943 {
1944 width = FRAME_SMALLEST_CHAR_WIDTH (f);
1945 height = FRAME_SMALLEST_FONT_HEIGHT (f);
1946 goto virtual_glyph;
1947 }
1948
1949 w = XWINDOW (window);
1950 width = WINDOW_FRAME_COLUMN_WIDTH (w);
1951 height = WINDOW_FRAME_LINE_HEIGHT (w);
1952
1953 x = window_relative_x_coord (w, part, gx);
1954 y = gy - WINDOW_TOP_EDGE_Y (w);
1955
1956 r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
1957 end_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
1958
1959 if (w->pseudo_window_p)
1960 {
1961 area = TEXT_AREA;
1962 part = ON_MODE_LINE; /* Don't adjust margin. */
1963 goto text_glyph;
1964 }
1965
1966 switch (part)
1967 {
1968 case ON_LEFT_MARGIN:
1969 area = LEFT_MARGIN_AREA;
1970 goto text_glyph;
1971
1972 case ON_RIGHT_MARGIN:
1973 area = RIGHT_MARGIN_AREA;
1974 goto text_glyph;
1975
1976 case ON_HEADER_LINE:
1977 case ON_MODE_LINE:
1978 gr = (part == ON_HEADER_LINE
1979 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
1980 : MATRIX_MODE_LINE_ROW (w->current_matrix));
1981 gy = gr->y;
1982 area = TEXT_AREA;
1983 goto text_glyph_row_found;
1984
1985 case ON_TEXT:
1986 area = TEXT_AREA;
1987
1988 text_glyph:
1989 gr = 0; gy = 0;
1990 for (; r <= end_row && r->enabled_p; ++r)
1991 if (r->y + r->height > y)
1992 {
1993 gr = r; gy = r->y;
1994 break;
1995 }
1996
1997 text_glyph_row_found:
1998 if (gr && gy <= y)
1999 {
2000 struct glyph *g = gr->glyphs[area];
2001 struct glyph *end = g + gr->used[area];
2002
2003 height = gr->height;
2004 for (gx = gr->x; g < end; gx += g->pixel_width, ++g)
2005 if (gx + g->pixel_width > x)
2006 break;
2007
2008 if (g < end)
2009 {
2010 if (g->type == IMAGE_GLYPH)
2011 {
2012 /* Don't remember when mouse is over image, as
2013 image may have hot-spots. */
2014 STORE_NATIVE_RECT (*rect, 0, 0, 0, 0);
2015 return;
2016 }
2017 width = g->pixel_width;
2018 }
2019 else
2020 {
2021 /* Use nominal char spacing at end of line. */
2022 x -= gx;
2023 gx += (x / width) * width;
2024 }
2025
2026 if (part != ON_MODE_LINE && part != ON_HEADER_LINE)
2027 gx += window_box_left_offset (w, area);
2028 }
2029 else
2030 {
2031 /* Use nominal line height at end of window. */
2032 gx = (x / width) * width;
2033 y -= gy;
2034 gy += (y / height) * height;
2035 }
2036 break;
2037
2038 case ON_LEFT_FRINGE:
2039 gx = (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2040 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w)
2041 : window_box_right_offset (w, LEFT_MARGIN_AREA));
2042 width = WINDOW_LEFT_FRINGE_WIDTH (w);
2043 goto row_glyph;
2044
2045 case ON_RIGHT_FRINGE:
2046 gx = (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2047 ? window_box_right_offset (w, RIGHT_MARGIN_AREA)
2048 : window_box_right_offset (w, TEXT_AREA));
2049 width = WINDOW_RIGHT_FRINGE_WIDTH (w);
2050 goto row_glyph;
2051
2052 case ON_SCROLL_BAR:
2053 gx = (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w)
2054 ? 0
2055 : (window_box_right_offset (w, RIGHT_MARGIN_AREA)
2056 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2057 ? WINDOW_RIGHT_FRINGE_WIDTH (w)
2058 : 0)));
2059 width = WINDOW_SCROLL_BAR_AREA_WIDTH (w);
2060
2061 row_glyph:
2062 gr = 0, gy = 0;
2063 for (; r <= end_row && r->enabled_p; ++r)
2064 if (r->y + r->height > y)
2065 {
2066 gr = r; gy = r->y;
2067 break;
2068 }
2069
2070 if (gr && gy <= y)
2071 height = gr->height;
2072 else
2073 {
2074 /* Use nominal line height at end of window. */
2075 y -= gy;
2076 gy += (y / height) * height;
2077 }
2078 break;
2079
2080 default:
2081 ;
2082 virtual_glyph:
2083 /* If there is no glyph under the mouse, then we divide the screen
2084 into a grid of the smallest glyph in the frame, and use that
2085 as our "glyph". */
2086
2087 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to
2088 round down even for negative values. */
2089 if (gx < 0)
2090 gx -= width - 1;
2091 if (gy < 0)
2092 gy -= height - 1;
2093
2094 gx = (gx / width) * width;
2095 gy = (gy / height) * height;
2096
2097 goto store_rect;
2098 }
2099
2100 gx += WINDOW_LEFT_EDGE_X (w);
2101 gy += WINDOW_TOP_EDGE_Y (w);
2102
2103 store_rect:
2104 STORE_NATIVE_RECT (*rect, gx, gy, width, height);
2105
2106 /* Visible feedback for debugging. */
2107 #if 0
2108 #if HAVE_X_WINDOWS
2109 XDrawRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2110 f->output_data.x->normal_gc,
2111 gx, gy, width, height);
2112 #endif
2113 #endif
2114 }
2115
2116
2117 #endif /* HAVE_WINDOW_SYSTEM */
2118
2119 \f
2120 /***********************************************************************
2121 Lisp form evaluation
2122 ***********************************************************************/
2123
2124 /* Error handler for safe_eval and safe_call. */
2125
2126 static Lisp_Object
2127 safe_eval_handler (Lisp_Object arg)
2128 {
2129 add_to_log ("Error during redisplay: %S", arg, Qnil);
2130 return Qnil;
2131 }
2132
2133
2134 /* Evaluate SEXPR and return the result, or nil if something went
2135 wrong. Prevent redisplay during the evaluation. */
2136
2137 /* Call function ARGS[0] with arguments ARGS[1] to ARGS[NARGS - 1].
2138 Return the result, or nil if something went wrong. Prevent
2139 redisplay during the evaluation. */
2140
2141 Lisp_Object
2142 safe_call (size_t nargs, Lisp_Object *args)
2143 {
2144 Lisp_Object val;
2145
2146 if (inhibit_eval_during_redisplay)
2147 val = Qnil;
2148 else
2149 {
2150 int count = SPECPDL_INDEX ();
2151 struct gcpro gcpro1;
2152
2153 GCPRO1 (args[0]);
2154 gcpro1.nvars = nargs;
2155 specbind (Qinhibit_redisplay, Qt);
2156 /* Use Qt to ensure debugger does not run,
2157 so there is no possibility of wanting to redisplay. */
2158 val = internal_condition_case_n (Ffuncall, nargs, args, Qt,
2159 safe_eval_handler);
2160 UNGCPRO;
2161 val = unbind_to (count, val);
2162 }
2163
2164 return val;
2165 }
2166
2167
2168 /* Call function FN with one argument ARG.
2169 Return the result, or nil if something went wrong. */
2170
2171 Lisp_Object
2172 safe_call1 (Lisp_Object fn, Lisp_Object arg)
2173 {
2174 Lisp_Object args[2];
2175 args[0] = fn;
2176 args[1] = arg;
2177 return safe_call (2, args);
2178 }
2179
2180 static Lisp_Object Qeval;
2181
2182 Lisp_Object
2183 safe_eval (Lisp_Object sexpr)
2184 {
2185 return safe_call1 (Qeval, sexpr);
2186 }
2187
2188 /* Call function FN with one argument ARG.
2189 Return the result, or nil if something went wrong. */
2190
2191 Lisp_Object
2192 safe_call2 (Lisp_Object fn, Lisp_Object arg1, Lisp_Object arg2)
2193 {
2194 Lisp_Object args[3];
2195 args[0] = fn;
2196 args[1] = arg1;
2197 args[2] = arg2;
2198 return safe_call (3, args);
2199 }
2200
2201
2202 \f
2203 /***********************************************************************
2204 Debugging
2205 ***********************************************************************/
2206
2207 #if 0
2208
2209 /* Define CHECK_IT to perform sanity checks on iterators.
2210 This is for debugging. It is too slow to do unconditionally. */
2211
2212 static void
2213 check_it (it)
2214 struct it *it;
2215 {
2216 if (it->method == GET_FROM_STRING)
2217 {
2218 xassert (STRINGP (it->string));
2219 xassert (IT_STRING_CHARPOS (*it) >= 0);
2220 }
2221 else
2222 {
2223 xassert (IT_STRING_CHARPOS (*it) < 0);
2224 if (it->method == GET_FROM_BUFFER)
2225 {
2226 /* Check that character and byte positions agree. */
2227 xassert (IT_CHARPOS (*it) == BYTE_TO_CHAR (IT_BYTEPOS (*it)));
2228 }
2229 }
2230
2231 if (it->dpvec)
2232 xassert (it->current.dpvec_index >= 0);
2233 else
2234 xassert (it->current.dpvec_index < 0);
2235 }
2236
2237 #define CHECK_IT(IT) check_it ((IT))
2238
2239 #else /* not 0 */
2240
2241 #define CHECK_IT(IT) (void) 0
2242
2243 #endif /* not 0 */
2244
2245
2246 #if GLYPH_DEBUG
2247
2248 /* Check that the window end of window W is what we expect it
2249 to be---the last row in the current matrix displaying text. */
2250
2251 static void
2252 check_window_end (w)
2253 struct window *w;
2254 {
2255 if (!MINI_WINDOW_P (w)
2256 && !NILP (w->window_end_valid))
2257 {
2258 struct glyph_row *row;
2259 xassert ((row = MATRIX_ROW (w->current_matrix,
2260 XFASTINT (w->window_end_vpos)),
2261 !row->enabled_p
2262 || MATRIX_ROW_DISPLAYS_TEXT_P (row)
2263 || MATRIX_ROW_VPOS (row, w->current_matrix) == 0));
2264 }
2265 }
2266
2267 #define CHECK_WINDOW_END(W) check_window_end ((W))
2268
2269 #else /* not GLYPH_DEBUG */
2270
2271 #define CHECK_WINDOW_END(W) (void) 0
2272
2273 #endif /* not GLYPH_DEBUG */
2274
2275
2276 \f
2277 /***********************************************************************
2278 Iterator initialization
2279 ***********************************************************************/
2280
2281 /* Initialize IT for displaying current_buffer in window W, starting
2282 at character position CHARPOS. CHARPOS < 0 means that no buffer
2283 position is specified which is useful when the iterator is assigned
2284 a position later. BYTEPOS is the byte position corresponding to
2285 CHARPOS. BYTEPOS < 0 means compute it from CHARPOS.
2286
2287 If ROW is not null, calls to produce_glyphs with IT as parameter
2288 will produce glyphs in that row.
2289
2290 BASE_FACE_ID is the id of a base face to use. It must be one of
2291 DEFAULT_FACE_ID for normal text, MODE_LINE_FACE_ID,
2292 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID for displaying
2293 mode lines, or TOOL_BAR_FACE_ID for displaying the tool-bar.
2294
2295 If ROW is null and BASE_FACE_ID is equal to MODE_LINE_FACE_ID,
2296 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID, the iterator
2297 will be initialized to use the corresponding mode line glyph row of
2298 the desired matrix of W. */
2299
2300 void
2301 init_iterator (struct it *it, struct window *w,
2302 EMACS_INT charpos, EMACS_INT bytepos,
2303 struct glyph_row *row, enum face_id base_face_id)
2304 {
2305 int highlight_region_p;
2306 enum face_id remapped_base_face_id = base_face_id;
2307
2308 /* Some precondition checks. */
2309 xassert (w != NULL && it != NULL);
2310 xassert (charpos < 0 || (charpos >= BUF_BEG (current_buffer)
2311 && charpos <= ZV));
2312
2313 /* If face attributes have been changed since the last redisplay,
2314 free realized faces now because they depend on face definitions
2315 that might have changed. Don't free faces while there might be
2316 desired matrices pending which reference these faces. */
2317 if (face_change_count && !inhibit_free_realized_faces)
2318 {
2319 face_change_count = 0;
2320 free_all_realized_faces (Qnil);
2321 }
2322
2323 /* Perhaps remap BASE_FACE_ID to a user-specified alternative. */
2324 if (! NILP (Vface_remapping_alist))
2325 remapped_base_face_id = lookup_basic_face (XFRAME (w->frame), base_face_id);
2326
2327 /* Use one of the mode line rows of W's desired matrix if
2328 appropriate. */
2329 if (row == NULL)
2330 {
2331 if (base_face_id == MODE_LINE_FACE_ID
2332 || base_face_id == MODE_LINE_INACTIVE_FACE_ID)
2333 row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
2334 else if (base_face_id == HEADER_LINE_FACE_ID)
2335 row = MATRIX_HEADER_LINE_ROW (w->desired_matrix);
2336 }
2337
2338 /* Clear IT. */
2339 memset (it, 0, sizeof *it);
2340 it->current.overlay_string_index = -1;
2341 it->current.dpvec_index = -1;
2342 it->base_face_id = remapped_base_face_id;
2343 it->string = Qnil;
2344 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
2345
2346 /* The window in which we iterate over current_buffer: */
2347 XSETWINDOW (it->window, w);
2348 it->w = w;
2349 it->f = XFRAME (w->frame);
2350
2351 it->cmp_it.id = -1;
2352
2353 /* Extra space between lines (on window systems only). */
2354 if (base_face_id == DEFAULT_FACE_ID
2355 && FRAME_WINDOW_P (it->f))
2356 {
2357 if (NATNUMP (BVAR (current_buffer, extra_line_spacing)))
2358 it->extra_line_spacing = XFASTINT (BVAR (current_buffer, extra_line_spacing));
2359 else if (FLOATP (BVAR (current_buffer, extra_line_spacing)))
2360 it->extra_line_spacing = (XFLOAT_DATA (BVAR (current_buffer, extra_line_spacing))
2361 * FRAME_LINE_HEIGHT (it->f));
2362 else if (it->f->extra_line_spacing > 0)
2363 it->extra_line_spacing = it->f->extra_line_spacing;
2364 it->max_extra_line_spacing = 0;
2365 }
2366
2367 /* If realized faces have been removed, e.g. because of face
2368 attribute changes of named faces, recompute them. When running
2369 in batch mode, the face cache of the initial frame is null. If
2370 we happen to get called, make a dummy face cache. */
2371 if (FRAME_FACE_CACHE (it->f) == NULL)
2372 init_frame_faces (it->f);
2373 if (FRAME_FACE_CACHE (it->f)->used == 0)
2374 recompute_basic_faces (it->f);
2375
2376 /* Current value of the `slice', `space-width', and 'height' properties. */
2377 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
2378 it->space_width = Qnil;
2379 it->font_height = Qnil;
2380 it->override_ascent = -1;
2381
2382 /* Are control characters displayed as `^C'? */
2383 it->ctl_arrow_p = !NILP (BVAR (current_buffer, ctl_arrow));
2384
2385 /* -1 means everything between a CR and the following line end
2386 is invisible. >0 means lines indented more than this value are
2387 invisible. */
2388 it->selective = (INTEGERP (BVAR (current_buffer, selective_display))
2389 ? XFASTINT (BVAR (current_buffer, selective_display))
2390 : (!NILP (BVAR (current_buffer, selective_display))
2391 ? -1 : 0));
2392 it->selective_display_ellipsis_p
2393 = !NILP (BVAR (current_buffer, selective_display_ellipses));
2394
2395 /* Display table to use. */
2396 it->dp = window_display_table (w);
2397
2398 /* Are multibyte characters enabled in current_buffer? */
2399 it->multibyte_p = !NILP (BVAR (current_buffer, enable_multibyte_characters));
2400
2401 /* Do we need to reorder bidirectional text? Not if this is a
2402 unibyte buffer: by definition, none of the single-byte characters
2403 are strong R2L, so no reordering is needed. And bidi.c doesn't
2404 support unibyte buffers anyway. */
2405 it->bidi_p
2406 = !NILP (BVAR (current_buffer, bidi_display_reordering)) && it->multibyte_p;
2407
2408 /* Non-zero if we should highlight the region. */
2409 highlight_region_p
2410 = (!NILP (Vtransient_mark_mode)
2411 && !NILP (BVAR (current_buffer, mark_active))
2412 && XMARKER (BVAR (current_buffer, mark))->buffer != 0);
2413
2414 /* Set IT->region_beg_charpos and IT->region_end_charpos to the
2415 start and end of a visible region in window IT->w. Set both to
2416 -1 to indicate no region. */
2417 if (highlight_region_p
2418 /* Maybe highlight only in selected window. */
2419 && (/* Either show region everywhere. */
2420 highlight_nonselected_windows
2421 /* Or show region in the selected window. */
2422 || w == XWINDOW (selected_window)
2423 /* Or show the region if we are in the mini-buffer and W is
2424 the window the mini-buffer refers to. */
2425 || (MINI_WINDOW_P (XWINDOW (selected_window))
2426 && WINDOWP (minibuf_selected_window)
2427 && w == XWINDOW (minibuf_selected_window))))
2428 {
2429 EMACS_INT markpos = marker_position (BVAR (current_buffer, mark));
2430 it->region_beg_charpos = min (PT, markpos);
2431 it->region_end_charpos = max (PT, markpos);
2432 }
2433 else
2434 it->region_beg_charpos = it->region_end_charpos = -1;
2435
2436 /* Get the position at which the redisplay_end_trigger hook should
2437 be run, if it is to be run at all. */
2438 if (MARKERP (w->redisplay_end_trigger)
2439 && XMARKER (w->redisplay_end_trigger)->buffer != 0)
2440 it->redisplay_end_trigger_charpos
2441 = marker_position (w->redisplay_end_trigger);
2442 else if (INTEGERP (w->redisplay_end_trigger))
2443 it->redisplay_end_trigger_charpos = XINT (w->redisplay_end_trigger);
2444
2445 /* Correct bogus values of tab_width. */
2446 it->tab_width = XINT (BVAR (current_buffer, tab_width));
2447 if (it->tab_width <= 0 || it->tab_width > 1000)
2448 it->tab_width = 8;
2449
2450 /* Are lines in the display truncated? */
2451 if (base_face_id != DEFAULT_FACE_ID
2452 || XINT (it->w->hscroll)
2453 || (! WINDOW_FULL_WIDTH_P (it->w)
2454 && ((!NILP (Vtruncate_partial_width_windows)
2455 && !INTEGERP (Vtruncate_partial_width_windows))
2456 || (INTEGERP (Vtruncate_partial_width_windows)
2457 && (WINDOW_TOTAL_COLS (it->w)
2458 < XINT (Vtruncate_partial_width_windows))))))
2459 it->line_wrap = TRUNCATE;
2460 else if (NILP (BVAR (current_buffer, truncate_lines)))
2461 it->line_wrap = NILP (BVAR (current_buffer, word_wrap))
2462 ? WINDOW_WRAP : WORD_WRAP;
2463 else
2464 it->line_wrap = TRUNCATE;
2465
2466 /* Get dimensions of truncation and continuation glyphs. These are
2467 displayed as fringe bitmaps under X, so we don't need them for such
2468 frames. */
2469 if (!FRAME_WINDOW_P (it->f))
2470 {
2471 if (it->line_wrap == TRUNCATE)
2472 {
2473 /* We will need the truncation glyph. */
2474 xassert (it->glyph_row == NULL);
2475 produce_special_glyphs (it, IT_TRUNCATION);
2476 it->truncation_pixel_width = it->pixel_width;
2477 }
2478 else
2479 {
2480 /* We will need the continuation glyph. */
2481 xassert (it->glyph_row == NULL);
2482 produce_special_glyphs (it, IT_CONTINUATION);
2483 it->continuation_pixel_width = it->pixel_width;
2484 }
2485
2486 /* Reset these values to zero because the produce_special_glyphs
2487 above has changed them. */
2488 it->pixel_width = it->ascent = it->descent = 0;
2489 it->phys_ascent = it->phys_descent = 0;
2490 }
2491
2492 /* Set this after getting the dimensions of truncation and
2493 continuation glyphs, so that we don't produce glyphs when calling
2494 produce_special_glyphs, above. */
2495 it->glyph_row = row;
2496 it->area = TEXT_AREA;
2497
2498 /* Forget any previous info about this row being reversed. */
2499 if (it->glyph_row)
2500 it->glyph_row->reversed_p = 0;
2501
2502 /* Get the dimensions of the display area. The display area
2503 consists of the visible window area plus a horizontally scrolled
2504 part to the left of the window. All x-values are relative to the
2505 start of this total display area. */
2506 if (base_face_id != DEFAULT_FACE_ID)
2507 {
2508 /* Mode lines, menu bar in terminal frames. */
2509 it->first_visible_x = 0;
2510 it->last_visible_x = WINDOW_TOTAL_WIDTH (w);
2511 }
2512 else
2513 {
2514 it->first_visible_x
2515 = XFASTINT (it->w->hscroll) * FRAME_COLUMN_WIDTH (it->f);
2516 it->last_visible_x = (it->first_visible_x
2517 + window_box_width (w, TEXT_AREA));
2518
2519 /* If we truncate lines, leave room for the truncator glyph(s) at
2520 the right margin. Otherwise, leave room for the continuation
2521 glyph(s). Truncation and continuation glyphs are not inserted
2522 for window-based redisplay. */
2523 if (!FRAME_WINDOW_P (it->f))
2524 {
2525 if (it->line_wrap == TRUNCATE)
2526 it->last_visible_x -= it->truncation_pixel_width;
2527 else
2528 it->last_visible_x -= it->continuation_pixel_width;
2529 }
2530
2531 it->header_line_p = WINDOW_WANTS_HEADER_LINE_P (w);
2532 it->current_y = WINDOW_HEADER_LINE_HEIGHT (w) + w->vscroll;
2533 }
2534
2535 /* Leave room for a border glyph. */
2536 if (!FRAME_WINDOW_P (it->f)
2537 && !WINDOW_RIGHTMOST_P (it->w))
2538 it->last_visible_x -= 1;
2539
2540 it->last_visible_y = window_text_bottom_y (w);
2541
2542 /* For mode lines and alike, arrange for the first glyph having a
2543 left box line if the face specifies a box. */
2544 if (base_face_id != DEFAULT_FACE_ID)
2545 {
2546 struct face *face;
2547
2548 it->face_id = remapped_base_face_id;
2549
2550 /* If we have a boxed mode line, make the first character appear
2551 with a left box line. */
2552 face = FACE_FROM_ID (it->f, remapped_base_face_id);
2553 if (face->box != FACE_NO_BOX)
2554 it->start_of_box_run_p = 1;
2555 }
2556
2557 /* If we are to reorder bidirectional text, init the bidi
2558 iterator. */
2559 if (it->bidi_p)
2560 {
2561 /* Note the paragraph direction that this buffer wants to
2562 use. */
2563 if (EQ (BVAR (current_buffer, bidi_paragraph_direction), Qleft_to_right))
2564 it->paragraph_embedding = L2R;
2565 else if (EQ (BVAR (current_buffer, bidi_paragraph_direction), Qright_to_left))
2566 it->paragraph_embedding = R2L;
2567 else
2568 it->paragraph_embedding = NEUTRAL_DIR;
2569 bidi_init_it (charpos, bytepos, FRAME_WINDOW_P (it->f), &it->bidi_it);
2570 }
2571
2572 /* If a buffer position was specified, set the iterator there,
2573 getting overlays and face properties from that position. */
2574 if (charpos >= BUF_BEG (current_buffer))
2575 {
2576 it->end_charpos = ZV;
2577 it->face_id = -1;
2578 IT_CHARPOS (*it) = charpos;
2579
2580 /* Compute byte position if not specified. */
2581 if (bytepos < charpos)
2582 IT_BYTEPOS (*it) = CHAR_TO_BYTE (charpos);
2583 else
2584 IT_BYTEPOS (*it) = bytepos;
2585
2586 it->start = it->current;
2587
2588 /* Compute faces etc. */
2589 reseat (it, it->current.pos, 1);
2590 }
2591
2592 CHECK_IT (it);
2593 }
2594
2595
2596 /* Initialize IT for the display of window W with window start POS. */
2597
2598 void
2599 start_display (struct it *it, struct window *w, struct text_pos pos)
2600 {
2601 struct glyph_row *row;
2602 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
2603
2604 row = w->desired_matrix->rows + first_vpos;
2605 init_iterator (it, w, CHARPOS (pos), BYTEPOS (pos), row, DEFAULT_FACE_ID);
2606 it->first_vpos = first_vpos;
2607
2608 /* Don't reseat to previous visible line start if current start
2609 position is in a string or image. */
2610 if (it->method == GET_FROM_BUFFER && it->line_wrap != TRUNCATE)
2611 {
2612 int start_at_line_beg_p;
2613 int first_y = it->current_y;
2614
2615 /* If window start is not at a line start, skip forward to POS to
2616 get the correct continuation lines width. */
2617 start_at_line_beg_p = (CHARPOS (pos) == BEGV
2618 || FETCH_BYTE (BYTEPOS (pos) - 1) == '\n');
2619 if (!start_at_line_beg_p)
2620 {
2621 int new_x;
2622
2623 reseat_at_previous_visible_line_start (it);
2624 move_it_to (it, CHARPOS (pos), -1, -1, -1, MOVE_TO_POS);
2625
2626 new_x = it->current_x + it->pixel_width;
2627
2628 /* If lines are continued, this line may end in the middle
2629 of a multi-glyph character (e.g. a control character
2630 displayed as \003, or in the middle of an overlay
2631 string). In this case move_it_to above will not have
2632 taken us to the start of the continuation line but to the
2633 end of the continued line. */
2634 if (it->current_x > 0
2635 && it->line_wrap != TRUNCATE /* Lines are continued. */
2636 && (/* And glyph doesn't fit on the line. */
2637 new_x > it->last_visible_x
2638 /* Or it fits exactly and we're on a window
2639 system frame. */
2640 || (new_x == it->last_visible_x
2641 && FRAME_WINDOW_P (it->f))))
2642 {
2643 if (it->current.dpvec_index >= 0
2644 || it->current.overlay_string_index >= 0)
2645 {
2646 set_iterator_to_next (it, 1);
2647 move_it_in_display_line_to (it, -1, -1, 0);
2648 }
2649
2650 it->continuation_lines_width += it->current_x;
2651 }
2652
2653 /* We're starting a new display line, not affected by the
2654 height of the continued line, so clear the appropriate
2655 fields in the iterator structure. */
2656 it->max_ascent = it->max_descent = 0;
2657 it->max_phys_ascent = it->max_phys_descent = 0;
2658
2659 it->current_y = first_y;
2660 it->vpos = 0;
2661 it->current_x = it->hpos = 0;
2662 }
2663 }
2664 }
2665
2666
2667 /* Return 1 if POS is a position in ellipses displayed for invisible
2668 text. W is the window we display, for text property lookup. */
2669
2670 static int
2671 in_ellipses_for_invisible_text_p (struct display_pos *pos, struct window *w)
2672 {
2673 Lisp_Object prop, window;
2674 int ellipses_p = 0;
2675 EMACS_INT charpos = CHARPOS (pos->pos);
2676
2677 /* If POS specifies a position in a display vector, this might
2678 be for an ellipsis displayed for invisible text. We won't
2679 get the iterator set up for delivering that ellipsis unless
2680 we make sure that it gets aware of the invisible text. */
2681 if (pos->dpvec_index >= 0
2682 && pos->overlay_string_index < 0
2683 && CHARPOS (pos->string_pos) < 0
2684 && charpos > BEGV
2685 && (XSETWINDOW (window, w),
2686 prop = Fget_char_property (make_number (charpos),
2687 Qinvisible, window),
2688 !TEXT_PROP_MEANS_INVISIBLE (prop)))
2689 {
2690 prop = Fget_char_property (make_number (charpos - 1), Qinvisible,
2691 window);
2692 ellipses_p = 2 == TEXT_PROP_MEANS_INVISIBLE (prop);
2693 }
2694
2695 return ellipses_p;
2696 }
2697
2698
2699 /* Initialize IT for stepping through current_buffer in window W,
2700 starting at position POS that includes overlay string and display
2701 vector/ control character translation position information. Value
2702 is zero if there are overlay strings with newlines at POS. */
2703
2704 static int
2705 init_from_display_pos (struct it *it, struct window *w, struct display_pos *pos)
2706 {
2707 EMACS_INT charpos = CHARPOS (pos->pos), bytepos = BYTEPOS (pos->pos);
2708 int i, overlay_strings_with_newlines = 0;
2709
2710 /* If POS specifies a position in a display vector, this might
2711 be for an ellipsis displayed for invisible text. We won't
2712 get the iterator set up for delivering that ellipsis unless
2713 we make sure that it gets aware of the invisible text. */
2714 if (in_ellipses_for_invisible_text_p (pos, w))
2715 {
2716 --charpos;
2717 bytepos = 0;
2718 }
2719
2720 /* Keep in mind: the call to reseat in init_iterator skips invisible
2721 text, so we might end up at a position different from POS. This
2722 is only a problem when POS is a row start after a newline and an
2723 overlay starts there with an after-string, and the overlay has an
2724 invisible property. Since we don't skip invisible text in
2725 display_line and elsewhere immediately after consuming the
2726 newline before the row start, such a POS will not be in a string,
2727 but the call to init_iterator below will move us to the
2728 after-string. */
2729 init_iterator (it, w, charpos, bytepos, NULL, DEFAULT_FACE_ID);
2730
2731 /* This only scans the current chunk -- it should scan all chunks.
2732 However, OVERLAY_STRING_CHUNK_SIZE has been increased from 3 in 21.1
2733 to 16 in 22.1 to make this a lesser problem. */
2734 for (i = 0; i < it->n_overlay_strings && i < OVERLAY_STRING_CHUNK_SIZE; ++i)
2735 {
2736 const char *s = SSDATA (it->overlay_strings[i]);
2737 const char *e = s + SBYTES (it->overlay_strings[i]);
2738
2739 while (s < e && *s != '\n')
2740 ++s;
2741
2742 if (s < e)
2743 {
2744 overlay_strings_with_newlines = 1;
2745 break;
2746 }
2747 }
2748
2749 /* If position is within an overlay string, set up IT to the right
2750 overlay string. */
2751 if (pos->overlay_string_index >= 0)
2752 {
2753 int relative_index;
2754
2755 /* If the first overlay string happens to have a `display'
2756 property for an image, the iterator will be set up for that
2757 image, and we have to undo that setup first before we can
2758 correct the overlay string index. */
2759 if (it->method == GET_FROM_IMAGE)
2760 pop_it (it);
2761
2762 /* We already have the first chunk of overlay strings in
2763 IT->overlay_strings. Load more until the one for
2764 pos->overlay_string_index is in IT->overlay_strings. */
2765 if (pos->overlay_string_index >= OVERLAY_STRING_CHUNK_SIZE)
2766 {
2767 int n = pos->overlay_string_index / OVERLAY_STRING_CHUNK_SIZE;
2768 it->current.overlay_string_index = 0;
2769 while (n--)
2770 {
2771 load_overlay_strings (it, 0);
2772 it->current.overlay_string_index += OVERLAY_STRING_CHUNK_SIZE;
2773 }
2774 }
2775
2776 it->current.overlay_string_index = pos->overlay_string_index;
2777 relative_index = (it->current.overlay_string_index
2778 % OVERLAY_STRING_CHUNK_SIZE);
2779 it->string = it->overlay_strings[relative_index];
2780 xassert (STRINGP (it->string));
2781 it->current.string_pos = pos->string_pos;
2782 it->method = GET_FROM_STRING;
2783 }
2784
2785 if (CHARPOS (pos->string_pos) >= 0)
2786 {
2787 /* Recorded position is not in an overlay string, but in another
2788 string. This can only be a string from a `display' property.
2789 IT should already be filled with that string. */
2790 it->current.string_pos = pos->string_pos;
2791 xassert (STRINGP (it->string));
2792 }
2793
2794 /* Restore position in display vector translations, control
2795 character translations or ellipses. */
2796 if (pos->dpvec_index >= 0)
2797 {
2798 if (it->dpvec == NULL)
2799 get_next_display_element (it);
2800 xassert (it->dpvec && it->current.dpvec_index == 0);
2801 it->current.dpvec_index = pos->dpvec_index;
2802 }
2803
2804 CHECK_IT (it);
2805 return !overlay_strings_with_newlines;
2806 }
2807
2808
2809 /* Initialize IT for stepping through current_buffer in window W
2810 starting at ROW->start. */
2811
2812 static void
2813 init_to_row_start (struct it *it, struct window *w, struct glyph_row *row)
2814 {
2815 init_from_display_pos (it, w, &row->start);
2816 it->start = row->start;
2817 it->continuation_lines_width = row->continuation_lines_width;
2818 CHECK_IT (it);
2819 }
2820
2821
2822 /* Initialize IT for stepping through current_buffer in window W
2823 starting in the line following ROW, i.e. starting at ROW->end.
2824 Value is zero if there are overlay strings with newlines at ROW's
2825 end position. */
2826
2827 static int
2828 init_to_row_end (struct it *it, struct window *w, struct glyph_row *row)
2829 {
2830 int success = 0;
2831
2832 if (init_from_display_pos (it, w, &row->end))
2833 {
2834 if (row->continued_p)
2835 it->continuation_lines_width
2836 = row->continuation_lines_width + row->pixel_width;
2837 CHECK_IT (it);
2838 success = 1;
2839 }
2840
2841 return success;
2842 }
2843
2844
2845
2846 \f
2847 /***********************************************************************
2848 Text properties
2849 ***********************************************************************/
2850
2851 /* Called when IT reaches IT->stop_charpos. Handle text property and
2852 overlay changes. Set IT->stop_charpos to the next position where
2853 to stop. */
2854
2855 static void
2856 handle_stop (struct it *it)
2857 {
2858 enum prop_handled handled;
2859 int handle_overlay_change_p;
2860 struct props *p;
2861
2862 it->dpvec = NULL;
2863 it->current.dpvec_index = -1;
2864 handle_overlay_change_p = !it->ignore_overlay_strings_at_pos_p;
2865 it->ignore_overlay_strings_at_pos_p = 0;
2866 it->ellipsis_p = 0;
2867
2868 /* Use face of preceding text for ellipsis (if invisible) */
2869 if (it->selective_display_ellipsis_p)
2870 it->saved_face_id = it->face_id;
2871
2872 do
2873 {
2874 handled = HANDLED_NORMALLY;
2875
2876 /* Call text property handlers. */
2877 for (p = it_props; p->handler; ++p)
2878 {
2879 handled = p->handler (it);
2880
2881 if (handled == HANDLED_RECOMPUTE_PROPS)
2882 break;
2883 else if (handled == HANDLED_RETURN)
2884 {
2885 /* We still want to show before and after strings from
2886 overlays even if the actual buffer text is replaced. */
2887 if (!handle_overlay_change_p
2888 || it->sp > 1
2889 || !get_overlay_strings_1 (it, 0, 0))
2890 {
2891 if (it->ellipsis_p)
2892 setup_for_ellipsis (it, 0);
2893 /* When handling a display spec, we might load an
2894 empty string. In that case, discard it here. We
2895 used to discard it in handle_single_display_spec,
2896 but that causes get_overlay_strings_1, above, to
2897 ignore overlay strings that we must check. */
2898 if (STRINGP (it->string) && !SCHARS (it->string))
2899 pop_it (it);
2900 return;
2901 }
2902 else if (STRINGP (it->string) && !SCHARS (it->string))
2903 pop_it (it);
2904 else
2905 {
2906 it->ignore_overlay_strings_at_pos_p = 1;
2907 it->string_from_display_prop_p = 0;
2908 handle_overlay_change_p = 0;
2909 }
2910 handled = HANDLED_RECOMPUTE_PROPS;
2911 break;
2912 }
2913 else if (handled == HANDLED_OVERLAY_STRING_CONSUMED)
2914 handle_overlay_change_p = 0;
2915 }
2916
2917 if (handled != HANDLED_RECOMPUTE_PROPS)
2918 {
2919 /* Don't check for overlay strings below when set to deliver
2920 characters from a display vector. */
2921 if (it->method == GET_FROM_DISPLAY_VECTOR)
2922 handle_overlay_change_p = 0;
2923
2924 /* Handle overlay changes.
2925 This sets HANDLED to HANDLED_RECOMPUTE_PROPS
2926 if it finds overlays. */
2927 if (handle_overlay_change_p)
2928 handled = handle_overlay_change (it);
2929 }
2930
2931 if (it->ellipsis_p)
2932 {
2933 setup_for_ellipsis (it, 0);
2934 break;
2935 }
2936 }
2937 while (handled == HANDLED_RECOMPUTE_PROPS);
2938
2939 /* Determine where to stop next. */
2940 if (handled == HANDLED_NORMALLY)
2941 compute_stop_pos (it);
2942 }
2943
2944
2945 /* Compute IT->stop_charpos from text property and overlay change
2946 information for IT's current position. */
2947
2948 static void
2949 compute_stop_pos (struct it *it)
2950 {
2951 register INTERVAL iv, next_iv;
2952 Lisp_Object object, limit, position;
2953 EMACS_INT charpos, bytepos;
2954
2955 /* If nowhere else, stop at the end. */
2956 it->stop_charpos = it->end_charpos;
2957
2958 if (STRINGP (it->string))
2959 {
2960 /* Strings are usually short, so don't limit the search for
2961 properties. */
2962 object = it->string;
2963 limit = Qnil;
2964 charpos = IT_STRING_CHARPOS (*it);
2965 bytepos = IT_STRING_BYTEPOS (*it);
2966 }
2967 else
2968 {
2969 EMACS_INT pos;
2970
2971 /* If next overlay change is in front of the current stop pos
2972 (which is IT->end_charpos), stop there. Note: value of
2973 next_overlay_change is point-max if no overlay change
2974 follows. */
2975 charpos = IT_CHARPOS (*it);
2976 bytepos = IT_BYTEPOS (*it);
2977 pos = next_overlay_change (charpos);
2978 if (pos < it->stop_charpos)
2979 it->stop_charpos = pos;
2980
2981 /* If showing the region, we have to stop at the region
2982 start or end because the face might change there. */
2983 if (it->region_beg_charpos > 0)
2984 {
2985 if (IT_CHARPOS (*it) < it->region_beg_charpos)
2986 it->stop_charpos = min (it->stop_charpos, it->region_beg_charpos);
2987 else if (IT_CHARPOS (*it) < it->region_end_charpos)
2988 it->stop_charpos = min (it->stop_charpos, it->region_end_charpos);
2989 }
2990
2991 /* Set up variables for computing the stop position from text
2992 property changes. */
2993 XSETBUFFER (object, current_buffer);
2994 limit = make_number (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT);
2995 }
2996
2997 /* Get the interval containing IT's position. Value is a null
2998 interval if there isn't such an interval. */
2999 position = make_number (charpos);
3000 iv = validate_interval_range (object, &position, &position, 0);
3001 if (!NULL_INTERVAL_P (iv))
3002 {
3003 Lisp_Object values_here[LAST_PROP_IDX];
3004 struct props *p;
3005
3006 /* Get properties here. */
3007 for (p = it_props; p->handler; ++p)
3008 values_here[p->idx] = textget (iv->plist, *p->name);
3009
3010 /* Look for an interval following iv that has different
3011 properties. */
3012 for (next_iv = next_interval (iv);
3013 (!NULL_INTERVAL_P (next_iv)
3014 && (NILP (limit)
3015 || XFASTINT (limit) > next_iv->position));
3016 next_iv = next_interval (next_iv))
3017 {
3018 for (p = it_props; p->handler; ++p)
3019 {
3020 Lisp_Object new_value;
3021
3022 new_value = textget (next_iv->plist, *p->name);
3023 if (!EQ (values_here[p->idx], new_value))
3024 break;
3025 }
3026
3027 if (p->handler)
3028 break;
3029 }
3030
3031 if (!NULL_INTERVAL_P (next_iv))
3032 {
3033 if (INTEGERP (limit)
3034 && next_iv->position >= XFASTINT (limit))
3035 /* No text property change up to limit. */
3036 it->stop_charpos = min (XFASTINT (limit), it->stop_charpos);
3037 else
3038 /* Text properties change in next_iv. */
3039 it->stop_charpos = min (it->stop_charpos, next_iv->position);
3040 }
3041 }
3042
3043 if (it->cmp_it.id < 0)
3044 {
3045 EMACS_INT stoppos = it->end_charpos;
3046
3047 if (it->bidi_p && it->bidi_it.scan_dir < 0)
3048 stoppos = -1;
3049 composition_compute_stop_pos (&it->cmp_it, charpos, bytepos,
3050 stoppos, it->string);
3051 }
3052
3053 xassert (STRINGP (it->string)
3054 || (it->stop_charpos >= BEGV
3055 && it->stop_charpos >= IT_CHARPOS (*it)));
3056 }
3057
3058
3059 /* Return the position of the next overlay change after POS in
3060 current_buffer. Value is point-max if no overlay change
3061 follows. This is like `next-overlay-change' but doesn't use
3062 xmalloc. */
3063
3064 static EMACS_INT
3065 next_overlay_change (EMACS_INT pos)
3066 {
3067 int noverlays;
3068 EMACS_INT endpos;
3069 Lisp_Object *overlays;
3070 int i;
3071
3072 /* Get all overlays at the given position. */
3073 GET_OVERLAYS_AT (pos, overlays, noverlays, &endpos, 1);
3074
3075 /* If any of these overlays ends before endpos,
3076 use its ending point instead. */
3077 for (i = 0; i < noverlays; ++i)
3078 {
3079 Lisp_Object oend;
3080 EMACS_INT oendpos;
3081
3082 oend = OVERLAY_END (overlays[i]);
3083 oendpos = OVERLAY_POSITION (oend);
3084 endpos = min (endpos, oendpos);
3085 }
3086
3087 return endpos;
3088 }
3089
3090 /* Return the character position of a display string at or after CHARPOS.
3091 If no display string exists at or after CHARPOS, return ZV. A
3092 display string is either an overlay with `display' property whose
3093 value is a string, or a `display' text property whose value is a
3094 string. FRAME_WINDOW_P is non-zero when we are displaying a window
3095 on a GUI frame. */
3096 EMACS_INT
3097 compute_display_string_pos (EMACS_INT charpos, int frame_window_p)
3098 {
3099 /* FIXME: Support display properties on strings (object = Qnil means
3100 current buffer). */
3101 Lisp_Object object = Qnil;
3102 Lisp_Object pos, spec;
3103 struct text_pos position;
3104 EMACS_INT bufpos;
3105
3106 if (charpos >= ZV)
3107 return ZV;
3108
3109 /* If the character at CHARPOS is where the display string begins,
3110 return CHARPOS. */
3111 pos = make_number (charpos);
3112 CHARPOS (position) = charpos;
3113 BYTEPOS (position) = CHAR_TO_BYTE (charpos);
3114 bufpos = charpos; /* FIXME! support strings as well */
3115 if (!NILP (spec = Fget_char_property (pos, Qdisplay, object))
3116 && (charpos <= BEGV
3117 || !EQ (Fget_char_property (make_number (charpos - 1), Qdisplay,
3118 object),
3119 spec))
3120 && handle_display_spec (NULL, spec, object, Qnil, &position, bufpos,
3121 frame_window_p))
3122 return charpos;
3123
3124 /* Look forward for the first character with a `display' property
3125 that will replace the underlying text when displayed. */
3126 do {
3127 pos = Fnext_single_char_property_change (pos, Qdisplay, object, Qnil);
3128 CHARPOS (position) = XFASTINT (pos);
3129 BYTEPOS (position) = CHAR_TO_BYTE (CHARPOS (position));
3130 if (CHARPOS (position) >= ZV)
3131 break;
3132 spec = Fget_char_property (pos, Qdisplay, object);
3133 bufpos = CHARPOS (position); /* FIXME! support strings as well */
3134 } while (NILP (spec)
3135 || !handle_display_spec (NULL, spec, object, Qnil, &position, bufpos,
3136 frame_window_p));
3137
3138 return CHARPOS (position);
3139 }
3140
3141 /* Return the character position of the end of the display string that
3142 started at CHARPOS. A display string is either an overlay with
3143 `display' property whose value is a string or a `display' text
3144 property whose value is a string. */
3145 EMACS_INT
3146 compute_display_string_end (EMACS_INT charpos)
3147 {
3148 /* FIXME: Support display properties on strings (object = Qnil means
3149 current buffer). */
3150 Lisp_Object object = Qnil;
3151 Lisp_Object pos = make_number (charpos);
3152
3153 if (charpos >= ZV)
3154 return ZV;
3155
3156 if (NILP (Fget_char_property (pos, Qdisplay, object)))
3157 abort ();
3158
3159 /* Look forward for the first character where the `display' property
3160 changes. */
3161 pos = Fnext_single_char_property_change (pos, Qdisplay, object, Qnil);
3162
3163 return XFASTINT (pos);
3164 }
3165
3166
3167 \f
3168 /***********************************************************************
3169 Fontification
3170 ***********************************************************************/
3171
3172 /* Handle changes in the `fontified' property of the current buffer by
3173 calling hook functions from Qfontification_functions to fontify
3174 regions of text. */
3175
3176 static enum prop_handled
3177 handle_fontified_prop (struct it *it)
3178 {
3179 Lisp_Object prop, pos;
3180 enum prop_handled handled = HANDLED_NORMALLY;
3181
3182 if (!NILP (Vmemory_full))
3183 return handled;
3184
3185 /* Get the value of the `fontified' property at IT's current buffer
3186 position. (The `fontified' property doesn't have a special
3187 meaning in strings.) If the value is nil, call functions from
3188 Qfontification_functions. */
3189 if (!STRINGP (it->string)
3190 && it->s == NULL
3191 && !NILP (Vfontification_functions)
3192 && !NILP (Vrun_hooks)
3193 && (pos = make_number (IT_CHARPOS (*it)),
3194 prop = Fget_char_property (pos, Qfontified, Qnil),
3195 /* Ignore the special cased nil value always present at EOB since
3196 no amount of fontifying will be able to change it. */
3197 NILP (prop) && IT_CHARPOS (*it) < Z))
3198 {
3199 int count = SPECPDL_INDEX ();
3200 Lisp_Object val;
3201 struct buffer *obuf = current_buffer;
3202 int begv = BEGV, zv = ZV;
3203 int old_clip_changed = current_buffer->clip_changed;
3204
3205 val = Vfontification_functions;
3206 specbind (Qfontification_functions, Qnil);
3207
3208 xassert (it->end_charpos == ZV);
3209
3210 if (!CONSP (val) || EQ (XCAR (val), Qlambda))
3211 safe_call1 (val, pos);
3212 else
3213 {
3214 Lisp_Object fns, fn;
3215 struct gcpro gcpro1, gcpro2;
3216
3217 fns = Qnil;
3218 GCPRO2 (val, fns);
3219
3220 for (; CONSP (val); val = XCDR (val))
3221 {
3222 fn = XCAR (val);
3223
3224 if (EQ (fn, Qt))
3225 {
3226 /* A value of t indicates this hook has a local
3227 binding; it means to run the global binding too.
3228 In a global value, t should not occur. If it
3229 does, we must ignore it to avoid an endless
3230 loop. */
3231 for (fns = Fdefault_value (Qfontification_functions);
3232 CONSP (fns);
3233 fns = XCDR (fns))
3234 {
3235 fn = XCAR (fns);
3236 if (!EQ (fn, Qt))
3237 safe_call1 (fn, pos);
3238 }
3239 }
3240 else
3241 safe_call1 (fn, pos);
3242 }
3243
3244 UNGCPRO;
3245 }
3246
3247 unbind_to (count, Qnil);
3248
3249 /* Fontification functions routinely call `save-restriction'.
3250 Normally, this tags clip_changed, which can confuse redisplay
3251 (see discussion in Bug#6671). Since we don't perform any
3252 special handling of fontification changes in the case where
3253 `save-restriction' isn't called, there's no point doing so in
3254 this case either. So, if the buffer's restrictions are
3255 actually left unchanged, reset clip_changed. */
3256 if (obuf == current_buffer)
3257 {
3258 if (begv == BEGV && zv == ZV)
3259 current_buffer->clip_changed = old_clip_changed;
3260 }
3261 /* There isn't much we can reasonably do to protect against
3262 misbehaving fontification, but here's a fig leaf. */
3263 else if (!NILP (BVAR (obuf, name)))
3264 set_buffer_internal_1 (obuf);
3265
3266 /* The fontification code may have added/removed text.
3267 It could do even a lot worse, but let's at least protect against
3268 the most obvious case where only the text past `pos' gets changed',
3269 as is/was done in grep.el where some escapes sequences are turned
3270 into face properties (bug#7876). */
3271 it->end_charpos = ZV;
3272
3273 /* Return HANDLED_RECOMPUTE_PROPS only if function fontified
3274 something. This avoids an endless loop if they failed to
3275 fontify the text for which reason ever. */
3276 if (!NILP (Fget_char_property (pos, Qfontified, Qnil)))
3277 handled = HANDLED_RECOMPUTE_PROPS;
3278 }
3279
3280 return handled;
3281 }
3282
3283
3284 \f
3285 /***********************************************************************
3286 Faces
3287 ***********************************************************************/
3288
3289 /* Set up iterator IT from face properties at its current position.
3290 Called from handle_stop. */
3291
3292 static enum prop_handled
3293 handle_face_prop (struct it *it)
3294 {
3295 int new_face_id;
3296 EMACS_INT next_stop;
3297
3298 if (!STRINGP (it->string))
3299 {
3300 new_face_id
3301 = face_at_buffer_position (it->w,
3302 IT_CHARPOS (*it),
3303 it->region_beg_charpos,
3304 it->region_end_charpos,
3305 &next_stop,
3306 (IT_CHARPOS (*it)
3307 + TEXT_PROP_DISTANCE_LIMIT),
3308 0, it->base_face_id);
3309
3310 /* Is this a start of a run of characters with box face?
3311 Caveat: this can be called for a freshly initialized
3312 iterator; face_id is -1 in this case. We know that the new
3313 face will not change until limit, i.e. if the new face has a
3314 box, all characters up to limit will have one. But, as
3315 usual, we don't know whether limit is really the end. */
3316 if (new_face_id != it->face_id)
3317 {
3318 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
3319
3320 /* If new face has a box but old face has not, this is
3321 the start of a run of characters with box, i.e. it has
3322 a shadow on the left side. The value of face_id of the
3323 iterator will be -1 if this is the initial call that gets
3324 the face. In this case, we have to look in front of IT's
3325 position and see whether there is a face != new_face_id. */
3326 it->start_of_box_run_p
3327 = (new_face->box != FACE_NO_BOX
3328 && (it->face_id >= 0
3329 || IT_CHARPOS (*it) == BEG
3330 || new_face_id != face_before_it_pos (it)));
3331 it->face_box_p = new_face->box != FACE_NO_BOX;
3332 }
3333 }
3334 else
3335 {
3336 int base_face_id;
3337 EMACS_INT bufpos;
3338 int i;
3339 Lisp_Object from_overlay
3340 = (it->current.overlay_string_index >= 0
3341 ? it->string_overlays[it->current.overlay_string_index]
3342 : Qnil);
3343
3344 /* See if we got to this string directly or indirectly from
3345 an overlay property. That includes the before-string or
3346 after-string of an overlay, strings in display properties
3347 provided by an overlay, their text properties, etc.
3348
3349 FROM_OVERLAY is the overlay that brought us here, or nil if none. */
3350 if (! NILP (from_overlay))
3351 for (i = it->sp - 1; i >= 0; i--)
3352 {
3353 if (it->stack[i].current.overlay_string_index >= 0)
3354 from_overlay
3355 = it->string_overlays[it->stack[i].current.overlay_string_index];
3356 else if (! NILP (it->stack[i].from_overlay))
3357 from_overlay = it->stack[i].from_overlay;
3358
3359 if (!NILP (from_overlay))
3360 break;
3361 }
3362
3363 if (! NILP (from_overlay))
3364 {
3365 bufpos = IT_CHARPOS (*it);
3366 /* For a string from an overlay, the base face depends
3367 only on text properties and ignores overlays. */
3368 base_face_id
3369 = face_for_overlay_string (it->w,
3370 IT_CHARPOS (*it),
3371 it->region_beg_charpos,
3372 it->region_end_charpos,
3373 &next_stop,
3374 (IT_CHARPOS (*it)
3375 + TEXT_PROP_DISTANCE_LIMIT),
3376 0,
3377 from_overlay);
3378 }
3379 else
3380 {
3381 bufpos = 0;
3382
3383 /* For strings from a `display' property, use the face at
3384 IT's current buffer position as the base face to merge
3385 with, so that overlay strings appear in the same face as
3386 surrounding text, unless they specify their own
3387 faces. */
3388 base_face_id = underlying_face_id (it);
3389 }
3390
3391 new_face_id = face_at_string_position (it->w,
3392 it->string,
3393 IT_STRING_CHARPOS (*it),
3394 bufpos,
3395 it->region_beg_charpos,
3396 it->region_end_charpos,
3397 &next_stop,
3398 base_face_id, 0);
3399
3400 /* Is this a start of a run of characters with box? Caveat:
3401 this can be called for a freshly allocated iterator; face_id
3402 is -1 is this case. We know that the new face will not
3403 change until the next check pos, i.e. if the new face has a
3404 box, all characters up to that position will have a
3405 box. But, as usual, we don't know whether that position
3406 is really the end. */
3407 if (new_face_id != it->face_id)
3408 {
3409 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
3410 struct face *old_face = FACE_FROM_ID (it->f, it->face_id);
3411
3412 /* If new face has a box but old face hasn't, this is the
3413 start of a run of characters with box, i.e. it has a
3414 shadow on the left side. */
3415 it->start_of_box_run_p
3416 = new_face->box && (old_face == NULL || !old_face->box);
3417 it->face_box_p = new_face->box != FACE_NO_BOX;
3418 }
3419 }
3420
3421 it->face_id = new_face_id;
3422 return HANDLED_NORMALLY;
3423 }
3424
3425
3426 /* Return the ID of the face ``underlying'' IT's current position,
3427 which is in a string. If the iterator is associated with a
3428 buffer, return the face at IT's current buffer position.
3429 Otherwise, use the iterator's base_face_id. */
3430
3431 static int
3432 underlying_face_id (struct it *it)
3433 {
3434 int face_id = it->base_face_id, i;
3435
3436 xassert (STRINGP (it->string));
3437
3438 for (i = it->sp - 1; i >= 0; --i)
3439 if (NILP (it->stack[i].string))
3440 face_id = it->stack[i].face_id;
3441
3442 return face_id;
3443 }
3444
3445
3446 /* Compute the face one character before or after the current position
3447 of IT. BEFORE_P non-zero means get the face in front of IT's
3448 position. Value is the id of the face. */
3449
3450 static int
3451 face_before_or_after_it_pos (struct it *it, int before_p)
3452 {
3453 int face_id, limit;
3454 EMACS_INT next_check_charpos;
3455 struct text_pos pos;
3456
3457 xassert (it->s == NULL);
3458
3459 if (STRINGP (it->string))
3460 {
3461 EMACS_INT bufpos;
3462 int base_face_id;
3463
3464 /* No face change past the end of the string (for the case
3465 we are padding with spaces). No face change before the
3466 string start. */
3467 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string)
3468 || (IT_STRING_CHARPOS (*it) == 0 && before_p))
3469 return it->face_id;
3470
3471 /* Set pos to the position before or after IT's current position. */
3472 if (before_p)
3473 pos = string_pos (IT_STRING_CHARPOS (*it) - 1, it->string);
3474 else
3475 /* For composition, we must check the character after the
3476 composition. */
3477 pos = (it->what == IT_COMPOSITION
3478 ? string_pos (IT_STRING_CHARPOS (*it)
3479 + it->cmp_it.nchars, it->string)
3480 : string_pos (IT_STRING_CHARPOS (*it) + 1, it->string));
3481
3482 if (it->current.overlay_string_index >= 0)
3483 bufpos = IT_CHARPOS (*it);
3484 else
3485 bufpos = 0;
3486
3487 base_face_id = underlying_face_id (it);
3488
3489 /* Get the face for ASCII, or unibyte. */
3490 face_id = face_at_string_position (it->w,
3491 it->string,
3492 CHARPOS (pos),
3493 bufpos,
3494 it->region_beg_charpos,
3495 it->region_end_charpos,
3496 &next_check_charpos,
3497 base_face_id, 0);
3498
3499 /* Correct the face for charsets different from ASCII. Do it
3500 for the multibyte case only. The face returned above is
3501 suitable for unibyte text if IT->string is unibyte. */
3502 if (STRING_MULTIBYTE (it->string))
3503 {
3504 const unsigned char *p = SDATA (it->string) + BYTEPOS (pos);
3505 int c, len;
3506 struct face *face = FACE_FROM_ID (it->f, face_id);
3507
3508 c = string_char_and_length (p, &len);
3509 face_id = FACE_FOR_CHAR (it->f, face, c, CHARPOS (pos), it->string);
3510 }
3511 }
3512 else
3513 {
3514 if ((IT_CHARPOS (*it) >= ZV && !before_p)
3515 || (IT_CHARPOS (*it) <= BEGV && before_p))
3516 return it->face_id;
3517
3518 limit = IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT;
3519 pos = it->current.pos;
3520
3521 if (before_p)
3522 DEC_TEXT_POS (pos, it->multibyte_p);
3523 else
3524 {
3525 if (it->what == IT_COMPOSITION)
3526 /* For composition, we must check the position after the
3527 composition. */
3528 pos.charpos += it->cmp_it.nchars, pos.bytepos += it->len;
3529 else
3530 INC_TEXT_POS (pos, it->multibyte_p);
3531 }
3532
3533 /* Determine face for CHARSET_ASCII, or unibyte. */
3534 face_id = face_at_buffer_position (it->w,
3535 CHARPOS (pos),
3536 it->region_beg_charpos,
3537 it->region_end_charpos,
3538 &next_check_charpos,
3539 limit, 0, -1);
3540
3541 /* Correct the face for charsets different from ASCII. Do it
3542 for the multibyte case only. The face returned above is
3543 suitable for unibyte text if current_buffer is unibyte. */
3544 if (it->multibyte_p)
3545 {
3546 int c = FETCH_MULTIBYTE_CHAR (BYTEPOS (pos));
3547 struct face *face = FACE_FROM_ID (it->f, face_id);
3548 face_id = FACE_FOR_CHAR (it->f, face, c, CHARPOS (pos), Qnil);
3549 }
3550 }
3551
3552 return face_id;
3553 }
3554
3555
3556 \f
3557 /***********************************************************************
3558 Invisible text
3559 ***********************************************************************/
3560
3561 /* Set up iterator IT from invisible properties at its current
3562 position. Called from handle_stop. */
3563
3564 static enum prop_handled
3565 handle_invisible_prop (struct it *it)
3566 {
3567 enum prop_handled handled = HANDLED_NORMALLY;
3568
3569 if (STRINGP (it->string))
3570 {
3571 Lisp_Object prop, end_charpos, limit, charpos;
3572
3573 /* Get the value of the invisible text property at the
3574 current position. Value will be nil if there is no such
3575 property. */
3576 charpos = make_number (IT_STRING_CHARPOS (*it));
3577 prop = Fget_text_property (charpos, Qinvisible, it->string);
3578
3579 if (!NILP (prop)
3580 && IT_STRING_CHARPOS (*it) < it->end_charpos)
3581 {
3582 handled = HANDLED_RECOMPUTE_PROPS;
3583
3584 /* Get the position at which the next change of the
3585 invisible text property can be found in IT->string.
3586 Value will be nil if the property value is the same for
3587 all the rest of IT->string. */
3588 XSETINT (limit, SCHARS (it->string));
3589 end_charpos = Fnext_single_property_change (charpos, Qinvisible,
3590 it->string, limit);
3591
3592 /* Text at current position is invisible. The next
3593 change in the property is at position end_charpos.
3594 Move IT's current position to that position. */
3595 if (INTEGERP (end_charpos)
3596 && XFASTINT (end_charpos) < XFASTINT (limit))
3597 {
3598 struct text_pos old;
3599 old = it->current.string_pos;
3600 IT_STRING_CHARPOS (*it) = XFASTINT (end_charpos);
3601 compute_string_pos (&it->current.string_pos, old, it->string);
3602 }
3603 else
3604 {
3605 /* The rest of the string is invisible. If this is an
3606 overlay string, proceed with the next overlay string
3607 or whatever comes and return a character from there. */
3608 if (it->current.overlay_string_index >= 0)
3609 {
3610 next_overlay_string (it);
3611 /* Don't check for overlay strings when we just
3612 finished processing them. */
3613 handled = HANDLED_OVERLAY_STRING_CONSUMED;
3614 }
3615 else
3616 {
3617 IT_STRING_CHARPOS (*it) = SCHARS (it->string);
3618 IT_STRING_BYTEPOS (*it) = SBYTES (it->string);
3619 }
3620 }
3621 }
3622 }
3623 else
3624 {
3625 int invis_p;
3626 EMACS_INT newpos, next_stop, start_charpos, tem;
3627 Lisp_Object pos, prop, overlay;
3628
3629 /* First of all, is there invisible text at this position? */
3630 tem = start_charpos = IT_CHARPOS (*it);
3631 pos = make_number (tem);
3632 prop = get_char_property_and_overlay (pos, Qinvisible, it->window,
3633 &overlay);
3634 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
3635
3636 /* If we are on invisible text, skip over it. */
3637 if (invis_p && start_charpos < it->end_charpos)
3638 {
3639 /* Record whether we have to display an ellipsis for the
3640 invisible text. */
3641 int display_ellipsis_p = invis_p == 2;
3642
3643 handled = HANDLED_RECOMPUTE_PROPS;
3644
3645 /* Loop skipping over invisible text. The loop is left at
3646 ZV or with IT on the first char being visible again. */
3647 do
3648 {
3649 /* Try to skip some invisible text. Return value is the
3650 position reached which can be equal to where we start
3651 if there is nothing invisible there. This skips both
3652 over invisible text properties and overlays with
3653 invisible property. */
3654 newpos = skip_invisible (tem, &next_stop, ZV, it->window);
3655
3656 /* If we skipped nothing at all we weren't at invisible
3657 text in the first place. If everything to the end of
3658 the buffer was skipped, end the loop. */
3659 if (newpos == tem || newpos >= ZV)
3660 invis_p = 0;
3661 else
3662 {
3663 /* We skipped some characters but not necessarily
3664 all there are. Check if we ended up on visible
3665 text. Fget_char_property returns the property of
3666 the char before the given position, i.e. if we
3667 get invis_p = 0, this means that the char at
3668 newpos is visible. */
3669 pos = make_number (newpos);
3670 prop = Fget_char_property (pos, Qinvisible, it->window);
3671 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
3672 }
3673
3674 /* If we ended up on invisible text, proceed to
3675 skip starting with next_stop. */
3676 if (invis_p)
3677 tem = next_stop;
3678
3679 /* If there are adjacent invisible texts, don't lose the
3680 second one's ellipsis. */
3681 if (invis_p == 2)
3682 display_ellipsis_p = 1;
3683 }
3684 while (invis_p);
3685
3686 /* The position newpos is now either ZV or on visible text. */
3687 if (it->bidi_p && newpos < ZV)
3688 {
3689 /* With bidi iteration, the region of invisible text
3690 could start and/or end in the middle of a non-base
3691 embedding level. Therefore, we need to skip
3692 invisible text using the bidi iterator, starting at
3693 IT's current position, until we find ourselves
3694 outside the invisible text. Skipping invisible text
3695 _after_ bidi iteration avoids affecting the visual
3696 order of the displayed text when invisible properties
3697 are added or removed. */
3698 if (it->bidi_it.first_elt && it->bidi_it.charpos < ZV)
3699 {
3700 /* If we were `reseat'ed to a new paragraph,
3701 determine the paragraph base direction. We need
3702 to do it now because next_element_from_buffer may
3703 not have a chance to do it, if we are going to
3704 skip any text at the beginning, which resets the
3705 FIRST_ELT flag. */
3706 bidi_paragraph_init (it->paragraph_embedding,
3707 &it->bidi_it, 1);
3708 }
3709 do
3710 {
3711 bidi_move_to_visually_next (&it->bidi_it);
3712 }
3713 while (it->stop_charpos <= it->bidi_it.charpos
3714 && it->bidi_it.charpos < newpos);
3715 IT_CHARPOS (*it) = it->bidi_it.charpos;
3716 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
3717 /* If we overstepped NEWPOS, record its position in the
3718 iterator, so that we skip invisible text if later the
3719 bidi iteration lands us in the invisible region
3720 again. */
3721 if (IT_CHARPOS (*it) >= newpos)
3722 it->prev_stop = newpos;
3723 }
3724 else
3725 {
3726 IT_CHARPOS (*it) = newpos;
3727 IT_BYTEPOS (*it) = CHAR_TO_BYTE (newpos);
3728 }
3729
3730 /* If there are before-strings at the start of invisible
3731 text, and the text is invisible because of a text
3732 property, arrange to show before-strings because 20.x did
3733 it that way. (If the text is invisible because of an
3734 overlay property instead of a text property, this is
3735 already handled in the overlay code.) */
3736 if (NILP (overlay)
3737 && get_overlay_strings (it, it->stop_charpos))
3738 {
3739 handled = HANDLED_RECOMPUTE_PROPS;
3740 it->stack[it->sp - 1].display_ellipsis_p = display_ellipsis_p;
3741 }
3742 else if (display_ellipsis_p)
3743 {
3744 /* Make sure that the glyphs of the ellipsis will get
3745 correct `charpos' values. If we would not update
3746 it->position here, the glyphs would belong to the
3747 last visible character _before_ the invisible
3748 text, which confuses `set_cursor_from_row'.
3749
3750 We use the last invisible position instead of the
3751 first because this way the cursor is always drawn on
3752 the first "." of the ellipsis, whenever PT is inside
3753 the invisible text. Otherwise the cursor would be
3754 placed _after_ the ellipsis when the point is after the
3755 first invisible character. */
3756 if (!STRINGP (it->object))
3757 {
3758 it->position.charpos = newpos - 1;
3759 it->position.bytepos = CHAR_TO_BYTE (it->position.charpos);
3760 }
3761 it->ellipsis_p = 1;
3762 /* Let the ellipsis display before
3763 considering any properties of the following char.
3764 Fixes jasonr@gnu.org 01 Oct 07 bug. */
3765 handled = HANDLED_RETURN;
3766 }
3767 }
3768 }
3769
3770 return handled;
3771 }
3772
3773
3774 /* Make iterator IT return `...' next.
3775 Replaces LEN characters from buffer. */
3776
3777 static void
3778 setup_for_ellipsis (struct it *it, int len)
3779 {
3780 /* Use the display table definition for `...'. Invalid glyphs
3781 will be handled by the method returning elements from dpvec. */
3782 if (it->dp && VECTORP (DISP_INVIS_VECTOR (it->dp)))
3783 {
3784 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
3785 it->dpvec = v->contents;
3786 it->dpend = v->contents + v->header.size;
3787 }
3788 else
3789 {
3790 /* Default `...'. */
3791 it->dpvec = default_invis_vector;
3792 it->dpend = default_invis_vector + 3;
3793 }
3794
3795 it->dpvec_char_len = len;
3796 it->current.dpvec_index = 0;
3797 it->dpvec_face_id = -1;
3798
3799 /* Remember the current face id in case glyphs specify faces.
3800 IT's face is restored in set_iterator_to_next.
3801 saved_face_id was set to preceding char's face in handle_stop. */
3802 if (it->saved_face_id < 0 || it->saved_face_id != it->face_id)
3803 it->saved_face_id = it->face_id = DEFAULT_FACE_ID;
3804
3805 it->method = GET_FROM_DISPLAY_VECTOR;
3806 it->ellipsis_p = 1;
3807 }
3808
3809
3810 \f
3811 /***********************************************************************
3812 'display' property
3813 ***********************************************************************/
3814
3815 /* Set up iterator IT from `display' property at its current position.
3816 Called from handle_stop.
3817 We return HANDLED_RETURN if some part of the display property
3818 overrides the display of the buffer text itself.
3819 Otherwise we return HANDLED_NORMALLY. */
3820
3821 static enum prop_handled
3822 handle_display_prop (struct it *it)
3823 {
3824 Lisp_Object propval, object, overlay;
3825 struct text_pos *position;
3826 EMACS_INT bufpos;
3827 /* Nonzero if some property replaces the display of the text itself. */
3828 int display_replaced_p = 0;
3829
3830 if (STRINGP (it->string))
3831 {
3832 object = it->string;
3833 position = &it->current.string_pos;
3834 bufpos = CHARPOS (it->current.pos);
3835 }
3836 else
3837 {
3838 XSETWINDOW (object, it->w);
3839 position = &it->current.pos;
3840 bufpos = CHARPOS (*position);
3841 }
3842
3843 /* Reset those iterator values set from display property values. */
3844 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
3845 it->space_width = Qnil;
3846 it->font_height = Qnil;
3847 it->voffset = 0;
3848
3849 /* We don't support recursive `display' properties, i.e. string
3850 values that have a string `display' property, that have a string
3851 `display' property etc. */
3852 if (!it->string_from_display_prop_p)
3853 it->area = TEXT_AREA;
3854
3855 propval = get_char_property_and_overlay (make_number (position->charpos),
3856 Qdisplay, object, &overlay);
3857 if (NILP (propval))
3858 return HANDLED_NORMALLY;
3859 /* Now OVERLAY is the overlay that gave us this property, or nil
3860 if it was a text property. */
3861
3862 if (!STRINGP (it->string))
3863 object = it->w->buffer;
3864
3865 display_replaced_p = handle_display_spec (it, propval, object, overlay,
3866 position, bufpos,
3867 FRAME_WINDOW_P (it->f));
3868
3869 return display_replaced_p ? HANDLED_RETURN : HANDLED_NORMALLY;
3870 }
3871
3872 /* Subroutine of handle_display_prop. Returns non-zero if the display
3873 specification in SPEC is a replacing specification, i.e. it would
3874 replace the text covered by `display' property with something else,
3875 such as an image or a display string.
3876
3877 See handle_single_display_spec for documentation of arguments.
3878 frame_window_p is non-zero if the window being redisplayed is on a
3879 GUI frame; this argument is used only if IT is NULL, see below.
3880
3881 IT can be NULL, if this is called by the bidi reordering code
3882 through compute_display_string_pos, which see. In that case, this
3883 function only examines SPEC, but does not otherwise "handle" it, in
3884 the sense that it doesn't set up members of IT from the display
3885 spec. */
3886 static int
3887 handle_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
3888 Lisp_Object overlay, struct text_pos *position,
3889 EMACS_INT bufpos, int frame_window_p)
3890 {
3891 int replacing_p = 0;
3892
3893 if (CONSP (spec)
3894 /* Simple specerties. */
3895 && !EQ (XCAR (spec), Qimage)
3896 && !EQ (XCAR (spec), Qspace)
3897 && !EQ (XCAR (spec), Qwhen)
3898 && !EQ (XCAR (spec), Qslice)
3899 && !EQ (XCAR (spec), Qspace_width)
3900 && !EQ (XCAR (spec), Qheight)
3901 && !EQ (XCAR (spec), Qraise)
3902 /* Marginal area specifications. */
3903 && !(CONSP (XCAR (spec)) && EQ (XCAR (XCAR (spec)), Qmargin))
3904 && !EQ (XCAR (spec), Qleft_fringe)
3905 && !EQ (XCAR (spec), Qright_fringe)
3906 && !NILP (XCAR (spec)))
3907 {
3908 for (; CONSP (spec); spec = XCDR (spec))
3909 {
3910 if (handle_single_display_spec (it, XCAR (spec), object, overlay,
3911 position, bufpos, replacing_p,
3912 frame_window_p))
3913 {
3914 replacing_p = 1;
3915 /* If some text in a string is replaced, `position' no
3916 longer points to the position of `object'. */
3917 if (!it || STRINGP (object))
3918 break;
3919 }
3920 }
3921 }
3922 else if (VECTORP (spec))
3923 {
3924 int i;
3925 for (i = 0; i < ASIZE (spec); ++i)
3926 if (handle_single_display_spec (it, AREF (spec, i), object, overlay,
3927 position, bufpos, replacing_p,
3928 frame_window_p))
3929 {
3930 replacing_p = 1;
3931 /* If some text in a string is replaced, `position' no
3932 longer points to the position of `object'. */
3933 if (!it || STRINGP (object))
3934 break;
3935 }
3936 }
3937 else
3938 {
3939 if (handle_single_display_spec (it, spec, object, overlay,
3940 position, bufpos, 0, frame_window_p))
3941 replacing_p = 1;
3942 }
3943
3944 return replacing_p;
3945 }
3946
3947 /* Value is the position of the end of the `display' property starting
3948 at START_POS in OBJECT. */
3949
3950 static struct text_pos
3951 display_prop_end (struct it *it, Lisp_Object object, struct text_pos start_pos)
3952 {
3953 Lisp_Object end;
3954 struct text_pos end_pos;
3955
3956 end = Fnext_single_char_property_change (make_number (CHARPOS (start_pos)),
3957 Qdisplay, object, Qnil);
3958 CHARPOS (end_pos) = XFASTINT (end);
3959 if (STRINGP (object))
3960 compute_string_pos (&end_pos, start_pos, it->string);
3961 else
3962 BYTEPOS (end_pos) = CHAR_TO_BYTE (XFASTINT (end));
3963
3964 return end_pos;
3965 }
3966
3967
3968 /* Set up IT from a single `display' property specification SPEC. OBJECT
3969 is the object in which the `display' property was found. *POSITION
3970 is the position in OBJECT at which the `display' property was found.
3971 BUFPOS is the buffer position of OBJECT (different from POSITION if
3972 OBJECT is not a buffer). DISPLAY_REPLACED_P non-zero means that we
3973 previously saw a display specification which already replaced text
3974 display with something else, for example an image; we ignore such
3975 properties after the first one has been processed.
3976
3977 OVERLAY is the overlay this `display' property came from,
3978 or nil if it was a text property.
3979
3980 If SPEC is a `space' or `image' specification, and in some other
3981 cases too, set *POSITION to the position where the `display'
3982 property ends.
3983
3984 If IT is NULL, only examine the property specification in SPEC, but
3985 don't set up IT. In that case, FRAME_WINDOW_P non-zero means SPEC
3986 is intended to be displayed in a window on a GUI frame.
3987
3988 Value is non-zero if something was found which replaces the display
3989 of buffer or string text. */
3990
3991 static int
3992 handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
3993 Lisp_Object overlay, struct text_pos *position,
3994 EMACS_INT bufpos, int display_replaced_p,
3995 int frame_window_p)
3996 {
3997 Lisp_Object form;
3998 Lisp_Object location, value;
3999 struct text_pos start_pos = *position;
4000 int valid_p;
4001
4002 /* If SPEC is a list of the form `(when FORM . VALUE)', evaluate FORM.
4003 If the result is non-nil, use VALUE instead of SPEC. */
4004 form = Qt;
4005 if (CONSP (spec) && EQ (XCAR (spec), Qwhen))
4006 {
4007 spec = XCDR (spec);
4008 if (!CONSP (spec))
4009 return 0;
4010 form = XCAR (spec);
4011 spec = XCDR (spec);
4012 }
4013
4014 if (!NILP (form) && !EQ (form, Qt))
4015 {
4016 int count = SPECPDL_INDEX ();
4017 struct gcpro gcpro1;
4018
4019 /* Bind `object' to the object having the `display' property, a
4020 buffer or string. Bind `position' to the position in the
4021 object where the property was found, and `buffer-position'
4022 to the current position in the buffer. */
4023
4024 if (NILP (object))
4025 XSETBUFFER (object, current_buffer);
4026 specbind (Qobject, object);
4027 specbind (Qposition, make_number (CHARPOS (*position)));
4028 specbind (Qbuffer_position, make_number (bufpos));
4029 GCPRO1 (form);
4030 form = safe_eval (form);
4031 UNGCPRO;
4032 unbind_to (count, Qnil);
4033 }
4034
4035 if (NILP (form))
4036 return 0;
4037
4038 /* Handle `(height HEIGHT)' specifications. */
4039 if (CONSP (spec)
4040 && EQ (XCAR (spec), Qheight)
4041 && CONSP (XCDR (spec)))
4042 {
4043 if (it)
4044 {
4045 if (!FRAME_WINDOW_P (it->f))
4046 return 0;
4047
4048 it->font_height = XCAR (XCDR (spec));
4049 if (!NILP (it->font_height))
4050 {
4051 struct face *face = FACE_FROM_ID (it->f, it->face_id);
4052 int new_height = -1;
4053
4054 if (CONSP (it->font_height)
4055 && (EQ (XCAR (it->font_height), Qplus)
4056 || EQ (XCAR (it->font_height), Qminus))
4057 && CONSP (XCDR (it->font_height))
4058 && INTEGERP (XCAR (XCDR (it->font_height))))
4059 {
4060 /* `(+ N)' or `(- N)' where N is an integer. */
4061 int steps = XINT (XCAR (XCDR (it->font_height)));
4062 if (EQ (XCAR (it->font_height), Qplus))
4063 steps = - steps;
4064 it->face_id = smaller_face (it->f, it->face_id, steps);
4065 }
4066 else if (FUNCTIONP (it->font_height))
4067 {
4068 /* Call function with current height as argument.
4069 Value is the new height. */
4070 Lisp_Object height;
4071 height = safe_call1 (it->font_height,
4072 face->lface[LFACE_HEIGHT_INDEX]);
4073 if (NUMBERP (height))
4074 new_height = XFLOATINT (height);
4075 }
4076 else if (NUMBERP (it->font_height))
4077 {
4078 /* Value is a multiple of the canonical char height. */
4079 struct face *f;
4080
4081 f = FACE_FROM_ID (it->f,
4082 lookup_basic_face (it->f, DEFAULT_FACE_ID));
4083 new_height = (XFLOATINT (it->font_height)
4084 * XINT (f->lface[LFACE_HEIGHT_INDEX]));
4085 }
4086 else
4087 {
4088 /* Evaluate IT->font_height with `height' bound to the
4089 current specified height to get the new height. */
4090 int count = SPECPDL_INDEX ();
4091
4092 specbind (Qheight, face->lface[LFACE_HEIGHT_INDEX]);
4093 value = safe_eval (it->font_height);
4094 unbind_to (count, Qnil);
4095
4096 if (NUMBERP (value))
4097 new_height = XFLOATINT (value);
4098 }
4099
4100 if (new_height > 0)
4101 it->face_id = face_with_height (it->f, it->face_id, new_height);
4102 }
4103 }
4104
4105 return 0;
4106 }
4107
4108 /* Handle `(space-width WIDTH)'. */
4109 if (CONSP (spec)
4110 && EQ (XCAR (spec), Qspace_width)
4111 && CONSP (XCDR (spec)))
4112 {
4113 if (it)
4114 {
4115 if (!FRAME_WINDOW_P (it->f))
4116 return 0;
4117
4118 value = XCAR (XCDR (spec));
4119 if (NUMBERP (value) && XFLOATINT (value) > 0)
4120 it->space_width = value;
4121 }
4122
4123 return 0;
4124 }
4125
4126 /* Handle `(slice X Y WIDTH HEIGHT)'. */
4127 if (CONSP (spec)
4128 && EQ (XCAR (spec), Qslice))
4129 {
4130 Lisp_Object tem;
4131
4132 if (it)
4133 {
4134 if (!FRAME_WINDOW_P (it->f))
4135 return 0;
4136
4137 if (tem = XCDR (spec), CONSP (tem))
4138 {
4139 it->slice.x = XCAR (tem);
4140 if (tem = XCDR (tem), CONSP (tem))
4141 {
4142 it->slice.y = XCAR (tem);
4143 if (tem = XCDR (tem), CONSP (tem))
4144 {
4145 it->slice.width = XCAR (tem);
4146 if (tem = XCDR (tem), CONSP (tem))
4147 it->slice.height = XCAR (tem);
4148 }
4149 }
4150 }
4151 }
4152
4153 return 0;
4154 }
4155
4156 /* Handle `(raise FACTOR)'. */
4157 if (CONSP (spec)
4158 && EQ (XCAR (spec), Qraise)
4159 && CONSP (XCDR (spec)))
4160 {
4161 if (it)
4162 {
4163 if (!FRAME_WINDOW_P (it->f))
4164 return 0;
4165
4166 #ifdef HAVE_WINDOW_SYSTEM
4167 value = XCAR (XCDR (spec));
4168 if (NUMBERP (value))
4169 {
4170 struct face *face = FACE_FROM_ID (it->f, it->face_id);
4171 it->voffset = - (XFLOATINT (value)
4172 * (FONT_HEIGHT (face->font)));
4173 }
4174 #endif /* HAVE_WINDOW_SYSTEM */
4175 }
4176
4177 return 0;
4178 }
4179
4180 /* Don't handle the other kinds of display specifications
4181 inside a string that we got from a `display' property. */
4182 if (it && it->string_from_display_prop_p)
4183 return 0;
4184
4185 /* Characters having this form of property are not displayed, so
4186 we have to find the end of the property. */
4187 if (it)
4188 {
4189 start_pos = *position;
4190 *position = display_prop_end (it, object, start_pos);
4191 }
4192 value = Qnil;
4193
4194 /* Stop the scan at that end position--we assume that all
4195 text properties change there. */
4196 if (it)
4197 it->stop_charpos = position->charpos;
4198
4199 /* Handle `(left-fringe BITMAP [FACE])'
4200 and `(right-fringe BITMAP [FACE])'. */
4201 if (CONSP (spec)
4202 && (EQ (XCAR (spec), Qleft_fringe)
4203 || EQ (XCAR (spec), Qright_fringe))
4204 && CONSP (XCDR (spec)))
4205 {
4206 int fringe_bitmap;
4207
4208 if (it)
4209 {
4210 if (!FRAME_WINDOW_P (it->f))
4211 /* If we return here, POSITION has been advanced
4212 across the text with this property. */
4213 return 0;
4214 }
4215 else if (!frame_window_p)
4216 return 0;
4217
4218 #ifdef HAVE_WINDOW_SYSTEM
4219 value = XCAR (XCDR (spec));
4220 if (!SYMBOLP (value)
4221 || !(fringe_bitmap = lookup_fringe_bitmap (value)))
4222 /* If we return here, POSITION has been advanced
4223 across the text with this property. */
4224 return 0;
4225
4226 if (it)
4227 {
4228 int face_id = lookup_basic_face (it->f, DEFAULT_FACE_ID);;
4229
4230 if (CONSP (XCDR (XCDR (spec))))
4231 {
4232 Lisp_Object face_name = XCAR (XCDR (XCDR (spec)));
4233 int face_id2 = lookup_derived_face (it->f, face_name,
4234 FRINGE_FACE_ID, 0);
4235 if (face_id2 >= 0)
4236 face_id = face_id2;
4237 }
4238
4239 /* Save current settings of IT so that we can restore them
4240 when we are finished with the glyph property value. */
4241 push_it (it, position);
4242
4243 it->area = TEXT_AREA;
4244 it->what = IT_IMAGE;
4245 it->image_id = -1; /* no image */
4246 it->position = start_pos;
4247 it->object = NILP (object) ? it->w->buffer : object;
4248 it->method = GET_FROM_IMAGE;
4249 it->from_overlay = Qnil;
4250 it->face_id = face_id;
4251
4252 /* Say that we haven't consumed the characters with
4253 `display' property yet. The call to pop_it in
4254 set_iterator_to_next will clean this up. */
4255 *position = start_pos;
4256
4257 if (EQ (XCAR (spec), Qleft_fringe))
4258 {
4259 it->left_user_fringe_bitmap = fringe_bitmap;
4260 it->left_user_fringe_face_id = face_id;
4261 }
4262 else
4263 {
4264 it->right_user_fringe_bitmap = fringe_bitmap;
4265 it->right_user_fringe_face_id = face_id;
4266 }
4267 }
4268 #endif /* HAVE_WINDOW_SYSTEM */
4269 return 1;
4270 }
4271
4272 /* Prepare to handle `((margin left-margin) ...)',
4273 `((margin right-margin) ...)' and `((margin nil) ...)'
4274 prefixes for display specifications. */
4275 location = Qunbound;
4276 if (CONSP (spec) && CONSP (XCAR (spec)))
4277 {
4278 Lisp_Object tem;
4279
4280 value = XCDR (spec);
4281 if (CONSP (value))
4282 value = XCAR (value);
4283
4284 tem = XCAR (spec);
4285 if (EQ (XCAR (tem), Qmargin)
4286 && (tem = XCDR (tem),
4287 tem = CONSP (tem) ? XCAR (tem) : Qnil,
4288 (NILP (tem)
4289 || EQ (tem, Qleft_margin)
4290 || EQ (tem, Qright_margin))))
4291 location = tem;
4292 }
4293
4294 if (EQ (location, Qunbound))
4295 {
4296 location = Qnil;
4297 value = spec;
4298 }
4299
4300 /* After this point, VALUE is the property after any
4301 margin prefix has been stripped. It must be a string,
4302 an image specification, or `(space ...)'.
4303
4304 LOCATION specifies where to display: `left-margin',
4305 `right-margin' or nil. */
4306
4307 valid_p = (STRINGP (value)
4308 #ifdef HAVE_WINDOW_SYSTEM
4309 || ((it ? FRAME_WINDOW_P (it->f) : frame_window_p)
4310 && valid_image_p (value))
4311 #endif /* not HAVE_WINDOW_SYSTEM */
4312 || (CONSP (value) && EQ (XCAR (value), Qspace)));
4313
4314 if (valid_p && !display_replaced_p)
4315 {
4316 if (!it)
4317 return 1;
4318
4319 /* Save current settings of IT so that we can restore them
4320 when we are finished with the glyph property value. */
4321 push_it (it, position);
4322 it->from_overlay = overlay;
4323
4324 if (NILP (location))
4325 it->area = TEXT_AREA;
4326 else if (EQ (location, Qleft_margin))
4327 it->area = LEFT_MARGIN_AREA;
4328 else
4329 it->area = RIGHT_MARGIN_AREA;
4330
4331 if (STRINGP (value))
4332 {
4333 it->string = value;
4334 it->multibyte_p = STRING_MULTIBYTE (it->string);
4335 it->current.overlay_string_index = -1;
4336 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
4337 it->end_charpos = it->string_nchars = SCHARS (it->string);
4338 it->method = GET_FROM_STRING;
4339 it->stop_charpos = 0;
4340 it->string_from_display_prop_p = 1;
4341 /* Say that we haven't consumed the characters with
4342 `display' property yet. The call to pop_it in
4343 set_iterator_to_next will clean this up. */
4344 if (BUFFERP (object))
4345 *position = start_pos;
4346 }
4347 else if (CONSP (value) && EQ (XCAR (value), Qspace))
4348 {
4349 it->method = GET_FROM_STRETCH;
4350 it->object = value;
4351 *position = it->position = start_pos;
4352 }
4353 #ifdef HAVE_WINDOW_SYSTEM
4354 else
4355 {
4356 it->what = IT_IMAGE;
4357 it->image_id = lookup_image (it->f, value);
4358 it->position = start_pos;
4359 it->object = NILP (object) ? it->w->buffer : object;
4360 it->method = GET_FROM_IMAGE;
4361
4362 /* Say that we haven't consumed the characters with
4363 `display' property yet. The call to pop_it in
4364 set_iterator_to_next will clean this up. */
4365 *position = start_pos;
4366 }
4367 #endif /* HAVE_WINDOW_SYSTEM */
4368
4369 return 1;
4370 }
4371
4372 /* Invalid property or property not supported. Restore
4373 POSITION to what it was before. */
4374 *position = start_pos;
4375 return 0;
4376 }
4377
4378
4379 /* Check if SPEC is a display sub-property value whose text should be
4380 treated as intangible. */
4381
4382 static int
4383 single_display_spec_intangible_p (Lisp_Object prop)
4384 {
4385 /* Skip over `when FORM'. */
4386 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
4387 {
4388 prop = XCDR (prop);
4389 if (!CONSP (prop))
4390 return 0;
4391 prop = XCDR (prop);
4392 }
4393
4394 if (STRINGP (prop))
4395 return 1;
4396
4397 if (!CONSP (prop))
4398 return 0;
4399
4400 /* Skip over `margin LOCATION'. If LOCATION is in the margins,
4401 we don't need to treat text as intangible. */
4402 if (EQ (XCAR (prop), Qmargin))
4403 {
4404 prop = XCDR (prop);
4405 if (!CONSP (prop))
4406 return 0;
4407
4408 prop = XCDR (prop);
4409 if (!CONSP (prop)
4410 || EQ (XCAR (prop), Qleft_margin)
4411 || EQ (XCAR (prop), Qright_margin))
4412 return 0;
4413 }
4414
4415 return (CONSP (prop)
4416 && (EQ (XCAR (prop), Qimage)
4417 || EQ (XCAR (prop), Qspace)));
4418 }
4419
4420
4421 /* Check if PROP is a display property value whose text should be
4422 treated as intangible. */
4423
4424 int
4425 display_prop_intangible_p (Lisp_Object prop)
4426 {
4427 if (CONSP (prop)
4428 && CONSP (XCAR (prop))
4429 && !EQ (Qmargin, XCAR (XCAR (prop))))
4430 {
4431 /* A list of sub-properties. */
4432 while (CONSP (prop))
4433 {
4434 if (single_display_spec_intangible_p (XCAR (prop)))
4435 return 1;
4436 prop = XCDR (prop);
4437 }
4438 }
4439 else if (VECTORP (prop))
4440 {
4441 /* A vector of sub-properties. */
4442 int i;
4443 for (i = 0; i < ASIZE (prop); ++i)
4444 if (single_display_spec_intangible_p (AREF (prop, i)))
4445 return 1;
4446 }
4447 else
4448 return single_display_spec_intangible_p (prop);
4449
4450 return 0;
4451 }
4452
4453
4454 /* Return 1 if PROP is a display sub-property value containing STRING. */
4455
4456 static int
4457 single_display_spec_string_p (Lisp_Object prop, Lisp_Object string)
4458 {
4459 if (EQ (string, prop))
4460 return 1;
4461
4462 /* Skip over `when FORM'. */
4463 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
4464 {
4465 prop = XCDR (prop);
4466 if (!CONSP (prop))
4467 return 0;
4468 prop = XCDR (prop);
4469 }
4470
4471 if (CONSP (prop))
4472 /* Skip over `margin LOCATION'. */
4473 if (EQ (XCAR (prop), Qmargin))
4474 {
4475 prop = XCDR (prop);
4476 if (!CONSP (prop))
4477 return 0;
4478
4479 prop = XCDR (prop);
4480 if (!CONSP (prop))
4481 return 0;
4482 }
4483
4484 return CONSP (prop) && EQ (XCAR (prop), string);
4485 }
4486
4487
4488 /* Return 1 if STRING appears in the `display' property PROP. */
4489
4490 static int
4491 display_prop_string_p (Lisp_Object prop, Lisp_Object string)
4492 {
4493 if (CONSP (prop)
4494 && CONSP (XCAR (prop))
4495 && !EQ (Qmargin, XCAR (XCAR (prop))))
4496 {
4497 /* A list of sub-properties. */
4498 while (CONSP (prop))
4499 {
4500 if (single_display_spec_string_p (XCAR (prop), string))
4501 return 1;
4502 prop = XCDR (prop);
4503 }
4504 }
4505 else if (VECTORP (prop))
4506 {
4507 /* A vector of sub-properties. */
4508 int i;
4509 for (i = 0; i < ASIZE (prop); ++i)
4510 if (single_display_spec_string_p (AREF (prop, i), string))
4511 return 1;
4512 }
4513 else
4514 return single_display_spec_string_p (prop, string);
4515
4516 return 0;
4517 }
4518
4519 /* Look for STRING in overlays and text properties in the current
4520 buffer, between character positions FROM and TO (excluding TO).
4521 BACK_P non-zero means look back (in this case, TO is supposed to be
4522 less than FROM).
4523 Value is the first character position where STRING was found, or
4524 zero if it wasn't found before hitting TO.
4525
4526 This function may only use code that doesn't eval because it is
4527 called asynchronously from note_mouse_highlight. */
4528
4529 static EMACS_INT
4530 string_buffer_position_lim (Lisp_Object string,
4531 EMACS_INT from, EMACS_INT to, int back_p)
4532 {
4533 Lisp_Object limit, prop, pos;
4534 int found = 0;
4535
4536 pos = make_number (from);
4537
4538 if (!back_p) /* looking forward */
4539 {
4540 limit = make_number (min (to, ZV));
4541 while (!found && !EQ (pos, limit))
4542 {
4543 prop = Fget_char_property (pos, Qdisplay, Qnil);
4544 if (!NILP (prop) && display_prop_string_p (prop, string))
4545 found = 1;
4546 else
4547 pos = Fnext_single_char_property_change (pos, Qdisplay, Qnil,
4548 limit);
4549 }
4550 }
4551 else /* looking back */
4552 {
4553 limit = make_number (max (to, BEGV));
4554 while (!found && !EQ (pos, limit))
4555 {
4556 prop = Fget_char_property (pos, Qdisplay, Qnil);
4557 if (!NILP (prop) && display_prop_string_p (prop, string))
4558 found = 1;
4559 else
4560 pos = Fprevious_single_char_property_change (pos, Qdisplay, Qnil,
4561 limit);
4562 }
4563 }
4564
4565 return found ? XINT (pos) : 0;
4566 }
4567
4568 /* Determine which buffer position in current buffer STRING comes from.
4569 AROUND_CHARPOS is an approximate position where it could come from.
4570 Value is the buffer position or 0 if it couldn't be determined.
4571
4572 This function is necessary because we don't record buffer positions
4573 in glyphs generated from strings (to keep struct glyph small).
4574 This function may only use code that doesn't eval because it is
4575 called asynchronously from note_mouse_highlight. */
4576
4577 static EMACS_INT
4578 string_buffer_position (Lisp_Object string, EMACS_INT around_charpos)
4579 {
4580 const int MAX_DISTANCE = 1000;
4581 EMACS_INT found = string_buffer_position_lim (string, around_charpos,
4582 around_charpos + MAX_DISTANCE,
4583 0);
4584
4585 if (!found)
4586 found = string_buffer_position_lim (string, around_charpos,
4587 around_charpos - MAX_DISTANCE, 1);
4588 return found;
4589 }
4590
4591
4592 \f
4593 /***********************************************************************
4594 `composition' property
4595 ***********************************************************************/
4596
4597 /* Set up iterator IT from `composition' property at its current
4598 position. Called from handle_stop. */
4599
4600 static enum prop_handled
4601 handle_composition_prop (struct it *it)
4602 {
4603 Lisp_Object prop, string;
4604 EMACS_INT pos, pos_byte, start, end;
4605
4606 if (STRINGP (it->string))
4607 {
4608 unsigned char *s;
4609
4610 pos = IT_STRING_CHARPOS (*it);
4611 pos_byte = IT_STRING_BYTEPOS (*it);
4612 string = it->string;
4613 s = SDATA (string) + pos_byte;
4614 it->c = STRING_CHAR (s);
4615 }
4616 else
4617 {
4618 pos = IT_CHARPOS (*it);
4619 pos_byte = IT_BYTEPOS (*it);
4620 string = Qnil;
4621 it->c = FETCH_CHAR (pos_byte);
4622 }
4623
4624 /* If there's a valid composition and point is not inside of the
4625 composition (in the case that the composition is from the current
4626 buffer), draw a glyph composed from the composition components. */
4627 if (find_composition (pos, -1, &start, &end, &prop, string)
4628 && COMPOSITION_VALID_P (start, end, prop)
4629 && (STRINGP (it->string) || (PT <= start || PT >= end)))
4630 {
4631 if (start != pos)
4632 {
4633 if (STRINGP (it->string))
4634 pos_byte = string_char_to_byte (it->string, start);
4635 else
4636 pos_byte = CHAR_TO_BYTE (start);
4637 }
4638 it->cmp_it.id = get_composition_id (start, pos_byte, end - start,
4639 prop, string);
4640
4641 if (it->cmp_it.id >= 0)
4642 {
4643 it->cmp_it.ch = -1;
4644 it->cmp_it.nchars = COMPOSITION_LENGTH (prop);
4645 it->cmp_it.nglyphs = -1;
4646 }
4647 }
4648
4649 return HANDLED_NORMALLY;
4650 }
4651
4652
4653 \f
4654 /***********************************************************************
4655 Overlay strings
4656 ***********************************************************************/
4657
4658 /* The following structure is used to record overlay strings for
4659 later sorting in load_overlay_strings. */
4660
4661 struct overlay_entry
4662 {
4663 Lisp_Object overlay;
4664 Lisp_Object string;
4665 int priority;
4666 int after_string_p;
4667 };
4668
4669
4670 /* Set up iterator IT from overlay strings at its current position.
4671 Called from handle_stop. */
4672
4673 static enum prop_handled
4674 handle_overlay_change (struct it *it)
4675 {
4676 if (!STRINGP (it->string) && get_overlay_strings (it, 0))
4677 return HANDLED_RECOMPUTE_PROPS;
4678 else
4679 return HANDLED_NORMALLY;
4680 }
4681
4682
4683 /* Set up the next overlay string for delivery by IT, if there is an
4684 overlay string to deliver. Called by set_iterator_to_next when the
4685 end of the current overlay string is reached. If there are more
4686 overlay strings to display, IT->string and
4687 IT->current.overlay_string_index are set appropriately here.
4688 Otherwise IT->string is set to nil. */
4689
4690 static void
4691 next_overlay_string (struct it *it)
4692 {
4693 ++it->current.overlay_string_index;
4694 if (it->current.overlay_string_index == it->n_overlay_strings)
4695 {
4696 /* No more overlay strings. Restore IT's settings to what
4697 they were before overlay strings were processed, and
4698 continue to deliver from current_buffer. */
4699
4700 it->ellipsis_p = (it->stack[it->sp - 1].display_ellipsis_p != 0);
4701 pop_it (it);
4702 xassert (it->sp > 0
4703 || (NILP (it->string)
4704 && it->method == GET_FROM_BUFFER
4705 && it->stop_charpos >= BEGV
4706 && it->stop_charpos <= it->end_charpos));
4707 it->current.overlay_string_index = -1;
4708 it->n_overlay_strings = 0;
4709 it->overlay_strings_charpos = -1;
4710
4711 /* If we're at the end of the buffer, record that we have
4712 processed the overlay strings there already, so that
4713 next_element_from_buffer doesn't try it again. */
4714 if (NILP (it->string) && IT_CHARPOS (*it) >= it->end_charpos)
4715 it->overlay_strings_at_end_processed_p = 1;
4716 }
4717 else
4718 {
4719 /* There are more overlay strings to process. If
4720 IT->current.overlay_string_index has advanced to a position
4721 where we must load IT->overlay_strings with more strings, do
4722 it. We must load at the IT->overlay_strings_charpos where
4723 IT->n_overlay_strings was originally computed; when invisible
4724 text is present, this might not be IT_CHARPOS (Bug#7016). */
4725 int i = it->current.overlay_string_index % OVERLAY_STRING_CHUNK_SIZE;
4726
4727 if (it->current.overlay_string_index && i == 0)
4728 load_overlay_strings (it, it->overlay_strings_charpos);
4729
4730 /* Initialize IT to deliver display elements from the overlay
4731 string. */
4732 it->string = it->overlay_strings[i];
4733 it->multibyte_p = STRING_MULTIBYTE (it->string);
4734 SET_TEXT_POS (it->current.string_pos, 0, 0);
4735 it->method = GET_FROM_STRING;
4736 it->stop_charpos = 0;
4737 if (it->cmp_it.stop_pos >= 0)
4738 it->cmp_it.stop_pos = 0;
4739 }
4740
4741 CHECK_IT (it);
4742 }
4743
4744
4745 /* Compare two overlay_entry structures E1 and E2. Used as a
4746 comparison function for qsort in load_overlay_strings. Overlay
4747 strings for the same position are sorted so that
4748
4749 1. All after-strings come in front of before-strings, except
4750 when they come from the same overlay.
4751
4752 2. Within after-strings, strings are sorted so that overlay strings
4753 from overlays with higher priorities come first.
4754
4755 2. Within before-strings, strings are sorted so that overlay
4756 strings from overlays with higher priorities come last.
4757
4758 Value is analogous to strcmp. */
4759
4760
4761 static int
4762 compare_overlay_entries (const void *e1, const void *e2)
4763 {
4764 struct overlay_entry *entry1 = (struct overlay_entry *) e1;
4765 struct overlay_entry *entry2 = (struct overlay_entry *) e2;
4766 int result;
4767
4768 if (entry1->after_string_p != entry2->after_string_p)
4769 {
4770 /* Let after-strings appear in front of before-strings if
4771 they come from different overlays. */
4772 if (EQ (entry1->overlay, entry2->overlay))
4773 result = entry1->after_string_p ? 1 : -1;
4774 else
4775 result = entry1->after_string_p ? -1 : 1;
4776 }
4777 else if (entry1->after_string_p)
4778 /* After-strings sorted in order of decreasing priority. */
4779 result = entry2->priority - entry1->priority;
4780 else
4781 /* Before-strings sorted in order of increasing priority. */
4782 result = entry1->priority - entry2->priority;
4783
4784 return result;
4785 }
4786
4787
4788 /* Load the vector IT->overlay_strings with overlay strings from IT's
4789 current buffer position, or from CHARPOS if that is > 0. Set
4790 IT->n_overlays to the total number of overlay strings found.
4791
4792 Overlay strings are processed OVERLAY_STRING_CHUNK_SIZE strings at
4793 a time. On entry into load_overlay_strings,
4794 IT->current.overlay_string_index gives the number of overlay
4795 strings that have already been loaded by previous calls to this
4796 function.
4797
4798 IT->add_overlay_start contains an additional overlay start
4799 position to consider for taking overlay strings from, if non-zero.
4800 This position comes into play when the overlay has an `invisible'
4801 property, and both before and after-strings. When we've skipped to
4802 the end of the overlay, because of its `invisible' property, we
4803 nevertheless want its before-string to appear.
4804 IT->add_overlay_start will contain the overlay start position
4805 in this case.
4806
4807 Overlay strings are sorted so that after-string strings come in
4808 front of before-string strings. Within before and after-strings,
4809 strings are sorted by overlay priority. See also function
4810 compare_overlay_entries. */
4811
4812 static void
4813 load_overlay_strings (struct it *it, EMACS_INT charpos)
4814 {
4815 Lisp_Object overlay, window, str, invisible;
4816 struct Lisp_Overlay *ov;
4817 EMACS_INT start, end;
4818 int size = 20;
4819 int n = 0, i, j, invis_p;
4820 struct overlay_entry *entries
4821 = (struct overlay_entry *) alloca (size * sizeof *entries);
4822
4823 if (charpos <= 0)
4824 charpos = IT_CHARPOS (*it);
4825
4826 /* Append the overlay string STRING of overlay OVERLAY to vector
4827 `entries' which has size `size' and currently contains `n'
4828 elements. AFTER_P non-zero means STRING is an after-string of
4829 OVERLAY. */
4830 #define RECORD_OVERLAY_STRING(OVERLAY, STRING, AFTER_P) \
4831 do \
4832 { \
4833 Lisp_Object priority; \
4834 \
4835 if (n == size) \
4836 { \
4837 int new_size = 2 * size; \
4838 struct overlay_entry *old = entries; \
4839 entries = \
4840 (struct overlay_entry *) alloca (new_size \
4841 * sizeof *entries); \
4842 memcpy (entries, old, size * sizeof *entries); \
4843 size = new_size; \
4844 } \
4845 \
4846 entries[n].string = (STRING); \
4847 entries[n].overlay = (OVERLAY); \
4848 priority = Foverlay_get ((OVERLAY), Qpriority); \
4849 entries[n].priority = INTEGERP (priority) ? XINT (priority) : 0; \
4850 entries[n].after_string_p = (AFTER_P); \
4851 ++n; \
4852 } \
4853 while (0)
4854
4855 /* Process overlay before the overlay center. */
4856 for (ov = current_buffer->overlays_before; ov; ov = ov->next)
4857 {
4858 XSETMISC (overlay, ov);
4859 xassert (OVERLAYP (overlay));
4860 start = OVERLAY_POSITION (OVERLAY_START (overlay));
4861 end = OVERLAY_POSITION (OVERLAY_END (overlay));
4862
4863 if (end < charpos)
4864 break;
4865
4866 /* Skip this overlay if it doesn't start or end at IT's current
4867 position. */
4868 if (end != charpos && start != charpos)
4869 continue;
4870
4871 /* Skip this overlay if it doesn't apply to IT->w. */
4872 window = Foverlay_get (overlay, Qwindow);
4873 if (WINDOWP (window) && XWINDOW (window) != it->w)
4874 continue;
4875
4876 /* If the text ``under'' the overlay is invisible, both before-
4877 and after-strings from this overlay are visible; start and
4878 end position are indistinguishable. */
4879 invisible = Foverlay_get (overlay, Qinvisible);
4880 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
4881
4882 /* If overlay has a non-empty before-string, record it. */
4883 if ((start == charpos || (end == charpos && invis_p))
4884 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
4885 && SCHARS (str))
4886 RECORD_OVERLAY_STRING (overlay, str, 0);
4887
4888 /* If overlay has a non-empty after-string, record it. */
4889 if ((end == charpos || (start == charpos && invis_p))
4890 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
4891 && SCHARS (str))
4892 RECORD_OVERLAY_STRING (overlay, str, 1);
4893 }
4894
4895 /* Process overlays after the overlay center. */
4896 for (ov = current_buffer->overlays_after; ov; ov = ov->next)
4897 {
4898 XSETMISC (overlay, ov);
4899 xassert (OVERLAYP (overlay));
4900 start = OVERLAY_POSITION (OVERLAY_START (overlay));
4901 end = OVERLAY_POSITION (OVERLAY_END (overlay));
4902
4903 if (start > charpos)
4904 break;
4905
4906 /* Skip this overlay if it doesn't start or end at IT's current
4907 position. */
4908 if (end != charpos && start != charpos)
4909 continue;
4910
4911 /* Skip this overlay if it doesn't apply to IT->w. */
4912 window = Foverlay_get (overlay, Qwindow);
4913 if (WINDOWP (window) && XWINDOW (window) != it->w)
4914 continue;
4915
4916 /* If the text ``under'' the overlay is invisible, it has a zero
4917 dimension, and both before- and after-strings apply. */
4918 invisible = Foverlay_get (overlay, Qinvisible);
4919 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
4920
4921 /* If overlay has a non-empty before-string, record it. */
4922 if ((start == charpos || (end == charpos && invis_p))
4923 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
4924 && SCHARS (str))
4925 RECORD_OVERLAY_STRING (overlay, str, 0);
4926
4927 /* If overlay has a non-empty after-string, record it. */
4928 if ((end == charpos || (start == charpos && invis_p))
4929 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
4930 && SCHARS (str))
4931 RECORD_OVERLAY_STRING (overlay, str, 1);
4932 }
4933
4934 #undef RECORD_OVERLAY_STRING
4935
4936 /* Sort entries. */
4937 if (n > 1)
4938 qsort (entries, n, sizeof *entries, compare_overlay_entries);
4939
4940 /* Record number of overlay strings, and where we computed it. */
4941 it->n_overlay_strings = n;
4942 it->overlay_strings_charpos = charpos;
4943
4944 /* IT->current.overlay_string_index is the number of overlay strings
4945 that have already been consumed by IT. Copy some of the
4946 remaining overlay strings to IT->overlay_strings. */
4947 i = 0;
4948 j = it->current.overlay_string_index;
4949 while (i < OVERLAY_STRING_CHUNK_SIZE && j < n)
4950 {
4951 it->overlay_strings[i] = entries[j].string;
4952 it->string_overlays[i++] = entries[j++].overlay;
4953 }
4954
4955 CHECK_IT (it);
4956 }
4957
4958
4959 /* Get the first chunk of overlay strings at IT's current buffer
4960 position, or at CHARPOS if that is > 0. Value is non-zero if at
4961 least one overlay string was found. */
4962
4963 static int
4964 get_overlay_strings_1 (struct it *it, EMACS_INT charpos, int compute_stop_p)
4965 {
4966 /* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to
4967 process. This fills IT->overlay_strings with strings, and sets
4968 IT->n_overlay_strings to the total number of strings to process.
4969 IT->pos.overlay_string_index has to be set temporarily to zero
4970 because load_overlay_strings needs this; it must be set to -1
4971 when no overlay strings are found because a zero value would
4972 indicate a position in the first overlay string. */
4973 it->current.overlay_string_index = 0;
4974 load_overlay_strings (it, charpos);
4975
4976 /* If we found overlay strings, set up IT to deliver display
4977 elements from the first one. Otherwise set up IT to deliver
4978 from current_buffer. */
4979 if (it->n_overlay_strings)
4980 {
4981 /* Make sure we know settings in current_buffer, so that we can
4982 restore meaningful values when we're done with the overlay
4983 strings. */
4984 if (compute_stop_p)
4985 compute_stop_pos (it);
4986 xassert (it->face_id >= 0);
4987
4988 /* Save IT's settings. They are restored after all overlay
4989 strings have been processed. */
4990 xassert (!compute_stop_p || it->sp == 0);
4991
4992 /* When called from handle_stop, there might be an empty display
4993 string loaded. In that case, don't bother saving it. */
4994 if (!STRINGP (it->string) || SCHARS (it->string))
4995 push_it (it, NULL);
4996
4997 /* Set up IT to deliver display elements from the first overlay
4998 string. */
4999 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
5000 it->string = it->overlay_strings[0];
5001 it->from_overlay = Qnil;
5002 it->stop_charpos = 0;
5003 xassert (STRINGP (it->string));
5004 it->end_charpos = SCHARS (it->string);
5005 it->multibyte_p = STRING_MULTIBYTE (it->string);
5006 it->method = GET_FROM_STRING;
5007 return 1;
5008 }
5009
5010 it->current.overlay_string_index = -1;
5011 return 0;
5012 }
5013
5014 static int
5015 get_overlay_strings (struct it *it, EMACS_INT charpos)
5016 {
5017 it->string = Qnil;
5018 it->method = GET_FROM_BUFFER;
5019
5020 (void) get_overlay_strings_1 (it, charpos, 1);
5021
5022 CHECK_IT (it);
5023
5024 /* Value is non-zero if we found at least one overlay string. */
5025 return STRINGP (it->string);
5026 }
5027
5028
5029 \f
5030 /***********************************************************************
5031 Saving and restoring state
5032 ***********************************************************************/
5033
5034 /* Save current settings of IT on IT->stack. Called, for example,
5035 before setting up IT for an overlay string, to be able to restore
5036 IT's settings to what they were after the overlay string has been
5037 processed. If POSITION is non-NULL, it is the position to save on
5038 the stack instead of IT->position. */
5039
5040 static void
5041 push_it (struct it *it, struct text_pos *position)
5042 {
5043 struct iterator_stack_entry *p;
5044
5045 xassert (it->sp < IT_STACK_SIZE);
5046 p = it->stack + it->sp;
5047
5048 p->stop_charpos = it->stop_charpos;
5049 p->prev_stop = it->prev_stop;
5050 p->base_level_stop = it->base_level_stop;
5051 p->cmp_it = it->cmp_it;
5052 xassert (it->face_id >= 0);
5053 p->face_id = it->face_id;
5054 p->string = it->string;
5055 p->method = it->method;
5056 p->from_overlay = it->from_overlay;
5057 switch (p->method)
5058 {
5059 case GET_FROM_IMAGE:
5060 p->u.image.object = it->object;
5061 p->u.image.image_id = it->image_id;
5062 p->u.image.slice = it->slice;
5063 break;
5064 case GET_FROM_STRETCH:
5065 p->u.stretch.object = it->object;
5066 break;
5067 }
5068 p->position = position ? *position : it->position;
5069 p->current = it->current;
5070 p->end_charpos = it->end_charpos;
5071 p->string_nchars = it->string_nchars;
5072 p->area = it->area;
5073 p->multibyte_p = it->multibyte_p;
5074 p->avoid_cursor_p = it->avoid_cursor_p;
5075 p->space_width = it->space_width;
5076 p->font_height = it->font_height;
5077 p->voffset = it->voffset;
5078 p->string_from_display_prop_p = it->string_from_display_prop_p;
5079 p->display_ellipsis_p = 0;
5080 p->line_wrap = it->line_wrap;
5081 ++it->sp;
5082 }
5083
5084 static void
5085 iterate_out_of_display_property (struct it *it)
5086 {
5087 /* Maybe initialize paragraph direction. If we are at the beginning
5088 of a new paragraph, next_element_from_buffer may not have a
5089 chance to do that. */
5090 if (it->bidi_it.first_elt && it->bidi_it.charpos < ZV)
5091 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1);
5092 /* prev_stop can be zero, so check against BEGV as well. */
5093 while (it->bidi_it.charpos >= BEGV
5094 && it->prev_stop <= it->bidi_it.charpos
5095 && it->bidi_it.charpos < CHARPOS (it->position))
5096 bidi_move_to_visually_next (&it->bidi_it);
5097 /* Record the stop_pos we just crossed, for when we cross it
5098 back, maybe. */
5099 if (it->bidi_it.charpos > CHARPOS (it->position))
5100 it->prev_stop = CHARPOS (it->position);
5101 /* If we ended up not where pop_it put us, resync IT's
5102 positional members with the bidi iterator. */
5103 if (it->bidi_it.charpos != CHARPOS (it->position))
5104 {
5105 SET_TEXT_POS (it->position,
5106 it->bidi_it.charpos, it->bidi_it.bytepos);
5107 it->current.pos = it->position;
5108 }
5109 }
5110
5111 /* Restore IT's settings from IT->stack. Called, for example, when no
5112 more overlay strings must be processed, and we return to delivering
5113 display elements from a buffer, or when the end of a string from a
5114 `display' property is reached and we return to delivering display
5115 elements from an overlay string, or from a buffer. */
5116
5117 static void
5118 pop_it (struct it *it)
5119 {
5120 struct iterator_stack_entry *p;
5121
5122 xassert (it->sp > 0);
5123 --it->sp;
5124 p = it->stack + it->sp;
5125 it->stop_charpos = p->stop_charpos;
5126 it->prev_stop = p->prev_stop;
5127 it->base_level_stop = p->base_level_stop;
5128 it->cmp_it = p->cmp_it;
5129 it->face_id = p->face_id;
5130 it->current = p->current;
5131 it->position = p->position;
5132 it->string = p->string;
5133 it->from_overlay = p->from_overlay;
5134 if (NILP (it->string))
5135 SET_TEXT_POS (it->current.string_pos, -1, -1);
5136 it->method = p->method;
5137 switch (it->method)
5138 {
5139 case GET_FROM_IMAGE:
5140 it->image_id = p->u.image.image_id;
5141 it->object = p->u.image.object;
5142 it->slice = p->u.image.slice;
5143 break;
5144 case GET_FROM_STRETCH:
5145 it->object = p->u.comp.object;
5146 break;
5147 case GET_FROM_BUFFER:
5148 it->object = it->w->buffer;
5149 if (it->bidi_p)
5150 {
5151 /* Bidi-iterate until we get out of the portion of text, if
5152 any, covered by a `display' text property or an overlay
5153 with `display' property. (We cannot just jump there,
5154 because the internal coherency of the bidi iterator state
5155 can not be preserved across such jumps.) We also must
5156 determine the paragraph base direction if the overlay we
5157 just processed is at the beginning of a new
5158 paragraph. */
5159 iterate_out_of_display_property (it);
5160 }
5161 break;
5162 case GET_FROM_STRING:
5163 it->object = it->string;
5164 break;
5165 case GET_FROM_DISPLAY_VECTOR:
5166 if (it->s)
5167 it->method = GET_FROM_C_STRING;
5168 else if (STRINGP (it->string))
5169 it->method = GET_FROM_STRING;
5170 else
5171 {
5172 it->method = GET_FROM_BUFFER;
5173 it->object = it->w->buffer;
5174 }
5175 }
5176 it->end_charpos = p->end_charpos;
5177 it->string_nchars = p->string_nchars;
5178 it->area = p->area;
5179 it->multibyte_p = p->multibyte_p;
5180 it->avoid_cursor_p = p->avoid_cursor_p;
5181 it->space_width = p->space_width;
5182 it->font_height = p->font_height;
5183 it->voffset = p->voffset;
5184 it->string_from_display_prop_p = p->string_from_display_prop_p;
5185 it->line_wrap = p->line_wrap;
5186 }
5187
5188
5189 \f
5190 /***********************************************************************
5191 Moving over lines
5192 ***********************************************************************/
5193
5194 /* Set IT's current position to the previous line start. */
5195
5196 static void
5197 back_to_previous_line_start (struct it *it)
5198 {
5199 IT_CHARPOS (*it) = find_next_newline_no_quit (IT_CHARPOS (*it) - 1, -1);
5200 IT_BYTEPOS (*it) = CHAR_TO_BYTE (IT_CHARPOS (*it));
5201 }
5202
5203
5204 /* Move IT to the next line start.
5205
5206 Value is non-zero if a newline was found. Set *SKIPPED_P to 1 if
5207 we skipped over part of the text (as opposed to moving the iterator
5208 continuously over the text). Otherwise, don't change the value
5209 of *SKIPPED_P.
5210
5211 Newlines may come from buffer text, overlay strings, or strings
5212 displayed via the `display' property. That's the reason we can't
5213 simply use find_next_newline_no_quit.
5214
5215 Note that this function may not skip over invisible text that is so
5216 because of text properties and immediately follows a newline. If
5217 it would, function reseat_at_next_visible_line_start, when called
5218 from set_iterator_to_next, would effectively make invisible
5219 characters following a newline part of the wrong glyph row, which
5220 leads to wrong cursor motion. */
5221
5222 static int
5223 forward_to_next_line_start (struct it *it, int *skipped_p)
5224 {
5225 int old_selective, newline_found_p, n;
5226 const int MAX_NEWLINE_DISTANCE = 500;
5227
5228 /* If already on a newline, just consume it to avoid unintended
5229 skipping over invisible text below. */
5230 if (it->what == IT_CHARACTER
5231 && it->c == '\n'
5232 && CHARPOS (it->position) == IT_CHARPOS (*it))
5233 {
5234 set_iterator_to_next (it, 0);
5235 it->c = 0;
5236 return 1;
5237 }
5238
5239 /* Don't handle selective display in the following. It's (a)
5240 unnecessary because it's done by the caller, and (b) leads to an
5241 infinite recursion because next_element_from_ellipsis indirectly
5242 calls this function. */
5243 old_selective = it->selective;
5244 it->selective = 0;
5245
5246 /* Scan for a newline within MAX_NEWLINE_DISTANCE display elements
5247 from buffer text. */
5248 for (n = newline_found_p = 0;
5249 !newline_found_p && n < MAX_NEWLINE_DISTANCE;
5250 n += STRINGP (it->string) ? 0 : 1)
5251 {
5252 if (!get_next_display_element (it))
5253 return 0;
5254 newline_found_p = it->what == IT_CHARACTER && it->c == '\n';
5255 set_iterator_to_next (it, 0);
5256 }
5257
5258 /* If we didn't find a newline near enough, see if we can use a
5259 short-cut. */
5260 if (!newline_found_p)
5261 {
5262 EMACS_INT start = IT_CHARPOS (*it);
5263 EMACS_INT limit = find_next_newline_no_quit (start, 1);
5264 Lisp_Object pos;
5265
5266 xassert (!STRINGP (it->string));
5267
5268 /* If there isn't any `display' property in sight, and no
5269 overlays, we can just use the position of the newline in
5270 buffer text. */
5271 if (it->stop_charpos >= limit
5272 || ((pos = Fnext_single_property_change (make_number (start),
5273 Qdisplay,
5274 Qnil, make_number (limit)),
5275 NILP (pos))
5276 && next_overlay_change (start) == ZV))
5277 {
5278 IT_CHARPOS (*it) = limit;
5279 IT_BYTEPOS (*it) = CHAR_TO_BYTE (limit);
5280 *skipped_p = newline_found_p = 1;
5281 }
5282 else
5283 {
5284 while (get_next_display_element (it)
5285 && !newline_found_p)
5286 {
5287 newline_found_p = ITERATOR_AT_END_OF_LINE_P (it);
5288 set_iterator_to_next (it, 0);
5289 }
5290 }
5291 }
5292
5293 it->selective = old_selective;
5294 return newline_found_p;
5295 }
5296
5297
5298 /* Set IT's current position to the previous visible line start. Skip
5299 invisible text that is so either due to text properties or due to
5300 selective display. Caution: this does not change IT->current_x and
5301 IT->hpos. */
5302
5303 static void
5304 back_to_previous_visible_line_start (struct it *it)
5305 {
5306 while (IT_CHARPOS (*it) > BEGV)
5307 {
5308 back_to_previous_line_start (it);
5309
5310 if (IT_CHARPOS (*it) <= BEGV)
5311 break;
5312
5313 /* If selective > 0, then lines indented more than its value are
5314 invisible. */
5315 if (it->selective > 0
5316 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
5317 (double) it->selective)) /* iftc */
5318 continue;
5319
5320 /* Check the newline before point for invisibility. */
5321 {
5322 Lisp_Object prop;
5323 prop = Fget_char_property (make_number (IT_CHARPOS (*it) - 1),
5324 Qinvisible, it->window);
5325 if (TEXT_PROP_MEANS_INVISIBLE (prop))
5326 continue;
5327 }
5328
5329 if (IT_CHARPOS (*it) <= BEGV)
5330 break;
5331
5332 {
5333 struct it it2;
5334 EMACS_INT pos;
5335 EMACS_INT beg, end;
5336 Lisp_Object val, overlay;
5337
5338 /* If newline is part of a composition, continue from start of composition */
5339 if (find_composition (IT_CHARPOS (*it), -1, &beg, &end, &val, Qnil)
5340 && beg < IT_CHARPOS (*it))
5341 goto replaced;
5342
5343 /* If newline is replaced by a display property, find start of overlay
5344 or interval and continue search from that point. */
5345 it2 = *it;
5346 pos = --IT_CHARPOS (it2);
5347 --IT_BYTEPOS (it2);
5348 it2.sp = 0;
5349 it2.string_from_display_prop_p = 0;
5350 if (handle_display_prop (&it2) == HANDLED_RETURN
5351 && !NILP (val = get_char_property_and_overlay
5352 (make_number (pos), Qdisplay, Qnil, &overlay))
5353 && (OVERLAYP (overlay)
5354 ? (beg = OVERLAY_POSITION (OVERLAY_START (overlay)))
5355 : get_property_and_range (pos, Qdisplay, &val, &beg, &end, Qnil)))
5356 goto replaced;
5357
5358 /* Newline is not replaced by anything -- so we are done. */
5359 break;
5360
5361 replaced:
5362 if (beg < BEGV)
5363 beg = BEGV;
5364 IT_CHARPOS (*it) = beg;
5365 IT_BYTEPOS (*it) = buf_charpos_to_bytepos (current_buffer, beg);
5366 }
5367 }
5368
5369 it->continuation_lines_width = 0;
5370
5371 xassert (IT_CHARPOS (*it) >= BEGV);
5372 xassert (IT_CHARPOS (*it) == BEGV
5373 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
5374 CHECK_IT (it);
5375 }
5376
5377
5378 /* Reseat iterator IT at the previous visible line start. Skip
5379 invisible text that is so either due to text properties or due to
5380 selective display. At the end, update IT's overlay information,
5381 face information etc. */
5382
5383 void
5384 reseat_at_previous_visible_line_start (struct it *it)
5385 {
5386 back_to_previous_visible_line_start (it);
5387 reseat (it, it->current.pos, 1);
5388 CHECK_IT (it);
5389 }
5390
5391
5392 /* Reseat iterator IT on the next visible line start in the current
5393 buffer. ON_NEWLINE_P non-zero means position IT on the newline
5394 preceding the line start. Skip over invisible text that is so
5395 because of selective display. Compute faces, overlays etc at the
5396 new position. Note that this function does not skip over text that
5397 is invisible because of text properties. */
5398
5399 static void
5400 reseat_at_next_visible_line_start (struct it *it, int on_newline_p)
5401 {
5402 int newline_found_p, skipped_p = 0;
5403
5404 newline_found_p = forward_to_next_line_start (it, &skipped_p);
5405
5406 /* Skip over lines that are invisible because they are indented
5407 more than the value of IT->selective. */
5408 if (it->selective > 0)
5409 while (IT_CHARPOS (*it) < ZV
5410 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
5411 (double) it->selective)) /* iftc */
5412 {
5413 xassert (IT_BYTEPOS (*it) == BEGV
5414 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
5415 newline_found_p = forward_to_next_line_start (it, &skipped_p);
5416 }
5417
5418 /* Position on the newline if that's what's requested. */
5419 if (on_newline_p && newline_found_p)
5420 {
5421 if (STRINGP (it->string))
5422 {
5423 if (IT_STRING_CHARPOS (*it) > 0)
5424 {
5425 --IT_STRING_CHARPOS (*it);
5426 --IT_STRING_BYTEPOS (*it);
5427 }
5428 }
5429 else if (IT_CHARPOS (*it) > BEGV)
5430 {
5431 --IT_CHARPOS (*it);
5432 --IT_BYTEPOS (*it);
5433 reseat (it, it->current.pos, 0);
5434 }
5435 }
5436 else if (skipped_p)
5437 reseat (it, it->current.pos, 0);
5438
5439 CHECK_IT (it);
5440 }
5441
5442
5443 \f
5444 /***********************************************************************
5445 Changing an iterator's position
5446 ***********************************************************************/
5447
5448 /* Change IT's current position to POS in current_buffer. If FORCE_P
5449 is non-zero, always check for text properties at the new position.
5450 Otherwise, text properties are only looked up if POS >=
5451 IT->check_charpos of a property. */
5452
5453 static void
5454 reseat (struct it *it, struct text_pos pos, int force_p)
5455 {
5456 EMACS_INT original_pos = IT_CHARPOS (*it);
5457
5458 reseat_1 (it, pos, 0);
5459
5460 /* Determine where to check text properties. Avoid doing it
5461 where possible because text property lookup is very expensive. */
5462 if (force_p
5463 || CHARPOS (pos) > it->stop_charpos
5464 || CHARPOS (pos) < original_pos)
5465 {
5466 if (it->bidi_p)
5467 {
5468 /* For bidi iteration, we need to prime prev_stop and
5469 base_level_stop with our best estimations. */
5470 if (CHARPOS (pos) < it->prev_stop)
5471 {
5472 handle_stop_backwards (it, BEGV);
5473 if (CHARPOS (pos) < it->base_level_stop)
5474 it->base_level_stop = 0;
5475 }
5476 else if (CHARPOS (pos) > it->stop_charpos
5477 && it->stop_charpos >= BEGV)
5478 handle_stop_backwards (it, it->stop_charpos);
5479 else /* force_p */
5480 handle_stop (it);
5481 }
5482 else
5483 {
5484 handle_stop (it);
5485 it->prev_stop = it->base_level_stop = 0;
5486 }
5487
5488 }
5489
5490 CHECK_IT (it);
5491 }
5492
5493
5494 /* Change IT's buffer position to POS. SET_STOP_P non-zero means set
5495 IT->stop_pos to POS, also. */
5496
5497 static void
5498 reseat_1 (struct it *it, struct text_pos pos, int set_stop_p)
5499 {
5500 /* Don't call this function when scanning a C string. */
5501 xassert (it->s == NULL);
5502
5503 /* POS must be a reasonable value. */
5504 xassert (CHARPOS (pos) >= BEGV && CHARPOS (pos) <= ZV);
5505
5506 it->current.pos = it->position = pos;
5507 it->end_charpos = ZV;
5508 it->dpvec = NULL;
5509 it->current.dpvec_index = -1;
5510 it->current.overlay_string_index = -1;
5511 IT_STRING_CHARPOS (*it) = -1;
5512 IT_STRING_BYTEPOS (*it) = -1;
5513 it->string = Qnil;
5514 it->string_from_display_prop_p = 0;
5515 it->method = GET_FROM_BUFFER;
5516 it->object = it->w->buffer;
5517 it->area = TEXT_AREA;
5518 it->multibyte_p = !NILP (BVAR (current_buffer, enable_multibyte_characters));
5519 it->sp = 0;
5520 it->string_from_display_prop_p = 0;
5521 it->face_before_selective_p = 0;
5522 if (it->bidi_p)
5523 {
5524 it->bidi_it.first_elt = 1;
5525 it->bidi_it.paragraph_dir = NEUTRAL_DIR;
5526 it->bidi_it.disp_pos = -1;
5527 }
5528
5529 if (set_stop_p)
5530 {
5531 it->stop_charpos = CHARPOS (pos);
5532 it->base_level_stop = CHARPOS (pos);
5533 }
5534 }
5535
5536
5537 /* Set up IT for displaying a string, starting at CHARPOS in window W.
5538 If S is non-null, it is a C string to iterate over. Otherwise,
5539 STRING gives a Lisp string to iterate over.
5540
5541 If PRECISION > 0, don't return more then PRECISION number of
5542 characters from the string.
5543
5544 If FIELD_WIDTH > 0, return padding spaces until FIELD_WIDTH
5545 characters have been returned. FIELD_WIDTH < 0 means an infinite
5546 field width.
5547
5548 MULTIBYTE = 0 means disable processing of multibyte characters,
5549 MULTIBYTE > 0 means enable it,
5550 MULTIBYTE < 0 means use IT->multibyte_p.
5551
5552 IT must be initialized via a prior call to init_iterator before
5553 calling this function. */
5554
5555 static void
5556 reseat_to_string (struct it *it, const char *s, Lisp_Object string,
5557 EMACS_INT charpos, EMACS_INT precision, int field_width,
5558 int multibyte)
5559 {
5560 /* No region in strings. */
5561 it->region_beg_charpos = it->region_end_charpos = -1;
5562
5563 /* No text property checks performed by default, but see below. */
5564 it->stop_charpos = -1;
5565
5566 /* Set iterator position and end position. */
5567 memset (&it->current, 0, sizeof it->current);
5568 it->current.overlay_string_index = -1;
5569 it->current.dpvec_index = -1;
5570 xassert (charpos >= 0);
5571
5572 /* If STRING is specified, use its multibyteness, otherwise use the
5573 setting of MULTIBYTE, if specified. */
5574 if (multibyte >= 0)
5575 it->multibyte_p = multibyte > 0;
5576
5577 if (s == NULL)
5578 {
5579 xassert (STRINGP (string));
5580 it->string = string;
5581 it->s = NULL;
5582 it->end_charpos = it->string_nchars = SCHARS (string);
5583 it->method = GET_FROM_STRING;
5584 it->current.string_pos = string_pos (charpos, string);
5585 }
5586 else
5587 {
5588 it->s = (const unsigned char *) s;
5589 it->string = Qnil;
5590
5591 /* Note that we use IT->current.pos, not it->current.string_pos,
5592 for displaying C strings. */
5593 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
5594 if (it->multibyte_p)
5595 {
5596 it->current.pos = c_string_pos (charpos, s, 1);
5597 it->end_charpos = it->string_nchars = number_of_chars (s, 1);
5598 }
5599 else
5600 {
5601 IT_CHARPOS (*it) = IT_BYTEPOS (*it) = charpos;
5602 it->end_charpos = it->string_nchars = strlen (s);
5603 }
5604
5605 it->method = GET_FROM_C_STRING;
5606 }
5607
5608 /* PRECISION > 0 means don't return more than PRECISION characters
5609 from the string. */
5610 if (precision > 0 && it->end_charpos - charpos > precision)
5611 it->end_charpos = it->string_nchars = charpos + precision;
5612
5613 /* FIELD_WIDTH > 0 means pad with spaces until FIELD_WIDTH
5614 characters have been returned. FIELD_WIDTH == 0 means don't pad,
5615 FIELD_WIDTH < 0 means infinite field width. This is useful for
5616 padding with `-' at the end of a mode line. */
5617 if (field_width < 0)
5618 field_width = INFINITY;
5619 if (field_width > it->end_charpos - charpos)
5620 it->end_charpos = charpos + field_width;
5621
5622 /* Use the standard display table for displaying strings. */
5623 if (DISP_TABLE_P (Vstandard_display_table))
5624 it->dp = XCHAR_TABLE (Vstandard_display_table);
5625
5626 it->stop_charpos = charpos;
5627 if (s == NULL && it->multibyte_p)
5628 {
5629 EMACS_INT endpos = SCHARS (it->string);
5630 if (endpos > it->end_charpos)
5631 endpos = it->end_charpos;
5632 composition_compute_stop_pos (&it->cmp_it, charpos, -1, endpos,
5633 it->string);
5634 }
5635 CHECK_IT (it);
5636 }
5637
5638
5639 \f
5640 /***********************************************************************
5641 Iteration
5642 ***********************************************************************/
5643
5644 /* Map enum it_method value to corresponding next_element_from_* function. */
5645
5646 static int (* get_next_element[NUM_IT_METHODS]) (struct it *it) =
5647 {
5648 next_element_from_buffer,
5649 next_element_from_display_vector,
5650 next_element_from_string,
5651 next_element_from_c_string,
5652 next_element_from_image,
5653 next_element_from_stretch
5654 };
5655
5656 #define GET_NEXT_DISPLAY_ELEMENT(it) (*get_next_element[(it)->method]) (it)
5657
5658
5659 /* Return 1 iff a character at CHARPOS (and BYTEPOS) is composed
5660 (possibly with the following characters). */
5661
5662 #define CHAR_COMPOSED_P(IT,CHARPOS,BYTEPOS,END_CHARPOS) \
5663 ((IT)->cmp_it.id >= 0 \
5664 || ((IT)->cmp_it.stop_pos == (CHARPOS) \
5665 && composition_reseat_it (&(IT)->cmp_it, CHARPOS, BYTEPOS, \
5666 END_CHARPOS, (IT)->w, \
5667 FACE_FROM_ID ((IT)->f, (IT)->face_id), \
5668 (IT)->string)))
5669
5670
5671 /* Lookup the char-table Vglyphless_char_display for character C (-1
5672 if we want information for no-font case), and return the display
5673 method symbol. By side-effect, update it->what and
5674 it->glyphless_method. This function is called from
5675 get_next_display_element for each character element, and from
5676 x_produce_glyphs when no suitable font was found. */
5677
5678 Lisp_Object
5679 lookup_glyphless_char_display (int c, struct it *it)
5680 {
5681 Lisp_Object glyphless_method = Qnil;
5682
5683 if (CHAR_TABLE_P (Vglyphless_char_display)
5684 && CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (Vglyphless_char_display)) >= 1)
5685 {
5686 if (c >= 0)
5687 {
5688 glyphless_method = CHAR_TABLE_REF (Vglyphless_char_display, c);
5689 if (CONSP (glyphless_method))
5690 glyphless_method = FRAME_WINDOW_P (it->f)
5691 ? XCAR (glyphless_method)
5692 : XCDR (glyphless_method);
5693 }
5694 else
5695 glyphless_method = XCHAR_TABLE (Vglyphless_char_display)->extras[0];
5696 }
5697
5698 retry:
5699 if (NILP (glyphless_method))
5700 {
5701 if (c >= 0)
5702 /* The default is to display the character by a proper font. */
5703 return Qnil;
5704 /* The default for the no-font case is to display an empty box. */
5705 glyphless_method = Qempty_box;
5706 }
5707 if (EQ (glyphless_method, Qzero_width))
5708 {
5709 if (c >= 0)
5710 return glyphless_method;
5711 /* This method can't be used for the no-font case. */
5712 glyphless_method = Qempty_box;
5713 }
5714 if (EQ (glyphless_method, Qthin_space))
5715 it->glyphless_method = GLYPHLESS_DISPLAY_THIN_SPACE;
5716 else if (EQ (glyphless_method, Qempty_box))
5717 it->glyphless_method = GLYPHLESS_DISPLAY_EMPTY_BOX;
5718 else if (EQ (glyphless_method, Qhex_code))
5719 it->glyphless_method = GLYPHLESS_DISPLAY_HEX_CODE;
5720 else if (STRINGP (glyphless_method))
5721 it->glyphless_method = GLYPHLESS_DISPLAY_ACRONYM;
5722 else
5723 {
5724 /* Invalid value. We use the default method. */
5725 glyphless_method = Qnil;
5726 goto retry;
5727 }
5728 it->what = IT_GLYPHLESS;
5729 return glyphless_method;
5730 }
5731
5732 /* Load IT's display element fields with information about the next
5733 display element from the current position of IT. Value is zero if
5734 end of buffer (or C string) is reached. */
5735
5736 static struct frame *last_escape_glyph_frame = NULL;
5737 static unsigned last_escape_glyph_face_id = (1 << FACE_ID_BITS);
5738 static int last_escape_glyph_merged_face_id = 0;
5739
5740 struct frame *last_glyphless_glyph_frame = NULL;
5741 unsigned last_glyphless_glyph_face_id = (1 << FACE_ID_BITS);
5742 int last_glyphless_glyph_merged_face_id = 0;
5743
5744 static int
5745 get_next_display_element (struct it *it)
5746 {
5747 /* Non-zero means that we found a display element. Zero means that
5748 we hit the end of what we iterate over. Performance note: the
5749 function pointer `method' used here turns out to be faster than
5750 using a sequence of if-statements. */
5751 int success_p;
5752
5753 get_next:
5754 success_p = GET_NEXT_DISPLAY_ELEMENT (it);
5755
5756 if (it->what == IT_CHARACTER)
5757 {
5758 /* UAX#9, L4: "A character is depicted by a mirrored glyph if
5759 and only if (a) the resolved directionality of that character
5760 is R..." */
5761 /* FIXME: Do we need an exception for characters from display
5762 tables? */
5763 if (it->bidi_p && it->bidi_it.type == STRONG_R)
5764 it->c = bidi_mirror_char (it->c);
5765 /* Map via display table or translate control characters.
5766 IT->c, IT->len etc. have been set to the next character by
5767 the function call above. If we have a display table, and it
5768 contains an entry for IT->c, translate it. Don't do this if
5769 IT->c itself comes from a display table, otherwise we could
5770 end up in an infinite recursion. (An alternative could be to
5771 count the recursion depth of this function and signal an
5772 error when a certain maximum depth is reached.) Is it worth
5773 it? */
5774 if (success_p && it->dpvec == NULL)
5775 {
5776 Lisp_Object dv;
5777 struct charset *unibyte = CHARSET_FROM_ID (charset_unibyte);
5778 enum { char_is_other = 0, char_is_nbsp, char_is_soft_hyphen }
5779 nbsp_or_shy = char_is_other;
5780 int c = it->c; /* This is the character to display. */
5781
5782 if (! it->multibyte_p && ! ASCII_CHAR_P (c))
5783 {
5784 xassert (SINGLE_BYTE_CHAR_P (c));
5785 if (unibyte_display_via_language_environment)
5786 {
5787 c = DECODE_CHAR (unibyte, c);
5788 if (c < 0)
5789 c = BYTE8_TO_CHAR (it->c);
5790 }
5791 else
5792 c = BYTE8_TO_CHAR (it->c);
5793 }
5794
5795 if (it->dp
5796 && (dv = DISP_CHAR_VECTOR (it->dp, c),
5797 VECTORP (dv)))
5798 {
5799 struct Lisp_Vector *v = XVECTOR (dv);
5800
5801 /* Return the first character from the display table
5802 entry, if not empty. If empty, don't display the
5803 current character. */
5804 if (v->header.size)
5805 {
5806 it->dpvec_char_len = it->len;
5807 it->dpvec = v->contents;
5808 it->dpend = v->contents + v->header.size;
5809 it->current.dpvec_index = 0;
5810 it->dpvec_face_id = -1;
5811 it->saved_face_id = it->face_id;
5812 it->method = GET_FROM_DISPLAY_VECTOR;
5813 it->ellipsis_p = 0;
5814 }
5815 else
5816 {
5817 set_iterator_to_next (it, 0);
5818 }
5819 goto get_next;
5820 }
5821
5822 if (! NILP (lookup_glyphless_char_display (c, it)))
5823 {
5824 if (it->what == IT_GLYPHLESS)
5825 goto done;
5826 /* Don't display this character. */
5827 set_iterator_to_next (it, 0);
5828 goto get_next;
5829 }
5830
5831 if (! ASCII_CHAR_P (c) && ! NILP (Vnobreak_char_display))
5832 nbsp_or_shy = (c == 0xA0 ? char_is_nbsp
5833 : c == 0xAD ? char_is_soft_hyphen
5834 : char_is_other);
5835
5836 /* Translate control characters into `\003' or `^C' form.
5837 Control characters coming from a display table entry are
5838 currently not translated because we use IT->dpvec to hold
5839 the translation. This could easily be changed but I
5840 don't believe that it is worth doing.
5841
5842 NBSP and SOFT-HYPEN are property translated too.
5843
5844 Non-printable characters and raw-byte characters are also
5845 translated to octal form. */
5846 if (((c < ' ' || c == 127) /* ASCII control chars */
5847 ? (it->area != TEXT_AREA
5848 /* In mode line, treat \n, \t like other crl chars. */
5849 || (c != '\t'
5850 && it->glyph_row
5851 && (it->glyph_row->mode_line_p || it->avoid_cursor_p))
5852 || (c != '\n' && c != '\t'))
5853 : (nbsp_or_shy
5854 || CHAR_BYTE8_P (c)
5855 || ! CHAR_PRINTABLE_P (c))))
5856 {
5857 /* C is a control character, NBSP, SOFT-HYPEN, raw-byte,
5858 or a non-printable character which must be displayed
5859 either as '\003' or as `^C' where the '\\' and '^'
5860 can be defined in the display table. Fill
5861 IT->ctl_chars with glyphs for what we have to
5862 display. Then, set IT->dpvec to these glyphs. */
5863 Lisp_Object gc;
5864 int ctl_len;
5865 int face_id, lface_id = 0 ;
5866 int escape_glyph;
5867
5868 /* Handle control characters with ^. */
5869
5870 if (ASCII_CHAR_P (c) && it->ctl_arrow_p)
5871 {
5872 int g;
5873
5874 g = '^'; /* default glyph for Control */
5875 /* Set IT->ctl_chars[0] to the glyph for `^'. */
5876 if (it->dp
5877 && (gc = DISP_CTRL_GLYPH (it->dp), GLYPH_CODE_P (gc))
5878 && GLYPH_CODE_CHAR_VALID_P (gc))
5879 {
5880 g = GLYPH_CODE_CHAR (gc);
5881 lface_id = GLYPH_CODE_FACE (gc);
5882 }
5883 if (lface_id)
5884 {
5885 face_id = merge_faces (it->f, Qt, lface_id, it->face_id);
5886 }
5887 else if (it->f == last_escape_glyph_frame
5888 && it->face_id == last_escape_glyph_face_id)
5889 {
5890 face_id = last_escape_glyph_merged_face_id;
5891 }
5892 else
5893 {
5894 /* Merge the escape-glyph face into the current face. */
5895 face_id = merge_faces (it->f, Qescape_glyph, 0,
5896 it->face_id);
5897 last_escape_glyph_frame = it->f;
5898 last_escape_glyph_face_id = it->face_id;
5899 last_escape_glyph_merged_face_id = face_id;
5900 }
5901
5902 XSETINT (it->ctl_chars[0], g);
5903 XSETINT (it->ctl_chars[1], c ^ 0100);
5904 ctl_len = 2;
5905 goto display_control;
5906 }
5907
5908 /* Handle non-break space in the mode where it only gets
5909 highlighting. */
5910
5911 if (EQ (Vnobreak_char_display, Qt)
5912 && nbsp_or_shy == char_is_nbsp)
5913 {
5914 /* Merge the no-break-space face into the current face. */
5915 face_id = merge_faces (it->f, Qnobreak_space, 0,
5916 it->face_id);
5917
5918 c = ' ';
5919 XSETINT (it->ctl_chars[0], ' ');
5920 ctl_len = 1;
5921 goto display_control;
5922 }
5923
5924 /* Handle sequences that start with the "escape glyph". */
5925
5926 /* the default escape glyph is \. */
5927 escape_glyph = '\\';
5928
5929 if (it->dp
5930 && (gc = DISP_ESCAPE_GLYPH (it->dp), GLYPH_CODE_P (gc))
5931 && GLYPH_CODE_CHAR_VALID_P (gc))
5932 {
5933 escape_glyph = GLYPH_CODE_CHAR (gc);
5934 lface_id = GLYPH_CODE_FACE (gc);
5935 }
5936 if (lface_id)
5937 {
5938 /* The display table specified a face.
5939 Merge it into face_id and also into escape_glyph. */
5940 face_id = merge_faces (it->f, Qt, lface_id,
5941 it->face_id);
5942 }
5943 else if (it->f == last_escape_glyph_frame
5944 && it->face_id == last_escape_glyph_face_id)
5945 {
5946 face_id = last_escape_glyph_merged_face_id;
5947 }
5948 else
5949 {
5950 /* Merge the escape-glyph face into the current face. */
5951 face_id = merge_faces (it->f, Qescape_glyph, 0,
5952 it->face_id);
5953 last_escape_glyph_frame = it->f;
5954 last_escape_glyph_face_id = it->face_id;
5955 last_escape_glyph_merged_face_id = face_id;
5956 }
5957
5958 /* Handle soft hyphens in the mode where they only get
5959 highlighting. */
5960
5961 if (EQ (Vnobreak_char_display, Qt)
5962 && nbsp_or_shy == char_is_soft_hyphen)
5963 {
5964 XSETINT (it->ctl_chars[0], '-');
5965 ctl_len = 1;
5966 goto display_control;
5967 }
5968
5969 /* Handle non-break space and soft hyphen
5970 with the escape glyph. */
5971
5972 if (nbsp_or_shy)
5973 {
5974 XSETINT (it->ctl_chars[0], escape_glyph);
5975 c = (nbsp_or_shy == char_is_nbsp ? ' ' : '-');
5976 XSETINT (it->ctl_chars[1], c);
5977 ctl_len = 2;
5978 goto display_control;
5979 }
5980
5981 {
5982 char str[10];
5983 int len, i;
5984
5985 if (CHAR_BYTE8_P (c))
5986 /* Display \200 instead of \17777600. */
5987 c = CHAR_TO_BYTE8 (c);
5988 len = sprintf (str, "%03o", c);
5989
5990 XSETINT (it->ctl_chars[0], escape_glyph);
5991 for (i = 0; i < len; i++)
5992 XSETINT (it->ctl_chars[i + 1], str[i]);
5993 ctl_len = len + 1;
5994 }
5995
5996 display_control:
5997 /* Set up IT->dpvec and return first character from it. */
5998 it->dpvec_char_len = it->len;
5999 it->dpvec = it->ctl_chars;
6000 it->dpend = it->dpvec + ctl_len;
6001 it->current.dpvec_index = 0;
6002 it->dpvec_face_id = face_id;
6003 it->saved_face_id = it->face_id;
6004 it->method = GET_FROM_DISPLAY_VECTOR;
6005 it->ellipsis_p = 0;
6006 goto get_next;
6007 }
6008 it->char_to_display = c;
6009 }
6010 else if (success_p)
6011 {
6012 it->char_to_display = it->c;
6013 }
6014 }
6015
6016 /* Adjust face id for a multibyte character. There are no multibyte
6017 character in unibyte text. */
6018 if ((it->what == IT_CHARACTER || it->what == IT_COMPOSITION)
6019 && it->multibyte_p
6020 && success_p
6021 && FRAME_WINDOW_P (it->f))
6022 {
6023 struct face *face = FACE_FROM_ID (it->f, it->face_id);
6024
6025 if (it->what == IT_COMPOSITION && it->cmp_it.ch >= 0)
6026 {
6027 /* Automatic composition with glyph-string. */
6028 Lisp_Object gstring = composition_gstring_from_id (it->cmp_it.id);
6029
6030 it->face_id = face_for_font (it->f, LGSTRING_FONT (gstring), face);
6031 }
6032 else
6033 {
6034 EMACS_INT pos = (it->s ? -1
6035 : STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
6036 : IT_CHARPOS (*it));
6037
6038 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display, pos,
6039 it->string);
6040 }
6041 }
6042
6043 done:
6044 /* Is this character the last one of a run of characters with
6045 box? If yes, set IT->end_of_box_run_p to 1. */
6046 if (it->face_box_p
6047 && it->s == NULL)
6048 {
6049 if (it->method == GET_FROM_STRING && it->sp)
6050 {
6051 int face_id = underlying_face_id (it);
6052 struct face *face = FACE_FROM_ID (it->f, face_id);
6053
6054 if (face)
6055 {
6056 if (face->box == FACE_NO_BOX)
6057 {
6058 /* If the box comes from face properties in a
6059 display string, check faces in that string. */
6060 int string_face_id = face_after_it_pos (it);
6061 it->end_of_box_run_p
6062 = (FACE_FROM_ID (it->f, string_face_id)->box
6063 == FACE_NO_BOX);
6064 }
6065 /* Otherwise, the box comes from the underlying face.
6066 If this is the last string character displayed, check
6067 the next buffer location. */
6068 else if ((IT_STRING_CHARPOS (*it) >= SCHARS (it->string) - 1)
6069 && (it->current.overlay_string_index
6070 == it->n_overlay_strings - 1))
6071 {
6072 EMACS_INT ignore;
6073 int next_face_id;
6074 struct text_pos pos = it->current.pos;
6075 INC_TEXT_POS (pos, it->multibyte_p);
6076
6077 next_face_id = face_at_buffer_position
6078 (it->w, CHARPOS (pos), it->region_beg_charpos,
6079 it->region_end_charpos, &ignore,
6080 (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT), 0,
6081 -1);
6082 it->end_of_box_run_p
6083 = (FACE_FROM_ID (it->f, next_face_id)->box
6084 == FACE_NO_BOX);
6085 }
6086 }
6087 }
6088 else
6089 {
6090 int face_id = face_after_it_pos (it);
6091 it->end_of_box_run_p
6092 = (face_id != it->face_id
6093 && FACE_FROM_ID (it->f, face_id)->box == FACE_NO_BOX);
6094 }
6095 }
6096
6097 /* Value is 0 if end of buffer or string reached. */
6098 return success_p;
6099 }
6100
6101
6102 /* Move IT to the next display element.
6103
6104 RESEAT_P non-zero means if called on a newline in buffer text,
6105 skip to the next visible line start.
6106
6107 Functions get_next_display_element and set_iterator_to_next are
6108 separate because I find this arrangement easier to handle than a
6109 get_next_display_element function that also increments IT's
6110 position. The way it is we can first look at an iterator's current
6111 display element, decide whether it fits on a line, and if it does,
6112 increment the iterator position. The other way around we probably
6113 would either need a flag indicating whether the iterator has to be
6114 incremented the next time, or we would have to implement a
6115 decrement position function which would not be easy to write. */
6116
6117 void
6118 set_iterator_to_next (struct it *it, int reseat_p)
6119 {
6120 /* Reset flags indicating start and end of a sequence of characters
6121 with box. Reset them at the start of this function because
6122 moving the iterator to a new position might set them. */
6123 it->start_of_box_run_p = it->end_of_box_run_p = 0;
6124
6125 switch (it->method)
6126 {
6127 case GET_FROM_BUFFER:
6128 /* The current display element of IT is a character from
6129 current_buffer. Advance in the buffer, and maybe skip over
6130 invisible lines that are so because of selective display. */
6131 if (ITERATOR_AT_END_OF_LINE_P (it) && reseat_p)
6132 reseat_at_next_visible_line_start (it, 0);
6133 else if (it->cmp_it.id >= 0)
6134 {
6135 /* We are currently getting glyphs from a composition. */
6136 int i;
6137
6138 if (! it->bidi_p)
6139 {
6140 IT_CHARPOS (*it) += it->cmp_it.nchars;
6141 IT_BYTEPOS (*it) += it->cmp_it.nbytes;
6142 if (it->cmp_it.to < it->cmp_it.nglyphs)
6143 {
6144 it->cmp_it.from = it->cmp_it.to;
6145 }
6146 else
6147 {
6148 it->cmp_it.id = -1;
6149 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
6150 IT_BYTEPOS (*it),
6151 it->end_charpos, Qnil);
6152 }
6153 }
6154 else if (! it->cmp_it.reversed_p)
6155 {
6156 /* Composition created while scanning forward. */
6157 /* Update IT's char/byte positions to point to the first
6158 character of the next grapheme cluster, or to the
6159 character visually after the current composition. */
6160 for (i = 0; i < it->cmp_it.nchars; i++)
6161 bidi_move_to_visually_next (&it->bidi_it);
6162 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
6163 IT_CHARPOS (*it) = it->bidi_it.charpos;
6164
6165 if (it->cmp_it.to < it->cmp_it.nglyphs)
6166 {
6167 /* Proceed to the next grapheme cluster. */
6168 it->cmp_it.from = it->cmp_it.to;
6169 }
6170 else
6171 {
6172 /* No more grapheme clusters in this composition.
6173 Find the next stop position. */
6174 EMACS_INT stop = it->end_charpos;
6175 if (it->bidi_it.scan_dir < 0)
6176 /* Now we are scanning backward and don't know
6177 where to stop. */
6178 stop = -1;
6179 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
6180 IT_BYTEPOS (*it), stop, Qnil);
6181 }
6182 }
6183 else
6184 {
6185 /* Composition created while scanning backward. */
6186 /* Update IT's char/byte positions to point to the last
6187 character of the previous grapheme cluster, or the
6188 character visually after the current composition. */
6189 for (i = 0; i < it->cmp_it.nchars; i++)
6190 bidi_move_to_visually_next (&it->bidi_it);
6191 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
6192 IT_CHARPOS (*it) = it->bidi_it.charpos;
6193 if (it->cmp_it.from > 0)
6194 {
6195 /* Proceed to the previous grapheme cluster. */
6196 it->cmp_it.to = it->cmp_it.from;
6197 }
6198 else
6199 {
6200 /* No more grapheme clusters in this composition.
6201 Find the next stop position. */
6202 EMACS_INT stop = it->end_charpos;
6203 if (it->bidi_it.scan_dir < 0)
6204 /* Now we are scanning backward and don't know
6205 where to stop. */
6206 stop = -1;
6207 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
6208 IT_BYTEPOS (*it), stop, Qnil);
6209 }
6210 }
6211 }
6212 else
6213 {
6214 xassert (it->len != 0);
6215
6216 if (!it->bidi_p)
6217 {
6218 IT_BYTEPOS (*it) += it->len;
6219 IT_CHARPOS (*it) += 1;
6220 }
6221 else
6222 {
6223 int prev_scan_dir = it->bidi_it.scan_dir;
6224 /* If this is a new paragraph, determine its base
6225 direction (a.k.a. its base embedding level). */
6226 if (it->bidi_it.new_paragraph)
6227 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 0);
6228 bidi_move_to_visually_next (&it->bidi_it);
6229 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
6230 IT_CHARPOS (*it) = it->bidi_it.charpos;
6231 if (prev_scan_dir != it->bidi_it.scan_dir)
6232 {
6233 /* As the scan direction was changed, we must
6234 re-compute the stop position for composition. */
6235 EMACS_INT stop = it->end_charpos;
6236 if (it->bidi_it.scan_dir < 0)
6237 stop = -1;
6238 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
6239 IT_BYTEPOS (*it), stop, Qnil);
6240 }
6241 }
6242 xassert (IT_BYTEPOS (*it) == CHAR_TO_BYTE (IT_CHARPOS (*it)));
6243 }
6244 break;
6245
6246 case GET_FROM_C_STRING:
6247 /* Current display element of IT is from a C string. */
6248 IT_BYTEPOS (*it) += it->len;
6249 IT_CHARPOS (*it) += 1;
6250 break;
6251
6252 case GET_FROM_DISPLAY_VECTOR:
6253 /* Current display element of IT is from a display table entry.
6254 Advance in the display table definition. Reset it to null if
6255 end reached, and continue with characters from buffers/
6256 strings. */
6257 ++it->current.dpvec_index;
6258
6259 /* Restore face of the iterator to what they were before the
6260 display vector entry (these entries may contain faces). */
6261 it->face_id = it->saved_face_id;
6262
6263 if (it->dpvec + it->current.dpvec_index == it->dpend)
6264 {
6265 int recheck_faces = it->ellipsis_p;
6266
6267 if (it->s)
6268 it->method = GET_FROM_C_STRING;
6269 else if (STRINGP (it->string))
6270 it->method = GET_FROM_STRING;
6271 else
6272 {
6273 it->method = GET_FROM_BUFFER;
6274 it->object = it->w->buffer;
6275 }
6276
6277 it->dpvec = NULL;
6278 it->current.dpvec_index = -1;
6279
6280 /* Skip over characters which were displayed via IT->dpvec. */
6281 if (it->dpvec_char_len < 0)
6282 reseat_at_next_visible_line_start (it, 1);
6283 else if (it->dpvec_char_len > 0)
6284 {
6285 if (it->method == GET_FROM_STRING
6286 && it->n_overlay_strings > 0)
6287 it->ignore_overlay_strings_at_pos_p = 1;
6288 it->len = it->dpvec_char_len;
6289 set_iterator_to_next (it, reseat_p);
6290 }
6291
6292 /* Maybe recheck faces after display vector */
6293 if (recheck_faces)
6294 it->stop_charpos = IT_CHARPOS (*it);
6295 }
6296 break;
6297
6298 case GET_FROM_STRING:
6299 /* Current display element is a character from a Lisp string. */
6300 xassert (it->s == NULL && STRINGP (it->string));
6301 if (it->cmp_it.id >= 0)
6302 {
6303 IT_STRING_CHARPOS (*it) += it->cmp_it.nchars;
6304 IT_STRING_BYTEPOS (*it) += it->cmp_it.nbytes;
6305 if (it->cmp_it.to < it->cmp_it.nglyphs)
6306 it->cmp_it.from = it->cmp_it.to;
6307 else
6308 {
6309 it->cmp_it.id = -1;
6310 composition_compute_stop_pos (&it->cmp_it,
6311 IT_STRING_CHARPOS (*it),
6312 IT_STRING_BYTEPOS (*it),
6313 it->end_charpos, it->string);
6314 }
6315 }
6316 else
6317 {
6318 IT_STRING_BYTEPOS (*it) += it->len;
6319 IT_STRING_CHARPOS (*it) += 1;
6320 }
6321
6322 consider_string_end:
6323
6324 if (it->current.overlay_string_index >= 0)
6325 {
6326 /* IT->string is an overlay string. Advance to the
6327 next, if there is one. */
6328 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
6329 {
6330 it->ellipsis_p = 0;
6331 next_overlay_string (it);
6332 if (it->ellipsis_p)
6333 setup_for_ellipsis (it, 0);
6334 }
6335 }
6336 else
6337 {
6338 /* IT->string is not an overlay string. If we reached
6339 its end, and there is something on IT->stack, proceed
6340 with what is on the stack. This can be either another
6341 string, this time an overlay string, or a buffer. */
6342 if (IT_STRING_CHARPOS (*it) == SCHARS (it->string)
6343 && it->sp > 0)
6344 {
6345 pop_it (it);
6346 if (it->method == GET_FROM_STRING)
6347 goto consider_string_end;
6348 }
6349 }
6350 break;
6351
6352 case GET_FROM_IMAGE:
6353 case GET_FROM_STRETCH:
6354 /* The position etc with which we have to proceed are on
6355 the stack. The position may be at the end of a string,
6356 if the `display' property takes up the whole string. */
6357 xassert (it->sp > 0);
6358 pop_it (it);
6359 if (it->method == GET_FROM_STRING)
6360 goto consider_string_end;
6361 break;
6362
6363 default:
6364 /* There are no other methods defined, so this should be a bug. */
6365 abort ();
6366 }
6367
6368 xassert (it->method != GET_FROM_STRING
6369 || (STRINGP (it->string)
6370 && IT_STRING_CHARPOS (*it) >= 0));
6371 }
6372
6373 /* Load IT's display element fields with information about the next
6374 display element which comes from a display table entry or from the
6375 result of translating a control character to one of the forms `^C'
6376 or `\003'.
6377
6378 IT->dpvec holds the glyphs to return as characters.
6379 IT->saved_face_id holds the face id before the display vector--it
6380 is restored into IT->face_id in set_iterator_to_next. */
6381
6382 static int
6383 next_element_from_display_vector (struct it *it)
6384 {
6385 Lisp_Object gc;
6386
6387 /* Precondition. */
6388 xassert (it->dpvec && it->current.dpvec_index >= 0);
6389
6390 it->face_id = it->saved_face_id;
6391
6392 /* KFS: This code used to check ip->dpvec[0] instead of the current element.
6393 That seemed totally bogus - so I changed it... */
6394 gc = it->dpvec[it->current.dpvec_index];
6395
6396 if (GLYPH_CODE_P (gc) && GLYPH_CODE_CHAR_VALID_P (gc))
6397 {
6398 it->c = GLYPH_CODE_CHAR (gc);
6399 it->len = CHAR_BYTES (it->c);
6400
6401 /* The entry may contain a face id to use. Such a face id is
6402 the id of a Lisp face, not a realized face. A face id of
6403 zero means no face is specified. */
6404 if (it->dpvec_face_id >= 0)
6405 it->face_id = it->dpvec_face_id;
6406 else
6407 {
6408 int lface_id = GLYPH_CODE_FACE (gc);
6409 if (lface_id > 0)
6410 it->face_id = merge_faces (it->f, Qt, lface_id,
6411 it->saved_face_id);
6412 }
6413 }
6414 else
6415 /* Display table entry is invalid. Return a space. */
6416 it->c = ' ', it->len = 1;
6417
6418 /* Don't change position and object of the iterator here. They are
6419 still the values of the character that had this display table
6420 entry or was translated, and that's what we want. */
6421 it->what = IT_CHARACTER;
6422 return 1;
6423 }
6424
6425
6426 /* Load IT with the next display element from Lisp string IT->string.
6427 IT->current.string_pos is the current position within the string.
6428 If IT->current.overlay_string_index >= 0, the Lisp string is an
6429 overlay string. */
6430
6431 static int
6432 next_element_from_string (struct it *it)
6433 {
6434 struct text_pos position;
6435
6436 xassert (STRINGP (it->string));
6437 xassert (IT_STRING_CHARPOS (*it) >= 0);
6438 position = it->current.string_pos;
6439
6440 /* Time to check for invisible text? */
6441 if (IT_STRING_CHARPOS (*it) < it->end_charpos
6442 && IT_STRING_CHARPOS (*it) == it->stop_charpos)
6443 {
6444 handle_stop (it);
6445
6446 /* Since a handler may have changed IT->method, we must
6447 recurse here. */
6448 return GET_NEXT_DISPLAY_ELEMENT (it);
6449 }
6450
6451 if (it->current.overlay_string_index >= 0)
6452 {
6453 /* Get the next character from an overlay string. In overlay
6454 strings, There is no field width or padding with spaces to
6455 do. */
6456 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
6457 {
6458 it->what = IT_EOB;
6459 return 0;
6460 }
6461 else if (CHAR_COMPOSED_P (it, IT_STRING_CHARPOS (*it),
6462 IT_STRING_BYTEPOS (*it), SCHARS (it->string))
6463 && next_element_from_composition (it))
6464 {
6465 return 1;
6466 }
6467 else if (STRING_MULTIBYTE (it->string))
6468 {
6469 const unsigned char *s = (SDATA (it->string)
6470 + IT_STRING_BYTEPOS (*it));
6471 it->c = string_char_and_length (s, &it->len);
6472 }
6473 else
6474 {
6475 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
6476 it->len = 1;
6477 }
6478 }
6479 else
6480 {
6481 /* Get the next character from a Lisp string that is not an
6482 overlay string. Such strings come from the mode line, for
6483 example. We may have to pad with spaces, or truncate the
6484 string. See also next_element_from_c_string. */
6485 if (IT_STRING_CHARPOS (*it) >= it->end_charpos)
6486 {
6487 it->what = IT_EOB;
6488 return 0;
6489 }
6490 else if (IT_STRING_CHARPOS (*it) >= it->string_nchars)
6491 {
6492 /* Pad with spaces. */
6493 it->c = ' ', it->len = 1;
6494 CHARPOS (position) = BYTEPOS (position) = -1;
6495 }
6496 else if (CHAR_COMPOSED_P (it, IT_STRING_CHARPOS (*it),
6497 IT_STRING_BYTEPOS (*it), it->string_nchars)
6498 && next_element_from_composition (it))
6499 {
6500 return 1;
6501 }
6502 else if (STRING_MULTIBYTE (it->string))
6503 {
6504 const unsigned char *s = (SDATA (it->string)
6505 + IT_STRING_BYTEPOS (*it));
6506 it->c = string_char_and_length (s, &it->len);
6507 }
6508 else
6509 {
6510 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
6511 it->len = 1;
6512 }
6513 }
6514
6515 /* Record what we have and where it came from. */
6516 it->what = IT_CHARACTER;
6517 it->object = it->string;
6518 it->position = position;
6519 return 1;
6520 }
6521
6522
6523 /* Load IT with next display element from C string IT->s.
6524 IT->string_nchars is the maximum number of characters to return
6525 from the string. IT->end_charpos may be greater than
6526 IT->string_nchars when this function is called, in which case we
6527 may have to return padding spaces. Value is zero if end of string
6528 reached, including padding spaces. */
6529
6530 static int
6531 next_element_from_c_string (struct it *it)
6532 {
6533 int success_p = 1;
6534
6535 xassert (it->s);
6536 it->what = IT_CHARACTER;
6537 BYTEPOS (it->position) = CHARPOS (it->position) = 0;
6538 it->object = Qnil;
6539
6540 /* IT's position can be greater IT->string_nchars in case a field
6541 width or precision has been specified when the iterator was
6542 initialized. */
6543 if (IT_CHARPOS (*it) >= it->end_charpos)
6544 {
6545 /* End of the game. */
6546 it->what = IT_EOB;
6547 success_p = 0;
6548 }
6549 else if (IT_CHARPOS (*it) >= it->string_nchars)
6550 {
6551 /* Pad with spaces. */
6552 it->c = ' ', it->len = 1;
6553 BYTEPOS (it->position) = CHARPOS (it->position) = -1;
6554 }
6555 else if (it->multibyte_p)
6556 it->c = string_char_and_length (it->s + IT_BYTEPOS (*it), &it->len);
6557 else
6558 it->c = it->s[IT_BYTEPOS (*it)], it->len = 1;
6559
6560 return success_p;
6561 }
6562
6563
6564 /* Set up IT to return characters from an ellipsis, if appropriate.
6565 The definition of the ellipsis glyphs may come from a display table
6566 entry. This function fills IT with the first glyph from the
6567 ellipsis if an ellipsis is to be displayed. */
6568
6569 static int
6570 next_element_from_ellipsis (struct it *it)
6571 {
6572 if (it->selective_display_ellipsis_p)
6573 setup_for_ellipsis (it, it->len);
6574 else
6575 {
6576 /* The face at the current position may be different from the
6577 face we find after the invisible text. Remember what it
6578 was in IT->saved_face_id, and signal that it's there by
6579 setting face_before_selective_p. */
6580 it->saved_face_id = it->face_id;
6581 it->method = GET_FROM_BUFFER;
6582 it->object = it->w->buffer;
6583 reseat_at_next_visible_line_start (it, 1);
6584 it->face_before_selective_p = 1;
6585 }
6586
6587 return GET_NEXT_DISPLAY_ELEMENT (it);
6588 }
6589
6590
6591 /* Deliver an image display element. The iterator IT is already
6592 filled with image information (done in handle_display_prop). Value
6593 is always 1. */
6594
6595
6596 static int
6597 next_element_from_image (struct it *it)
6598 {
6599 it->what = IT_IMAGE;
6600 it->ignore_overlay_strings_at_pos_p = 0;
6601 return 1;
6602 }
6603
6604
6605 /* Fill iterator IT with next display element from a stretch glyph
6606 property. IT->object is the value of the text property. Value is
6607 always 1. */
6608
6609 static int
6610 next_element_from_stretch (struct it *it)
6611 {
6612 it->what = IT_STRETCH;
6613 return 1;
6614 }
6615
6616 /* Scan forward from CHARPOS in the current buffer, until we find a
6617 stop position > current IT's position. Then handle the stop
6618 position before that. This is called when we bump into a stop
6619 position while reordering bidirectional text. CHARPOS should be
6620 the last previously processed stop_pos (or BEGV, if none were
6621 processed yet) whose position is less that IT's current
6622 position. */
6623
6624 static void
6625 handle_stop_backwards (struct it *it, EMACS_INT charpos)
6626 {
6627 EMACS_INT where_we_are = IT_CHARPOS (*it);
6628 struct display_pos save_current = it->current;
6629 struct text_pos save_position = it->position;
6630 struct text_pos pos1;
6631 EMACS_INT next_stop;
6632
6633 /* Scan in strict logical order. */
6634 it->bidi_p = 0;
6635 do
6636 {
6637 it->prev_stop = charpos;
6638 SET_TEXT_POS (pos1, charpos, CHAR_TO_BYTE (charpos));
6639 reseat_1 (it, pos1, 0);
6640 compute_stop_pos (it);
6641 /* We must advance forward, right? */
6642 if (it->stop_charpos <= it->prev_stop)
6643 abort ();
6644 charpos = it->stop_charpos;
6645 }
6646 while (charpos <= where_we_are);
6647
6648 next_stop = it->stop_charpos;
6649 it->stop_charpos = it->prev_stop;
6650 it->bidi_p = 1;
6651 it->current = save_current;
6652 it->position = save_position;
6653 handle_stop (it);
6654 it->stop_charpos = next_stop;
6655 }
6656
6657 /* Load IT with the next display element from current_buffer. Value
6658 is zero if end of buffer reached. IT->stop_charpos is the next
6659 position at which to stop and check for text properties or buffer
6660 end. */
6661
6662 static int
6663 next_element_from_buffer (struct it *it)
6664 {
6665 int success_p = 1;
6666
6667 xassert (IT_CHARPOS (*it) >= BEGV);
6668
6669 /* With bidi reordering, the character to display might not be the
6670 character at IT_CHARPOS. BIDI_IT.FIRST_ELT non-zero means that
6671 we were reseat()ed to a new buffer position, which is potentially
6672 a different paragraph. */
6673 if (it->bidi_p && it->bidi_it.first_elt)
6674 {
6675 it->bidi_it.charpos = IT_CHARPOS (*it);
6676 it->bidi_it.bytepos = IT_BYTEPOS (*it);
6677 if (it->bidi_it.bytepos == ZV_BYTE)
6678 {
6679 /* Nothing to do, but reset the FIRST_ELT flag, like
6680 bidi_paragraph_init does, because we are not going to
6681 call it. */
6682 it->bidi_it.first_elt = 0;
6683 }
6684 else if (it->bidi_it.bytepos == BEGV_BYTE
6685 /* FIXME: Should support all Unicode line separators. */
6686 || FETCH_CHAR (it->bidi_it.bytepos - 1) == '\n'
6687 || FETCH_CHAR (it->bidi_it.bytepos) == '\n')
6688 {
6689 /* If we are at the beginning of a line, we can produce the
6690 next element right away. */
6691 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1);
6692 bidi_move_to_visually_next (&it->bidi_it);
6693 }
6694 else
6695 {
6696 EMACS_INT orig_bytepos = IT_BYTEPOS (*it);
6697
6698 /* We need to prime the bidi iterator starting at the line's
6699 beginning, before we will be able to produce the next
6700 element. */
6701 IT_CHARPOS (*it) = find_next_newline_no_quit (IT_CHARPOS (*it), -1);
6702 IT_BYTEPOS (*it) = CHAR_TO_BYTE (IT_CHARPOS (*it));
6703 it->bidi_it.charpos = IT_CHARPOS (*it);
6704 it->bidi_it.bytepos = IT_BYTEPOS (*it);
6705 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1);
6706 do
6707 {
6708 /* Now return to buffer position where we were asked to
6709 get the next display element, and produce that. */
6710 bidi_move_to_visually_next (&it->bidi_it);
6711 }
6712 while (it->bidi_it.bytepos != orig_bytepos
6713 && it->bidi_it.bytepos < ZV_BYTE);
6714 }
6715
6716 it->bidi_it.first_elt = 0; /* paranoia: bidi.c does this */
6717 /* Adjust IT's position information to where we ended up. */
6718 IT_CHARPOS (*it) = it->bidi_it.charpos;
6719 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
6720 SET_TEXT_POS (it->position, IT_CHARPOS (*it), IT_BYTEPOS (*it));
6721 {
6722 EMACS_INT stop = it->end_charpos;
6723 if (it->bidi_it.scan_dir < 0)
6724 stop = -1;
6725 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
6726 IT_BYTEPOS (*it), stop, Qnil);
6727 }
6728 }
6729
6730 if (IT_CHARPOS (*it) >= it->stop_charpos)
6731 {
6732 if (IT_CHARPOS (*it) >= it->end_charpos)
6733 {
6734 int overlay_strings_follow_p;
6735
6736 /* End of the game, except when overlay strings follow that
6737 haven't been returned yet. */
6738 if (it->overlay_strings_at_end_processed_p)
6739 overlay_strings_follow_p = 0;
6740 else
6741 {
6742 it->overlay_strings_at_end_processed_p = 1;
6743 overlay_strings_follow_p = get_overlay_strings (it, 0);
6744 }
6745
6746 if (overlay_strings_follow_p)
6747 success_p = GET_NEXT_DISPLAY_ELEMENT (it);
6748 else
6749 {
6750 it->what = IT_EOB;
6751 it->position = it->current.pos;
6752 success_p = 0;
6753 }
6754 }
6755 else if (!(!it->bidi_p
6756 || BIDI_AT_BASE_LEVEL (it->bidi_it)
6757 || IT_CHARPOS (*it) == it->stop_charpos))
6758 {
6759 /* With bidi non-linear iteration, we could find ourselves
6760 far beyond the last computed stop_charpos, with several
6761 other stop positions in between that we missed. Scan
6762 them all now, in buffer's logical order, until we find
6763 and handle the last stop_charpos that precedes our
6764 current position. */
6765 handle_stop_backwards (it, it->stop_charpos);
6766 return GET_NEXT_DISPLAY_ELEMENT (it);
6767 }
6768 else
6769 {
6770 if (it->bidi_p)
6771 {
6772 /* Take note of the stop position we just moved across,
6773 for when we will move back across it. */
6774 it->prev_stop = it->stop_charpos;
6775 /* If we are at base paragraph embedding level, take
6776 note of the last stop position seen at this
6777 level. */
6778 if (BIDI_AT_BASE_LEVEL (it->bidi_it))
6779 it->base_level_stop = it->stop_charpos;
6780 }
6781 handle_stop (it);
6782 return GET_NEXT_DISPLAY_ELEMENT (it);
6783 }
6784 }
6785 else if (it->bidi_p
6786 /* We can sometimes back up for reasons that have nothing
6787 to do with bidi reordering. E.g., compositions. The
6788 code below is only needed when we are above the base
6789 embedding level, so test for that explicitly. */
6790 && !BIDI_AT_BASE_LEVEL (it->bidi_it)
6791 && IT_CHARPOS (*it) < it->prev_stop)
6792 {
6793 if (it->base_level_stop <= 0)
6794 it->base_level_stop = BEGV;
6795 if (IT_CHARPOS (*it) < it->base_level_stop)
6796 abort ();
6797 handle_stop_backwards (it, it->base_level_stop);
6798 return GET_NEXT_DISPLAY_ELEMENT (it);
6799 }
6800 else
6801 {
6802 /* No face changes, overlays etc. in sight, so just return a
6803 character from current_buffer. */
6804 unsigned char *p;
6805 EMACS_INT stop;
6806
6807 /* Maybe run the redisplay end trigger hook. Performance note:
6808 This doesn't seem to cost measurable time. */
6809 if (it->redisplay_end_trigger_charpos
6810 && it->glyph_row
6811 && IT_CHARPOS (*it) >= it->redisplay_end_trigger_charpos)
6812 run_redisplay_end_trigger_hook (it);
6813
6814 stop = it->bidi_it.scan_dir < 0 ? -1 : it->end_charpos;
6815 if (CHAR_COMPOSED_P (it, IT_CHARPOS (*it), IT_BYTEPOS (*it),
6816 stop)
6817 && next_element_from_composition (it))
6818 {
6819 return 1;
6820 }
6821
6822 /* Get the next character, maybe multibyte. */
6823 p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
6824 if (it->multibyte_p && !ASCII_BYTE_P (*p))
6825 it->c = STRING_CHAR_AND_LENGTH (p, it->len);
6826 else
6827 it->c = *p, it->len = 1;
6828
6829 /* Record what we have and where it came from. */
6830 it->what = IT_CHARACTER;
6831 it->object = it->w->buffer;
6832 it->position = it->current.pos;
6833
6834 /* Normally we return the character found above, except when we
6835 really want to return an ellipsis for selective display. */
6836 if (it->selective)
6837 {
6838 if (it->c == '\n')
6839 {
6840 /* A value of selective > 0 means hide lines indented more
6841 than that number of columns. */
6842 if (it->selective > 0
6843 && IT_CHARPOS (*it) + 1 < ZV
6844 && indented_beyond_p (IT_CHARPOS (*it) + 1,
6845 IT_BYTEPOS (*it) + 1,
6846 (double) it->selective)) /* iftc */
6847 {
6848 success_p = next_element_from_ellipsis (it);
6849 it->dpvec_char_len = -1;
6850 }
6851 }
6852 else if (it->c == '\r' && it->selective == -1)
6853 {
6854 /* A value of selective == -1 means that everything from the
6855 CR to the end of the line is invisible, with maybe an
6856 ellipsis displayed for it. */
6857 success_p = next_element_from_ellipsis (it);
6858 it->dpvec_char_len = -1;
6859 }
6860 }
6861 }
6862
6863 /* Value is zero if end of buffer reached. */
6864 xassert (!success_p || it->what != IT_CHARACTER || it->len > 0);
6865 return success_p;
6866 }
6867
6868
6869 /* Run the redisplay end trigger hook for IT. */
6870
6871 static void
6872 run_redisplay_end_trigger_hook (struct it *it)
6873 {
6874 Lisp_Object args[3];
6875
6876 /* IT->glyph_row should be non-null, i.e. we should be actually
6877 displaying something, or otherwise we should not run the hook. */
6878 xassert (it->glyph_row);
6879
6880 /* Set up hook arguments. */
6881 args[0] = Qredisplay_end_trigger_functions;
6882 args[1] = it->window;
6883 XSETINT (args[2], it->redisplay_end_trigger_charpos);
6884 it->redisplay_end_trigger_charpos = 0;
6885
6886 /* Since we are *trying* to run these functions, don't try to run
6887 them again, even if they get an error. */
6888 it->w->redisplay_end_trigger = Qnil;
6889 Frun_hook_with_args (3, args);
6890
6891 /* Notice if it changed the face of the character we are on. */
6892 handle_face_prop (it);
6893 }
6894
6895
6896 /* Deliver a composition display element. Unlike the other
6897 next_element_from_XXX, this function is not registered in the array
6898 get_next_element[]. It is called from next_element_from_buffer and
6899 next_element_from_string when necessary. */
6900
6901 static int
6902 next_element_from_composition (struct it *it)
6903 {
6904 it->what = IT_COMPOSITION;
6905 it->len = it->cmp_it.nbytes;
6906 if (STRINGP (it->string))
6907 {
6908 if (it->c < 0)
6909 {
6910 IT_STRING_CHARPOS (*it) += it->cmp_it.nchars;
6911 IT_STRING_BYTEPOS (*it) += it->cmp_it.nbytes;
6912 return 0;
6913 }
6914 it->position = it->current.string_pos;
6915 it->object = it->string;
6916 it->c = composition_update_it (&it->cmp_it, IT_STRING_CHARPOS (*it),
6917 IT_STRING_BYTEPOS (*it), it->string);
6918 }
6919 else
6920 {
6921 if (it->c < 0)
6922 {
6923 IT_CHARPOS (*it) += it->cmp_it.nchars;
6924 IT_BYTEPOS (*it) += it->cmp_it.nbytes;
6925 if (it->bidi_p)
6926 {
6927 if (it->bidi_it.new_paragraph)
6928 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 0);
6929 /* Resync the bidi iterator with IT's new position.
6930 FIXME: this doesn't support bidirectional text. */
6931 while (it->bidi_it.charpos < IT_CHARPOS (*it))
6932 bidi_move_to_visually_next (&it->bidi_it);
6933 }
6934 return 0;
6935 }
6936 it->position = it->current.pos;
6937 it->object = it->w->buffer;
6938 it->c = composition_update_it (&it->cmp_it, IT_CHARPOS (*it),
6939 IT_BYTEPOS (*it), Qnil);
6940 }
6941 return 1;
6942 }
6943
6944
6945 \f
6946 /***********************************************************************
6947 Moving an iterator without producing glyphs
6948 ***********************************************************************/
6949
6950 /* Check if iterator is at a position corresponding to a valid buffer
6951 position after some move_it_ call. */
6952
6953 #define IT_POS_VALID_AFTER_MOVE_P(it) \
6954 ((it)->method == GET_FROM_STRING \
6955 ? IT_STRING_CHARPOS (*it) == 0 \
6956 : 1)
6957
6958
6959 /* Move iterator IT to a specified buffer or X position within one
6960 line on the display without producing glyphs.
6961
6962 OP should be a bit mask including some or all of these bits:
6963 MOVE_TO_X: Stop upon reaching x-position TO_X.
6964 MOVE_TO_POS: Stop upon reaching buffer or string position TO_CHARPOS.
6965 Regardless of OP's value, stop upon reaching the end of the display line.
6966
6967 TO_X is normally a value 0 <= TO_X <= IT->last_visible_x.
6968 This means, in particular, that TO_X includes window's horizontal
6969 scroll amount.
6970
6971 The return value has several possible values that
6972 say what condition caused the scan to stop:
6973
6974 MOVE_POS_MATCH_OR_ZV
6975 - when TO_POS or ZV was reached.
6976
6977 MOVE_X_REACHED
6978 -when TO_X was reached before TO_POS or ZV were reached.
6979
6980 MOVE_LINE_CONTINUED
6981 - when we reached the end of the display area and the line must
6982 be continued.
6983
6984 MOVE_LINE_TRUNCATED
6985 - when we reached the end of the display area and the line is
6986 truncated.
6987
6988 MOVE_NEWLINE_OR_CR
6989 - when we stopped at a line end, i.e. a newline or a CR and selective
6990 display is on. */
6991
6992 static enum move_it_result
6993 move_it_in_display_line_to (struct it *it,
6994 EMACS_INT to_charpos, int to_x,
6995 enum move_operation_enum op)
6996 {
6997 enum move_it_result result = MOVE_UNDEFINED;
6998 struct glyph_row *saved_glyph_row;
6999 struct it wrap_it, atpos_it, atx_it;
7000 int may_wrap = 0;
7001 enum it_method prev_method = it->method;
7002 EMACS_INT prev_pos = IT_CHARPOS (*it);
7003
7004 /* Don't produce glyphs in produce_glyphs. */
7005 saved_glyph_row = it->glyph_row;
7006 it->glyph_row = NULL;
7007
7008 /* Use wrap_it to save a copy of IT wherever a word wrap could
7009 occur. Use atpos_it to save a copy of IT at the desired buffer
7010 position, if found, so that we can scan ahead and check if the
7011 word later overshoots the window edge. Use atx_it similarly, for
7012 pixel positions. */
7013 wrap_it.sp = -1;
7014 atpos_it.sp = -1;
7015 atx_it.sp = -1;
7016
7017 #define BUFFER_POS_REACHED_P() \
7018 ((op & MOVE_TO_POS) != 0 \
7019 && BUFFERP (it->object) \
7020 && (IT_CHARPOS (*it) == to_charpos \
7021 || (!it->bidi_p && IT_CHARPOS (*it) > to_charpos)) \
7022 && (it->method == GET_FROM_BUFFER \
7023 || (it->method == GET_FROM_DISPLAY_VECTOR \
7024 && it->dpvec + it->current.dpvec_index + 1 >= it->dpend)))
7025
7026 /* If there's a line-/wrap-prefix, handle it. */
7027 if (it->hpos == 0 && it->method == GET_FROM_BUFFER
7028 && it->current_y < it->last_visible_y)
7029 handle_line_prefix (it);
7030
7031 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
7032 SET_TEXT_POS (this_line_min_pos, IT_CHARPOS (*it), IT_BYTEPOS (*it));
7033
7034 while (1)
7035 {
7036 int x, i, ascent = 0, descent = 0;
7037
7038 /* Utility macro to reset an iterator with x, ascent, and descent. */
7039 #define IT_RESET_X_ASCENT_DESCENT(IT) \
7040 ((IT)->current_x = x, (IT)->max_ascent = ascent, \
7041 (IT)->max_descent = descent)
7042
7043 /* Stop if we move beyond TO_CHARPOS (after an image or stretch
7044 glyph). */
7045 if ((op & MOVE_TO_POS) != 0
7046 && BUFFERP (it->object)
7047 && it->method == GET_FROM_BUFFER
7048 && ((!it->bidi_p && IT_CHARPOS (*it) > to_charpos)
7049 || (it->bidi_p
7050 && (prev_method == GET_FROM_IMAGE
7051 || prev_method == GET_FROM_STRETCH)
7052 /* Passed TO_CHARPOS from left to right. */
7053 && ((prev_pos < to_charpos
7054 && IT_CHARPOS (*it) > to_charpos)
7055 /* Passed TO_CHARPOS from right to left. */
7056 || (prev_pos > to_charpos
7057 && IT_CHARPOS (*it) < to_charpos)))))
7058 {
7059 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
7060 {
7061 result = MOVE_POS_MATCH_OR_ZV;
7062 break;
7063 }
7064 else if (it->line_wrap == WORD_WRAP && atpos_it.sp < 0)
7065 /* If wrap_it is valid, the current position might be in a
7066 word that is wrapped. So, save the iterator in
7067 atpos_it and continue to see if wrapping happens. */
7068 atpos_it = *it;
7069 }
7070
7071 prev_method = it->method;
7072 if (it->method == GET_FROM_BUFFER)
7073 prev_pos = IT_CHARPOS (*it);
7074 /* Stop when ZV reached.
7075 We used to stop here when TO_CHARPOS reached as well, but that is
7076 too soon if this glyph does not fit on this line. So we handle it
7077 explicitly below. */
7078 if (!get_next_display_element (it))
7079 {
7080 result = MOVE_POS_MATCH_OR_ZV;
7081 break;
7082 }
7083
7084 if (it->line_wrap == TRUNCATE)
7085 {
7086 if (BUFFER_POS_REACHED_P ())
7087 {
7088 result = MOVE_POS_MATCH_OR_ZV;
7089 break;
7090 }
7091 }
7092 else
7093 {
7094 if (it->line_wrap == WORD_WRAP)
7095 {
7096 if (IT_DISPLAYING_WHITESPACE (it))
7097 may_wrap = 1;
7098 else if (may_wrap)
7099 {
7100 /* We have reached a glyph that follows one or more
7101 whitespace characters. If the position is
7102 already found, we are done. */
7103 if (atpos_it.sp >= 0)
7104 {
7105 *it = atpos_it;
7106 result = MOVE_POS_MATCH_OR_ZV;
7107 goto done;
7108 }
7109 if (atx_it.sp >= 0)
7110 {
7111 *it = atx_it;
7112 result = MOVE_X_REACHED;
7113 goto done;
7114 }
7115 /* Otherwise, we can wrap here. */
7116 wrap_it = *it;
7117 may_wrap = 0;
7118 }
7119 }
7120 }
7121
7122 /* Remember the line height for the current line, in case
7123 the next element doesn't fit on the line. */
7124 ascent = it->max_ascent;
7125 descent = it->max_descent;
7126
7127 /* The call to produce_glyphs will get the metrics of the
7128 display element IT is loaded with. Record the x-position
7129 before this display element, in case it doesn't fit on the
7130 line. */
7131 x = it->current_x;
7132
7133 PRODUCE_GLYPHS (it);
7134
7135 if (it->area != TEXT_AREA)
7136 {
7137 set_iterator_to_next (it, 1);
7138 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
7139 SET_TEXT_POS (this_line_min_pos,
7140 IT_CHARPOS (*it), IT_BYTEPOS (*it));
7141 continue;
7142 }
7143
7144 /* The number of glyphs we get back in IT->nglyphs will normally
7145 be 1 except when IT->c is (i) a TAB, or (ii) a multi-glyph
7146 character on a terminal frame, or (iii) a line end. For the
7147 second case, IT->nglyphs - 1 padding glyphs will be present.
7148 (On X frames, there is only one glyph produced for a
7149 composite character.)
7150
7151 The behavior implemented below means, for continuation lines,
7152 that as many spaces of a TAB as fit on the current line are
7153 displayed there. For terminal frames, as many glyphs of a
7154 multi-glyph character are displayed in the current line, too.
7155 This is what the old redisplay code did, and we keep it that
7156 way. Under X, the whole shape of a complex character must
7157 fit on the line or it will be completely displayed in the
7158 next line.
7159
7160 Note that both for tabs and padding glyphs, all glyphs have
7161 the same width. */
7162 if (it->nglyphs)
7163 {
7164 /* More than one glyph or glyph doesn't fit on line. All
7165 glyphs have the same width. */
7166 int single_glyph_width = it->pixel_width / it->nglyphs;
7167 int new_x;
7168 int x_before_this_char = x;
7169 int hpos_before_this_char = it->hpos;
7170
7171 for (i = 0; i < it->nglyphs; ++i, x = new_x)
7172 {
7173 new_x = x + single_glyph_width;
7174
7175 /* We want to leave anything reaching TO_X to the caller. */
7176 if ((op & MOVE_TO_X) && new_x > to_x)
7177 {
7178 if (BUFFER_POS_REACHED_P ())
7179 {
7180 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
7181 goto buffer_pos_reached;
7182 if (atpos_it.sp < 0)
7183 {
7184 atpos_it = *it;
7185 IT_RESET_X_ASCENT_DESCENT (&atpos_it);
7186 }
7187 }
7188 else
7189 {
7190 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
7191 {
7192 it->current_x = x;
7193 result = MOVE_X_REACHED;
7194 break;
7195 }
7196 if (atx_it.sp < 0)
7197 {
7198 atx_it = *it;
7199 IT_RESET_X_ASCENT_DESCENT (&atx_it);
7200 }
7201 }
7202 }
7203
7204 if (/* Lines are continued. */
7205 it->line_wrap != TRUNCATE
7206 && (/* And glyph doesn't fit on the line. */
7207 new_x > it->last_visible_x
7208 /* Or it fits exactly and we're on a window
7209 system frame. */
7210 || (new_x == it->last_visible_x
7211 && FRAME_WINDOW_P (it->f))))
7212 {
7213 if (/* IT->hpos == 0 means the very first glyph
7214 doesn't fit on the line, e.g. a wide image. */
7215 it->hpos == 0
7216 || (new_x == it->last_visible_x
7217 && FRAME_WINDOW_P (it->f)))
7218 {
7219 ++it->hpos;
7220 it->current_x = new_x;
7221
7222 /* The character's last glyph just barely fits
7223 in this row. */
7224 if (i == it->nglyphs - 1)
7225 {
7226 /* If this is the destination position,
7227 return a position *before* it in this row,
7228 now that we know it fits in this row. */
7229 if (BUFFER_POS_REACHED_P ())
7230 {
7231 if (it->line_wrap != WORD_WRAP
7232 || wrap_it.sp < 0)
7233 {
7234 it->hpos = hpos_before_this_char;
7235 it->current_x = x_before_this_char;
7236 result = MOVE_POS_MATCH_OR_ZV;
7237 break;
7238 }
7239 if (it->line_wrap == WORD_WRAP
7240 && atpos_it.sp < 0)
7241 {
7242 atpos_it = *it;
7243 atpos_it.current_x = x_before_this_char;
7244 atpos_it.hpos = hpos_before_this_char;
7245 }
7246 }
7247
7248 set_iterator_to_next (it, 1);
7249 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
7250 SET_TEXT_POS (this_line_min_pos,
7251 IT_CHARPOS (*it), IT_BYTEPOS (*it));
7252 /* On graphical terminals, newlines may
7253 "overflow" into the fringe if
7254 overflow-newline-into-fringe is non-nil.
7255 On text-only terminals, newlines may
7256 overflow into the last glyph on the
7257 display line.*/
7258 if (!FRAME_WINDOW_P (it->f)
7259 || IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
7260 {
7261 if (!get_next_display_element (it))
7262 {
7263 result = MOVE_POS_MATCH_OR_ZV;
7264 break;
7265 }
7266 if (BUFFER_POS_REACHED_P ())
7267 {
7268 if (ITERATOR_AT_END_OF_LINE_P (it))
7269 result = MOVE_POS_MATCH_OR_ZV;
7270 else
7271 result = MOVE_LINE_CONTINUED;
7272 break;
7273 }
7274 if (ITERATOR_AT_END_OF_LINE_P (it))
7275 {
7276 result = MOVE_NEWLINE_OR_CR;
7277 break;
7278 }
7279 }
7280 }
7281 }
7282 else
7283 IT_RESET_X_ASCENT_DESCENT (it);
7284
7285 if (wrap_it.sp >= 0)
7286 {
7287 *it = wrap_it;
7288 atpos_it.sp = -1;
7289 atx_it.sp = -1;
7290 }
7291
7292 TRACE_MOVE ((stderr, "move_it_in: continued at %d\n",
7293 IT_CHARPOS (*it)));
7294 result = MOVE_LINE_CONTINUED;
7295 break;
7296 }
7297
7298 if (BUFFER_POS_REACHED_P ())
7299 {
7300 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
7301 goto buffer_pos_reached;
7302 if (it->line_wrap == WORD_WRAP && atpos_it.sp < 0)
7303 {
7304 atpos_it = *it;
7305 IT_RESET_X_ASCENT_DESCENT (&atpos_it);
7306 }
7307 }
7308
7309 if (new_x > it->first_visible_x)
7310 {
7311 /* Glyph is visible. Increment number of glyphs that
7312 would be displayed. */
7313 ++it->hpos;
7314 }
7315 }
7316
7317 if (result != MOVE_UNDEFINED)
7318 break;
7319 }
7320 else if (BUFFER_POS_REACHED_P ())
7321 {
7322 buffer_pos_reached:
7323 IT_RESET_X_ASCENT_DESCENT (it);
7324 result = MOVE_POS_MATCH_OR_ZV;
7325 break;
7326 }
7327 else if ((op & MOVE_TO_X) && it->current_x >= to_x)
7328 {
7329 /* Stop when TO_X specified and reached. This check is
7330 necessary here because of lines consisting of a line end,
7331 only. The line end will not produce any glyphs and we
7332 would never get MOVE_X_REACHED. */
7333 xassert (it->nglyphs == 0);
7334 result = MOVE_X_REACHED;
7335 break;
7336 }
7337
7338 /* Is this a line end? If yes, we're done. */
7339 if (ITERATOR_AT_END_OF_LINE_P (it))
7340 {
7341 result = MOVE_NEWLINE_OR_CR;
7342 break;
7343 }
7344
7345 if (it->method == GET_FROM_BUFFER)
7346 prev_pos = IT_CHARPOS (*it);
7347 /* The current display element has been consumed. Advance
7348 to the next. */
7349 set_iterator_to_next (it, 1);
7350 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
7351 SET_TEXT_POS (this_line_min_pos, IT_CHARPOS (*it), IT_BYTEPOS (*it));
7352
7353 /* Stop if lines are truncated and IT's current x-position is
7354 past the right edge of the window now. */
7355 if (it->line_wrap == TRUNCATE
7356 && it->current_x >= it->last_visible_x)
7357 {
7358 if (!FRAME_WINDOW_P (it->f)
7359 || IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
7360 {
7361 if (!get_next_display_element (it)
7362 || BUFFER_POS_REACHED_P ())
7363 {
7364 result = MOVE_POS_MATCH_OR_ZV;
7365 break;
7366 }
7367 if (ITERATOR_AT_END_OF_LINE_P (it))
7368 {
7369 result = MOVE_NEWLINE_OR_CR;
7370 break;
7371 }
7372 }
7373 result = MOVE_LINE_TRUNCATED;
7374 break;
7375 }
7376 #undef IT_RESET_X_ASCENT_DESCENT
7377 }
7378
7379 #undef BUFFER_POS_REACHED_P
7380
7381 /* If we scanned beyond to_pos and didn't find a point to wrap at,
7382 restore the saved iterator. */
7383 if (atpos_it.sp >= 0)
7384 *it = atpos_it;
7385 else if (atx_it.sp >= 0)
7386 *it = atx_it;
7387
7388 done:
7389
7390 /* Restore the iterator settings altered at the beginning of this
7391 function. */
7392 it->glyph_row = saved_glyph_row;
7393 return result;
7394 }
7395
7396 /* For external use. */
7397 void
7398 move_it_in_display_line (struct it *it,
7399 EMACS_INT to_charpos, int to_x,
7400 enum move_operation_enum op)
7401 {
7402 if (it->line_wrap == WORD_WRAP
7403 && (op & MOVE_TO_X))
7404 {
7405 struct it save_it = *it;
7406 int skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
7407 /* When word-wrap is on, TO_X may lie past the end
7408 of a wrapped line. Then it->current is the
7409 character on the next line, so backtrack to the
7410 space before the wrap point. */
7411 if (skip == MOVE_LINE_CONTINUED)
7412 {
7413 int prev_x = max (it->current_x - 1, 0);
7414 *it = save_it;
7415 move_it_in_display_line_to
7416 (it, -1, prev_x, MOVE_TO_X);
7417 }
7418 }
7419 else
7420 move_it_in_display_line_to (it, to_charpos, to_x, op);
7421 }
7422
7423
7424 /* Move IT forward until it satisfies one or more of the criteria in
7425 TO_CHARPOS, TO_X, TO_Y, and TO_VPOS.
7426
7427 OP is a bit-mask that specifies where to stop, and in particular,
7428 which of those four position arguments makes a difference. See the
7429 description of enum move_operation_enum.
7430
7431 If TO_CHARPOS is in invisible text, e.g. a truncated part of a
7432 screen line, this function will set IT to the next position >
7433 TO_CHARPOS. */
7434
7435 void
7436 move_it_to (struct it *it, EMACS_INT to_charpos, int to_x, int to_y, int to_vpos, int op)
7437 {
7438 enum move_it_result skip, skip2 = MOVE_X_REACHED;
7439 int line_height, line_start_x = 0, reached = 0;
7440
7441 for (;;)
7442 {
7443 if (op & MOVE_TO_VPOS)
7444 {
7445 /* If no TO_CHARPOS and no TO_X specified, stop at the
7446 start of the line TO_VPOS. */
7447 if ((op & (MOVE_TO_X | MOVE_TO_POS)) == 0)
7448 {
7449 if (it->vpos == to_vpos)
7450 {
7451 reached = 1;
7452 break;
7453 }
7454 else
7455 skip = move_it_in_display_line_to (it, -1, -1, 0);
7456 }
7457 else
7458 {
7459 /* TO_VPOS >= 0 means stop at TO_X in the line at
7460 TO_VPOS, or at TO_POS, whichever comes first. */
7461 if (it->vpos == to_vpos)
7462 {
7463 reached = 2;
7464 break;
7465 }
7466
7467 skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
7468
7469 if (skip == MOVE_POS_MATCH_OR_ZV || it->vpos == to_vpos)
7470 {
7471 reached = 3;
7472 break;
7473 }
7474 else if (skip == MOVE_X_REACHED && it->vpos != to_vpos)
7475 {
7476 /* We have reached TO_X but not in the line we want. */
7477 skip = move_it_in_display_line_to (it, to_charpos,
7478 -1, MOVE_TO_POS);
7479 if (skip == MOVE_POS_MATCH_OR_ZV)
7480 {
7481 reached = 4;
7482 break;
7483 }
7484 }
7485 }
7486 }
7487 else if (op & MOVE_TO_Y)
7488 {
7489 struct it it_backup;
7490
7491 if (it->line_wrap == WORD_WRAP)
7492 it_backup = *it;
7493
7494 /* TO_Y specified means stop at TO_X in the line containing
7495 TO_Y---or at TO_CHARPOS if this is reached first. The
7496 problem is that we can't really tell whether the line
7497 contains TO_Y before we have completely scanned it, and
7498 this may skip past TO_X. What we do is to first scan to
7499 TO_X.
7500
7501 If TO_X is not specified, use a TO_X of zero. The reason
7502 is to make the outcome of this function more predictable.
7503 If we didn't use TO_X == 0, we would stop at the end of
7504 the line which is probably not what a caller would expect
7505 to happen. */
7506 skip = move_it_in_display_line_to
7507 (it, to_charpos, ((op & MOVE_TO_X) ? to_x : 0),
7508 (MOVE_TO_X | (op & MOVE_TO_POS)));
7509
7510 /* If TO_CHARPOS is reached or ZV, we don't have to do more. */
7511 if (skip == MOVE_POS_MATCH_OR_ZV)
7512 reached = 5;
7513 else if (skip == MOVE_X_REACHED)
7514 {
7515 /* If TO_X was reached, we want to know whether TO_Y is
7516 in the line. We know this is the case if the already
7517 scanned glyphs make the line tall enough. Otherwise,
7518 we must check by scanning the rest of the line. */
7519 line_height = it->max_ascent + it->max_descent;
7520 if (to_y >= it->current_y
7521 && to_y < it->current_y + line_height)
7522 {
7523 reached = 6;
7524 break;
7525 }
7526 it_backup = *it;
7527 TRACE_MOVE ((stderr, "move_it: from %d\n", IT_CHARPOS (*it)));
7528 skip2 = move_it_in_display_line_to (it, to_charpos, -1,
7529 op & MOVE_TO_POS);
7530 TRACE_MOVE ((stderr, "move_it: to %d\n", IT_CHARPOS (*it)));
7531 line_height = it->max_ascent + it->max_descent;
7532 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
7533
7534 if (to_y >= it->current_y
7535 && to_y < it->current_y + line_height)
7536 {
7537 /* If TO_Y is in this line and TO_X was reached
7538 above, we scanned too far. We have to restore
7539 IT's settings to the ones before skipping. */
7540 *it = it_backup;
7541 reached = 6;
7542 }
7543 else
7544 {
7545 skip = skip2;
7546 if (skip == MOVE_POS_MATCH_OR_ZV)
7547 reached = 7;
7548 }
7549 }
7550 else
7551 {
7552 /* Check whether TO_Y is in this line. */
7553 line_height = it->max_ascent + it->max_descent;
7554 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
7555
7556 if (to_y >= it->current_y
7557 && to_y < it->current_y + line_height)
7558 {
7559 /* When word-wrap is on, TO_X may lie past the end
7560 of a wrapped line. Then it->current is the
7561 character on the next line, so backtrack to the
7562 space before the wrap point. */
7563 if (skip == MOVE_LINE_CONTINUED
7564 && it->line_wrap == WORD_WRAP)
7565 {
7566 int prev_x = max (it->current_x - 1, 0);
7567 *it = it_backup;
7568 skip = move_it_in_display_line_to
7569 (it, -1, prev_x, MOVE_TO_X);
7570 }
7571 reached = 6;
7572 }
7573 }
7574
7575 if (reached)
7576 break;
7577 }
7578 else if (BUFFERP (it->object)
7579 && (it->method == GET_FROM_BUFFER
7580 || it->method == GET_FROM_STRETCH)
7581 && IT_CHARPOS (*it) >= to_charpos)
7582 skip = MOVE_POS_MATCH_OR_ZV;
7583 else
7584 skip = move_it_in_display_line_to (it, to_charpos, -1, MOVE_TO_POS);
7585
7586 switch (skip)
7587 {
7588 case MOVE_POS_MATCH_OR_ZV:
7589 reached = 8;
7590 goto out;
7591
7592 case MOVE_NEWLINE_OR_CR:
7593 set_iterator_to_next (it, 1);
7594 it->continuation_lines_width = 0;
7595 break;
7596
7597 case MOVE_LINE_TRUNCATED:
7598 it->continuation_lines_width = 0;
7599 reseat_at_next_visible_line_start (it, 0);
7600 if ((op & MOVE_TO_POS) != 0
7601 && IT_CHARPOS (*it) > to_charpos)
7602 {
7603 reached = 9;
7604 goto out;
7605 }
7606 break;
7607
7608 case MOVE_LINE_CONTINUED:
7609 /* For continued lines ending in a tab, some of the glyphs
7610 associated with the tab are displayed on the current
7611 line. Since it->current_x does not include these glyphs,
7612 we use it->last_visible_x instead. */
7613 if (it->c == '\t')
7614 {
7615 it->continuation_lines_width += it->last_visible_x;
7616 /* When moving by vpos, ensure that the iterator really
7617 advances to the next line (bug#847, bug#969). Fixme:
7618 do we need to do this in other circumstances? */
7619 if (it->current_x != it->last_visible_x
7620 && (op & MOVE_TO_VPOS)
7621 && !(op & (MOVE_TO_X | MOVE_TO_POS)))
7622 {
7623 line_start_x = it->current_x + it->pixel_width
7624 - it->last_visible_x;
7625 set_iterator_to_next (it, 0);
7626 }
7627 }
7628 else
7629 it->continuation_lines_width += it->current_x;
7630 break;
7631
7632 default:
7633 abort ();
7634 }
7635
7636 /* Reset/increment for the next run. */
7637 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
7638 it->current_x = line_start_x;
7639 line_start_x = 0;
7640 it->hpos = 0;
7641 it->current_y += it->max_ascent + it->max_descent;
7642 ++it->vpos;
7643 last_height = it->max_ascent + it->max_descent;
7644 last_max_ascent = it->max_ascent;
7645 it->max_ascent = it->max_descent = 0;
7646 }
7647
7648 out:
7649
7650 /* On text terminals, we may stop at the end of a line in the middle
7651 of a multi-character glyph. If the glyph itself is continued,
7652 i.e. it is actually displayed on the next line, don't treat this
7653 stopping point as valid; move to the next line instead (unless
7654 that brings us offscreen). */
7655 if (!FRAME_WINDOW_P (it->f)
7656 && op & MOVE_TO_POS
7657 && IT_CHARPOS (*it) == to_charpos
7658 && it->what == IT_CHARACTER
7659 && it->nglyphs > 1
7660 && it->line_wrap == WINDOW_WRAP
7661 && it->current_x == it->last_visible_x - 1
7662 && it->c != '\n'
7663 && it->c != '\t'
7664 && it->vpos < XFASTINT (it->w->window_end_vpos))
7665 {
7666 it->continuation_lines_width += it->current_x;
7667 it->current_x = it->hpos = it->max_ascent = it->max_descent = 0;
7668 it->current_y += it->max_ascent + it->max_descent;
7669 ++it->vpos;
7670 last_height = it->max_ascent + it->max_descent;
7671 last_max_ascent = it->max_ascent;
7672 }
7673
7674 TRACE_MOVE ((stderr, "move_it_to: reached %d\n", reached));
7675 }
7676
7677
7678 /* Move iterator IT backward by a specified y-distance DY, DY >= 0.
7679
7680 If DY > 0, move IT backward at least that many pixels. DY = 0
7681 means move IT backward to the preceding line start or BEGV. This
7682 function may move over more than DY pixels if IT->current_y - DY
7683 ends up in the middle of a line; in this case IT->current_y will be
7684 set to the top of the line moved to. */
7685
7686 void
7687 move_it_vertically_backward (struct it *it, int dy)
7688 {
7689 int nlines, h;
7690 struct it it2, it3;
7691 EMACS_INT start_pos;
7692
7693 move_further_back:
7694 xassert (dy >= 0);
7695
7696 start_pos = IT_CHARPOS (*it);
7697
7698 /* Estimate how many newlines we must move back. */
7699 nlines = max (1, dy / FRAME_LINE_HEIGHT (it->f));
7700
7701 /* Set the iterator's position that many lines back. */
7702 while (nlines-- && IT_CHARPOS (*it) > BEGV)
7703 back_to_previous_visible_line_start (it);
7704
7705 /* Reseat the iterator here. When moving backward, we don't want
7706 reseat to skip forward over invisible text, set up the iterator
7707 to deliver from overlay strings at the new position etc. So,
7708 use reseat_1 here. */
7709 reseat_1 (it, it->current.pos, 1);
7710
7711 /* We are now surely at a line start. */
7712 it->current_x = it->hpos = 0;
7713 it->continuation_lines_width = 0;
7714
7715 /* Move forward and see what y-distance we moved. First move to the
7716 start of the next line so that we get its height. We need this
7717 height to be able to tell whether we reached the specified
7718 y-distance. */
7719 it2 = *it;
7720 it2.max_ascent = it2.max_descent = 0;
7721 do
7722 {
7723 move_it_to (&it2, start_pos, -1, -1, it2.vpos + 1,
7724 MOVE_TO_POS | MOVE_TO_VPOS);
7725 }
7726 while (!IT_POS_VALID_AFTER_MOVE_P (&it2));
7727 xassert (IT_CHARPOS (*it) >= BEGV);
7728 it3 = it2;
7729
7730 move_it_to (&it2, start_pos, -1, -1, -1, MOVE_TO_POS);
7731 xassert (IT_CHARPOS (*it) >= BEGV);
7732 /* H is the actual vertical distance from the position in *IT
7733 and the starting position. */
7734 h = it2.current_y - it->current_y;
7735 /* NLINES is the distance in number of lines. */
7736 nlines = it2.vpos - it->vpos;
7737
7738 /* Correct IT's y and vpos position
7739 so that they are relative to the starting point. */
7740 it->vpos -= nlines;
7741 it->current_y -= h;
7742
7743 if (dy == 0)
7744 {
7745 /* DY == 0 means move to the start of the screen line. The
7746 value of nlines is > 0 if continuation lines were involved. */
7747 if (nlines > 0)
7748 move_it_by_lines (it, nlines);
7749 }
7750 else
7751 {
7752 /* The y-position we try to reach, relative to *IT.
7753 Note that H has been subtracted in front of the if-statement. */
7754 int target_y = it->current_y + h - dy;
7755 int y0 = it3.current_y;
7756 int y1 = line_bottom_y (&it3);
7757 int line_height = y1 - y0;
7758
7759 /* If we did not reach target_y, try to move further backward if
7760 we can. If we moved too far backward, try to move forward. */
7761 if (target_y < it->current_y
7762 /* This is heuristic. In a window that's 3 lines high, with
7763 a line height of 13 pixels each, recentering with point
7764 on the bottom line will try to move -39/2 = 19 pixels
7765 backward. Try to avoid moving into the first line. */
7766 && (it->current_y - target_y
7767 > min (window_box_height (it->w), line_height * 2 / 3))
7768 && IT_CHARPOS (*it) > BEGV)
7769 {
7770 TRACE_MOVE ((stderr, " not far enough -> move_vert %d\n",
7771 target_y - it->current_y));
7772 dy = it->current_y - target_y;
7773 goto move_further_back;
7774 }
7775 else if (target_y >= it->current_y + line_height
7776 && IT_CHARPOS (*it) < ZV)
7777 {
7778 /* Should move forward by at least one line, maybe more.
7779
7780 Note: Calling move_it_by_lines can be expensive on
7781 terminal frames, where compute_motion is used (via
7782 vmotion) to do the job, when there are very long lines
7783 and truncate-lines is nil. That's the reason for
7784 treating terminal frames specially here. */
7785
7786 if (!FRAME_WINDOW_P (it->f))
7787 move_it_vertically (it, target_y - (it->current_y + line_height));
7788 else
7789 {
7790 do
7791 {
7792 move_it_by_lines (it, 1);
7793 }
7794 while (target_y >= line_bottom_y (it) && IT_CHARPOS (*it) < ZV);
7795 }
7796 }
7797 }
7798 }
7799
7800
7801 /* Move IT by a specified amount of pixel lines DY. DY negative means
7802 move backwards. DY = 0 means move to start of screen line. At the
7803 end, IT will be on the start of a screen line. */
7804
7805 void
7806 move_it_vertically (struct it *it, int dy)
7807 {
7808 if (dy <= 0)
7809 move_it_vertically_backward (it, -dy);
7810 else
7811 {
7812 TRACE_MOVE ((stderr, "move_it_v: from %d, %d\n", IT_CHARPOS (*it), dy));
7813 move_it_to (it, ZV, -1, it->current_y + dy, -1,
7814 MOVE_TO_POS | MOVE_TO_Y);
7815 TRACE_MOVE ((stderr, "move_it_v: to %d\n", IT_CHARPOS (*it)));
7816
7817 /* If buffer ends in ZV without a newline, move to the start of
7818 the line to satisfy the post-condition. */
7819 if (IT_CHARPOS (*it) == ZV
7820 && ZV > BEGV
7821 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
7822 move_it_by_lines (it, 0);
7823 }
7824 }
7825
7826
7827 /* Move iterator IT past the end of the text line it is in. */
7828
7829 void
7830 move_it_past_eol (struct it *it)
7831 {
7832 enum move_it_result rc;
7833
7834 rc = move_it_in_display_line_to (it, Z, 0, MOVE_TO_POS);
7835 if (rc == MOVE_NEWLINE_OR_CR)
7836 set_iterator_to_next (it, 0);
7837 }
7838
7839
7840 /* Move IT by a specified number DVPOS of screen lines down. DVPOS
7841 negative means move up. DVPOS == 0 means move to the start of the
7842 screen line.
7843
7844 Optimization idea: If we would know that IT->f doesn't use
7845 a face with proportional font, we could be faster for
7846 truncate-lines nil. */
7847
7848 void
7849 move_it_by_lines (struct it *it, int dvpos)
7850 {
7851
7852 /* The commented-out optimization uses vmotion on terminals. This
7853 gives bad results, because elements like it->what, on which
7854 callers such as pos_visible_p rely, aren't updated. */
7855 /* struct position pos;
7856 if (!FRAME_WINDOW_P (it->f))
7857 {
7858 struct text_pos textpos;
7859
7860 pos = *vmotion (IT_CHARPOS (*it), dvpos, it->w);
7861 SET_TEXT_POS (textpos, pos.bufpos, pos.bytepos);
7862 reseat (it, textpos, 1);
7863 it->vpos += pos.vpos;
7864 it->current_y += pos.vpos;
7865 }
7866 else */
7867
7868 if (dvpos == 0)
7869 {
7870 /* DVPOS == 0 means move to the start of the screen line. */
7871 move_it_vertically_backward (it, 0);
7872 xassert (it->current_x == 0 && it->hpos == 0);
7873 /* Let next call to line_bottom_y calculate real line height */
7874 last_height = 0;
7875 }
7876 else if (dvpos > 0)
7877 {
7878 move_it_to (it, -1, -1, -1, it->vpos + dvpos, MOVE_TO_VPOS);
7879 if (!IT_POS_VALID_AFTER_MOVE_P (it))
7880 move_it_to (it, IT_CHARPOS (*it) + 1, -1, -1, -1, MOVE_TO_POS);
7881 }
7882 else
7883 {
7884 struct it it2;
7885 EMACS_INT start_charpos, i;
7886
7887 /* Start at the beginning of the screen line containing IT's
7888 position. This may actually move vertically backwards,
7889 in case of overlays, so adjust dvpos accordingly. */
7890 dvpos += it->vpos;
7891 move_it_vertically_backward (it, 0);
7892 dvpos -= it->vpos;
7893
7894 /* Go back -DVPOS visible lines and reseat the iterator there. */
7895 start_charpos = IT_CHARPOS (*it);
7896 for (i = -dvpos; i > 0 && IT_CHARPOS (*it) > BEGV; --i)
7897 back_to_previous_visible_line_start (it);
7898 reseat (it, it->current.pos, 1);
7899
7900 /* Move further back if we end up in a string or an image. */
7901 while (!IT_POS_VALID_AFTER_MOVE_P (it))
7902 {
7903 /* First try to move to start of display line. */
7904 dvpos += it->vpos;
7905 move_it_vertically_backward (it, 0);
7906 dvpos -= it->vpos;
7907 if (IT_POS_VALID_AFTER_MOVE_P (it))
7908 break;
7909 /* If start of line is still in string or image,
7910 move further back. */
7911 back_to_previous_visible_line_start (it);
7912 reseat (it, it->current.pos, 1);
7913 dvpos--;
7914 }
7915
7916 it->current_x = it->hpos = 0;
7917
7918 /* Above call may have moved too far if continuation lines
7919 are involved. Scan forward and see if it did. */
7920 it2 = *it;
7921 it2.vpos = it2.current_y = 0;
7922 move_it_to (&it2, start_charpos, -1, -1, -1, MOVE_TO_POS);
7923 it->vpos -= it2.vpos;
7924 it->current_y -= it2.current_y;
7925 it->current_x = it->hpos = 0;
7926
7927 /* If we moved too far back, move IT some lines forward. */
7928 if (it2.vpos > -dvpos)
7929 {
7930 int delta = it2.vpos + dvpos;
7931 it2 = *it;
7932 move_it_to (it, -1, -1, -1, it->vpos + delta, MOVE_TO_VPOS);
7933 /* Move back again if we got too far ahead. */
7934 if (IT_CHARPOS (*it) >= start_charpos)
7935 *it = it2;
7936 }
7937 }
7938 }
7939
7940 /* Return 1 if IT points into the middle of a display vector. */
7941
7942 int
7943 in_display_vector_p (struct it *it)
7944 {
7945 return (it->method == GET_FROM_DISPLAY_VECTOR
7946 && it->current.dpvec_index > 0
7947 && it->dpvec + it->current.dpvec_index != it->dpend);
7948 }
7949
7950 \f
7951 /***********************************************************************
7952 Messages
7953 ***********************************************************************/
7954
7955
7956 /* Add a message with format string FORMAT and arguments ARG1 and ARG2
7957 to *Messages*. */
7958
7959 void
7960 add_to_log (const char *format, Lisp_Object arg1, Lisp_Object arg2)
7961 {
7962 Lisp_Object args[3];
7963 Lisp_Object msg, fmt;
7964 char *buffer;
7965 EMACS_INT len;
7966 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
7967 USE_SAFE_ALLOCA;
7968
7969 /* Do nothing if called asynchronously. Inserting text into
7970 a buffer may call after-change-functions and alike and
7971 that would means running Lisp asynchronously. */
7972 if (handling_signal)
7973 return;
7974
7975 fmt = msg = Qnil;
7976 GCPRO4 (fmt, msg, arg1, arg2);
7977
7978 args[0] = fmt = build_string (format);
7979 args[1] = arg1;
7980 args[2] = arg2;
7981 msg = Fformat (3, args);
7982
7983 len = SBYTES (msg) + 1;
7984 SAFE_ALLOCA (buffer, char *, len);
7985 memcpy (buffer, SDATA (msg), len);
7986
7987 message_dolog (buffer, len - 1, 1, 0);
7988 SAFE_FREE ();
7989
7990 UNGCPRO;
7991 }
7992
7993
7994 /* Output a newline in the *Messages* buffer if "needs" one. */
7995
7996 void
7997 message_log_maybe_newline (void)
7998 {
7999 if (message_log_need_newline)
8000 message_dolog ("", 0, 1, 0);
8001 }
8002
8003
8004 /* Add a string M of length NBYTES to the message log, optionally
8005 terminated with a newline when NLFLAG is non-zero. MULTIBYTE, if
8006 nonzero, means interpret the contents of M as multibyte. This
8007 function calls low-level routines in order to bypass text property
8008 hooks, etc. which might not be safe to run.
8009
8010 This may GC (insert may run before/after change hooks),
8011 so the buffer M must NOT point to a Lisp string. */
8012
8013 void
8014 message_dolog (const char *m, EMACS_INT nbytes, int nlflag, int multibyte)
8015 {
8016 const unsigned char *msg = (const unsigned char *) m;
8017
8018 if (!NILP (Vmemory_full))
8019 return;
8020
8021 if (!NILP (Vmessage_log_max))
8022 {
8023 struct buffer *oldbuf;
8024 Lisp_Object oldpoint, oldbegv, oldzv;
8025 int old_windows_or_buffers_changed = windows_or_buffers_changed;
8026 EMACS_INT point_at_end = 0;
8027 EMACS_INT zv_at_end = 0;
8028 Lisp_Object old_deactivate_mark, tem;
8029 struct gcpro gcpro1;
8030
8031 old_deactivate_mark = Vdeactivate_mark;
8032 oldbuf = current_buffer;
8033 Fset_buffer (Fget_buffer_create (Vmessages_buffer_name));
8034 BVAR (current_buffer, undo_list) = Qt;
8035
8036 oldpoint = message_dolog_marker1;
8037 set_marker_restricted (oldpoint, make_number (PT), Qnil);
8038 oldbegv = message_dolog_marker2;
8039 set_marker_restricted (oldbegv, make_number (BEGV), Qnil);
8040 oldzv = message_dolog_marker3;
8041 set_marker_restricted (oldzv, make_number (ZV), Qnil);
8042 GCPRO1 (old_deactivate_mark);
8043
8044 if (PT == Z)
8045 point_at_end = 1;
8046 if (ZV == Z)
8047 zv_at_end = 1;
8048
8049 BEGV = BEG;
8050 BEGV_BYTE = BEG_BYTE;
8051 ZV = Z;
8052 ZV_BYTE = Z_BYTE;
8053 TEMP_SET_PT_BOTH (Z, Z_BYTE);
8054
8055 /* Insert the string--maybe converting multibyte to single byte
8056 or vice versa, so that all the text fits the buffer. */
8057 if (multibyte
8058 && NILP (BVAR (current_buffer, enable_multibyte_characters)))
8059 {
8060 EMACS_INT i;
8061 int c, char_bytes;
8062 char work[1];
8063
8064 /* Convert a multibyte string to single-byte
8065 for the *Message* buffer. */
8066 for (i = 0; i < nbytes; i += char_bytes)
8067 {
8068 c = string_char_and_length (msg + i, &char_bytes);
8069 work[0] = (ASCII_CHAR_P (c)
8070 ? c
8071 : multibyte_char_to_unibyte (c));
8072 insert_1_both (work, 1, 1, 1, 0, 0);
8073 }
8074 }
8075 else if (! multibyte
8076 && ! NILP (BVAR (current_buffer, enable_multibyte_characters)))
8077 {
8078 EMACS_INT i;
8079 int c, char_bytes;
8080 unsigned char str[MAX_MULTIBYTE_LENGTH];
8081 /* Convert a single-byte string to multibyte
8082 for the *Message* buffer. */
8083 for (i = 0; i < nbytes; i++)
8084 {
8085 c = msg[i];
8086 MAKE_CHAR_MULTIBYTE (c);
8087 char_bytes = CHAR_STRING (c, str);
8088 insert_1_both ((char *) str, 1, char_bytes, 1, 0, 0);
8089 }
8090 }
8091 else if (nbytes)
8092 insert_1 (m, nbytes, 1, 0, 0);
8093
8094 if (nlflag)
8095 {
8096 EMACS_INT this_bol, this_bol_byte, prev_bol, prev_bol_byte;
8097 unsigned long int dups;
8098 insert_1 ("\n", 1, 1, 0, 0);
8099
8100 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE, -2, 0);
8101 this_bol = PT;
8102 this_bol_byte = PT_BYTE;
8103
8104 /* See if this line duplicates the previous one.
8105 If so, combine duplicates. */
8106 if (this_bol > BEG)
8107 {
8108 scan_newline (PT, PT_BYTE, BEG, BEG_BYTE, -2, 0);
8109 prev_bol = PT;
8110 prev_bol_byte = PT_BYTE;
8111
8112 dups = message_log_check_duplicate (prev_bol_byte,
8113 this_bol_byte);
8114 if (dups)
8115 {
8116 del_range_both (prev_bol, prev_bol_byte,
8117 this_bol, this_bol_byte, 0);
8118 if (dups > 1)
8119 {
8120 char dupstr[40];
8121 int duplen;
8122
8123 /* If you change this format, don't forget to also
8124 change message_log_check_duplicate. */
8125 sprintf (dupstr, " [%lu times]", dups);
8126 duplen = strlen (dupstr);
8127 TEMP_SET_PT_BOTH (Z - 1, Z_BYTE - 1);
8128 insert_1 (dupstr, duplen, 1, 0, 1);
8129 }
8130 }
8131 }
8132
8133 /* If we have more than the desired maximum number of lines
8134 in the *Messages* buffer now, delete the oldest ones.
8135 This is safe because we don't have undo in this buffer. */
8136
8137 if (NATNUMP (Vmessage_log_max))
8138 {
8139 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE,
8140 -XFASTINT (Vmessage_log_max) - 1, 0);
8141 del_range_both (BEG, BEG_BYTE, PT, PT_BYTE, 0);
8142 }
8143 }
8144 BEGV = XMARKER (oldbegv)->charpos;
8145 BEGV_BYTE = marker_byte_position (oldbegv);
8146
8147 if (zv_at_end)
8148 {
8149 ZV = Z;
8150 ZV_BYTE = Z_BYTE;
8151 }
8152 else
8153 {
8154 ZV = XMARKER (oldzv)->charpos;
8155 ZV_BYTE = marker_byte_position (oldzv);
8156 }
8157
8158 if (point_at_end)
8159 TEMP_SET_PT_BOTH (Z, Z_BYTE);
8160 else
8161 /* We can't do Fgoto_char (oldpoint) because it will run some
8162 Lisp code. */
8163 TEMP_SET_PT_BOTH (XMARKER (oldpoint)->charpos,
8164 XMARKER (oldpoint)->bytepos);
8165
8166 UNGCPRO;
8167 unchain_marker (XMARKER (oldpoint));
8168 unchain_marker (XMARKER (oldbegv));
8169 unchain_marker (XMARKER (oldzv));
8170
8171 tem = Fget_buffer_window (Fcurrent_buffer (), Qt);
8172 set_buffer_internal (oldbuf);
8173 if (NILP (tem))
8174 windows_or_buffers_changed = old_windows_or_buffers_changed;
8175 message_log_need_newline = !nlflag;
8176 Vdeactivate_mark = old_deactivate_mark;
8177 }
8178 }
8179
8180
8181 /* We are at the end of the buffer after just having inserted a newline.
8182 (Note: We depend on the fact we won't be crossing the gap.)
8183 Check to see if the most recent message looks a lot like the previous one.
8184 Return 0 if different, 1 if the new one should just replace it, or a
8185 value N > 1 if we should also append " [N times]". */
8186
8187 static unsigned long int
8188 message_log_check_duplicate (EMACS_INT prev_bol_byte, EMACS_INT this_bol_byte)
8189 {
8190 EMACS_INT i;
8191 EMACS_INT len = Z_BYTE - 1 - this_bol_byte;
8192 int seen_dots = 0;
8193 unsigned char *p1 = BUF_BYTE_ADDRESS (current_buffer, prev_bol_byte);
8194 unsigned char *p2 = BUF_BYTE_ADDRESS (current_buffer, this_bol_byte);
8195
8196 for (i = 0; i < len; i++)
8197 {
8198 if (i >= 3 && p1[i-3] == '.' && p1[i-2] == '.' && p1[i-1] == '.')
8199 seen_dots = 1;
8200 if (p1[i] != p2[i])
8201 return seen_dots;
8202 }
8203 p1 += len;
8204 if (*p1 == '\n')
8205 return 2;
8206 if (*p1++ == ' ' && *p1++ == '[')
8207 {
8208 char *pend;
8209 unsigned long int n = strtoul ((char *) p1, &pend, 10);
8210 if (strncmp (pend, " times]\n", 8) == 0)
8211 return n+1;
8212 }
8213 return 0;
8214 }
8215 \f
8216
8217 /* Display an echo area message M with a specified length of NBYTES
8218 bytes. The string may include null characters. If M is 0, clear
8219 out any existing message, and let the mini-buffer text show
8220 through.
8221
8222 This may GC, so the buffer M must NOT point to a Lisp string. */
8223
8224 void
8225 message2 (const char *m, EMACS_INT nbytes, int multibyte)
8226 {
8227 /* First flush out any partial line written with print. */
8228 message_log_maybe_newline ();
8229 if (m)
8230 message_dolog (m, nbytes, 1, multibyte);
8231 message2_nolog (m, nbytes, multibyte);
8232 }
8233
8234
8235 /* The non-logging counterpart of message2. */
8236
8237 void
8238 message2_nolog (const char *m, EMACS_INT nbytes, int multibyte)
8239 {
8240 struct frame *sf = SELECTED_FRAME ();
8241 message_enable_multibyte = multibyte;
8242
8243 if (FRAME_INITIAL_P (sf))
8244 {
8245 if (noninteractive_need_newline)
8246 putc ('\n', stderr);
8247 noninteractive_need_newline = 0;
8248 if (m)
8249 fwrite (m, nbytes, 1, stderr);
8250 if (cursor_in_echo_area == 0)
8251 fprintf (stderr, "\n");
8252 fflush (stderr);
8253 }
8254 /* A null message buffer means that the frame hasn't really been
8255 initialized yet. Error messages get reported properly by
8256 cmd_error, so this must be just an informative message; toss it. */
8257 else if (INTERACTIVE
8258 && sf->glyphs_initialized_p
8259 && FRAME_MESSAGE_BUF (sf))
8260 {
8261 Lisp_Object mini_window;
8262 struct frame *f;
8263
8264 /* Get the frame containing the mini-buffer
8265 that the selected frame is using. */
8266 mini_window = FRAME_MINIBUF_WINDOW (sf);
8267 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
8268
8269 FRAME_SAMPLE_VISIBILITY (f);
8270 if (FRAME_VISIBLE_P (sf)
8271 && ! FRAME_VISIBLE_P (f))
8272 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (mini_window)));
8273
8274 if (m)
8275 {
8276 set_message (m, Qnil, nbytes, multibyte);
8277 if (minibuffer_auto_raise)
8278 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
8279 }
8280 else
8281 clear_message (1, 1);
8282
8283 do_pending_window_change (0);
8284 echo_area_display (1);
8285 do_pending_window_change (0);
8286 if (FRAME_TERMINAL (f)->frame_up_to_date_hook != 0 && ! gc_in_progress)
8287 (*FRAME_TERMINAL (f)->frame_up_to_date_hook) (f);
8288 }
8289 }
8290
8291
8292 /* Display an echo area message M with a specified length of NBYTES
8293 bytes. The string may include null characters. If M is not a
8294 string, clear out any existing message, and let the mini-buffer
8295 text show through.
8296
8297 This function cancels echoing. */
8298
8299 void
8300 message3 (Lisp_Object m, EMACS_INT nbytes, int multibyte)
8301 {
8302 struct gcpro gcpro1;
8303
8304 GCPRO1 (m);
8305 clear_message (1,1);
8306 cancel_echoing ();
8307
8308 /* First flush out any partial line written with print. */
8309 message_log_maybe_newline ();
8310 if (STRINGP (m))
8311 {
8312 char *buffer;
8313 USE_SAFE_ALLOCA;
8314
8315 SAFE_ALLOCA (buffer, char *, nbytes);
8316 memcpy (buffer, SDATA (m), nbytes);
8317 message_dolog (buffer, nbytes, 1, multibyte);
8318 SAFE_FREE ();
8319 }
8320 message3_nolog (m, nbytes, multibyte);
8321
8322 UNGCPRO;
8323 }
8324
8325
8326 /* The non-logging version of message3.
8327 This does not cancel echoing, because it is used for echoing.
8328 Perhaps we need to make a separate function for echoing
8329 and make this cancel echoing. */
8330
8331 void
8332 message3_nolog (Lisp_Object m, EMACS_INT nbytes, int multibyte)
8333 {
8334 struct frame *sf = SELECTED_FRAME ();
8335 message_enable_multibyte = multibyte;
8336
8337 if (FRAME_INITIAL_P (sf))
8338 {
8339 if (noninteractive_need_newline)
8340 putc ('\n', stderr);
8341 noninteractive_need_newline = 0;
8342 if (STRINGP (m))
8343 fwrite (SDATA (m), nbytes, 1, stderr);
8344 if (cursor_in_echo_area == 0)
8345 fprintf (stderr, "\n");
8346 fflush (stderr);
8347 }
8348 /* A null message buffer means that the frame hasn't really been
8349 initialized yet. Error messages get reported properly by
8350 cmd_error, so this must be just an informative message; toss it. */
8351 else if (INTERACTIVE
8352 && sf->glyphs_initialized_p
8353 && FRAME_MESSAGE_BUF (sf))
8354 {
8355 Lisp_Object mini_window;
8356 Lisp_Object frame;
8357 struct frame *f;
8358
8359 /* Get the frame containing the mini-buffer
8360 that the selected frame is using. */
8361 mini_window = FRAME_MINIBUF_WINDOW (sf);
8362 frame = XWINDOW (mini_window)->frame;
8363 f = XFRAME (frame);
8364
8365 FRAME_SAMPLE_VISIBILITY (f);
8366 if (FRAME_VISIBLE_P (sf)
8367 && !FRAME_VISIBLE_P (f))
8368 Fmake_frame_visible (frame);
8369
8370 if (STRINGP (m) && SCHARS (m) > 0)
8371 {
8372 set_message (NULL, m, nbytes, multibyte);
8373 if (minibuffer_auto_raise)
8374 Fraise_frame (frame);
8375 /* Assume we are not echoing.
8376 (If we are, echo_now will override this.) */
8377 echo_message_buffer = Qnil;
8378 }
8379 else
8380 clear_message (1, 1);
8381
8382 do_pending_window_change (0);
8383 echo_area_display (1);
8384 do_pending_window_change (0);
8385 if (FRAME_TERMINAL (f)->frame_up_to_date_hook != 0 && ! gc_in_progress)
8386 (*FRAME_TERMINAL (f)->frame_up_to_date_hook) (f);
8387 }
8388 }
8389
8390
8391 /* Display a null-terminated echo area message M. If M is 0, clear
8392 out any existing message, and let the mini-buffer text show through.
8393
8394 The buffer M must continue to exist until after the echo area gets
8395 cleared or some other message gets displayed there. Do not pass
8396 text that is stored in a Lisp string. Do not pass text in a buffer
8397 that was alloca'd. */
8398
8399 void
8400 message1 (const char *m)
8401 {
8402 message2 (m, (m ? strlen (m) : 0), 0);
8403 }
8404
8405
8406 /* The non-logging counterpart of message1. */
8407
8408 void
8409 message1_nolog (const char *m)
8410 {
8411 message2_nolog (m, (m ? strlen (m) : 0), 0);
8412 }
8413
8414 /* Display a message M which contains a single %s
8415 which gets replaced with STRING. */
8416
8417 void
8418 message_with_string (const char *m, Lisp_Object string, int log)
8419 {
8420 CHECK_STRING (string);
8421
8422 if (noninteractive)
8423 {
8424 if (m)
8425 {
8426 if (noninteractive_need_newline)
8427 putc ('\n', stderr);
8428 noninteractive_need_newline = 0;
8429 fprintf (stderr, m, SDATA (string));
8430 if (!cursor_in_echo_area)
8431 fprintf (stderr, "\n");
8432 fflush (stderr);
8433 }
8434 }
8435 else if (INTERACTIVE)
8436 {
8437 /* The frame whose minibuffer we're going to display the message on.
8438 It may be larger than the selected frame, so we need
8439 to use its buffer, not the selected frame's buffer. */
8440 Lisp_Object mini_window;
8441 struct frame *f, *sf = SELECTED_FRAME ();
8442
8443 /* Get the frame containing the minibuffer
8444 that the selected frame is using. */
8445 mini_window = FRAME_MINIBUF_WINDOW (sf);
8446 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
8447
8448 /* A null message buffer means that the frame hasn't really been
8449 initialized yet. Error messages get reported properly by
8450 cmd_error, so this must be just an informative message; toss it. */
8451 if (FRAME_MESSAGE_BUF (f))
8452 {
8453 Lisp_Object args[2], msg;
8454 struct gcpro gcpro1, gcpro2;
8455
8456 args[0] = build_string (m);
8457 args[1] = msg = string;
8458 GCPRO2 (args[0], msg);
8459 gcpro1.nvars = 2;
8460
8461 msg = Fformat (2, args);
8462
8463 if (log)
8464 message3 (msg, SBYTES (msg), STRING_MULTIBYTE (msg));
8465 else
8466 message3_nolog (msg, SBYTES (msg), STRING_MULTIBYTE (msg));
8467
8468 UNGCPRO;
8469
8470 /* Print should start at the beginning of the message
8471 buffer next time. */
8472 message_buf_print = 0;
8473 }
8474 }
8475 }
8476
8477
8478 /* Dump an informative message to the minibuf. If M is 0, clear out
8479 any existing message, and let the mini-buffer text show through. */
8480
8481 static void
8482 vmessage (const char *m, va_list ap)
8483 {
8484 if (noninteractive)
8485 {
8486 if (m)
8487 {
8488 if (noninteractive_need_newline)
8489 putc ('\n', stderr);
8490 noninteractive_need_newline = 0;
8491 vfprintf (stderr, m, ap);
8492 if (cursor_in_echo_area == 0)
8493 fprintf (stderr, "\n");
8494 fflush (stderr);
8495 }
8496 }
8497 else if (INTERACTIVE)
8498 {
8499 /* The frame whose mini-buffer we're going to display the message
8500 on. It may be larger than the selected frame, so we need to
8501 use its buffer, not the selected frame's buffer. */
8502 Lisp_Object mini_window;
8503 struct frame *f, *sf = SELECTED_FRAME ();
8504
8505 /* Get the frame containing the mini-buffer
8506 that the selected frame is using. */
8507 mini_window = FRAME_MINIBUF_WINDOW (sf);
8508 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
8509
8510 /* A null message buffer means that the frame hasn't really been
8511 initialized yet. Error messages get reported properly by
8512 cmd_error, so this must be just an informative message; toss
8513 it. */
8514 if (FRAME_MESSAGE_BUF (f))
8515 {
8516 if (m)
8517 {
8518 size_t len;
8519
8520 len = doprnt (FRAME_MESSAGE_BUF (f),
8521 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, ap);
8522
8523 message2 (FRAME_MESSAGE_BUF (f), len, 0);
8524 }
8525 else
8526 message1 (0);
8527
8528 /* Print should start at the beginning of the message
8529 buffer next time. */
8530 message_buf_print = 0;
8531 }
8532 }
8533 }
8534
8535 void
8536 message (const char *m, ...)
8537 {
8538 va_list ap;
8539 va_start (ap, m);
8540 vmessage (m, ap);
8541 va_end (ap);
8542 }
8543
8544
8545 #if 0
8546 /* The non-logging version of message. */
8547
8548 void
8549 message_nolog (const char *m, ...)
8550 {
8551 Lisp_Object old_log_max;
8552 va_list ap;
8553 va_start (ap, m);
8554 old_log_max = Vmessage_log_max;
8555 Vmessage_log_max = Qnil;
8556 vmessage (m, ap);
8557 Vmessage_log_max = old_log_max;
8558 va_end (ap);
8559 }
8560 #endif
8561
8562
8563 /* Display the current message in the current mini-buffer. This is
8564 only called from error handlers in process.c, and is not time
8565 critical. */
8566
8567 void
8568 update_echo_area (void)
8569 {
8570 if (!NILP (echo_area_buffer[0]))
8571 {
8572 Lisp_Object string;
8573 string = Fcurrent_message ();
8574 message3 (string, SBYTES (string),
8575 !NILP (BVAR (current_buffer, enable_multibyte_characters)));
8576 }
8577 }
8578
8579
8580 /* Make sure echo area buffers in `echo_buffers' are live.
8581 If they aren't, make new ones. */
8582
8583 static void
8584 ensure_echo_area_buffers (void)
8585 {
8586 int i;
8587
8588 for (i = 0; i < 2; ++i)
8589 if (!BUFFERP (echo_buffer[i])
8590 || NILP (BVAR (XBUFFER (echo_buffer[i]), name)))
8591 {
8592 char name[30];
8593 Lisp_Object old_buffer;
8594 int j;
8595
8596 old_buffer = echo_buffer[i];
8597 sprintf (name, " *Echo Area %d*", i);
8598 echo_buffer[i] = Fget_buffer_create (build_string (name));
8599 BVAR (XBUFFER (echo_buffer[i]), truncate_lines) = Qnil;
8600 /* to force word wrap in echo area -
8601 it was decided to postpone this*/
8602 /* XBUFFER (echo_buffer[i])->word_wrap = Qt; */
8603
8604 for (j = 0; j < 2; ++j)
8605 if (EQ (old_buffer, echo_area_buffer[j]))
8606 echo_area_buffer[j] = echo_buffer[i];
8607 }
8608 }
8609
8610
8611 /* Call FN with args A1..A4 with either the current or last displayed
8612 echo_area_buffer as current buffer.
8613
8614 WHICH zero means use the current message buffer
8615 echo_area_buffer[0]. If that is nil, choose a suitable buffer
8616 from echo_buffer[] and clear it.
8617
8618 WHICH > 0 means use echo_area_buffer[1]. If that is nil, choose a
8619 suitable buffer from echo_buffer[] and clear it.
8620
8621 If WHICH < 0, set echo_area_buffer[1] to echo_area_buffer[0], so
8622 that the current message becomes the last displayed one, make
8623 choose a suitable buffer for echo_area_buffer[0], and clear it.
8624
8625 Value is what FN returns. */
8626
8627 static int
8628 with_echo_area_buffer (struct window *w, int which,
8629 int (*fn) (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT),
8630 EMACS_INT a1, Lisp_Object a2, EMACS_INT a3, EMACS_INT a4)
8631 {
8632 Lisp_Object buffer;
8633 int this_one, the_other, clear_buffer_p, rc;
8634 int count = SPECPDL_INDEX ();
8635
8636 /* If buffers aren't live, make new ones. */
8637 ensure_echo_area_buffers ();
8638
8639 clear_buffer_p = 0;
8640
8641 if (which == 0)
8642 this_one = 0, the_other = 1;
8643 else if (which > 0)
8644 this_one = 1, the_other = 0;
8645 else
8646 {
8647 this_one = 0, the_other = 1;
8648 clear_buffer_p = 1;
8649
8650 /* We need a fresh one in case the current echo buffer equals
8651 the one containing the last displayed echo area message. */
8652 if (!NILP (echo_area_buffer[this_one])
8653 && EQ (echo_area_buffer[this_one], echo_area_buffer[the_other]))
8654 echo_area_buffer[this_one] = Qnil;
8655 }
8656
8657 /* Choose a suitable buffer from echo_buffer[] is we don't
8658 have one. */
8659 if (NILP (echo_area_buffer[this_one]))
8660 {
8661 echo_area_buffer[this_one]
8662 = (EQ (echo_area_buffer[the_other], echo_buffer[this_one])
8663 ? echo_buffer[the_other]
8664 : echo_buffer[this_one]);
8665 clear_buffer_p = 1;
8666 }
8667
8668 buffer = echo_area_buffer[this_one];
8669
8670 /* Don't get confused by reusing the buffer used for echoing
8671 for a different purpose. */
8672 if (echo_kboard == NULL && EQ (buffer, echo_message_buffer))
8673 cancel_echoing ();
8674
8675 record_unwind_protect (unwind_with_echo_area_buffer,
8676 with_echo_area_buffer_unwind_data (w));
8677
8678 /* Make the echo area buffer current. Note that for display
8679 purposes, it is not necessary that the displayed window's buffer
8680 == current_buffer, except for text property lookup. So, let's
8681 only set that buffer temporarily here without doing a full
8682 Fset_window_buffer. We must also change w->pointm, though,
8683 because otherwise an assertions in unshow_buffer fails, and Emacs
8684 aborts. */
8685 set_buffer_internal_1 (XBUFFER (buffer));
8686 if (w)
8687 {
8688 w->buffer = buffer;
8689 set_marker_both (w->pointm, buffer, BEG, BEG_BYTE);
8690 }
8691
8692 BVAR (current_buffer, undo_list) = Qt;
8693 BVAR (current_buffer, read_only) = Qnil;
8694 specbind (Qinhibit_read_only, Qt);
8695 specbind (Qinhibit_modification_hooks, Qt);
8696
8697 if (clear_buffer_p && Z > BEG)
8698 del_range (BEG, Z);
8699
8700 xassert (BEGV >= BEG);
8701 xassert (ZV <= Z && ZV >= BEGV);
8702
8703 rc = fn (a1, a2, a3, a4);
8704
8705 xassert (BEGV >= BEG);
8706 xassert (ZV <= Z && ZV >= BEGV);
8707
8708 unbind_to (count, Qnil);
8709 return rc;
8710 }
8711
8712
8713 /* Save state that should be preserved around the call to the function
8714 FN called in with_echo_area_buffer. */
8715
8716 static Lisp_Object
8717 with_echo_area_buffer_unwind_data (struct window *w)
8718 {
8719 int i = 0;
8720 Lisp_Object vector, tmp;
8721
8722 /* Reduce consing by keeping one vector in
8723 Vwith_echo_area_save_vector. */
8724 vector = Vwith_echo_area_save_vector;
8725 Vwith_echo_area_save_vector = Qnil;
8726
8727 if (NILP (vector))
8728 vector = Fmake_vector (make_number (7), Qnil);
8729
8730 XSETBUFFER (tmp, current_buffer); ASET (vector, i, tmp); ++i;
8731 ASET (vector, i, Vdeactivate_mark); ++i;
8732 ASET (vector, i, make_number (windows_or_buffers_changed)); ++i;
8733
8734 if (w)
8735 {
8736 XSETWINDOW (tmp, w); ASET (vector, i, tmp); ++i;
8737 ASET (vector, i, w->buffer); ++i;
8738 ASET (vector, i, make_number (XMARKER (w->pointm)->charpos)); ++i;
8739 ASET (vector, i, make_number (XMARKER (w->pointm)->bytepos)); ++i;
8740 }
8741 else
8742 {
8743 int end = i + 4;
8744 for (; i < end; ++i)
8745 ASET (vector, i, Qnil);
8746 }
8747
8748 xassert (i == ASIZE (vector));
8749 return vector;
8750 }
8751
8752
8753 /* Restore global state from VECTOR which was created by
8754 with_echo_area_buffer_unwind_data. */
8755
8756 static Lisp_Object
8757 unwind_with_echo_area_buffer (Lisp_Object vector)
8758 {
8759 set_buffer_internal_1 (XBUFFER (AREF (vector, 0)));
8760 Vdeactivate_mark = AREF (vector, 1);
8761 windows_or_buffers_changed = XFASTINT (AREF (vector, 2));
8762
8763 if (WINDOWP (AREF (vector, 3)))
8764 {
8765 struct window *w;
8766 Lisp_Object buffer, charpos, bytepos;
8767
8768 w = XWINDOW (AREF (vector, 3));
8769 buffer = AREF (vector, 4);
8770 charpos = AREF (vector, 5);
8771 bytepos = AREF (vector, 6);
8772
8773 w->buffer = buffer;
8774 set_marker_both (w->pointm, buffer,
8775 XFASTINT (charpos), XFASTINT (bytepos));
8776 }
8777
8778 Vwith_echo_area_save_vector = vector;
8779 return Qnil;
8780 }
8781
8782
8783 /* Set up the echo area for use by print functions. MULTIBYTE_P
8784 non-zero means we will print multibyte. */
8785
8786 void
8787 setup_echo_area_for_printing (int multibyte_p)
8788 {
8789 /* If we can't find an echo area any more, exit. */
8790 if (! FRAME_LIVE_P (XFRAME (selected_frame)))
8791 Fkill_emacs (Qnil);
8792
8793 ensure_echo_area_buffers ();
8794
8795 if (!message_buf_print)
8796 {
8797 /* A message has been output since the last time we printed.
8798 Choose a fresh echo area buffer. */
8799 if (EQ (echo_area_buffer[1], echo_buffer[0]))
8800 echo_area_buffer[0] = echo_buffer[1];
8801 else
8802 echo_area_buffer[0] = echo_buffer[0];
8803
8804 /* Switch to that buffer and clear it. */
8805 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
8806 BVAR (current_buffer, truncate_lines) = Qnil;
8807
8808 if (Z > BEG)
8809 {
8810 int count = SPECPDL_INDEX ();
8811 specbind (Qinhibit_read_only, Qt);
8812 /* Note that undo recording is always disabled. */
8813 del_range (BEG, Z);
8814 unbind_to (count, Qnil);
8815 }
8816 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
8817
8818 /* Set up the buffer for the multibyteness we need. */
8819 if (multibyte_p
8820 != !NILP (BVAR (current_buffer, enable_multibyte_characters)))
8821 Fset_buffer_multibyte (multibyte_p ? Qt : Qnil);
8822
8823 /* Raise the frame containing the echo area. */
8824 if (minibuffer_auto_raise)
8825 {
8826 struct frame *sf = SELECTED_FRAME ();
8827 Lisp_Object mini_window;
8828 mini_window = FRAME_MINIBUF_WINDOW (sf);
8829 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
8830 }
8831
8832 message_log_maybe_newline ();
8833 message_buf_print = 1;
8834 }
8835 else
8836 {
8837 if (NILP (echo_area_buffer[0]))
8838 {
8839 if (EQ (echo_area_buffer[1], echo_buffer[0]))
8840 echo_area_buffer[0] = echo_buffer[1];
8841 else
8842 echo_area_buffer[0] = echo_buffer[0];
8843 }
8844
8845 if (current_buffer != XBUFFER (echo_area_buffer[0]))
8846 {
8847 /* Someone switched buffers between print requests. */
8848 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
8849 BVAR (current_buffer, truncate_lines) = Qnil;
8850 }
8851 }
8852 }
8853
8854
8855 /* Display an echo area message in window W. Value is non-zero if W's
8856 height is changed. If display_last_displayed_message_p is
8857 non-zero, display the message that was last displayed, otherwise
8858 display the current message. */
8859
8860 static int
8861 display_echo_area (struct window *w)
8862 {
8863 int i, no_message_p, window_height_changed_p, count;
8864
8865 /* Temporarily disable garbage collections while displaying the echo
8866 area. This is done because a GC can print a message itself.
8867 That message would modify the echo area buffer's contents while a
8868 redisplay of the buffer is going on, and seriously confuse
8869 redisplay. */
8870 count = inhibit_garbage_collection ();
8871
8872 /* If there is no message, we must call display_echo_area_1
8873 nevertheless because it resizes the window. But we will have to
8874 reset the echo_area_buffer in question to nil at the end because
8875 with_echo_area_buffer will sets it to an empty buffer. */
8876 i = display_last_displayed_message_p ? 1 : 0;
8877 no_message_p = NILP (echo_area_buffer[i]);
8878
8879 window_height_changed_p
8880 = with_echo_area_buffer (w, display_last_displayed_message_p,
8881 display_echo_area_1,
8882 (intptr_t) w, Qnil, 0, 0);
8883
8884 if (no_message_p)
8885 echo_area_buffer[i] = Qnil;
8886
8887 unbind_to (count, Qnil);
8888 return window_height_changed_p;
8889 }
8890
8891
8892 /* Helper for display_echo_area. Display the current buffer which
8893 contains the current echo area message in window W, a mini-window,
8894 a pointer to which is passed in A1. A2..A4 are currently not used.
8895 Change the height of W so that all of the message is displayed.
8896 Value is non-zero if height of W was changed. */
8897
8898 static int
8899 display_echo_area_1 (EMACS_INT a1, Lisp_Object a2, EMACS_INT a3, EMACS_INT a4)
8900 {
8901 intptr_t i1 = a1;
8902 struct window *w = (struct window *) i1;
8903 Lisp_Object window;
8904 struct text_pos start;
8905 int window_height_changed_p = 0;
8906
8907 /* Do this before displaying, so that we have a large enough glyph
8908 matrix for the display. If we can't get enough space for the
8909 whole text, display the last N lines. That works by setting w->start. */
8910 window_height_changed_p = resize_mini_window (w, 0);
8911
8912 /* Use the starting position chosen by resize_mini_window. */
8913 SET_TEXT_POS_FROM_MARKER (start, w->start);
8914
8915 /* Display. */
8916 clear_glyph_matrix (w->desired_matrix);
8917 XSETWINDOW (window, w);
8918 try_window (window, start, 0);
8919
8920 return window_height_changed_p;
8921 }
8922
8923
8924 /* Resize the echo area window to exactly the size needed for the
8925 currently displayed message, if there is one. If a mini-buffer
8926 is active, don't shrink it. */
8927
8928 void
8929 resize_echo_area_exactly (void)
8930 {
8931 if (BUFFERP (echo_area_buffer[0])
8932 && WINDOWP (echo_area_window))
8933 {
8934 struct window *w = XWINDOW (echo_area_window);
8935 int resized_p;
8936 Lisp_Object resize_exactly;
8937
8938 if (minibuf_level == 0)
8939 resize_exactly = Qt;
8940 else
8941 resize_exactly = Qnil;
8942
8943 resized_p = with_echo_area_buffer (w, 0, resize_mini_window_1,
8944 (intptr_t) w, resize_exactly,
8945 0, 0);
8946 if (resized_p)
8947 {
8948 ++windows_or_buffers_changed;
8949 ++update_mode_lines;
8950 redisplay_internal ();
8951 }
8952 }
8953 }
8954
8955
8956 /* Callback function for with_echo_area_buffer, when used from
8957 resize_echo_area_exactly. A1 contains a pointer to the window to
8958 resize, EXACTLY non-nil means resize the mini-window exactly to the
8959 size of the text displayed. A3 and A4 are not used. Value is what
8960 resize_mini_window returns. */
8961
8962 static int
8963 resize_mini_window_1 (EMACS_INT a1, Lisp_Object exactly, EMACS_INT a3, EMACS_INT a4)
8964 {
8965 intptr_t i1 = a1;
8966 return resize_mini_window ((struct window *) i1, !NILP (exactly));
8967 }
8968
8969
8970 /* Resize mini-window W to fit the size of its contents. EXACT_P
8971 means size the window exactly to the size needed. Otherwise, it's
8972 only enlarged until W's buffer is empty.
8973
8974 Set W->start to the right place to begin display. If the whole
8975 contents fit, start at the beginning. Otherwise, start so as
8976 to make the end of the contents appear. This is particularly
8977 important for y-or-n-p, but seems desirable generally.
8978
8979 Value is non-zero if the window height has been changed. */
8980
8981 int
8982 resize_mini_window (struct window *w, int exact_p)
8983 {
8984 struct frame *f = XFRAME (w->frame);
8985 int window_height_changed_p = 0;
8986
8987 xassert (MINI_WINDOW_P (w));
8988
8989 /* By default, start display at the beginning. */
8990 set_marker_both (w->start, w->buffer,
8991 BUF_BEGV (XBUFFER (w->buffer)),
8992 BUF_BEGV_BYTE (XBUFFER (w->buffer)));
8993
8994 /* Don't resize windows while redisplaying a window; it would
8995 confuse redisplay functions when the size of the window they are
8996 displaying changes from under them. Such a resizing can happen,
8997 for instance, when which-func prints a long message while
8998 we are running fontification-functions. We're running these
8999 functions with safe_call which binds inhibit-redisplay to t. */
9000 if (!NILP (Vinhibit_redisplay))
9001 return 0;
9002
9003 /* Nil means don't try to resize. */
9004 if (NILP (Vresize_mini_windows)
9005 || (FRAME_X_P (f) && FRAME_X_OUTPUT (f) == NULL))
9006 return 0;
9007
9008 if (!FRAME_MINIBUF_ONLY_P (f))
9009 {
9010 struct it it;
9011 struct window *root = XWINDOW (FRAME_ROOT_WINDOW (f));
9012 int total_height = WINDOW_TOTAL_LINES (root) + WINDOW_TOTAL_LINES (w);
9013 int height, max_height;
9014 int unit = FRAME_LINE_HEIGHT (f);
9015 struct text_pos start;
9016 struct buffer *old_current_buffer = NULL;
9017
9018 if (current_buffer != XBUFFER (w->buffer))
9019 {
9020 old_current_buffer = current_buffer;
9021 set_buffer_internal (XBUFFER (w->buffer));
9022 }
9023
9024 init_iterator (&it, w, BEGV, BEGV_BYTE, NULL, DEFAULT_FACE_ID);
9025
9026 /* Compute the max. number of lines specified by the user. */
9027 if (FLOATP (Vmax_mini_window_height))
9028 max_height = XFLOATINT (Vmax_mini_window_height) * FRAME_LINES (f);
9029 else if (INTEGERP (Vmax_mini_window_height))
9030 max_height = XINT (Vmax_mini_window_height);
9031 else
9032 max_height = total_height / 4;
9033
9034 /* Correct that max. height if it's bogus. */
9035 max_height = max (1, max_height);
9036 max_height = min (total_height, max_height);
9037
9038 /* Find out the height of the text in the window. */
9039 if (it.line_wrap == TRUNCATE)
9040 height = 1;
9041 else
9042 {
9043 last_height = 0;
9044 move_it_to (&it, ZV, -1, -1, -1, MOVE_TO_POS);
9045 if (it.max_ascent == 0 && it.max_descent == 0)
9046 height = it.current_y + last_height;
9047 else
9048 height = it.current_y + it.max_ascent + it.max_descent;
9049 height -= min (it.extra_line_spacing, it.max_extra_line_spacing);
9050 height = (height + unit - 1) / unit;
9051 }
9052
9053 /* Compute a suitable window start. */
9054 if (height > max_height)
9055 {
9056 height = max_height;
9057 init_iterator (&it, w, ZV, ZV_BYTE, NULL, DEFAULT_FACE_ID);
9058 move_it_vertically_backward (&it, (height - 1) * unit);
9059 start = it.current.pos;
9060 }
9061 else
9062 SET_TEXT_POS (start, BEGV, BEGV_BYTE);
9063 SET_MARKER_FROM_TEXT_POS (w->start, start);
9064
9065 if (EQ (Vresize_mini_windows, Qgrow_only))
9066 {
9067 /* Let it grow only, until we display an empty message, in which
9068 case the window shrinks again. */
9069 if (height > WINDOW_TOTAL_LINES (w))
9070 {
9071 int old_height = WINDOW_TOTAL_LINES (w);
9072 freeze_window_starts (f, 1);
9073 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
9074 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
9075 }
9076 else if (height < WINDOW_TOTAL_LINES (w)
9077 && (exact_p || BEGV == ZV))
9078 {
9079 int old_height = WINDOW_TOTAL_LINES (w);
9080 freeze_window_starts (f, 0);
9081 shrink_mini_window (w);
9082 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
9083 }
9084 }
9085 else
9086 {
9087 /* Always resize to exact size needed. */
9088 if (height > WINDOW_TOTAL_LINES (w))
9089 {
9090 int old_height = WINDOW_TOTAL_LINES (w);
9091 freeze_window_starts (f, 1);
9092 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
9093 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
9094 }
9095 else if (height < WINDOW_TOTAL_LINES (w))
9096 {
9097 int old_height = WINDOW_TOTAL_LINES (w);
9098 freeze_window_starts (f, 0);
9099 shrink_mini_window (w);
9100
9101 if (height)
9102 {
9103 freeze_window_starts (f, 1);
9104 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
9105 }
9106
9107 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
9108 }
9109 }
9110
9111 if (old_current_buffer)
9112 set_buffer_internal (old_current_buffer);
9113 }
9114
9115 return window_height_changed_p;
9116 }
9117
9118
9119 /* Value is the current message, a string, or nil if there is no
9120 current message. */
9121
9122 Lisp_Object
9123 current_message (void)
9124 {
9125 Lisp_Object msg;
9126
9127 if (!BUFFERP (echo_area_buffer[0]))
9128 msg = Qnil;
9129 else
9130 {
9131 with_echo_area_buffer (0, 0, current_message_1,
9132 (intptr_t) &msg, Qnil, 0, 0);
9133 if (NILP (msg))
9134 echo_area_buffer[0] = Qnil;
9135 }
9136
9137 return msg;
9138 }
9139
9140
9141 static int
9142 current_message_1 (EMACS_INT a1, Lisp_Object a2, EMACS_INT a3, EMACS_INT a4)
9143 {
9144 intptr_t i1 = a1;
9145 Lisp_Object *msg = (Lisp_Object *) i1;
9146
9147 if (Z > BEG)
9148 *msg = make_buffer_string (BEG, Z, 1);
9149 else
9150 *msg = Qnil;
9151 return 0;
9152 }
9153
9154
9155 /* Push the current message on Vmessage_stack for later restauration
9156 by restore_message. Value is non-zero if the current message isn't
9157 empty. This is a relatively infrequent operation, so it's not
9158 worth optimizing. */
9159
9160 int
9161 push_message (void)
9162 {
9163 Lisp_Object msg;
9164 msg = current_message ();
9165 Vmessage_stack = Fcons (msg, Vmessage_stack);
9166 return STRINGP (msg);
9167 }
9168
9169
9170 /* Restore message display from the top of Vmessage_stack. */
9171
9172 void
9173 restore_message (void)
9174 {
9175 Lisp_Object msg;
9176
9177 xassert (CONSP (Vmessage_stack));
9178 msg = XCAR (Vmessage_stack);
9179 if (STRINGP (msg))
9180 message3_nolog (msg, SBYTES (msg), STRING_MULTIBYTE (msg));
9181 else
9182 message3_nolog (msg, 0, 0);
9183 }
9184
9185
9186 /* Handler for record_unwind_protect calling pop_message. */
9187
9188 Lisp_Object
9189 pop_message_unwind (Lisp_Object dummy)
9190 {
9191 pop_message ();
9192 return Qnil;
9193 }
9194
9195 /* Pop the top-most entry off Vmessage_stack. */
9196
9197 static void
9198 pop_message (void)
9199 {
9200 xassert (CONSP (Vmessage_stack));
9201 Vmessage_stack = XCDR (Vmessage_stack);
9202 }
9203
9204
9205 /* Check that Vmessage_stack is nil. Called from emacs.c when Emacs
9206 exits. If the stack is not empty, we have a missing pop_message
9207 somewhere. */
9208
9209 void
9210 check_message_stack (void)
9211 {
9212 if (!NILP (Vmessage_stack))
9213 abort ();
9214 }
9215
9216
9217 /* Truncate to NCHARS what will be displayed in the echo area the next
9218 time we display it---but don't redisplay it now. */
9219
9220 void
9221 truncate_echo_area (EMACS_INT nchars)
9222 {
9223 if (nchars == 0)
9224 echo_area_buffer[0] = Qnil;
9225 /* A null message buffer means that the frame hasn't really been
9226 initialized yet. Error messages get reported properly by
9227 cmd_error, so this must be just an informative message; toss it. */
9228 else if (!noninteractive
9229 && INTERACTIVE
9230 && !NILP (echo_area_buffer[0]))
9231 {
9232 struct frame *sf = SELECTED_FRAME ();
9233 if (FRAME_MESSAGE_BUF (sf))
9234 with_echo_area_buffer (0, 0, truncate_message_1, nchars, Qnil, 0, 0);
9235 }
9236 }
9237
9238
9239 /* Helper function for truncate_echo_area. Truncate the current
9240 message to at most NCHARS characters. */
9241
9242 static int
9243 truncate_message_1 (EMACS_INT nchars, Lisp_Object a2, EMACS_INT a3, EMACS_INT a4)
9244 {
9245 if (BEG + nchars < Z)
9246 del_range (BEG + nchars, Z);
9247 if (Z == BEG)
9248 echo_area_buffer[0] = Qnil;
9249 return 0;
9250 }
9251
9252
9253 /* Set the current message to a substring of S or STRING.
9254
9255 If STRING is a Lisp string, set the message to the first NBYTES
9256 bytes from STRING. NBYTES zero means use the whole string. If
9257 STRING is multibyte, the message will be displayed multibyte.
9258
9259 If S is not null, set the message to the first LEN bytes of S. LEN
9260 zero means use the whole string. MULTIBYTE_P non-zero means S is
9261 multibyte. Display the message multibyte in that case.
9262
9263 Doesn't GC, as with_echo_area_buffer binds Qinhibit_modification_hooks
9264 to t before calling set_message_1 (which calls insert).
9265 */
9266
9267 static void
9268 set_message (const char *s, Lisp_Object string,
9269 EMACS_INT nbytes, int multibyte_p)
9270 {
9271 message_enable_multibyte
9272 = ((s && multibyte_p)
9273 || (STRINGP (string) && STRING_MULTIBYTE (string)));
9274
9275 with_echo_area_buffer (0, -1, set_message_1,
9276 (intptr_t) s, string, nbytes, multibyte_p);
9277 message_buf_print = 0;
9278 help_echo_showing_p = 0;
9279 }
9280
9281
9282 /* Helper function for set_message. Arguments have the same meaning
9283 as there, with A1 corresponding to S and A2 corresponding to STRING
9284 This function is called with the echo area buffer being
9285 current. */
9286
9287 static int
9288 set_message_1 (EMACS_INT a1, Lisp_Object a2, EMACS_INT nbytes, EMACS_INT multibyte_p)
9289 {
9290 intptr_t i1 = a1;
9291 const char *s = (const char *) i1;
9292 const unsigned char *msg = (const unsigned char *) s;
9293 Lisp_Object string = a2;
9294
9295 /* Change multibyteness of the echo buffer appropriately. */
9296 if (message_enable_multibyte
9297 != !NILP (BVAR (current_buffer, enable_multibyte_characters)))
9298 Fset_buffer_multibyte (message_enable_multibyte ? Qt : Qnil);
9299
9300 BVAR (current_buffer, truncate_lines) = message_truncate_lines ? Qt : Qnil;
9301 if (!NILP (BVAR (current_buffer, bidi_display_reordering)))
9302 BVAR (current_buffer, bidi_paragraph_direction) = Qleft_to_right;
9303
9304 /* Insert new message at BEG. */
9305 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
9306
9307 if (STRINGP (string))
9308 {
9309 EMACS_INT nchars;
9310
9311 if (nbytes == 0)
9312 nbytes = SBYTES (string);
9313 nchars = string_byte_to_char (string, nbytes);
9314
9315 /* This function takes care of single/multibyte conversion. We
9316 just have to ensure that the echo area buffer has the right
9317 setting of enable_multibyte_characters. */
9318 insert_from_string (string, 0, 0, nchars, nbytes, 1);
9319 }
9320 else if (s)
9321 {
9322 if (nbytes == 0)
9323 nbytes = strlen (s);
9324
9325 if (multibyte_p && NILP (BVAR (current_buffer, enable_multibyte_characters)))
9326 {
9327 /* Convert from multi-byte to single-byte. */
9328 EMACS_INT i;
9329 int c, n;
9330 char work[1];
9331
9332 /* Convert a multibyte string to single-byte. */
9333 for (i = 0; i < nbytes; i += n)
9334 {
9335 c = string_char_and_length (msg + i, &n);
9336 work[0] = (ASCII_CHAR_P (c)
9337 ? c
9338 : multibyte_char_to_unibyte (c));
9339 insert_1_both (work, 1, 1, 1, 0, 0);
9340 }
9341 }
9342 else if (!multibyte_p
9343 && !NILP (BVAR (current_buffer, enable_multibyte_characters)))
9344 {
9345 /* Convert from single-byte to multi-byte. */
9346 EMACS_INT i;
9347 int c, n;
9348 unsigned char str[MAX_MULTIBYTE_LENGTH];
9349
9350 /* Convert a single-byte string to multibyte. */
9351 for (i = 0; i < nbytes; i++)
9352 {
9353 c = msg[i];
9354 MAKE_CHAR_MULTIBYTE (c);
9355 n = CHAR_STRING (c, str);
9356 insert_1_both ((char *) str, 1, n, 1, 0, 0);
9357 }
9358 }
9359 else
9360 insert_1 (s, nbytes, 1, 0, 0);
9361 }
9362
9363 return 0;
9364 }
9365
9366
9367 /* Clear messages. CURRENT_P non-zero means clear the current
9368 message. LAST_DISPLAYED_P non-zero means clear the message
9369 last displayed. */
9370
9371 void
9372 clear_message (int current_p, int last_displayed_p)
9373 {
9374 if (current_p)
9375 {
9376 echo_area_buffer[0] = Qnil;
9377 message_cleared_p = 1;
9378 }
9379
9380 if (last_displayed_p)
9381 echo_area_buffer[1] = Qnil;
9382
9383 message_buf_print = 0;
9384 }
9385
9386 /* Clear garbaged frames.
9387
9388 This function is used where the old redisplay called
9389 redraw_garbaged_frames which in turn called redraw_frame which in
9390 turn called clear_frame. The call to clear_frame was a source of
9391 flickering. I believe a clear_frame is not necessary. It should
9392 suffice in the new redisplay to invalidate all current matrices,
9393 and ensure a complete redisplay of all windows. */
9394
9395 static void
9396 clear_garbaged_frames (void)
9397 {
9398 if (frame_garbaged)
9399 {
9400 Lisp_Object tail, frame;
9401 int changed_count = 0;
9402
9403 FOR_EACH_FRAME (tail, frame)
9404 {
9405 struct frame *f = XFRAME (frame);
9406
9407 if (FRAME_VISIBLE_P (f) && FRAME_GARBAGED_P (f))
9408 {
9409 if (f->resized_p)
9410 {
9411 Fredraw_frame (frame);
9412 f->force_flush_display_p = 1;
9413 }
9414 clear_current_matrices (f);
9415 changed_count++;
9416 f->garbaged = 0;
9417 f->resized_p = 0;
9418 }
9419 }
9420
9421 frame_garbaged = 0;
9422 if (changed_count)
9423 ++windows_or_buffers_changed;
9424 }
9425 }
9426
9427
9428 /* Redisplay the echo area of the selected frame. If UPDATE_FRAME_P
9429 is non-zero update selected_frame. Value is non-zero if the
9430 mini-windows height has been changed. */
9431
9432 static int
9433 echo_area_display (int update_frame_p)
9434 {
9435 Lisp_Object mini_window;
9436 struct window *w;
9437 struct frame *f;
9438 int window_height_changed_p = 0;
9439 struct frame *sf = SELECTED_FRAME ();
9440
9441 mini_window = FRAME_MINIBUF_WINDOW (sf);
9442 w = XWINDOW (mini_window);
9443 f = XFRAME (WINDOW_FRAME (w));
9444
9445 /* Don't display if frame is invisible or not yet initialized. */
9446 if (!FRAME_VISIBLE_P (f) || !f->glyphs_initialized_p)
9447 return 0;
9448
9449 #ifdef HAVE_WINDOW_SYSTEM
9450 /* When Emacs starts, selected_frame may be the initial terminal
9451 frame. If we let this through, a message would be displayed on
9452 the terminal. */
9453 if (FRAME_INITIAL_P (XFRAME (selected_frame)))
9454 return 0;
9455 #endif /* HAVE_WINDOW_SYSTEM */
9456
9457 /* Redraw garbaged frames. */
9458 if (frame_garbaged)
9459 clear_garbaged_frames ();
9460
9461 if (!NILP (echo_area_buffer[0]) || minibuf_level == 0)
9462 {
9463 echo_area_window = mini_window;
9464 window_height_changed_p = display_echo_area (w);
9465 w->must_be_updated_p = 1;
9466
9467 /* Update the display, unless called from redisplay_internal.
9468 Also don't update the screen during redisplay itself. The
9469 update will happen at the end of redisplay, and an update
9470 here could cause confusion. */
9471 if (update_frame_p && !redisplaying_p)
9472 {
9473 int n = 0;
9474
9475 /* If the display update has been interrupted by pending
9476 input, update mode lines in the frame. Due to the
9477 pending input, it might have been that redisplay hasn't
9478 been called, so that mode lines above the echo area are
9479 garbaged. This looks odd, so we prevent it here. */
9480 if (!display_completed)
9481 n = redisplay_mode_lines (FRAME_ROOT_WINDOW (f), 0);
9482
9483 if (window_height_changed_p
9484 /* Don't do this if Emacs is shutting down. Redisplay
9485 needs to run hooks. */
9486 && !NILP (Vrun_hooks))
9487 {
9488 /* Must update other windows. Likewise as in other
9489 cases, don't let this update be interrupted by
9490 pending input. */
9491 int count = SPECPDL_INDEX ();
9492 specbind (Qredisplay_dont_pause, Qt);
9493 windows_or_buffers_changed = 1;
9494 redisplay_internal ();
9495 unbind_to (count, Qnil);
9496 }
9497 else if (FRAME_WINDOW_P (f) && n == 0)
9498 {
9499 /* Window configuration is the same as before.
9500 Can do with a display update of the echo area,
9501 unless we displayed some mode lines. */
9502 update_single_window (w, 1);
9503 FRAME_RIF (f)->flush_display (f);
9504 }
9505 else
9506 update_frame (f, 1, 1);
9507
9508 /* If cursor is in the echo area, make sure that the next
9509 redisplay displays the minibuffer, so that the cursor will
9510 be replaced with what the minibuffer wants. */
9511 if (cursor_in_echo_area)
9512 ++windows_or_buffers_changed;
9513 }
9514 }
9515 else if (!EQ (mini_window, selected_window))
9516 windows_or_buffers_changed++;
9517
9518 /* Last displayed message is now the current message. */
9519 echo_area_buffer[1] = echo_area_buffer[0];
9520 /* Inform read_char that we're not echoing. */
9521 echo_message_buffer = Qnil;
9522
9523 /* Prevent redisplay optimization in redisplay_internal by resetting
9524 this_line_start_pos. This is done because the mini-buffer now
9525 displays the message instead of its buffer text. */
9526 if (EQ (mini_window, selected_window))
9527 CHARPOS (this_line_start_pos) = 0;
9528
9529 return window_height_changed_p;
9530 }
9531
9532
9533 \f
9534 /***********************************************************************
9535 Mode Lines and Frame Titles
9536 ***********************************************************************/
9537
9538 /* A buffer for constructing non-propertized mode-line strings and
9539 frame titles in it; allocated from the heap in init_xdisp and
9540 resized as needed in store_mode_line_noprop_char. */
9541
9542 static char *mode_line_noprop_buf;
9543
9544 /* The buffer's end, and a current output position in it. */
9545
9546 static char *mode_line_noprop_buf_end;
9547 static char *mode_line_noprop_ptr;
9548
9549 #define MODE_LINE_NOPROP_LEN(start) \
9550 ((mode_line_noprop_ptr - mode_line_noprop_buf) - start)
9551
9552 static enum {
9553 MODE_LINE_DISPLAY = 0,
9554 MODE_LINE_TITLE,
9555 MODE_LINE_NOPROP,
9556 MODE_LINE_STRING
9557 } mode_line_target;
9558
9559 /* Alist that caches the results of :propertize.
9560 Each element is (PROPERTIZED-STRING . PROPERTY-LIST). */
9561 static Lisp_Object mode_line_proptrans_alist;
9562
9563 /* List of strings making up the mode-line. */
9564 static Lisp_Object mode_line_string_list;
9565
9566 /* Base face property when building propertized mode line string. */
9567 static Lisp_Object mode_line_string_face;
9568 static Lisp_Object mode_line_string_face_prop;
9569
9570
9571 /* Unwind data for mode line strings */
9572
9573 static Lisp_Object Vmode_line_unwind_vector;
9574
9575 static Lisp_Object
9576 format_mode_line_unwind_data (struct buffer *obuf,
9577 Lisp_Object owin,
9578 int save_proptrans)
9579 {
9580 Lisp_Object vector, tmp;
9581
9582 /* Reduce consing by keeping one vector in
9583 Vwith_echo_area_save_vector. */
9584 vector = Vmode_line_unwind_vector;
9585 Vmode_line_unwind_vector = Qnil;
9586
9587 if (NILP (vector))
9588 vector = Fmake_vector (make_number (8), Qnil);
9589
9590 ASET (vector, 0, make_number (mode_line_target));
9591 ASET (vector, 1, make_number (MODE_LINE_NOPROP_LEN (0)));
9592 ASET (vector, 2, mode_line_string_list);
9593 ASET (vector, 3, save_proptrans ? mode_line_proptrans_alist : Qt);
9594 ASET (vector, 4, mode_line_string_face);
9595 ASET (vector, 5, mode_line_string_face_prop);
9596
9597 if (obuf)
9598 XSETBUFFER (tmp, obuf);
9599 else
9600 tmp = Qnil;
9601 ASET (vector, 6, tmp);
9602 ASET (vector, 7, owin);
9603
9604 return vector;
9605 }
9606
9607 static Lisp_Object
9608 unwind_format_mode_line (Lisp_Object vector)
9609 {
9610 mode_line_target = XINT (AREF (vector, 0));
9611 mode_line_noprop_ptr = mode_line_noprop_buf + XINT (AREF (vector, 1));
9612 mode_line_string_list = AREF (vector, 2);
9613 if (! EQ (AREF (vector, 3), Qt))
9614 mode_line_proptrans_alist = AREF (vector, 3);
9615 mode_line_string_face = AREF (vector, 4);
9616 mode_line_string_face_prop = AREF (vector, 5);
9617
9618 if (!NILP (AREF (vector, 7)))
9619 /* Select window before buffer, since it may change the buffer. */
9620 Fselect_window (AREF (vector, 7), Qt);
9621
9622 if (!NILP (AREF (vector, 6)))
9623 {
9624 set_buffer_internal_1 (XBUFFER (AREF (vector, 6)));
9625 ASET (vector, 6, Qnil);
9626 }
9627
9628 Vmode_line_unwind_vector = vector;
9629 return Qnil;
9630 }
9631
9632
9633 /* Store a single character C for the frame title in mode_line_noprop_buf.
9634 Re-allocate mode_line_noprop_buf if necessary. */
9635
9636 static void
9637 store_mode_line_noprop_char (char c)
9638 {
9639 /* If output position has reached the end of the allocated buffer,
9640 double the buffer's size. */
9641 if (mode_line_noprop_ptr == mode_line_noprop_buf_end)
9642 {
9643 int len = MODE_LINE_NOPROP_LEN (0);
9644 int new_size = 2 * len * sizeof *mode_line_noprop_buf;
9645 mode_line_noprop_buf = (char *) xrealloc (mode_line_noprop_buf, new_size);
9646 mode_line_noprop_buf_end = mode_line_noprop_buf + new_size;
9647 mode_line_noprop_ptr = mode_line_noprop_buf + len;
9648 }
9649
9650 *mode_line_noprop_ptr++ = c;
9651 }
9652
9653
9654 /* Store part of a frame title in mode_line_noprop_buf, beginning at
9655 mode_line_noprop_ptr. STRING is the string to store. Do not copy
9656 characters that yield more columns than PRECISION; PRECISION <= 0
9657 means copy the whole string. Pad with spaces until FIELD_WIDTH
9658 number of characters have been copied; FIELD_WIDTH <= 0 means don't
9659 pad. Called from display_mode_element when it is used to build a
9660 frame title. */
9661
9662 static int
9663 store_mode_line_noprop (const char *string, int field_width, int precision)
9664 {
9665 const unsigned char *str = (const unsigned char *) string;
9666 int n = 0;
9667 EMACS_INT dummy, nbytes;
9668
9669 /* Copy at most PRECISION chars from STR. */
9670 nbytes = strlen (string);
9671 n += c_string_width (str, nbytes, precision, &dummy, &nbytes);
9672 while (nbytes--)
9673 store_mode_line_noprop_char (*str++);
9674
9675 /* Fill up with spaces until FIELD_WIDTH reached. */
9676 while (field_width > 0
9677 && n < field_width)
9678 {
9679 store_mode_line_noprop_char (' ');
9680 ++n;
9681 }
9682
9683 return n;
9684 }
9685
9686 /***********************************************************************
9687 Frame Titles
9688 ***********************************************************************/
9689
9690 #ifdef HAVE_WINDOW_SYSTEM
9691
9692 /* Set the title of FRAME, if it has changed. The title format is
9693 Vicon_title_format if FRAME is iconified, otherwise it is
9694 frame_title_format. */
9695
9696 static void
9697 x_consider_frame_title (Lisp_Object frame)
9698 {
9699 struct frame *f = XFRAME (frame);
9700
9701 if (FRAME_WINDOW_P (f)
9702 || FRAME_MINIBUF_ONLY_P (f)
9703 || f->explicit_name)
9704 {
9705 /* Do we have more than one visible frame on this X display? */
9706 Lisp_Object tail;
9707 Lisp_Object fmt;
9708 int title_start;
9709 char *title;
9710 int len;
9711 struct it it;
9712 int count = SPECPDL_INDEX ();
9713
9714 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
9715 {
9716 Lisp_Object other_frame = XCAR (tail);
9717 struct frame *tf = XFRAME (other_frame);
9718
9719 if (tf != f
9720 && FRAME_KBOARD (tf) == FRAME_KBOARD (f)
9721 && !FRAME_MINIBUF_ONLY_P (tf)
9722 && !EQ (other_frame, tip_frame)
9723 && (FRAME_VISIBLE_P (tf) || FRAME_ICONIFIED_P (tf)))
9724 break;
9725 }
9726
9727 /* Set global variable indicating that multiple frames exist. */
9728 multiple_frames = CONSP (tail);
9729
9730 /* Switch to the buffer of selected window of the frame. Set up
9731 mode_line_target so that display_mode_element will output into
9732 mode_line_noprop_buf; then display the title. */
9733 record_unwind_protect (unwind_format_mode_line,
9734 format_mode_line_unwind_data
9735 (current_buffer, selected_window, 0));
9736
9737 Fselect_window (f->selected_window, Qt);
9738 set_buffer_internal_1 (XBUFFER (XWINDOW (f->selected_window)->buffer));
9739 fmt = FRAME_ICONIFIED_P (f) ? Vicon_title_format : Vframe_title_format;
9740
9741 mode_line_target = MODE_LINE_TITLE;
9742 title_start = MODE_LINE_NOPROP_LEN (0);
9743 init_iterator (&it, XWINDOW (f->selected_window), -1, -1,
9744 NULL, DEFAULT_FACE_ID);
9745 display_mode_element (&it, 0, -1, -1, fmt, Qnil, 0);
9746 len = MODE_LINE_NOPROP_LEN (title_start);
9747 title = mode_line_noprop_buf + title_start;
9748 unbind_to (count, Qnil);
9749
9750 /* Set the title only if it's changed. This avoids consing in
9751 the common case where it hasn't. (If it turns out that we've
9752 already wasted too much time by walking through the list with
9753 display_mode_element, then we might need to optimize at a
9754 higher level than this.) */
9755 if (! STRINGP (f->name)
9756 || SBYTES (f->name) != len
9757 || memcmp (title, SDATA (f->name), len) != 0)
9758 x_implicitly_set_name (f, make_string (title, len), Qnil);
9759 }
9760 }
9761
9762 #endif /* not HAVE_WINDOW_SYSTEM */
9763
9764
9765
9766 \f
9767 /***********************************************************************
9768 Menu Bars
9769 ***********************************************************************/
9770
9771
9772 /* Prepare for redisplay by updating menu-bar item lists when
9773 appropriate. This can call eval. */
9774
9775 void
9776 prepare_menu_bars (void)
9777 {
9778 int all_windows;
9779 struct gcpro gcpro1, gcpro2;
9780 struct frame *f;
9781 Lisp_Object tooltip_frame;
9782
9783 #ifdef HAVE_WINDOW_SYSTEM
9784 tooltip_frame = tip_frame;
9785 #else
9786 tooltip_frame = Qnil;
9787 #endif
9788
9789 /* Update all frame titles based on their buffer names, etc. We do
9790 this before the menu bars so that the buffer-menu will show the
9791 up-to-date frame titles. */
9792 #ifdef HAVE_WINDOW_SYSTEM
9793 if (windows_or_buffers_changed || update_mode_lines)
9794 {
9795 Lisp_Object tail, frame;
9796
9797 FOR_EACH_FRAME (tail, frame)
9798 {
9799 f = XFRAME (frame);
9800 if (!EQ (frame, tooltip_frame)
9801 && (FRAME_VISIBLE_P (f) || FRAME_ICONIFIED_P (f)))
9802 x_consider_frame_title (frame);
9803 }
9804 }
9805 #endif /* HAVE_WINDOW_SYSTEM */
9806
9807 /* Update the menu bar item lists, if appropriate. This has to be
9808 done before any actual redisplay or generation of display lines. */
9809 all_windows = (update_mode_lines
9810 || buffer_shared > 1
9811 || windows_or_buffers_changed);
9812 if (all_windows)
9813 {
9814 Lisp_Object tail, frame;
9815 int count = SPECPDL_INDEX ();
9816 /* 1 means that update_menu_bar has run its hooks
9817 so any further calls to update_menu_bar shouldn't do so again. */
9818 int menu_bar_hooks_run = 0;
9819
9820 record_unwind_save_match_data ();
9821
9822 FOR_EACH_FRAME (tail, frame)
9823 {
9824 f = XFRAME (frame);
9825
9826 /* Ignore tooltip frame. */
9827 if (EQ (frame, tooltip_frame))
9828 continue;
9829
9830 /* If a window on this frame changed size, report that to
9831 the user and clear the size-change flag. */
9832 if (FRAME_WINDOW_SIZES_CHANGED (f))
9833 {
9834 Lisp_Object functions;
9835
9836 /* Clear flag first in case we get an error below. */
9837 FRAME_WINDOW_SIZES_CHANGED (f) = 0;
9838 functions = Vwindow_size_change_functions;
9839 GCPRO2 (tail, functions);
9840
9841 while (CONSP (functions))
9842 {
9843 if (!EQ (XCAR (functions), Qt))
9844 call1 (XCAR (functions), frame);
9845 functions = XCDR (functions);
9846 }
9847 UNGCPRO;
9848 }
9849
9850 GCPRO1 (tail);
9851 menu_bar_hooks_run = update_menu_bar (f, 0, menu_bar_hooks_run);
9852 #ifdef HAVE_WINDOW_SYSTEM
9853 update_tool_bar (f, 0);
9854 #endif
9855 #ifdef HAVE_NS
9856 if (windows_or_buffers_changed
9857 && FRAME_NS_P (f))
9858 ns_set_doc_edited (f, Fbuffer_modified_p
9859 (XWINDOW (f->selected_window)->buffer));
9860 #endif
9861 UNGCPRO;
9862 }
9863
9864 unbind_to (count, Qnil);
9865 }
9866 else
9867 {
9868 struct frame *sf = SELECTED_FRAME ();
9869 update_menu_bar (sf, 1, 0);
9870 #ifdef HAVE_WINDOW_SYSTEM
9871 update_tool_bar (sf, 1);
9872 #endif
9873 }
9874 }
9875
9876
9877 /* Update the menu bar item list for frame F. This has to be done
9878 before we start to fill in any display lines, because it can call
9879 eval.
9880
9881 If SAVE_MATCH_DATA is non-zero, we must save and restore it here.
9882
9883 If HOOKS_RUN is 1, that means a previous call to update_menu_bar
9884 already ran the menu bar hooks for this redisplay, so there
9885 is no need to run them again. The return value is the
9886 updated value of this flag, to pass to the next call. */
9887
9888 static int
9889 update_menu_bar (struct frame *f, int save_match_data, int hooks_run)
9890 {
9891 Lisp_Object window;
9892 register struct window *w;
9893
9894 /* If called recursively during a menu update, do nothing. This can
9895 happen when, for instance, an activate-menubar-hook causes a
9896 redisplay. */
9897 if (inhibit_menubar_update)
9898 return hooks_run;
9899
9900 window = FRAME_SELECTED_WINDOW (f);
9901 w = XWINDOW (window);
9902
9903 if (FRAME_WINDOW_P (f)
9904 ?
9905 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
9906 || defined (HAVE_NS) || defined (USE_GTK)
9907 FRAME_EXTERNAL_MENU_BAR (f)
9908 #else
9909 FRAME_MENU_BAR_LINES (f) > 0
9910 #endif
9911 : FRAME_MENU_BAR_LINES (f) > 0)
9912 {
9913 /* If the user has switched buffers or windows, we need to
9914 recompute to reflect the new bindings. But we'll
9915 recompute when update_mode_lines is set too; that means
9916 that people can use force-mode-line-update to request
9917 that the menu bar be recomputed. The adverse effect on
9918 the rest of the redisplay algorithm is about the same as
9919 windows_or_buffers_changed anyway. */
9920 if (windows_or_buffers_changed
9921 /* This used to test w->update_mode_line, but we believe
9922 there is no need to recompute the menu in that case. */
9923 || update_mode_lines
9924 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
9925 < BUF_MODIFF (XBUFFER (w->buffer)))
9926 != !NILP (w->last_had_star))
9927 || ((!NILP (Vtransient_mark_mode)
9928 && !NILP (BVAR (XBUFFER (w->buffer), mark_active)))
9929 != !NILP (w->region_showing)))
9930 {
9931 struct buffer *prev = current_buffer;
9932 int count = SPECPDL_INDEX ();
9933
9934 specbind (Qinhibit_menubar_update, Qt);
9935
9936 set_buffer_internal_1 (XBUFFER (w->buffer));
9937 if (save_match_data)
9938 record_unwind_save_match_data ();
9939 if (NILP (Voverriding_local_map_menu_flag))
9940 {
9941 specbind (Qoverriding_terminal_local_map, Qnil);
9942 specbind (Qoverriding_local_map, Qnil);
9943 }
9944
9945 if (!hooks_run)
9946 {
9947 /* Run the Lucid hook. */
9948 safe_run_hooks (Qactivate_menubar_hook);
9949
9950 /* If it has changed current-menubar from previous value,
9951 really recompute the menu-bar from the value. */
9952 if (! NILP (Vlucid_menu_bar_dirty_flag))
9953 call0 (Qrecompute_lucid_menubar);
9954
9955 safe_run_hooks (Qmenu_bar_update_hook);
9956
9957 hooks_run = 1;
9958 }
9959
9960 XSETFRAME (Vmenu_updating_frame, f);
9961 FRAME_MENU_BAR_ITEMS (f) = menu_bar_items (FRAME_MENU_BAR_ITEMS (f));
9962
9963 /* Redisplay the menu bar in case we changed it. */
9964 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
9965 || defined (HAVE_NS) || defined (USE_GTK)
9966 if (FRAME_WINDOW_P (f))
9967 {
9968 #if defined (HAVE_NS)
9969 /* All frames on Mac OS share the same menubar. So only
9970 the selected frame should be allowed to set it. */
9971 if (f == SELECTED_FRAME ())
9972 #endif
9973 set_frame_menubar (f, 0, 0);
9974 }
9975 else
9976 /* On a terminal screen, the menu bar is an ordinary screen
9977 line, and this makes it get updated. */
9978 w->update_mode_line = Qt;
9979 #else /* ! (USE_X_TOOLKIT || HAVE_NTGUI || HAVE_NS || USE_GTK) */
9980 /* In the non-toolkit version, the menu bar is an ordinary screen
9981 line, and this makes it get updated. */
9982 w->update_mode_line = Qt;
9983 #endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI || HAVE_NS || USE_GTK) */
9984
9985 unbind_to (count, Qnil);
9986 set_buffer_internal_1 (prev);
9987 }
9988 }
9989
9990 return hooks_run;
9991 }
9992
9993
9994 \f
9995 /***********************************************************************
9996 Output Cursor
9997 ***********************************************************************/
9998
9999 #ifdef HAVE_WINDOW_SYSTEM
10000
10001 /* EXPORT:
10002 Nominal cursor position -- where to draw output.
10003 HPOS and VPOS are window relative glyph matrix coordinates.
10004 X and Y are window relative pixel coordinates. */
10005
10006 struct cursor_pos output_cursor;
10007
10008
10009 /* EXPORT:
10010 Set the global variable output_cursor to CURSOR. All cursor
10011 positions are relative to updated_window. */
10012
10013 void
10014 set_output_cursor (struct cursor_pos *cursor)
10015 {
10016 output_cursor.hpos = cursor->hpos;
10017 output_cursor.vpos = cursor->vpos;
10018 output_cursor.x = cursor->x;
10019 output_cursor.y = cursor->y;
10020 }
10021
10022
10023 /* EXPORT for RIF:
10024 Set a nominal cursor position.
10025
10026 HPOS and VPOS are column/row positions in a window glyph matrix. X
10027 and Y are window text area relative pixel positions.
10028
10029 If this is done during an update, updated_window will contain the
10030 window that is being updated and the position is the future output
10031 cursor position for that window. If updated_window is null, use
10032 selected_window and display the cursor at the given position. */
10033
10034 void
10035 x_cursor_to (int vpos, int hpos, int y, int x)
10036 {
10037 struct window *w;
10038
10039 /* If updated_window is not set, work on selected_window. */
10040 if (updated_window)
10041 w = updated_window;
10042 else
10043 w = XWINDOW (selected_window);
10044
10045 /* Set the output cursor. */
10046 output_cursor.hpos = hpos;
10047 output_cursor.vpos = vpos;
10048 output_cursor.x = x;
10049 output_cursor.y = y;
10050
10051 /* If not called as part of an update, really display the cursor.
10052 This will also set the cursor position of W. */
10053 if (updated_window == NULL)
10054 {
10055 BLOCK_INPUT;
10056 display_and_set_cursor (w, 1, hpos, vpos, x, y);
10057 if (FRAME_RIF (SELECTED_FRAME ())->flush_display_optional)
10058 FRAME_RIF (SELECTED_FRAME ())->flush_display_optional (SELECTED_FRAME ());
10059 UNBLOCK_INPUT;
10060 }
10061 }
10062
10063 #endif /* HAVE_WINDOW_SYSTEM */
10064
10065 \f
10066 /***********************************************************************
10067 Tool-bars
10068 ***********************************************************************/
10069
10070 #ifdef HAVE_WINDOW_SYSTEM
10071
10072 /* Where the mouse was last time we reported a mouse event. */
10073
10074 FRAME_PTR last_mouse_frame;
10075
10076 /* Tool-bar item index of the item on which a mouse button was pressed
10077 or -1. */
10078
10079 int last_tool_bar_item;
10080
10081
10082 static Lisp_Object
10083 update_tool_bar_unwind (Lisp_Object frame)
10084 {
10085 selected_frame = frame;
10086 return Qnil;
10087 }
10088
10089 /* Update the tool-bar item list for frame F. This has to be done
10090 before we start to fill in any display lines. Called from
10091 prepare_menu_bars. If SAVE_MATCH_DATA is non-zero, we must save
10092 and restore it here. */
10093
10094 static void
10095 update_tool_bar (struct frame *f, int save_match_data)
10096 {
10097 #if defined (USE_GTK) || defined (HAVE_NS)
10098 int do_update = FRAME_EXTERNAL_TOOL_BAR (f);
10099 #else
10100 int do_update = WINDOWP (f->tool_bar_window)
10101 && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)) > 0;
10102 #endif
10103
10104 if (do_update)
10105 {
10106 Lisp_Object window;
10107 struct window *w;
10108
10109 window = FRAME_SELECTED_WINDOW (f);
10110 w = XWINDOW (window);
10111
10112 /* If the user has switched buffers or windows, we need to
10113 recompute to reflect the new bindings. But we'll
10114 recompute when update_mode_lines is set too; that means
10115 that people can use force-mode-line-update to request
10116 that the menu bar be recomputed. The adverse effect on
10117 the rest of the redisplay algorithm is about the same as
10118 windows_or_buffers_changed anyway. */
10119 if (windows_or_buffers_changed
10120 || !NILP (w->update_mode_line)
10121 || update_mode_lines
10122 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
10123 < BUF_MODIFF (XBUFFER (w->buffer)))
10124 != !NILP (w->last_had_star))
10125 || ((!NILP (Vtransient_mark_mode)
10126 && !NILP (BVAR (XBUFFER (w->buffer), mark_active)))
10127 != !NILP (w->region_showing)))
10128 {
10129 struct buffer *prev = current_buffer;
10130 int count = SPECPDL_INDEX ();
10131 Lisp_Object frame, new_tool_bar;
10132 int new_n_tool_bar;
10133 struct gcpro gcpro1;
10134
10135 /* Set current_buffer to the buffer of the selected
10136 window of the frame, so that we get the right local
10137 keymaps. */
10138 set_buffer_internal_1 (XBUFFER (w->buffer));
10139
10140 /* Save match data, if we must. */
10141 if (save_match_data)
10142 record_unwind_save_match_data ();
10143
10144 /* Make sure that we don't accidentally use bogus keymaps. */
10145 if (NILP (Voverriding_local_map_menu_flag))
10146 {
10147 specbind (Qoverriding_terminal_local_map, Qnil);
10148 specbind (Qoverriding_local_map, Qnil);
10149 }
10150
10151 GCPRO1 (new_tool_bar);
10152
10153 /* We must temporarily set the selected frame to this frame
10154 before calling tool_bar_items, because the calculation of
10155 the tool-bar keymap uses the selected frame (see
10156 `tool-bar-make-keymap' in tool-bar.el). */
10157 record_unwind_protect (update_tool_bar_unwind, selected_frame);
10158 XSETFRAME (frame, f);
10159 selected_frame = frame;
10160
10161 /* Build desired tool-bar items from keymaps. */
10162 new_tool_bar = tool_bar_items (Fcopy_sequence (f->tool_bar_items),
10163 &new_n_tool_bar);
10164
10165 /* Redisplay the tool-bar if we changed it. */
10166 if (new_n_tool_bar != f->n_tool_bar_items
10167 || NILP (Fequal (new_tool_bar, f->tool_bar_items)))
10168 {
10169 /* Redisplay that happens asynchronously due to an expose event
10170 may access f->tool_bar_items. Make sure we update both
10171 variables within BLOCK_INPUT so no such event interrupts. */
10172 BLOCK_INPUT;
10173 f->tool_bar_items = new_tool_bar;
10174 f->n_tool_bar_items = new_n_tool_bar;
10175 w->update_mode_line = Qt;
10176 UNBLOCK_INPUT;
10177 }
10178
10179 UNGCPRO;
10180
10181 unbind_to (count, Qnil);
10182 set_buffer_internal_1 (prev);
10183 }
10184 }
10185 }
10186
10187
10188 /* Set F->desired_tool_bar_string to a Lisp string representing frame
10189 F's desired tool-bar contents. F->tool_bar_items must have
10190 been set up previously by calling prepare_menu_bars. */
10191
10192 static void
10193 build_desired_tool_bar_string (struct frame *f)
10194 {
10195 int i, size, size_needed;
10196 struct gcpro gcpro1, gcpro2, gcpro3;
10197 Lisp_Object image, plist, props;
10198
10199 image = plist = props = Qnil;
10200 GCPRO3 (image, plist, props);
10201
10202 /* Prepare F->desired_tool_bar_string. If we can reuse it, do so.
10203 Otherwise, make a new string. */
10204
10205 /* The size of the string we might be able to reuse. */
10206 size = (STRINGP (f->desired_tool_bar_string)
10207 ? SCHARS (f->desired_tool_bar_string)
10208 : 0);
10209
10210 /* We need one space in the string for each image. */
10211 size_needed = f->n_tool_bar_items;
10212
10213 /* Reuse f->desired_tool_bar_string, if possible. */
10214 if (size < size_needed || NILP (f->desired_tool_bar_string))
10215 f->desired_tool_bar_string = Fmake_string (make_number (size_needed),
10216 make_number (' '));
10217 else
10218 {
10219 props = list4 (Qdisplay, Qnil, Qmenu_item, Qnil);
10220 Fremove_text_properties (make_number (0), make_number (size),
10221 props, f->desired_tool_bar_string);
10222 }
10223
10224 /* Put a `display' property on the string for the images to display,
10225 put a `menu_item' property on tool-bar items with a value that
10226 is the index of the item in F's tool-bar item vector. */
10227 for (i = 0; i < f->n_tool_bar_items; ++i)
10228 {
10229 #define PROP(IDX) AREF (f->tool_bar_items, i * TOOL_BAR_ITEM_NSLOTS + (IDX))
10230
10231 int enabled_p = !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P));
10232 int selected_p = !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P));
10233 int hmargin, vmargin, relief, idx, end;
10234
10235 /* If image is a vector, choose the image according to the
10236 button state. */
10237 image = PROP (TOOL_BAR_ITEM_IMAGES);
10238 if (VECTORP (image))
10239 {
10240 if (enabled_p)
10241 idx = (selected_p
10242 ? TOOL_BAR_IMAGE_ENABLED_SELECTED
10243 : TOOL_BAR_IMAGE_ENABLED_DESELECTED);
10244 else
10245 idx = (selected_p
10246 ? TOOL_BAR_IMAGE_DISABLED_SELECTED
10247 : TOOL_BAR_IMAGE_DISABLED_DESELECTED);
10248
10249 xassert (ASIZE (image) >= idx);
10250 image = AREF (image, idx);
10251 }
10252 else
10253 idx = -1;
10254
10255 /* Ignore invalid image specifications. */
10256 if (!valid_image_p (image))
10257 continue;
10258
10259 /* Display the tool-bar button pressed, or depressed. */
10260 plist = Fcopy_sequence (XCDR (image));
10261
10262 /* Compute margin and relief to draw. */
10263 relief = (tool_bar_button_relief >= 0
10264 ? tool_bar_button_relief
10265 : DEFAULT_TOOL_BAR_BUTTON_RELIEF);
10266 hmargin = vmargin = relief;
10267
10268 if (INTEGERP (Vtool_bar_button_margin)
10269 && XINT (Vtool_bar_button_margin) > 0)
10270 {
10271 hmargin += XFASTINT (Vtool_bar_button_margin);
10272 vmargin += XFASTINT (Vtool_bar_button_margin);
10273 }
10274 else if (CONSP (Vtool_bar_button_margin))
10275 {
10276 if (INTEGERP (XCAR (Vtool_bar_button_margin))
10277 && XINT (XCAR (Vtool_bar_button_margin)) > 0)
10278 hmargin += XFASTINT (XCAR (Vtool_bar_button_margin));
10279
10280 if (INTEGERP (XCDR (Vtool_bar_button_margin))
10281 && XINT (XCDR (Vtool_bar_button_margin)) > 0)
10282 vmargin += XFASTINT (XCDR (Vtool_bar_button_margin));
10283 }
10284
10285 if (auto_raise_tool_bar_buttons_p)
10286 {
10287 /* Add a `:relief' property to the image spec if the item is
10288 selected. */
10289 if (selected_p)
10290 {
10291 plist = Fplist_put (plist, QCrelief, make_number (-relief));
10292 hmargin -= relief;
10293 vmargin -= relief;
10294 }
10295 }
10296 else
10297 {
10298 /* If image is selected, display it pressed, i.e. with a
10299 negative relief. If it's not selected, display it with a
10300 raised relief. */
10301 plist = Fplist_put (plist, QCrelief,
10302 (selected_p
10303 ? make_number (-relief)
10304 : make_number (relief)));
10305 hmargin -= relief;
10306 vmargin -= relief;
10307 }
10308
10309 /* Put a margin around the image. */
10310 if (hmargin || vmargin)
10311 {
10312 if (hmargin == vmargin)
10313 plist = Fplist_put (plist, QCmargin, make_number (hmargin));
10314 else
10315 plist = Fplist_put (plist, QCmargin,
10316 Fcons (make_number (hmargin),
10317 make_number (vmargin)));
10318 }
10319
10320 /* If button is not enabled, and we don't have special images
10321 for the disabled state, make the image appear disabled by
10322 applying an appropriate algorithm to it. */
10323 if (!enabled_p && idx < 0)
10324 plist = Fplist_put (plist, QCconversion, Qdisabled);
10325
10326 /* Put a `display' text property on the string for the image to
10327 display. Put a `menu-item' property on the string that gives
10328 the start of this item's properties in the tool-bar items
10329 vector. */
10330 image = Fcons (Qimage, plist);
10331 props = list4 (Qdisplay, image,
10332 Qmenu_item, make_number (i * TOOL_BAR_ITEM_NSLOTS));
10333
10334 /* Let the last image hide all remaining spaces in the tool bar
10335 string. The string can be longer than needed when we reuse a
10336 previous string. */
10337 if (i + 1 == f->n_tool_bar_items)
10338 end = SCHARS (f->desired_tool_bar_string);
10339 else
10340 end = i + 1;
10341 Fadd_text_properties (make_number (i), make_number (end),
10342 props, f->desired_tool_bar_string);
10343 #undef PROP
10344 }
10345
10346 UNGCPRO;
10347 }
10348
10349
10350 /* Display one line of the tool-bar of frame IT->f.
10351
10352 HEIGHT specifies the desired height of the tool-bar line.
10353 If the actual height of the glyph row is less than HEIGHT, the
10354 row's height is increased to HEIGHT, and the icons are centered
10355 vertically in the new height.
10356
10357 If HEIGHT is -1, we are counting needed tool-bar lines, so don't
10358 count a final empty row in case the tool-bar width exactly matches
10359 the window width.
10360 */
10361
10362 static void
10363 display_tool_bar_line (struct it *it, int height)
10364 {
10365 struct glyph_row *row = it->glyph_row;
10366 int max_x = it->last_visible_x;
10367 struct glyph *last;
10368
10369 prepare_desired_row (row);
10370 row->y = it->current_y;
10371
10372 /* Note that this isn't made use of if the face hasn't a box,
10373 so there's no need to check the face here. */
10374 it->start_of_box_run_p = 1;
10375
10376 while (it->current_x < max_x)
10377 {
10378 int x, n_glyphs_before, i, nglyphs;
10379 struct it it_before;
10380
10381 /* Get the next display element. */
10382 if (!get_next_display_element (it))
10383 {
10384 /* Don't count empty row if we are counting needed tool-bar lines. */
10385 if (height < 0 && !it->hpos)
10386 return;
10387 break;
10388 }
10389
10390 /* Produce glyphs. */
10391 n_glyphs_before = row->used[TEXT_AREA];
10392 it_before = *it;
10393
10394 PRODUCE_GLYPHS (it);
10395
10396 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
10397 i = 0;
10398 x = it_before.current_x;
10399 while (i < nglyphs)
10400 {
10401 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
10402
10403 if (x + glyph->pixel_width > max_x)
10404 {
10405 /* Glyph doesn't fit on line. Backtrack. */
10406 row->used[TEXT_AREA] = n_glyphs_before;
10407 *it = it_before;
10408 /* If this is the only glyph on this line, it will never fit on the
10409 tool-bar, so skip it. But ensure there is at least one glyph,
10410 so we don't accidentally disable the tool-bar. */
10411 if (n_glyphs_before == 0
10412 && (it->vpos > 0 || IT_STRING_CHARPOS (*it) < it->end_charpos-1))
10413 break;
10414 goto out;
10415 }
10416
10417 ++it->hpos;
10418 x += glyph->pixel_width;
10419 ++i;
10420 }
10421
10422 /* Stop at line ends. */
10423 if (ITERATOR_AT_END_OF_LINE_P (it))
10424 break;
10425
10426 set_iterator_to_next (it, 1);
10427 }
10428
10429 out:;
10430
10431 row->displays_text_p = row->used[TEXT_AREA] != 0;
10432
10433 /* Use default face for the border below the tool bar.
10434
10435 FIXME: When auto-resize-tool-bars is grow-only, there is
10436 no additional border below the possibly empty tool-bar lines.
10437 So to make the extra empty lines look "normal", we have to
10438 use the tool-bar face for the border too. */
10439 if (!row->displays_text_p && !EQ (Vauto_resize_tool_bars, Qgrow_only))
10440 it->face_id = DEFAULT_FACE_ID;
10441
10442 extend_face_to_end_of_line (it);
10443 last = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
10444 last->right_box_line_p = 1;
10445 if (last == row->glyphs[TEXT_AREA])
10446 last->left_box_line_p = 1;
10447
10448 /* Make line the desired height and center it vertically. */
10449 if ((height -= it->max_ascent + it->max_descent) > 0)
10450 {
10451 /* Don't add more than one line height. */
10452 height %= FRAME_LINE_HEIGHT (it->f);
10453 it->max_ascent += height / 2;
10454 it->max_descent += (height + 1) / 2;
10455 }
10456
10457 compute_line_metrics (it);
10458
10459 /* If line is empty, make it occupy the rest of the tool-bar. */
10460 if (!row->displays_text_p)
10461 {
10462 row->height = row->phys_height = it->last_visible_y - row->y;
10463 row->visible_height = row->height;
10464 row->ascent = row->phys_ascent = 0;
10465 row->extra_line_spacing = 0;
10466 }
10467
10468 row->full_width_p = 1;
10469 row->continued_p = 0;
10470 row->truncated_on_left_p = 0;
10471 row->truncated_on_right_p = 0;
10472
10473 it->current_x = it->hpos = 0;
10474 it->current_y += row->height;
10475 ++it->vpos;
10476 ++it->glyph_row;
10477 }
10478
10479
10480 /* Max tool-bar height. */
10481
10482 #define MAX_FRAME_TOOL_BAR_HEIGHT(f) \
10483 ((FRAME_LINE_HEIGHT (f) * FRAME_LINES (f)))
10484
10485 /* Value is the number of screen lines needed to make all tool-bar
10486 items of frame F visible. The number of actual rows needed is
10487 returned in *N_ROWS if non-NULL. */
10488
10489 static int
10490 tool_bar_lines_needed (struct frame *f, int *n_rows)
10491 {
10492 struct window *w = XWINDOW (f->tool_bar_window);
10493 struct it it;
10494 /* tool_bar_lines_needed is called from redisplay_tool_bar after building
10495 the desired matrix, so use (unused) mode-line row as temporary row to
10496 avoid destroying the first tool-bar row. */
10497 struct glyph_row *temp_row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
10498
10499 /* Initialize an iterator for iteration over
10500 F->desired_tool_bar_string in the tool-bar window of frame F. */
10501 init_iterator (&it, w, -1, -1, temp_row, TOOL_BAR_FACE_ID);
10502 it.first_visible_x = 0;
10503 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
10504 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
10505
10506 while (!ITERATOR_AT_END_P (&it))
10507 {
10508 clear_glyph_row (temp_row);
10509 it.glyph_row = temp_row;
10510 display_tool_bar_line (&it, -1);
10511 }
10512 clear_glyph_row (temp_row);
10513
10514 /* f->n_tool_bar_rows == 0 means "unknown"; -1 means no tool-bar. */
10515 if (n_rows)
10516 *n_rows = it.vpos > 0 ? it.vpos : -1;
10517
10518 return (it.current_y + FRAME_LINE_HEIGHT (f) - 1) / FRAME_LINE_HEIGHT (f);
10519 }
10520
10521
10522 DEFUN ("tool-bar-lines-needed", Ftool_bar_lines_needed, Stool_bar_lines_needed,
10523 0, 1, 0,
10524 doc: /* Return the number of lines occupied by the tool bar of FRAME. */)
10525 (Lisp_Object frame)
10526 {
10527 struct frame *f;
10528 struct window *w;
10529 int nlines = 0;
10530
10531 if (NILP (frame))
10532 frame = selected_frame;
10533 else
10534 CHECK_FRAME (frame);
10535 f = XFRAME (frame);
10536
10537 if (WINDOWP (f->tool_bar_window)
10538 || (w = XWINDOW (f->tool_bar_window),
10539 WINDOW_TOTAL_LINES (w) > 0))
10540 {
10541 update_tool_bar (f, 1);
10542 if (f->n_tool_bar_items)
10543 {
10544 build_desired_tool_bar_string (f);
10545 nlines = tool_bar_lines_needed (f, NULL);
10546 }
10547 }
10548
10549 return make_number (nlines);
10550 }
10551
10552
10553 /* Display the tool-bar of frame F. Value is non-zero if tool-bar's
10554 height should be changed. */
10555
10556 static int
10557 redisplay_tool_bar (struct frame *f)
10558 {
10559 struct window *w;
10560 struct it it;
10561 struct glyph_row *row;
10562
10563 #if defined (USE_GTK) || defined (HAVE_NS)
10564 if (FRAME_EXTERNAL_TOOL_BAR (f))
10565 update_frame_tool_bar (f);
10566 return 0;
10567 #endif
10568
10569 /* If frame hasn't a tool-bar window or if it is zero-height, don't
10570 do anything. This means you must start with tool-bar-lines
10571 non-zero to get the auto-sizing effect. Or in other words, you
10572 can turn off tool-bars by specifying tool-bar-lines zero. */
10573 if (!WINDOWP (f->tool_bar_window)
10574 || (w = XWINDOW (f->tool_bar_window),
10575 WINDOW_TOTAL_LINES (w) == 0))
10576 return 0;
10577
10578 /* Set up an iterator for the tool-bar window. */
10579 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
10580 it.first_visible_x = 0;
10581 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
10582 row = it.glyph_row;
10583
10584 /* Build a string that represents the contents of the tool-bar. */
10585 build_desired_tool_bar_string (f);
10586 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
10587
10588 if (f->n_tool_bar_rows == 0)
10589 {
10590 int nlines;
10591
10592 if ((nlines = tool_bar_lines_needed (f, &f->n_tool_bar_rows),
10593 nlines != WINDOW_TOTAL_LINES (w)))
10594 {
10595 Lisp_Object frame;
10596 int old_height = WINDOW_TOTAL_LINES (w);
10597
10598 XSETFRAME (frame, f);
10599 Fmodify_frame_parameters (frame,
10600 Fcons (Fcons (Qtool_bar_lines,
10601 make_number (nlines)),
10602 Qnil));
10603 if (WINDOW_TOTAL_LINES (w) != old_height)
10604 {
10605 clear_glyph_matrix (w->desired_matrix);
10606 fonts_changed_p = 1;
10607 return 1;
10608 }
10609 }
10610 }
10611
10612 /* Display as many lines as needed to display all tool-bar items. */
10613
10614 if (f->n_tool_bar_rows > 0)
10615 {
10616 int border, rows, height, extra;
10617
10618 if (INTEGERP (Vtool_bar_border))
10619 border = XINT (Vtool_bar_border);
10620 else if (EQ (Vtool_bar_border, Qinternal_border_width))
10621 border = FRAME_INTERNAL_BORDER_WIDTH (f);
10622 else if (EQ (Vtool_bar_border, Qborder_width))
10623 border = f->border_width;
10624 else
10625 border = 0;
10626 if (border < 0)
10627 border = 0;
10628
10629 rows = f->n_tool_bar_rows;
10630 height = max (1, (it.last_visible_y - border) / rows);
10631 extra = it.last_visible_y - border - height * rows;
10632
10633 while (it.current_y < it.last_visible_y)
10634 {
10635 int h = 0;
10636 if (extra > 0 && rows-- > 0)
10637 {
10638 h = (extra + rows - 1) / rows;
10639 extra -= h;
10640 }
10641 display_tool_bar_line (&it, height + h);
10642 }
10643 }
10644 else
10645 {
10646 while (it.current_y < it.last_visible_y)
10647 display_tool_bar_line (&it, 0);
10648 }
10649
10650 /* It doesn't make much sense to try scrolling in the tool-bar
10651 window, so don't do it. */
10652 w->desired_matrix->no_scrolling_p = 1;
10653 w->must_be_updated_p = 1;
10654
10655 if (!NILP (Vauto_resize_tool_bars))
10656 {
10657 int max_tool_bar_height = MAX_FRAME_TOOL_BAR_HEIGHT (f);
10658 int change_height_p = 0;
10659
10660 /* If we couldn't display everything, change the tool-bar's
10661 height if there is room for more. */
10662 if (IT_STRING_CHARPOS (it) < it.end_charpos
10663 && it.current_y < max_tool_bar_height)
10664 change_height_p = 1;
10665
10666 row = it.glyph_row - 1;
10667
10668 /* If there are blank lines at the end, except for a partially
10669 visible blank line at the end that is smaller than
10670 FRAME_LINE_HEIGHT, change the tool-bar's height. */
10671 if (!row->displays_text_p
10672 && row->height >= FRAME_LINE_HEIGHT (f))
10673 change_height_p = 1;
10674
10675 /* If row displays tool-bar items, but is partially visible,
10676 change the tool-bar's height. */
10677 if (row->displays_text_p
10678 && MATRIX_ROW_BOTTOM_Y (row) > it.last_visible_y
10679 && MATRIX_ROW_BOTTOM_Y (row) < max_tool_bar_height)
10680 change_height_p = 1;
10681
10682 /* Resize windows as needed by changing the `tool-bar-lines'
10683 frame parameter. */
10684 if (change_height_p)
10685 {
10686 Lisp_Object frame;
10687 int old_height = WINDOW_TOTAL_LINES (w);
10688 int nrows;
10689 int nlines = tool_bar_lines_needed (f, &nrows);
10690
10691 change_height_p = ((EQ (Vauto_resize_tool_bars, Qgrow_only)
10692 && !f->minimize_tool_bar_window_p)
10693 ? (nlines > old_height)
10694 : (nlines != old_height));
10695 f->minimize_tool_bar_window_p = 0;
10696
10697 if (change_height_p)
10698 {
10699 XSETFRAME (frame, f);
10700 Fmodify_frame_parameters (frame,
10701 Fcons (Fcons (Qtool_bar_lines,
10702 make_number (nlines)),
10703 Qnil));
10704 if (WINDOW_TOTAL_LINES (w) != old_height)
10705 {
10706 clear_glyph_matrix (w->desired_matrix);
10707 f->n_tool_bar_rows = nrows;
10708 fonts_changed_p = 1;
10709 return 1;
10710 }
10711 }
10712 }
10713 }
10714
10715 f->minimize_tool_bar_window_p = 0;
10716 return 0;
10717 }
10718
10719
10720 /* Get information about the tool-bar item which is displayed in GLYPH
10721 on frame F. Return in *PROP_IDX the index where tool-bar item
10722 properties start in F->tool_bar_items. Value is zero if
10723 GLYPH doesn't display a tool-bar item. */
10724
10725 static int
10726 tool_bar_item_info (struct frame *f, struct glyph *glyph, int *prop_idx)
10727 {
10728 Lisp_Object prop;
10729 int success_p;
10730 int charpos;
10731
10732 /* This function can be called asynchronously, which means we must
10733 exclude any possibility that Fget_text_property signals an
10734 error. */
10735 charpos = min (SCHARS (f->current_tool_bar_string), glyph->charpos);
10736 charpos = max (0, charpos);
10737
10738 /* Get the text property `menu-item' at pos. The value of that
10739 property is the start index of this item's properties in
10740 F->tool_bar_items. */
10741 prop = Fget_text_property (make_number (charpos),
10742 Qmenu_item, f->current_tool_bar_string);
10743 if (INTEGERP (prop))
10744 {
10745 *prop_idx = XINT (prop);
10746 success_p = 1;
10747 }
10748 else
10749 success_p = 0;
10750
10751 return success_p;
10752 }
10753
10754 \f
10755 /* Get information about the tool-bar item at position X/Y on frame F.
10756 Return in *GLYPH a pointer to the glyph of the tool-bar item in
10757 the current matrix of the tool-bar window of F, or NULL if not
10758 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
10759 item in F->tool_bar_items. Value is
10760
10761 -1 if X/Y is not on a tool-bar item
10762 0 if X/Y is on the same item that was highlighted before.
10763 1 otherwise. */
10764
10765 static int
10766 get_tool_bar_item (struct frame *f, int x, int y, struct glyph **glyph,
10767 int *hpos, int *vpos, int *prop_idx)
10768 {
10769 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
10770 struct window *w = XWINDOW (f->tool_bar_window);
10771 int area;
10772
10773 /* Find the glyph under X/Y. */
10774 *glyph = x_y_to_hpos_vpos (w, x, y, hpos, vpos, 0, 0, &area);
10775 if (*glyph == NULL)
10776 return -1;
10777
10778 /* Get the start of this tool-bar item's properties in
10779 f->tool_bar_items. */
10780 if (!tool_bar_item_info (f, *glyph, prop_idx))
10781 return -1;
10782
10783 /* Is mouse on the highlighted item? */
10784 if (EQ (f->tool_bar_window, hlinfo->mouse_face_window)
10785 && *vpos >= hlinfo->mouse_face_beg_row
10786 && *vpos <= hlinfo->mouse_face_end_row
10787 && (*vpos > hlinfo->mouse_face_beg_row
10788 || *hpos >= hlinfo->mouse_face_beg_col)
10789 && (*vpos < hlinfo->mouse_face_end_row
10790 || *hpos < hlinfo->mouse_face_end_col
10791 || hlinfo->mouse_face_past_end))
10792 return 0;
10793
10794 return 1;
10795 }
10796
10797
10798 /* EXPORT:
10799 Handle mouse button event on the tool-bar of frame F, at
10800 frame-relative coordinates X/Y. DOWN_P is 1 for a button press,
10801 0 for button release. MODIFIERS is event modifiers for button
10802 release. */
10803
10804 void
10805 handle_tool_bar_click (struct frame *f, int x, int y, int down_p,
10806 unsigned int modifiers)
10807 {
10808 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
10809 struct window *w = XWINDOW (f->tool_bar_window);
10810 int hpos, vpos, prop_idx;
10811 struct glyph *glyph;
10812 Lisp_Object enabled_p;
10813
10814 /* If not on the highlighted tool-bar item, return. */
10815 frame_to_window_pixel_xy (w, &x, &y);
10816 if (get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx) != 0)
10817 return;
10818
10819 /* If item is disabled, do nothing. */
10820 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
10821 if (NILP (enabled_p))
10822 return;
10823
10824 if (down_p)
10825 {
10826 /* Show item in pressed state. */
10827 show_mouse_face (hlinfo, DRAW_IMAGE_SUNKEN);
10828 hlinfo->mouse_face_image_state = DRAW_IMAGE_SUNKEN;
10829 last_tool_bar_item = prop_idx;
10830 }
10831 else
10832 {
10833 Lisp_Object key, frame;
10834 struct input_event event;
10835 EVENT_INIT (event);
10836
10837 /* Show item in released state. */
10838 show_mouse_face (hlinfo, DRAW_IMAGE_RAISED);
10839 hlinfo->mouse_face_image_state = DRAW_IMAGE_RAISED;
10840
10841 key = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_KEY);
10842
10843 XSETFRAME (frame, f);
10844 event.kind = TOOL_BAR_EVENT;
10845 event.frame_or_window = frame;
10846 event.arg = frame;
10847 kbd_buffer_store_event (&event);
10848
10849 event.kind = TOOL_BAR_EVENT;
10850 event.frame_or_window = frame;
10851 event.arg = key;
10852 event.modifiers = modifiers;
10853 kbd_buffer_store_event (&event);
10854 last_tool_bar_item = -1;
10855 }
10856 }
10857
10858
10859 /* Possibly highlight a tool-bar item on frame F when mouse moves to
10860 tool-bar window-relative coordinates X/Y. Called from
10861 note_mouse_highlight. */
10862
10863 static void
10864 note_tool_bar_highlight (struct frame *f, int x, int y)
10865 {
10866 Lisp_Object window = f->tool_bar_window;
10867 struct window *w = XWINDOW (window);
10868 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
10869 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
10870 int hpos, vpos;
10871 struct glyph *glyph;
10872 struct glyph_row *row;
10873 int i;
10874 Lisp_Object enabled_p;
10875 int prop_idx;
10876 enum draw_glyphs_face draw = DRAW_IMAGE_RAISED;
10877 int mouse_down_p, rc;
10878
10879 /* Function note_mouse_highlight is called with negative X/Y
10880 values when mouse moves outside of the frame. */
10881 if (x <= 0 || y <= 0)
10882 {
10883 clear_mouse_face (hlinfo);
10884 return;
10885 }
10886
10887 rc = get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx);
10888 if (rc < 0)
10889 {
10890 /* Not on tool-bar item. */
10891 clear_mouse_face (hlinfo);
10892 return;
10893 }
10894 else if (rc == 0)
10895 /* On same tool-bar item as before. */
10896 goto set_help_echo;
10897
10898 clear_mouse_face (hlinfo);
10899
10900 /* Mouse is down, but on different tool-bar item? */
10901 mouse_down_p = (dpyinfo->grabbed
10902 && f == last_mouse_frame
10903 && FRAME_LIVE_P (f));
10904 if (mouse_down_p
10905 && last_tool_bar_item != prop_idx)
10906 return;
10907
10908 hlinfo->mouse_face_image_state = DRAW_NORMAL_TEXT;
10909 draw = mouse_down_p ? DRAW_IMAGE_SUNKEN : DRAW_IMAGE_RAISED;
10910
10911 /* If tool-bar item is not enabled, don't highlight it. */
10912 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
10913 if (!NILP (enabled_p))
10914 {
10915 /* Compute the x-position of the glyph. In front and past the
10916 image is a space. We include this in the highlighted area. */
10917 row = MATRIX_ROW (w->current_matrix, vpos);
10918 for (i = x = 0; i < hpos; ++i)
10919 x += row->glyphs[TEXT_AREA][i].pixel_width;
10920
10921 /* Record this as the current active region. */
10922 hlinfo->mouse_face_beg_col = hpos;
10923 hlinfo->mouse_face_beg_row = vpos;
10924 hlinfo->mouse_face_beg_x = x;
10925 hlinfo->mouse_face_beg_y = row->y;
10926 hlinfo->mouse_face_past_end = 0;
10927
10928 hlinfo->mouse_face_end_col = hpos + 1;
10929 hlinfo->mouse_face_end_row = vpos;
10930 hlinfo->mouse_face_end_x = x + glyph->pixel_width;
10931 hlinfo->mouse_face_end_y = row->y;
10932 hlinfo->mouse_face_window = window;
10933 hlinfo->mouse_face_face_id = TOOL_BAR_FACE_ID;
10934
10935 /* Display it as active. */
10936 show_mouse_face (hlinfo, draw);
10937 hlinfo->mouse_face_image_state = draw;
10938 }
10939
10940 set_help_echo:
10941
10942 /* Set help_echo_string to a help string to display for this tool-bar item.
10943 XTread_socket does the rest. */
10944 help_echo_object = help_echo_window = Qnil;
10945 help_echo_pos = -1;
10946 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_HELP);
10947 if (NILP (help_echo_string))
10948 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_CAPTION);
10949 }
10950
10951 #endif /* HAVE_WINDOW_SYSTEM */
10952
10953
10954 \f
10955 /************************************************************************
10956 Horizontal scrolling
10957 ************************************************************************/
10958
10959 static int hscroll_window_tree (Lisp_Object);
10960 static int hscroll_windows (Lisp_Object);
10961
10962 /* For all leaf windows in the window tree rooted at WINDOW, set their
10963 hscroll value so that PT is (i) visible in the window, and (ii) so
10964 that it is not within a certain margin at the window's left and
10965 right border. Value is non-zero if any window's hscroll has been
10966 changed. */
10967
10968 static int
10969 hscroll_window_tree (Lisp_Object window)
10970 {
10971 int hscrolled_p = 0;
10972 int hscroll_relative_p = FLOATP (Vhscroll_step);
10973 int hscroll_step_abs = 0;
10974 double hscroll_step_rel = 0;
10975
10976 if (hscroll_relative_p)
10977 {
10978 hscroll_step_rel = XFLOAT_DATA (Vhscroll_step);
10979 if (hscroll_step_rel < 0)
10980 {
10981 hscroll_relative_p = 0;
10982 hscroll_step_abs = 0;
10983 }
10984 }
10985 else if (INTEGERP (Vhscroll_step))
10986 {
10987 hscroll_step_abs = XINT (Vhscroll_step);
10988 if (hscroll_step_abs < 0)
10989 hscroll_step_abs = 0;
10990 }
10991 else
10992 hscroll_step_abs = 0;
10993
10994 while (WINDOWP (window))
10995 {
10996 struct window *w = XWINDOW (window);
10997
10998 if (WINDOWP (w->hchild))
10999 hscrolled_p |= hscroll_window_tree (w->hchild);
11000 else if (WINDOWP (w->vchild))
11001 hscrolled_p |= hscroll_window_tree (w->vchild);
11002 else if (w->cursor.vpos >= 0)
11003 {
11004 int h_margin;
11005 int text_area_width;
11006 struct glyph_row *current_cursor_row
11007 = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
11008 struct glyph_row *desired_cursor_row
11009 = MATRIX_ROW (w->desired_matrix, w->cursor.vpos);
11010 struct glyph_row *cursor_row
11011 = (desired_cursor_row->enabled_p
11012 ? desired_cursor_row
11013 : current_cursor_row);
11014
11015 text_area_width = window_box_width (w, TEXT_AREA);
11016
11017 /* Scroll when cursor is inside this scroll margin. */
11018 h_margin = hscroll_margin * WINDOW_FRAME_COLUMN_WIDTH (w);
11019
11020 if (!NILP (Fbuffer_local_value (Qauto_hscroll_mode, w->buffer))
11021 && ((XFASTINT (w->hscroll)
11022 && w->cursor.x <= h_margin)
11023 || (cursor_row->enabled_p
11024 && cursor_row->truncated_on_right_p
11025 && (w->cursor.x >= text_area_width - h_margin))))
11026 {
11027 struct it it;
11028 int hscroll;
11029 struct buffer *saved_current_buffer;
11030 EMACS_INT pt;
11031 int wanted_x;
11032
11033 /* Find point in a display of infinite width. */
11034 saved_current_buffer = current_buffer;
11035 current_buffer = XBUFFER (w->buffer);
11036
11037 if (w == XWINDOW (selected_window))
11038 pt = PT;
11039 else
11040 {
11041 pt = marker_position (w->pointm);
11042 pt = max (BEGV, pt);
11043 pt = min (ZV, pt);
11044 }
11045
11046 /* Move iterator to pt starting at cursor_row->start in
11047 a line with infinite width. */
11048 init_to_row_start (&it, w, cursor_row);
11049 it.last_visible_x = INFINITY;
11050 move_it_in_display_line_to (&it, pt, -1, MOVE_TO_POS);
11051 current_buffer = saved_current_buffer;
11052
11053 /* Position cursor in window. */
11054 if (!hscroll_relative_p && hscroll_step_abs == 0)
11055 hscroll = max (0, (it.current_x
11056 - (ITERATOR_AT_END_OF_LINE_P (&it)
11057 ? (text_area_width - 4 * FRAME_COLUMN_WIDTH (it.f))
11058 : (text_area_width / 2))))
11059 / FRAME_COLUMN_WIDTH (it.f);
11060 else if (w->cursor.x >= text_area_width - h_margin)
11061 {
11062 if (hscroll_relative_p)
11063 wanted_x = text_area_width * (1 - hscroll_step_rel)
11064 - h_margin;
11065 else
11066 wanted_x = text_area_width
11067 - hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
11068 - h_margin;
11069 hscroll
11070 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
11071 }
11072 else
11073 {
11074 if (hscroll_relative_p)
11075 wanted_x = text_area_width * hscroll_step_rel
11076 + h_margin;
11077 else
11078 wanted_x = hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
11079 + h_margin;
11080 hscroll
11081 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
11082 }
11083 hscroll = max (hscroll, XFASTINT (w->min_hscroll));
11084
11085 /* Don't call Fset_window_hscroll if value hasn't
11086 changed because it will prevent redisplay
11087 optimizations. */
11088 if (XFASTINT (w->hscroll) != hscroll)
11089 {
11090 XBUFFER (w->buffer)->prevent_redisplay_optimizations_p = 1;
11091 w->hscroll = make_number (hscroll);
11092 hscrolled_p = 1;
11093 }
11094 }
11095 }
11096
11097 window = w->next;
11098 }
11099
11100 /* Value is non-zero if hscroll of any leaf window has been changed. */
11101 return hscrolled_p;
11102 }
11103
11104
11105 /* Set hscroll so that cursor is visible and not inside horizontal
11106 scroll margins for all windows in the tree rooted at WINDOW. See
11107 also hscroll_window_tree above. Value is non-zero if any window's
11108 hscroll has been changed. If it has, desired matrices on the frame
11109 of WINDOW are cleared. */
11110
11111 static int
11112 hscroll_windows (Lisp_Object window)
11113 {
11114 int hscrolled_p = hscroll_window_tree (window);
11115 if (hscrolled_p)
11116 clear_desired_matrices (XFRAME (WINDOW_FRAME (XWINDOW (window))));
11117 return hscrolled_p;
11118 }
11119
11120
11121 \f
11122 /************************************************************************
11123 Redisplay
11124 ************************************************************************/
11125
11126 /* Variables holding some state of redisplay if GLYPH_DEBUG is defined
11127 to a non-zero value. This is sometimes handy to have in a debugger
11128 session. */
11129
11130 #if GLYPH_DEBUG
11131
11132 /* First and last unchanged row for try_window_id. */
11133
11134 int debug_first_unchanged_at_end_vpos;
11135 int debug_last_unchanged_at_beg_vpos;
11136
11137 /* Delta vpos and y. */
11138
11139 int debug_dvpos, debug_dy;
11140
11141 /* Delta in characters and bytes for try_window_id. */
11142
11143 EMACS_INT debug_delta, debug_delta_bytes;
11144
11145 /* Values of window_end_pos and window_end_vpos at the end of
11146 try_window_id. */
11147
11148 EMACS_INT debug_end_vpos;
11149
11150 /* Append a string to W->desired_matrix->method. FMT is a printf
11151 format string. A1...A9 are a supplement for a variable-length
11152 argument list. If trace_redisplay_p is non-zero also printf the
11153 resulting string to stderr. */
11154
11155 static void
11156 debug_method_add (w, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9)
11157 struct window *w;
11158 char *fmt;
11159 int a1, a2, a3, a4, a5, a6, a7, a8, a9;
11160 {
11161 char buffer[512];
11162 char *method = w->desired_matrix->method;
11163 int len = strlen (method);
11164 int size = sizeof w->desired_matrix->method;
11165 int remaining = size - len - 1;
11166
11167 sprintf (buffer, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9);
11168 if (len && remaining)
11169 {
11170 method[len] = '|';
11171 --remaining, ++len;
11172 }
11173
11174 strncpy (method + len, buffer, remaining);
11175
11176 if (trace_redisplay_p)
11177 fprintf (stderr, "%p (%s): %s\n",
11178 w,
11179 ((BUFFERP (w->buffer)
11180 && STRINGP (XBUFFER (w->buffer)->name))
11181 ? SSDATA (XBUFFER (w->buffer)->name)
11182 : "no buffer"),
11183 buffer);
11184 }
11185
11186 #endif /* GLYPH_DEBUG */
11187
11188
11189 /* Value is non-zero if all changes in window W, which displays
11190 current_buffer, are in the text between START and END. START is a
11191 buffer position, END is given as a distance from Z. Used in
11192 redisplay_internal for display optimization. */
11193
11194 static INLINE int
11195 text_outside_line_unchanged_p (struct window *w,
11196 EMACS_INT start, EMACS_INT end)
11197 {
11198 int unchanged_p = 1;
11199
11200 /* If text or overlays have changed, see where. */
11201 if (XFASTINT (w->last_modified) < MODIFF
11202 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
11203 {
11204 /* Gap in the line? */
11205 if (GPT < start || Z - GPT < end)
11206 unchanged_p = 0;
11207
11208 /* Changes start in front of the line, or end after it? */
11209 if (unchanged_p
11210 && (BEG_UNCHANGED < start - 1
11211 || END_UNCHANGED < end))
11212 unchanged_p = 0;
11213
11214 /* If selective display, can't optimize if changes start at the
11215 beginning of the line. */
11216 if (unchanged_p
11217 && INTEGERP (BVAR (current_buffer, selective_display))
11218 && XINT (BVAR (current_buffer, selective_display)) > 0
11219 && (BEG_UNCHANGED < start || GPT <= start))
11220 unchanged_p = 0;
11221
11222 /* If there are overlays at the start or end of the line, these
11223 may have overlay strings with newlines in them. A change at
11224 START, for instance, may actually concern the display of such
11225 overlay strings as well, and they are displayed on different
11226 lines. So, quickly rule out this case. (For the future, it
11227 might be desirable to implement something more telling than
11228 just BEG/END_UNCHANGED.) */
11229 if (unchanged_p)
11230 {
11231 if (BEG + BEG_UNCHANGED == start
11232 && overlay_touches_p (start))
11233 unchanged_p = 0;
11234 if (END_UNCHANGED == end
11235 && overlay_touches_p (Z - end))
11236 unchanged_p = 0;
11237 }
11238
11239 /* Under bidi reordering, adding or deleting a character in the
11240 beginning of a paragraph, before the first strong directional
11241 character, can change the base direction of the paragraph (unless
11242 the buffer specifies a fixed paragraph direction), which will
11243 require to redisplay the whole paragraph. It might be worthwhile
11244 to find the paragraph limits and widen the range of redisplayed
11245 lines to that, but for now just give up this optimization. */
11246 if (!NILP (BVAR (XBUFFER (w->buffer), bidi_display_reordering))
11247 && NILP (BVAR (XBUFFER (w->buffer), bidi_paragraph_direction)))
11248 unchanged_p = 0;
11249 }
11250
11251 return unchanged_p;
11252 }
11253
11254
11255 /* Do a frame update, taking possible shortcuts into account. This is
11256 the main external entry point for redisplay.
11257
11258 If the last redisplay displayed an echo area message and that message
11259 is no longer requested, we clear the echo area or bring back the
11260 mini-buffer if that is in use. */
11261
11262 void
11263 redisplay (void)
11264 {
11265 redisplay_internal ();
11266 }
11267
11268
11269 static Lisp_Object
11270 overlay_arrow_string_or_property (Lisp_Object var)
11271 {
11272 Lisp_Object val;
11273
11274 if (val = Fget (var, Qoverlay_arrow_string), STRINGP (val))
11275 return val;
11276
11277 return Voverlay_arrow_string;
11278 }
11279
11280 /* Return 1 if there are any overlay-arrows in current_buffer. */
11281 static int
11282 overlay_arrow_in_current_buffer_p (void)
11283 {
11284 Lisp_Object vlist;
11285
11286 for (vlist = Voverlay_arrow_variable_list;
11287 CONSP (vlist);
11288 vlist = XCDR (vlist))
11289 {
11290 Lisp_Object var = XCAR (vlist);
11291 Lisp_Object val;
11292
11293 if (!SYMBOLP (var))
11294 continue;
11295 val = find_symbol_value (var);
11296 if (MARKERP (val)
11297 && current_buffer == XMARKER (val)->buffer)
11298 return 1;
11299 }
11300 return 0;
11301 }
11302
11303
11304 /* Return 1 if any overlay_arrows have moved or overlay-arrow-string
11305 has changed. */
11306
11307 static int
11308 overlay_arrows_changed_p (void)
11309 {
11310 Lisp_Object vlist;
11311
11312 for (vlist = Voverlay_arrow_variable_list;
11313 CONSP (vlist);
11314 vlist = XCDR (vlist))
11315 {
11316 Lisp_Object var = XCAR (vlist);
11317 Lisp_Object val, pstr;
11318
11319 if (!SYMBOLP (var))
11320 continue;
11321 val = find_symbol_value (var);
11322 if (!MARKERP (val))
11323 continue;
11324 if (! EQ (COERCE_MARKER (val),
11325 Fget (var, Qlast_arrow_position))
11326 || ! (pstr = overlay_arrow_string_or_property (var),
11327 EQ (pstr, Fget (var, Qlast_arrow_string))))
11328 return 1;
11329 }
11330 return 0;
11331 }
11332
11333 /* Mark overlay arrows to be updated on next redisplay. */
11334
11335 static void
11336 update_overlay_arrows (int up_to_date)
11337 {
11338 Lisp_Object vlist;
11339
11340 for (vlist = Voverlay_arrow_variable_list;
11341 CONSP (vlist);
11342 vlist = XCDR (vlist))
11343 {
11344 Lisp_Object var = XCAR (vlist);
11345
11346 if (!SYMBOLP (var))
11347 continue;
11348
11349 if (up_to_date > 0)
11350 {
11351 Lisp_Object val = find_symbol_value (var);
11352 Fput (var, Qlast_arrow_position,
11353 COERCE_MARKER (val));
11354 Fput (var, Qlast_arrow_string,
11355 overlay_arrow_string_or_property (var));
11356 }
11357 else if (up_to_date < 0
11358 || !NILP (Fget (var, Qlast_arrow_position)))
11359 {
11360 Fput (var, Qlast_arrow_position, Qt);
11361 Fput (var, Qlast_arrow_string, Qt);
11362 }
11363 }
11364 }
11365
11366
11367 /* Return overlay arrow string to display at row.
11368 Return integer (bitmap number) for arrow bitmap in left fringe.
11369 Return nil if no overlay arrow. */
11370
11371 static Lisp_Object
11372 overlay_arrow_at_row (struct it *it, struct glyph_row *row)
11373 {
11374 Lisp_Object vlist;
11375
11376 for (vlist = Voverlay_arrow_variable_list;
11377 CONSP (vlist);
11378 vlist = XCDR (vlist))
11379 {
11380 Lisp_Object var = XCAR (vlist);
11381 Lisp_Object val;
11382
11383 if (!SYMBOLP (var))
11384 continue;
11385
11386 val = find_symbol_value (var);
11387
11388 if (MARKERP (val)
11389 && current_buffer == XMARKER (val)->buffer
11390 && (MATRIX_ROW_START_CHARPOS (row) == marker_position (val)))
11391 {
11392 if (FRAME_WINDOW_P (it->f)
11393 /* FIXME: if ROW->reversed_p is set, this should test
11394 the right fringe, not the left one. */
11395 && WINDOW_LEFT_FRINGE_WIDTH (it->w) > 0)
11396 {
11397 #ifdef HAVE_WINDOW_SYSTEM
11398 if (val = Fget (var, Qoverlay_arrow_bitmap), SYMBOLP (val))
11399 {
11400 int fringe_bitmap;
11401 if ((fringe_bitmap = lookup_fringe_bitmap (val)) != 0)
11402 return make_number (fringe_bitmap);
11403 }
11404 #endif
11405 return make_number (-1); /* Use default arrow bitmap */
11406 }
11407 return overlay_arrow_string_or_property (var);
11408 }
11409 }
11410
11411 return Qnil;
11412 }
11413
11414 /* Return 1 if point moved out of or into a composition. Otherwise
11415 return 0. PREV_BUF and PREV_PT are the last point buffer and
11416 position. BUF and PT are the current point buffer and position. */
11417
11418 static int
11419 check_point_in_composition (struct buffer *prev_buf, EMACS_INT prev_pt,
11420 struct buffer *buf, EMACS_INT pt)
11421 {
11422 EMACS_INT start, end;
11423 Lisp_Object prop;
11424 Lisp_Object buffer;
11425
11426 XSETBUFFER (buffer, buf);
11427 /* Check a composition at the last point if point moved within the
11428 same buffer. */
11429 if (prev_buf == buf)
11430 {
11431 if (prev_pt == pt)
11432 /* Point didn't move. */
11433 return 0;
11434
11435 if (prev_pt > BUF_BEGV (buf) && prev_pt < BUF_ZV (buf)
11436 && find_composition (prev_pt, -1, &start, &end, &prop, buffer)
11437 && COMPOSITION_VALID_P (start, end, prop)
11438 && start < prev_pt && end > prev_pt)
11439 /* The last point was within the composition. Return 1 iff
11440 point moved out of the composition. */
11441 return (pt <= start || pt >= end);
11442 }
11443
11444 /* Check a composition at the current point. */
11445 return (pt > BUF_BEGV (buf) && pt < BUF_ZV (buf)
11446 && find_composition (pt, -1, &start, &end, &prop, buffer)
11447 && COMPOSITION_VALID_P (start, end, prop)
11448 && start < pt && end > pt);
11449 }
11450
11451
11452 /* Reconsider the setting of B->clip_changed which is displayed
11453 in window W. */
11454
11455 static INLINE void
11456 reconsider_clip_changes (struct window *w, struct buffer *b)
11457 {
11458 if (b->clip_changed
11459 && !NILP (w->window_end_valid)
11460 && w->current_matrix->buffer == b
11461 && w->current_matrix->zv == BUF_ZV (b)
11462 && w->current_matrix->begv == BUF_BEGV (b))
11463 b->clip_changed = 0;
11464
11465 /* If display wasn't paused, and W is not a tool bar window, see if
11466 point has been moved into or out of a composition. In that case,
11467 we set b->clip_changed to 1 to force updating the screen. If
11468 b->clip_changed has already been set to 1, we can skip this
11469 check. */
11470 if (!b->clip_changed
11471 && BUFFERP (w->buffer) && !NILP (w->window_end_valid))
11472 {
11473 EMACS_INT pt;
11474
11475 if (w == XWINDOW (selected_window))
11476 pt = PT;
11477 else
11478 pt = marker_position (w->pointm);
11479
11480 if ((w->current_matrix->buffer != XBUFFER (w->buffer)
11481 || pt != XINT (w->last_point))
11482 && check_point_in_composition (w->current_matrix->buffer,
11483 XINT (w->last_point),
11484 XBUFFER (w->buffer), pt))
11485 b->clip_changed = 1;
11486 }
11487 }
11488 \f
11489
11490 /* Select FRAME to forward the values of frame-local variables into C
11491 variables so that the redisplay routines can access those values
11492 directly. */
11493
11494 static void
11495 select_frame_for_redisplay (Lisp_Object frame)
11496 {
11497 Lisp_Object tail, tem;
11498 Lisp_Object old = selected_frame;
11499 struct Lisp_Symbol *sym;
11500
11501 xassert (FRAMEP (frame) && FRAME_LIVE_P (XFRAME (frame)));
11502
11503 selected_frame = frame;
11504
11505 do {
11506 for (tail = XFRAME (frame)->param_alist; CONSP (tail); tail = XCDR (tail))
11507 if (CONSP (XCAR (tail))
11508 && (tem = XCAR (XCAR (tail)),
11509 SYMBOLP (tem))
11510 && (sym = indirect_variable (XSYMBOL (tem)),
11511 sym->redirect == SYMBOL_LOCALIZED)
11512 && sym->val.blv->frame_local)
11513 /* Use find_symbol_value rather than Fsymbol_value
11514 to avoid an error if it is void. */
11515 find_symbol_value (tem);
11516 } while (!EQ (frame, old) && (frame = old, 1));
11517 }
11518
11519
11520 #define STOP_POLLING \
11521 do { if (! polling_stopped_here) stop_polling (); \
11522 polling_stopped_here = 1; } while (0)
11523
11524 #define RESUME_POLLING \
11525 do { if (polling_stopped_here) start_polling (); \
11526 polling_stopped_here = 0; } while (0)
11527
11528
11529 /* Perhaps in the future avoid recentering windows if it
11530 is not necessary; currently that causes some problems. */
11531
11532 static void
11533 redisplay_internal (void)
11534 {
11535 struct window *w = XWINDOW (selected_window);
11536 struct window *sw;
11537 struct frame *fr;
11538 int pending;
11539 int must_finish = 0;
11540 struct text_pos tlbufpos, tlendpos;
11541 int number_of_visible_frames;
11542 int count, count1;
11543 struct frame *sf;
11544 int polling_stopped_here = 0;
11545 Lisp_Object old_frame = selected_frame;
11546
11547 /* Non-zero means redisplay has to consider all windows on all
11548 frames. Zero means, only selected_window is considered. */
11549 int consider_all_windows_p;
11550
11551 TRACE ((stderr, "redisplay_internal %d\n", redisplaying_p));
11552
11553 /* No redisplay if running in batch mode or frame is not yet fully
11554 initialized, or redisplay is explicitly turned off by setting
11555 Vinhibit_redisplay. */
11556 if (FRAME_INITIAL_P (SELECTED_FRAME ())
11557 || !NILP (Vinhibit_redisplay))
11558 return;
11559
11560 /* Don't examine these until after testing Vinhibit_redisplay.
11561 When Emacs is shutting down, perhaps because its connection to
11562 X has dropped, we should not look at them at all. */
11563 fr = XFRAME (w->frame);
11564 sf = SELECTED_FRAME ();
11565
11566 if (!fr->glyphs_initialized_p)
11567 return;
11568
11569 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS)
11570 if (popup_activated ())
11571 return;
11572 #endif
11573
11574 /* I don't think this happens but let's be paranoid. */
11575 if (redisplaying_p)
11576 return;
11577
11578 /* Record a function that resets redisplaying_p to its old value
11579 when we leave this function. */
11580 count = SPECPDL_INDEX ();
11581 record_unwind_protect (unwind_redisplay,
11582 Fcons (make_number (redisplaying_p), selected_frame));
11583 ++redisplaying_p;
11584 specbind (Qinhibit_free_realized_faces, Qnil);
11585
11586 {
11587 Lisp_Object tail, frame;
11588
11589 FOR_EACH_FRAME (tail, frame)
11590 {
11591 struct frame *f = XFRAME (frame);
11592 f->already_hscrolled_p = 0;
11593 }
11594 }
11595
11596 retry:
11597 /* Remember the currently selected window. */
11598 sw = w;
11599
11600 if (!EQ (old_frame, selected_frame)
11601 && FRAME_LIVE_P (XFRAME (old_frame)))
11602 /* When running redisplay, we play a bit fast-and-loose and allow e.g.
11603 selected_frame and selected_window to be temporarily out-of-sync so
11604 when we come back here via `goto retry', we need to resync because we
11605 may need to run Elisp code (via prepare_menu_bars). */
11606 select_frame_for_redisplay (old_frame);
11607
11608 pending = 0;
11609 reconsider_clip_changes (w, current_buffer);
11610 last_escape_glyph_frame = NULL;
11611 last_escape_glyph_face_id = (1 << FACE_ID_BITS);
11612 last_glyphless_glyph_frame = NULL;
11613 last_glyphless_glyph_face_id = (1 << FACE_ID_BITS);
11614
11615 /* If new fonts have been loaded that make a glyph matrix adjustment
11616 necessary, do it. */
11617 if (fonts_changed_p)
11618 {
11619 adjust_glyphs (NULL);
11620 ++windows_or_buffers_changed;
11621 fonts_changed_p = 0;
11622 }
11623
11624 /* If face_change_count is non-zero, init_iterator will free all
11625 realized faces, which includes the faces referenced from current
11626 matrices. So, we can't reuse current matrices in this case. */
11627 if (face_change_count)
11628 ++windows_or_buffers_changed;
11629
11630 if ((FRAME_TERMCAP_P (sf) || FRAME_MSDOS_P (sf))
11631 && FRAME_TTY (sf)->previous_frame != sf)
11632 {
11633 /* Since frames on a single ASCII terminal share the same
11634 display area, displaying a different frame means redisplay
11635 the whole thing. */
11636 windows_or_buffers_changed++;
11637 SET_FRAME_GARBAGED (sf);
11638 #ifndef DOS_NT
11639 set_tty_color_mode (FRAME_TTY (sf), sf);
11640 #endif
11641 FRAME_TTY (sf)->previous_frame = sf;
11642 }
11643
11644 /* Set the visible flags for all frames. Do this before checking
11645 for resized or garbaged frames; they want to know if their frames
11646 are visible. See the comment in frame.h for
11647 FRAME_SAMPLE_VISIBILITY. */
11648 {
11649 Lisp_Object tail, frame;
11650
11651 number_of_visible_frames = 0;
11652
11653 FOR_EACH_FRAME (tail, frame)
11654 {
11655 struct frame *f = XFRAME (frame);
11656
11657 FRAME_SAMPLE_VISIBILITY (f);
11658 if (FRAME_VISIBLE_P (f))
11659 ++number_of_visible_frames;
11660 clear_desired_matrices (f);
11661 }
11662 }
11663
11664 /* Notice any pending interrupt request to change frame size. */
11665 do_pending_window_change (1);
11666
11667 /* do_pending_window_change could change the selected_window due to
11668 frame resizing which makes the selected window too small. */
11669 if (WINDOWP (selected_window) && (w = XWINDOW (selected_window)) != sw)
11670 {
11671 sw = w;
11672 reconsider_clip_changes (w, current_buffer);
11673 }
11674
11675 /* Clear frames marked as garbaged. */
11676 if (frame_garbaged)
11677 clear_garbaged_frames ();
11678
11679 /* Build menubar and tool-bar items. */
11680 if (NILP (Vmemory_full))
11681 prepare_menu_bars ();
11682
11683 if (windows_or_buffers_changed)
11684 update_mode_lines++;
11685
11686 /* Detect case that we need to write or remove a star in the mode line. */
11687 if ((SAVE_MODIFF < MODIFF) != !NILP (w->last_had_star))
11688 {
11689 w->update_mode_line = Qt;
11690 if (buffer_shared > 1)
11691 update_mode_lines++;
11692 }
11693
11694 /* Avoid invocation of point motion hooks by `current_column' below. */
11695 count1 = SPECPDL_INDEX ();
11696 specbind (Qinhibit_point_motion_hooks, Qt);
11697
11698 /* If %c is in the mode line, update it if needed. */
11699 if (!NILP (w->column_number_displayed)
11700 /* This alternative quickly identifies a common case
11701 where no change is needed. */
11702 && !(PT == XFASTINT (w->last_point)
11703 && XFASTINT (w->last_modified) >= MODIFF
11704 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
11705 && (XFASTINT (w->column_number_displayed) != current_column ()))
11706 w->update_mode_line = Qt;
11707
11708 unbind_to (count1, Qnil);
11709
11710 FRAME_SCROLL_BOTTOM_VPOS (XFRAME (w->frame)) = -1;
11711
11712 /* The variable buffer_shared is set in redisplay_window and
11713 indicates that we redisplay a buffer in different windows. See
11714 there. */
11715 consider_all_windows_p = (update_mode_lines || buffer_shared > 1
11716 || cursor_type_changed);
11717
11718 /* If specs for an arrow have changed, do thorough redisplay
11719 to ensure we remove any arrow that should no longer exist. */
11720 if (overlay_arrows_changed_p ())
11721 consider_all_windows_p = windows_or_buffers_changed = 1;
11722
11723 /* Normally the message* functions will have already displayed and
11724 updated the echo area, but the frame may have been trashed, or
11725 the update may have been preempted, so display the echo area
11726 again here. Checking message_cleared_p captures the case that
11727 the echo area should be cleared. */
11728 if ((!NILP (echo_area_buffer[0]) && !display_last_displayed_message_p)
11729 || (!NILP (echo_area_buffer[1]) && display_last_displayed_message_p)
11730 || (message_cleared_p
11731 && minibuf_level == 0
11732 /* If the mini-window is currently selected, this means the
11733 echo-area doesn't show through. */
11734 && !MINI_WINDOW_P (XWINDOW (selected_window))))
11735 {
11736 int window_height_changed_p = echo_area_display (0);
11737 must_finish = 1;
11738
11739 /* If we don't display the current message, don't clear the
11740 message_cleared_p flag, because, if we did, we wouldn't clear
11741 the echo area in the next redisplay which doesn't preserve
11742 the echo area. */
11743 if (!display_last_displayed_message_p)
11744 message_cleared_p = 0;
11745
11746 if (fonts_changed_p)
11747 goto retry;
11748 else if (window_height_changed_p)
11749 {
11750 consider_all_windows_p = 1;
11751 ++update_mode_lines;
11752 ++windows_or_buffers_changed;
11753
11754 /* If window configuration was changed, frames may have been
11755 marked garbaged. Clear them or we will experience
11756 surprises wrt scrolling. */
11757 if (frame_garbaged)
11758 clear_garbaged_frames ();
11759 }
11760 }
11761 else if (EQ (selected_window, minibuf_window)
11762 && (current_buffer->clip_changed
11763 || XFASTINT (w->last_modified) < MODIFF
11764 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
11765 && resize_mini_window (w, 0))
11766 {
11767 /* Resized active mini-window to fit the size of what it is
11768 showing if its contents might have changed. */
11769 must_finish = 1;
11770 /* FIXME: this causes all frames to be updated, which seems unnecessary
11771 since only the current frame needs to be considered. This function needs
11772 to be rewritten with two variables, consider_all_windows and
11773 consider_all_frames. */
11774 consider_all_windows_p = 1;
11775 ++windows_or_buffers_changed;
11776 ++update_mode_lines;
11777
11778 /* If window configuration was changed, frames may have been
11779 marked garbaged. Clear them or we will experience
11780 surprises wrt scrolling. */
11781 if (frame_garbaged)
11782 clear_garbaged_frames ();
11783 }
11784
11785
11786 /* If showing the region, and mark has changed, we must redisplay
11787 the whole window. The assignment to this_line_start_pos prevents
11788 the optimization directly below this if-statement. */
11789 if (((!NILP (Vtransient_mark_mode)
11790 && !NILP (BVAR (XBUFFER (w->buffer), mark_active)))
11791 != !NILP (w->region_showing))
11792 || (!NILP (w->region_showing)
11793 && !EQ (w->region_showing,
11794 Fmarker_position (BVAR (XBUFFER (w->buffer), mark)))))
11795 CHARPOS (this_line_start_pos) = 0;
11796
11797 /* Optimize the case that only the line containing the cursor in the
11798 selected window has changed. Variables starting with this_ are
11799 set in display_line and record information about the line
11800 containing the cursor. */
11801 tlbufpos = this_line_start_pos;
11802 tlendpos = this_line_end_pos;
11803 if (!consider_all_windows_p
11804 && CHARPOS (tlbufpos) > 0
11805 && NILP (w->update_mode_line)
11806 && !current_buffer->clip_changed
11807 && !current_buffer->prevent_redisplay_optimizations_p
11808 && FRAME_VISIBLE_P (XFRAME (w->frame))
11809 && !FRAME_OBSCURED_P (XFRAME (w->frame))
11810 /* Make sure recorded data applies to current buffer, etc. */
11811 && this_line_buffer == current_buffer
11812 && current_buffer == XBUFFER (w->buffer)
11813 && NILP (w->force_start)
11814 && NILP (w->optional_new_start)
11815 /* Point must be on the line that we have info recorded about. */
11816 && PT >= CHARPOS (tlbufpos)
11817 && PT <= Z - CHARPOS (tlendpos)
11818 /* All text outside that line, including its final newline,
11819 must be unchanged. */
11820 && text_outside_line_unchanged_p (w, CHARPOS (tlbufpos),
11821 CHARPOS (tlendpos)))
11822 {
11823 if (CHARPOS (tlbufpos) > BEGV
11824 && FETCH_BYTE (BYTEPOS (tlbufpos) - 1) != '\n'
11825 && (CHARPOS (tlbufpos) == ZV
11826 || FETCH_BYTE (BYTEPOS (tlbufpos)) == '\n'))
11827 /* Former continuation line has disappeared by becoming empty. */
11828 goto cancel;
11829 else if (XFASTINT (w->last_modified) < MODIFF
11830 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF
11831 || MINI_WINDOW_P (w))
11832 {
11833 /* We have to handle the case of continuation around a
11834 wide-column character (see the comment in indent.c around
11835 line 1340).
11836
11837 For instance, in the following case:
11838
11839 -------- Insert --------
11840 K_A_N_\\ `a' K_A_N_a\ `X_' are wide-column chars.
11841 J_I_ ==> J_I_ `^^' are cursors.
11842 ^^ ^^
11843 -------- --------
11844
11845 As we have to redraw the line above, we cannot use this
11846 optimization. */
11847
11848 struct it it;
11849 int line_height_before = this_line_pixel_height;
11850
11851 /* Note that start_display will handle the case that the
11852 line starting at tlbufpos is a continuation line. */
11853 start_display (&it, w, tlbufpos);
11854
11855 /* Implementation note: It this still necessary? */
11856 if (it.current_x != this_line_start_x)
11857 goto cancel;
11858
11859 TRACE ((stderr, "trying display optimization 1\n"));
11860 w->cursor.vpos = -1;
11861 overlay_arrow_seen = 0;
11862 it.vpos = this_line_vpos;
11863 it.current_y = this_line_y;
11864 it.glyph_row = MATRIX_ROW (w->desired_matrix, this_line_vpos);
11865 display_line (&it);
11866
11867 /* If line contains point, is not continued,
11868 and ends at same distance from eob as before, we win. */
11869 if (w->cursor.vpos >= 0
11870 /* Line is not continued, otherwise this_line_start_pos
11871 would have been set to 0 in display_line. */
11872 && CHARPOS (this_line_start_pos)
11873 /* Line ends as before. */
11874 && CHARPOS (this_line_end_pos) == CHARPOS (tlendpos)
11875 /* Line has same height as before. Otherwise other lines
11876 would have to be shifted up or down. */
11877 && this_line_pixel_height == line_height_before)
11878 {
11879 /* If this is not the window's last line, we must adjust
11880 the charstarts of the lines below. */
11881 if (it.current_y < it.last_visible_y)
11882 {
11883 struct glyph_row *row
11884 = MATRIX_ROW (w->current_matrix, this_line_vpos + 1);
11885 EMACS_INT delta, delta_bytes;
11886
11887 /* We used to distinguish between two cases here,
11888 conditioned by Z - CHARPOS (tlendpos) == ZV, for
11889 when the line ends in a newline or the end of the
11890 buffer's accessible portion. But both cases did
11891 the same, so they were collapsed. */
11892 delta = (Z
11893 - CHARPOS (tlendpos)
11894 - MATRIX_ROW_START_CHARPOS (row));
11895 delta_bytes = (Z_BYTE
11896 - BYTEPOS (tlendpos)
11897 - MATRIX_ROW_START_BYTEPOS (row));
11898
11899 increment_matrix_positions (w->current_matrix,
11900 this_line_vpos + 1,
11901 w->current_matrix->nrows,
11902 delta, delta_bytes);
11903 }
11904
11905 /* If this row displays text now but previously didn't,
11906 or vice versa, w->window_end_vpos may have to be
11907 adjusted. */
11908 if ((it.glyph_row - 1)->displays_text_p)
11909 {
11910 if (XFASTINT (w->window_end_vpos) < this_line_vpos)
11911 XSETINT (w->window_end_vpos, this_line_vpos);
11912 }
11913 else if (XFASTINT (w->window_end_vpos) == this_line_vpos
11914 && this_line_vpos > 0)
11915 XSETINT (w->window_end_vpos, this_line_vpos - 1);
11916 w->window_end_valid = Qnil;
11917
11918 /* Update hint: No need to try to scroll in update_window. */
11919 w->desired_matrix->no_scrolling_p = 1;
11920
11921 #if GLYPH_DEBUG
11922 *w->desired_matrix->method = 0;
11923 debug_method_add (w, "optimization 1");
11924 #endif
11925 #ifdef HAVE_WINDOW_SYSTEM
11926 update_window_fringes (w, 0);
11927 #endif
11928 goto update;
11929 }
11930 else
11931 goto cancel;
11932 }
11933 else if (/* Cursor position hasn't changed. */
11934 PT == XFASTINT (w->last_point)
11935 /* Make sure the cursor was last displayed
11936 in this window. Otherwise we have to reposition it. */
11937 && 0 <= w->cursor.vpos
11938 && WINDOW_TOTAL_LINES (w) > w->cursor.vpos)
11939 {
11940 if (!must_finish)
11941 {
11942 do_pending_window_change (1);
11943 /* If selected_window changed, redisplay again. */
11944 if (WINDOWP (selected_window)
11945 && (w = XWINDOW (selected_window)) != sw)
11946 goto retry;
11947
11948 /* We used to always goto end_of_redisplay here, but this
11949 isn't enough if we have a blinking cursor. */
11950 if (w->cursor_off_p == w->last_cursor_off_p)
11951 goto end_of_redisplay;
11952 }
11953 goto update;
11954 }
11955 /* If highlighting the region, or if the cursor is in the echo area,
11956 then we can't just move the cursor. */
11957 else if (! (!NILP (Vtransient_mark_mode)
11958 && !NILP (BVAR (current_buffer, mark_active)))
11959 && (EQ (selected_window, BVAR (current_buffer, last_selected_window))
11960 || highlight_nonselected_windows)
11961 && NILP (w->region_showing)
11962 && NILP (Vshow_trailing_whitespace)
11963 && !cursor_in_echo_area)
11964 {
11965 struct it it;
11966 struct glyph_row *row;
11967
11968 /* Skip from tlbufpos to PT and see where it is. Note that
11969 PT may be in invisible text. If so, we will end at the
11970 next visible position. */
11971 init_iterator (&it, w, CHARPOS (tlbufpos), BYTEPOS (tlbufpos),
11972 NULL, DEFAULT_FACE_ID);
11973 it.current_x = this_line_start_x;
11974 it.current_y = this_line_y;
11975 it.vpos = this_line_vpos;
11976
11977 /* The call to move_it_to stops in front of PT, but
11978 moves over before-strings. */
11979 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
11980
11981 if (it.vpos == this_line_vpos
11982 && (row = MATRIX_ROW (w->current_matrix, this_line_vpos),
11983 row->enabled_p))
11984 {
11985 xassert (this_line_vpos == it.vpos);
11986 xassert (this_line_y == it.current_y);
11987 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
11988 #if GLYPH_DEBUG
11989 *w->desired_matrix->method = 0;
11990 debug_method_add (w, "optimization 3");
11991 #endif
11992 goto update;
11993 }
11994 else
11995 goto cancel;
11996 }
11997
11998 cancel:
11999 /* Text changed drastically or point moved off of line. */
12000 SET_MATRIX_ROW_ENABLED_P (w->desired_matrix, this_line_vpos, 0);
12001 }
12002
12003 CHARPOS (this_line_start_pos) = 0;
12004 consider_all_windows_p |= buffer_shared > 1;
12005 ++clear_face_cache_count;
12006 #ifdef HAVE_WINDOW_SYSTEM
12007 ++clear_image_cache_count;
12008 #endif
12009
12010 /* Build desired matrices, and update the display. If
12011 consider_all_windows_p is non-zero, do it for all windows on all
12012 frames. Otherwise do it for selected_window, only. */
12013
12014 if (consider_all_windows_p)
12015 {
12016 Lisp_Object tail, frame;
12017
12018 FOR_EACH_FRAME (tail, frame)
12019 XFRAME (frame)->updated_p = 0;
12020
12021 /* Recompute # windows showing selected buffer. This will be
12022 incremented each time such a window is displayed. */
12023 buffer_shared = 0;
12024
12025 FOR_EACH_FRAME (tail, frame)
12026 {
12027 struct frame *f = XFRAME (frame);
12028
12029 if (FRAME_WINDOW_P (f) || FRAME_TERMCAP_P (f) || f == sf)
12030 {
12031 if (! EQ (frame, selected_frame))
12032 /* Select the frame, for the sake of frame-local
12033 variables. */
12034 select_frame_for_redisplay (frame);
12035
12036 /* Mark all the scroll bars to be removed; we'll redeem
12037 the ones we want when we redisplay their windows. */
12038 if (FRAME_TERMINAL (f)->condemn_scroll_bars_hook)
12039 FRAME_TERMINAL (f)->condemn_scroll_bars_hook (f);
12040
12041 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
12042 redisplay_windows (FRAME_ROOT_WINDOW (f));
12043
12044 /* The X error handler may have deleted that frame. */
12045 if (!FRAME_LIVE_P (f))
12046 continue;
12047
12048 /* Any scroll bars which redisplay_windows should have
12049 nuked should now go away. */
12050 if (FRAME_TERMINAL (f)->judge_scroll_bars_hook)
12051 FRAME_TERMINAL (f)->judge_scroll_bars_hook (f);
12052
12053 /* If fonts changed, display again. */
12054 /* ??? rms: I suspect it is a mistake to jump all the way
12055 back to retry here. It should just retry this frame. */
12056 if (fonts_changed_p)
12057 goto retry;
12058
12059 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
12060 {
12061 /* See if we have to hscroll. */
12062 if (!f->already_hscrolled_p)
12063 {
12064 f->already_hscrolled_p = 1;
12065 if (hscroll_windows (f->root_window))
12066 goto retry;
12067 }
12068
12069 /* Prevent various kinds of signals during display
12070 update. stdio is not robust about handling
12071 signals, which can cause an apparent I/O
12072 error. */
12073 if (interrupt_input)
12074 unrequest_sigio ();
12075 STOP_POLLING;
12076
12077 /* Update the display. */
12078 set_window_update_flags (XWINDOW (f->root_window), 1);
12079 pending |= update_frame (f, 0, 0);
12080 f->updated_p = 1;
12081 }
12082 }
12083 }
12084
12085 if (!EQ (old_frame, selected_frame)
12086 && FRAME_LIVE_P (XFRAME (old_frame)))
12087 /* We played a bit fast-and-loose above and allowed selected_frame
12088 and selected_window to be temporarily out-of-sync but let's make
12089 sure this stays contained. */
12090 select_frame_for_redisplay (old_frame);
12091 eassert (EQ (XFRAME (selected_frame)->selected_window, selected_window));
12092
12093 if (!pending)
12094 {
12095 /* Do the mark_window_display_accurate after all windows have
12096 been redisplayed because this call resets flags in buffers
12097 which are needed for proper redisplay. */
12098 FOR_EACH_FRAME (tail, frame)
12099 {
12100 struct frame *f = XFRAME (frame);
12101 if (f->updated_p)
12102 {
12103 mark_window_display_accurate (f->root_window, 1);
12104 if (FRAME_TERMINAL (f)->frame_up_to_date_hook)
12105 FRAME_TERMINAL (f)->frame_up_to_date_hook (f);
12106 }
12107 }
12108 }
12109 }
12110 else if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
12111 {
12112 Lisp_Object mini_window;
12113 struct frame *mini_frame;
12114
12115 displayed_buffer = XBUFFER (XWINDOW (selected_window)->buffer);
12116 /* Use list_of_error, not Qerror, so that
12117 we catch only errors and don't run the debugger. */
12118 internal_condition_case_1 (redisplay_window_1, selected_window,
12119 list_of_error,
12120 redisplay_window_error);
12121
12122 /* Compare desired and current matrices, perform output. */
12123
12124 update:
12125 /* If fonts changed, display again. */
12126 if (fonts_changed_p)
12127 goto retry;
12128
12129 /* Prevent various kinds of signals during display update.
12130 stdio is not robust about handling signals,
12131 which can cause an apparent I/O error. */
12132 if (interrupt_input)
12133 unrequest_sigio ();
12134 STOP_POLLING;
12135
12136 if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
12137 {
12138 if (hscroll_windows (selected_window))
12139 goto retry;
12140
12141 XWINDOW (selected_window)->must_be_updated_p = 1;
12142 pending = update_frame (sf, 0, 0);
12143 }
12144
12145 /* We may have called echo_area_display at the top of this
12146 function. If the echo area is on another frame, that may
12147 have put text on a frame other than the selected one, so the
12148 above call to update_frame would not have caught it. Catch
12149 it here. */
12150 mini_window = FRAME_MINIBUF_WINDOW (sf);
12151 mini_frame = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
12152
12153 if (mini_frame != sf && FRAME_WINDOW_P (mini_frame))
12154 {
12155 XWINDOW (mini_window)->must_be_updated_p = 1;
12156 pending |= update_frame (mini_frame, 0, 0);
12157 if (!pending && hscroll_windows (mini_window))
12158 goto retry;
12159 }
12160 }
12161
12162 /* If display was paused because of pending input, make sure we do a
12163 thorough update the next time. */
12164 if (pending)
12165 {
12166 /* Prevent the optimization at the beginning of
12167 redisplay_internal that tries a single-line update of the
12168 line containing the cursor in the selected window. */
12169 CHARPOS (this_line_start_pos) = 0;
12170
12171 /* Let the overlay arrow be updated the next time. */
12172 update_overlay_arrows (0);
12173
12174 /* If we pause after scrolling, some rows in the current
12175 matrices of some windows are not valid. */
12176 if (!WINDOW_FULL_WIDTH_P (w)
12177 && !FRAME_WINDOW_P (XFRAME (w->frame)))
12178 update_mode_lines = 1;
12179 }
12180 else
12181 {
12182 if (!consider_all_windows_p)
12183 {
12184 /* This has already been done above if
12185 consider_all_windows_p is set. */
12186 mark_window_display_accurate_1 (w, 1);
12187
12188 /* Say overlay arrows are up to date. */
12189 update_overlay_arrows (1);
12190
12191 if (FRAME_TERMINAL (sf)->frame_up_to_date_hook != 0)
12192 FRAME_TERMINAL (sf)->frame_up_to_date_hook (sf);
12193 }
12194
12195 update_mode_lines = 0;
12196 windows_or_buffers_changed = 0;
12197 cursor_type_changed = 0;
12198 }
12199
12200 /* Start SIGIO interrupts coming again. Having them off during the
12201 code above makes it less likely one will discard output, but not
12202 impossible, since there might be stuff in the system buffer here.
12203 But it is much hairier to try to do anything about that. */
12204 if (interrupt_input)
12205 request_sigio ();
12206 RESUME_POLLING;
12207
12208 /* If a frame has become visible which was not before, redisplay
12209 again, so that we display it. Expose events for such a frame
12210 (which it gets when becoming visible) don't call the parts of
12211 redisplay constructing glyphs, so simply exposing a frame won't
12212 display anything in this case. So, we have to display these
12213 frames here explicitly. */
12214 if (!pending)
12215 {
12216 Lisp_Object tail, frame;
12217 int new_count = 0;
12218
12219 FOR_EACH_FRAME (tail, frame)
12220 {
12221 int this_is_visible = 0;
12222
12223 if (XFRAME (frame)->visible)
12224 this_is_visible = 1;
12225 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
12226 if (XFRAME (frame)->visible)
12227 this_is_visible = 1;
12228
12229 if (this_is_visible)
12230 new_count++;
12231 }
12232
12233 if (new_count != number_of_visible_frames)
12234 windows_or_buffers_changed++;
12235 }
12236
12237 /* Change frame size now if a change is pending. */
12238 do_pending_window_change (1);
12239
12240 /* If we just did a pending size change, or have additional
12241 visible frames, or selected_window changed, redisplay again. */
12242 if ((windows_or_buffers_changed && !pending)
12243 || (WINDOWP (selected_window) && (w = XWINDOW (selected_window)) != sw))
12244 goto retry;
12245
12246 /* Clear the face and image caches.
12247
12248 We used to do this only if consider_all_windows_p. But the cache
12249 needs to be cleared if a timer creates images in the current
12250 buffer (e.g. the test case in Bug#6230). */
12251
12252 if (clear_face_cache_count > CLEAR_FACE_CACHE_COUNT)
12253 {
12254 clear_face_cache (0);
12255 clear_face_cache_count = 0;
12256 }
12257
12258 #ifdef HAVE_WINDOW_SYSTEM
12259 if (clear_image_cache_count > CLEAR_IMAGE_CACHE_COUNT)
12260 {
12261 clear_image_caches (Qnil);
12262 clear_image_cache_count = 0;
12263 }
12264 #endif /* HAVE_WINDOW_SYSTEM */
12265
12266 end_of_redisplay:
12267 unbind_to (count, Qnil);
12268 RESUME_POLLING;
12269 }
12270
12271
12272 /* Redisplay, but leave alone any recent echo area message unless
12273 another message has been requested in its place.
12274
12275 This is useful in situations where you need to redisplay but no
12276 user action has occurred, making it inappropriate for the message
12277 area to be cleared. See tracking_off and
12278 wait_reading_process_output for examples of these situations.
12279
12280 FROM_WHERE is an integer saying from where this function was
12281 called. This is useful for debugging. */
12282
12283 void
12284 redisplay_preserve_echo_area (int from_where)
12285 {
12286 TRACE ((stderr, "redisplay_preserve_echo_area (%d)\n", from_where));
12287
12288 if (!NILP (echo_area_buffer[1]))
12289 {
12290 /* We have a previously displayed message, but no current
12291 message. Redisplay the previous message. */
12292 display_last_displayed_message_p = 1;
12293 redisplay_internal ();
12294 display_last_displayed_message_p = 0;
12295 }
12296 else
12297 redisplay_internal ();
12298
12299 if (FRAME_RIF (SELECTED_FRAME ()) != NULL
12300 && FRAME_RIF (SELECTED_FRAME ())->flush_display_optional)
12301 FRAME_RIF (SELECTED_FRAME ())->flush_display_optional (NULL);
12302 }
12303
12304
12305 /* Function registered with record_unwind_protect in
12306 redisplay_internal. Reset redisplaying_p to the value it had
12307 before redisplay_internal was called, and clear
12308 prevent_freeing_realized_faces_p. It also selects the previously
12309 selected frame, unless it has been deleted (by an X connection
12310 failure during redisplay, for example). */
12311
12312 static Lisp_Object
12313 unwind_redisplay (Lisp_Object val)
12314 {
12315 Lisp_Object old_redisplaying_p, old_frame;
12316
12317 old_redisplaying_p = XCAR (val);
12318 redisplaying_p = XFASTINT (old_redisplaying_p);
12319 old_frame = XCDR (val);
12320 if (! EQ (old_frame, selected_frame)
12321 && FRAME_LIVE_P (XFRAME (old_frame)))
12322 select_frame_for_redisplay (old_frame);
12323 return Qnil;
12324 }
12325
12326
12327 /* Mark the display of window W as accurate or inaccurate. If
12328 ACCURATE_P is non-zero mark display of W as accurate. If
12329 ACCURATE_P is zero, arrange for W to be redisplayed the next time
12330 redisplay_internal is called. */
12331
12332 static void
12333 mark_window_display_accurate_1 (struct window *w, int accurate_p)
12334 {
12335 if (BUFFERP (w->buffer))
12336 {
12337 struct buffer *b = XBUFFER (w->buffer);
12338
12339 w->last_modified
12340 = make_number (accurate_p ? BUF_MODIFF (b) : 0);
12341 w->last_overlay_modified
12342 = make_number (accurate_p ? BUF_OVERLAY_MODIFF (b) : 0);
12343 w->last_had_star
12344 = BUF_MODIFF (b) > BUF_SAVE_MODIFF (b) ? Qt : Qnil;
12345
12346 if (accurate_p)
12347 {
12348 b->clip_changed = 0;
12349 b->prevent_redisplay_optimizations_p = 0;
12350
12351 BUF_UNCHANGED_MODIFIED (b) = BUF_MODIFF (b);
12352 BUF_OVERLAY_UNCHANGED_MODIFIED (b) = BUF_OVERLAY_MODIFF (b);
12353 BUF_BEG_UNCHANGED (b) = BUF_GPT (b) - BUF_BEG (b);
12354 BUF_END_UNCHANGED (b) = BUF_Z (b) - BUF_GPT (b);
12355
12356 w->current_matrix->buffer = b;
12357 w->current_matrix->begv = BUF_BEGV (b);
12358 w->current_matrix->zv = BUF_ZV (b);
12359
12360 w->last_cursor = w->cursor;
12361 w->last_cursor_off_p = w->cursor_off_p;
12362
12363 if (w == XWINDOW (selected_window))
12364 w->last_point = make_number (BUF_PT (b));
12365 else
12366 w->last_point = make_number (XMARKER (w->pointm)->charpos);
12367 }
12368 }
12369
12370 if (accurate_p)
12371 {
12372 w->window_end_valid = w->buffer;
12373 w->update_mode_line = Qnil;
12374 }
12375 }
12376
12377
12378 /* Mark the display of windows in the window tree rooted at WINDOW as
12379 accurate or inaccurate. If ACCURATE_P is non-zero mark display of
12380 windows as accurate. If ACCURATE_P is zero, arrange for windows to
12381 be redisplayed the next time redisplay_internal is called. */
12382
12383 void
12384 mark_window_display_accurate (Lisp_Object window, int accurate_p)
12385 {
12386 struct window *w;
12387
12388 for (; !NILP (window); window = w->next)
12389 {
12390 w = XWINDOW (window);
12391 mark_window_display_accurate_1 (w, accurate_p);
12392
12393 if (!NILP (w->vchild))
12394 mark_window_display_accurate (w->vchild, accurate_p);
12395 if (!NILP (w->hchild))
12396 mark_window_display_accurate (w->hchild, accurate_p);
12397 }
12398
12399 if (accurate_p)
12400 {
12401 update_overlay_arrows (1);
12402 }
12403 else
12404 {
12405 /* Force a thorough redisplay the next time by setting
12406 last_arrow_position and last_arrow_string to t, which is
12407 unequal to any useful value of Voverlay_arrow_... */
12408 update_overlay_arrows (-1);
12409 }
12410 }
12411
12412
12413 /* Return value in display table DP (Lisp_Char_Table *) for character
12414 C. Since a display table doesn't have any parent, we don't have to
12415 follow parent. Do not call this function directly but use the
12416 macro DISP_CHAR_VECTOR. */
12417
12418 Lisp_Object
12419 disp_char_vector (struct Lisp_Char_Table *dp, int c)
12420 {
12421 Lisp_Object val;
12422
12423 if (ASCII_CHAR_P (c))
12424 {
12425 val = dp->ascii;
12426 if (SUB_CHAR_TABLE_P (val))
12427 val = XSUB_CHAR_TABLE (val)->contents[c];
12428 }
12429 else
12430 {
12431 Lisp_Object table;
12432
12433 XSETCHAR_TABLE (table, dp);
12434 val = char_table_ref (table, c);
12435 }
12436 if (NILP (val))
12437 val = dp->defalt;
12438 return val;
12439 }
12440
12441
12442 \f
12443 /***********************************************************************
12444 Window Redisplay
12445 ***********************************************************************/
12446
12447 /* Redisplay all leaf windows in the window tree rooted at WINDOW. */
12448
12449 static void
12450 redisplay_windows (Lisp_Object window)
12451 {
12452 while (!NILP (window))
12453 {
12454 struct window *w = XWINDOW (window);
12455
12456 if (!NILP (w->hchild))
12457 redisplay_windows (w->hchild);
12458 else if (!NILP (w->vchild))
12459 redisplay_windows (w->vchild);
12460 else if (!NILP (w->buffer))
12461 {
12462 displayed_buffer = XBUFFER (w->buffer);
12463 /* Use list_of_error, not Qerror, so that
12464 we catch only errors and don't run the debugger. */
12465 internal_condition_case_1 (redisplay_window_0, window,
12466 list_of_error,
12467 redisplay_window_error);
12468 }
12469
12470 window = w->next;
12471 }
12472 }
12473
12474 static Lisp_Object
12475 redisplay_window_error (Lisp_Object ignore)
12476 {
12477 displayed_buffer->display_error_modiff = BUF_MODIFF (displayed_buffer);
12478 return Qnil;
12479 }
12480
12481 static Lisp_Object
12482 redisplay_window_0 (Lisp_Object window)
12483 {
12484 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
12485 redisplay_window (window, 0);
12486 return Qnil;
12487 }
12488
12489 static Lisp_Object
12490 redisplay_window_1 (Lisp_Object window)
12491 {
12492 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
12493 redisplay_window (window, 1);
12494 return Qnil;
12495 }
12496 \f
12497
12498 /* Set cursor position of W. PT is assumed to be displayed in ROW.
12499 DELTA and DELTA_BYTES are the numbers of characters and bytes by
12500 which positions recorded in ROW differ from current buffer
12501 positions.
12502
12503 Return 0 if cursor is not on this row, 1 otherwise. */
12504
12505 static int
12506 set_cursor_from_row (struct window *w, struct glyph_row *row,
12507 struct glyph_matrix *matrix,
12508 EMACS_INT delta, EMACS_INT delta_bytes,
12509 int dy, int dvpos)
12510 {
12511 struct glyph *glyph = row->glyphs[TEXT_AREA];
12512 struct glyph *end = glyph + row->used[TEXT_AREA];
12513 struct glyph *cursor = NULL;
12514 /* The last known character position in row. */
12515 EMACS_INT last_pos = MATRIX_ROW_START_CHARPOS (row) + delta;
12516 int x = row->x;
12517 EMACS_INT pt_old = PT - delta;
12518 EMACS_INT pos_before = MATRIX_ROW_START_CHARPOS (row) + delta;
12519 EMACS_INT pos_after = MATRIX_ROW_END_CHARPOS (row) + delta;
12520 struct glyph *glyph_before = glyph - 1, *glyph_after = end;
12521 /* A glyph beyond the edge of TEXT_AREA which we should never
12522 touch. */
12523 struct glyph *glyphs_end = end;
12524 /* Non-zero means we've found a match for cursor position, but that
12525 glyph has the avoid_cursor_p flag set. */
12526 int match_with_avoid_cursor = 0;
12527 /* Non-zero means we've seen at least one glyph that came from a
12528 display string. */
12529 int string_seen = 0;
12530 /* Largest and smalles buffer positions seen so far during scan of
12531 glyph row. */
12532 EMACS_INT bpos_max = pos_before;
12533 EMACS_INT bpos_min = pos_after;
12534 /* Last buffer position covered by an overlay string with an integer
12535 `cursor' property. */
12536 EMACS_INT bpos_covered = 0;
12537
12538 /* Skip over glyphs not having an object at the start and the end of
12539 the row. These are special glyphs like truncation marks on
12540 terminal frames. */
12541 if (row->displays_text_p)
12542 {
12543 if (!row->reversed_p)
12544 {
12545 while (glyph < end
12546 && INTEGERP (glyph->object)
12547 && glyph->charpos < 0)
12548 {
12549 x += glyph->pixel_width;
12550 ++glyph;
12551 }
12552 while (end > glyph
12553 && INTEGERP ((end - 1)->object)
12554 /* CHARPOS is zero for blanks and stretch glyphs
12555 inserted by extend_face_to_end_of_line. */
12556 && (end - 1)->charpos <= 0)
12557 --end;
12558 glyph_before = glyph - 1;
12559 glyph_after = end;
12560 }
12561 else
12562 {
12563 struct glyph *g;
12564
12565 /* If the glyph row is reversed, we need to process it from back
12566 to front, so swap the edge pointers. */
12567 glyphs_end = end = glyph - 1;
12568 glyph += row->used[TEXT_AREA] - 1;
12569
12570 while (glyph > end + 1
12571 && INTEGERP (glyph->object)
12572 && glyph->charpos < 0)
12573 {
12574 --glyph;
12575 x -= glyph->pixel_width;
12576 }
12577 if (INTEGERP (glyph->object) && glyph->charpos < 0)
12578 --glyph;
12579 /* By default, in reversed rows we put the cursor on the
12580 rightmost (first in the reading order) glyph. */
12581 for (g = end + 1; g < glyph; g++)
12582 x += g->pixel_width;
12583 while (end < glyph
12584 && INTEGERP ((end + 1)->object)
12585 && (end + 1)->charpos <= 0)
12586 ++end;
12587 glyph_before = glyph + 1;
12588 glyph_after = end;
12589 }
12590 }
12591 else if (row->reversed_p)
12592 {
12593 /* In R2L rows that don't display text, put the cursor on the
12594 rightmost glyph. Case in point: an empty last line that is
12595 part of an R2L paragraph. */
12596 cursor = end - 1;
12597 /* Avoid placing the cursor on the last glyph of the row, where
12598 on terminal frames we hold the vertical border between
12599 adjacent windows. */
12600 if (!FRAME_WINDOW_P (WINDOW_XFRAME (w))
12601 && !WINDOW_RIGHTMOST_P (w)
12602 && cursor == row->glyphs[LAST_AREA] - 1)
12603 cursor--;
12604 x = -1; /* will be computed below, at label compute_x */
12605 }
12606
12607 /* Step 1: Try to find the glyph whose character position
12608 corresponds to point. If that's not possible, find 2 glyphs
12609 whose character positions are the closest to point, one before
12610 point, the other after it. */
12611 if (!row->reversed_p)
12612 while (/* not marched to end of glyph row */
12613 glyph < end
12614 /* glyph was not inserted by redisplay for internal purposes */
12615 && !INTEGERP (glyph->object))
12616 {
12617 if (BUFFERP (glyph->object))
12618 {
12619 EMACS_INT dpos = glyph->charpos - pt_old;
12620
12621 if (glyph->charpos > bpos_max)
12622 bpos_max = glyph->charpos;
12623 if (glyph->charpos < bpos_min)
12624 bpos_min = glyph->charpos;
12625 if (!glyph->avoid_cursor_p)
12626 {
12627 /* If we hit point, we've found the glyph on which to
12628 display the cursor. */
12629 if (dpos == 0)
12630 {
12631 match_with_avoid_cursor = 0;
12632 break;
12633 }
12634 /* See if we've found a better approximation to
12635 POS_BEFORE or to POS_AFTER. Note that we want the
12636 first (leftmost) glyph of all those that are the
12637 closest from below, and the last (rightmost) of all
12638 those from above. */
12639 if (0 > dpos && dpos > pos_before - pt_old)
12640 {
12641 pos_before = glyph->charpos;
12642 glyph_before = glyph;
12643 }
12644 else if (0 < dpos && dpos <= pos_after - pt_old)
12645 {
12646 pos_after = glyph->charpos;
12647 glyph_after = glyph;
12648 }
12649 }
12650 else if (dpos == 0)
12651 match_with_avoid_cursor = 1;
12652 }
12653 else if (STRINGP (glyph->object))
12654 {
12655 Lisp_Object chprop;
12656 EMACS_INT glyph_pos = glyph->charpos;
12657
12658 chprop = Fget_char_property (make_number (glyph_pos), Qcursor,
12659 glyph->object);
12660 if (INTEGERP (chprop))
12661 {
12662 bpos_covered = bpos_max + XINT (chprop);
12663 /* If the `cursor' property covers buffer positions up
12664 to and including point, we should display cursor on
12665 this glyph. Note that overlays and text properties
12666 with string values stop bidi reordering, so every
12667 buffer position to the left of the string is always
12668 smaller than any position to the right of the
12669 string. Therefore, if a `cursor' property on one
12670 of the string's characters has an integer value, we
12671 will break out of the loop below _before_ we get to
12672 the position match above. IOW, integer values of
12673 the `cursor' property override the "exact match for
12674 point" strategy of positioning the cursor. */
12675 /* Implementation note: bpos_max == pt_old when, e.g.,
12676 we are in an empty line, where bpos_max is set to
12677 MATRIX_ROW_START_CHARPOS, see above. */
12678 if (bpos_max <= pt_old && bpos_covered >= pt_old)
12679 {
12680 cursor = glyph;
12681 break;
12682 }
12683 }
12684
12685 string_seen = 1;
12686 }
12687 x += glyph->pixel_width;
12688 ++glyph;
12689 }
12690 else if (glyph > end) /* row is reversed */
12691 while (!INTEGERP (glyph->object))
12692 {
12693 if (BUFFERP (glyph->object))
12694 {
12695 EMACS_INT dpos = glyph->charpos - pt_old;
12696
12697 if (glyph->charpos > bpos_max)
12698 bpos_max = glyph->charpos;
12699 if (glyph->charpos < bpos_min)
12700 bpos_min = glyph->charpos;
12701 if (!glyph->avoid_cursor_p)
12702 {
12703 if (dpos == 0)
12704 {
12705 match_with_avoid_cursor = 0;
12706 break;
12707 }
12708 if (0 > dpos && dpos > pos_before - pt_old)
12709 {
12710 pos_before = glyph->charpos;
12711 glyph_before = glyph;
12712 }
12713 else if (0 < dpos && dpos <= pos_after - pt_old)
12714 {
12715 pos_after = glyph->charpos;
12716 glyph_after = glyph;
12717 }
12718 }
12719 else if (dpos == 0)
12720 match_with_avoid_cursor = 1;
12721 }
12722 else if (STRINGP (glyph->object))
12723 {
12724 Lisp_Object chprop;
12725 EMACS_INT glyph_pos = glyph->charpos;
12726
12727 chprop = Fget_char_property (make_number (glyph_pos), Qcursor,
12728 glyph->object);
12729 if (INTEGERP (chprop))
12730 {
12731 bpos_covered = bpos_max + XINT (chprop);
12732 /* If the `cursor' property covers buffer positions up
12733 to and including point, we should display cursor on
12734 this glyph. */
12735 if (bpos_max <= pt_old && bpos_covered >= pt_old)
12736 {
12737 cursor = glyph;
12738 break;
12739 }
12740 }
12741 string_seen = 1;
12742 }
12743 --glyph;
12744 if (glyph == glyphs_end) /* don't dereference outside TEXT_AREA */
12745 {
12746 x--; /* can't use any pixel_width */
12747 break;
12748 }
12749 x -= glyph->pixel_width;
12750 }
12751
12752 /* Step 2: If we didn't find an exact match for point, we need to
12753 look for a proper place to put the cursor among glyphs between
12754 GLYPH_BEFORE and GLYPH_AFTER. */
12755 if (!((row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end)
12756 && BUFFERP (glyph->object) && glyph->charpos == pt_old)
12757 && bpos_covered < pt_old)
12758 {
12759 /* An empty line has a single glyph whose OBJECT is zero and
12760 whose CHARPOS is the position of a newline on that line.
12761 Note that on a TTY, there are more glyphs after that, which
12762 were produced by extend_face_to_end_of_line, but their
12763 CHARPOS is zero or negative. */
12764 int empty_line_p =
12765 (row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end)
12766 && INTEGERP (glyph->object) && glyph->charpos > 0;
12767
12768 if (row->ends_in_ellipsis_p && pos_after == last_pos)
12769 {
12770 EMACS_INT ellipsis_pos;
12771
12772 /* Scan back over the ellipsis glyphs. */
12773 if (!row->reversed_p)
12774 {
12775 ellipsis_pos = (glyph - 1)->charpos;
12776 while (glyph > row->glyphs[TEXT_AREA]
12777 && (glyph - 1)->charpos == ellipsis_pos)
12778 glyph--, x -= glyph->pixel_width;
12779 /* That loop always goes one position too far, including
12780 the glyph before the ellipsis. So scan forward over
12781 that one. */
12782 x += glyph->pixel_width;
12783 glyph++;
12784 }
12785 else /* row is reversed */
12786 {
12787 ellipsis_pos = (glyph + 1)->charpos;
12788 while (glyph < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1
12789 && (glyph + 1)->charpos == ellipsis_pos)
12790 glyph++, x += glyph->pixel_width;
12791 x -= glyph->pixel_width;
12792 glyph--;
12793 }
12794 }
12795 else if (match_with_avoid_cursor
12796 /* A truncated row may not include PT among its
12797 character positions. Setting the cursor inside the
12798 scroll margin will trigger recalculation of hscroll
12799 in hscroll_window_tree. */
12800 || (row->truncated_on_left_p && pt_old < bpos_min)
12801 || (row->truncated_on_right_p && pt_old > bpos_max)
12802 /* Zero-width characters produce no glyphs. */
12803 || (!string_seen
12804 && !empty_line_p
12805 && (row->reversed_p
12806 ? glyph_after > glyphs_end
12807 : glyph_after < glyphs_end)))
12808 {
12809 cursor = glyph_after;
12810 x = -1;
12811 }
12812 else if (string_seen)
12813 {
12814 int incr = row->reversed_p ? -1 : +1;
12815
12816 /* Need to find the glyph that came out of a string which is
12817 present at point. That glyph is somewhere between
12818 GLYPH_BEFORE and GLYPH_AFTER, and it came from a string
12819 positioned between POS_BEFORE and POS_AFTER in the
12820 buffer. */
12821 struct glyph *stop = glyph_after;
12822 EMACS_INT pos = pos_before;
12823
12824 x = -1;
12825 for (glyph = glyph_before + incr;
12826 row->reversed_p ? glyph > stop : glyph < stop; )
12827 {
12828
12829 /* Any glyphs that come from the buffer are here because
12830 of bidi reordering. Skip them, and only pay
12831 attention to glyphs that came from some string. */
12832 if (STRINGP (glyph->object))
12833 {
12834 Lisp_Object str;
12835 EMACS_INT tem;
12836
12837 str = glyph->object;
12838 tem = string_buffer_position_lim (str, pos, pos_after, 0);
12839 if (tem == 0 /* from overlay */
12840 || pos <= tem)
12841 {
12842 /* If the string from which this glyph came is
12843 found in the buffer at point, then we've
12844 found the glyph we've been looking for. If
12845 it comes from an overlay (tem == 0), and it
12846 has the `cursor' property on one of its
12847 glyphs, record that glyph as a candidate for
12848 displaying the cursor. (As in the
12849 unidirectional version, we will display the
12850 cursor on the last candidate we find.) */
12851 if (tem == 0 || tem == pt_old)
12852 {
12853 /* The glyphs from this string could have
12854 been reordered. Find the one with the
12855 smallest string position. Or there could
12856 be a character in the string with the
12857 `cursor' property, which means display
12858 cursor on that character's glyph. */
12859 EMACS_INT strpos = glyph->charpos;
12860
12861 if (tem)
12862 cursor = glyph;
12863 for ( ;
12864 (row->reversed_p ? glyph > stop : glyph < stop)
12865 && EQ (glyph->object, str);
12866 glyph += incr)
12867 {
12868 Lisp_Object cprop;
12869 EMACS_INT gpos = glyph->charpos;
12870
12871 cprop = Fget_char_property (make_number (gpos),
12872 Qcursor,
12873 glyph->object);
12874 if (!NILP (cprop))
12875 {
12876 cursor = glyph;
12877 break;
12878 }
12879 if (tem && glyph->charpos < strpos)
12880 {
12881 strpos = glyph->charpos;
12882 cursor = glyph;
12883 }
12884 }
12885
12886 if (tem == pt_old)
12887 goto compute_x;
12888 }
12889 if (tem)
12890 pos = tem + 1; /* don't find previous instances */
12891 }
12892 /* This string is not what we want; skip all of the
12893 glyphs that came from it. */
12894 while ((row->reversed_p ? glyph > stop : glyph < stop)
12895 && EQ (glyph->object, str))
12896 glyph += incr;
12897 }
12898 else
12899 glyph += incr;
12900 }
12901
12902 /* If we reached the end of the line, and END was from a string,
12903 the cursor is not on this line. */
12904 if (cursor == NULL
12905 && (row->reversed_p ? glyph <= end : glyph >= end)
12906 && STRINGP (end->object)
12907 && row->continued_p)
12908 return 0;
12909 }
12910 }
12911
12912 compute_x:
12913 if (cursor != NULL)
12914 glyph = cursor;
12915 if (x < 0)
12916 {
12917 struct glyph *g;
12918
12919 /* Need to compute x that corresponds to GLYPH. */
12920 for (g = row->glyphs[TEXT_AREA], x = row->x; g < glyph; g++)
12921 {
12922 if (g >= row->glyphs[TEXT_AREA] + row->used[TEXT_AREA])
12923 abort ();
12924 x += g->pixel_width;
12925 }
12926 }
12927
12928 /* ROW could be part of a continued line, which, under bidi
12929 reordering, might have other rows whose start and end charpos
12930 occlude point. Only set w->cursor if we found a better
12931 approximation to the cursor position than we have from previously
12932 examined candidate rows belonging to the same continued line. */
12933 if (/* we already have a candidate row */
12934 w->cursor.vpos >= 0
12935 /* that candidate is not the row we are processing */
12936 && MATRIX_ROW (matrix, w->cursor.vpos) != row
12937 /* the row we are processing is part of a continued line */
12938 && (row->continued_p || MATRIX_ROW_CONTINUATION_LINE_P (row))
12939 /* Make sure cursor.vpos specifies a row whose start and end
12940 charpos occlude point. This is because some callers of this
12941 function leave cursor.vpos at the row where the cursor was
12942 displayed during the last redisplay cycle. */
12943 && MATRIX_ROW_START_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos)) <= pt_old
12944 && pt_old < MATRIX_ROW_END_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos)))
12945 {
12946 struct glyph *g1 =
12947 MATRIX_ROW_GLYPH_START (matrix, w->cursor.vpos) + w->cursor.hpos;
12948
12949 /* Don't consider glyphs that are outside TEXT_AREA. */
12950 if (!(row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end))
12951 return 0;
12952 /* Keep the candidate whose buffer position is the closest to
12953 point. */
12954 if (/* previous candidate is a glyph in TEXT_AREA of that row */
12955 w->cursor.hpos >= 0
12956 && w->cursor.hpos < MATRIX_ROW_USED (matrix, w->cursor.vpos)
12957 && BUFFERP (g1->object)
12958 && (g1->charpos == pt_old /* an exact match always wins */
12959 || (BUFFERP (glyph->object)
12960 && eabs (g1->charpos - pt_old)
12961 < eabs (glyph->charpos - pt_old))))
12962 return 0;
12963 /* If this candidate gives an exact match, use that. */
12964 if (!(BUFFERP (glyph->object) && glyph->charpos == pt_old)
12965 /* Otherwise, keep the candidate that comes from a row
12966 spanning less buffer positions. This may win when one or
12967 both candidate positions are on glyphs that came from
12968 display strings, for which we cannot compare buffer
12969 positions. */
12970 && MATRIX_ROW_END_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))
12971 - MATRIX_ROW_START_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))
12972 < MATRIX_ROW_END_CHARPOS (row) - MATRIX_ROW_START_CHARPOS (row))
12973 return 0;
12974 }
12975 w->cursor.hpos = glyph - row->glyphs[TEXT_AREA];
12976 w->cursor.x = x;
12977 w->cursor.vpos = MATRIX_ROW_VPOS (row, matrix) + dvpos;
12978 w->cursor.y = row->y + dy;
12979
12980 if (w == XWINDOW (selected_window))
12981 {
12982 if (!row->continued_p
12983 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
12984 && row->x == 0)
12985 {
12986 this_line_buffer = XBUFFER (w->buffer);
12987
12988 CHARPOS (this_line_start_pos)
12989 = MATRIX_ROW_START_CHARPOS (row) + delta;
12990 BYTEPOS (this_line_start_pos)
12991 = MATRIX_ROW_START_BYTEPOS (row) + delta_bytes;
12992
12993 CHARPOS (this_line_end_pos)
12994 = Z - (MATRIX_ROW_END_CHARPOS (row) + delta);
12995 BYTEPOS (this_line_end_pos)
12996 = Z_BYTE - (MATRIX_ROW_END_BYTEPOS (row) + delta_bytes);
12997
12998 this_line_y = w->cursor.y;
12999 this_line_pixel_height = row->height;
13000 this_line_vpos = w->cursor.vpos;
13001 this_line_start_x = row->x;
13002 }
13003 else
13004 CHARPOS (this_line_start_pos) = 0;
13005 }
13006
13007 return 1;
13008 }
13009
13010
13011 /* Run window scroll functions, if any, for WINDOW with new window
13012 start STARTP. Sets the window start of WINDOW to that position.
13013
13014 We assume that the window's buffer is really current. */
13015
13016 static INLINE struct text_pos
13017 run_window_scroll_functions (Lisp_Object window, struct text_pos startp)
13018 {
13019 struct window *w = XWINDOW (window);
13020 SET_MARKER_FROM_TEXT_POS (w->start, startp);
13021
13022 if (current_buffer != XBUFFER (w->buffer))
13023 abort ();
13024
13025 if (!NILP (Vwindow_scroll_functions))
13026 {
13027 run_hook_with_args_2 (Qwindow_scroll_functions, window,
13028 make_number (CHARPOS (startp)));
13029 SET_TEXT_POS_FROM_MARKER (startp, w->start);
13030 /* In case the hook functions switch buffers. */
13031 if (current_buffer != XBUFFER (w->buffer))
13032 set_buffer_internal_1 (XBUFFER (w->buffer));
13033 }
13034
13035 return startp;
13036 }
13037
13038
13039 /* Make sure the line containing the cursor is fully visible.
13040 A value of 1 means there is nothing to be done.
13041 (Either the line is fully visible, or it cannot be made so,
13042 or we cannot tell.)
13043
13044 If FORCE_P is non-zero, return 0 even if partial visible cursor row
13045 is higher than window.
13046
13047 A value of 0 means the caller should do scrolling
13048 as if point had gone off the screen. */
13049
13050 static int
13051 cursor_row_fully_visible_p (struct window *w, int force_p, int current_matrix_p)
13052 {
13053 struct glyph_matrix *matrix;
13054 struct glyph_row *row;
13055 int window_height;
13056
13057 if (!make_cursor_line_fully_visible_p)
13058 return 1;
13059
13060 /* It's not always possible to find the cursor, e.g, when a window
13061 is full of overlay strings. Don't do anything in that case. */
13062 if (w->cursor.vpos < 0)
13063 return 1;
13064
13065 matrix = current_matrix_p ? w->current_matrix : w->desired_matrix;
13066 row = MATRIX_ROW (matrix, w->cursor.vpos);
13067
13068 /* If the cursor row is not partially visible, there's nothing to do. */
13069 if (!MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row))
13070 return 1;
13071
13072 /* If the row the cursor is in is taller than the window's height,
13073 it's not clear what to do, so do nothing. */
13074 window_height = window_box_height (w);
13075 if (row->height >= window_height)
13076 {
13077 if (!force_p || MINI_WINDOW_P (w)
13078 || w->vscroll || w->cursor.vpos == 0)
13079 return 1;
13080 }
13081 return 0;
13082 }
13083
13084
13085 /* Try scrolling PT into view in window WINDOW. JUST_THIS_ONE_P
13086 non-zero means only WINDOW is redisplayed in redisplay_internal.
13087 TEMP_SCROLL_STEP has the same meaning as emacs_scroll_step, and is used
13088 in redisplay_window to bring a partially visible line into view in
13089 the case that only the cursor has moved.
13090
13091 LAST_LINE_MISFIT should be nonzero if we're scrolling because the
13092 last screen line's vertical height extends past the end of the screen.
13093
13094 Value is
13095
13096 1 if scrolling succeeded
13097
13098 0 if scrolling didn't find point.
13099
13100 -1 if new fonts have been loaded so that we must interrupt
13101 redisplay, adjust glyph matrices, and try again. */
13102
13103 enum
13104 {
13105 SCROLLING_SUCCESS,
13106 SCROLLING_FAILED,
13107 SCROLLING_NEED_LARGER_MATRICES
13108 };
13109
13110 /* If scroll-conservatively is more than this, never recenter.
13111
13112 If you change this, don't forget to update the doc string of
13113 `scroll-conservatively' and the Emacs manual. */
13114 #define SCROLL_LIMIT 100
13115
13116 static int
13117 try_scrolling (Lisp_Object window, int just_this_one_p,
13118 EMACS_INT arg_scroll_conservatively, EMACS_INT scroll_step,
13119 int temp_scroll_step, int last_line_misfit)
13120 {
13121 struct window *w = XWINDOW (window);
13122 struct frame *f = XFRAME (w->frame);
13123 struct text_pos pos, startp;
13124 struct it it;
13125 int this_scroll_margin, scroll_max, rc, height;
13126 int dy = 0, amount_to_scroll = 0, scroll_down_p = 0;
13127 int extra_scroll_margin_lines = last_line_misfit ? 1 : 0;
13128 Lisp_Object aggressive;
13129 /* We will never try scrolling more than this number of lines. */
13130 int scroll_limit = SCROLL_LIMIT;
13131
13132 #if GLYPH_DEBUG
13133 debug_method_add (w, "try_scrolling");
13134 #endif
13135
13136 SET_TEXT_POS_FROM_MARKER (startp, w->start);
13137
13138 /* Compute scroll margin height in pixels. We scroll when point is
13139 within this distance from the top or bottom of the window. */
13140 if (scroll_margin > 0)
13141 this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4)
13142 * FRAME_LINE_HEIGHT (f);
13143 else
13144 this_scroll_margin = 0;
13145
13146 /* Force arg_scroll_conservatively to have a reasonable value, to
13147 avoid scrolling too far away with slow move_it_* functions. Note
13148 that the user can supply scroll-conservatively equal to
13149 `most-positive-fixnum', which can be larger than INT_MAX. */
13150 if (arg_scroll_conservatively > scroll_limit)
13151 {
13152 arg_scroll_conservatively = scroll_limit + 1;
13153 scroll_max = scroll_limit * FRAME_LINE_HEIGHT (f);
13154 }
13155 else if (scroll_step || arg_scroll_conservatively || temp_scroll_step)
13156 /* Compute how much we should try to scroll maximally to bring
13157 point into view. */
13158 scroll_max = (max (scroll_step,
13159 max (arg_scroll_conservatively, temp_scroll_step))
13160 * FRAME_LINE_HEIGHT (f));
13161 else if (NUMBERP (BVAR (current_buffer, scroll_down_aggressively))
13162 || NUMBERP (BVAR (current_buffer, scroll_up_aggressively)))
13163 /* We're trying to scroll because of aggressive scrolling but no
13164 scroll_step is set. Choose an arbitrary one. */
13165 scroll_max = 10 * FRAME_LINE_HEIGHT (f);
13166 else
13167 scroll_max = 0;
13168
13169 too_near_end:
13170
13171 /* Decide whether to scroll down. */
13172 if (PT > CHARPOS (startp))
13173 {
13174 int scroll_margin_y;
13175
13176 /* Compute the pixel ypos of the scroll margin, then move it to
13177 either that ypos or PT, whichever comes first. */
13178 start_display (&it, w, startp);
13179 scroll_margin_y = it.last_visible_y - this_scroll_margin
13180 - FRAME_LINE_HEIGHT (f) * extra_scroll_margin_lines;
13181 move_it_to (&it, PT, -1, scroll_margin_y - 1, -1,
13182 (MOVE_TO_POS | MOVE_TO_Y));
13183
13184 if (PT > CHARPOS (it.current.pos))
13185 {
13186 int y0 = line_bottom_y (&it);
13187 /* Compute how many pixels below window bottom to stop searching
13188 for PT. This avoids costly search for PT that is far away if
13189 the user limited scrolling by a small number of lines, but
13190 always finds PT if scroll_conservatively is set to a large
13191 number, such as most-positive-fixnum. */
13192 int slack = max (scroll_max, 10 * FRAME_LINE_HEIGHT (f));
13193 int y_to_move = it.last_visible_y + slack;
13194
13195 /* Compute the distance from the scroll margin to PT or to
13196 the scroll limit, whichever comes first. This should
13197 include the height of the cursor line, to make that line
13198 fully visible. */
13199 move_it_to (&it, PT, -1, y_to_move,
13200 -1, MOVE_TO_POS | MOVE_TO_Y);
13201 dy = line_bottom_y (&it) - y0;
13202
13203 if (dy > scroll_max)
13204 return SCROLLING_FAILED;
13205
13206 scroll_down_p = 1;
13207 }
13208 }
13209
13210 if (scroll_down_p)
13211 {
13212 /* Point is in or below the bottom scroll margin, so move the
13213 window start down. If scrolling conservatively, move it just
13214 enough down to make point visible. If scroll_step is set,
13215 move it down by scroll_step. */
13216 if (arg_scroll_conservatively)
13217 amount_to_scroll
13218 = min (max (dy, FRAME_LINE_HEIGHT (f)),
13219 FRAME_LINE_HEIGHT (f) * arg_scroll_conservatively);
13220 else if (scroll_step || temp_scroll_step)
13221 amount_to_scroll = scroll_max;
13222 else
13223 {
13224 aggressive = BVAR (current_buffer, scroll_up_aggressively);
13225 height = WINDOW_BOX_TEXT_HEIGHT (w);
13226 if (NUMBERP (aggressive))
13227 {
13228 double float_amount = XFLOATINT (aggressive) * height;
13229 amount_to_scroll = float_amount;
13230 if (amount_to_scroll == 0 && float_amount > 0)
13231 amount_to_scroll = 1;
13232 /* Don't let point enter the scroll margin near top of
13233 the window. */
13234 if (amount_to_scroll > height - 2*this_scroll_margin + dy)
13235 amount_to_scroll = height - 2*this_scroll_margin + dy;
13236 }
13237 }
13238
13239 if (amount_to_scroll <= 0)
13240 return SCROLLING_FAILED;
13241
13242 start_display (&it, w, startp);
13243 if (arg_scroll_conservatively <= scroll_limit)
13244 move_it_vertically (&it, amount_to_scroll);
13245 else
13246 {
13247 /* Extra precision for users who set scroll-conservatively
13248 to a large number: make sure the amount we scroll
13249 the window start is never less than amount_to_scroll,
13250 which was computed as distance from window bottom to
13251 point. This matters when lines at window top and lines
13252 below window bottom have different height. */
13253 struct it it1 = it;
13254 /* We use a temporary it1 because line_bottom_y can modify
13255 its argument, if it moves one line down; see there. */
13256 int start_y = line_bottom_y (&it1);
13257
13258 do {
13259 move_it_by_lines (&it, 1);
13260 it1 = it;
13261 } while (line_bottom_y (&it1) - start_y < amount_to_scroll);
13262 }
13263
13264 /* If STARTP is unchanged, move it down another screen line. */
13265 if (CHARPOS (it.current.pos) == CHARPOS (startp))
13266 move_it_by_lines (&it, 1);
13267 startp = it.current.pos;
13268 }
13269 else
13270 {
13271 struct text_pos scroll_margin_pos = startp;
13272
13273 /* See if point is inside the scroll margin at the top of the
13274 window. */
13275 if (this_scroll_margin)
13276 {
13277 start_display (&it, w, startp);
13278 move_it_vertically (&it, this_scroll_margin);
13279 scroll_margin_pos = it.current.pos;
13280 }
13281
13282 if (PT < CHARPOS (scroll_margin_pos))
13283 {
13284 /* Point is in the scroll margin at the top of the window or
13285 above what is displayed in the window. */
13286 int y0, y_to_move;
13287
13288 /* Compute the vertical distance from PT to the scroll
13289 margin position. Move as far as scroll_max allows, or
13290 one screenful, or 10 screen lines, whichever is largest.
13291 Give up if distance is greater than scroll_max. */
13292 SET_TEXT_POS (pos, PT, PT_BYTE);
13293 start_display (&it, w, pos);
13294 y0 = it.current_y;
13295 y_to_move = max (it.last_visible_y,
13296 max (scroll_max, 10 * FRAME_LINE_HEIGHT (f)));
13297 move_it_to (&it, CHARPOS (scroll_margin_pos), 0,
13298 y_to_move, -1,
13299 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
13300 dy = it.current_y - y0;
13301 if (dy > scroll_max)
13302 return SCROLLING_FAILED;
13303
13304 /* Compute new window start. */
13305 start_display (&it, w, startp);
13306
13307 if (arg_scroll_conservatively)
13308 amount_to_scroll = max (dy, FRAME_LINE_HEIGHT (f) *
13309 max (scroll_step, temp_scroll_step));
13310 else if (scroll_step || temp_scroll_step)
13311 amount_to_scroll = scroll_max;
13312 else
13313 {
13314 aggressive = BVAR (current_buffer, scroll_down_aggressively);
13315 height = WINDOW_BOX_TEXT_HEIGHT (w);
13316 if (NUMBERP (aggressive))
13317 {
13318 double float_amount = XFLOATINT (aggressive) * height;
13319 amount_to_scroll = float_amount;
13320 if (amount_to_scroll == 0 && float_amount > 0)
13321 amount_to_scroll = 1;
13322 amount_to_scroll -=
13323 this_scroll_margin - dy - FRAME_LINE_HEIGHT (f);
13324 /* Don't let point enter the scroll margin near
13325 bottom of the window. */
13326 if (amount_to_scroll > height - 2*this_scroll_margin + dy)
13327 amount_to_scroll = height - 2*this_scroll_margin + dy;
13328 }
13329 }
13330
13331 if (amount_to_scroll <= 0)
13332 return SCROLLING_FAILED;
13333
13334 move_it_vertically_backward (&it, amount_to_scroll);
13335 startp = it.current.pos;
13336 }
13337 }
13338
13339 /* Run window scroll functions. */
13340 startp = run_window_scroll_functions (window, startp);
13341
13342 /* Display the window. Give up if new fonts are loaded, or if point
13343 doesn't appear. */
13344 if (!try_window (window, startp, 0))
13345 rc = SCROLLING_NEED_LARGER_MATRICES;
13346 else if (w->cursor.vpos < 0)
13347 {
13348 clear_glyph_matrix (w->desired_matrix);
13349 rc = SCROLLING_FAILED;
13350 }
13351 else
13352 {
13353 /* Maybe forget recorded base line for line number display. */
13354 if (!just_this_one_p
13355 || current_buffer->clip_changed
13356 || BEG_UNCHANGED < CHARPOS (startp))
13357 w->base_line_number = Qnil;
13358
13359 /* If cursor ends up on a partially visible line,
13360 treat that as being off the bottom of the screen. */
13361 if (! cursor_row_fully_visible_p (w, extra_scroll_margin_lines <= 1, 0)
13362 /* It's possible that the cursor is on the first line of the
13363 buffer, which is partially obscured due to a vscroll
13364 (Bug#7537). In that case, avoid looping forever . */
13365 && extra_scroll_margin_lines < w->desired_matrix->nrows - 1)
13366 {
13367 clear_glyph_matrix (w->desired_matrix);
13368 ++extra_scroll_margin_lines;
13369 goto too_near_end;
13370 }
13371 rc = SCROLLING_SUCCESS;
13372 }
13373
13374 return rc;
13375 }
13376
13377
13378 /* Compute a suitable window start for window W if display of W starts
13379 on a continuation line. Value is non-zero if a new window start
13380 was computed.
13381
13382 The new window start will be computed, based on W's width, starting
13383 from the start of the continued line. It is the start of the
13384 screen line with the minimum distance from the old start W->start. */
13385
13386 static int
13387 compute_window_start_on_continuation_line (struct window *w)
13388 {
13389 struct text_pos pos, start_pos;
13390 int window_start_changed_p = 0;
13391
13392 SET_TEXT_POS_FROM_MARKER (start_pos, w->start);
13393
13394 /* If window start is on a continuation line... Window start may be
13395 < BEGV in case there's invisible text at the start of the
13396 buffer (M-x rmail, for example). */
13397 if (CHARPOS (start_pos) > BEGV
13398 && FETCH_BYTE (BYTEPOS (start_pos) - 1) != '\n')
13399 {
13400 struct it it;
13401 struct glyph_row *row;
13402
13403 /* Handle the case that the window start is out of range. */
13404 if (CHARPOS (start_pos) < BEGV)
13405 SET_TEXT_POS (start_pos, BEGV, BEGV_BYTE);
13406 else if (CHARPOS (start_pos) > ZV)
13407 SET_TEXT_POS (start_pos, ZV, ZV_BYTE);
13408
13409 /* Find the start of the continued line. This should be fast
13410 because scan_buffer is fast (newline cache). */
13411 row = w->desired_matrix->rows + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0);
13412 init_iterator (&it, w, CHARPOS (start_pos), BYTEPOS (start_pos),
13413 row, DEFAULT_FACE_ID);
13414 reseat_at_previous_visible_line_start (&it);
13415
13416 /* If the line start is "too far" away from the window start,
13417 say it takes too much time to compute a new window start. */
13418 if (CHARPOS (start_pos) - IT_CHARPOS (it)
13419 < WINDOW_TOTAL_LINES (w) * WINDOW_TOTAL_COLS (w))
13420 {
13421 int min_distance, distance;
13422
13423 /* Move forward by display lines to find the new window
13424 start. If window width was enlarged, the new start can
13425 be expected to be > the old start. If window width was
13426 decreased, the new window start will be < the old start.
13427 So, we're looking for the display line start with the
13428 minimum distance from the old window start. */
13429 pos = it.current.pos;
13430 min_distance = INFINITY;
13431 while ((distance = eabs (CHARPOS (start_pos) - IT_CHARPOS (it))),
13432 distance < min_distance)
13433 {
13434 min_distance = distance;
13435 pos = it.current.pos;
13436 move_it_by_lines (&it, 1);
13437 }
13438
13439 /* Set the window start there. */
13440 SET_MARKER_FROM_TEXT_POS (w->start, pos);
13441 window_start_changed_p = 1;
13442 }
13443 }
13444
13445 return window_start_changed_p;
13446 }
13447
13448
13449 /* Try cursor movement in case text has not changed in window WINDOW,
13450 with window start STARTP. Value is
13451
13452 CURSOR_MOVEMENT_SUCCESS if successful
13453
13454 CURSOR_MOVEMENT_CANNOT_BE_USED if this method cannot be used
13455
13456 CURSOR_MOVEMENT_MUST_SCROLL if we know we have to scroll the
13457 display. *SCROLL_STEP is set to 1, under certain circumstances, if
13458 we want to scroll as if scroll-step were set to 1. See the code.
13459
13460 CURSOR_MOVEMENT_NEED_LARGER_MATRICES if we need larger matrices, in
13461 which case we have to abort this redisplay, and adjust matrices
13462 first. */
13463
13464 enum
13465 {
13466 CURSOR_MOVEMENT_SUCCESS,
13467 CURSOR_MOVEMENT_CANNOT_BE_USED,
13468 CURSOR_MOVEMENT_MUST_SCROLL,
13469 CURSOR_MOVEMENT_NEED_LARGER_MATRICES
13470 };
13471
13472 static int
13473 try_cursor_movement (Lisp_Object window, struct text_pos startp, int *scroll_step)
13474 {
13475 struct window *w = XWINDOW (window);
13476 struct frame *f = XFRAME (w->frame);
13477 int rc = CURSOR_MOVEMENT_CANNOT_BE_USED;
13478
13479 #if GLYPH_DEBUG
13480 if (inhibit_try_cursor_movement)
13481 return rc;
13482 #endif
13483
13484 /* Handle case where text has not changed, only point, and it has
13485 not moved off the frame. */
13486 if (/* Point may be in this window. */
13487 PT >= CHARPOS (startp)
13488 /* Selective display hasn't changed. */
13489 && !current_buffer->clip_changed
13490 /* Function force-mode-line-update is used to force a thorough
13491 redisplay. It sets either windows_or_buffers_changed or
13492 update_mode_lines. So don't take a shortcut here for these
13493 cases. */
13494 && !update_mode_lines
13495 && !windows_or_buffers_changed
13496 && !cursor_type_changed
13497 /* Can't use this case if highlighting a region. When a
13498 region exists, cursor movement has to do more than just
13499 set the cursor. */
13500 && !(!NILP (Vtransient_mark_mode)
13501 && !NILP (BVAR (current_buffer, mark_active)))
13502 && NILP (w->region_showing)
13503 && NILP (Vshow_trailing_whitespace)
13504 /* Right after splitting windows, last_point may be nil. */
13505 && INTEGERP (w->last_point)
13506 /* This code is not used for mini-buffer for the sake of the case
13507 of redisplaying to replace an echo area message; since in
13508 that case the mini-buffer contents per se are usually
13509 unchanged. This code is of no real use in the mini-buffer
13510 since the handling of this_line_start_pos, etc., in redisplay
13511 handles the same cases. */
13512 && !EQ (window, minibuf_window)
13513 /* When splitting windows or for new windows, it happens that
13514 redisplay is called with a nil window_end_vpos or one being
13515 larger than the window. This should really be fixed in
13516 window.c. I don't have this on my list, now, so we do
13517 approximately the same as the old redisplay code. --gerd. */
13518 && INTEGERP (w->window_end_vpos)
13519 && XFASTINT (w->window_end_vpos) < w->current_matrix->nrows
13520 && (FRAME_WINDOW_P (f)
13521 || !overlay_arrow_in_current_buffer_p ()))
13522 {
13523 int this_scroll_margin, top_scroll_margin;
13524 struct glyph_row *row = NULL;
13525
13526 #if GLYPH_DEBUG
13527 debug_method_add (w, "cursor movement");
13528 #endif
13529
13530 /* Scroll if point within this distance from the top or bottom
13531 of the window. This is a pixel value. */
13532 if (scroll_margin > 0)
13533 {
13534 this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
13535 this_scroll_margin *= FRAME_LINE_HEIGHT (f);
13536 }
13537 else
13538 this_scroll_margin = 0;
13539
13540 top_scroll_margin = this_scroll_margin;
13541 if (WINDOW_WANTS_HEADER_LINE_P (w))
13542 top_scroll_margin += CURRENT_HEADER_LINE_HEIGHT (w);
13543
13544 /* Start with the row the cursor was displayed during the last
13545 not paused redisplay. Give up if that row is not valid. */
13546 if (w->last_cursor.vpos < 0
13547 || w->last_cursor.vpos >= w->current_matrix->nrows)
13548 rc = CURSOR_MOVEMENT_MUST_SCROLL;
13549 else
13550 {
13551 row = MATRIX_ROW (w->current_matrix, w->last_cursor.vpos);
13552 if (row->mode_line_p)
13553 ++row;
13554 if (!row->enabled_p)
13555 rc = CURSOR_MOVEMENT_MUST_SCROLL;
13556 }
13557
13558 if (rc == CURSOR_MOVEMENT_CANNOT_BE_USED)
13559 {
13560 int scroll_p = 0, must_scroll = 0;
13561 int last_y = window_text_bottom_y (w) - this_scroll_margin;
13562
13563 if (PT > XFASTINT (w->last_point))
13564 {
13565 /* Point has moved forward. */
13566 while (MATRIX_ROW_END_CHARPOS (row) < PT
13567 && MATRIX_ROW_BOTTOM_Y (row) < last_y)
13568 {
13569 xassert (row->enabled_p);
13570 ++row;
13571 }
13572
13573 /* If the end position of a row equals the start
13574 position of the next row, and PT is at that position,
13575 we would rather display cursor in the next line. */
13576 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
13577 && MATRIX_ROW_END_CHARPOS (row) == PT
13578 && row < w->current_matrix->rows
13579 + w->current_matrix->nrows - 1
13580 && MATRIX_ROW_START_CHARPOS (row+1) == PT
13581 && !cursor_row_p (row))
13582 ++row;
13583
13584 /* If within the scroll margin, scroll. Note that
13585 MATRIX_ROW_BOTTOM_Y gives the pixel position at which
13586 the next line would be drawn, and that
13587 this_scroll_margin can be zero. */
13588 if (MATRIX_ROW_BOTTOM_Y (row) > last_y
13589 || PT > MATRIX_ROW_END_CHARPOS (row)
13590 /* Line is completely visible last line in window
13591 and PT is to be set in the next line. */
13592 || (MATRIX_ROW_BOTTOM_Y (row) == last_y
13593 && PT == MATRIX_ROW_END_CHARPOS (row)
13594 && !row->ends_at_zv_p
13595 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
13596 scroll_p = 1;
13597 }
13598 else if (PT < XFASTINT (w->last_point))
13599 {
13600 /* Cursor has to be moved backward. Note that PT >=
13601 CHARPOS (startp) because of the outer if-statement. */
13602 while (!row->mode_line_p
13603 && (MATRIX_ROW_START_CHARPOS (row) > PT
13604 || (MATRIX_ROW_START_CHARPOS (row) == PT
13605 && (MATRIX_ROW_STARTS_IN_MIDDLE_OF_CHAR_P (row)
13606 || (/* STARTS_IN_MIDDLE_OF_STRING_P (row) */
13607 row > w->current_matrix->rows
13608 && (row-1)->ends_in_newline_from_string_p))))
13609 && (row->y > top_scroll_margin
13610 || CHARPOS (startp) == BEGV))
13611 {
13612 xassert (row->enabled_p);
13613 --row;
13614 }
13615
13616 /* Consider the following case: Window starts at BEGV,
13617 there is invisible, intangible text at BEGV, so that
13618 display starts at some point START > BEGV. It can
13619 happen that we are called with PT somewhere between
13620 BEGV and START. Try to handle that case. */
13621 if (row < w->current_matrix->rows
13622 || row->mode_line_p)
13623 {
13624 row = w->current_matrix->rows;
13625 if (row->mode_line_p)
13626 ++row;
13627 }
13628
13629 /* Due to newlines in overlay strings, we may have to
13630 skip forward over overlay strings. */
13631 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
13632 && MATRIX_ROW_END_CHARPOS (row) == PT
13633 && !cursor_row_p (row))
13634 ++row;
13635
13636 /* If within the scroll margin, scroll. */
13637 if (row->y < top_scroll_margin
13638 && CHARPOS (startp) != BEGV)
13639 scroll_p = 1;
13640 }
13641 else
13642 {
13643 /* Cursor did not move. So don't scroll even if cursor line
13644 is partially visible, as it was so before. */
13645 rc = CURSOR_MOVEMENT_SUCCESS;
13646 }
13647
13648 if (PT < MATRIX_ROW_START_CHARPOS (row)
13649 || PT > MATRIX_ROW_END_CHARPOS (row))
13650 {
13651 /* if PT is not in the glyph row, give up. */
13652 rc = CURSOR_MOVEMENT_MUST_SCROLL;
13653 must_scroll = 1;
13654 }
13655 else if (rc != CURSOR_MOVEMENT_SUCCESS
13656 && !NILP (BVAR (XBUFFER (w->buffer), bidi_display_reordering)))
13657 {
13658 /* If rows are bidi-reordered and point moved, back up
13659 until we find a row that does not belong to a
13660 continuation line. This is because we must consider
13661 all rows of a continued line as candidates for the
13662 new cursor positioning, since row start and end
13663 positions change non-linearly with vertical position
13664 in such rows. */
13665 /* FIXME: Revisit this when glyph ``spilling'' in
13666 continuation lines' rows is implemented for
13667 bidi-reordered rows. */
13668 while (MATRIX_ROW_CONTINUATION_LINE_P (row))
13669 {
13670 xassert (row->enabled_p);
13671 --row;
13672 /* If we hit the beginning of the displayed portion
13673 without finding the first row of a continued
13674 line, give up. */
13675 if (row <= w->current_matrix->rows)
13676 {
13677 rc = CURSOR_MOVEMENT_MUST_SCROLL;
13678 break;
13679 }
13680
13681 }
13682 }
13683 if (must_scroll)
13684 ;
13685 else if (rc != CURSOR_MOVEMENT_SUCCESS
13686 && MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row)
13687 && make_cursor_line_fully_visible_p)
13688 {
13689 if (PT == MATRIX_ROW_END_CHARPOS (row)
13690 && !row->ends_at_zv_p
13691 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
13692 rc = CURSOR_MOVEMENT_MUST_SCROLL;
13693 else if (row->height > window_box_height (w))
13694 {
13695 /* If we end up in a partially visible line, let's
13696 make it fully visible, except when it's taller
13697 than the window, in which case we can't do much
13698 about it. */
13699 *scroll_step = 1;
13700 rc = CURSOR_MOVEMENT_MUST_SCROLL;
13701 }
13702 else
13703 {
13704 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
13705 if (!cursor_row_fully_visible_p (w, 0, 1))
13706 rc = CURSOR_MOVEMENT_MUST_SCROLL;
13707 else
13708 rc = CURSOR_MOVEMENT_SUCCESS;
13709 }
13710 }
13711 else if (scroll_p)
13712 rc = CURSOR_MOVEMENT_MUST_SCROLL;
13713 else if (rc != CURSOR_MOVEMENT_SUCCESS
13714 && !NILP (BVAR (XBUFFER (w->buffer), bidi_display_reordering)))
13715 {
13716 /* With bidi-reordered rows, there could be more than
13717 one candidate row whose start and end positions
13718 occlude point. We need to let set_cursor_from_row
13719 find the best candidate. */
13720 /* FIXME: Revisit this when glyph ``spilling'' in
13721 continuation lines' rows is implemented for
13722 bidi-reordered rows. */
13723 int rv = 0;
13724
13725 do
13726 {
13727 if (MATRIX_ROW_START_CHARPOS (row) <= PT
13728 && PT <= MATRIX_ROW_END_CHARPOS (row)
13729 && cursor_row_p (row))
13730 rv |= set_cursor_from_row (w, row, w->current_matrix,
13731 0, 0, 0, 0);
13732 /* As soon as we've found the first suitable row
13733 whose ends_at_zv_p flag is set, we are done. */
13734 if (rv
13735 && MATRIX_ROW (w->current_matrix, w->cursor.vpos)->ends_at_zv_p)
13736 {
13737 rc = CURSOR_MOVEMENT_SUCCESS;
13738 break;
13739 }
13740 ++row;
13741 }
13742 while ((MATRIX_ROW_CONTINUATION_LINE_P (row)
13743 && MATRIX_ROW_BOTTOM_Y (row) <= last_y)
13744 || (MATRIX_ROW_START_CHARPOS (row) == PT
13745 && MATRIX_ROW_BOTTOM_Y (row) < last_y));
13746 /* If we didn't find any candidate rows, or exited the
13747 loop before all the candidates were examined, signal
13748 to the caller that this method failed. */
13749 if (rc != CURSOR_MOVEMENT_SUCCESS
13750 && (!rv || MATRIX_ROW_CONTINUATION_LINE_P (row)))
13751 rc = CURSOR_MOVEMENT_MUST_SCROLL;
13752 else if (rv)
13753 rc = CURSOR_MOVEMENT_SUCCESS;
13754 }
13755 else
13756 {
13757 do
13758 {
13759 if (set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0))
13760 {
13761 rc = CURSOR_MOVEMENT_SUCCESS;
13762 break;
13763 }
13764 ++row;
13765 }
13766 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
13767 && MATRIX_ROW_START_CHARPOS (row) == PT
13768 && cursor_row_p (row));
13769 }
13770 }
13771 }
13772
13773 return rc;
13774 }
13775
13776 #if !defined USE_TOOLKIT_SCROLL_BARS || defined USE_GTK
13777 static
13778 #endif
13779 void
13780 set_vertical_scroll_bar (struct window *w)
13781 {
13782 EMACS_INT start, end, whole;
13783
13784 /* Calculate the start and end positions for the current window.
13785 At some point, it would be nice to choose between scrollbars
13786 which reflect the whole buffer size, with special markers
13787 indicating narrowing, and scrollbars which reflect only the
13788 visible region.
13789
13790 Note that mini-buffers sometimes aren't displaying any text. */
13791 if (!MINI_WINDOW_P (w)
13792 || (w == XWINDOW (minibuf_window)
13793 && NILP (echo_area_buffer[0])))
13794 {
13795 struct buffer *buf = XBUFFER (w->buffer);
13796 whole = BUF_ZV (buf) - BUF_BEGV (buf);
13797 start = marker_position (w->start) - BUF_BEGV (buf);
13798 /* I don't think this is guaranteed to be right. For the
13799 moment, we'll pretend it is. */
13800 end = BUF_Z (buf) - XFASTINT (w->window_end_pos) - BUF_BEGV (buf);
13801
13802 if (end < start)
13803 end = start;
13804 if (whole < (end - start))
13805 whole = end - start;
13806 }
13807 else
13808 start = end = whole = 0;
13809
13810 /* Indicate what this scroll bar ought to be displaying now. */
13811 if (FRAME_TERMINAL (XFRAME (w->frame))->set_vertical_scroll_bar_hook)
13812 (*FRAME_TERMINAL (XFRAME (w->frame))->set_vertical_scroll_bar_hook)
13813 (w, end - start, whole, start);
13814 }
13815
13816
13817 /* Redisplay leaf window WINDOW. JUST_THIS_ONE_P non-zero means only
13818 selected_window is redisplayed.
13819
13820 We can return without actually redisplaying the window if
13821 fonts_changed_p is nonzero. In that case, redisplay_internal will
13822 retry. */
13823
13824 static void
13825 redisplay_window (Lisp_Object window, int just_this_one_p)
13826 {
13827 struct window *w = XWINDOW (window);
13828 struct frame *f = XFRAME (w->frame);
13829 struct buffer *buffer = XBUFFER (w->buffer);
13830 struct buffer *old = current_buffer;
13831 struct text_pos lpoint, opoint, startp;
13832 int update_mode_line;
13833 int tem;
13834 struct it it;
13835 /* Record it now because it's overwritten. */
13836 int current_matrix_up_to_date_p = 0;
13837 int used_current_matrix_p = 0;
13838 /* This is less strict than current_matrix_up_to_date_p.
13839 It indictes that the buffer contents and narrowing are unchanged. */
13840 int buffer_unchanged_p = 0;
13841 int temp_scroll_step = 0;
13842 int count = SPECPDL_INDEX ();
13843 int rc;
13844 int centering_position = -1;
13845 int last_line_misfit = 0;
13846 EMACS_INT beg_unchanged, end_unchanged;
13847
13848 SET_TEXT_POS (lpoint, PT, PT_BYTE);
13849 opoint = lpoint;
13850
13851 /* W must be a leaf window here. */
13852 xassert (!NILP (w->buffer));
13853 #if GLYPH_DEBUG
13854 *w->desired_matrix->method = 0;
13855 #endif
13856
13857 restart:
13858 reconsider_clip_changes (w, buffer);
13859
13860 /* Has the mode line to be updated? */
13861 update_mode_line = (!NILP (w->update_mode_line)
13862 || update_mode_lines
13863 || buffer->clip_changed
13864 || buffer->prevent_redisplay_optimizations_p);
13865
13866 if (MINI_WINDOW_P (w))
13867 {
13868 if (w == XWINDOW (echo_area_window)
13869 && !NILP (echo_area_buffer[0]))
13870 {
13871 if (update_mode_line)
13872 /* We may have to update a tty frame's menu bar or a
13873 tool-bar. Example `M-x C-h C-h C-g'. */
13874 goto finish_menu_bars;
13875 else
13876 /* We've already displayed the echo area glyphs in this window. */
13877 goto finish_scroll_bars;
13878 }
13879 else if ((w != XWINDOW (minibuf_window)
13880 || minibuf_level == 0)
13881 /* When buffer is nonempty, redisplay window normally. */
13882 && BUF_Z (XBUFFER (w->buffer)) == BUF_BEG (XBUFFER (w->buffer))
13883 /* Quail displays non-mini buffers in minibuffer window.
13884 In that case, redisplay the window normally. */
13885 && !NILP (Fmemq (w->buffer, Vminibuffer_list)))
13886 {
13887 /* W is a mini-buffer window, but it's not active, so clear
13888 it. */
13889 int yb = window_text_bottom_y (w);
13890 struct glyph_row *row;
13891 int y;
13892
13893 for (y = 0, row = w->desired_matrix->rows;
13894 y < yb;
13895 y += row->height, ++row)
13896 blank_row (w, row, y);
13897 goto finish_scroll_bars;
13898 }
13899
13900 clear_glyph_matrix (w->desired_matrix);
13901 }
13902
13903 /* Otherwise set up data on this window; select its buffer and point
13904 value. */
13905 /* Really select the buffer, for the sake of buffer-local
13906 variables. */
13907 set_buffer_internal_1 (XBUFFER (w->buffer));
13908
13909 current_matrix_up_to_date_p
13910 = (!NILP (w->window_end_valid)
13911 && !current_buffer->clip_changed
13912 && !current_buffer->prevent_redisplay_optimizations_p
13913 && XFASTINT (w->last_modified) >= MODIFF
13914 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
13915
13916 /* Run the window-bottom-change-functions
13917 if it is possible that the text on the screen has changed
13918 (either due to modification of the text, or any other reason). */
13919 if (!current_matrix_up_to_date_p
13920 && !NILP (Vwindow_text_change_functions))
13921 {
13922 safe_run_hooks (Qwindow_text_change_functions);
13923 goto restart;
13924 }
13925
13926 beg_unchanged = BEG_UNCHANGED;
13927 end_unchanged = END_UNCHANGED;
13928
13929 SET_TEXT_POS (opoint, PT, PT_BYTE);
13930
13931 specbind (Qinhibit_point_motion_hooks, Qt);
13932
13933 buffer_unchanged_p
13934 = (!NILP (w->window_end_valid)
13935 && !current_buffer->clip_changed
13936 && XFASTINT (w->last_modified) >= MODIFF
13937 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
13938
13939 /* When windows_or_buffers_changed is non-zero, we can't rely on
13940 the window end being valid, so set it to nil there. */
13941 if (windows_or_buffers_changed)
13942 {
13943 /* If window starts on a continuation line, maybe adjust the
13944 window start in case the window's width changed. */
13945 if (XMARKER (w->start)->buffer == current_buffer)
13946 compute_window_start_on_continuation_line (w);
13947
13948 w->window_end_valid = Qnil;
13949 }
13950
13951 /* Some sanity checks. */
13952 CHECK_WINDOW_END (w);
13953 if (Z == Z_BYTE && CHARPOS (opoint) != BYTEPOS (opoint))
13954 abort ();
13955 if (BYTEPOS (opoint) < CHARPOS (opoint))
13956 abort ();
13957
13958 /* If %c is in mode line, update it if needed. */
13959 if (!NILP (w->column_number_displayed)
13960 /* This alternative quickly identifies a common case
13961 where no change is needed. */
13962 && !(PT == XFASTINT (w->last_point)
13963 && XFASTINT (w->last_modified) >= MODIFF
13964 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
13965 && (XFASTINT (w->column_number_displayed) != current_column ()))
13966 update_mode_line = 1;
13967
13968 /* Count number of windows showing the selected buffer. An indirect
13969 buffer counts as its base buffer. */
13970 if (!just_this_one_p)
13971 {
13972 struct buffer *current_base, *window_base;
13973 current_base = current_buffer;
13974 window_base = XBUFFER (XWINDOW (selected_window)->buffer);
13975 if (current_base->base_buffer)
13976 current_base = current_base->base_buffer;
13977 if (window_base->base_buffer)
13978 window_base = window_base->base_buffer;
13979 if (current_base == window_base)
13980 buffer_shared++;
13981 }
13982
13983 /* Point refers normally to the selected window. For any other
13984 window, set up appropriate value. */
13985 if (!EQ (window, selected_window))
13986 {
13987 EMACS_INT new_pt = XMARKER (w->pointm)->charpos;
13988 EMACS_INT new_pt_byte = marker_byte_position (w->pointm);
13989 if (new_pt < BEGV)
13990 {
13991 new_pt = BEGV;
13992 new_pt_byte = BEGV_BYTE;
13993 set_marker_both (w->pointm, Qnil, BEGV, BEGV_BYTE);
13994 }
13995 else if (new_pt > (ZV - 1))
13996 {
13997 new_pt = ZV;
13998 new_pt_byte = ZV_BYTE;
13999 set_marker_both (w->pointm, Qnil, ZV, ZV_BYTE);
14000 }
14001
14002 /* We don't use SET_PT so that the point-motion hooks don't run. */
14003 TEMP_SET_PT_BOTH (new_pt, new_pt_byte);
14004 }
14005
14006 /* If any of the character widths specified in the display table
14007 have changed, invalidate the width run cache. It's true that
14008 this may be a bit late to catch such changes, but the rest of
14009 redisplay goes (non-fatally) haywire when the display table is
14010 changed, so why should we worry about doing any better? */
14011 if (current_buffer->width_run_cache)
14012 {
14013 struct Lisp_Char_Table *disptab = buffer_display_table ();
14014
14015 if (! disptab_matches_widthtab (disptab,
14016 XVECTOR (BVAR (current_buffer, width_table))))
14017 {
14018 invalidate_region_cache (current_buffer,
14019 current_buffer->width_run_cache,
14020 BEG, Z);
14021 recompute_width_table (current_buffer, disptab);
14022 }
14023 }
14024
14025 /* If window-start is screwed up, choose a new one. */
14026 if (XMARKER (w->start)->buffer != current_buffer)
14027 goto recenter;
14028
14029 SET_TEXT_POS_FROM_MARKER (startp, w->start);
14030
14031 /* If someone specified a new starting point but did not insist,
14032 check whether it can be used. */
14033 if (!NILP (w->optional_new_start)
14034 && CHARPOS (startp) >= BEGV
14035 && CHARPOS (startp) <= ZV)
14036 {
14037 w->optional_new_start = Qnil;
14038 start_display (&it, w, startp);
14039 move_it_to (&it, PT, 0, it.last_visible_y, -1,
14040 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
14041 if (IT_CHARPOS (it) == PT)
14042 w->force_start = Qt;
14043 /* IT may overshoot PT if text at PT is invisible. */
14044 else if (IT_CHARPOS (it) > PT && CHARPOS (startp) <= PT)
14045 w->force_start = Qt;
14046 }
14047
14048 force_start:
14049
14050 /* Handle case where place to start displaying has been specified,
14051 unless the specified location is outside the accessible range. */
14052 if (!NILP (w->force_start)
14053 || w->frozen_window_start_p)
14054 {
14055 /* We set this later on if we have to adjust point. */
14056 int new_vpos = -1;
14057
14058 w->force_start = Qnil;
14059 w->vscroll = 0;
14060 w->window_end_valid = Qnil;
14061
14062 /* Forget any recorded base line for line number display. */
14063 if (!buffer_unchanged_p)
14064 w->base_line_number = Qnil;
14065
14066 /* Redisplay the mode line. Select the buffer properly for that.
14067 Also, run the hook window-scroll-functions
14068 because we have scrolled. */
14069 /* Note, we do this after clearing force_start because
14070 if there's an error, it is better to forget about force_start
14071 than to get into an infinite loop calling the hook functions
14072 and having them get more errors. */
14073 if (!update_mode_line
14074 || ! NILP (Vwindow_scroll_functions))
14075 {
14076 update_mode_line = 1;
14077 w->update_mode_line = Qt;
14078 startp = run_window_scroll_functions (window, startp);
14079 }
14080
14081 w->last_modified = make_number (0);
14082 w->last_overlay_modified = make_number (0);
14083 if (CHARPOS (startp) < BEGV)
14084 SET_TEXT_POS (startp, BEGV, BEGV_BYTE);
14085 else if (CHARPOS (startp) > ZV)
14086 SET_TEXT_POS (startp, ZV, ZV_BYTE);
14087
14088 /* Redisplay, then check if cursor has been set during the
14089 redisplay. Give up if new fonts were loaded. */
14090 /* We used to issue a CHECK_MARGINS argument to try_window here,
14091 but this causes scrolling to fail when point begins inside
14092 the scroll margin (bug#148) -- cyd */
14093 if (!try_window (window, startp, 0))
14094 {
14095 w->force_start = Qt;
14096 clear_glyph_matrix (w->desired_matrix);
14097 goto need_larger_matrices;
14098 }
14099
14100 if (w->cursor.vpos < 0 && !w->frozen_window_start_p)
14101 {
14102 /* If point does not appear, try to move point so it does
14103 appear. The desired matrix has been built above, so we
14104 can use it here. */
14105 new_vpos = window_box_height (w) / 2;
14106 }
14107
14108 if (!cursor_row_fully_visible_p (w, 0, 0))
14109 {
14110 /* Point does appear, but on a line partly visible at end of window.
14111 Move it back to a fully-visible line. */
14112 new_vpos = window_box_height (w);
14113 }
14114
14115 /* If we need to move point for either of the above reasons,
14116 now actually do it. */
14117 if (new_vpos >= 0)
14118 {
14119 struct glyph_row *row;
14120
14121 row = MATRIX_FIRST_TEXT_ROW (w->desired_matrix);
14122 while (MATRIX_ROW_BOTTOM_Y (row) < new_vpos)
14123 ++row;
14124
14125 TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row),
14126 MATRIX_ROW_START_BYTEPOS (row));
14127
14128 if (w != XWINDOW (selected_window))
14129 set_marker_both (w->pointm, Qnil, PT, PT_BYTE);
14130 else if (current_buffer == old)
14131 SET_TEXT_POS (lpoint, PT, PT_BYTE);
14132
14133 set_cursor_from_row (w, row, w->desired_matrix, 0, 0, 0, 0);
14134
14135 /* If we are highlighting the region, then we just changed
14136 the region, so redisplay to show it. */
14137 if (!NILP (Vtransient_mark_mode)
14138 && !NILP (BVAR (current_buffer, mark_active)))
14139 {
14140 clear_glyph_matrix (w->desired_matrix);
14141 if (!try_window (window, startp, 0))
14142 goto need_larger_matrices;
14143 }
14144 }
14145
14146 #if GLYPH_DEBUG
14147 debug_method_add (w, "forced window start");
14148 #endif
14149 goto done;
14150 }
14151
14152 /* Handle case where text has not changed, only point, and it has
14153 not moved off the frame, and we are not retrying after hscroll.
14154 (current_matrix_up_to_date_p is nonzero when retrying.) */
14155 if (current_matrix_up_to_date_p
14156 && (rc = try_cursor_movement (window, startp, &temp_scroll_step),
14157 rc != CURSOR_MOVEMENT_CANNOT_BE_USED))
14158 {
14159 switch (rc)
14160 {
14161 case CURSOR_MOVEMENT_SUCCESS:
14162 used_current_matrix_p = 1;
14163 goto done;
14164
14165 case CURSOR_MOVEMENT_MUST_SCROLL:
14166 goto try_to_scroll;
14167
14168 default:
14169 abort ();
14170 }
14171 }
14172 /* If current starting point was originally the beginning of a line
14173 but no longer is, find a new starting point. */
14174 else if (!NILP (w->start_at_line_beg)
14175 && !(CHARPOS (startp) <= BEGV
14176 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n'))
14177 {
14178 #if GLYPH_DEBUG
14179 debug_method_add (w, "recenter 1");
14180 #endif
14181 goto recenter;
14182 }
14183
14184 /* Try scrolling with try_window_id. Value is > 0 if update has
14185 been done, it is -1 if we know that the same window start will
14186 not work. It is 0 if unsuccessful for some other reason. */
14187 else if ((tem = try_window_id (w)) != 0)
14188 {
14189 #if GLYPH_DEBUG
14190 debug_method_add (w, "try_window_id %d", tem);
14191 #endif
14192
14193 if (fonts_changed_p)
14194 goto need_larger_matrices;
14195 if (tem > 0)
14196 goto done;
14197
14198 /* Otherwise try_window_id has returned -1 which means that we
14199 don't want the alternative below this comment to execute. */
14200 }
14201 else if (CHARPOS (startp) >= BEGV
14202 && CHARPOS (startp) <= ZV
14203 && PT >= CHARPOS (startp)
14204 && (CHARPOS (startp) < ZV
14205 /* Avoid starting at end of buffer. */
14206 || CHARPOS (startp) == BEGV
14207 || (XFASTINT (w->last_modified) >= MODIFF
14208 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)))
14209 {
14210
14211 /* If first window line is a continuation line, and window start
14212 is inside the modified region, but the first change is before
14213 current window start, we must select a new window start.
14214
14215 However, if this is the result of a down-mouse event (e.g. by
14216 extending the mouse-drag-overlay), we don't want to select a
14217 new window start, since that would change the position under
14218 the mouse, resulting in an unwanted mouse-movement rather
14219 than a simple mouse-click. */
14220 if (NILP (w->start_at_line_beg)
14221 && NILP (do_mouse_tracking)
14222 && CHARPOS (startp) > BEGV
14223 && CHARPOS (startp) > BEG + beg_unchanged
14224 && CHARPOS (startp) <= Z - end_unchanged
14225 /* Even if w->start_at_line_beg is nil, a new window may
14226 start at a line_beg, since that's how set_buffer_window
14227 sets it. So, we need to check the return value of
14228 compute_window_start_on_continuation_line. (See also
14229 bug#197). */
14230 && XMARKER (w->start)->buffer == current_buffer
14231 && compute_window_start_on_continuation_line (w))
14232 {
14233 w->force_start = Qt;
14234 SET_TEXT_POS_FROM_MARKER (startp, w->start);
14235 goto force_start;
14236 }
14237
14238 #if GLYPH_DEBUG
14239 debug_method_add (w, "same window start");
14240 #endif
14241
14242 /* Try to redisplay starting at same place as before.
14243 If point has not moved off frame, accept the results. */
14244 if (!current_matrix_up_to_date_p
14245 /* Don't use try_window_reusing_current_matrix in this case
14246 because a window scroll function can have changed the
14247 buffer. */
14248 || !NILP (Vwindow_scroll_functions)
14249 || MINI_WINDOW_P (w)
14250 || !(used_current_matrix_p
14251 = try_window_reusing_current_matrix (w)))
14252 {
14253 IF_DEBUG (debug_method_add (w, "1"));
14254 if (try_window (window, startp, TRY_WINDOW_CHECK_MARGINS) < 0)
14255 /* -1 means we need to scroll.
14256 0 means we need new matrices, but fonts_changed_p
14257 is set in that case, so we will detect it below. */
14258 goto try_to_scroll;
14259 }
14260
14261 if (fonts_changed_p)
14262 goto need_larger_matrices;
14263
14264 if (w->cursor.vpos >= 0)
14265 {
14266 if (!just_this_one_p
14267 || current_buffer->clip_changed
14268 || BEG_UNCHANGED < CHARPOS (startp))
14269 /* Forget any recorded base line for line number display. */
14270 w->base_line_number = Qnil;
14271
14272 if (!cursor_row_fully_visible_p (w, 1, 0))
14273 {
14274 clear_glyph_matrix (w->desired_matrix);
14275 last_line_misfit = 1;
14276 }
14277 /* Drop through and scroll. */
14278 else
14279 goto done;
14280 }
14281 else
14282 clear_glyph_matrix (w->desired_matrix);
14283 }
14284
14285 try_to_scroll:
14286
14287 w->last_modified = make_number (0);
14288 w->last_overlay_modified = make_number (0);
14289
14290 /* Redisplay the mode line. Select the buffer properly for that. */
14291 if (!update_mode_line)
14292 {
14293 update_mode_line = 1;
14294 w->update_mode_line = Qt;
14295 }
14296
14297 /* Try to scroll by specified few lines. */
14298 if ((scroll_conservatively
14299 || emacs_scroll_step
14300 || temp_scroll_step
14301 || NUMBERP (BVAR (current_buffer, scroll_up_aggressively))
14302 || NUMBERP (BVAR (current_buffer, scroll_down_aggressively)))
14303 && CHARPOS (startp) >= BEGV
14304 && CHARPOS (startp) <= ZV)
14305 {
14306 /* The function returns -1 if new fonts were loaded, 1 if
14307 successful, 0 if not successful. */
14308 int ss = try_scrolling (window, just_this_one_p,
14309 scroll_conservatively,
14310 emacs_scroll_step,
14311 temp_scroll_step, last_line_misfit);
14312 switch (ss)
14313 {
14314 case SCROLLING_SUCCESS:
14315 goto done;
14316
14317 case SCROLLING_NEED_LARGER_MATRICES:
14318 goto need_larger_matrices;
14319
14320 case SCROLLING_FAILED:
14321 break;
14322
14323 default:
14324 abort ();
14325 }
14326 }
14327
14328 /* Finally, just choose a place to start which positions point
14329 according to user preferences. */
14330
14331 recenter:
14332
14333 #if GLYPH_DEBUG
14334 debug_method_add (w, "recenter");
14335 #endif
14336
14337 /* w->vscroll = 0; */
14338
14339 /* Forget any previously recorded base line for line number display. */
14340 if (!buffer_unchanged_p)
14341 w->base_line_number = Qnil;
14342
14343 /* Determine the window start relative to point. */
14344 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
14345 it.current_y = it.last_visible_y;
14346 if (centering_position < 0)
14347 {
14348 int margin =
14349 scroll_margin > 0
14350 ? min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4)
14351 : 0;
14352 EMACS_INT margin_pos = CHARPOS (startp);
14353 int scrolling_up;
14354 Lisp_Object aggressive;
14355
14356 /* If there is a scroll margin at the top of the window, find
14357 its character position. */
14358 if (margin
14359 /* Cannot call start_display if startp is not in the
14360 accessible region of the buffer. This can happen when we
14361 have just switched to a different buffer and/or changed
14362 its restriction. In that case, startp is initialized to
14363 the character position 1 (BEG) because we did not yet
14364 have chance to display the buffer even once. */
14365 && BEGV <= CHARPOS (startp) && CHARPOS (startp) <= ZV)
14366 {
14367 struct it it1;
14368
14369 start_display (&it1, w, startp);
14370 move_it_vertically (&it1, margin);
14371 margin_pos = IT_CHARPOS (it1);
14372 }
14373 scrolling_up = PT > margin_pos;
14374 aggressive =
14375 scrolling_up
14376 ? BVAR (current_buffer, scroll_up_aggressively)
14377 : BVAR (current_buffer, scroll_down_aggressively);
14378
14379 if (!MINI_WINDOW_P (w)
14380 && (scroll_conservatively > SCROLL_LIMIT || NUMBERP (aggressive)))
14381 {
14382 int pt_offset = 0;
14383
14384 /* Setting scroll-conservatively overrides
14385 scroll-*-aggressively. */
14386 if (!scroll_conservatively && NUMBERP (aggressive))
14387 {
14388 double float_amount = XFLOATINT (aggressive);
14389
14390 pt_offset = float_amount * WINDOW_BOX_TEXT_HEIGHT (w);
14391 if (pt_offset == 0 && float_amount > 0)
14392 pt_offset = 1;
14393 if (pt_offset)
14394 margin -= 1;
14395 }
14396 /* Compute how much to move the window start backward from
14397 point so that point will be displayed where the user
14398 wants it. */
14399 if (scrolling_up)
14400 {
14401 centering_position = it.last_visible_y;
14402 if (pt_offset)
14403 centering_position -= pt_offset;
14404 centering_position -=
14405 FRAME_LINE_HEIGHT (f) * (1 + margin + (last_line_misfit != 0));
14406 /* Don't let point enter the scroll margin near top of
14407 the window. */
14408 if (centering_position < margin * FRAME_LINE_HEIGHT (f))
14409 centering_position = margin * FRAME_LINE_HEIGHT (f);
14410 }
14411 else
14412 centering_position = margin * FRAME_LINE_HEIGHT (f) + pt_offset;
14413 }
14414 else
14415 /* Set the window start half the height of the window backward
14416 from point. */
14417 centering_position = window_box_height (w) / 2;
14418 }
14419 move_it_vertically_backward (&it, centering_position);
14420
14421 xassert (IT_CHARPOS (it) >= BEGV);
14422
14423 /* The function move_it_vertically_backward may move over more
14424 than the specified y-distance. If it->w is small, e.g. a
14425 mini-buffer window, we may end up in front of the window's
14426 display area. Start displaying at the start of the line
14427 containing PT in this case. */
14428 if (it.current_y <= 0)
14429 {
14430 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
14431 move_it_vertically_backward (&it, 0);
14432 it.current_y = 0;
14433 }
14434
14435 it.current_x = it.hpos = 0;
14436
14437 /* Set the window start position here explicitly, to avoid an
14438 infinite loop in case the functions in window-scroll-functions
14439 get errors. */
14440 set_marker_both (w->start, Qnil, IT_CHARPOS (it), IT_BYTEPOS (it));
14441
14442 /* Run scroll hooks. */
14443 startp = run_window_scroll_functions (window, it.current.pos);
14444
14445 /* Redisplay the window. */
14446 if (!current_matrix_up_to_date_p
14447 || windows_or_buffers_changed
14448 || cursor_type_changed
14449 /* Don't use try_window_reusing_current_matrix in this case
14450 because it can have changed the buffer. */
14451 || !NILP (Vwindow_scroll_functions)
14452 || !just_this_one_p
14453 || MINI_WINDOW_P (w)
14454 || !(used_current_matrix_p
14455 = try_window_reusing_current_matrix (w)))
14456 try_window (window, startp, 0);
14457
14458 /* If new fonts have been loaded (due to fontsets), give up. We
14459 have to start a new redisplay since we need to re-adjust glyph
14460 matrices. */
14461 if (fonts_changed_p)
14462 goto need_larger_matrices;
14463
14464 /* If cursor did not appear assume that the middle of the window is
14465 in the first line of the window. Do it again with the next line.
14466 (Imagine a window of height 100, displaying two lines of height
14467 60. Moving back 50 from it->last_visible_y will end in the first
14468 line.) */
14469 if (w->cursor.vpos < 0)
14470 {
14471 if (!NILP (w->window_end_valid)
14472 && PT >= Z - XFASTINT (w->window_end_pos))
14473 {
14474 clear_glyph_matrix (w->desired_matrix);
14475 move_it_by_lines (&it, 1);
14476 try_window (window, it.current.pos, 0);
14477 }
14478 else if (PT < IT_CHARPOS (it))
14479 {
14480 clear_glyph_matrix (w->desired_matrix);
14481 move_it_by_lines (&it, -1);
14482 try_window (window, it.current.pos, 0);
14483 }
14484 else
14485 {
14486 /* Not much we can do about it. */
14487 }
14488 }
14489
14490 /* Consider the following case: Window starts at BEGV, there is
14491 invisible, intangible text at BEGV, so that display starts at
14492 some point START > BEGV. It can happen that we are called with
14493 PT somewhere between BEGV and START. Try to handle that case. */
14494 if (w->cursor.vpos < 0)
14495 {
14496 struct glyph_row *row = w->current_matrix->rows;
14497 if (row->mode_line_p)
14498 ++row;
14499 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
14500 }
14501
14502 if (!cursor_row_fully_visible_p (w, 0, 0))
14503 {
14504 /* If vscroll is enabled, disable it and try again. */
14505 if (w->vscroll)
14506 {
14507 w->vscroll = 0;
14508 clear_glyph_matrix (w->desired_matrix);
14509 goto recenter;
14510 }
14511
14512 /* If centering point failed to make the whole line visible,
14513 put point at the top instead. That has to make the whole line
14514 visible, if it can be done. */
14515 if (centering_position == 0)
14516 goto done;
14517
14518 clear_glyph_matrix (w->desired_matrix);
14519 centering_position = 0;
14520 goto recenter;
14521 }
14522
14523 done:
14524
14525 SET_TEXT_POS_FROM_MARKER (startp, w->start);
14526 w->start_at_line_beg = ((CHARPOS (startp) == BEGV
14527 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n')
14528 ? Qt : Qnil);
14529
14530 /* Display the mode line, if we must. */
14531 if ((update_mode_line
14532 /* If window not full width, must redo its mode line
14533 if (a) the window to its side is being redone and
14534 (b) we do a frame-based redisplay. This is a consequence
14535 of how inverted lines are drawn in frame-based redisplay. */
14536 || (!just_this_one_p
14537 && !FRAME_WINDOW_P (f)
14538 && !WINDOW_FULL_WIDTH_P (w))
14539 /* Line number to display. */
14540 || INTEGERP (w->base_line_pos)
14541 /* Column number is displayed and different from the one displayed. */
14542 || (!NILP (w->column_number_displayed)
14543 && (XFASTINT (w->column_number_displayed) != current_column ())))
14544 /* This means that the window has a mode line. */
14545 && (WINDOW_WANTS_MODELINE_P (w)
14546 || WINDOW_WANTS_HEADER_LINE_P (w)))
14547 {
14548 display_mode_lines (w);
14549
14550 /* If mode line height has changed, arrange for a thorough
14551 immediate redisplay using the correct mode line height. */
14552 if (WINDOW_WANTS_MODELINE_P (w)
14553 && CURRENT_MODE_LINE_HEIGHT (w) != DESIRED_MODE_LINE_HEIGHT (w))
14554 {
14555 fonts_changed_p = 1;
14556 MATRIX_MODE_LINE_ROW (w->current_matrix)->height
14557 = DESIRED_MODE_LINE_HEIGHT (w);
14558 }
14559
14560 /* If header line height has changed, arrange for a thorough
14561 immediate redisplay using the correct header line height. */
14562 if (WINDOW_WANTS_HEADER_LINE_P (w)
14563 && CURRENT_HEADER_LINE_HEIGHT (w) != DESIRED_HEADER_LINE_HEIGHT (w))
14564 {
14565 fonts_changed_p = 1;
14566 MATRIX_HEADER_LINE_ROW (w->current_matrix)->height
14567 = DESIRED_HEADER_LINE_HEIGHT (w);
14568 }
14569
14570 if (fonts_changed_p)
14571 goto need_larger_matrices;
14572 }
14573
14574 if (!line_number_displayed
14575 && !BUFFERP (w->base_line_pos))
14576 {
14577 w->base_line_pos = Qnil;
14578 w->base_line_number = Qnil;
14579 }
14580
14581 finish_menu_bars:
14582
14583 /* When we reach a frame's selected window, redo the frame's menu bar. */
14584 if (update_mode_line
14585 && EQ (FRAME_SELECTED_WINDOW (f), window))
14586 {
14587 int redisplay_menu_p = 0;
14588
14589 if (FRAME_WINDOW_P (f))
14590 {
14591 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
14592 || defined (HAVE_NS) || defined (USE_GTK)
14593 redisplay_menu_p = FRAME_EXTERNAL_MENU_BAR (f);
14594 #else
14595 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
14596 #endif
14597 }
14598 else
14599 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
14600
14601 if (redisplay_menu_p)
14602 display_menu_bar (w);
14603
14604 #ifdef HAVE_WINDOW_SYSTEM
14605 if (FRAME_WINDOW_P (f))
14606 {
14607 #if defined (USE_GTK) || defined (HAVE_NS)
14608 if (FRAME_EXTERNAL_TOOL_BAR (f))
14609 redisplay_tool_bar (f);
14610 #else
14611 if (WINDOWP (f->tool_bar_window)
14612 && (FRAME_TOOL_BAR_LINES (f) > 0
14613 || !NILP (Vauto_resize_tool_bars))
14614 && redisplay_tool_bar (f))
14615 ignore_mouse_drag_p = 1;
14616 #endif
14617 }
14618 #endif
14619 }
14620
14621 #ifdef HAVE_WINDOW_SYSTEM
14622 if (FRAME_WINDOW_P (f)
14623 && update_window_fringes (w, (just_this_one_p
14624 || (!used_current_matrix_p && !overlay_arrow_seen)
14625 || w->pseudo_window_p)))
14626 {
14627 update_begin (f);
14628 BLOCK_INPUT;
14629 if (draw_window_fringes (w, 1))
14630 x_draw_vertical_border (w);
14631 UNBLOCK_INPUT;
14632 update_end (f);
14633 }
14634 #endif /* HAVE_WINDOW_SYSTEM */
14635
14636 /* We go to this label, with fonts_changed_p nonzero,
14637 if it is necessary to try again using larger glyph matrices.
14638 We have to redeem the scroll bar even in this case,
14639 because the loop in redisplay_internal expects that. */
14640 need_larger_matrices:
14641 ;
14642 finish_scroll_bars:
14643
14644 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
14645 {
14646 /* Set the thumb's position and size. */
14647 set_vertical_scroll_bar (w);
14648
14649 /* Note that we actually used the scroll bar attached to this
14650 window, so it shouldn't be deleted at the end of redisplay. */
14651 if (FRAME_TERMINAL (f)->redeem_scroll_bar_hook)
14652 (*FRAME_TERMINAL (f)->redeem_scroll_bar_hook) (w);
14653 }
14654
14655 /* Restore current_buffer and value of point in it. The window
14656 update may have changed the buffer, so first make sure `opoint'
14657 is still valid (Bug#6177). */
14658 if (CHARPOS (opoint) < BEGV)
14659 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
14660 else if (CHARPOS (opoint) > ZV)
14661 TEMP_SET_PT_BOTH (Z, Z_BYTE);
14662 else
14663 TEMP_SET_PT_BOTH (CHARPOS (opoint), BYTEPOS (opoint));
14664
14665 set_buffer_internal_1 (old);
14666 /* Avoid an abort in TEMP_SET_PT_BOTH if the buffer has become
14667 shorter. This can be caused by log truncation in *Messages*. */
14668 if (CHARPOS (lpoint) <= ZV)
14669 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
14670
14671 unbind_to (count, Qnil);
14672 }
14673
14674
14675 /* Build the complete desired matrix of WINDOW with a window start
14676 buffer position POS.
14677
14678 Value is 1 if successful. It is zero if fonts were loaded during
14679 redisplay which makes re-adjusting glyph matrices necessary, and -1
14680 if point would appear in the scroll margins.
14681 (We check the former only if TRY_WINDOW_IGNORE_FONTS_CHANGE is
14682 unset in FLAGS, and the latter only if TRY_WINDOW_CHECK_MARGINS is
14683 set in FLAGS.) */
14684
14685 int
14686 try_window (Lisp_Object window, struct text_pos pos, int flags)
14687 {
14688 struct window *w = XWINDOW (window);
14689 struct it it;
14690 struct glyph_row *last_text_row = NULL;
14691 struct frame *f = XFRAME (w->frame);
14692
14693 /* Make POS the new window start. */
14694 set_marker_both (w->start, Qnil, CHARPOS (pos), BYTEPOS (pos));
14695
14696 /* Mark cursor position as unknown. No overlay arrow seen. */
14697 w->cursor.vpos = -1;
14698 overlay_arrow_seen = 0;
14699
14700 /* Initialize iterator and info to start at POS. */
14701 start_display (&it, w, pos);
14702
14703 /* Display all lines of W. */
14704 while (it.current_y < it.last_visible_y)
14705 {
14706 if (display_line (&it))
14707 last_text_row = it.glyph_row - 1;
14708 if (fonts_changed_p && !(flags & TRY_WINDOW_IGNORE_FONTS_CHANGE))
14709 return 0;
14710 }
14711
14712 /* Don't let the cursor end in the scroll margins. */
14713 if ((flags & TRY_WINDOW_CHECK_MARGINS)
14714 && !MINI_WINDOW_P (w))
14715 {
14716 int this_scroll_margin;
14717
14718 if (scroll_margin > 0)
14719 {
14720 this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
14721 this_scroll_margin *= FRAME_LINE_HEIGHT (f);
14722 }
14723 else
14724 this_scroll_margin = 0;
14725
14726 if ((w->cursor.y >= 0 /* not vscrolled */
14727 && w->cursor.y < this_scroll_margin
14728 && CHARPOS (pos) > BEGV
14729 && IT_CHARPOS (it) < ZV)
14730 /* rms: considering make_cursor_line_fully_visible_p here
14731 seems to give wrong results. We don't want to recenter
14732 when the last line is partly visible, we want to allow
14733 that case to be handled in the usual way. */
14734 || w->cursor.y > it.last_visible_y - this_scroll_margin - 1)
14735 {
14736 w->cursor.vpos = -1;
14737 clear_glyph_matrix (w->desired_matrix);
14738 return -1;
14739 }
14740 }
14741
14742 /* If bottom moved off end of frame, change mode line percentage. */
14743 if (XFASTINT (w->window_end_pos) <= 0
14744 && Z != IT_CHARPOS (it))
14745 w->update_mode_line = Qt;
14746
14747 /* Set window_end_pos to the offset of the last character displayed
14748 on the window from the end of current_buffer. Set
14749 window_end_vpos to its row number. */
14750 if (last_text_row)
14751 {
14752 xassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row));
14753 w->window_end_bytepos
14754 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
14755 w->window_end_pos
14756 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
14757 w->window_end_vpos
14758 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
14759 xassert (MATRIX_ROW (w->desired_matrix, XFASTINT (w->window_end_vpos))
14760 ->displays_text_p);
14761 }
14762 else
14763 {
14764 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
14765 w->window_end_pos = make_number (Z - ZV);
14766 w->window_end_vpos = make_number (0);
14767 }
14768
14769 /* But that is not valid info until redisplay finishes. */
14770 w->window_end_valid = Qnil;
14771 return 1;
14772 }
14773
14774
14775 \f
14776 /************************************************************************
14777 Window redisplay reusing current matrix when buffer has not changed
14778 ************************************************************************/
14779
14780 /* Try redisplay of window W showing an unchanged buffer with a
14781 different window start than the last time it was displayed by
14782 reusing its current matrix. Value is non-zero if successful.
14783 W->start is the new window start. */
14784
14785 static int
14786 try_window_reusing_current_matrix (struct window *w)
14787 {
14788 struct frame *f = XFRAME (w->frame);
14789 struct glyph_row *bottom_row;
14790 struct it it;
14791 struct run run;
14792 struct text_pos start, new_start;
14793 int nrows_scrolled, i;
14794 struct glyph_row *last_text_row;
14795 struct glyph_row *last_reused_text_row;
14796 struct glyph_row *start_row;
14797 int start_vpos, min_y, max_y;
14798
14799 #if GLYPH_DEBUG
14800 if (inhibit_try_window_reusing)
14801 return 0;
14802 #endif
14803
14804 if (/* This function doesn't handle terminal frames. */
14805 !FRAME_WINDOW_P (f)
14806 /* Don't try to reuse the display if windows have been split
14807 or such. */
14808 || windows_or_buffers_changed
14809 || cursor_type_changed)
14810 return 0;
14811
14812 /* Can't do this if region may have changed. */
14813 if ((!NILP (Vtransient_mark_mode)
14814 && !NILP (BVAR (current_buffer, mark_active)))
14815 || !NILP (w->region_showing)
14816 || !NILP (Vshow_trailing_whitespace))
14817 return 0;
14818
14819 /* If top-line visibility has changed, give up. */
14820 if (WINDOW_WANTS_HEADER_LINE_P (w)
14821 != MATRIX_HEADER_LINE_ROW (w->current_matrix)->mode_line_p)
14822 return 0;
14823
14824 /* Give up if old or new display is scrolled vertically. We could
14825 make this function handle this, but right now it doesn't. */
14826 start_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
14827 if (w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row))
14828 return 0;
14829
14830 /* The variable new_start now holds the new window start. The old
14831 start `start' can be determined from the current matrix. */
14832 SET_TEXT_POS_FROM_MARKER (new_start, w->start);
14833 start = start_row->minpos;
14834 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
14835
14836 /* Clear the desired matrix for the display below. */
14837 clear_glyph_matrix (w->desired_matrix);
14838
14839 if (CHARPOS (new_start) <= CHARPOS (start))
14840 {
14841 /* Don't use this method if the display starts with an ellipsis
14842 displayed for invisible text. It's not easy to handle that case
14843 below, and it's certainly not worth the effort since this is
14844 not a frequent case. */
14845 if (in_ellipses_for_invisible_text_p (&start_row->start, w))
14846 return 0;
14847
14848 IF_DEBUG (debug_method_add (w, "twu1"));
14849
14850 /* Display up to a row that can be reused. The variable
14851 last_text_row is set to the last row displayed that displays
14852 text. Note that it.vpos == 0 if or if not there is a
14853 header-line; it's not the same as the MATRIX_ROW_VPOS! */
14854 start_display (&it, w, new_start);
14855 w->cursor.vpos = -1;
14856 last_text_row = last_reused_text_row = NULL;
14857
14858 while (it.current_y < it.last_visible_y
14859 && !fonts_changed_p)
14860 {
14861 /* If we have reached into the characters in the START row,
14862 that means the line boundaries have changed. So we
14863 can't start copying with the row START. Maybe it will
14864 work to start copying with the following row. */
14865 while (IT_CHARPOS (it) > CHARPOS (start))
14866 {
14867 /* Advance to the next row as the "start". */
14868 start_row++;
14869 start = start_row->minpos;
14870 /* If there are no more rows to try, or just one, give up. */
14871 if (start_row == MATRIX_MODE_LINE_ROW (w->current_matrix) - 1
14872 || w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row)
14873 || CHARPOS (start) == ZV)
14874 {
14875 clear_glyph_matrix (w->desired_matrix);
14876 return 0;
14877 }
14878
14879 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
14880 }
14881 /* If we have reached alignment,
14882 we can copy the rest of the rows. */
14883 if (IT_CHARPOS (it) == CHARPOS (start))
14884 break;
14885
14886 if (display_line (&it))
14887 last_text_row = it.glyph_row - 1;
14888 }
14889
14890 /* A value of current_y < last_visible_y means that we stopped
14891 at the previous window start, which in turn means that we
14892 have at least one reusable row. */
14893 if (it.current_y < it.last_visible_y)
14894 {
14895 struct glyph_row *row;
14896
14897 /* IT.vpos always starts from 0; it counts text lines. */
14898 nrows_scrolled = it.vpos - (start_row - MATRIX_FIRST_TEXT_ROW (w->current_matrix));
14899
14900 /* Find PT if not already found in the lines displayed. */
14901 if (w->cursor.vpos < 0)
14902 {
14903 int dy = it.current_y - start_row->y;
14904
14905 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
14906 row = row_containing_pos (w, PT, row, NULL, dy);
14907 if (row)
14908 set_cursor_from_row (w, row, w->current_matrix, 0, 0,
14909 dy, nrows_scrolled);
14910 else
14911 {
14912 clear_glyph_matrix (w->desired_matrix);
14913 return 0;
14914 }
14915 }
14916
14917 /* Scroll the display. Do it before the current matrix is
14918 changed. The problem here is that update has not yet
14919 run, i.e. part of the current matrix is not up to date.
14920 scroll_run_hook will clear the cursor, and use the
14921 current matrix to get the height of the row the cursor is
14922 in. */
14923 run.current_y = start_row->y;
14924 run.desired_y = it.current_y;
14925 run.height = it.last_visible_y - it.current_y;
14926
14927 if (run.height > 0 && run.current_y != run.desired_y)
14928 {
14929 update_begin (f);
14930 FRAME_RIF (f)->update_window_begin_hook (w);
14931 FRAME_RIF (f)->clear_window_mouse_face (w);
14932 FRAME_RIF (f)->scroll_run_hook (w, &run);
14933 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
14934 update_end (f);
14935 }
14936
14937 /* Shift current matrix down by nrows_scrolled lines. */
14938 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
14939 rotate_matrix (w->current_matrix,
14940 start_vpos,
14941 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
14942 nrows_scrolled);
14943
14944 /* Disable lines that must be updated. */
14945 for (i = 0; i < nrows_scrolled; ++i)
14946 (start_row + i)->enabled_p = 0;
14947
14948 /* Re-compute Y positions. */
14949 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
14950 max_y = it.last_visible_y;
14951 for (row = start_row + nrows_scrolled;
14952 row < bottom_row;
14953 ++row)
14954 {
14955 row->y = it.current_y;
14956 row->visible_height = row->height;
14957
14958 if (row->y < min_y)
14959 row->visible_height -= min_y - row->y;
14960 if (row->y + row->height > max_y)
14961 row->visible_height -= row->y + row->height - max_y;
14962 row->redraw_fringe_bitmaps_p = 1;
14963
14964 it.current_y += row->height;
14965
14966 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
14967 last_reused_text_row = row;
14968 if (MATRIX_ROW_BOTTOM_Y (row) >= it.last_visible_y)
14969 break;
14970 }
14971
14972 /* Disable lines in the current matrix which are now
14973 below the window. */
14974 for (++row; row < bottom_row; ++row)
14975 row->enabled_p = row->mode_line_p = 0;
14976 }
14977
14978 /* Update window_end_pos etc.; last_reused_text_row is the last
14979 reused row from the current matrix containing text, if any.
14980 The value of last_text_row is the last displayed line
14981 containing text. */
14982 if (last_reused_text_row)
14983 {
14984 w->window_end_bytepos
14985 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_reused_text_row);
14986 w->window_end_pos
14987 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_reused_text_row));
14988 w->window_end_vpos
14989 = make_number (MATRIX_ROW_VPOS (last_reused_text_row,
14990 w->current_matrix));
14991 }
14992 else if (last_text_row)
14993 {
14994 w->window_end_bytepos
14995 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
14996 w->window_end_pos
14997 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
14998 w->window_end_vpos
14999 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
15000 }
15001 else
15002 {
15003 /* This window must be completely empty. */
15004 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
15005 w->window_end_pos = make_number (Z - ZV);
15006 w->window_end_vpos = make_number (0);
15007 }
15008 w->window_end_valid = Qnil;
15009
15010 /* Update hint: don't try scrolling again in update_window. */
15011 w->desired_matrix->no_scrolling_p = 1;
15012
15013 #if GLYPH_DEBUG
15014 debug_method_add (w, "try_window_reusing_current_matrix 1");
15015 #endif
15016 return 1;
15017 }
15018 else if (CHARPOS (new_start) > CHARPOS (start))
15019 {
15020 struct glyph_row *pt_row, *row;
15021 struct glyph_row *first_reusable_row;
15022 struct glyph_row *first_row_to_display;
15023 int dy;
15024 int yb = window_text_bottom_y (w);
15025
15026 /* Find the row starting at new_start, if there is one. Don't
15027 reuse a partially visible line at the end. */
15028 first_reusable_row = start_row;
15029 while (first_reusable_row->enabled_p
15030 && MATRIX_ROW_BOTTOM_Y (first_reusable_row) < yb
15031 && (MATRIX_ROW_START_CHARPOS (first_reusable_row)
15032 < CHARPOS (new_start)))
15033 ++first_reusable_row;
15034
15035 /* Give up if there is no row to reuse. */
15036 if (MATRIX_ROW_BOTTOM_Y (first_reusable_row) >= yb
15037 || !first_reusable_row->enabled_p
15038 || (MATRIX_ROW_START_CHARPOS (first_reusable_row)
15039 != CHARPOS (new_start)))
15040 return 0;
15041
15042 /* We can reuse fully visible rows beginning with
15043 first_reusable_row to the end of the window. Set
15044 first_row_to_display to the first row that cannot be reused.
15045 Set pt_row to the row containing point, if there is any. */
15046 pt_row = NULL;
15047 for (first_row_to_display = first_reusable_row;
15048 MATRIX_ROW_BOTTOM_Y (first_row_to_display) < yb;
15049 ++first_row_to_display)
15050 {
15051 if (PT >= MATRIX_ROW_START_CHARPOS (first_row_to_display)
15052 && PT < MATRIX_ROW_END_CHARPOS (first_row_to_display))
15053 pt_row = first_row_to_display;
15054 }
15055
15056 /* Start displaying at the start of first_row_to_display. */
15057 xassert (first_row_to_display->y < yb);
15058 init_to_row_start (&it, w, first_row_to_display);
15059
15060 nrows_scrolled = (MATRIX_ROW_VPOS (first_reusable_row, w->current_matrix)
15061 - start_vpos);
15062 it.vpos = (MATRIX_ROW_VPOS (first_row_to_display, w->current_matrix)
15063 - nrows_scrolled);
15064 it.current_y = (first_row_to_display->y - first_reusable_row->y
15065 + WINDOW_HEADER_LINE_HEIGHT (w));
15066
15067 /* Display lines beginning with first_row_to_display in the
15068 desired matrix. Set last_text_row to the last row displayed
15069 that displays text. */
15070 it.glyph_row = MATRIX_ROW (w->desired_matrix, it.vpos);
15071 if (pt_row == NULL)
15072 w->cursor.vpos = -1;
15073 last_text_row = NULL;
15074 while (it.current_y < it.last_visible_y && !fonts_changed_p)
15075 if (display_line (&it))
15076 last_text_row = it.glyph_row - 1;
15077
15078 /* If point is in a reused row, adjust y and vpos of the cursor
15079 position. */
15080 if (pt_row)
15081 {
15082 w->cursor.vpos -= nrows_scrolled;
15083 w->cursor.y -= first_reusable_row->y - start_row->y;
15084 }
15085
15086 /* Give up if point isn't in a row displayed or reused. (This
15087 also handles the case where w->cursor.vpos < nrows_scrolled
15088 after the calls to display_line, which can happen with scroll
15089 margins. See bug#1295.) */
15090 if (w->cursor.vpos < 0)
15091 {
15092 clear_glyph_matrix (w->desired_matrix);
15093 return 0;
15094 }
15095
15096 /* Scroll the display. */
15097 run.current_y = first_reusable_row->y;
15098 run.desired_y = WINDOW_HEADER_LINE_HEIGHT (w);
15099 run.height = it.last_visible_y - run.current_y;
15100 dy = run.current_y - run.desired_y;
15101
15102 if (run.height)
15103 {
15104 update_begin (f);
15105 FRAME_RIF (f)->update_window_begin_hook (w);
15106 FRAME_RIF (f)->clear_window_mouse_face (w);
15107 FRAME_RIF (f)->scroll_run_hook (w, &run);
15108 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
15109 update_end (f);
15110 }
15111
15112 /* Adjust Y positions of reused rows. */
15113 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
15114 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
15115 max_y = it.last_visible_y;
15116 for (row = first_reusable_row; row < first_row_to_display; ++row)
15117 {
15118 row->y -= dy;
15119 row->visible_height = row->height;
15120 if (row->y < min_y)
15121 row->visible_height -= min_y - row->y;
15122 if (row->y + row->height > max_y)
15123 row->visible_height -= row->y + row->height - max_y;
15124 row->redraw_fringe_bitmaps_p = 1;
15125 }
15126
15127 /* Scroll the current matrix. */
15128 xassert (nrows_scrolled > 0);
15129 rotate_matrix (w->current_matrix,
15130 start_vpos,
15131 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
15132 -nrows_scrolled);
15133
15134 /* Disable rows not reused. */
15135 for (row -= nrows_scrolled; row < bottom_row; ++row)
15136 row->enabled_p = 0;
15137
15138 /* Point may have moved to a different line, so we cannot assume that
15139 the previous cursor position is valid; locate the correct row. */
15140 if (pt_row)
15141 {
15142 for (row = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
15143 row < bottom_row && PT >= MATRIX_ROW_END_CHARPOS (row);
15144 row++)
15145 {
15146 w->cursor.vpos++;
15147 w->cursor.y = row->y;
15148 }
15149 if (row < bottom_row)
15150 {
15151 struct glyph *glyph = row->glyphs[TEXT_AREA] + w->cursor.hpos;
15152 struct glyph *end = glyph + row->used[TEXT_AREA];
15153
15154 /* Can't use this optimization with bidi-reordered glyph
15155 rows, unless cursor is already at point. */
15156 if (!NILP (BVAR (XBUFFER (w->buffer), bidi_display_reordering)))
15157 {
15158 if (!(w->cursor.hpos >= 0
15159 && w->cursor.hpos < row->used[TEXT_AREA]
15160 && BUFFERP (glyph->object)
15161 && glyph->charpos == PT))
15162 return 0;
15163 }
15164 else
15165 for (; glyph < end
15166 && (!BUFFERP (glyph->object)
15167 || glyph->charpos < PT);
15168 glyph++)
15169 {
15170 w->cursor.hpos++;
15171 w->cursor.x += glyph->pixel_width;
15172 }
15173 }
15174 }
15175
15176 /* Adjust window end. A null value of last_text_row means that
15177 the window end is in reused rows which in turn means that
15178 only its vpos can have changed. */
15179 if (last_text_row)
15180 {
15181 w->window_end_bytepos
15182 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
15183 w->window_end_pos
15184 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
15185 w->window_end_vpos
15186 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
15187 }
15188 else
15189 {
15190 w->window_end_vpos
15191 = make_number (XFASTINT (w->window_end_vpos) - nrows_scrolled);
15192 }
15193
15194 w->window_end_valid = Qnil;
15195 w->desired_matrix->no_scrolling_p = 1;
15196
15197 #if GLYPH_DEBUG
15198 debug_method_add (w, "try_window_reusing_current_matrix 2");
15199 #endif
15200 return 1;
15201 }
15202
15203 return 0;
15204 }
15205
15206
15207 \f
15208 /************************************************************************
15209 Window redisplay reusing current matrix when buffer has changed
15210 ************************************************************************/
15211
15212 static struct glyph_row *find_last_unchanged_at_beg_row (struct window *);
15213 static struct glyph_row *find_first_unchanged_at_end_row (struct window *,
15214 EMACS_INT *, EMACS_INT *);
15215 static struct glyph_row *
15216 find_last_row_displaying_text (struct glyph_matrix *, struct it *,
15217 struct glyph_row *);
15218
15219
15220 /* Return the last row in MATRIX displaying text. If row START is
15221 non-null, start searching with that row. IT gives the dimensions
15222 of the display. Value is null if matrix is empty; otherwise it is
15223 a pointer to the row found. */
15224
15225 static struct glyph_row *
15226 find_last_row_displaying_text (struct glyph_matrix *matrix, struct it *it,
15227 struct glyph_row *start)
15228 {
15229 struct glyph_row *row, *row_found;
15230
15231 /* Set row_found to the last row in IT->w's current matrix
15232 displaying text. The loop looks funny but think of partially
15233 visible lines. */
15234 row_found = NULL;
15235 row = start ? start : MATRIX_FIRST_TEXT_ROW (matrix);
15236 while (MATRIX_ROW_DISPLAYS_TEXT_P (row))
15237 {
15238 xassert (row->enabled_p);
15239 row_found = row;
15240 if (MATRIX_ROW_BOTTOM_Y (row) >= it->last_visible_y)
15241 break;
15242 ++row;
15243 }
15244
15245 return row_found;
15246 }
15247
15248
15249 /* Return the last row in the current matrix of W that is not affected
15250 by changes at the start of current_buffer that occurred since W's
15251 current matrix was built. Value is null if no such row exists.
15252
15253 BEG_UNCHANGED us the number of characters unchanged at the start of
15254 current_buffer. BEG + BEG_UNCHANGED is the buffer position of the
15255 first changed character in current_buffer. Characters at positions <
15256 BEG + BEG_UNCHANGED are at the same buffer positions as they were
15257 when the current matrix was built. */
15258
15259 static struct glyph_row *
15260 find_last_unchanged_at_beg_row (struct window *w)
15261 {
15262 EMACS_INT first_changed_pos = BEG + BEG_UNCHANGED;
15263 struct glyph_row *row;
15264 struct glyph_row *row_found = NULL;
15265 int yb = window_text_bottom_y (w);
15266
15267 /* Find the last row displaying unchanged text. */
15268 for (row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
15269 MATRIX_ROW_DISPLAYS_TEXT_P (row)
15270 && MATRIX_ROW_START_CHARPOS (row) < first_changed_pos;
15271 ++row)
15272 {
15273 if (/* If row ends before first_changed_pos, it is unchanged,
15274 except in some case. */
15275 MATRIX_ROW_END_CHARPOS (row) <= first_changed_pos
15276 /* When row ends in ZV and we write at ZV it is not
15277 unchanged. */
15278 && !row->ends_at_zv_p
15279 /* When first_changed_pos is the end of a continued line,
15280 row is not unchanged because it may be no longer
15281 continued. */
15282 && !(MATRIX_ROW_END_CHARPOS (row) == first_changed_pos
15283 && (row->continued_p
15284 || row->exact_window_width_line_p)))
15285 row_found = row;
15286
15287 /* Stop if last visible row. */
15288 if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
15289 break;
15290 }
15291
15292 return row_found;
15293 }
15294
15295
15296 /* Find the first glyph row in the current matrix of W that is not
15297 affected by changes at the end of current_buffer since the
15298 time W's current matrix was built.
15299
15300 Return in *DELTA the number of chars by which buffer positions in
15301 unchanged text at the end of current_buffer must be adjusted.
15302
15303 Return in *DELTA_BYTES the corresponding number of bytes.
15304
15305 Value is null if no such row exists, i.e. all rows are affected by
15306 changes. */
15307
15308 static struct glyph_row *
15309 find_first_unchanged_at_end_row (struct window *w,
15310 EMACS_INT *delta, EMACS_INT *delta_bytes)
15311 {
15312 struct glyph_row *row;
15313 struct glyph_row *row_found = NULL;
15314
15315 *delta = *delta_bytes = 0;
15316
15317 /* Display must not have been paused, otherwise the current matrix
15318 is not up to date. */
15319 eassert (!NILP (w->window_end_valid));
15320
15321 /* A value of window_end_pos >= END_UNCHANGED means that the window
15322 end is in the range of changed text. If so, there is no
15323 unchanged row at the end of W's current matrix. */
15324 if (XFASTINT (w->window_end_pos) >= END_UNCHANGED)
15325 return NULL;
15326
15327 /* Set row to the last row in W's current matrix displaying text. */
15328 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
15329
15330 /* If matrix is entirely empty, no unchanged row exists. */
15331 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
15332 {
15333 /* The value of row is the last glyph row in the matrix having a
15334 meaningful buffer position in it. The end position of row
15335 corresponds to window_end_pos. This allows us to translate
15336 buffer positions in the current matrix to current buffer
15337 positions for characters not in changed text. */
15338 EMACS_INT Z_old =
15339 MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
15340 EMACS_INT Z_BYTE_old =
15341 MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
15342 EMACS_INT last_unchanged_pos, last_unchanged_pos_old;
15343 struct glyph_row *first_text_row
15344 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
15345
15346 *delta = Z - Z_old;
15347 *delta_bytes = Z_BYTE - Z_BYTE_old;
15348
15349 /* Set last_unchanged_pos to the buffer position of the last
15350 character in the buffer that has not been changed. Z is the
15351 index + 1 of the last character in current_buffer, i.e. by
15352 subtracting END_UNCHANGED we get the index of the last
15353 unchanged character, and we have to add BEG to get its buffer
15354 position. */
15355 last_unchanged_pos = Z - END_UNCHANGED + BEG;
15356 last_unchanged_pos_old = last_unchanged_pos - *delta;
15357
15358 /* Search backward from ROW for a row displaying a line that
15359 starts at a minimum position >= last_unchanged_pos_old. */
15360 for (; row > first_text_row; --row)
15361 {
15362 /* This used to abort, but it can happen.
15363 It is ok to just stop the search instead here. KFS. */
15364 if (!row->enabled_p || !MATRIX_ROW_DISPLAYS_TEXT_P (row))
15365 break;
15366
15367 if (MATRIX_ROW_START_CHARPOS (row) >= last_unchanged_pos_old)
15368 row_found = row;
15369 }
15370 }
15371
15372 eassert (!row_found || MATRIX_ROW_DISPLAYS_TEXT_P (row_found));
15373
15374 return row_found;
15375 }
15376
15377
15378 /* Make sure that glyph rows in the current matrix of window W
15379 reference the same glyph memory as corresponding rows in the
15380 frame's frame matrix. This function is called after scrolling W's
15381 current matrix on a terminal frame in try_window_id and
15382 try_window_reusing_current_matrix. */
15383
15384 static void
15385 sync_frame_with_window_matrix_rows (struct window *w)
15386 {
15387 struct frame *f = XFRAME (w->frame);
15388 struct glyph_row *window_row, *window_row_end, *frame_row;
15389
15390 /* Preconditions: W must be a leaf window and full-width. Its frame
15391 must have a frame matrix. */
15392 xassert (NILP (w->hchild) && NILP (w->vchild));
15393 xassert (WINDOW_FULL_WIDTH_P (w));
15394 xassert (!FRAME_WINDOW_P (f));
15395
15396 /* If W is a full-width window, glyph pointers in W's current matrix
15397 have, by definition, to be the same as glyph pointers in the
15398 corresponding frame matrix. Note that frame matrices have no
15399 marginal areas (see build_frame_matrix). */
15400 window_row = w->current_matrix->rows;
15401 window_row_end = window_row + w->current_matrix->nrows;
15402 frame_row = f->current_matrix->rows + WINDOW_TOP_EDGE_LINE (w);
15403 while (window_row < window_row_end)
15404 {
15405 struct glyph *start = window_row->glyphs[LEFT_MARGIN_AREA];
15406 struct glyph *end = window_row->glyphs[LAST_AREA];
15407
15408 frame_row->glyphs[LEFT_MARGIN_AREA] = start;
15409 frame_row->glyphs[TEXT_AREA] = start;
15410 frame_row->glyphs[RIGHT_MARGIN_AREA] = end;
15411 frame_row->glyphs[LAST_AREA] = end;
15412
15413 /* Disable frame rows whose corresponding window rows have
15414 been disabled in try_window_id. */
15415 if (!window_row->enabled_p)
15416 frame_row->enabled_p = 0;
15417
15418 ++window_row, ++frame_row;
15419 }
15420 }
15421
15422
15423 /* Find the glyph row in window W containing CHARPOS. Consider all
15424 rows between START and END (not inclusive). END null means search
15425 all rows to the end of the display area of W. Value is the row
15426 containing CHARPOS or null. */
15427
15428 struct glyph_row *
15429 row_containing_pos (struct window *w, EMACS_INT charpos,
15430 struct glyph_row *start, struct glyph_row *end, int dy)
15431 {
15432 struct glyph_row *row = start;
15433 struct glyph_row *best_row = NULL;
15434 EMACS_INT mindif = BUF_ZV (XBUFFER (w->buffer)) + 1;
15435 int last_y;
15436
15437 /* If we happen to start on a header-line, skip that. */
15438 if (row->mode_line_p)
15439 ++row;
15440
15441 if ((end && row >= end) || !row->enabled_p)
15442 return NULL;
15443
15444 last_y = window_text_bottom_y (w) - dy;
15445
15446 while (1)
15447 {
15448 /* Give up if we have gone too far. */
15449 if (end && row >= end)
15450 return NULL;
15451 /* This formerly returned if they were equal.
15452 I think that both quantities are of a "last plus one" type;
15453 if so, when they are equal, the row is within the screen. -- rms. */
15454 if (MATRIX_ROW_BOTTOM_Y (row) > last_y)
15455 return NULL;
15456
15457 /* If it is in this row, return this row. */
15458 if (! (MATRIX_ROW_END_CHARPOS (row) < charpos
15459 || (MATRIX_ROW_END_CHARPOS (row) == charpos
15460 /* The end position of a row equals the start
15461 position of the next row. If CHARPOS is there, we
15462 would rather display it in the next line, except
15463 when this line ends in ZV. */
15464 && !row->ends_at_zv_p
15465 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
15466 && charpos >= MATRIX_ROW_START_CHARPOS (row))
15467 {
15468 struct glyph *g;
15469
15470 if (NILP (BVAR (XBUFFER (w->buffer), bidi_display_reordering))
15471 || (!best_row && !row->continued_p))
15472 return row;
15473 /* In bidi-reordered rows, there could be several rows
15474 occluding point, all of them belonging to the same
15475 continued line. We need to find the row which fits
15476 CHARPOS the best. */
15477 for (g = row->glyphs[TEXT_AREA];
15478 g < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
15479 g++)
15480 {
15481 if (!STRINGP (g->object))
15482 {
15483 if (g->charpos > 0 && eabs (g->charpos - charpos) < mindif)
15484 {
15485 mindif = eabs (g->charpos - charpos);
15486 best_row = row;
15487 /* Exact match always wins. */
15488 if (mindif == 0)
15489 return best_row;
15490 }
15491 }
15492 }
15493 }
15494 else if (best_row && !row->continued_p)
15495 return best_row;
15496 ++row;
15497 }
15498 }
15499
15500
15501 /* Try to redisplay window W by reusing its existing display. W's
15502 current matrix must be up to date when this function is called,
15503 i.e. window_end_valid must not be nil.
15504
15505 Value is
15506
15507 1 if display has been updated
15508 0 if otherwise unsuccessful
15509 -1 if redisplay with same window start is known not to succeed
15510
15511 The following steps are performed:
15512
15513 1. Find the last row in the current matrix of W that is not
15514 affected by changes at the start of current_buffer. If no such row
15515 is found, give up.
15516
15517 2. Find the first row in W's current matrix that is not affected by
15518 changes at the end of current_buffer. Maybe there is no such row.
15519
15520 3. Display lines beginning with the row + 1 found in step 1 to the
15521 row found in step 2 or, if step 2 didn't find a row, to the end of
15522 the window.
15523
15524 4. If cursor is not known to appear on the window, give up.
15525
15526 5. If display stopped at the row found in step 2, scroll the
15527 display and current matrix as needed.
15528
15529 6. Maybe display some lines at the end of W, if we must. This can
15530 happen under various circumstances, like a partially visible line
15531 becoming fully visible, or because newly displayed lines are displayed
15532 in smaller font sizes.
15533
15534 7. Update W's window end information. */
15535
15536 static int
15537 try_window_id (struct window *w)
15538 {
15539 struct frame *f = XFRAME (w->frame);
15540 struct glyph_matrix *current_matrix = w->current_matrix;
15541 struct glyph_matrix *desired_matrix = w->desired_matrix;
15542 struct glyph_row *last_unchanged_at_beg_row;
15543 struct glyph_row *first_unchanged_at_end_row;
15544 struct glyph_row *row;
15545 struct glyph_row *bottom_row;
15546 int bottom_vpos;
15547 struct it it;
15548 EMACS_INT delta = 0, delta_bytes = 0, stop_pos;
15549 int dvpos, dy;
15550 struct text_pos start_pos;
15551 struct run run;
15552 int first_unchanged_at_end_vpos = 0;
15553 struct glyph_row *last_text_row, *last_text_row_at_end;
15554 struct text_pos start;
15555 EMACS_INT first_changed_charpos, last_changed_charpos;
15556
15557 #if GLYPH_DEBUG
15558 if (inhibit_try_window_id)
15559 return 0;
15560 #endif
15561
15562 /* This is handy for debugging. */
15563 #if 0
15564 #define GIVE_UP(X) \
15565 do { \
15566 fprintf (stderr, "try_window_id give up %d\n", (X)); \
15567 return 0; \
15568 } while (0)
15569 #else
15570 #define GIVE_UP(X) return 0
15571 #endif
15572
15573 SET_TEXT_POS_FROM_MARKER (start, w->start);
15574
15575 /* Don't use this for mini-windows because these can show
15576 messages and mini-buffers, and we don't handle that here. */
15577 if (MINI_WINDOW_P (w))
15578 GIVE_UP (1);
15579
15580 /* This flag is used to prevent redisplay optimizations. */
15581 if (windows_or_buffers_changed || cursor_type_changed)
15582 GIVE_UP (2);
15583
15584 /* Verify that narrowing has not changed.
15585 Also verify that we were not told to prevent redisplay optimizations.
15586 It would be nice to further
15587 reduce the number of cases where this prevents try_window_id. */
15588 if (current_buffer->clip_changed
15589 || current_buffer->prevent_redisplay_optimizations_p)
15590 GIVE_UP (3);
15591
15592 /* Window must either use window-based redisplay or be full width. */
15593 if (!FRAME_WINDOW_P (f)
15594 && (!FRAME_LINE_INS_DEL_OK (f)
15595 || !WINDOW_FULL_WIDTH_P (w)))
15596 GIVE_UP (4);
15597
15598 /* Give up if point is known NOT to appear in W. */
15599 if (PT < CHARPOS (start))
15600 GIVE_UP (5);
15601
15602 /* Another way to prevent redisplay optimizations. */
15603 if (XFASTINT (w->last_modified) == 0)
15604 GIVE_UP (6);
15605
15606 /* Verify that window is not hscrolled. */
15607 if (XFASTINT (w->hscroll) != 0)
15608 GIVE_UP (7);
15609
15610 /* Verify that display wasn't paused. */
15611 if (NILP (w->window_end_valid))
15612 GIVE_UP (8);
15613
15614 /* Can't use this if highlighting a region because a cursor movement
15615 will do more than just set the cursor. */
15616 if (!NILP (Vtransient_mark_mode)
15617 && !NILP (BVAR (current_buffer, mark_active)))
15618 GIVE_UP (9);
15619
15620 /* Likewise if highlighting trailing whitespace. */
15621 if (!NILP (Vshow_trailing_whitespace))
15622 GIVE_UP (11);
15623
15624 /* Likewise if showing a region. */
15625 if (!NILP (w->region_showing))
15626 GIVE_UP (10);
15627
15628 /* Can't use this if overlay arrow position and/or string have
15629 changed. */
15630 if (overlay_arrows_changed_p ())
15631 GIVE_UP (12);
15632
15633 /* When word-wrap is on, adding a space to the first word of a
15634 wrapped line can change the wrap position, altering the line
15635 above it. It might be worthwhile to handle this more
15636 intelligently, but for now just redisplay from scratch. */
15637 if (!NILP (BVAR (XBUFFER (w->buffer), word_wrap)))
15638 GIVE_UP (21);
15639
15640 /* Under bidi reordering, adding or deleting a character in the
15641 beginning of a paragraph, before the first strong directional
15642 character, can change the base direction of the paragraph (unless
15643 the buffer specifies a fixed paragraph direction), which will
15644 require to redisplay the whole paragraph. It might be worthwhile
15645 to find the paragraph limits and widen the range of redisplayed
15646 lines to that, but for now just give up this optimization and
15647 redisplay from scratch. */
15648 if (!NILP (BVAR (XBUFFER (w->buffer), bidi_display_reordering))
15649 && NILP (BVAR (XBUFFER (w->buffer), bidi_paragraph_direction)))
15650 GIVE_UP (22);
15651
15652 /* Make sure beg_unchanged and end_unchanged are up to date. Do it
15653 only if buffer has really changed. The reason is that the gap is
15654 initially at Z for freshly visited files. The code below would
15655 set end_unchanged to 0 in that case. */
15656 if (MODIFF > SAVE_MODIFF
15657 /* This seems to happen sometimes after saving a buffer. */
15658 || BEG_UNCHANGED + END_UNCHANGED > Z_BYTE)
15659 {
15660 if (GPT - BEG < BEG_UNCHANGED)
15661 BEG_UNCHANGED = GPT - BEG;
15662 if (Z - GPT < END_UNCHANGED)
15663 END_UNCHANGED = Z - GPT;
15664 }
15665
15666 /* The position of the first and last character that has been changed. */
15667 first_changed_charpos = BEG + BEG_UNCHANGED;
15668 last_changed_charpos = Z - END_UNCHANGED;
15669
15670 /* If window starts after a line end, and the last change is in
15671 front of that newline, then changes don't affect the display.
15672 This case happens with stealth-fontification. Note that although
15673 the display is unchanged, glyph positions in the matrix have to
15674 be adjusted, of course. */
15675 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
15676 if (MATRIX_ROW_DISPLAYS_TEXT_P (row)
15677 && ((last_changed_charpos < CHARPOS (start)
15678 && CHARPOS (start) == BEGV)
15679 || (last_changed_charpos < CHARPOS (start) - 1
15680 && FETCH_BYTE (BYTEPOS (start) - 1) == '\n')))
15681 {
15682 EMACS_INT Z_old, Z_delta, Z_BYTE_old, Z_delta_bytes;
15683 struct glyph_row *r0;
15684
15685 /* Compute how many chars/bytes have been added to or removed
15686 from the buffer. */
15687 Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
15688 Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
15689 Z_delta = Z - Z_old;
15690 Z_delta_bytes = Z_BYTE - Z_BYTE_old;
15691
15692 /* Give up if PT is not in the window. Note that it already has
15693 been checked at the start of try_window_id that PT is not in
15694 front of the window start. */
15695 if (PT >= MATRIX_ROW_END_CHARPOS (row) + Z_delta)
15696 GIVE_UP (13);
15697
15698 /* If window start is unchanged, we can reuse the whole matrix
15699 as is, after adjusting glyph positions. No need to compute
15700 the window end again, since its offset from Z hasn't changed. */
15701 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
15702 if (CHARPOS (start) == MATRIX_ROW_START_CHARPOS (r0) + Z_delta
15703 && BYTEPOS (start) == MATRIX_ROW_START_BYTEPOS (r0) + Z_delta_bytes
15704 /* PT must not be in a partially visible line. */
15705 && !(PT >= MATRIX_ROW_START_CHARPOS (row) + Z_delta
15706 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
15707 {
15708 /* Adjust positions in the glyph matrix. */
15709 if (Z_delta || Z_delta_bytes)
15710 {
15711 struct glyph_row *r1
15712 = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
15713 increment_matrix_positions (w->current_matrix,
15714 MATRIX_ROW_VPOS (r0, current_matrix),
15715 MATRIX_ROW_VPOS (r1, current_matrix),
15716 Z_delta, Z_delta_bytes);
15717 }
15718
15719 /* Set the cursor. */
15720 row = row_containing_pos (w, PT, r0, NULL, 0);
15721 if (row)
15722 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
15723 else
15724 abort ();
15725 return 1;
15726 }
15727 }
15728
15729 /* Handle the case that changes are all below what is displayed in
15730 the window, and that PT is in the window. This shortcut cannot
15731 be taken if ZV is visible in the window, and text has been added
15732 there that is visible in the window. */
15733 if (first_changed_charpos >= MATRIX_ROW_END_CHARPOS (row)
15734 /* ZV is not visible in the window, or there are no
15735 changes at ZV, actually. */
15736 && (current_matrix->zv > MATRIX_ROW_END_CHARPOS (row)
15737 || first_changed_charpos == last_changed_charpos))
15738 {
15739 struct glyph_row *r0;
15740
15741 /* Give up if PT is not in the window. Note that it already has
15742 been checked at the start of try_window_id that PT is not in
15743 front of the window start. */
15744 if (PT >= MATRIX_ROW_END_CHARPOS (row))
15745 GIVE_UP (14);
15746
15747 /* If window start is unchanged, we can reuse the whole matrix
15748 as is, without changing glyph positions since no text has
15749 been added/removed in front of the window end. */
15750 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
15751 if (TEXT_POS_EQUAL_P (start, r0->minpos)
15752 /* PT must not be in a partially visible line. */
15753 && !(PT >= MATRIX_ROW_START_CHARPOS (row)
15754 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
15755 {
15756 /* We have to compute the window end anew since text
15757 could have been added/removed after it. */
15758 w->window_end_pos
15759 = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
15760 w->window_end_bytepos
15761 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
15762
15763 /* Set the cursor. */
15764 row = row_containing_pos (w, PT, r0, NULL, 0);
15765 if (row)
15766 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
15767 else
15768 abort ();
15769 return 2;
15770 }
15771 }
15772
15773 /* Give up if window start is in the changed area.
15774
15775 The condition used to read
15776
15777 (BEG_UNCHANGED + END_UNCHANGED != Z - BEG && ...)
15778
15779 but why that was tested escapes me at the moment. */
15780 if (CHARPOS (start) >= first_changed_charpos
15781 && CHARPOS (start) <= last_changed_charpos)
15782 GIVE_UP (15);
15783
15784 /* Check that window start agrees with the start of the first glyph
15785 row in its current matrix. Check this after we know the window
15786 start is not in changed text, otherwise positions would not be
15787 comparable. */
15788 row = MATRIX_FIRST_TEXT_ROW (current_matrix);
15789 if (!TEXT_POS_EQUAL_P (start, row->minpos))
15790 GIVE_UP (16);
15791
15792 /* Give up if the window ends in strings. Overlay strings
15793 at the end are difficult to handle, so don't try. */
15794 row = MATRIX_ROW (current_matrix, XFASTINT (w->window_end_vpos));
15795 if (MATRIX_ROW_START_CHARPOS (row) == MATRIX_ROW_END_CHARPOS (row))
15796 GIVE_UP (20);
15797
15798 /* Compute the position at which we have to start displaying new
15799 lines. Some of the lines at the top of the window might be
15800 reusable because they are not displaying changed text. Find the
15801 last row in W's current matrix not affected by changes at the
15802 start of current_buffer. Value is null if changes start in the
15803 first line of window. */
15804 last_unchanged_at_beg_row = find_last_unchanged_at_beg_row (w);
15805 if (last_unchanged_at_beg_row)
15806 {
15807 /* Avoid starting to display in the moddle of a character, a TAB
15808 for instance. This is easier than to set up the iterator
15809 exactly, and it's not a frequent case, so the additional
15810 effort wouldn't really pay off. */
15811 while ((MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row)
15812 || last_unchanged_at_beg_row->ends_in_newline_from_string_p)
15813 && last_unchanged_at_beg_row > w->current_matrix->rows)
15814 --last_unchanged_at_beg_row;
15815
15816 if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row))
15817 GIVE_UP (17);
15818
15819 if (init_to_row_end (&it, w, last_unchanged_at_beg_row) == 0)
15820 GIVE_UP (18);
15821 start_pos = it.current.pos;
15822
15823 /* Start displaying new lines in the desired matrix at the same
15824 vpos we would use in the current matrix, i.e. below
15825 last_unchanged_at_beg_row. */
15826 it.vpos = 1 + MATRIX_ROW_VPOS (last_unchanged_at_beg_row,
15827 current_matrix);
15828 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
15829 it.current_y = MATRIX_ROW_BOTTOM_Y (last_unchanged_at_beg_row);
15830
15831 xassert (it.hpos == 0 && it.current_x == 0);
15832 }
15833 else
15834 {
15835 /* There are no reusable lines at the start of the window.
15836 Start displaying in the first text line. */
15837 start_display (&it, w, start);
15838 it.vpos = it.first_vpos;
15839 start_pos = it.current.pos;
15840 }
15841
15842 /* Find the first row that is not affected by changes at the end of
15843 the buffer. Value will be null if there is no unchanged row, in
15844 which case we must redisplay to the end of the window. delta
15845 will be set to the value by which buffer positions beginning with
15846 first_unchanged_at_end_row have to be adjusted due to text
15847 changes. */
15848 first_unchanged_at_end_row
15849 = find_first_unchanged_at_end_row (w, &delta, &delta_bytes);
15850 IF_DEBUG (debug_delta = delta);
15851 IF_DEBUG (debug_delta_bytes = delta_bytes);
15852
15853 /* Set stop_pos to the buffer position up to which we will have to
15854 display new lines. If first_unchanged_at_end_row != NULL, this
15855 is the buffer position of the start of the line displayed in that
15856 row. For first_unchanged_at_end_row == NULL, use 0 to indicate
15857 that we don't stop at a buffer position. */
15858 stop_pos = 0;
15859 if (first_unchanged_at_end_row)
15860 {
15861 xassert (last_unchanged_at_beg_row == NULL
15862 || first_unchanged_at_end_row >= last_unchanged_at_beg_row);
15863
15864 /* If this is a continuation line, move forward to the next one
15865 that isn't. Changes in lines above affect this line.
15866 Caution: this may move first_unchanged_at_end_row to a row
15867 not displaying text. */
15868 while (MATRIX_ROW_CONTINUATION_LINE_P (first_unchanged_at_end_row)
15869 && MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
15870 && (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
15871 < it.last_visible_y))
15872 ++first_unchanged_at_end_row;
15873
15874 if (!MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
15875 || (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
15876 >= it.last_visible_y))
15877 first_unchanged_at_end_row = NULL;
15878 else
15879 {
15880 stop_pos = (MATRIX_ROW_START_CHARPOS (first_unchanged_at_end_row)
15881 + delta);
15882 first_unchanged_at_end_vpos
15883 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, current_matrix);
15884 xassert (stop_pos >= Z - END_UNCHANGED);
15885 }
15886 }
15887 else if (last_unchanged_at_beg_row == NULL)
15888 GIVE_UP (19);
15889
15890
15891 #if GLYPH_DEBUG
15892
15893 /* Either there is no unchanged row at the end, or the one we have
15894 now displays text. This is a necessary condition for the window
15895 end pos calculation at the end of this function. */
15896 xassert (first_unchanged_at_end_row == NULL
15897 || MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
15898
15899 debug_last_unchanged_at_beg_vpos
15900 = (last_unchanged_at_beg_row
15901 ? MATRIX_ROW_VPOS (last_unchanged_at_beg_row, current_matrix)
15902 : -1);
15903 debug_first_unchanged_at_end_vpos = first_unchanged_at_end_vpos;
15904
15905 #endif /* GLYPH_DEBUG != 0 */
15906
15907
15908 /* Display new lines. Set last_text_row to the last new line
15909 displayed which has text on it, i.e. might end up as being the
15910 line where the window_end_vpos is. */
15911 w->cursor.vpos = -1;
15912 last_text_row = NULL;
15913 overlay_arrow_seen = 0;
15914 while (it.current_y < it.last_visible_y
15915 && !fonts_changed_p
15916 && (first_unchanged_at_end_row == NULL
15917 || IT_CHARPOS (it) < stop_pos))
15918 {
15919 if (display_line (&it))
15920 last_text_row = it.glyph_row - 1;
15921 }
15922
15923 if (fonts_changed_p)
15924 return -1;
15925
15926
15927 /* Compute differences in buffer positions, y-positions etc. for
15928 lines reused at the bottom of the window. Compute what we can
15929 scroll. */
15930 if (first_unchanged_at_end_row
15931 /* No lines reused because we displayed everything up to the
15932 bottom of the window. */
15933 && it.current_y < it.last_visible_y)
15934 {
15935 dvpos = (it.vpos
15936 - MATRIX_ROW_VPOS (first_unchanged_at_end_row,
15937 current_matrix));
15938 dy = it.current_y - first_unchanged_at_end_row->y;
15939 run.current_y = first_unchanged_at_end_row->y;
15940 run.desired_y = run.current_y + dy;
15941 run.height = it.last_visible_y - max (run.current_y, run.desired_y);
15942 }
15943 else
15944 {
15945 delta = delta_bytes = dvpos = dy
15946 = run.current_y = run.desired_y = run.height = 0;
15947 first_unchanged_at_end_row = NULL;
15948 }
15949 IF_DEBUG (debug_dvpos = dvpos; debug_dy = dy);
15950
15951
15952 /* Find the cursor if not already found. We have to decide whether
15953 PT will appear on this window (it sometimes doesn't, but this is
15954 not a very frequent case.) This decision has to be made before
15955 the current matrix is altered. A value of cursor.vpos < 0 means
15956 that PT is either in one of the lines beginning at
15957 first_unchanged_at_end_row or below the window. Don't care for
15958 lines that might be displayed later at the window end; as
15959 mentioned, this is not a frequent case. */
15960 if (w->cursor.vpos < 0)
15961 {
15962 /* Cursor in unchanged rows at the top? */
15963 if (PT < CHARPOS (start_pos)
15964 && last_unchanged_at_beg_row)
15965 {
15966 row = row_containing_pos (w, PT,
15967 MATRIX_FIRST_TEXT_ROW (w->current_matrix),
15968 last_unchanged_at_beg_row + 1, 0);
15969 if (row)
15970 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
15971 }
15972
15973 /* Start from first_unchanged_at_end_row looking for PT. */
15974 else if (first_unchanged_at_end_row)
15975 {
15976 row = row_containing_pos (w, PT - delta,
15977 first_unchanged_at_end_row, NULL, 0);
15978 if (row)
15979 set_cursor_from_row (w, row, w->current_matrix, delta,
15980 delta_bytes, dy, dvpos);
15981 }
15982
15983 /* Give up if cursor was not found. */
15984 if (w->cursor.vpos < 0)
15985 {
15986 clear_glyph_matrix (w->desired_matrix);
15987 return -1;
15988 }
15989 }
15990
15991 /* Don't let the cursor end in the scroll margins. */
15992 {
15993 int this_scroll_margin, cursor_height;
15994
15995 this_scroll_margin = max (0, scroll_margin);
15996 this_scroll_margin = min (this_scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
15997 this_scroll_margin *= FRAME_LINE_HEIGHT (it.f);
15998 cursor_height = MATRIX_ROW (w->desired_matrix, w->cursor.vpos)->height;
15999
16000 if ((w->cursor.y < this_scroll_margin
16001 && CHARPOS (start) > BEGV)
16002 /* Old redisplay didn't take scroll margin into account at the bottom,
16003 but then global-hl-line-mode doesn't scroll. KFS 2004-06-14 */
16004 || (w->cursor.y + (make_cursor_line_fully_visible_p
16005 ? cursor_height + this_scroll_margin
16006 : 1)) > it.last_visible_y)
16007 {
16008 w->cursor.vpos = -1;
16009 clear_glyph_matrix (w->desired_matrix);
16010 return -1;
16011 }
16012 }
16013
16014 /* Scroll the display. Do it before changing the current matrix so
16015 that xterm.c doesn't get confused about where the cursor glyph is
16016 found. */
16017 if (dy && run.height)
16018 {
16019 update_begin (f);
16020
16021 if (FRAME_WINDOW_P (f))
16022 {
16023 FRAME_RIF (f)->update_window_begin_hook (w);
16024 FRAME_RIF (f)->clear_window_mouse_face (w);
16025 FRAME_RIF (f)->scroll_run_hook (w, &run);
16026 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
16027 }
16028 else
16029 {
16030 /* Terminal frame. In this case, dvpos gives the number of
16031 lines to scroll by; dvpos < 0 means scroll up. */
16032 int from_vpos
16033 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, w->current_matrix);
16034 int from = WINDOW_TOP_EDGE_LINE (w) + from_vpos;
16035 int end = (WINDOW_TOP_EDGE_LINE (w)
16036 + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0)
16037 + window_internal_height (w));
16038
16039 #if defined (HAVE_GPM) || defined (MSDOS)
16040 x_clear_window_mouse_face (w);
16041 #endif
16042 /* Perform the operation on the screen. */
16043 if (dvpos > 0)
16044 {
16045 /* Scroll last_unchanged_at_beg_row to the end of the
16046 window down dvpos lines. */
16047 set_terminal_window (f, end);
16048
16049 /* On dumb terminals delete dvpos lines at the end
16050 before inserting dvpos empty lines. */
16051 if (!FRAME_SCROLL_REGION_OK (f))
16052 ins_del_lines (f, end - dvpos, -dvpos);
16053
16054 /* Insert dvpos empty lines in front of
16055 last_unchanged_at_beg_row. */
16056 ins_del_lines (f, from, dvpos);
16057 }
16058 else if (dvpos < 0)
16059 {
16060 /* Scroll up last_unchanged_at_beg_vpos to the end of
16061 the window to last_unchanged_at_beg_vpos - |dvpos|. */
16062 set_terminal_window (f, end);
16063
16064 /* Delete dvpos lines in front of
16065 last_unchanged_at_beg_vpos. ins_del_lines will set
16066 the cursor to the given vpos and emit |dvpos| delete
16067 line sequences. */
16068 ins_del_lines (f, from + dvpos, dvpos);
16069
16070 /* On a dumb terminal insert dvpos empty lines at the
16071 end. */
16072 if (!FRAME_SCROLL_REGION_OK (f))
16073 ins_del_lines (f, end + dvpos, -dvpos);
16074 }
16075
16076 set_terminal_window (f, 0);
16077 }
16078
16079 update_end (f);
16080 }
16081
16082 /* Shift reused rows of the current matrix to the right position.
16083 BOTTOM_ROW is the last + 1 row in the current matrix reserved for
16084 text. */
16085 bottom_row = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
16086 bottom_vpos = MATRIX_ROW_VPOS (bottom_row, current_matrix);
16087 if (dvpos < 0)
16088 {
16089 rotate_matrix (current_matrix, first_unchanged_at_end_vpos + dvpos,
16090 bottom_vpos, dvpos);
16091 enable_glyph_matrix_rows (current_matrix, bottom_vpos + dvpos,
16092 bottom_vpos, 0);
16093 }
16094 else if (dvpos > 0)
16095 {
16096 rotate_matrix (current_matrix, first_unchanged_at_end_vpos,
16097 bottom_vpos, dvpos);
16098 enable_glyph_matrix_rows (current_matrix, first_unchanged_at_end_vpos,
16099 first_unchanged_at_end_vpos + dvpos, 0);
16100 }
16101
16102 /* For frame-based redisplay, make sure that current frame and window
16103 matrix are in sync with respect to glyph memory. */
16104 if (!FRAME_WINDOW_P (f))
16105 sync_frame_with_window_matrix_rows (w);
16106
16107 /* Adjust buffer positions in reused rows. */
16108 if (delta || delta_bytes)
16109 increment_matrix_positions (current_matrix,
16110 first_unchanged_at_end_vpos + dvpos,
16111 bottom_vpos, delta, delta_bytes);
16112
16113 /* Adjust Y positions. */
16114 if (dy)
16115 shift_glyph_matrix (w, current_matrix,
16116 first_unchanged_at_end_vpos + dvpos,
16117 bottom_vpos, dy);
16118
16119 if (first_unchanged_at_end_row)
16120 {
16121 first_unchanged_at_end_row += dvpos;
16122 if (first_unchanged_at_end_row->y >= it.last_visible_y
16123 || !MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row))
16124 first_unchanged_at_end_row = NULL;
16125 }
16126
16127 /* If scrolling up, there may be some lines to display at the end of
16128 the window. */
16129 last_text_row_at_end = NULL;
16130 if (dy < 0)
16131 {
16132 /* Scrolling up can leave for example a partially visible line
16133 at the end of the window to be redisplayed. */
16134 /* Set last_row to the glyph row in the current matrix where the
16135 window end line is found. It has been moved up or down in
16136 the matrix by dvpos. */
16137 int last_vpos = XFASTINT (w->window_end_vpos) + dvpos;
16138 struct glyph_row *last_row = MATRIX_ROW (current_matrix, last_vpos);
16139
16140 /* If last_row is the window end line, it should display text. */
16141 xassert (last_row->displays_text_p);
16142
16143 /* If window end line was partially visible before, begin
16144 displaying at that line. Otherwise begin displaying with the
16145 line following it. */
16146 if (MATRIX_ROW_BOTTOM_Y (last_row) - dy >= it.last_visible_y)
16147 {
16148 init_to_row_start (&it, w, last_row);
16149 it.vpos = last_vpos;
16150 it.current_y = last_row->y;
16151 }
16152 else
16153 {
16154 init_to_row_end (&it, w, last_row);
16155 it.vpos = 1 + last_vpos;
16156 it.current_y = MATRIX_ROW_BOTTOM_Y (last_row);
16157 ++last_row;
16158 }
16159
16160 /* We may start in a continuation line. If so, we have to
16161 get the right continuation_lines_width and current_x. */
16162 it.continuation_lines_width = last_row->continuation_lines_width;
16163 it.hpos = it.current_x = 0;
16164
16165 /* Display the rest of the lines at the window end. */
16166 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
16167 while (it.current_y < it.last_visible_y
16168 && !fonts_changed_p)
16169 {
16170 /* Is it always sure that the display agrees with lines in
16171 the current matrix? I don't think so, so we mark rows
16172 displayed invalid in the current matrix by setting their
16173 enabled_p flag to zero. */
16174 MATRIX_ROW (w->current_matrix, it.vpos)->enabled_p = 0;
16175 if (display_line (&it))
16176 last_text_row_at_end = it.glyph_row - 1;
16177 }
16178 }
16179
16180 /* Update window_end_pos and window_end_vpos. */
16181 if (first_unchanged_at_end_row
16182 && !last_text_row_at_end)
16183 {
16184 /* Window end line if one of the preserved rows from the current
16185 matrix. Set row to the last row displaying text in current
16186 matrix starting at first_unchanged_at_end_row, after
16187 scrolling. */
16188 xassert (first_unchanged_at_end_row->displays_text_p);
16189 row = find_last_row_displaying_text (w->current_matrix, &it,
16190 first_unchanged_at_end_row);
16191 xassert (row && MATRIX_ROW_DISPLAYS_TEXT_P (row));
16192
16193 w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
16194 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
16195 w->window_end_vpos
16196 = make_number (MATRIX_ROW_VPOS (row, w->current_matrix));
16197 xassert (w->window_end_bytepos >= 0);
16198 IF_DEBUG (debug_method_add (w, "A"));
16199 }
16200 else if (last_text_row_at_end)
16201 {
16202 w->window_end_pos
16203 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row_at_end));
16204 w->window_end_bytepos
16205 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row_at_end);
16206 w->window_end_vpos
16207 = make_number (MATRIX_ROW_VPOS (last_text_row_at_end, desired_matrix));
16208 xassert (w->window_end_bytepos >= 0);
16209 IF_DEBUG (debug_method_add (w, "B"));
16210 }
16211 else if (last_text_row)
16212 {
16213 /* We have displayed either to the end of the window or at the
16214 end of the window, i.e. the last row with text is to be found
16215 in the desired matrix. */
16216 w->window_end_pos
16217 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
16218 w->window_end_bytepos
16219 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
16220 w->window_end_vpos
16221 = make_number (MATRIX_ROW_VPOS (last_text_row, desired_matrix));
16222 xassert (w->window_end_bytepos >= 0);
16223 }
16224 else if (first_unchanged_at_end_row == NULL
16225 && last_text_row == NULL
16226 && last_text_row_at_end == NULL)
16227 {
16228 /* Displayed to end of window, but no line containing text was
16229 displayed. Lines were deleted at the end of the window. */
16230 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
16231 int vpos = XFASTINT (w->window_end_vpos);
16232 struct glyph_row *current_row = current_matrix->rows + vpos;
16233 struct glyph_row *desired_row = desired_matrix->rows + vpos;
16234
16235 for (row = NULL;
16236 row == NULL && vpos >= first_vpos;
16237 --vpos, --current_row, --desired_row)
16238 {
16239 if (desired_row->enabled_p)
16240 {
16241 if (desired_row->displays_text_p)
16242 row = desired_row;
16243 }
16244 else if (current_row->displays_text_p)
16245 row = current_row;
16246 }
16247
16248 xassert (row != NULL);
16249 w->window_end_vpos = make_number (vpos + 1);
16250 w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
16251 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
16252 xassert (w->window_end_bytepos >= 0);
16253 IF_DEBUG (debug_method_add (w, "C"));
16254 }
16255 else
16256 abort ();
16257
16258 IF_DEBUG (debug_end_pos = XFASTINT (w->window_end_pos);
16259 debug_end_vpos = XFASTINT (w->window_end_vpos));
16260
16261 /* Record that display has not been completed. */
16262 w->window_end_valid = Qnil;
16263 w->desired_matrix->no_scrolling_p = 1;
16264 return 3;
16265
16266 #undef GIVE_UP
16267 }
16268
16269
16270 \f
16271 /***********************************************************************
16272 More debugging support
16273 ***********************************************************************/
16274
16275 #if GLYPH_DEBUG
16276
16277 void dump_glyph_row (struct glyph_row *, int, int);
16278 void dump_glyph_matrix (struct glyph_matrix *, int);
16279 void dump_glyph (struct glyph_row *, struct glyph *, int);
16280
16281
16282 /* Dump the contents of glyph matrix MATRIX on stderr.
16283
16284 GLYPHS 0 means don't show glyph contents.
16285 GLYPHS 1 means show glyphs in short form
16286 GLYPHS > 1 means show glyphs in long form. */
16287
16288 void
16289 dump_glyph_matrix (matrix, glyphs)
16290 struct glyph_matrix *matrix;
16291 int glyphs;
16292 {
16293 int i;
16294 for (i = 0; i < matrix->nrows; ++i)
16295 dump_glyph_row (MATRIX_ROW (matrix, i), i, glyphs);
16296 }
16297
16298
16299 /* Dump contents of glyph GLYPH to stderr. ROW and AREA are
16300 the glyph row and area where the glyph comes from. */
16301
16302 void
16303 dump_glyph (row, glyph, area)
16304 struct glyph_row *row;
16305 struct glyph *glyph;
16306 int area;
16307 {
16308 if (glyph->type == CHAR_GLYPH)
16309 {
16310 fprintf (stderr,
16311 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
16312 glyph - row->glyphs[TEXT_AREA],
16313 'C',
16314 glyph->charpos,
16315 (BUFFERP (glyph->object)
16316 ? 'B'
16317 : (STRINGP (glyph->object)
16318 ? 'S'
16319 : '-')),
16320 glyph->pixel_width,
16321 glyph->u.ch,
16322 (glyph->u.ch < 0x80 && glyph->u.ch >= ' '
16323 ? glyph->u.ch
16324 : '.'),
16325 glyph->face_id,
16326 glyph->left_box_line_p,
16327 glyph->right_box_line_p);
16328 }
16329 else if (glyph->type == STRETCH_GLYPH)
16330 {
16331 fprintf (stderr,
16332 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
16333 glyph - row->glyphs[TEXT_AREA],
16334 'S',
16335 glyph->charpos,
16336 (BUFFERP (glyph->object)
16337 ? 'B'
16338 : (STRINGP (glyph->object)
16339 ? 'S'
16340 : '-')),
16341 glyph->pixel_width,
16342 0,
16343 '.',
16344 glyph->face_id,
16345 glyph->left_box_line_p,
16346 glyph->right_box_line_p);
16347 }
16348 else if (glyph->type == IMAGE_GLYPH)
16349 {
16350 fprintf (stderr,
16351 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
16352 glyph - row->glyphs[TEXT_AREA],
16353 'I',
16354 glyph->charpos,
16355 (BUFFERP (glyph->object)
16356 ? 'B'
16357 : (STRINGP (glyph->object)
16358 ? 'S'
16359 : '-')),
16360 glyph->pixel_width,
16361 glyph->u.img_id,
16362 '.',
16363 glyph->face_id,
16364 glyph->left_box_line_p,
16365 glyph->right_box_line_p);
16366 }
16367 else if (glyph->type == COMPOSITE_GLYPH)
16368 {
16369 fprintf (stderr,
16370 " %5d %4c %6d %c %3d 0x%05x",
16371 glyph - row->glyphs[TEXT_AREA],
16372 '+',
16373 glyph->charpos,
16374 (BUFFERP (glyph->object)
16375 ? 'B'
16376 : (STRINGP (glyph->object)
16377 ? 'S'
16378 : '-')),
16379 glyph->pixel_width,
16380 glyph->u.cmp.id);
16381 if (glyph->u.cmp.automatic)
16382 fprintf (stderr,
16383 "[%d-%d]",
16384 glyph->slice.cmp.from, glyph->slice.cmp.to);
16385 fprintf (stderr, " . %4d %1.1d%1.1d\n",
16386 glyph->face_id,
16387 glyph->left_box_line_p,
16388 glyph->right_box_line_p);
16389 }
16390 }
16391
16392
16393 /* Dump the contents of glyph row at VPOS in MATRIX to stderr.
16394 GLYPHS 0 means don't show glyph contents.
16395 GLYPHS 1 means show glyphs in short form
16396 GLYPHS > 1 means show glyphs in long form. */
16397
16398 void
16399 dump_glyph_row (row, vpos, glyphs)
16400 struct glyph_row *row;
16401 int vpos, glyphs;
16402 {
16403 if (glyphs != 1)
16404 {
16405 fprintf (stderr, "Row Start End Used oE><\\CTZFesm X Y W H V A P\n");
16406 fprintf (stderr, "======================================================================\n");
16407
16408 fprintf (stderr, "%3d %5d %5d %4d %1.1d%1.1d%1.1d%1.1d\
16409 %1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d %4d %4d %4d %4d %4d %4d %4d\n",
16410 vpos,
16411 MATRIX_ROW_START_CHARPOS (row),
16412 MATRIX_ROW_END_CHARPOS (row),
16413 row->used[TEXT_AREA],
16414 row->contains_overlapping_glyphs_p,
16415 row->enabled_p,
16416 row->truncated_on_left_p,
16417 row->truncated_on_right_p,
16418 row->continued_p,
16419 MATRIX_ROW_CONTINUATION_LINE_P (row),
16420 row->displays_text_p,
16421 row->ends_at_zv_p,
16422 row->fill_line_p,
16423 row->ends_in_middle_of_char_p,
16424 row->starts_in_middle_of_char_p,
16425 row->mouse_face_p,
16426 row->x,
16427 row->y,
16428 row->pixel_width,
16429 row->height,
16430 row->visible_height,
16431 row->ascent,
16432 row->phys_ascent);
16433 fprintf (stderr, "%9d %5d\t%5d\n", row->start.overlay_string_index,
16434 row->end.overlay_string_index,
16435 row->continuation_lines_width);
16436 fprintf (stderr, "%9d %5d\n",
16437 CHARPOS (row->start.string_pos),
16438 CHARPOS (row->end.string_pos));
16439 fprintf (stderr, "%9d %5d\n", row->start.dpvec_index,
16440 row->end.dpvec_index);
16441 }
16442
16443 if (glyphs > 1)
16444 {
16445 int area;
16446
16447 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
16448 {
16449 struct glyph *glyph = row->glyphs[area];
16450 struct glyph *glyph_end = glyph + row->used[area];
16451
16452 /* Glyph for a line end in text. */
16453 if (area == TEXT_AREA && glyph == glyph_end && glyph->charpos > 0)
16454 ++glyph_end;
16455
16456 if (glyph < glyph_end)
16457 fprintf (stderr, " Glyph Type Pos O W Code C Face LR\n");
16458
16459 for (; glyph < glyph_end; ++glyph)
16460 dump_glyph (row, glyph, area);
16461 }
16462 }
16463 else if (glyphs == 1)
16464 {
16465 int area;
16466
16467 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
16468 {
16469 char *s = (char *) alloca (row->used[area] + 1);
16470 int i;
16471
16472 for (i = 0; i < row->used[area]; ++i)
16473 {
16474 struct glyph *glyph = row->glyphs[area] + i;
16475 if (glyph->type == CHAR_GLYPH
16476 && glyph->u.ch < 0x80
16477 && glyph->u.ch >= ' ')
16478 s[i] = glyph->u.ch;
16479 else
16480 s[i] = '.';
16481 }
16482
16483 s[i] = '\0';
16484 fprintf (stderr, "%3d: (%d) '%s'\n", vpos, row->enabled_p, s);
16485 }
16486 }
16487 }
16488
16489
16490 DEFUN ("dump-glyph-matrix", Fdump_glyph_matrix,
16491 Sdump_glyph_matrix, 0, 1, "p",
16492 doc: /* Dump the current matrix of the selected window to stderr.
16493 Shows contents of glyph row structures. With non-nil
16494 parameter GLYPHS, dump glyphs as well. If GLYPHS is 1 show
16495 glyphs in short form, otherwise show glyphs in long form. */)
16496 (Lisp_Object glyphs)
16497 {
16498 struct window *w = XWINDOW (selected_window);
16499 struct buffer *buffer = XBUFFER (w->buffer);
16500
16501 fprintf (stderr, "PT = %d, BEGV = %d. ZV = %d\n",
16502 BUF_PT (buffer), BUF_BEGV (buffer), BUF_ZV (buffer));
16503 fprintf (stderr, "Cursor x = %d, y = %d, hpos = %d, vpos = %d\n",
16504 w->cursor.x, w->cursor.y, w->cursor.hpos, w->cursor.vpos);
16505 fprintf (stderr, "=============================================\n");
16506 dump_glyph_matrix (w->current_matrix,
16507 NILP (glyphs) ? 0 : XINT (glyphs));
16508 return Qnil;
16509 }
16510
16511
16512 DEFUN ("dump-frame-glyph-matrix", Fdump_frame_glyph_matrix,
16513 Sdump_frame_glyph_matrix, 0, 0, "", doc: /* */)
16514 (void)
16515 {
16516 struct frame *f = XFRAME (selected_frame);
16517 dump_glyph_matrix (f->current_matrix, 1);
16518 return Qnil;
16519 }
16520
16521
16522 DEFUN ("dump-glyph-row", Fdump_glyph_row, Sdump_glyph_row, 1, 2, "",
16523 doc: /* Dump glyph row ROW to stderr.
16524 GLYPH 0 means don't dump glyphs.
16525 GLYPH 1 means dump glyphs in short form.
16526 GLYPH > 1 or omitted means dump glyphs in long form. */)
16527 (Lisp_Object row, Lisp_Object glyphs)
16528 {
16529 struct glyph_matrix *matrix;
16530 int vpos;
16531
16532 CHECK_NUMBER (row);
16533 matrix = XWINDOW (selected_window)->current_matrix;
16534 vpos = XINT (row);
16535 if (vpos >= 0 && vpos < matrix->nrows)
16536 dump_glyph_row (MATRIX_ROW (matrix, vpos),
16537 vpos,
16538 INTEGERP (glyphs) ? XINT (glyphs) : 2);
16539 return Qnil;
16540 }
16541
16542
16543 DEFUN ("dump-tool-bar-row", Fdump_tool_bar_row, Sdump_tool_bar_row, 1, 2, "",
16544 doc: /* Dump glyph row ROW of the tool-bar of the current frame to stderr.
16545 GLYPH 0 means don't dump glyphs.
16546 GLYPH 1 means dump glyphs in short form.
16547 GLYPH > 1 or omitted means dump glyphs in long form. */)
16548 (Lisp_Object row, Lisp_Object glyphs)
16549 {
16550 struct frame *sf = SELECTED_FRAME ();
16551 struct glyph_matrix *m = XWINDOW (sf->tool_bar_window)->current_matrix;
16552 int vpos;
16553
16554 CHECK_NUMBER (row);
16555 vpos = XINT (row);
16556 if (vpos >= 0 && vpos < m->nrows)
16557 dump_glyph_row (MATRIX_ROW (m, vpos), vpos,
16558 INTEGERP (glyphs) ? XINT (glyphs) : 2);
16559 return Qnil;
16560 }
16561
16562
16563 DEFUN ("trace-redisplay", Ftrace_redisplay, Strace_redisplay, 0, 1, "P",
16564 doc: /* Toggle tracing of redisplay.
16565 With ARG, turn tracing on if and only if ARG is positive. */)
16566 (Lisp_Object arg)
16567 {
16568 if (NILP (arg))
16569 trace_redisplay_p = !trace_redisplay_p;
16570 else
16571 {
16572 arg = Fprefix_numeric_value (arg);
16573 trace_redisplay_p = XINT (arg) > 0;
16574 }
16575
16576 return Qnil;
16577 }
16578
16579
16580 DEFUN ("trace-to-stderr", Ftrace_to_stderr, Strace_to_stderr, 1, MANY, "",
16581 doc: /* Like `format', but print result to stderr.
16582 usage: (trace-to-stderr STRING &rest OBJECTS) */)
16583 (size_t nargs, Lisp_Object *args)
16584 {
16585 Lisp_Object s = Fformat (nargs, args);
16586 fprintf (stderr, "%s", SDATA (s));
16587 return Qnil;
16588 }
16589
16590 #endif /* GLYPH_DEBUG */
16591
16592
16593 \f
16594 /***********************************************************************
16595 Building Desired Matrix Rows
16596 ***********************************************************************/
16597
16598 /* Return a temporary glyph row holding the glyphs of an overlay arrow.
16599 Used for non-window-redisplay windows, and for windows w/o left fringe. */
16600
16601 static struct glyph_row *
16602 get_overlay_arrow_glyph_row (struct window *w, Lisp_Object overlay_arrow_string)
16603 {
16604 struct frame *f = XFRAME (WINDOW_FRAME (w));
16605 struct buffer *buffer = XBUFFER (w->buffer);
16606 struct buffer *old = current_buffer;
16607 const unsigned char *arrow_string = SDATA (overlay_arrow_string);
16608 int arrow_len = SCHARS (overlay_arrow_string);
16609 const unsigned char *arrow_end = arrow_string + arrow_len;
16610 const unsigned char *p;
16611 struct it it;
16612 int multibyte_p;
16613 int n_glyphs_before;
16614
16615 set_buffer_temp (buffer);
16616 init_iterator (&it, w, -1, -1, &scratch_glyph_row, DEFAULT_FACE_ID);
16617 it.glyph_row->used[TEXT_AREA] = 0;
16618 SET_TEXT_POS (it.position, 0, 0);
16619
16620 multibyte_p = !NILP (BVAR (buffer, enable_multibyte_characters));
16621 p = arrow_string;
16622 while (p < arrow_end)
16623 {
16624 Lisp_Object face, ilisp;
16625
16626 /* Get the next character. */
16627 if (multibyte_p)
16628 it.c = it.char_to_display = string_char_and_length (p, &it.len);
16629 else
16630 {
16631 it.c = it.char_to_display = *p, it.len = 1;
16632 if (! ASCII_CHAR_P (it.c))
16633 it.char_to_display = BYTE8_TO_CHAR (it.c);
16634 }
16635 p += it.len;
16636
16637 /* Get its face. */
16638 ilisp = make_number (p - arrow_string);
16639 face = Fget_text_property (ilisp, Qface, overlay_arrow_string);
16640 it.face_id = compute_char_face (f, it.char_to_display, face);
16641
16642 /* Compute its width, get its glyphs. */
16643 n_glyphs_before = it.glyph_row->used[TEXT_AREA];
16644 SET_TEXT_POS (it.position, -1, -1);
16645 PRODUCE_GLYPHS (&it);
16646
16647 /* If this character doesn't fit any more in the line, we have
16648 to remove some glyphs. */
16649 if (it.current_x > it.last_visible_x)
16650 {
16651 it.glyph_row->used[TEXT_AREA] = n_glyphs_before;
16652 break;
16653 }
16654 }
16655
16656 set_buffer_temp (old);
16657 return it.glyph_row;
16658 }
16659
16660
16661 /* Insert truncation glyphs at the start of IT->glyph_row. Truncation
16662 glyphs are only inserted for terminal frames since we can't really
16663 win with truncation glyphs when partially visible glyphs are
16664 involved. Which glyphs to insert is determined by
16665 produce_special_glyphs. */
16666
16667 static void
16668 insert_left_trunc_glyphs (struct it *it)
16669 {
16670 struct it truncate_it;
16671 struct glyph *from, *end, *to, *toend;
16672
16673 xassert (!FRAME_WINDOW_P (it->f));
16674
16675 /* Get the truncation glyphs. */
16676 truncate_it = *it;
16677 truncate_it.current_x = 0;
16678 truncate_it.face_id = DEFAULT_FACE_ID;
16679 truncate_it.glyph_row = &scratch_glyph_row;
16680 truncate_it.glyph_row->used[TEXT_AREA] = 0;
16681 CHARPOS (truncate_it.position) = BYTEPOS (truncate_it.position) = -1;
16682 truncate_it.object = make_number (0);
16683 produce_special_glyphs (&truncate_it, IT_TRUNCATION);
16684
16685 /* Overwrite glyphs from IT with truncation glyphs. */
16686 if (!it->glyph_row->reversed_p)
16687 {
16688 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
16689 end = from + truncate_it.glyph_row->used[TEXT_AREA];
16690 to = it->glyph_row->glyphs[TEXT_AREA];
16691 toend = to + it->glyph_row->used[TEXT_AREA];
16692
16693 while (from < end)
16694 *to++ = *from++;
16695
16696 /* There may be padding glyphs left over. Overwrite them too. */
16697 while (to < toend && CHAR_GLYPH_PADDING_P (*to))
16698 {
16699 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
16700 while (from < end)
16701 *to++ = *from++;
16702 }
16703
16704 if (to > toend)
16705 it->glyph_row->used[TEXT_AREA] = to - it->glyph_row->glyphs[TEXT_AREA];
16706 }
16707 else
16708 {
16709 /* In R2L rows, overwrite the last (rightmost) glyphs, and do
16710 that back to front. */
16711 end = truncate_it.glyph_row->glyphs[TEXT_AREA];
16712 from = end + truncate_it.glyph_row->used[TEXT_AREA] - 1;
16713 toend = it->glyph_row->glyphs[TEXT_AREA];
16714 to = toend + it->glyph_row->used[TEXT_AREA] - 1;
16715
16716 while (from >= end && to >= toend)
16717 *to-- = *from--;
16718 while (to >= toend && CHAR_GLYPH_PADDING_P (*to))
16719 {
16720 from =
16721 truncate_it.glyph_row->glyphs[TEXT_AREA]
16722 + truncate_it.glyph_row->used[TEXT_AREA] - 1;
16723 while (from >= end && to >= toend)
16724 *to-- = *from--;
16725 }
16726 if (from >= end)
16727 {
16728 /* Need to free some room before prepending additional
16729 glyphs. */
16730 int move_by = from - end + 1;
16731 struct glyph *g0 = it->glyph_row->glyphs[TEXT_AREA];
16732 struct glyph *g = g0 + it->glyph_row->used[TEXT_AREA] - 1;
16733
16734 for ( ; g >= g0; g--)
16735 g[move_by] = *g;
16736 while (from >= end)
16737 *to-- = *from--;
16738 it->glyph_row->used[TEXT_AREA] += move_by;
16739 }
16740 }
16741 }
16742
16743
16744 /* Compute the pixel height and width of IT->glyph_row.
16745
16746 Most of the time, ascent and height of a display line will be equal
16747 to the max_ascent and max_height values of the display iterator
16748 structure. This is not the case if
16749
16750 1. We hit ZV without displaying anything. In this case, max_ascent
16751 and max_height will be zero.
16752
16753 2. We have some glyphs that don't contribute to the line height.
16754 (The glyph row flag contributes_to_line_height_p is for future
16755 pixmap extensions).
16756
16757 The first case is easily covered by using default values because in
16758 these cases, the line height does not really matter, except that it
16759 must not be zero. */
16760
16761 static void
16762 compute_line_metrics (struct it *it)
16763 {
16764 struct glyph_row *row = it->glyph_row;
16765
16766 if (FRAME_WINDOW_P (it->f))
16767 {
16768 int i, min_y, max_y;
16769
16770 /* The line may consist of one space only, that was added to
16771 place the cursor on it. If so, the row's height hasn't been
16772 computed yet. */
16773 if (row->height == 0)
16774 {
16775 if (it->max_ascent + it->max_descent == 0)
16776 it->max_descent = it->max_phys_descent = FRAME_LINE_HEIGHT (it->f);
16777 row->ascent = it->max_ascent;
16778 row->height = it->max_ascent + it->max_descent;
16779 row->phys_ascent = it->max_phys_ascent;
16780 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
16781 row->extra_line_spacing = it->max_extra_line_spacing;
16782 }
16783
16784 /* Compute the width of this line. */
16785 row->pixel_width = row->x;
16786 for (i = 0; i < row->used[TEXT_AREA]; ++i)
16787 row->pixel_width += row->glyphs[TEXT_AREA][i].pixel_width;
16788
16789 xassert (row->pixel_width >= 0);
16790 xassert (row->ascent >= 0 && row->height > 0);
16791
16792 row->overlapping_p = (MATRIX_ROW_OVERLAPS_SUCC_P (row)
16793 || MATRIX_ROW_OVERLAPS_PRED_P (row));
16794
16795 /* If first line's physical ascent is larger than its logical
16796 ascent, use the physical ascent, and make the row taller.
16797 This makes accented characters fully visible. */
16798 if (row == MATRIX_FIRST_TEXT_ROW (it->w->desired_matrix)
16799 && row->phys_ascent > row->ascent)
16800 {
16801 row->height += row->phys_ascent - row->ascent;
16802 row->ascent = row->phys_ascent;
16803 }
16804
16805 /* Compute how much of the line is visible. */
16806 row->visible_height = row->height;
16807
16808 min_y = WINDOW_HEADER_LINE_HEIGHT (it->w);
16809 max_y = WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w);
16810
16811 if (row->y < min_y)
16812 row->visible_height -= min_y - row->y;
16813 if (row->y + row->height > max_y)
16814 row->visible_height -= row->y + row->height - max_y;
16815 }
16816 else
16817 {
16818 row->pixel_width = row->used[TEXT_AREA];
16819 if (row->continued_p)
16820 row->pixel_width -= it->continuation_pixel_width;
16821 else if (row->truncated_on_right_p)
16822 row->pixel_width -= it->truncation_pixel_width;
16823 row->ascent = row->phys_ascent = 0;
16824 row->height = row->phys_height = row->visible_height = 1;
16825 row->extra_line_spacing = 0;
16826 }
16827
16828 /* Compute a hash code for this row. */
16829 {
16830 int area, i;
16831 row->hash = 0;
16832 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
16833 for (i = 0; i < row->used[area]; ++i)
16834 row->hash = ((((row->hash << 4) + (row->hash >> 24)) & 0x0fffffff)
16835 + row->glyphs[area][i].u.val
16836 + row->glyphs[area][i].face_id
16837 + row->glyphs[area][i].padding_p
16838 + (row->glyphs[area][i].type << 2));
16839 }
16840
16841 it->max_ascent = it->max_descent = 0;
16842 it->max_phys_ascent = it->max_phys_descent = 0;
16843 }
16844
16845
16846 /* Append one space to the glyph row of iterator IT if doing a
16847 window-based redisplay. The space has the same face as
16848 IT->face_id. Value is non-zero if a space was added.
16849
16850 This function is called to make sure that there is always one glyph
16851 at the end of a glyph row that the cursor can be set on under
16852 window-systems. (If there weren't such a glyph we would not know
16853 how wide and tall a box cursor should be displayed).
16854
16855 At the same time this space let's a nicely handle clearing to the
16856 end of the line if the row ends in italic text. */
16857
16858 static int
16859 append_space_for_newline (struct it *it, int default_face_p)
16860 {
16861 if (FRAME_WINDOW_P (it->f))
16862 {
16863 int n = it->glyph_row->used[TEXT_AREA];
16864
16865 if (it->glyph_row->glyphs[TEXT_AREA] + n
16866 < it->glyph_row->glyphs[1 + TEXT_AREA])
16867 {
16868 /* Save some values that must not be changed.
16869 Must save IT->c and IT->len because otherwise
16870 ITERATOR_AT_END_P wouldn't work anymore after
16871 append_space_for_newline has been called. */
16872 enum display_element_type saved_what = it->what;
16873 int saved_c = it->c, saved_len = it->len;
16874 int saved_char_to_display = it->char_to_display;
16875 int saved_x = it->current_x;
16876 int saved_face_id = it->face_id;
16877 struct text_pos saved_pos;
16878 Lisp_Object saved_object;
16879 struct face *face;
16880
16881 saved_object = it->object;
16882 saved_pos = it->position;
16883
16884 it->what = IT_CHARACTER;
16885 memset (&it->position, 0, sizeof it->position);
16886 it->object = make_number (0);
16887 it->c = it->char_to_display = ' ';
16888 it->len = 1;
16889
16890 if (default_face_p)
16891 it->face_id = DEFAULT_FACE_ID;
16892 else if (it->face_before_selective_p)
16893 it->face_id = it->saved_face_id;
16894 face = FACE_FROM_ID (it->f, it->face_id);
16895 it->face_id = FACE_FOR_CHAR (it->f, face, 0, -1, Qnil);
16896
16897 PRODUCE_GLYPHS (it);
16898
16899 it->override_ascent = -1;
16900 it->constrain_row_ascent_descent_p = 0;
16901 it->current_x = saved_x;
16902 it->object = saved_object;
16903 it->position = saved_pos;
16904 it->what = saved_what;
16905 it->face_id = saved_face_id;
16906 it->len = saved_len;
16907 it->c = saved_c;
16908 it->char_to_display = saved_char_to_display;
16909 return 1;
16910 }
16911 }
16912
16913 return 0;
16914 }
16915
16916
16917 /* Extend the face of the last glyph in the text area of IT->glyph_row
16918 to the end of the display line. Called from display_line. If the
16919 glyph row is empty, add a space glyph to it so that we know the
16920 face to draw. Set the glyph row flag fill_line_p. If the glyph
16921 row is R2L, prepend a stretch glyph to cover the empty space to the
16922 left of the leftmost glyph. */
16923
16924 static void
16925 extend_face_to_end_of_line (struct it *it)
16926 {
16927 struct face *face;
16928 struct frame *f = it->f;
16929
16930 /* If line is already filled, do nothing. Non window-system frames
16931 get a grace of one more ``pixel'' because their characters are
16932 1-``pixel'' wide, so they hit the equality too early. This grace
16933 is needed only for R2L rows that are not continued, to produce
16934 one extra blank where we could display the cursor. */
16935 if (it->current_x >= it->last_visible_x
16936 + (!FRAME_WINDOW_P (f)
16937 && it->glyph_row->reversed_p
16938 && !it->glyph_row->continued_p))
16939 return;
16940
16941 /* Face extension extends the background and box of IT->face_id
16942 to the end of the line. If the background equals the background
16943 of the frame, we don't have to do anything. */
16944 if (it->face_before_selective_p)
16945 face = FACE_FROM_ID (f, it->saved_face_id);
16946 else
16947 face = FACE_FROM_ID (f, it->face_id);
16948
16949 if (FRAME_WINDOW_P (f)
16950 && it->glyph_row->displays_text_p
16951 && face->box == FACE_NO_BOX
16952 && face->background == FRAME_BACKGROUND_PIXEL (f)
16953 && !face->stipple
16954 && !it->glyph_row->reversed_p)
16955 return;
16956
16957 /* Set the glyph row flag indicating that the face of the last glyph
16958 in the text area has to be drawn to the end of the text area. */
16959 it->glyph_row->fill_line_p = 1;
16960
16961 /* If current character of IT is not ASCII, make sure we have the
16962 ASCII face. This will be automatically undone the next time
16963 get_next_display_element returns a multibyte character. Note
16964 that the character will always be single byte in unibyte
16965 text. */
16966 if (!ASCII_CHAR_P (it->c))
16967 {
16968 it->face_id = FACE_FOR_CHAR (f, face, 0, -1, Qnil);
16969 }
16970
16971 if (FRAME_WINDOW_P (f))
16972 {
16973 /* If the row is empty, add a space with the current face of IT,
16974 so that we know which face to draw. */
16975 if (it->glyph_row->used[TEXT_AREA] == 0)
16976 {
16977 it->glyph_row->glyphs[TEXT_AREA][0] = space_glyph;
16978 it->glyph_row->glyphs[TEXT_AREA][0].face_id = it->face_id;
16979 it->glyph_row->used[TEXT_AREA] = 1;
16980 }
16981 #ifdef HAVE_WINDOW_SYSTEM
16982 if (it->glyph_row->reversed_p)
16983 {
16984 /* Prepend a stretch glyph to the row, such that the
16985 rightmost glyph will be drawn flushed all the way to the
16986 right margin of the window. The stretch glyph that will
16987 occupy the empty space, if any, to the left of the
16988 glyphs. */
16989 struct font *font = face->font ? face->font : FRAME_FONT (f);
16990 struct glyph *row_start = it->glyph_row->glyphs[TEXT_AREA];
16991 struct glyph *row_end = row_start + it->glyph_row->used[TEXT_AREA];
16992 struct glyph *g;
16993 int row_width, stretch_ascent, stretch_width;
16994 struct text_pos saved_pos;
16995 int saved_face_id, saved_avoid_cursor;
16996
16997 for (row_width = 0, g = row_start; g < row_end; g++)
16998 row_width += g->pixel_width;
16999 stretch_width = window_box_width (it->w, TEXT_AREA) - row_width;
17000 if (stretch_width > 0)
17001 {
17002 stretch_ascent =
17003 (((it->ascent + it->descent)
17004 * FONT_BASE (font)) / FONT_HEIGHT (font));
17005 saved_pos = it->position;
17006 memset (&it->position, 0, sizeof it->position);
17007 saved_avoid_cursor = it->avoid_cursor_p;
17008 it->avoid_cursor_p = 1;
17009 saved_face_id = it->face_id;
17010 /* The last row's stretch glyph should get the default
17011 face, to avoid painting the rest of the window with
17012 the region face, if the region ends at ZV. */
17013 if (it->glyph_row->ends_at_zv_p)
17014 it->face_id = DEFAULT_FACE_ID;
17015 else
17016 it->face_id = face->id;
17017 append_stretch_glyph (it, make_number (0), stretch_width,
17018 it->ascent + it->descent, stretch_ascent);
17019 it->position = saved_pos;
17020 it->avoid_cursor_p = saved_avoid_cursor;
17021 it->face_id = saved_face_id;
17022 }
17023 }
17024 #endif /* HAVE_WINDOW_SYSTEM */
17025 }
17026 else
17027 {
17028 /* Save some values that must not be changed. */
17029 int saved_x = it->current_x;
17030 struct text_pos saved_pos;
17031 Lisp_Object saved_object;
17032 enum display_element_type saved_what = it->what;
17033 int saved_face_id = it->face_id;
17034
17035 saved_object = it->object;
17036 saved_pos = it->position;
17037
17038 it->what = IT_CHARACTER;
17039 memset (&it->position, 0, sizeof it->position);
17040 it->object = make_number (0);
17041 it->c = it->char_to_display = ' ';
17042 it->len = 1;
17043 /* The last row's blank glyphs should get the default face, to
17044 avoid painting the rest of the window with the region face,
17045 if the region ends at ZV. */
17046 if (it->glyph_row->ends_at_zv_p)
17047 it->face_id = DEFAULT_FACE_ID;
17048 else
17049 it->face_id = face->id;
17050
17051 PRODUCE_GLYPHS (it);
17052
17053 while (it->current_x <= it->last_visible_x)
17054 PRODUCE_GLYPHS (it);
17055
17056 /* Don't count these blanks really. It would let us insert a left
17057 truncation glyph below and make us set the cursor on them, maybe. */
17058 it->current_x = saved_x;
17059 it->object = saved_object;
17060 it->position = saved_pos;
17061 it->what = saved_what;
17062 it->face_id = saved_face_id;
17063 }
17064 }
17065
17066
17067 /* Value is non-zero if text starting at CHARPOS in current_buffer is
17068 trailing whitespace. */
17069
17070 static int
17071 trailing_whitespace_p (EMACS_INT charpos)
17072 {
17073 EMACS_INT bytepos = CHAR_TO_BYTE (charpos);
17074 int c = 0;
17075
17076 while (bytepos < ZV_BYTE
17077 && (c = FETCH_CHAR (bytepos),
17078 c == ' ' || c == '\t'))
17079 ++bytepos;
17080
17081 if (bytepos >= ZV_BYTE || c == '\n' || c == '\r')
17082 {
17083 if (bytepos != PT_BYTE)
17084 return 1;
17085 }
17086 return 0;
17087 }
17088
17089
17090 /* Highlight trailing whitespace, if any, in ROW. */
17091
17092 static void
17093 highlight_trailing_whitespace (struct frame *f, struct glyph_row *row)
17094 {
17095 int used = row->used[TEXT_AREA];
17096
17097 if (used)
17098 {
17099 struct glyph *start = row->glyphs[TEXT_AREA];
17100 struct glyph *glyph = start + used - 1;
17101
17102 if (row->reversed_p)
17103 {
17104 /* Right-to-left rows need to be processed in the opposite
17105 direction, so swap the edge pointers. */
17106 glyph = start;
17107 start = row->glyphs[TEXT_AREA] + used - 1;
17108 }
17109
17110 /* Skip over glyphs inserted to display the cursor at the
17111 end of a line, for extending the face of the last glyph
17112 to the end of the line on terminals, and for truncation
17113 and continuation glyphs. */
17114 if (!row->reversed_p)
17115 {
17116 while (glyph >= start
17117 && glyph->type == CHAR_GLYPH
17118 && INTEGERP (glyph->object))
17119 --glyph;
17120 }
17121 else
17122 {
17123 while (glyph <= start
17124 && glyph->type == CHAR_GLYPH
17125 && INTEGERP (glyph->object))
17126 ++glyph;
17127 }
17128
17129 /* If last glyph is a space or stretch, and it's trailing
17130 whitespace, set the face of all trailing whitespace glyphs in
17131 IT->glyph_row to `trailing-whitespace'. */
17132 if ((row->reversed_p ? glyph <= start : glyph >= start)
17133 && BUFFERP (glyph->object)
17134 && (glyph->type == STRETCH_GLYPH
17135 || (glyph->type == CHAR_GLYPH
17136 && glyph->u.ch == ' '))
17137 && trailing_whitespace_p (glyph->charpos))
17138 {
17139 int face_id = lookup_named_face (f, Qtrailing_whitespace, 0);
17140 if (face_id < 0)
17141 return;
17142
17143 if (!row->reversed_p)
17144 {
17145 while (glyph >= start
17146 && BUFFERP (glyph->object)
17147 && (glyph->type == STRETCH_GLYPH
17148 || (glyph->type == CHAR_GLYPH
17149 && glyph->u.ch == ' ')))
17150 (glyph--)->face_id = face_id;
17151 }
17152 else
17153 {
17154 while (glyph <= start
17155 && BUFFERP (glyph->object)
17156 && (glyph->type == STRETCH_GLYPH
17157 || (glyph->type == CHAR_GLYPH
17158 && glyph->u.ch == ' ')))
17159 (glyph++)->face_id = face_id;
17160 }
17161 }
17162 }
17163 }
17164
17165
17166 /* Value is non-zero if glyph row ROW should be
17167 used to hold the cursor. */
17168
17169 static int
17170 cursor_row_p (struct glyph_row *row)
17171 {
17172 int result = 1;
17173
17174 if (PT == CHARPOS (row->end.pos))
17175 {
17176 /* Suppose the row ends on a string.
17177 Unless the row is continued, that means it ends on a newline
17178 in the string. If it's anything other than a display string
17179 (e.g. a before-string from an overlay), we don't want the
17180 cursor there. (This heuristic seems to give the optimal
17181 behavior for the various types of multi-line strings.) */
17182 if (CHARPOS (row->end.string_pos) >= 0)
17183 {
17184 if (row->continued_p)
17185 result = 1;
17186 else
17187 {
17188 /* Check for `display' property. */
17189 struct glyph *beg = row->glyphs[TEXT_AREA];
17190 struct glyph *end = beg + row->used[TEXT_AREA] - 1;
17191 struct glyph *glyph;
17192
17193 result = 0;
17194 for (glyph = end; glyph >= beg; --glyph)
17195 if (STRINGP (glyph->object))
17196 {
17197 Lisp_Object prop
17198 = Fget_char_property (make_number (PT),
17199 Qdisplay, Qnil);
17200 result =
17201 (!NILP (prop)
17202 && display_prop_string_p (prop, glyph->object));
17203 break;
17204 }
17205 }
17206 }
17207 else if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
17208 {
17209 /* If the row ends in middle of a real character,
17210 and the line is continued, we want the cursor here.
17211 That's because CHARPOS (ROW->end.pos) would equal
17212 PT if PT is before the character. */
17213 if (!row->ends_in_ellipsis_p)
17214 result = row->continued_p;
17215 else
17216 /* If the row ends in an ellipsis, then
17217 CHARPOS (ROW->end.pos) will equal point after the
17218 invisible text. We want that position to be displayed
17219 after the ellipsis. */
17220 result = 0;
17221 }
17222 /* If the row ends at ZV, display the cursor at the end of that
17223 row instead of at the start of the row below. */
17224 else if (row->ends_at_zv_p)
17225 result = 1;
17226 else
17227 result = 0;
17228 }
17229
17230 return result;
17231 }
17232
17233 \f
17234
17235 /* Push the display property PROP so that it will be rendered at the
17236 current position in IT. Return 1 if PROP was successfully pushed,
17237 0 otherwise. */
17238
17239 static int
17240 push_display_prop (struct it *it, Lisp_Object prop)
17241 {
17242 push_it (it, NULL);
17243
17244 if (STRINGP (prop))
17245 {
17246 if (SCHARS (prop) == 0)
17247 {
17248 pop_it (it);
17249 return 0;
17250 }
17251
17252 it->string = prop;
17253 it->multibyte_p = STRING_MULTIBYTE (it->string);
17254 it->current.overlay_string_index = -1;
17255 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
17256 it->end_charpos = it->string_nchars = SCHARS (it->string);
17257 it->method = GET_FROM_STRING;
17258 it->stop_charpos = 0;
17259 }
17260 else if (CONSP (prop) && EQ (XCAR (prop), Qspace))
17261 {
17262 it->method = GET_FROM_STRETCH;
17263 it->object = prop;
17264 }
17265 #ifdef HAVE_WINDOW_SYSTEM
17266 else if (IMAGEP (prop))
17267 {
17268 it->what = IT_IMAGE;
17269 it->image_id = lookup_image (it->f, prop);
17270 it->method = GET_FROM_IMAGE;
17271 }
17272 #endif /* HAVE_WINDOW_SYSTEM */
17273 else
17274 {
17275 pop_it (it); /* bogus display property, give up */
17276 return 0;
17277 }
17278
17279 return 1;
17280 }
17281
17282 /* Return the character-property PROP at the current position in IT. */
17283
17284 static Lisp_Object
17285 get_it_property (struct it *it, Lisp_Object prop)
17286 {
17287 Lisp_Object position;
17288
17289 if (STRINGP (it->object))
17290 position = make_number (IT_STRING_CHARPOS (*it));
17291 else if (BUFFERP (it->object))
17292 position = make_number (IT_CHARPOS (*it));
17293 else
17294 return Qnil;
17295
17296 return Fget_char_property (position, prop, it->object);
17297 }
17298
17299 /* See if there's a line- or wrap-prefix, and if so, push it on IT. */
17300
17301 static void
17302 handle_line_prefix (struct it *it)
17303 {
17304 Lisp_Object prefix;
17305 if (it->continuation_lines_width > 0)
17306 {
17307 prefix = get_it_property (it, Qwrap_prefix);
17308 if (NILP (prefix))
17309 prefix = Vwrap_prefix;
17310 }
17311 else
17312 {
17313 prefix = get_it_property (it, Qline_prefix);
17314 if (NILP (prefix))
17315 prefix = Vline_prefix;
17316 }
17317 if (! NILP (prefix) && push_display_prop (it, prefix))
17318 {
17319 /* If the prefix is wider than the window, and we try to wrap
17320 it, it would acquire its own wrap prefix, and so on till the
17321 iterator stack overflows. So, don't wrap the prefix. */
17322 it->line_wrap = TRUNCATE;
17323 it->avoid_cursor_p = 1;
17324 }
17325 }
17326
17327 \f
17328
17329 /* Remove N glyphs at the start of a reversed IT->glyph_row. Called
17330 only for R2L lines from display_line, when it decides that too many
17331 glyphs were produced by PRODUCE_GLYPHS, and the line needs to be
17332 continued. */
17333 static void
17334 unproduce_glyphs (struct it *it, int n)
17335 {
17336 struct glyph *glyph, *end;
17337
17338 xassert (it->glyph_row);
17339 xassert (it->glyph_row->reversed_p);
17340 xassert (it->area == TEXT_AREA);
17341 xassert (n <= it->glyph_row->used[TEXT_AREA]);
17342
17343 if (n > it->glyph_row->used[TEXT_AREA])
17344 n = it->glyph_row->used[TEXT_AREA];
17345 glyph = it->glyph_row->glyphs[TEXT_AREA] + n;
17346 end = it->glyph_row->glyphs[TEXT_AREA] + it->glyph_row->used[TEXT_AREA];
17347 for ( ; glyph < end; glyph++)
17348 glyph[-n] = *glyph;
17349 }
17350
17351 /* Find the positions in a bidi-reordered ROW to serve as ROW->minpos
17352 and ROW->maxpos. */
17353 static void
17354 find_row_edges (struct it *it, struct glyph_row *row,
17355 EMACS_INT min_pos, EMACS_INT min_bpos,
17356 EMACS_INT max_pos, EMACS_INT max_bpos)
17357 {
17358 /* FIXME: Revisit this when glyph ``spilling'' in continuation
17359 lines' rows is implemented for bidi-reordered rows. */
17360
17361 /* ROW->minpos is the value of min_pos, the minimal buffer position
17362 we have in ROW. */
17363 if (min_pos <= ZV)
17364 SET_TEXT_POS (row->minpos, min_pos, min_bpos);
17365 else
17366 /* We didn't find _any_ valid buffer positions in any of the
17367 glyphs, so we must trust the iterator's computed positions. */
17368 row->minpos = row->start.pos;
17369 if (max_pos <= 0)
17370 {
17371 max_pos = CHARPOS (it->current.pos);
17372 max_bpos = BYTEPOS (it->current.pos);
17373 }
17374
17375 /* Here are the various use-cases for ending the row, and the
17376 corresponding values for ROW->maxpos:
17377
17378 Line ends in a newline from buffer eol_pos + 1
17379 Line is continued from buffer max_pos + 1
17380 Line is truncated on right it->current.pos
17381 Line ends in a newline from string max_pos
17382 Line is continued from string max_pos
17383 Line is continued from display vector max_pos
17384 Line is entirely from a string min_pos == max_pos
17385 Line is entirely from a display vector min_pos == max_pos
17386 Line that ends at ZV ZV
17387
17388 If you discover other use-cases, please add them here as
17389 appropriate. */
17390 if (row->ends_at_zv_p)
17391 row->maxpos = it->current.pos;
17392 else if (row->used[TEXT_AREA])
17393 {
17394 if (row->ends_in_newline_from_string_p)
17395 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
17396 else if (CHARPOS (it->eol_pos) > 0)
17397 SET_TEXT_POS (row->maxpos,
17398 CHARPOS (it->eol_pos) + 1, BYTEPOS (it->eol_pos) + 1);
17399 else if (row->continued_p)
17400 {
17401 /* If max_pos is different from IT's current position, it
17402 means IT->method does not belong to the display element
17403 at max_pos. However, it also means that the display
17404 element at max_pos was displayed in its entirety on this
17405 line, which is equivalent to saying that the next line
17406 starts at the next buffer position. */
17407 if (IT_CHARPOS (*it) == max_pos && it->method != GET_FROM_BUFFER)
17408 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
17409 else
17410 {
17411 INC_BOTH (max_pos, max_bpos);
17412 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
17413 }
17414 }
17415 else if (row->truncated_on_right_p)
17416 /* display_line already called reseat_at_next_visible_line_start,
17417 which puts the iterator at the beginning of the next line, in
17418 the logical order. */
17419 row->maxpos = it->current.pos;
17420 else if (max_pos == min_pos && it->method != GET_FROM_BUFFER)
17421 /* A line that is entirely from a string/image/stretch... */
17422 row->maxpos = row->minpos;
17423 else
17424 abort ();
17425 }
17426 else
17427 row->maxpos = it->current.pos;
17428 }
17429
17430 /* Construct the glyph row IT->glyph_row in the desired matrix of
17431 IT->w from text at the current position of IT. See dispextern.h
17432 for an overview of struct it. Value is non-zero if
17433 IT->glyph_row displays text, as opposed to a line displaying ZV
17434 only. */
17435
17436 static int
17437 display_line (struct it *it)
17438 {
17439 struct glyph_row *row = it->glyph_row;
17440 Lisp_Object overlay_arrow_string;
17441 struct it wrap_it;
17442 int may_wrap = 0, wrap_x IF_LINT (= 0);
17443 int wrap_row_used = -1;
17444 int wrap_row_ascent IF_LINT (= 0), wrap_row_height IF_LINT (= 0);
17445 int wrap_row_phys_ascent IF_LINT (= 0), wrap_row_phys_height IF_LINT (= 0);
17446 int wrap_row_extra_line_spacing IF_LINT (= 0);
17447 EMACS_INT wrap_row_min_pos IF_LINT (= 0), wrap_row_min_bpos IF_LINT (= 0);
17448 EMACS_INT wrap_row_max_pos IF_LINT (= 0), wrap_row_max_bpos IF_LINT (= 0);
17449 int cvpos;
17450 EMACS_INT min_pos = ZV + 1, max_pos = 0;
17451 EMACS_INT min_bpos IF_LINT (= 0), max_bpos IF_LINT (= 0);
17452
17453 /* We always start displaying at hpos zero even if hscrolled. */
17454 xassert (it->hpos == 0 && it->current_x == 0);
17455
17456 if (MATRIX_ROW_VPOS (row, it->w->desired_matrix)
17457 >= it->w->desired_matrix->nrows)
17458 {
17459 it->w->nrows_scale_factor++;
17460 fonts_changed_p = 1;
17461 return 0;
17462 }
17463
17464 /* Is IT->w showing the region? */
17465 it->w->region_showing = it->region_beg_charpos > 0 ? Qt : Qnil;
17466
17467 /* Clear the result glyph row and enable it. */
17468 prepare_desired_row (row);
17469
17470 row->y = it->current_y;
17471 row->start = it->start;
17472 row->continuation_lines_width = it->continuation_lines_width;
17473 row->displays_text_p = 1;
17474 row->starts_in_middle_of_char_p = it->starts_in_middle_of_char_p;
17475 it->starts_in_middle_of_char_p = 0;
17476
17477 /* Arrange the overlays nicely for our purposes. Usually, we call
17478 display_line on only one line at a time, in which case this
17479 can't really hurt too much, or we call it on lines which appear
17480 one after another in the buffer, in which case all calls to
17481 recenter_overlay_lists but the first will be pretty cheap. */
17482 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
17483
17484 /* Move over display elements that are not visible because we are
17485 hscrolled. This may stop at an x-position < IT->first_visible_x
17486 if the first glyph is partially visible or if we hit a line end. */
17487 if (it->current_x < it->first_visible_x)
17488 {
17489 this_line_min_pos = row->start.pos;
17490 move_it_in_display_line_to (it, ZV, it->first_visible_x,
17491 MOVE_TO_POS | MOVE_TO_X);
17492 /* Record the smallest positions seen while we moved over
17493 display elements that are not visible. This is needed by
17494 redisplay_internal for optimizing the case where the cursor
17495 stays inside the same line. The rest of this function only
17496 considers positions that are actually displayed, so
17497 RECORD_MAX_MIN_POS will not otherwise record positions that
17498 are hscrolled to the left of the left edge of the window. */
17499 min_pos = CHARPOS (this_line_min_pos);
17500 min_bpos = BYTEPOS (this_line_min_pos);
17501 }
17502 else
17503 {
17504 /* We only do this when not calling `move_it_in_display_line_to'
17505 above, because move_it_in_display_line_to calls
17506 handle_line_prefix itself. */
17507 handle_line_prefix (it);
17508 }
17509
17510 /* Get the initial row height. This is either the height of the
17511 text hscrolled, if there is any, or zero. */
17512 row->ascent = it->max_ascent;
17513 row->height = it->max_ascent + it->max_descent;
17514 row->phys_ascent = it->max_phys_ascent;
17515 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
17516 row->extra_line_spacing = it->max_extra_line_spacing;
17517
17518 /* Utility macro to record max and min buffer positions seen until now. */
17519 #define RECORD_MAX_MIN_POS(IT) \
17520 do \
17521 { \
17522 if (IT_CHARPOS (*(IT)) < min_pos) \
17523 { \
17524 min_pos = IT_CHARPOS (*(IT)); \
17525 min_bpos = IT_BYTEPOS (*(IT)); \
17526 } \
17527 if (IT_CHARPOS (*(IT)) > max_pos) \
17528 { \
17529 max_pos = IT_CHARPOS (*(IT)); \
17530 max_bpos = IT_BYTEPOS (*(IT)); \
17531 } \
17532 } \
17533 while (0)
17534
17535 /* Loop generating characters. The loop is left with IT on the next
17536 character to display. */
17537 while (1)
17538 {
17539 int n_glyphs_before, hpos_before, x_before;
17540 int x, nglyphs;
17541 int ascent = 0, descent = 0, phys_ascent = 0, phys_descent = 0;
17542
17543 /* Retrieve the next thing to display. Value is zero if end of
17544 buffer reached. */
17545 if (!get_next_display_element (it))
17546 {
17547 /* Maybe add a space at the end of this line that is used to
17548 display the cursor there under X. Set the charpos of the
17549 first glyph of blank lines not corresponding to any text
17550 to -1. */
17551 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
17552 row->exact_window_width_line_p = 1;
17553 else if ((append_space_for_newline (it, 1) && row->used[TEXT_AREA] == 1)
17554 || row->used[TEXT_AREA] == 0)
17555 {
17556 row->glyphs[TEXT_AREA]->charpos = -1;
17557 row->displays_text_p = 0;
17558
17559 if (!NILP (BVAR (XBUFFER (it->w->buffer), indicate_empty_lines))
17560 && (!MINI_WINDOW_P (it->w)
17561 || (minibuf_level && EQ (it->window, minibuf_window))))
17562 row->indicate_empty_line_p = 1;
17563 }
17564
17565 it->continuation_lines_width = 0;
17566 row->ends_at_zv_p = 1;
17567 /* A row that displays right-to-left text must always have
17568 its last face extended all the way to the end of line,
17569 even if this row ends in ZV, because we still write to
17570 the screen left to right. */
17571 if (row->reversed_p)
17572 extend_face_to_end_of_line (it);
17573 break;
17574 }
17575
17576 /* Now, get the metrics of what we want to display. This also
17577 generates glyphs in `row' (which is IT->glyph_row). */
17578 n_glyphs_before = row->used[TEXT_AREA];
17579 x = it->current_x;
17580
17581 /* Remember the line height so far in case the next element doesn't
17582 fit on the line. */
17583 if (it->line_wrap != TRUNCATE)
17584 {
17585 ascent = it->max_ascent;
17586 descent = it->max_descent;
17587 phys_ascent = it->max_phys_ascent;
17588 phys_descent = it->max_phys_descent;
17589
17590 if (it->line_wrap == WORD_WRAP && it->area == TEXT_AREA)
17591 {
17592 if (IT_DISPLAYING_WHITESPACE (it))
17593 may_wrap = 1;
17594 else if (may_wrap)
17595 {
17596 wrap_it = *it;
17597 wrap_x = x;
17598 wrap_row_used = row->used[TEXT_AREA];
17599 wrap_row_ascent = row->ascent;
17600 wrap_row_height = row->height;
17601 wrap_row_phys_ascent = row->phys_ascent;
17602 wrap_row_phys_height = row->phys_height;
17603 wrap_row_extra_line_spacing = row->extra_line_spacing;
17604 wrap_row_min_pos = min_pos;
17605 wrap_row_min_bpos = min_bpos;
17606 wrap_row_max_pos = max_pos;
17607 wrap_row_max_bpos = max_bpos;
17608 may_wrap = 0;
17609 }
17610 }
17611 }
17612
17613 PRODUCE_GLYPHS (it);
17614
17615 /* If this display element was in marginal areas, continue with
17616 the next one. */
17617 if (it->area != TEXT_AREA)
17618 {
17619 row->ascent = max (row->ascent, it->max_ascent);
17620 row->height = max (row->height, it->max_ascent + it->max_descent);
17621 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
17622 row->phys_height = max (row->phys_height,
17623 it->max_phys_ascent + it->max_phys_descent);
17624 row->extra_line_spacing = max (row->extra_line_spacing,
17625 it->max_extra_line_spacing);
17626 set_iterator_to_next (it, 1);
17627 continue;
17628 }
17629
17630 /* Does the display element fit on the line? If we truncate
17631 lines, we should draw past the right edge of the window. If
17632 we don't truncate, we want to stop so that we can display the
17633 continuation glyph before the right margin. If lines are
17634 continued, there are two possible strategies for characters
17635 resulting in more than 1 glyph (e.g. tabs): Display as many
17636 glyphs as possible in this line and leave the rest for the
17637 continuation line, or display the whole element in the next
17638 line. Original redisplay did the former, so we do it also. */
17639 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
17640 hpos_before = it->hpos;
17641 x_before = x;
17642
17643 if (/* Not a newline. */
17644 nglyphs > 0
17645 /* Glyphs produced fit entirely in the line. */
17646 && it->current_x < it->last_visible_x)
17647 {
17648 it->hpos += nglyphs;
17649 row->ascent = max (row->ascent, it->max_ascent);
17650 row->height = max (row->height, it->max_ascent + it->max_descent);
17651 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
17652 row->phys_height = max (row->phys_height,
17653 it->max_phys_ascent + it->max_phys_descent);
17654 row->extra_line_spacing = max (row->extra_line_spacing,
17655 it->max_extra_line_spacing);
17656 if (it->current_x - it->pixel_width < it->first_visible_x)
17657 row->x = x - it->first_visible_x;
17658 /* Record the maximum and minimum buffer positions seen so
17659 far in glyphs that will be displayed by this row. */
17660 if (it->bidi_p)
17661 RECORD_MAX_MIN_POS (it);
17662 }
17663 else
17664 {
17665 int i, new_x;
17666 struct glyph *glyph;
17667
17668 for (i = 0; i < nglyphs; ++i, x = new_x)
17669 {
17670 glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
17671 new_x = x + glyph->pixel_width;
17672
17673 if (/* Lines are continued. */
17674 it->line_wrap != TRUNCATE
17675 && (/* Glyph doesn't fit on the line. */
17676 new_x > it->last_visible_x
17677 /* Or it fits exactly on a window system frame. */
17678 || (new_x == it->last_visible_x
17679 && FRAME_WINDOW_P (it->f))))
17680 {
17681 /* End of a continued line. */
17682
17683 if (it->hpos == 0
17684 || (new_x == it->last_visible_x
17685 && FRAME_WINDOW_P (it->f)))
17686 {
17687 /* Current glyph is the only one on the line or
17688 fits exactly on the line. We must continue
17689 the line because we can't draw the cursor
17690 after the glyph. */
17691 row->continued_p = 1;
17692 it->current_x = new_x;
17693 it->continuation_lines_width += new_x;
17694 ++it->hpos;
17695 /* Record the maximum and minimum buffer
17696 positions seen so far in glyphs that will be
17697 displayed by this row. */
17698 if (it->bidi_p)
17699 RECORD_MAX_MIN_POS (it);
17700 if (i == nglyphs - 1)
17701 {
17702 /* If line-wrap is on, check if a previous
17703 wrap point was found. */
17704 if (wrap_row_used > 0
17705 /* Even if there is a previous wrap
17706 point, continue the line here as
17707 usual, if (i) the previous character
17708 was a space or tab AND (ii) the
17709 current character is not. */
17710 && (!may_wrap
17711 || IT_DISPLAYING_WHITESPACE (it)))
17712 goto back_to_wrap;
17713
17714 set_iterator_to_next (it, 1);
17715 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
17716 {
17717 if (!get_next_display_element (it))
17718 {
17719 row->exact_window_width_line_p = 1;
17720 it->continuation_lines_width = 0;
17721 row->continued_p = 0;
17722 row->ends_at_zv_p = 1;
17723 }
17724 else if (ITERATOR_AT_END_OF_LINE_P (it))
17725 {
17726 row->continued_p = 0;
17727 row->exact_window_width_line_p = 1;
17728 }
17729 }
17730 }
17731 }
17732 else if (CHAR_GLYPH_PADDING_P (*glyph)
17733 && !FRAME_WINDOW_P (it->f))
17734 {
17735 /* A padding glyph that doesn't fit on this line.
17736 This means the whole character doesn't fit
17737 on the line. */
17738 if (row->reversed_p)
17739 unproduce_glyphs (it, row->used[TEXT_AREA]
17740 - n_glyphs_before);
17741 row->used[TEXT_AREA] = n_glyphs_before;
17742
17743 /* Fill the rest of the row with continuation
17744 glyphs like in 20.x. */
17745 while (row->glyphs[TEXT_AREA] + row->used[TEXT_AREA]
17746 < row->glyphs[1 + TEXT_AREA])
17747 produce_special_glyphs (it, IT_CONTINUATION);
17748
17749 row->continued_p = 1;
17750 it->current_x = x_before;
17751 it->continuation_lines_width += x_before;
17752
17753 /* Restore the height to what it was before the
17754 element not fitting on the line. */
17755 it->max_ascent = ascent;
17756 it->max_descent = descent;
17757 it->max_phys_ascent = phys_ascent;
17758 it->max_phys_descent = phys_descent;
17759 }
17760 else if (wrap_row_used > 0)
17761 {
17762 back_to_wrap:
17763 if (row->reversed_p)
17764 unproduce_glyphs (it,
17765 row->used[TEXT_AREA] - wrap_row_used);
17766 *it = wrap_it;
17767 it->continuation_lines_width += wrap_x;
17768 row->used[TEXT_AREA] = wrap_row_used;
17769 row->ascent = wrap_row_ascent;
17770 row->height = wrap_row_height;
17771 row->phys_ascent = wrap_row_phys_ascent;
17772 row->phys_height = wrap_row_phys_height;
17773 row->extra_line_spacing = wrap_row_extra_line_spacing;
17774 min_pos = wrap_row_min_pos;
17775 min_bpos = wrap_row_min_bpos;
17776 max_pos = wrap_row_max_pos;
17777 max_bpos = wrap_row_max_bpos;
17778 row->continued_p = 1;
17779 row->ends_at_zv_p = 0;
17780 row->exact_window_width_line_p = 0;
17781 it->continuation_lines_width += x;
17782
17783 /* Make sure that a non-default face is extended
17784 up to the right margin of the window. */
17785 extend_face_to_end_of_line (it);
17786 }
17787 else if (it->c == '\t' && FRAME_WINDOW_P (it->f))
17788 {
17789 /* A TAB that extends past the right edge of the
17790 window. This produces a single glyph on
17791 window system frames. We leave the glyph in
17792 this row and let it fill the row, but don't
17793 consume the TAB. */
17794 it->continuation_lines_width += it->last_visible_x;
17795 row->ends_in_middle_of_char_p = 1;
17796 row->continued_p = 1;
17797 glyph->pixel_width = it->last_visible_x - x;
17798 it->starts_in_middle_of_char_p = 1;
17799 }
17800 else
17801 {
17802 /* Something other than a TAB that draws past
17803 the right edge of the window. Restore
17804 positions to values before the element. */
17805 if (row->reversed_p)
17806 unproduce_glyphs (it, row->used[TEXT_AREA]
17807 - (n_glyphs_before + i));
17808 row->used[TEXT_AREA] = n_glyphs_before + i;
17809
17810 /* Display continuation glyphs. */
17811 if (!FRAME_WINDOW_P (it->f))
17812 produce_special_glyphs (it, IT_CONTINUATION);
17813 row->continued_p = 1;
17814
17815 it->current_x = x_before;
17816 it->continuation_lines_width += x;
17817 extend_face_to_end_of_line (it);
17818
17819 if (nglyphs > 1 && i > 0)
17820 {
17821 row->ends_in_middle_of_char_p = 1;
17822 it->starts_in_middle_of_char_p = 1;
17823 }
17824
17825 /* Restore the height to what it was before the
17826 element not fitting on the line. */
17827 it->max_ascent = ascent;
17828 it->max_descent = descent;
17829 it->max_phys_ascent = phys_ascent;
17830 it->max_phys_descent = phys_descent;
17831 }
17832
17833 break;
17834 }
17835 else if (new_x > it->first_visible_x)
17836 {
17837 /* Increment number of glyphs actually displayed. */
17838 ++it->hpos;
17839
17840 /* Record the maximum and minimum buffer positions
17841 seen so far in glyphs that will be displayed by
17842 this row. */
17843 if (it->bidi_p)
17844 RECORD_MAX_MIN_POS (it);
17845
17846 if (x < it->first_visible_x)
17847 /* Glyph is partially visible, i.e. row starts at
17848 negative X position. */
17849 row->x = x - it->first_visible_x;
17850 }
17851 else
17852 {
17853 /* Glyph is completely off the left margin of the
17854 window. This should not happen because of the
17855 move_it_in_display_line at the start of this
17856 function, unless the text display area of the
17857 window is empty. */
17858 xassert (it->first_visible_x <= it->last_visible_x);
17859 }
17860 }
17861
17862 row->ascent = max (row->ascent, it->max_ascent);
17863 row->height = max (row->height, it->max_ascent + it->max_descent);
17864 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
17865 row->phys_height = max (row->phys_height,
17866 it->max_phys_ascent + it->max_phys_descent);
17867 row->extra_line_spacing = max (row->extra_line_spacing,
17868 it->max_extra_line_spacing);
17869
17870 /* End of this display line if row is continued. */
17871 if (row->continued_p || row->ends_at_zv_p)
17872 break;
17873 }
17874
17875 at_end_of_line:
17876 /* Is this a line end? If yes, we're also done, after making
17877 sure that a non-default face is extended up to the right
17878 margin of the window. */
17879 if (ITERATOR_AT_END_OF_LINE_P (it))
17880 {
17881 int used_before = row->used[TEXT_AREA];
17882
17883 row->ends_in_newline_from_string_p = STRINGP (it->object);
17884
17885 /* Add a space at the end of the line that is used to
17886 display the cursor there. */
17887 if (!IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
17888 append_space_for_newline (it, 0);
17889
17890 /* Extend the face to the end of the line. */
17891 extend_face_to_end_of_line (it);
17892
17893 /* Make sure we have the position. */
17894 if (used_before == 0)
17895 row->glyphs[TEXT_AREA]->charpos = CHARPOS (it->position);
17896
17897 /* Record the position of the newline, for use in
17898 find_row_edges. */
17899 it->eol_pos = it->current.pos;
17900
17901 /* Consume the line end. This skips over invisible lines. */
17902 set_iterator_to_next (it, 1);
17903 it->continuation_lines_width = 0;
17904 break;
17905 }
17906
17907 /* Proceed with next display element. Note that this skips
17908 over lines invisible because of selective display. */
17909 set_iterator_to_next (it, 1);
17910
17911 /* If we truncate lines, we are done when the last displayed
17912 glyphs reach past the right margin of the window. */
17913 if (it->line_wrap == TRUNCATE
17914 && (FRAME_WINDOW_P (it->f)
17915 ? (it->current_x >= it->last_visible_x)
17916 : (it->current_x > it->last_visible_x)))
17917 {
17918 /* Maybe add truncation glyphs. */
17919 if (!FRAME_WINDOW_P (it->f))
17920 {
17921 int i, n;
17922
17923 if (!row->reversed_p)
17924 {
17925 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
17926 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
17927 break;
17928 }
17929 else
17930 {
17931 for (i = 0; i < row->used[TEXT_AREA]; i++)
17932 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
17933 break;
17934 /* Remove any padding glyphs at the front of ROW, to
17935 make room for the truncation glyphs we will be
17936 adding below. The loop below always inserts at
17937 least one truncation glyph, so also remove the
17938 last glyph added to ROW. */
17939 unproduce_glyphs (it, i + 1);
17940 /* Adjust i for the loop below. */
17941 i = row->used[TEXT_AREA] - (i + 1);
17942 }
17943
17944 for (n = row->used[TEXT_AREA]; i < n; ++i)
17945 {
17946 row->used[TEXT_AREA] = i;
17947 produce_special_glyphs (it, IT_TRUNCATION);
17948 }
17949 }
17950 else if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
17951 {
17952 /* Don't truncate if we can overflow newline into fringe. */
17953 if (!get_next_display_element (it))
17954 {
17955 it->continuation_lines_width = 0;
17956 row->ends_at_zv_p = 1;
17957 row->exact_window_width_line_p = 1;
17958 break;
17959 }
17960 if (ITERATOR_AT_END_OF_LINE_P (it))
17961 {
17962 row->exact_window_width_line_p = 1;
17963 goto at_end_of_line;
17964 }
17965 }
17966
17967 row->truncated_on_right_p = 1;
17968 it->continuation_lines_width = 0;
17969 reseat_at_next_visible_line_start (it, 0);
17970 row->ends_at_zv_p = FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n';
17971 it->hpos = hpos_before;
17972 it->current_x = x_before;
17973 break;
17974 }
17975 }
17976
17977 /* If line is not empty and hscrolled, maybe insert truncation glyphs
17978 at the left window margin. */
17979 if (it->first_visible_x
17980 && IT_CHARPOS (*it) != CHARPOS (row->start.pos))
17981 {
17982 if (!FRAME_WINDOW_P (it->f))
17983 insert_left_trunc_glyphs (it);
17984 row->truncated_on_left_p = 1;
17985 }
17986
17987 /* Remember the position at which this line ends.
17988
17989 BIDI Note: any code that needs MATRIX_ROW_START/END_CHARPOS
17990 cannot be before the call to find_row_edges below, since that is
17991 where these positions are determined. */
17992 row->end = it->current;
17993 if (!it->bidi_p)
17994 {
17995 row->minpos = row->start.pos;
17996 row->maxpos = row->end.pos;
17997 }
17998 else
17999 {
18000 /* ROW->minpos and ROW->maxpos must be the smallest and
18001 `1 + the largest' buffer positions in ROW. But if ROW was
18002 bidi-reordered, these two positions can be anywhere in the
18003 row, so we must determine them now. */
18004 find_row_edges (it, row, min_pos, min_bpos, max_pos, max_bpos);
18005 }
18006
18007 /* If the start of this line is the overlay arrow-position, then
18008 mark this glyph row as the one containing the overlay arrow.
18009 This is clearly a mess with variable size fonts. It would be
18010 better to let it be displayed like cursors under X. */
18011 if ((row->displays_text_p || !overlay_arrow_seen)
18012 && (overlay_arrow_string = overlay_arrow_at_row (it, row),
18013 !NILP (overlay_arrow_string)))
18014 {
18015 /* Overlay arrow in window redisplay is a fringe bitmap. */
18016 if (STRINGP (overlay_arrow_string))
18017 {
18018 struct glyph_row *arrow_row
18019 = get_overlay_arrow_glyph_row (it->w, overlay_arrow_string);
18020 struct glyph *glyph = arrow_row->glyphs[TEXT_AREA];
18021 struct glyph *arrow_end = glyph + arrow_row->used[TEXT_AREA];
18022 struct glyph *p = row->glyphs[TEXT_AREA];
18023 struct glyph *p2, *end;
18024
18025 /* Copy the arrow glyphs. */
18026 while (glyph < arrow_end)
18027 *p++ = *glyph++;
18028
18029 /* Throw away padding glyphs. */
18030 p2 = p;
18031 end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
18032 while (p2 < end && CHAR_GLYPH_PADDING_P (*p2))
18033 ++p2;
18034 if (p2 > p)
18035 {
18036 while (p2 < end)
18037 *p++ = *p2++;
18038 row->used[TEXT_AREA] = p2 - row->glyphs[TEXT_AREA];
18039 }
18040 }
18041 else
18042 {
18043 xassert (INTEGERP (overlay_arrow_string));
18044 row->overlay_arrow_bitmap = XINT (overlay_arrow_string);
18045 }
18046 overlay_arrow_seen = 1;
18047 }
18048
18049 /* Compute pixel dimensions of this line. */
18050 compute_line_metrics (it);
18051
18052 /* Record whether this row ends inside an ellipsis. */
18053 row->ends_in_ellipsis_p
18054 = (it->method == GET_FROM_DISPLAY_VECTOR
18055 && it->ellipsis_p);
18056
18057 /* Save fringe bitmaps in this row. */
18058 row->left_user_fringe_bitmap = it->left_user_fringe_bitmap;
18059 row->left_user_fringe_face_id = it->left_user_fringe_face_id;
18060 row->right_user_fringe_bitmap = it->right_user_fringe_bitmap;
18061 row->right_user_fringe_face_id = it->right_user_fringe_face_id;
18062
18063 it->left_user_fringe_bitmap = 0;
18064 it->left_user_fringe_face_id = 0;
18065 it->right_user_fringe_bitmap = 0;
18066 it->right_user_fringe_face_id = 0;
18067
18068 /* Maybe set the cursor. */
18069 cvpos = it->w->cursor.vpos;
18070 if ((cvpos < 0
18071 /* In bidi-reordered rows, keep checking for proper cursor
18072 position even if one has been found already, because buffer
18073 positions in such rows change non-linearly with ROW->VPOS,
18074 when a line is continued. One exception: when we are at ZV,
18075 display cursor on the first suitable glyph row, since all
18076 the empty rows after that also have their position set to ZV. */
18077 /* FIXME: Revisit this when glyph ``spilling'' in continuation
18078 lines' rows is implemented for bidi-reordered rows. */
18079 || (it->bidi_p
18080 && !MATRIX_ROW (it->w->desired_matrix, cvpos)->ends_at_zv_p))
18081 && PT >= MATRIX_ROW_START_CHARPOS (row)
18082 && PT <= MATRIX_ROW_END_CHARPOS (row)
18083 && cursor_row_p (row))
18084 set_cursor_from_row (it->w, row, it->w->desired_matrix, 0, 0, 0, 0);
18085
18086 /* Highlight trailing whitespace. */
18087 if (!NILP (Vshow_trailing_whitespace))
18088 highlight_trailing_whitespace (it->f, it->glyph_row);
18089
18090 /* Prepare for the next line. This line starts horizontally at (X
18091 HPOS) = (0 0). Vertical positions are incremented. As a
18092 convenience for the caller, IT->glyph_row is set to the next
18093 row to be used. */
18094 it->current_x = it->hpos = 0;
18095 it->current_y += row->height;
18096 SET_TEXT_POS (it->eol_pos, 0, 0);
18097 ++it->vpos;
18098 ++it->glyph_row;
18099 /* The next row should by default use the same value of the
18100 reversed_p flag as this one. set_iterator_to_next decides when
18101 it's a new paragraph, and PRODUCE_GLYPHS recomputes the value of
18102 the flag accordingly. */
18103 if (it->glyph_row < MATRIX_BOTTOM_TEXT_ROW (it->w->desired_matrix, it->w))
18104 it->glyph_row->reversed_p = row->reversed_p;
18105 it->start = row->end;
18106 return row->displays_text_p;
18107
18108 #undef RECORD_MAX_MIN_POS
18109 }
18110
18111 DEFUN ("current-bidi-paragraph-direction", Fcurrent_bidi_paragraph_direction,
18112 Scurrent_bidi_paragraph_direction, 0, 1, 0,
18113 doc: /* Return paragraph direction at point in BUFFER.
18114 Value is either `left-to-right' or `right-to-left'.
18115 If BUFFER is omitted or nil, it defaults to the current buffer.
18116
18117 Paragraph direction determines how the text in the paragraph is displayed.
18118 In left-to-right paragraphs, text begins at the left margin of the window
18119 and the reading direction is generally left to right. In right-to-left
18120 paragraphs, text begins at the right margin and is read from right to left.
18121
18122 See also `bidi-paragraph-direction'. */)
18123 (Lisp_Object buffer)
18124 {
18125 struct buffer *buf = current_buffer;
18126 struct buffer *old = buf;
18127
18128 if (! NILP (buffer))
18129 {
18130 CHECK_BUFFER (buffer);
18131 buf = XBUFFER (buffer);
18132 }
18133
18134 if (NILP (BVAR (buf, bidi_display_reordering)))
18135 return Qleft_to_right;
18136 else if (!NILP (BVAR (buf, bidi_paragraph_direction)))
18137 return BVAR (buf, bidi_paragraph_direction);
18138 else
18139 {
18140 /* Determine the direction from buffer text. We could try to
18141 use current_matrix if it is up to date, but this seems fast
18142 enough as it is. */
18143 struct bidi_it itb;
18144 EMACS_INT pos = BUF_PT (buf);
18145 EMACS_INT bytepos = BUF_PT_BYTE (buf);
18146 int c;
18147
18148 set_buffer_temp (buf);
18149 /* bidi_paragraph_init finds the base direction of the paragraph
18150 by searching forward from paragraph start. We need the base
18151 direction of the current or _previous_ paragraph, so we need
18152 to make sure we are within that paragraph. To that end, find
18153 the previous non-empty line. */
18154 if (pos >= ZV && pos > BEGV)
18155 {
18156 pos--;
18157 bytepos = CHAR_TO_BYTE (pos);
18158 }
18159 while ((c = FETCH_BYTE (bytepos)) == '\n'
18160 || c == ' ' || c == '\t' || c == '\f')
18161 {
18162 if (bytepos <= BEGV_BYTE)
18163 break;
18164 bytepos--;
18165 pos--;
18166 }
18167 while (!CHAR_HEAD_P (FETCH_BYTE (bytepos)))
18168 bytepos--;
18169 itb.charpos = pos;
18170 itb.bytepos = bytepos;
18171 itb.nchars = -1;
18172 itb.frame_window_p = FRAME_WINDOW_P (SELECTED_FRAME ()); /* guesswork */
18173 itb.first_elt = 1;
18174 itb.separator_limit = -1;
18175 itb.paragraph_dir = NEUTRAL_DIR;
18176
18177 bidi_paragraph_init (NEUTRAL_DIR, &itb, 1);
18178 set_buffer_temp (old);
18179 switch (itb.paragraph_dir)
18180 {
18181 case L2R:
18182 return Qleft_to_right;
18183 break;
18184 case R2L:
18185 return Qright_to_left;
18186 break;
18187 default:
18188 abort ();
18189 }
18190 }
18191 }
18192
18193
18194 \f
18195 /***********************************************************************
18196 Menu Bar
18197 ***********************************************************************/
18198
18199 /* Redisplay the menu bar in the frame for window W.
18200
18201 The menu bar of X frames that don't have X toolkit support is
18202 displayed in a special window W->frame->menu_bar_window.
18203
18204 The menu bar of terminal frames is treated specially as far as
18205 glyph matrices are concerned. Menu bar lines are not part of
18206 windows, so the update is done directly on the frame matrix rows
18207 for the menu bar. */
18208
18209 static void
18210 display_menu_bar (struct window *w)
18211 {
18212 struct frame *f = XFRAME (WINDOW_FRAME (w));
18213 struct it it;
18214 Lisp_Object items;
18215 int i;
18216
18217 /* Don't do all this for graphical frames. */
18218 #ifdef HAVE_NTGUI
18219 if (FRAME_W32_P (f))
18220 return;
18221 #endif
18222 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
18223 if (FRAME_X_P (f))
18224 return;
18225 #endif
18226
18227 #ifdef HAVE_NS
18228 if (FRAME_NS_P (f))
18229 return;
18230 #endif /* HAVE_NS */
18231
18232 #ifdef USE_X_TOOLKIT
18233 xassert (!FRAME_WINDOW_P (f));
18234 init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MENU_FACE_ID);
18235 it.first_visible_x = 0;
18236 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
18237 #else /* not USE_X_TOOLKIT */
18238 if (FRAME_WINDOW_P (f))
18239 {
18240 /* Menu bar lines are displayed in the desired matrix of the
18241 dummy window menu_bar_window. */
18242 struct window *menu_w;
18243 xassert (WINDOWP (f->menu_bar_window));
18244 menu_w = XWINDOW (f->menu_bar_window);
18245 init_iterator (&it, menu_w, -1, -1, menu_w->desired_matrix->rows,
18246 MENU_FACE_ID);
18247 it.first_visible_x = 0;
18248 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
18249 }
18250 else
18251 {
18252 /* This is a TTY frame, i.e. character hpos/vpos are used as
18253 pixel x/y. */
18254 init_iterator (&it, w, -1, -1, f->desired_matrix->rows,
18255 MENU_FACE_ID);
18256 it.first_visible_x = 0;
18257 it.last_visible_x = FRAME_COLS (f);
18258 }
18259 #endif /* not USE_X_TOOLKIT */
18260
18261 if (! mode_line_inverse_video)
18262 /* Force the menu-bar to be displayed in the default face. */
18263 it.base_face_id = it.face_id = DEFAULT_FACE_ID;
18264
18265 /* Clear all rows of the menu bar. */
18266 for (i = 0; i < FRAME_MENU_BAR_LINES (f); ++i)
18267 {
18268 struct glyph_row *row = it.glyph_row + i;
18269 clear_glyph_row (row);
18270 row->enabled_p = 1;
18271 row->full_width_p = 1;
18272 }
18273
18274 /* Display all items of the menu bar. */
18275 items = FRAME_MENU_BAR_ITEMS (it.f);
18276 for (i = 0; i < ASIZE (items); i += 4)
18277 {
18278 Lisp_Object string;
18279
18280 /* Stop at nil string. */
18281 string = AREF (items, i + 1);
18282 if (NILP (string))
18283 break;
18284
18285 /* Remember where item was displayed. */
18286 ASET (items, i + 3, make_number (it.hpos));
18287
18288 /* Display the item, pad with one space. */
18289 if (it.current_x < it.last_visible_x)
18290 display_string (NULL, string, Qnil, 0, 0, &it,
18291 SCHARS (string) + 1, 0, 0, -1);
18292 }
18293
18294 /* Fill out the line with spaces. */
18295 if (it.current_x < it.last_visible_x)
18296 display_string ("", Qnil, Qnil, 0, 0, &it, -1, 0, 0, -1);
18297
18298 /* Compute the total height of the lines. */
18299 compute_line_metrics (&it);
18300 }
18301
18302
18303 \f
18304 /***********************************************************************
18305 Mode Line
18306 ***********************************************************************/
18307
18308 /* Redisplay mode lines in the window tree whose root is WINDOW. If
18309 FORCE is non-zero, redisplay mode lines unconditionally.
18310 Otherwise, redisplay only mode lines that are garbaged. Value is
18311 the number of windows whose mode lines were redisplayed. */
18312
18313 static int
18314 redisplay_mode_lines (Lisp_Object window, int force)
18315 {
18316 int nwindows = 0;
18317
18318 while (!NILP (window))
18319 {
18320 struct window *w = XWINDOW (window);
18321
18322 if (WINDOWP (w->hchild))
18323 nwindows += redisplay_mode_lines (w->hchild, force);
18324 else if (WINDOWP (w->vchild))
18325 nwindows += redisplay_mode_lines (w->vchild, force);
18326 else if (force
18327 || FRAME_GARBAGED_P (XFRAME (w->frame))
18328 || !MATRIX_MODE_LINE_ROW (w->current_matrix)->enabled_p)
18329 {
18330 struct text_pos lpoint;
18331 struct buffer *old = current_buffer;
18332
18333 /* Set the window's buffer for the mode line display. */
18334 SET_TEXT_POS (lpoint, PT, PT_BYTE);
18335 set_buffer_internal_1 (XBUFFER (w->buffer));
18336
18337 /* Point refers normally to the selected window. For any
18338 other window, set up appropriate value. */
18339 if (!EQ (window, selected_window))
18340 {
18341 struct text_pos pt;
18342
18343 SET_TEXT_POS_FROM_MARKER (pt, w->pointm);
18344 if (CHARPOS (pt) < BEGV)
18345 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
18346 else if (CHARPOS (pt) > (ZV - 1))
18347 TEMP_SET_PT_BOTH (ZV, ZV_BYTE);
18348 else
18349 TEMP_SET_PT_BOTH (CHARPOS (pt), BYTEPOS (pt));
18350 }
18351
18352 /* Display mode lines. */
18353 clear_glyph_matrix (w->desired_matrix);
18354 if (display_mode_lines (w))
18355 {
18356 ++nwindows;
18357 w->must_be_updated_p = 1;
18358 }
18359
18360 /* Restore old settings. */
18361 set_buffer_internal_1 (old);
18362 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
18363 }
18364
18365 window = w->next;
18366 }
18367
18368 return nwindows;
18369 }
18370
18371
18372 /* Display the mode and/or header line of window W. Value is the
18373 sum number of mode lines and header lines displayed. */
18374
18375 static int
18376 display_mode_lines (struct window *w)
18377 {
18378 Lisp_Object old_selected_window, old_selected_frame;
18379 int n = 0;
18380
18381 old_selected_frame = selected_frame;
18382 selected_frame = w->frame;
18383 old_selected_window = selected_window;
18384 XSETWINDOW (selected_window, w);
18385
18386 /* These will be set while the mode line specs are processed. */
18387 line_number_displayed = 0;
18388 w->column_number_displayed = Qnil;
18389
18390 if (WINDOW_WANTS_MODELINE_P (w))
18391 {
18392 struct window *sel_w = XWINDOW (old_selected_window);
18393
18394 /* Select mode line face based on the real selected window. */
18395 display_mode_line (w, CURRENT_MODE_LINE_FACE_ID_3 (sel_w, sel_w, w),
18396 BVAR (current_buffer, mode_line_format));
18397 ++n;
18398 }
18399
18400 if (WINDOW_WANTS_HEADER_LINE_P (w))
18401 {
18402 display_mode_line (w, HEADER_LINE_FACE_ID,
18403 BVAR (current_buffer, header_line_format));
18404 ++n;
18405 }
18406
18407 selected_frame = old_selected_frame;
18408 selected_window = old_selected_window;
18409 return n;
18410 }
18411
18412
18413 /* Display mode or header line of window W. FACE_ID specifies which
18414 line to display; it is either MODE_LINE_FACE_ID or
18415 HEADER_LINE_FACE_ID. FORMAT is the mode/header line format to
18416 display. Value is the pixel height of the mode/header line
18417 displayed. */
18418
18419 static int
18420 display_mode_line (struct window *w, enum face_id face_id, Lisp_Object format)
18421 {
18422 struct it it;
18423 struct face *face;
18424 int count = SPECPDL_INDEX ();
18425
18426 init_iterator (&it, w, -1, -1, NULL, face_id);
18427 /* Don't extend on a previously drawn mode-line.
18428 This may happen if called from pos_visible_p. */
18429 it.glyph_row->enabled_p = 0;
18430 prepare_desired_row (it.glyph_row);
18431
18432 it.glyph_row->mode_line_p = 1;
18433
18434 if (! mode_line_inverse_video)
18435 /* Force the mode-line to be displayed in the default face. */
18436 it.base_face_id = it.face_id = DEFAULT_FACE_ID;
18437
18438 record_unwind_protect (unwind_format_mode_line,
18439 format_mode_line_unwind_data (NULL, Qnil, 0));
18440
18441 mode_line_target = MODE_LINE_DISPLAY;
18442
18443 /* Temporarily make frame's keyboard the current kboard so that
18444 kboard-local variables in the mode_line_format will get the right
18445 values. */
18446 push_kboard (FRAME_KBOARD (it.f));
18447 record_unwind_save_match_data ();
18448 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
18449 pop_kboard ();
18450
18451 unbind_to (count, Qnil);
18452
18453 /* Fill up with spaces. */
18454 display_string (" ", Qnil, Qnil, 0, 0, &it, 10000, -1, -1, 0);
18455
18456 compute_line_metrics (&it);
18457 it.glyph_row->full_width_p = 1;
18458 it.glyph_row->continued_p = 0;
18459 it.glyph_row->truncated_on_left_p = 0;
18460 it.glyph_row->truncated_on_right_p = 0;
18461
18462 /* Make a 3D mode-line have a shadow at its right end. */
18463 face = FACE_FROM_ID (it.f, face_id);
18464 extend_face_to_end_of_line (&it);
18465 if (face->box != FACE_NO_BOX)
18466 {
18467 struct glyph *last = (it.glyph_row->glyphs[TEXT_AREA]
18468 + it.glyph_row->used[TEXT_AREA] - 1);
18469 last->right_box_line_p = 1;
18470 }
18471
18472 return it.glyph_row->height;
18473 }
18474
18475 /* Move element ELT in LIST to the front of LIST.
18476 Return the updated list. */
18477
18478 static Lisp_Object
18479 move_elt_to_front (Lisp_Object elt, Lisp_Object list)
18480 {
18481 register Lisp_Object tail, prev;
18482 register Lisp_Object tem;
18483
18484 tail = list;
18485 prev = Qnil;
18486 while (CONSP (tail))
18487 {
18488 tem = XCAR (tail);
18489
18490 if (EQ (elt, tem))
18491 {
18492 /* Splice out the link TAIL. */
18493 if (NILP (prev))
18494 list = XCDR (tail);
18495 else
18496 Fsetcdr (prev, XCDR (tail));
18497
18498 /* Now make it the first. */
18499 Fsetcdr (tail, list);
18500 return tail;
18501 }
18502 else
18503 prev = tail;
18504 tail = XCDR (tail);
18505 QUIT;
18506 }
18507
18508 /* Not found--return unchanged LIST. */
18509 return list;
18510 }
18511
18512 /* Contribute ELT to the mode line for window IT->w. How it
18513 translates into text depends on its data type.
18514
18515 IT describes the display environment in which we display, as usual.
18516
18517 DEPTH is the depth in recursion. It is used to prevent
18518 infinite recursion here.
18519
18520 FIELD_WIDTH is the number of characters the display of ELT should
18521 occupy in the mode line, and PRECISION is the maximum number of
18522 characters to display from ELT's representation. See
18523 display_string for details.
18524
18525 Returns the hpos of the end of the text generated by ELT.
18526
18527 PROPS is a property list to add to any string we encounter.
18528
18529 If RISKY is nonzero, remove (disregard) any properties in any string
18530 we encounter, and ignore :eval and :propertize.
18531
18532 The global variable `mode_line_target' determines whether the
18533 output is passed to `store_mode_line_noprop',
18534 `store_mode_line_string', or `display_string'. */
18535
18536 static int
18537 display_mode_element (struct it *it, int depth, int field_width, int precision,
18538 Lisp_Object elt, Lisp_Object props, int risky)
18539 {
18540 int n = 0, field, prec;
18541 int literal = 0;
18542
18543 tail_recurse:
18544 if (depth > 100)
18545 elt = build_string ("*too-deep*");
18546
18547 depth++;
18548
18549 switch (SWITCH_ENUM_CAST (XTYPE (elt)))
18550 {
18551 case Lisp_String:
18552 {
18553 /* A string: output it and check for %-constructs within it. */
18554 unsigned char c;
18555 EMACS_INT offset = 0;
18556
18557 if (SCHARS (elt) > 0
18558 && (!NILP (props) || risky))
18559 {
18560 Lisp_Object oprops, aelt;
18561 oprops = Ftext_properties_at (make_number (0), elt);
18562
18563 /* If the starting string's properties are not what
18564 we want, translate the string. Also, if the string
18565 is risky, do that anyway. */
18566
18567 if (NILP (Fequal (props, oprops)) || risky)
18568 {
18569 /* If the starting string has properties,
18570 merge the specified ones onto the existing ones. */
18571 if (! NILP (oprops) && !risky)
18572 {
18573 Lisp_Object tem;
18574
18575 oprops = Fcopy_sequence (oprops);
18576 tem = props;
18577 while (CONSP (tem))
18578 {
18579 oprops = Fplist_put (oprops, XCAR (tem),
18580 XCAR (XCDR (tem)));
18581 tem = XCDR (XCDR (tem));
18582 }
18583 props = oprops;
18584 }
18585
18586 aelt = Fassoc (elt, mode_line_proptrans_alist);
18587 if (! NILP (aelt) && !NILP (Fequal (props, XCDR (aelt))))
18588 {
18589 /* AELT is what we want. Move it to the front
18590 without consing. */
18591 elt = XCAR (aelt);
18592 mode_line_proptrans_alist
18593 = move_elt_to_front (aelt, mode_line_proptrans_alist);
18594 }
18595 else
18596 {
18597 Lisp_Object tem;
18598
18599 /* If AELT has the wrong props, it is useless.
18600 so get rid of it. */
18601 if (! NILP (aelt))
18602 mode_line_proptrans_alist
18603 = Fdelq (aelt, mode_line_proptrans_alist);
18604
18605 elt = Fcopy_sequence (elt);
18606 Fset_text_properties (make_number (0), Flength (elt),
18607 props, elt);
18608 /* Add this item to mode_line_proptrans_alist. */
18609 mode_line_proptrans_alist
18610 = Fcons (Fcons (elt, props),
18611 mode_line_proptrans_alist);
18612 /* Truncate mode_line_proptrans_alist
18613 to at most 50 elements. */
18614 tem = Fnthcdr (make_number (50),
18615 mode_line_proptrans_alist);
18616 if (! NILP (tem))
18617 XSETCDR (tem, Qnil);
18618 }
18619 }
18620 }
18621
18622 offset = 0;
18623
18624 if (literal)
18625 {
18626 prec = precision - n;
18627 switch (mode_line_target)
18628 {
18629 case MODE_LINE_NOPROP:
18630 case MODE_LINE_TITLE:
18631 n += store_mode_line_noprop (SSDATA (elt), -1, prec);
18632 break;
18633 case MODE_LINE_STRING:
18634 n += store_mode_line_string (NULL, elt, 1, 0, prec, Qnil);
18635 break;
18636 case MODE_LINE_DISPLAY:
18637 n += display_string (NULL, elt, Qnil, 0, 0, it,
18638 0, prec, 0, STRING_MULTIBYTE (elt));
18639 break;
18640 }
18641
18642 break;
18643 }
18644
18645 /* Handle the non-literal case. */
18646
18647 while ((precision <= 0 || n < precision)
18648 && SREF (elt, offset) != 0
18649 && (mode_line_target != MODE_LINE_DISPLAY
18650 || it->current_x < it->last_visible_x))
18651 {
18652 EMACS_INT last_offset = offset;
18653
18654 /* Advance to end of string or next format specifier. */
18655 while ((c = SREF (elt, offset++)) != '\0' && c != '%')
18656 ;
18657
18658 if (offset - 1 != last_offset)
18659 {
18660 EMACS_INT nchars, nbytes;
18661
18662 /* Output to end of string or up to '%'. Field width
18663 is length of string. Don't output more than
18664 PRECISION allows us. */
18665 offset--;
18666
18667 prec = c_string_width (SDATA (elt) + last_offset,
18668 offset - last_offset, precision - n,
18669 &nchars, &nbytes);
18670
18671 switch (mode_line_target)
18672 {
18673 case MODE_LINE_NOPROP:
18674 case MODE_LINE_TITLE:
18675 n += store_mode_line_noprop (SSDATA (elt) + last_offset, 0, prec);
18676 break;
18677 case MODE_LINE_STRING:
18678 {
18679 EMACS_INT bytepos = last_offset;
18680 EMACS_INT charpos = string_byte_to_char (elt, bytepos);
18681 EMACS_INT endpos = (precision <= 0
18682 ? string_byte_to_char (elt, offset)
18683 : charpos + nchars);
18684
18685 n += store_mode_line_string (NULL,
18686 Fsubstring (elt, make_number (charpos),
18687 make_number (endpos)),
18688 0, 0, 0, Qnil);
18689 }
18690 break;
18691 case MODE_LINE_DISPLAY:
18692 {
18693 EMACS_INT bytepos = last_offset;
18694 EMACS_INT charpos = string_byte_to_char (elt, bytepos);
18695
18696 if (precision <= 0)
18697 nchars = string_byte_to_char (elt, offset) - charpos;
18698 n += display_string (NULL, elt, Qnil, 0, charpos,
18699 it, 0, nchars, 0,
18700 STRING_MULTIBYTE (elt));
18701 }
18702 break;
18703 }
18704 }
18705 else /* c == '%' */
18706 {
18707 EMACS_INT percent_position = offset;
18708
18709 /* Get the specified minimum width. Zero means
18710 don't pad. */
18711 field = 0;
18712 while ((c = SREF (elt, offset++)) >= '0' && c <= '9')
18713 field = field * 10 + c - '0';
18714
18715 /* Don't pad beyond the total padding allowed. */
18716 if (field_width - n > 0 && field > field_width - n)
18717 field = field_width - n;
18718
18719 /* Note that either PRECISION <= 0 or N < PRECISION. */
18720 prec = precision - n;
18721
18722 if (c == 'M')
18723 n += display_mode_element (it, depth, field, prec,
18724 Vglobal_mode_string, props,
18725 risky);
18726 else if (c != 0)
18727 {
18728 int multibyte;
18729 EMACS_INT bytepos, charpos;
18730 const char *spec;
18731 Lisp_Object string;
18732
18733 bytepos = percent_position;
18734 charpos = (STRING_MULTIBYTE (elt)
18735 ? string_byte_to_char (elt, bytepos)
18736 : bytepos);
18737 spec = decode_mode_spec (it->w, c, field, &string);
18738 multibyte = STRINGP (string) && STRING_MULTIBYTE (string);
18739
18740 switch (mode_line_target)
18741 {
18742 case MODE_LINE_NOPROP:
18743 case MODE_LINE_TITLE:
18744 n += store_mode_line_noprop (spec, field, prec);
18745 break;
18746 case MODE_LINE_STRING:
18747 {
18748 int len = strlen (spec);
18749 Lisp_Object tem = make_string (spec, len);
18750 props = Ftext_properties_at (make_number (charpos), elt);
18751 /* Should only keep face property in props */
18752 n += store_mode_line_string (NULL, tem, 0, field, prec, props);
18753 }
18754 break;
18755 case MODE_LINE_DISPLAY:
18756 {
18757 int nglyphs_before, nwritten;
18758
18759 nglyphs_before = it->glyph_row->used[TEXT_AREA];
18760 nwritten = display_string (spec, string, elt,
18761 charpos, 0, it,
18762 field, prec, 0,
18763 multibyte);
18764
18765 /* Assign to the glyphs written above the
18766 string where the `%x' came from, position
18767 of the `%'. */
18768 if (nwritten > 0)
18769 {
18770 struct glyph *glyph
18771 = (it->glyph_row->glyphs[TEXT_AREA]
18772 + nglyphs_before);
18773 int i;
18774
18775 for (i = 0; i < nwritten; ++i)
18776 {
18777 glyph[i].object = elt;
18778 glyph[i].charpos = charpos;
18779 }
18780
18781 n += nwritten;
18782 }
18783 }
18784 break;
18785 }
18786 }
18787 else /* c == 0 */
18788 break;
18789 }
18790 }
18791 }
18792 break;
18793
18794 case Lisp_Symbol:
18795 /* A symbol: process the value of the symbol recursively
18796 as if it appeared here directly. Avoid error if symbol void.
18797 Special case: if value of symbol is a string, output the string
18798 literally. */
18799 {
18800 register Lisp_Object tem;
18801
18802 /* If the variable is not marked as risky to set
18803 then its contents are risky to use. */
18804 if (NILP (Fget (elt, Qrisky_local_variable)))
18805 risky = 1;
18806
18807 tem = Fboundp (elt);
18808 if (!NILP (tem))
18809 {
18810 tem = Fsymbol_value (elt);
18811 /* If value is a string, output that string literally:
18812 don't check for % within it. */
18813 if (STRINGP (tem))
18814 literal = 1;
18815
18816 if (!EQ (tem, elt))
18817 {
18818 /* Give up right away for nil or t. */
18819 elt = tem;
18820 goto tail_recurse;
18821 }
18822 }
18823 }
18824 break;
18825
18826 case Lisp_Cons:
18827 {
18828 register Lisp_Object car, tem;
18829
18830 /* A cons cell: five distinct cases.
18831 If first element is :eval or :propertize, do something special.
18832 If first element is a string or a cons, process all the elements
18833 and effectively concatenate them.
18834 If first element is a negative number, truncate displaying cdr to
18835 at most that many characters. If positive, pad (with spaces)
18836 to at least that many characters.
18837 If first element is a symbol, process the cadr or caddr recursively
18838 according to whether the symbol's value is non-nil or nil. */
18839 car = XCAR (elt);
18840 if (EQ (car, QCeval))
18841 {
18842 /* An element of the form (:eval FORM) means evaluate FORM
18843 and use the result as mode line elements. */
18844
18845 if (risky)
18846 break;
18847
18848 if (CONSP (XCDR (elt)))
18849 {
18850 Lisp_Object spec;
18851 spec = safe_eval (XCAR (XCDR (elt)));
18852 n += display_mode_element (it, depth, field_width - n,
18853 precision - n, spec, props,
18854 risky);
18855 }
18856 }
18857 else if (EQ (car, QCpropertize))
18858 {
18859 /* An element of the form (:propertize ELT PROPS...)
18860 means display ELT but applying properties PROPS. */
18861
18862 if (risky)
18863 break;
18864
18865 if (CONSP (XCDR (elt)))
18866 n += display_mode_element (it, depth, field_width - n,
18867 precision - n, XCAR (XCDR (elt)),
18868 XCDR (XCDR (elt)), risky);
18869 }
18870 else if (SYMBOLP (car))
18871 {
18872 tem = Fboundp (car);
18873 elt = XCDR (elt);
18874 if (!CONSP (elt))
18875 goto invalid;
18876 /* elt is now the cdr, and we know it is a cons cell.
18877 Use its car if CAR has a non-nil value. */
18878 if (!NILP (tem))
18879 {
18880 tem = Fsymbol_value (car);
18881 if (!NILP (tem))
18882 {
18883 elt = XCAR (elt);
18884 goto tail_recurse;
18885 }
18886 }
18887 /* Symbol's value is nil (or symbol is unbound)
18888 Get the cddr of the original list
18889 and if possible find the caddr and use that. */
18890 elt = XCDR (elt);
18891 if (NILP (elt))
18892 break;
18893 else if (!CONSP (elt))
18894 goto invalid;
18895 elt = XCAR (elt);
18896 goto tail_recurse;
18897 }
18898 else if (INTEGERP (car))
18899 {
18900 register int lim = XINT (car);
18901 elt = XCDR (elt);
18902 if (lim < 0)
18903 {
18904 /* Negative int means reduce maximum width. */
18905 if (precision <= 0)
18906 precision = -lim;
18907 else
18908 precision = min (precision, -lim);
18909 }
18910 else if (lim > 0)
18911 {
18912 /* Padding specified. Don't let it be more than
18913 current maximum. */
18914 if (precision > 0)
18915 lim = min (precision, lim);
18916
18917 /* If that's more padding than already wanted, queue it.
18918 But don't reduce padding already specified even if
18919 that is beyond the current truncation point. */
18920 field_width = max (lim, field_width);
18921 }
18922 goto tail_recurse;
18923 }
18924 else if (STRINGP (car) || CONSP (car))
18925 {
18926 Lisp_Object halftail = elt;
18927 int len = 0;
18928
18929 while (CONSP (elt)
18930 && (precision <= 0 || n < precision))
18931 {
18932 n += display_mode_element (it, depth,
18933 /* Do padding only after the last
18934 element in the list. */
18935 (! CONSP (XCDR (elt))
18936 ? field_width - n
18937 : 0),
18938 precision - n, XCAR (elt),
18939 props, risky);
18940 elt = XCDR (elt);
18941 len++;
18942 if ((len & 1) == 0)
18943 halftail = XCDR (halftail);
18944 /* Check for cycle. */
18945 if (EQ (halftail, elt))
18946 break;
18947 }
18948 }
18949 }
18950 break;
18951
18952 default:
18953 invalid:
18954 elt = build_string ("*invalid*");
18955 goto tail_recurse;
18956 }
18957
18958 /* Pad to FIELD_WIDTH. */
18959 if (field_width > 0 && n < field_width)
18960 {
18961 switch (mode_line_target)
18962 {
18963 case MODE_LINE_NOPROP:
18964 case MODE_LINE_TITLE:
18965 n += store_mode_line_noprop ("", field_width - n, 0);
18966 break;
18967 case MODE_LINE_STRING:
18968 n += store_mode_line_string ("", Qnil, 0, field_width - n, 0, Qnil);
18969 break;
18970 case MODE_LINE_DISPLAY:
18971 n += display_string ("", Qnil, Qnil, 0, 0, it, field_width - n,
18972 0, 0, 0);
18973 break;
18974 }
18975 }
18976
18977 return n;
18978 }
18979
18980 /* Store a mode-line string element in mode_line_string_list.
18981
18982 If STRING is non-null, display that C string. Otherwise, the Lisp
18983 string LISP_STRING is displayed.
18984
18985 FIELD_WIDTH is the minimum number of output glyphs to produce.
18986 If STRING has fewer characters than FIELD_WIDTH, pad to the right
18987 with spaces. FIELD_WIDTH <= 0 means don't pad.
18988
18989 PRECISION is the maximum number of characters to output from
18990 STRING. PRECISION <= 0 means don't truncate the string.
18991
18992 If COPY_STRING is non-zero, make a copy of LISP_STRING before adding
18993 properties to the string.
18994
18995 PROPS are the properties to add to the string.
18996 The mode_line_string_face face property is always added to the string.
18997 */
18998
18999 static int
19000 store_mode_line_string (const char *string, Lisp_Object lisp_string, int copy_string,
19001 int field_width, int precision, Lisp_Object props)
19002 {
19003 EMACS_INT len;
19004 int n = 0;
19005
19006 if (string != NULL)
19007 {
19008 len = strlen (string);
19009 if (precision > 0 && len > precision)
19010 len = precision;
19011 lisp_string = make_string (string, len);
19012 if (NILP (props))
19013 props = mode_line_string_face_prop;
19014 else if (!NILP (mode_line_string_face))
19015 {
19016 Lisp_Object face = Fplist_get (props, Qface);
19017 props = Fcopy_sequence (props);
19018 if (NILP (face))
19019 face = mode_line_string_face;
19020 else
19021 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
19022 props = Fplist_put (props, Qface, face);
19023 }
19024 Fadd_text_properties (make_number (0), make_number (len),
19025 props, lisp_string);
19026 }
19027 else
19028 {
19029 len = XFASTINT (Flength (lisp_string));
19030 if (precision > 0 && len > precision)
19031 {
19032 len = precision;
19033 lisp_string = Fsubstring (lisp_string, make_number (0), make_number (len));
19034 precision = -1;
19035 }
19036 if (!NILP (mode_line_string_face))
19037 {
19038 Lisp_Object face;
19039 if (NILP (props))
19040 props = Ftext_properties_at (make_number (0), lisp_string);
19041 face = Fplist_get (props, Qface);
19042 if (NILP (face))
19043 face = mode_line_string_face;
19044 else
19045 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
19046 props = Fcons (Qface, Fcons (face, Qnil));
19047 if (copy_string)
19048 lisp_string = Fcopy_sequence (lisp_string);
19049 }
19050 if (!NILP (props))
19051 Fadd_text_properties (make_number (0), make_number (len),
19052 props, lisp_string);
19053 }
19054
19055 if (len > 0)
19056 {
19057 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
19058 n += len;
19059 }
19060
19061 if (field_width > len)
19062 {
19063 field_width -= len;
19064 lisp_string = Fmake_string (make_number (field_width), make_number (' '));
19065 if (!NILP (props))
19066 Fadd_text_properties (make_number (0), make_number (field_width),
19067 props, lisp_string);
19068 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
19069 n += field_width;
19070 }
19071
19072 return n;
19073 }
19074
19075
19076 DEFUN ("format-mode-line", Fformat_mode_line, Sformat_mode_line,
19077 1, 4, 0,
19078 doc: /* Format a string out of a mode line format specification.
19079 First arg FORMAT specifies the mode line format (see `mode-line-format'
19080 for details) to use.
19081
19082 By default, the format is evaluated for the currently selected window.
19083
19084 Optional second arg FACE specifies the face property to put on all
19085 characters for which no face is specified. The value nil means the
19086 default face. The value t means whatever face the window's mode line
19087 currently uses (either `mode-line' or `mode-line-inactive',
19088 depending on whether the window is the selected window or not).
19089 An integer value means the value string has no text
19090 properties.
19091
19092 Optional third and fourth args WINDOW and BUFFER specify the window
19093 and buffer to use as the context for the formatting (defaults
19094 are the selected window and the WINDOW's buffer). */)
19095 (Lisp_Object format, Lisp_Object face,
19096 Lisp_Object window, Lisp_Object buffer)
19097 {
19098 struct it it;
19099 int len;
19100 struct window *w;
19101 struct buffer *old_buffer = NULL;
19102 int face_id;
19103 int no_props = INTEGERP (face);
19104 int count = SPECPDL_INDEX ();
19105 Lisp_Object str;
19106 int string_start = 0;
19107
19108 if (NILP (window))
19109 window = selected_window;
19110 CHECK_WINDOW (window);
19111 w = XWINDOW (window);
19112
19113 if (NILP (buffer))
19114 buffer = w->buffer;
19115 CHECK_BUFFER (buffer);
19116
19117 /* Make formatting the modeline a non-op when noninteractive, otherwise
19118 there will be problems later caused by a partially initialized frame. */
19119 if (NILP (format) || noninteractive)
19120 return empty_unibyte_string;
19121
19122 if (no_props)
19123 face = Qnil;
19124
19125 face_id = (NILP (face) || EQ (face, Qdefault)) ? DEFAULT_FACE_ID
19126 : EQ (face, Qt) ? (EQ (window, selected_window)
19127 ? MODE_LINE_FACE_ID : MODE_LINE_INACTIVE_FACE_ID)
19128 : EQ (face, Qmode_line) ? MODE_LINE_FACE_ID
19129 : EQ (face, Qmode_line_inactive) ? MODE_LINE_INACTIVE_FACE_ID
19130 : EQ (face, Qheader_line) ? HEADER_LINE_FACE_ID
19131 : EQ (face, Qtool_bar) ? TOOL_BAR_FACE_ID
19132 : DEFAULT_FACE_ID;
19133
19134 if (XBUFFER (buffer) != current_buffer)
19135 old_buffer = current_buffer;
19136
19137 /* Save things including mode_line_proptrans_alist,
19138 and set that to nil so that we don't alter the outer value. */
19139 record_unwind_protect (unwind_format_mode_line,
19140 format_mode_line_unwind_data
19141 (old_buffer, selected_window, 1));
19142 mode_line_proptrans_alist = Qnil;
19143
19144 Fselect_window (window, Qt);
19145 if (old_buffer)
19146 set_buffer_internal_1 (XBUFFER (buffer));
19147
19148 init_iterator (&it, w, -1, -1, NULL, face_id);
19149
19150 if (no_props)
19151 {
19152 mode_line_target = MODE_LINE_NOPROP;
19153 mode_line_string_face_prop = Qnil;
19154 mode_line_string_list = Qnil;
19155 string_start = MODE_LINE_NOPROP_LEN (0);
19156 }
19157 else
19158 {
19159 mode_line_target = MODE_LINE_STRING;
19160 mode_line_string_list = Qnil;
19161 mode_line_string_face = face;
19162 mode_line_string_face_prop
19163 = (NILP (face) ? Qnil : Fcons (Qface, Fcons (face, Qnil)));
19164 }
19165
19166 push_kboard (FRAME_KBOARD (it.f));
19167 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
19168 pop_kboard ();
19169
19170 if (no_props)
19171 {
19172 len = MODE_LINE_NOPROP_LEN (string_start);
19173 str = make_string (mode_line_noprop_buf + string_start, len);
19174 }
19175 else
19176 {
19177 mode_line_string_list = Fnreverse (mode_line_string_list);
19178 str = Fmapconcat (intern ("identity"), mode_line_string_list,
19179 empty_unibyte_string);
19180 }
19181
19182 unbind_to (count, Qnil);
19183 return str;
19184 }
19185
19186 /* Write a null-terminated, right justified decimal representation of
19187 the positive integer D to BUF using a minimal field width WIDTH. */
19188
19189 static void
19190 pint2str (register char *buf, register int width, register EMACS_INT d)
19191 {
19192 register char *p = buf;
19193
19194 if (d <= 0)
19195 *p++ = '0';
19196 else
19197 {
19198 while (d > 0)
19199 {
19200 *p++ = d % 10 + '0';
19201 d /= 10;
19202 }
19203 }
19204
19205 for (width -= (int) (p - buf); width > 0; --width)
19206 *p++ = ' ';
19207 *p-- = '\0';
19208 while (p > buf)
19209 {
19210 d = *buf;
19211 *buf++ = *p;
19212 *p-- = d;
19213 }
19214 }
19215
19216 /* Write a null-terminated, right justified decimal and "human
19217 readable" representation of the nonnegative integer D to BUF using
19218 a minimal field width WIDTH. D should be smaller than 999.5e24. */
19219
19220 static const char power_letter[] =
19221 {
19222 0, /* no letter */
19223 'k', /* kilo */
19224 'M', /* mega */
19225 'G', /* giga */
19226 'T', /* tera */
19227 'P', /* peta */
19228 'E', /* exa */
19229 'Z', /* zetta */
19230 'Y' /* yotta */
19231 };
19232
19233 static void
19234 pint2hrstr (char *buf, int width, EMACS_INT d)
19235 {
19236 /* We aim to represent the nonnegative integer D as
19237 QUOTIENT.TENTHS * 10 ^ (3 * EXPONENT). */
19238 EMACS_INT quotient = d;
19239 int remainder = 0;
19240 /* -1 means: do not use TENTHS. */
19241 int tenths = -1;
19242 int exponent = 0;
19243
19244 /* Length of QUOTIENT.TENTHS as a string. */
19245 int length;
19246
19247 char * psuffix;
19248 char * p;
19249
19250 if (1000 <= quotient)
19251 {
19252 /* Scale to the appropriate EXPONENT. */
19253 do
19254 {
19255 remainder = quotient % 1000;
19256 quotient /= 1000;
19257 exponent++;
19258 }
19259 while (1000 <= quotient);
19260
19261 /* Round to nearest and decide whether to use TENTHS or not. */
19262 if (quotient <= 9)
19263 {
19264 tenths = remainder / 100;
19265 if (50 <= remainder % 100)
19266 {
19267 if (tenths < 9)
19268 tenths++;
19269 else
19270 {
19271 quotient++;
19272 if (quotient == 10)
19273 tenths = -1;
19274 else
19275 tenths = 0;
19276 }
19277 }
19278 }
19279 else
19280 if (500 <= remainder)
19281 {
19282 if (quotient < 999)
19283 quotient++;
19284 else
19285 {
19286 quotient = 1;
19287 exponent++;
19288 tenths = 0;
19289 }
19290 }
19291 }
19292
19293 /* Calculate the LENGTH of QUOTIENT.TENTHS as a string. */
19294 if (tenths == -1 && quotient <= 99)
19295 if (quotient <= 9)
19296 length = 1;
19297 else
19298 length = 2;
19299 else
19300 length = 3;
19301 p = psuffix = buf + max (width, length);
19302
19303 /* Print EXPONENT. */
19304 *psuffix++ = power_letter[exponent];
19305 *psuffix = '\0';
19306
19307 /* Print TENTHS. */
19308 if (tenths >= 0)
19309 {
19310 *--p = '0' + tenths;
19311 *--p = '.';
19312 }
19313
19314 /* Print QUOTIENT. */
19315 do
19316 {
19317 int digit = quotient % 10;
19318 *--p = '0' + digit;
19319 }
19320 while ((quotient /= 10) != 0);
19321
19322 /* Print leading spaces. */
19323 while (buf < p)
19324 *--p = ' ';
19325 }
19326
19327 /* Set a mnemonic character for coding_system (Lisp symbol) in BUF.
19328 If EOL_FLAG is 1, set also a mnemonic character for end-of-line
19329 type of CODING_SYSTEM. Return updated pointer into BUF. */
19330
19331 static unsigned char invalid_eol_type[] = "(*invalid*)";
19332
19333 static char *
19334 decode_mode_spec_coding (Lisp_Object coding_system, register char *buf, int eol_flag)
19335 {
19336 Lisp_Object val;
19337 int multibyte = !NILP (BVAR (current_buffer, enable_multibyte_characters));
19338 const unsigned char *eol_str;
19339 int eol_str_len;
19340 /* The EOL conversion we are using. */
19341 Lisp_Object eoltype;
19342
19343 val = CODING_SYSTEM_SPEC (coding_system);
19344 eoltype = Qnil;
19345
19346 if (!VECTORP (val)) /* Not yet decided. */
19347 {
19348 if (multibyte)
19349 *buf++ = '-';
19350 if (eol_flag)
19351 eoltype = eol_mnemonic_undecided;
19352 /* Don't mention EOL conversion if it isn't decided. */
19353 }
19354 else
19355 {
19356 Lisp_Object attrs;
19357 Lisp_Object eolvalue;
19358
19359 attrs = AREF (val, 0);
19360 eolvalue = AREF (val, 2);
19361
19362 if (multibyte)
19363 *buf++ = XFASTINT (CODING_ATTR_MNEMONIC (attrs));
19364
19365 if (eol_flag)
19366 {
19367 /* The EOL conversion that is normal on this system. */
19368
19369 if (NILP (eolvalue)) /* Not yet decided. */
19370 eoltype = eol_mnemonic_undecided;
19371 else if (VECTORP (eolvalue)) /* Not yet decided. */
19372 eoltype = eol_mnemonic_undecided;
19373 else /* eolvalue is Qunix, Qdos, or Qmac. */
19374 eoltype = (EQ (eolvalue, Qunix)
19375 ? eol_mnemonic_unix
19376 : (EQ (eolvalue, Qdos) == 1
19377 ? eol_mnemonic_dos : eol_mnemonic_mac));
19378 }
19379 }
19380
19381 if (eol_flag)
19382 {
19383 /* Mention the EOL conversion if it is not the usual one. */
19384 if (STRINGP (eoltype))
19385 {
19386 eol_str = SDATA (eoltype);
19387 eol_str_len = SBYTES (eoltype);
19388 }
19389 else if (CHARACTERP (eoltype))
19390 {
19391 unsigned char *tmp = (unsigned char *) alloca (MAX_MULTIBYTE_LENGTH);
19392 eol_str_len = CHAR_STRING (XINT (eoltype), tmp);
19393 eol_str = tmp;
19394 }
19395 else
19396 {
19397 eol_str = invalid_eol_type;
19398 eol_str_len = sizeof (invalid_eol_type) - 1;
19399 }
19400 memcpy (buf, eol_str, eol_str_len);
19401 buf += eol_str_len;
19402 }
19403
19404 return buf;
19405 }
19406
19407 /* Return a string for the output of a mode line %-spec for window W,
19408 generated by character C. FIELD_WIDTH > 0 means pad the string
19409 returned with spaces to that value. Return a Lisp string in
19410 *STRING if the resulting string is taken from that Lisp string.
19411
19412 Note we operate on the current buffer for most purposes,
19413 the exception being w->base_line_pos. */
19414
19415 static char lots_of_dashes[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
19416
19417 static const char *
19418 decode_mode_spec (struct window *w, register int c, int field_width,
19419 Lisp_Object *string)
19420 {
19421 Lisp_Object obj;
19422 struct frame *f = XFRAME (WINDOW_FRAME (w));
19423 char *decode_mode_spec_buf = f->decode_mode_spec_buffer;
19424 struct buffer *b = current_buffer;
19425
19426 obj = Qnil;
19427 *string = Qnil;
19428
19429 switch (c)
19430 {
19431 case '*':
19432 if (!NILP (BVAR (b, read_only)))
19433 return "%";
19434 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
19435 return "*";
19436 return "-";
19437
19438 case '+':
19439 /* This differs from %* only for a modified read-only buffer. */
19440 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
19441 return "*";
19442 if (!NILP (BVAR (b, read_only)))
19443 return "%";
19444 return "-";
19445
19446 case '&':
19447 /* This differs from %* in ignoring read-only-ness. */
19448 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
19449 return "*";
19450 return "-";
19451
19452 case '%':
19453 return "%";
19454
19455 case '[':
19456 {
19457 int i;
19458 char *p;
19459
19460 if (command_loop_level > 5)
19461 return "[[[... ";
19462 p = decode_mode_spec_buf;
19463 for (i = 0; i < command_loop_level; i++)
19464 *p++ = '[';
19465 *p = 0;
19466 return decode_mode_spec_buf;
19467 }
19468
19469 case ']':
19470 {
19471 int i;
19472 char *p;
19473
19474 if (command_loop_level > 5)
19475 return " ...]]]";
19476 p = decode_mode_spec_buf;
19477 for (i = 0; i < command_loop_level; i++)
19478 *p++ = ']';
19479 *p = 0;
19480 return decode_mode_spec_buf;
19481 }
19482
19483 case '-':
19484 {
19485 register int i;
19486
19487 /* Let lots_of_dashes be a string of infinite length. */
19488 if (mode_line_target == MODE_LINE_NOPROP ||
19489 mode_line_target == MODE_LINE_STRING)
19490 return "--";
19491 if (field_width <= 0
19492 || field_width > sizeof (lots_of_dashes))
19493 {
19494 for (i = 0; i < FRAME_MESSAGE_BUF_SIZE (f) - 1; ++i)
19495 decode_mode_spec_buf[i] = '-';
19496 decode_mode_spec_buf[i] = '\0';
19497 return decode_mode_spec_buf;
19498 }
19499 else
19500 return lots_of_dashes;
19501 }
19502
19503 case 'b':
19504 obj = BVAR (b, name);
19505 break;
19506
19507 case 'c':
19508 /* %c and %l are ignored in `frame-title-format'.
19509 (In redisplay_internal, the frame title is drawn _before_ the
19510 windows are updated, so the stuff which depends on actual
19511 window contents (such as %l) may fail to render properly, or
19512 even crash emacs.) */
19513 if (mode_line_target == MODE_LINE_TITLE)
19514 return "";
19515 else
19516 {
19517 EMACS_INT col = current_column ();
19518 w->column_number_displayed = make_number (col);
19519 pint2str (decode_mode_spec_buf, field_width, col);
19520 return decode_mode_spec_buf;
19521 }
19522
19523 case 'e':
19524 #ifndef SYSTEM_MALLOC
19525 {
19526 if (NILP (Vmemory_full))
19527 return "";
19528 else
19529 return "!MEM FULL! ";
19530 }
19531 #else
19532 return "";
19533 #endif
19534
19535 case 'F':
19536 /* %F displays the frame name. */
19537 if (!NILP (f->title))
19538 return SSDATA (f->title);
19539 if (f->explicit_name || ! FRAME_WINDOW_P (f))
19540 return SSDATA (f->name);
19541 return "Emacs";
19542
19543 case 'f':
19544 obj = BVAR (b, filename);
19545 break;
19546
19547 case 'i':
19548 {
19549 EMACS_INT size = ZV - BEGV;
19550 pint2str (decode_mode_spec_buf, field_width, size);
19551 return decode_mode_spec_buf;
19552 }
19553
19554 case 'I':
19555 {
19556 EMACS_INT size = ZV - BEGV;
19557 pint2hrstr (decode_mode_spec_buf, field_width, size);
19558 return decode_mode_spec_buf;
19559 }
19560
19561 case 'l':
19562 {
19563 EMACS_INT startpos, startpos_byte, line, linepos, linepos_byte;
19564 EMACS_INT topline, nlines, height;
19565 EMACS_INT junk;
19566
19567 /* %c and %l are ignored in `frame-title-format'. */
19568 if (mode_line_target == MODE_LINE_TITLE)
19569 return "";
19570
19571 startpos = XMARKER (w->start)->charpos;
19572 startpos_byte = marker_byte_position (w->start);
19573 height = WINDOW_TOTAL_LINES (w);
19574
19575 /* If we decided that this buffer isn't suitable for line numbers,
19576 don't forget that too fast. */
19577 if (EQ (w->base_line_pos, w->buffer))
19578 goto no_value;
19579 /* But do forget it, if the window shows a different buffer now. */
19580 else if (BUFFERP (w->base_line_pos))
19581 w->base_line_pos = Qnil;
19582
19583 /* If the buffer is very big, don't waste time. */
19584 if (INTEGERP (Vline_number_display_limit)
19585 && BUF_ZV (b) - BUF_BEGV (b) > XINT (Vline_number_display_limit))
19586 {
19587 w->base_line_pos = Qnil;
19588 w->base_line_number = Qnil;
19589 goto no_value;
19590 }
19591
19592 if (INTEGERP (w->base_line_number)
19593 && INTEGERP (w->base_line_pos)
19594 && XFASTINT (w->base_line_pos) <= startpos)
19595 {
19596 line = XFASTINT (w->base_line_number);
19597 linepos = XFASTINT (w->base_line_pos);
19598 linepos_byte = buf_charpos_to_bytepos (b, linepos);
19599 }
19600 else
19601 {
19602 line = 1;
19603 linepos = BUF_BEGV (b);
19604 linepos_byte = BUF_BEGV_BYTE (b);
19605 }
19606
19607 /* Count lines from base line to window start position. */
19608 nlines = display_count_lines (linepos_byte,
19609 startpos_byte,
19610 startpos, &junk);
19611
19612 topline = nlines + line;
19613
19614 /* Determine a new base line, if the old one is too close
19615 or too far away, or if we did not have one.
19616 "Too close" means it's plausible a scroll-down would
19617 go back past it. */
19618 if (startpos == BUF_BEGV (b))
19619 {
19620 w->base_line_number = make_number (topline);
19621 w->base_line_pos = make_number (BUF_BEGV (b));
19622 }
19623 else if (nlines < height + 25 || nlines > height * 3 + 50
19624 || linepos == BUF_BEGV (b))
19625 {
19626 EMACS_INT limit = BUF_BEGV (b);
19627 EMACS_INT limit_byte = BUF_BEGV_BYTE (b);
19628 EMACS_INT position;
19629 EMACS_INT distance =
19630 (height * 2 + 30) * line_number_display_limit_width;
19631
19632 if (startpos - distance > limit)
19633 {
19634 limit = startpos - distance;
19635 limit_byte = CHAR_TO_BYTE (limit);
19636 }
19637
19638 nlines = display_count_lines (startpos_byte,
19639 limit_byte,
19640 - (height * 2 + 30),
19641 &position);
19642 /* If we couldn't find the lines we wanted within
19643 line_number_display_limit_width chars per line,
19644 give up on line numbers for this window. */
19645 if (position == limit_byte && limit == startpos - distance)
19646 {
19647 w->base_line_pos = w->buffer;
19648 w->base_line_number = Qnil;
19649 goto no_value;
19650 }
19651
19652 w->base_line_number = make_number (topline - nlines);
19653 w->base_line_pos = make_number (BYTE_TO_CHAR (position));
19654 }
19655
19656 /* Now count lines from the start pos to point. */
19657 nlines = display_count_lines (startpos_byte,
19658 PT_BYTE, PT, &junk);
19659
19660 /* Record that we did display the line number. */
19661 line_number_displayed = 1;
19662
19663 /* Make the string to show. */
19664 pint2str (decode_mode_spec_buf, field_width, topline + nlines);
19665 return decode_mode_spec_buf;
19666 no_value:
19667 {
19668 char* p = decode_mode_spec_buf;
19669 int pad = field_width - 2;
19670 while (pad-- > 0)
19671 *p++ = ' ';
19672 *p++ = '?';
19673 *p++ = '?';
19674 *p = '\0';
19675 return decode_mode_spec_buf;
19676 }
19677 }
19678 break;
19679
19680 case 'm':
19681 obj = BVAR (b, mode_name);
19682 break;
19683
19684 case 'n':
19685 if (BUF_BEGV (b) > BUF_BEG (b) || BUF_ZV (b) < BUF_Z (b))
19686 return " Narrow";
19687 break;
19688
19689 case 'p':
19690 {
19691 EMACS_INT pos = marker_position (w->start);
19692 EMACS_INT total = BUF_ZV (b) - BUF_BEGV (b);
19693
19694 if (XFASTINT (w->window_end_pos) <= BUF_Z (b) - BUF_ZV (b))
19695 {
19696 if (pos <= BUF_BEGV (b))
19697 return "All";
19698 else
19699 return "Bottom";
19700 }
19701 else if (pos <= BUF_BEGV (b))
19702 return "Top";
19703 else
19704 {
19705 if (total > 1000000)
19706 /* Do it differently for a large value, to avoid overflow. */
19707 total = ((pos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
19708 else
19709 total = ((pos - BUF_BEGV (b)) * 100 + total - 1) / total;
19710 /* We can't normally display a 3-digit number,
19711 so get us a 2-digit number that is close. */
19712 if (total == 100)
19713 total = 99;
19714 sprintf (decode_mode_spec_buf, "%2"pI"d%%", total);
19715 return decode_mode_spec_buf;
19716 }
19717 }
19718
19719 /* Display percentage of size above the bottom of the screen. */
19720 case 'P':
19721 {
19722 EMACS_INT toppos = marker_position (w->start);
19723 EMACS_INT botpos = BUF_Z (b) - XFASTINT (w->window_end_pos);
19724 EMACS_INT total = BUF_ZV (b) - BUF_BEGV (b);
19725
19726 if (botpos >= BUF_ZV (b))
19727 {
19728 if (toppos <= BUF_BEGV (b))
19729 return "All";
19730 else
19731 return "Bottom";
19732 }
19733 else
19734 {
19735 if (total > 1000000)
19736 /* Do it differently for a large value, to avoid overflow. */
19737 total = ((botpos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
19738 else
19739 total = ((botpos - BUF_BEGV (b)) * 100 + total - 1) / total;
19740 /* We can't normally display a 3-digit number,
19741 so get us a 2-digit number that is close. */
19742 if (total == 100)
19743 total = 99;
19744 if (toppos <= BUF_BEGV (b))
19745 sprintf (decode_mode_spec_buf, "Top%2"pI"d%%", total);
19746 else
19747 sprintf (decode_mode_spec_buf, "%2"pI"d%%", total);
19748 return decode_mode_spec_buf;
19749 }
19750 }
19751
19752 case 's':
19753 /* status of process */
19754 obj = Fget_buffer_process (Fcurrent_buffer ());
19755 if (NILP (obj))
19756 return "no process";
19757 #ifndef MSDOS
19758 obj = Fsymbol_name (Fprocess_status (obj));
19759 #endif
19760 break;
19761
19762 case '@':
19763 {
19764 int count = inhibit_garbage_collection ();
19765 Lisp_Object val = call1 (intern ("file-remote-p"),
19766 BVAR (current_buffer, directory));
19767 unbind_to (count, Qnil);
19768
19769 if (NILP (val))
19770 return "-";
19771 else
19772 return "@";
19773 }
19774
19775 case 't': /* indicate TEXT or BINARY */
19776 return "T";
19777
19778 case 'z':
19779 /* coding-system (not including end-of-line format) */
19780 case 'Z':
19781 /* coding-system (including end-of-line type) */
19782 {
19783 int eol_flag = (c == 'Z');
19784 char *p = decode_mode_spec_buf;
19785
19786 if (! FRAME_WINDOW_P (f))
19787 {
19788 /* No need to mention EOL here--the terminal never needs
19789 to do EOL conversion. */
19790 p = decode_mode_spec_coding (CODING_ID_NAME
19791 (FRAME_KEYBOARD_CODING (f)->id),
19792 p, 0);
19793 p = decode_mode_spec_coding (CODING_ID_NAME
19794 (FRAME_TERMINAL_CODING (f)->id),
19795 p, 0);
19796 }
19797 p = decode_mode_spec_coding (BVAR (b, buffer_file_coding_system),
19798 p, eol_flag);
19799
19800 #if 0 /* This proves to be annoying; I think we can do without. -- rms. */
19801 #ifdef subprocesses
19802 obj = Fget_buffer_process (Fcurrent_buffer ());
19803 if (PROCESSP (obj))
19804 {
19805 p = decode_mode_spec_coding (XPROCESS (obj)->decode_coding_system,
19806 p, eol_flag);
19807 p = decode_mode_spec_coding (XPROCESS (obj)->encode_coding_system,
19808 p, eol_flag);
19809 }
19810 #endif /* subprocesses */
19811 #endif /* 0 */
19812 *p = 0;
19813 return decode_mode_spec_buf;
19814 }
19815 }
19816
19817 if (STRINGP (obj))
19818 {
19819 *string = obj;
19820 return SSDATA (obj);
19821 }
19822 else
19823 return "";
19824 }
19825
19826
19827 /* Count up to COUNT lines starting from START_BYTE.
19828 But don't go beyond LIMIT_BYTE.
19829 Return the number of lines thus found (always nonnegative).
19830
19831 Set *BYTE_POS_PTR to 1 if we found COUNT lines, 0 if we hit LIMIT. */
19832
19833 static EMACS_INT
19834 display_count_lines (EMACS_INT start_byte,
19835 EMACS_INT limit_byte, EMACS_INT count,
19836 EMACS_INT *byte_pos_ptr)
19837 {
19838 register unsigned char *cursor;
19839 unsigned char *base;
19840
19841 register EMACS_INT ceiling;
19842 register unsigned char *ceiling_addr;
19843 EMACS_INT orig_count = count;
19844
19845 /* If we are not in selective display mode,
19846 check only for newlines. */
19847 int selective_display = (!NILP (BVAR (current_buffer, selective_display))
19848 && !INTEGERP (BVAR (current_buffer, selective_display)));
19849
19850 if (count > 0)
19851 {
19852 while (start_byte < limit_byte)
19853 {
19854 ceiling = BUFFER_CEILING_OF (start_byte);
19855 ceiling = min (limit_byte - 1, ceiling);
19856 ceiling_addr = BYTE_POS_ADDR (ceiling) + 1;
19857 base = (cursor = BYTE_POS_ADDR (start_byte));
19858 while (1)
19859 {
19860 if (selective_display)
19861 while (*cursor != '\n' && *cursor != 015 && ++cursor != ceiling_addr)
19862 ;
19863 else
19864 while (*cursor != '\n' && ++cursor != ceiling_addr)
19865 ;
19866
19867 if (cursor != ceiling_addr)
19868 {
19869 if (--count == 0)
19870 {
19871 start_byte += cursor - base + 1;
19872 *byte_pos_ptr = start_byte;
19873 return orig_count;
19874 }
19875 else
19876 if (++cursor == ceiling_addr)
19877 break;
19878 }
19879 else
19880 break;
19881 }
19882 start_byte += cursor - base;
19883 }
19884 }
19885 else
19886 {
19887 while (start_byte > limit_byte)
19888 {
19889 ceiling = BUFFER_FLOOR_OF (start_byte - 1);
19890 ceiling = max (limit_byte, ceiling);
19891 ceiling_addr = BYTE_POS_ADDR (ceiling) - 1;
19892 base = (cursor = BYTE_POS_ADDR (start_byte - 1) + 1);
19893 while (1)
19894 {
19895 if (selective_display)
19896 while (--cursor != ceiling_addr
19897 && *cursor != '\n' && *cursor != 015)
19898 ;
19899 else
19900 while (--cursor != ceiling_addr && *cursor != '\n')
19901 ;
19902
19903 if (cursor != ceiling_addr)
19904 {
19905 if (++count == 0)
19906 {
19907 start_byte += cursor - base + 1;
19908 *byte_pos_ptr = start_byte;
19909 /* When scanning backwards, we should
19910 not count the newline posterior to which we stop. */
19911 return - orig_count - 1;
19912 }
19913 }
19914 else
19915 break;
19916 }
19917 /* Here we add 1 to compensate for the last decrement
19918 of CURSOR, which took it past the valid range. */
19919 start_byte += cursor - base + 1;
19920 }
19921 }
19922
19923 *byte_pos_ptr = limit_byte;
19924
19925 if (count < 0)
19926 return - orig_count + count;
19927 return orig_count - count;
19928
19929 }
19930
19931
19932 \f
19933 /***********************************************************************
19934 Displaying strings
19935 ***********************************************************************/
19936
19937 /* Display a NUL-terminated string, starting with index START.
19938
19939 If STRING is non-null, display that C string. Otherwise, the Lisp
19940 string LISP_STRING is displayed. There's a case that STRING is
19941 non-null and LISP_STRING is not nil. It means STRING is a string
19942 data of LISP_STRING. In that case, we display LISP_STRING while
19943 ignoring its text properties.
19944
19945 If FACE_STRING is not nil, FACE_STRING_POS is a position in
19946 FACE_STRING. Display STRING or LISP_STRING with the face at
19947 FACE_STRING_POS in FACE_STRING:
19948
19949 Display the string in the environment given by IT, but use the
19950 standard display table, temporarily.
19951
19952 FIELD_WIDTH is the minimum number of output glyphs to produce.
19953 If STRING has fewer characters than FIELD_WIDTH, pad to the right
19954 with spaces. If STRING has more characters, more than FIELD_WIDTH
19955 glyphs will be produced. FIELD_WIDTH <= 0 means don't pad.
19956
19957 PRECISION is the maximum number of characters to output from
19958 STRING. PRECISION < 0 means don't truncate the string.
19959
19960 This is roughly equivalent to printf format specifiers:
19961
19962 FIELD_WIDTH PRECISION PRINTF
19963 ----------------------------------------
19964 -1 -1 %s
19965 -1 10 %.10s
19966 10 -1 %10s
19967 20 10 %20.10s
19968
19969 MULTIBYTE zero means do not display multibyte chars, > 0 means do
19970 display them, and < 0 means obey the current buffer's value of
19971 enable_multibyte_characters.
19972
19973 Value is the number of columns displayed. */
19974
19975 static int
19976 display_string (const char *string, Lisp_Object lisp_string, Lisp_Object face_string,
19977 EMACS_INT face_string_pos, EMACS_INT start, struct it *it,
19978 int field_width, int precision, int max_x, int multibyte)
19979 {
19980 int hpos_at_start = it->hpos;
19981 int saved_face_id = it->face_id;
19982 struct glyph_row *row = it->glyph_row;
19983
19984 /* Initialize the iterator IT for iteration over STRING beginning
19985 with index START. */
19986 reseat_to_string (it, NILP (lisp_string) ? string : NULL, lisp_string, start,
19987 precision, field_width, multibyte);
19988 if (string && STRINGP (lisp_string))
19989 /* LISP_STRING is the one returned by decode_mode_spec. We should
19990 ignore its text properties. */
19991 it->stop_charpos = -1;
19992
19993 /* If displaying STRING, set up the face of the iterator
19994 from LISP_STRING, if that's given. */
19995 if (STRINGP (face_string))
19996 {
19997 EMACS_INT endptr;
19998 struct face *face;
19999
20000 it->face_id
20001 = face_at_string_position (it->w, face_string, face_string_pos,
20002 0, it->region_beg_charpos,
20003 it->region_end_charpos,
20004 &endptr, it->base_face_id, 0);
20005 face = FACE_FROM_ID (it->f, it->face_id);
20006 it->face_box_p = face->box != FACE_NO_BOX;
20007 }
20008
20009 /* Set max_x to the maximum allowed X position. Don't let it go
20010 beyond the right edge of the window. */
20011 if (max_x <= 0)
20012 max_x = it->last_visible_x;
20013 else
20014 max_x = min (max_x, it->last_visible_x);
20015
20016 /* Skip over display elements that are not visible. because IT->w is
20017 hscrolled. */
20018 if (it->current_x < it->first_visible_x)
20019 move_it_in_display_line_to (it, 100000, it->first_visible_x,
20020 MOVE_TO_POS | MOVE_TO_X);
20021
20022 row->ascent = it->max_ascent;
20023 row->height = it->max_ascent + it->max_descent;
20024 row->phys_ascent = it->max_phys_ascent;
20025 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
20026 row->extra_line_spacing = it->max_extra_line_spacing;
20027
20028 /* This condition is for the case that we are called with current_x
20029 past last_visible_x. */
20030 while (it->current_x < max_x)
20031 {
20032 int x_before, x, n_glyphs_before, i, nglyphs;
20033
20034 /* Get the next display element. */
20035 if (!get_next_display_element (it))
20036 break;
20037
20038 /* Produce glyphs. */
20039 x_before = it->current_x;
20040 n_glyphs_before = it->glyph_row->used[TEXT_AREA];
20041 PRODUCE_GLYPHS (it);
20042
20043 nglyphs = it->glyph_row->used[TEXT_AREA] - n_glyphs_before;
20044 i = 0;
20045 x = x_before;
20046 while (i < nglyphs)
20047 {
20048 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
20049
20050 if (it->line_wrap != TRUNCATE
20051 && x + glyph->pixel_width > max_x)
20052 {
20053 /* End of continued line or max_x reached. */
20054 if (CHAR_GLYPH_PADDING_P (*glyph))
20055 {
20056 /* A wide character is unbreakable. */
20057 it->glyph_row->used[TEXT_AREA] = n_glyphs_before;
20058 it->current_x = x_before;
20059 }
20060 else
20061 {
20062 it->glyph_row->used[TEXT_AREA] = n_glyphs_before + i;
20063 it->current_x = x;
20064 }
20065 break;
20066 }
20067 else if (x + glyph->pixel_width >= it->first_visible_x)
20068 {
20069 /* Glyph is at least partially visible. */
20070 ++it->hpos;
20071 if (x < it->first_visible_x)
20072 it->glyph_row->x = x - it->first_visible_x;
20073 }
20074 else
20075 {
20076 /* Glyph is off the left margin of the display area.
20077 Should not happen. */
20078 abort ();
20079 }
20080
20081 row->ascent = max (row->ascent, it->max_ascent);
20082 row->height = max (row->height, it->max_ascent + it->max_descent);
20083 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
20084 row->phys_height = max (row->phys_height,
20085 it->max_phys_ascent + it->max_phys_descent);
20086 row->extra_line_spacing = max (row->extra_line_spacing,
20087 it->max_extra_line_spacing);
20088 x += glyph->pixel_width;
20089 ++i;
20090 }
20091
20092 /* Stop if max_x reached. */
20093 if (i < nglyphs)
20094 break;
20095
20096 /* Stop at line ends. */
20097 if (ITERATOR_AT_END_OF_LINE_P (it))
20098 {
20099 it->continuation_lines_width = 0;
20100 break;
20101 }
20102
20103 set_iterator_to_next (it, 1);
20104
20105 /* Stop if truncating at the right edge. */
20106 if (it->line_wrap == TRUNCATE
20107 && it->current_x >= it->last_visible_x)
20108 {
20109 /* Add truncation mark, but don't do it if the line is
20110 truncated at a padding space. */
20111 if (IT_CHARPOS (*it) < it->string_nchars)
20112 {
20113 if (!FRAME_WINDOW_P (it->f))
20114 {
20115 int ii, n;
20116
20117 if (it->current_x > it->last_visible_x)
20118 {
20119 for (ii = row->used[TEXT_AREA] - 1; ii > 0; --ii)
20120 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][ii]))
20121 break;
20122 for (n = row->used[TEXT_AREA]; ii < n; ++ii)
20123 {
20124 row->used[TEXT_AREA] = ii;
20125 produce_special_glyphs (it, IT_TRUNCATION);
20126 }
20127 }
20128 produce_special_glyphs (it, IT_TRUNCATION);
20129 }
20130 it->glyph_row->truncated_on_right_p = 1;
20131 }
20132 break;
20133 }
20134 }
20135
20136 /* Maybe insert a truncation at the left. */
20137 if (it->first_visible_x
20138 && IT_CHARPOS (*it) > 0)
20139 {
20140 if (!FRAME_WINDOW_P (it->f))
20141 insert_left_trunc_glyphs (it);
20142 it->glyph_row->truncated_on_left_p = 1;
20143 }
20144
20145 it->face_id = saved_face_id;
20146
20147 /* Value is number of columns displayed. */
20148 return it->hpos - hpos_at_start;
20149 }
20150
20151
20152 \f
20153 /* This is like a combination of memq and assq. Return 1/2 if PROPVAL
20154 appears as an element of LIST or as the car of an element of LIST.
20155 If PROPVAL is a list, compare each element against LIST in that
20156 way, and return 1/2 if any element of PROPVAL is found in LIST.
20157 Otherwise return 0. This function cannot quit.
20158 The return value is 2 if the text is invisible but with an ellipsis
20159 and 1 if it's invisible and without an ellipsis. */
20160
20161 int
20162 invisible_p (register Lisp_Object propval, Lisp_Object list)
20163 {
20164 register Lisp_Object tail, proptail;
20165
20166 for (tail = list; CONSP (tail); tail = XCDR (tail))
20167 {
20168 register Lisp_Object tem;
20169 tem = XCAR (tail);
20170 if (EQ (propval, tem))
20171 return 1;
20172 if (CONSP (tem) && EQ (propval, XCAR (tem)))
20173 return NILP (XCDR (tem)) ? 1 : 2;
20174 }
20175
20176 if (CONSP (propval))
20177 {
20178 for (proptail = propval; CONSP (proptail); proptail = XCDR (proptail))
20179 {
20180 Lisp_Object propelt;
20181 propelt = XCAR (proptail);
20182 for (tail = list; CONSP (tail); tail = XCDR (tail))
20183 {
20184 register Lisp_Object tem;
20185 tem = XCAR (tail);
20186 if (EQ (propelt, tem))
20187 return 1;
20188 if (CONSP (tem) && EQ (propelt, XCAR (tem)))
20189 return NILP (XCDR (tem)) ? 1 : 2;
20190 }
20191 }
20192 }
20193
20194 return 0;
20195 }
20196
20197 DEFUN ("invisible-p", Finvisible_p, Sinvisible_p, 1, 1, 0,
20198 doc: /* Non-nil if the property makes the text invisible.
20199 POS-OR-PROP can be a marker or number, in which case it is taken to be
20200 a position in the current buffer and the value of the `invisible' property
20201 is checked; or it can be some other value, which is then presumed to be the
20202 value of the `invisible' property of the text of interest.
20203 The non-nil value returned can be t for truly invisible text or something
20204 else if the text is replaced by an ellipsis. */)
20205 (Lisp_Object pos_or_prop)
20206 {
20207 Lisp_Object prop
20208 = (NATNUMP (pos_or_prop) || MARKERP (pos_or_prop)
20209 ? Fget_char_property (pos_or_prop, Qinvisible, Qnil)
20210 : pos_or_prop);
20211 int invis = TEXT_PROP_MEANS_INVISIBLE (prop);
20212 return (invis == 0 ? Qnil
20213 : invis == 1 ? Qt
20214 : make_number (invis));
20215 }
20216
20217 /* Calculate a width or height in pixels from a specification using
20218 the following elements:
20219
20220 SPEC ::=
20221 NUM - a (fractional) multiple of the default font width/height
20222 (NUM) - specifies exactly NUM pixels
20223 UNIT - a fixed number of pixels, see below.
20224 ELEMENT - size of a display element in pixels, see below.
20225 (NUM . SPEC) - equals NUM * SPEC
20226 (+ SPEC SPEC ...) - add pixel values
20227 (- SPEC SPEC ...) - subtract pixel values
20228 (- SPEC) - negate pixel value
20229
20230 NUM ::=
20231 INT or FLOAT - a number constant
20232 SYMBOL - use symbol's (buffer local) variable binding.
20233
20234 UNIT ::=
20235 in - pixels per inch *)
20236 mm - pixels per 1/1000 meter *)
20237 cm - pixels per 1/100 meter *)
20238 width - width of current font in pixels.
20239 height - height of current font in pixels.
20240
20241 *) using the ratio(s) defined in display-pixels-per-inch.
20242
20243 ELEMENT ::=
20244
20245 left-fringe - left fringe width in pixels
20246 right-fringe - right fringe width in pixels
20247
20248 left-margin - left margin width in pixels
20249 right-margin - right margin width in pixels
20250
20251 scroll-bar - scroll-bar area width in pixels
20252
20253 Examples:
20254
20255 Pixels corresponding to 5 inches:
20256 (5 . in)
20257
20258 Total width of non-text areas on left side of window (if scroll-bar is on left):
20259 '(space :width (+ left-fringe left-margin scroll-bar))
20260
20261 Align to first text column (in header line):
20262 '(space :align-to 0)
20263
20264 Align to middle of text area minus half the width of variable `my-image'
20265 containing a loaded image:
20266 '(space :align-to (0.5 . (- text my-image)))
20267
20268 Width of left margin minus width of 1 character in the default font:
20269 '(space :width (- left-margin 1))
20270
20271 Width of left margin minus width of 2 characters in the current font:
20272 '(space :width (- left-margin (2 . width)))
20273
20274 Center 1 character over left-margin (in header line):
20275 '(space :align-to (+ left-margin (0.5 . left-margin) -0.5))
20276
20277 Different ways to express width of left fringe plus left margin minus one pixel:
20278 '(space :width (- (+ left-fringe left-margin) (1)))
20279 '(space :width (+ left-fringe left-margin (- (1))))
20280 '(space :width (+ left-fringe left-margin (-1)))
20281
20282 */
20283
20284 #define NUMVAL(X) \
20285 ((INTEGERP (X) || FLOATP (X)) \
20286 ? XFLOATINT (X) \
20287 : - 1)
20288
20289 int
20290 calc_pixel_width_or_height (double *res, struct it *it, Lisp_Object prop,
20291 struct font *font, int width_p, int *align_to)
20292 {
20293 double pixels;
20294
20295 #define OK_PIXELS(val) ((*res = (double)(val)), 1)
20296 #define OK_ALIGN_TO(val) ((*align_to = (int)(val)), 1)
20297
20298 if (NILP (prop))
20299 return OK_PIXELS (0);
20300
20301 xassert (FRAME_LIVE_P (it->f));
20302
20303 if (SYMBOLP (prop))
20304 {
20305 if (SCHARS (SYMBOL_NAME (prop)) == 2)
20306 {
20307 char *unit = SSDATA (SYMBOL_NAME (prop));
20308
20309 if (unit[0] == 'i' && unit[1] == 'n')
20310 pixels = 1.0;
20311 else if (unit[0] == 'm' && unit[1] == 'm')
20312 pixels = 25.4;
20313 else if (unit[0] == 'c' && unit[1] == 'm')
20314 pixels = 2.54;
20315 else
20316 pixels = 0;
20317 if (pixels > 0)
20318 {
20319 double ppi;
20320 #ifdef HAVE_WINDOW_SYSTEM
20321 if (FRAME_WINDOW_P (it->f)
20322 && (ppi = (width_p
20323 ? FRAME_X_DISPLAY_INFO (it->f)->resx
20324 : FRAME_X_DISPLAY_INFO (it->f)->resy),
20325 ppi > 0))
20326 return OK_PIXELS (ppi / pixels);
20327 #endif
20328
20329 if ((ppi = NUMVAL (Vdisplay_pixels_per_inch), ppi > 0)
20330 || (CONSP (Vdisplay_pixels_per_inch)
20331 && (ppi = (width_p
20332 ? NUMVAL (XCAR (Vdisplay_pixels_per_inch))
20333 : NUMVAL (XCDR (Vdisplay_pixels_per_inch))),
20334 ppi > 0)))
20335 return OK_PIXELS (ppi / pixels);
20336
20337 return 0;
20338 }
20339 }
20340
20341 #ifdef HAVE_WINDOW_SYSTEM
20342 if (EQ (prop, Qheight))
20343 return OK_PIXELS (font ? FONT_HEIGHT (font) : FRAME_LINE_HEIGHT (it->f));
20344 if (EQ (prop, Qwidth))
20345 return OK_PIXELS (font ? FONT_WIDTH (font) : FRAME_COLUMN_WIDTH (it->f));
20346 #else
20347 if (EQ (prop, Qheight) || EQ (prop, Qwidth))
20348 return OK_PIXELS (1);
20349 #endif
20350
20351 if (EQ (prop, Qtext))
20352 return OK_PIXELS (width_p
20353 ? window_box_width (it->w, TEXT_AREA)
20354 : WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w));
20355
20356 if (align_to && *align_to < 0)
20357 {
20358 *res = 0;
20359 if (EQ (prop, Qleft))
20360 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA));
20361 if (EQ (prop, Qright))
20362 return OK_ALIGN_TO (window_box_right_offset (it->w, TEXT_AREA));
20363 if (EQ (prop, Qcenter))
20364 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA)
20365 + window_box_width (it->w, TEXT_AREA) / 2);
20366 if (EQ (prop, Qleft_fringe))
20367 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
20368 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (it->w)
20369 : window_box_right_offset (it->w, LEFT_MARGIN_AREA));
20370 if (EQ (prop, Qright_fringe))
20371 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
20372 ? window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
20373 : window_box_right_offset (it->w, TEXT_AREA));
20374 if (EQ (prop, Qleft_margin))
20375 return OK_ALIGN_TO (window_box_left_offset (it->w, LEFT_MARGIN_AREA));
20376 if (EQ (prop, Qright_margin))
20377 return OK_ALIGN_TO (window_box_left_offset (it->w, RIGHT_MARGIN_AREA));
20378 if (EQ (prop, Qscroll_bar))
20379 return OK_ALIGN_TO (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (it->w)
20380 ? 0
20381 : (window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
20382 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
20383 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
20384 : 0)));
20385 }
20386 else
20387 {
20388 if (EQ (prop, Qleft_fringe))
20389 return OK_PIXELS (WINDOW_LEFT_FRINGE_WIDTH (it->w));
20390 if (EQ (prop, Qright_fringe))
20391 return OK_PIXELS (WINDOW_RIGHT_FRINGE_WIDTH (it->w));
20392 if (EQ (prop, Qleft_margin))
20393 return OK_PIXELS (WINDOW_LEFT_MARGIN_WIDTH (it->w));
20394 if (EQ (prop, Qright_margin))
20395 return OK_PIXELS (WINDOW_RIGHT_MARGIN_WIDTH (it->w));
20396 if (EQ (prop, Qscroll_bar))
20397 return OK_PIXELS (WINDOW_SCROLL_BAR_AREA_WIDTH (it->w));
20398 }
20399
20400 prop = Fbuffer_local_value (prop, it->w->buffer);
20401 }
20402
20403 if (INTEGERP (prop) || FLOATP (prop))
20404 {
20405 int base_unit = (width_p
20406 ? FRAME_COLUMN_WIDTH (it->f)
20407 : FRAME_LINE_HEIGHT (it->f));
20408 return OK_PIXELS (XFLOATINT (prop) * base_unit);
20409 }
20410
20411 if (CONSP (prop))
20412 {
20413 Lisp_Object car = XCAR (prop);
20414 Lisp_Object cdr = XCDR (prop);
20415
20416 if (SYMBOLP (car))
20417 {
20418 #ifdef HAVE_WINDOW_SYSTEM
20419 if (FRAME_WINDOW_P (it->f)
20420 && valid_image_p (prop))
20421 {
20422 int id = lookup_image (it->f, prop);
20423 struct image *img = IMAGE_FROM_ID (it->f, id);
20424
20425 return OK_PIXELS (width_p ? img->width : img->height);
20426 }
20427 #endif
20428 if (EQ (car, Qplus) || EQ (car, Qminus))
20429 {
20430 int first = 1;
20431 double px;
20432
20433 pixels = 0;
20434 while (CONSP (cdr))
20435 {
20436 if (!calc_pixel_width_or_height (&px, it, XCAR (cdr),
20437 font, width_p, align_to))
20438 return 0;
20439 if (first)
20440 pixels = (EQ (car, Qplus) ? px : -px), first = 0;
20441 else
20442 pixels += px;
20443 cdr = XCDR (cdr);
20444 }
20445 if (EQ (car, Qminus))
20446 pixels = -pixels;
20447 return OK_PIXELS (pixels);
20448 }
20449
20450 car = Fbuffer_local_value (car, it->w->buffer);
20451 }
20452
20453 if (INTEGERP (car) || FLOATP (car))
20454 {
20455 double fact;
20456 pixels = XFLOATINT (car);
20457 if (NILP (cdr))
20458 return OK_PIXELS (pixels);
20459 if (calc_pixel_width_or_height (&fact, it, cdr,
20460 font, width_p, align_to))
20461 return OK_PIXELS (pixels * fact);
20462 return 0;
20463 }
20464
20465 return 0;
20466 }
20467
20468 return 0;
20469 }
20470
20471 \f
20472 /***********************************************************************
20473 Glyph Display
20474 ***********************************************************************/
20475
20476 #ifdef HAVE_WINDOW_SYSTEM
20477
20478 #if GLYPH_DEBUG
20479
20480 void
20481 dump_glyph_string (s)
20482 struct glyph_string *s;
20483 {
20484 fprintf (stderr, "glyph string\n");
20485 fprintf (stderr, " x, y, w, h = %d, %d, %d, %d\n",
20486 s->x, s->y, s->width, s->height);
20487 fprintf (stderr, " ybase = %d\n", s->ybase);
20488 fprintf (stderr, " hl = %d\n", s->hl);
20489 fprintf (stderr, " left overhang = %d, right = %d\n",
20490 s->left_overhang, s->right_overhang);
20491 fprintf (stderr, " nchars = %d\n", s->nchars);
20492 fprintf (stderr, " extends to end of line = %d\n",
20493 s->extends_to_end_of_line_p);
20494 fprintf (stderr, " font height = %d\n", FONT_HEIGHT (s->font));
20495 fprintf (stderr, " bg width = %d\n", s->background_width);
20496 }
20497
20498 #endif /* GLYPH_DEBUG */
20499
20500 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
20501 of XChar2b structures for S; it can't be allocated in
20502 init_glyph_string because it must be allocated via `alloca'. W
20503 is the window on which S is drawn. ROW and AREA are the glyph row
20504 and area within the row from which S is constructed. START is the
20505 index of the first glyph structure covered by S. HL is a
20506 face-override for drawing S. */
20507
20508 #ifdef HAVE_NTGUI
20509 #define OPTIONAL_HDC(hdc) HDC hdc,
20510 #define DECLARE_HDC(hdc) HDC hdc;
20511 #define ALLOCATE_HDC(hdc, f) hdc = get_frame_dc ((f))
20512 #define RELEASE_HDC(hdc, f) release_frame_dc ((f), (hdc))
20513 #endif
20514
20515 #ifndef OPTIONAL_HDC
20516 #define OPTIONAL_HDC(hdc)
20517 #define DECLARE_HDC(hdc)
20518 #define ALLOCATE_HDC(hdc, f)
20519 #define RELEASE_HDC(hdc, f)
20520 #endif
20521
20522 static void
20523 init_glyph_string (struct glyph_string *s,
20524 OPTIONAL_HDC (hdc)
20525 XChar2b *char2b, struct window *w, struct glyph_row *row,
20526 enum glyph_row_area area, int start, enum draw_glyphs_face hl)
20527 {
20528 memset (s, 0, sizeof *s);
20529 s->w = w;
20530 s->f = XFRAME (w->frame);
20531 #ifdef HAVE_NTGUI
20532 s->hdc = hdc;
20533 #endif
20534 s->display = FRAME_X_DISPLAY (s->f);
20535 s->window = FRAME_X_WINDOW (s->f);
20536 s->char2b = char2b;
20537 s->hl = hl;
20538 s->row = row;
20539 s->area = area;
20540 s->first_glyph = row->glyphs[area] + start;
20541 s->height = row->height;
20542 s->y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
20543 s->ybase = s->y + row->ascent;
20544 }
20545
20546
20547 /* Append the list of glyph strings with head H and tail T to the list
20548 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
20549
20550 static INLINE void
20551 append_glyph_string_lists (struct glyph_string **head, struct glyph_string **tail,
20552 struct glyph_string *h, struct glyph_string *t)
20553 {
20554 if (h)
20555 {
20556 if (*head)
20557 (*tail)->next = h;
20558 else
20559 *head = h;
20560 h->prev = *tail;
20561 *tail = t;
20562 }
20563 }
20564
20565
20566 /* Prepend the list of glyph strings with head H and tail T to the
20567 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
20568 result. */
20569
20570 static INLINE void
20571 prepend_glyph_string_lists (struct glyph_string **head, struct glyph_string **tail,
20572 struct glyph_string *h, struct glyph_string *t)
20573 {
20574 if (h)
20575 {
20576 if (*head)
20577 (*head)->prev = t;
20578 else
20579 *tail = t;
20580 t->next = *head;
20581 *head = h;
20582 }
20583 }
20584
20585
20586 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
20587 Set *HEAD and *TAIL to the resulting list. */
20588
20589 static INLINE void
20590 append_glyph_string (struct glyph_string **head, struct glyph_string **tail,
20591 struct glyph_string *s)
20592 {
20593 s->next = s->prev = NULL;
20594 append_glyph_string_lists (head, tail, s, s);
20595 }
20596
20597
20598 /* Get face and two-byte form of character C in face FACE_ID on frame F.
20599 The encoding of C is returned in *CHAR2B. DISPLAY_P non-zero means
20600 make sure that X resources for the face returned are allocated.
20601 Value is a pointer to a realized face that is ready for display if
20602 DISPLAY_P is non-zero. */
20603
20604 static INLINE struct face *
20605 get_char_face_and_encoding (struct frame *f, int c, int face_id,
20606 XChar2b *char2b, int display_p)
20607 {
20608 struct face *face = FACE_FROM_ID (f, face_id);
20609
20610 if (face->font)
20611 {
20612 unsigned code = face->font->driver->encode_char (face->font, c);
20613
20614 if (code != FONT_INVALID_CODE)
20615 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
20616 else
20617 STORE_XCHAR2B (char2b, 0, 0);
20618 }
20619
20620 /* Make sure X resources of the face are allocated. */
20621 #ifdef HAVE_X_WINDOWS
20622 if (display_p)
20623 #endif
20624 {
20625 xassert (face != NULL);
20626 PREPARE_FACE_FOR_DISPLAY (f, face);
20627 }
20628
20629 return face;
20630 }
20631
20632
20633 /* Get face and two-byte form of character glyph GLYPH on frame F.
20634 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
20635 a pointer to a realized face that is ready for display. */
20636
20637 static INLINE struct face *
20638 get_glyph_face_and_encoding (struct frame *f, struct glyph *glyph,
20639 XChar2b *char2b, int *two_byte_p)
20640 {
20641 struct face *face;
20642
20643 xassert (glyph->type == CHAR_GLYPH);
20644 face = FACE_FROM_ID (f, glyph->face_id);
20645
20646 if (two_byte_p)
20647 *two_byte_p = 0;
20648
20649 if (face->font)
20650 {
20651 unsigned code;
20652
20653 if (CHAR_BYTE8_P (glyph->u.ch))
20654 code = CHAR_TO_BYTE8 (glyph->u.ch);
20655 else
20656 code = face->font->driver->encode_char (face->font, glyph->u.ch);
20657
20658 if (code != FONT_INVALID_CODE)
20659 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
20660 else
20661 STORE_XCHAR2B (char2b, 0, 0);
20662 }
20663
20664 /* Make sure X resources of the face are allocated. */
20665 xassert (face != NULL);
20666 PREPARE_FACE_FOR_DISPLAY (f, face);
20667 return face;
20668 }
20669
20670
20671 /* Get glyph code of character C in FONT in the two-byte form CHAR2B.
20672 Retunr 1 if FONT has a glyph for C, otherwise return 0. */
20673
20674 static INLINE int
20675 get_char_glyph_code (int c, struct font *font, XChar2b *char2b)
20676 {
20677 unsigned code;
20678
20679 if (CHAR_BYTE8_P (c))
20680 code = CHAR_TO_BYTE8 (c);
20681 else
20682 code = font->driver->encode_char (font, c);
20683
20684 if (code == FONT_INVALID_CODE)
20685 return 0;
20686 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
20687 return 1;
20688 }
20689
20690
20691 /* Fill glyph string S with composition components specified by S->cmp.
20692
20693 BASE_FACE is the base face of the composition.
20694 S->cmp_from is the index of the first component for S.
20695
20696 OVERLAPS non-zero means S should draw the foreground only, and use
20697 its physical height for clipping. See also draw_glyphs.
20698
20699 Value is the index of a component not in S. */
20700
20701 static int
20702 fill_composite_glyph_string (struct glyph_string *s, struct face *base_face,
20703 int overlaps)
20704 {
20705 int i;
20706 /* For all glyphs of this composition, starting at the offset
20707 S->cmp_from, until we reach the end of the definition or encounter a
20708 glyph that requires the different face, add it to S. */
20709 struct face *face;
20710
20711 xassert (s);
20712
20713 s->for_overlaps = overlaps;
20714 s->face = NULL;
20715 s->font = NULL;
20716 for (i = s->cmp_from; i < s->cmp->glyph_len; i++)
20717 {
20718 int c = COMPOSITION_GLYPH (s->cmp, i);
20719
20720 if (c != '\t')
20721 {
20722 int face_id = FACE_FOR_CHAR (s->f, base_face->ascii_face, c,
20723 -1, Qnil);
20724
20725 face = get_char_face_and_encoding (s->f, c, face_id,
20726 s->char2b + i, 1);
20727 if (face)
20728 {
20729 if (! s->face)
20730 {
20731 s->face = face;
20732 s->font = s->face->font;
20733 }
20734 else if (s->face != face)
20735 break;
20736 }
20737 }
20738 ++s->nchars;
20739 }
20740 s->cmp_to = i;
20741
20742 /* All glyph strings for the same composition has the same width,
20743 i.e. the width set for the first component of the composition. */
20744 s->width = s->first_glyph->pixel_width;
20745
20746 /* If the specified font could not be loaded, use the frame's
20747 default font, but record the fact that we couldn't load it in
20748 the glyph string so that we can draw rectangles for the
20749 characters of the glyph string. */
20750 if (s->font == NULL)
20751 {
20752 s->font_not_found_p = 1;
20753 s->font = FRAME_FONT (s->f);
20754 }
20755
20756 /* Adjust base line for subscript/superscript text. */
20757 s->ybase += s->first_glyph->voffset;
20758
20759 /* This glyph string must always be drawn with 16-bit functions. */
20760 s->two_byte_p = 1;
20761
20762 return s->cmp_to;
20763 }
20764
20765 static int
20766 fill_gstring_glyph_string (struct glyph_string *s, int face_id,
20767 int start, int end, int overlaps)
20768 {
20769 struct glyph *glyph, *last;
20770 Lisp_Object lgstring;
20771 int i;
20772
20773 s->for_overlaps = overlaps;
20774 glyph = s->row->glyphs[s->area] + start;
20775 last = s->row->glyphs[s->area] + end;
20776 s->cmp_id = glyph->u.cmp.id;
20777 s->cmp_from = glyph->slice.cmp.from;
20778 s->cmp_to = glyph->slice.cmp.to + 1;
20779 s->face = FACE_FROM_ID (s->f, face_id);
20780 lgstring = composition_gstring_from_id (s->cmp_id);
20781 s->font = XFONT_OBJECT (LGSTRING_FONT (lgstring));
20782 glyph++;
20783 while (glyph < last
20784 && glyph->u.cmp.automatic
20785 && glyph->u.cmp.id == s->cmp_id
20786 && s->cmp_to == glyph->slice.cmp.from)
20787 s->cmp_to = (glyph++)->slice.cmp.to + 1;
20788
20789 for (i = s->cmp_from; i < s->cmp_to; i++)
20790 {
20791 Lisp_Object lglyph = LGSTRING_GLYPH (lgstring, i);
20792 unsigned code = LGLYPH_CODE (lglyph);
20793
20794 STORE_XCHAR2B ((s->char2b + i), code >> 8, code & 0xFF);
20795 }
20796 s->width = composition_gstring_width (lgstring, s->cmp_from, s->cmp_to, NULL);
20797 return glyph - s->row->glyphs[s->area];
20798 }
20799
20800
20801 /* Fill glyph string S from a sequence glyphs for glyphless characters.
20802 See the comment of fill_glyph_string for arguments.
20803 Value is the index of the first glyph not in S. */
20804
20805
20806 static int
20807 fill_glyphless_glyph_string (struct glyph_string *s, int face_id,
20808 int start, int end, int overlaps)
20809 {
20810 struct glyph *glyph, *last;
20811 int voffset;
20812
20813 xassert (s->first_glyph->type == GLYPHLESS_GLYPH);
20814 s->for_overlaps = overlaps;
20815 glyph = s->row->glyphs[s->area] + start;
20816 last = s->row->glyphs[s->area] + end;
20817 voffset = glyph->voffset;
20818 s->face = FACE_FROM_ID (s->f, face_id);
20819 s->font = s->face->font;
20820 s->nchars = 1;
20821 s->width = glyph->pixel_width;
20822 glyph++;
20823 while (glyph < last
20824 && glyph->type == GLYPHLESS_GLYPH
20825 && glyph->voffset == voffset
20826 && glyph->face_id == face_id)
20827 {
20828 s->nchars++;
20829 s->width += glyph->pixel_width;
20830 glyph++;
20831 }
20832 s->ybase += voffset;
20833 return glyph - s->row->glyphs[s->area];
20834 }
20835
20836
20837 /* Fill glyph string S from a sequence of character glyphs.
20838
20839 FACE_ID is the face id of the string. START is the index of the
20840 first glyph to consider, END is the index of the last + 1.
20841 OVERLAPS non-zero means S should draw the foreground only, and use
20842 its physical height for clipping. See also draw_glyphs.
20843
20844 Value is the index of the first glyph not in S. */
20845
20846 static int
20847 fill_glyph_string (struct glyph_string *s, int face_id,
20848 int start, int end, int overlaps)
20849 {
20850 struct glyph *glyph, *last;
20851 int voffset;
20852 int glyph_not_available_p;
20853
20854 xassert (s->f == XFRAME (s->w->frame));
20855 xassert (s->nchars == 0);
20856 xassert (start >= 0 && end > start);
20857
20858 s->for_overlaps = overlaps;
20859 glyph = s->row->glyphs[s->area] + start;
20860 last = s->row->glyphs[s->area] + end;
20861 voffset = glyph->voffset;
20862 s->padding_p = glyph->padding_p;
20863 glyph_not_available_p = glyph->glyph_not_available_p;
20864
20865 while (glyph < last
20866 && glyph->type == CHAR_GLYPH
20867 && glyph->voffset == voffset
20868 /* Same face id implies same font, nowadays. */
20869 && glyph->face_id == face_id
20870 && glyph->glyph_not_available_p == glyph_not_available_p)
20871 {
20872 int two_byte_p;
20873
20874 s->face = get_glyph_face_and_encoding (s->f, glyph,
20875 s->char2b + s->nchars,
20876 &two_byte_p);
20877 s->two_byte_p = two_byte_p;
20878 ++s->nchars;
20879 xassert (s->nchars <= end - start);
20880 s->width += glyph->pixel_width;
20881 if (glyph++->padding_p != s->padding_p)
20882 break;
20883 }
20884
20885 s->font = s->face->font;
20886
20887 /* If the specified font could not be loaded, use the frame's font,
20888 but record the fact that we couldn't load it in
20889 S->font_not_found_p so that we can draw rectangles for the
20890 characters of the glyph string. */
20891 if (s->font == NULL || glyph_not_available_p)
20892 {
20893 s->font_not_found_p = 1;
20894 s->font = FRAME_FONT (s->f);
20895 }
20896
20897 /* Adjust base line for subscript/superscript text. */
20898 s->ybase += voffset;
20899
20900 xassert (s->face && s->face->gc);
20901 return glyph - s->row->glyphs[s->area];
20902 }
20903
20904
20905 /* Fill glyph string S from image glyph S->first_glyph. */
20906
20907 static void
20908 fill_image_glyph_string (struct glyph_string *s)
20909 {
20910 xassert (s->first_glyph->type == IMAGE_GLYPH);
20911 s->img = IMAGE_FROM_ID (s->f, s->first_glyph->u.img_id);
20912 xassert (s->img);
20913 s->slice = s->first_glyph->slice.img;
20914 s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
20915 s->font = s->face->font;
20916 s->width = s->first_glyph->pixel_width;
20917
20918 /* Adjust base line for subscript/superscript text. */
20919 s->ybase += s->first_glyph->voffset;
20920 }
20921
20922
20923 /* Fill glyph string S from a sequence of stretch glyphs.
20924
20925 START is the index of the first glyph to consider,
20926 END is the index of the last + 1.
20927
20928 Value is the index of the first glyph not in S. */
20929
20930 static int
20931 fill_stretch_glyph_string (struct glyph_string *s, int start, int end)
20932 {
20933 struct glyph *glyph, *last;
20934 int voffset, face_id;
20935
20936 xassert (s->first_glyph->type == STRETCH_GLYPH);
20937
20938 glyph = s->row->glyphs[s->area] + start;
20939 last = s->row->glyphs[s->area] + end;
20940 face_id = glyph->face_id;
20941 s->face = FACE_FROM_ID (s->f, face_id);
20942 s->font = s->face->font;
20943 s->width = glyph->pixel_width;
20944 s->nchars = 1;
20945 voffset = glyph->voffset;
20946
20947 for (++glyph;
20948 (glyph < last
20949 && glyph->type == STRETCH_GLYPH
20950 && glyph->voffset == voffset
20951 && glyph->face_id == face_id);
20952 ++glyph)
20953 s->width += glyph->pixel_width;
20954
20955 /* Adjust base line for subscript/superscript text. */
20956 s->ybase += voffset;
20957
20958 /* The case that face->gc == 0 is handled when drawing the glyph
20959 string by calling PREPARE_FACE_FOR_DISPLAY. */
20960 xassert (s->face);
20961 return glyph - s->row->glyphs[s->area];
20962 }
20963
20964 static struct font_metrics *
20965 get_per_char_metric (struct font *font, XChar2b *char2b)
20966 {
20967 static struct font_metrics metrics;
20968 unsigned code = (XCHAR2B_BYTE1 (char2b) << 8) | XCHAR2B_BYTE2 (char2b);
20969
20970 if (! font || code == FONT_INVALID_CODE)
20971 return NULL;
20972 font->driver->text_extents (font, &code, 1, &metrics);
20973 return &metrics;
20974 }
20975
20976 /* EXPORT for RIF:
20977 Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
20978 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
20979 assumed to be zero. */
20980
20981 void
20982 x_get_glyph_overhangs (struct glyph *glyph, struct frame *f, int *left, int *right)
20983 {
20984 *left = *right = 0;
20985
20986 if (glyph->type == CHAR_GLYPH)
20987 {
20988 struct face *face;
20989 XChar2b char2b;
20990 struct font_metrics *pcm;
20991
20992 face = get_glyph_face_and_encoding (f, glyph, &char2b, NULL);
20993 if (face->font && (pcm = get_per_char_metric (face->font, &char2b)))
20994 {
20995 if (pcm->rbearing > pcm->width)
20996 *right = pcm->rbearing - pcm->width;
20997 if (pcm->lbearing < 0)
20998 *left = -pcm->lbearing;
20999 }
21000 }
21001 else if (glyph->type == COMPOSITE_GLYPH)
21002 {
21003 if (! glyph->u.cmp.automatic)
21004 {
21005 struct composition *cmp = composition_table[glyph->u.cmp.id];
21006
21007 if (cmp->rbearing > cmp->pixel_width)
21008 *right = cmp->rbearing - cmp->pixel_width;
21009 if (cmp->lbearing < 0)
21010 *left = - cmp->lbearing;
21011 }
21012 else
21013 {
21014 Lisp_Object gstring = composition_gstring_from_id (glyph->u.cmp.id);
21015 struct font_metrics metrics;
21016
21017 composition_gstring_width (gstring, glyph->slice.cmp.from,
21018 glyph->slice.cmp.to + 1, &metrics);
21019 if (metrics.rbearing > metrics.width)
21020 *right = metrics.rbearing - metrics.width;
21021 if (metrics.lbearing < 0)
21022 *left = - metrics.lbearing;
21023 }
21024 }
21025 }
21026
21027
21028 /* Return the index of the first glyph preceding glyph string S that
21029 is overwritten by S because of S's left overhang. Value is -1
21030 if no glyphs are overwritten. */
21031
21032 static int
21033 left_overwritten (struct glyph_string *s)
21034 {
21035 int k;
21036
21037 if (s->left_overhang)
21038 {
21039 int x = 0, i;
21040 struct glyph *glyphs = s->row->glyphs[s->area];
21041 int first = s->first_glyph - glyphs;
21042
21043 for (i = first - 1; i >= 0 && x > -s->left_overhang; --i)
21044 x -= glyphs[i].pixel_width;
21045
21046 k = i + 1;
21047 }
21048 else
21049 k = -1;
21050
21051 return k;
21052 }
21053
21054
21055 /* Return the index of the first glyph preceding glyph string S that
21056 is overwriting S because of its right overhang. Value is -1 if no
21057 glyph in front of S overwrites S. */
21058
21059 static int
21060 left_overwriting (struct glyph_string *s)
21061 {
21062 int i, k, x;
21063 struct glyph *glyphs = s->row->glyphs[s->area];
21064 int first = s->first_glyph - glyphs;
21065
21066 k = -1;
21067 x = 0;
21068 for (i = first - 1; i >= 0; --i)
21069 {
21070 int left, right;
21071 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
21072 if (x + right > 0)
21073 k = i;
21074 x -= glyphs[i].pixel_width;
21075 }
21076
21077 return k;
21078 }
21079
21080
21081 /* Return the index of the last glyph following glyph string S that is
21082 overwritten by S because of S's right overhang. Value is -1 if
21083 no such glyph is found. */
21084
21085 static int
21086 right_overwritten (struct glyph_string *s)
21087 {
21088 int k = -1;
21089
21090 if (s->right_overhang)
21091 {
21092 int x = 0, i;
21093 struct glyph *glyphs = s->row->glyphs[s->area];
21094 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
21095 int end = s->row->used[s->area];
21096
21097 for (i = first; i < end && s->right_overhang > x; ++i)
21098 x += glyphs[i].pixel_width;
21099
21100 k = i;
21101 }
21102
21103 return k;
21104 }
21105
21106
21107 /* Return the index of the last glyph following glyph string S that
21108 overwrites S because of its left overhang. Value is negative
21109 if no such glyph is found. */
21110
21111 static int
21112 right_overwriting (struct glyph_string *s)
21113 {
21114 int i, k, x;
21115 int end = s->row->used[s->area];
21116 struct glyph *glyphs = s->row->glyphs[s->area];
21117 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
21118
21119 k = -1;
21120 x = 0;
21121 for (i = first; i < end; ++i)
21122 {
21123 int left, right;
21124 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
21125 if (x - left < 0)
21126 k = i;
21127 x += glyphs[i].pixel_width;
21128 }
21129
21130 return k;
21131 }
21132
21133
21134 /* Set background width of glyph string S. START is the index of the
21135 first glyph following S. LAST_X is the right-most x-position + 1
21136 in the drawing area. */
21137
21138 static INLINE void
21139 set_glyph_string_background_width (struct glyph_string *s, int start, int last_x)
21140 {
21141 /* If the face of this glyph string has to be drawn to the end of
21142 the drawing area, set S->extends_to_end_of_line_p. */
21143
21144 if (start == s->row->used[s->area]
21145 && s->area == TEXT_AREA
21146 && ((s->row->fill_line_p
21147 && (s->hl == DRAW_NORMAL_TEXT
21148 || s->hl == DRAW_IMAGE_RAISED
21149 || s->hl == DRAW_IMAGE_SUNKEN))
21150 || s->hl == DRAW_MOUSE_FACE))
21151 s->extends_to_end_of_line_p = 1;
21152
21153 /* If S extends its face to the end of the line, set its
21154 background_width to the distance to the right edge of the drawing
21155 area. */
21156 if (s->extends_to_end_of_line_p)
21157 s->background_width = last_x - s->x + 1;
21158 else
21159 s->background_width = s->width;
21160 }
21161
21162
21163 /* Compute overhangs and x-positions for glyph string S and its
21164 predecessors, or successors. X is the starting x-position for S.
21165 BACKWARD_P non-zero means process predecessors. */
21166
21167 static void
21168 compute_overhangs_and_x (struct glyph_string *s, int x, int backward_p)
21169 {
21170 if (backward_p)
21171 {
21172 while (s)
21173 {
21174 if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
21175 FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
21176 x -= s->width;
21177 s->x = x;
21178 s = s->prev;
21179 }
21180 }
21181 else
21182 {
21183 while (s)
21184 {
21185 if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
21186 FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
21187 s->x = x;
21188 x += s->width;
21189 s = s->next;
21190 }
21191 }
21192 }
21193
21194
21195
21196 /* The following macros are only called from draw_glyphs below.
21197 They reference the following parameters of that function directly:
21198 `w', `row', `area', and `overlap_p'
21199 as well as the following local variables:
21200 `s', `f', and `hdc' (in W32) */
21201
21202 #ifdef HAVE_NTGUI
21203 /* On W32, silently add local `hdc' variable to argument list of
21204 init_glyph_string. */
21205 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
21206 init_glyph_string (s, hdc, char2b, w, row, area, start, hl)
21207 #else
21208 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
21209 init_glyph_string (s, char2b, w, row, area, start, hl)
21210 #endif
21211
21212 /* Add a glyph string for a stretch glyph to the list of strings
21213 between HEAD and TAIL. START is the index of the stretch glyph in
21214 row area AREA of glyph row ROW. END is the index of the last glyph
21215 in that glyph row area. X is the current output position assigned
21216 to the new glyph string constructed. HL overrides that face of the
21217 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
21218 is the right-most x-position of the drawing area. */
21219
21220 /* SunOS 4 bundled cc, barfed on continuations in the arg lists here
21221 and below -- keep them on one line. */
21222 #define BUILD_STRETCH_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
21223 do \
21224 { \
21225 s = (struct glyph_string *) alloca (sizeof *s); \
21226 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
21227 START = fill_stretch_glyph_string (s, START, END); \
21228 append_glyph_string (&HEAD, &TAIL, s); \
21229 s->x = (X); \
21230 } \
21231 while (0)
21232
21233
21234 /* Add a glyph string for an image glyph to the list of strings
21235 between HEAD and TAIL. START is the index of the image glyph in
21236 row area AREA of glyph row ROW. END is the index of the last glyph
21237 in that glyph row area. X is the current output position assigned
21238 to the new glyph string constructed. HL overrides that face of the
21239 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
21240 is the right-most x-position of the drawing area. */
21241
21242 #define BUILD_IMAGE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
21243 do \
21244 { \
21245 s = (struct glyph_string *) alloca (sizeof *s); \
21246 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
21247 fill_image_glyph_string (s); \
21248 append_glyph_string (&HEAD, &TAIL, s); \
21249 ++START; \
21250 s->x = (X); \
21251 } \
21252 while (0)
21253
21254
21255 /* Add a glyph string for a sequence of character glyphs to the list
21256 of strings between HEAD and TAIL. START is the index of the first
21257 glyph in row area AREA of glyph row ROW that is part of the new
21258 glyph string. END is the index of the last glyph in that glyph row
21259 area. X is the current output position assigned to the new glyph
21260 string constructed. HL overrides that face of the glyph; e.g. it
21261 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
21262 right-most x-position of the drawing area. */
21263
21264 #define BUILD_CHAR_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
21265 do \
21266 { \
21267 int face_id; \
21268 XChar2b *char2b; \
21269 \
21270 face_id = (row)->glyphs[area][START].face_id; \
21271 \
21272 s = (struct glyph_string *) alloca (sizeof *s); \
21273 char2b = (XChar2b *) alloca ((END - START) * sizeof *char2b); \
21274 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
21275 append_glyph_string (&HEAD, &TAIL, s); \
21276 s->x = (X); \
21277 START = fill_glyph_string (s, face_id, START, END, overlaps); \
21278 } \
21279 while (0)
21280
21281
21282 /* Add a glyph string for a composite sequence to the list of strings
21283 between HEAD and TAIL. START is the index of the first glyph in
21284 row area AREA of glyph row ROW that is part of the new glyph
21285 string. END is the index of the last glyph in that glyph row area.
21286 X is the current output position assigned to the new glyph string
21287 constructed. HL overrides that face of the glyph; e.g. it is
21288 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
21289 x-position of the drawing area. */
21290
21291 #define BUILD_COMPOSITE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
21292 do { \
21293 int face_id = (row)->glyphs[area][START].face_id; \
21294 struct face *base_face = FACE_FROM_ID (f, face_id); \
21295 int cmp_id = (row)->glyphs[area][START].u.cmp.id; \
21296 struct composition *cmp = composition_table[cmp_id]; \
21297 XChar2b *char2b; \
21298 struct glyph_string *first_s IF_LINT (= NULL); \
21299 int n; \
21300 \
21301 char2b = (XChar2b *) alloca ((sizeof *char2b) * cmp->glyph_len); \
21302 \
21303 /* Make glyph_strings for each glyph sequence that is drawable by \
21304 the same face, and append them to HEAD/TAIL. */ \
21305 for (n = 0; n < cmp->glyph_len;) \
21306 { \
21307 s = (struct glyph_string *) alloca (sizeof *s); \
21308 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
21309 append_glyph_string (&(HEAD), &(TAIL), s); \
21310 s->cmp = cmp; \
21311 s->cmp_from = n; \
21312 s->x = (X); \
21313 if (n == 0) \
21314 first_s = s; \
21315 n = fill_composite_glyph_string (s, base_face, overlaps); \
21316 } \
21317 \
21318 ++START; \
21319 s = first_s; \
21320 } while (0)
21321
21322
21323 /* Add a glyph string for a glyph-string sequence to the list of strings
21324 between HEAD and TAIL. */
21325
21326 #define BUILD_GSTRING_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
21327 do { \
21328 int face_id; \
21329 XChar2b *char2b; \
21330 Lisp_Object gstring; \
21331 \
21332 face_id = (row)->glyphs[area][START].face_id; \
21333 gstring = (composition_gstring_from_id \
21334 ((row)->glyphs[area][START].u.cmp.id)); \
21335 s = (struct glyph_string *) alloca (sizeof *s); \
21336 char2b = (XChar2b *) alloca ((sizeof *char2b) \
21337 * LGSTRING_GLYPH_LEN (gstring)); \
21338 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
21339 append_glyph_string (&(HEAD), &(TAIL), s); \
21340 s->x = (X); \
21341 START = fill_gstring_glyph_string (s, face_id, START, END, overlaps); \
21342 } while (0)
21343
21344
21345 /* Add a glyph string for a sequence of glyphless character's glyphs
21346 to the list of strings between HEAD and TAIL. The meanings of
21347 arguments are the same as those of BUILD_CHAR_GLYPH_STRINGS. */
21348
21349 #define BUILD_GLYPHLESS_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
21350 do \
21351 { \
21352 int face_id; \
21353 \
21354 face_id = (row)->glyphs[area][START].face_id; \
21355 \
21356 s = (struct glyph_string *) alloca (sizeof *s); \
21357 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
21358 append_glyph_string (&HEAD, &TAIL, s); \
21359 s->x = (X); \
21360 START = fill_glyphless_glyph_string (s, face_id, START, END, \
21361 overlaps); \
21362 } \
21363 while (0)
21364
21365
21366 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
21367 of AREA of glyph row ROW on window W between indices START and END.
21368 HL overrides the face for drawing glyph strings, e.g. it is
21369 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
21370 x-positions of the drawing area.
21371
21372 This is an ugly monster macro construct because we must use alloca
21373 to allocate glyph strings (because draw_glyphs can be called
21374 asynchronously). */
21375
21376 #define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
21377 do \
21378 { \
21379 HEAD = TAIL = NULL; \
21380 while (START < END) \
21381 { \
21382 struct glyph *first_glyph = (row)->glyphs[area] + START; \
21383 switch (first_glyph->type) \
21384 { \
21385 case CHAR_GLYPH: \
21386 BUILD_CHAR_GLYPH_STRINGS (START, END, HEAD, TAIL, \
21387 HL, X, LAST_X); \
21388 break; \
21389 \
21390 case COMPOSITE_GLYPH: \
21391 if (first_glyph->u.cmp.automatic) \
21392 BUILD_GSTRING_GLYPH_STRING (START, END, HEAD, TAIL, \
21393 HL, X, LAST_X); \
21394 else \
21395 BUILD_COMPOSITE_GLYPH_STRING (START, END, HEAD, TAIL, \
21396 HL, X, LAST_X); \
21397 break; \
21398 \
21399 case STRETCH_GLYPH: \
21400 BUILD_STRETCH_GLYPH_STRING (START, END, HEAD, TAIL, \
21401 HL, X, LAST_X); \
21402 break; \
21403 \
21404 case IMAGE_GLYPH: \
21405 BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL, \
21406 HL, X, LAST_X); \
21407 break; \
21408 \
21409 case GLYPHLESS_GLYPH: \
21410 BUILD_GLYPHLESS_GLYPH_STRING (START, END, HEAD, TAIL, \
21411 HL, X, LAST_X); \
21412 break; \
21413 \
21414 default: \
21415 abort (); \
21416 } \
21417 \
21418 if (s) \
21419 { \
21420 set_glyph_string_background_width (s, START, LAST_X); \
21421 (X) += s->width; \
21422 } \
21423 } \
21424 } while (0)
21425
21426
21427 /* Draw glyphs between START and END in AREA of ROW on window W,
21428 starting at x-position X. X is relative to AREA in W. HL is a
21429 face-override with the following meaning:
21430
21431 DRAW_NORMAL_TEXT draw normally
21432 DRAW_CURSOR draw in cursor face
21433 DRAW_MOUSE_FACE draw in mouse face.
21434 DRAW_INVERSE_VIDEO draw in mode line face
21435 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
21436 DRAW_IMAGE_RAISED draw an image with a raised relief around it
21437
21438 If OVERLAPS is non-zero, draw only the foreground of characters and
21439 clip to the physical height of ROW. Non-zero value also defines
21440 the overlapping part to be drawn:
21441
21442 OVERLAPS_PRED overlap with preceding rows
21443 OVERLAPS_SUCC overlap with succeeding rows
21444 OVERLAPS_BOTH overlap with both preceding/succeeding rows
21445 OVERLAPS_ERASED_CURSOR overlap with erased cursor area
21446
21447 Value is the x-position reached, relative to AREA of W. */
21448
21449 static int
21450 draw_glyphs (struct window *w, int x, struct glyph_row *row,
21451 enum glyph_row_area area, EMACS_INT start, EMACS_INT end,
21452 enum draw_glyphs_face hl, int overlaps)
21453 {
21454 struct glyph_string *head, *tail;
21455 struct glyph_string *s;
21456 struct glyph_string *clip_head = NULL, *clip_tail = NULL;
21457 int i, j, x_reached, last_x, area_left = 0;
21458 struct frame *f = XFRAME (WINDOW_FRAME (w));
21459 DECLARE_HDC (hdc);
21460
21461 ALLOCATE_HDC (hdc, f);
21462
21463 /* Let's rather be paranoid than getting a SEGV. */
21464 end = min (end, row->used[area]);
21465 start = max (0, start);
21466 start = min (end, start);
21467
21468 /* Translate X to frame coordinates. Set last_x to the right
21469 end of the drawing area. */
21470 if (row->full_width_p)
21471 {
21472 /* X is relative to the left edge of W, without scroll bars
21473 or fringes. */
21474 area_left = WINDOW_LEFT_EDGE_X (w);
21475 last_x = WINDOW_LEFT_EDGE_X (w) + WINDOW_TOTAL_WIDTH (w);
21476 }
21477 else
21478 {
21479 area_left = window_box_left (w, area);
21480 last_x = area_left + window_box_width (w, area);
21481 }
21482 x += area_left;
21483
21484 /* Build a doubly-linked list of glyph_string structures between
21485 head and tail from what we have to draw. Note that the macro
21486 BUILD_GLYPH_STRINGS will modify its start parameter. That's
21487 the reason we use a separate variable `i'. */
21488 i = start;
21489 BUILD_GLYPH_STRINGS (i, end, head, tail, hl, x, last_x);
21490 if (tail)
21491 x_reached = tail->x + tail->background_width;
21492 else
21493 x_reached = x;
21494
21495 /* If there are any glyphs with lbearing < 0 or rbearing > width in
21496 the row, redraw some glyphs in front or following the glyph
21497 strings built above. */
21498 if (head && !overlaps && row->contains_overlapping_glyphs_p)
21499 {
21500 struct glyph_string *h, *t;
21501 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
21502 int mouse_beg_col IF_LINT (= 0), mouse_end_col IF_LINT (= 0);
21503 int check_mouse_face = 0;
21504 int dummy_x = 0;
21505
21506 /* If mouse highlighting is on, we may need to draw adjacent
21507 glyphs using mouse-face highlighting. */
21508 if (area == TEXT_AREA && row->mouse_face_p)
21509 {
21510 struct glyph_row *mouse_beg_row, *mouse_end_row;
21511
21512 mouse_beg_row = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_beg_row);
21513 mouse_end_row = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_end_row);
21514
21515 if (row >= mouse_beg_row && row <= mouse_end_row)
21516 {
21517 check_mouse_face = 1;
21518 mouse_beg_col = (row == mouse_beg_row)
21519 ? hlinfo->mouse_face_beg_col : 0;
21520 mouse_end_col = (row == mouse_end_row)
21521 ? hlinfo->mouse_face_end_col
21522 : row->used[TEXT_AREA];
21523 }
21524 }
21525
21526 /* Compute overhangs for all glyph strings. */
21527 if (FRAME_RIF (f)->compute_glyph_string_overhangs)
21528 for (s = head; s; s = s->next)
21529 FRAME_RIF (f)->compute_glyph_string_overhangs (s);
21530
21531 /* Prepend glyph strings for glyphs in front of the first glyph
21532 string that are overwritten because of the first glyph
21533 string's left overhang. The background of all strings
21534 prepended must be drawn because the first glyph string
21535 draws over it. */
21536 i = left_overwritten (head);
21537 if (i >= 0)
21538 {
21539 enum draw_glyphs_face overlap_hl;
21540
21541 /* If this row contains mouse highlighting, attempt to draw
21542 the overlapped glyphs with the correct highlight. This
21543 code fails if the overlap encompasses more than one glyph
21544 and mouse-highlight spans only some of these glyphs.
21545 However, making it work perfectly involves a lot more
21546 code, and I don't know if the pathological case occurs in
21547 practice, so we'll stick to this for now. --- cyd */
21548 if (check_mouse_face
21549 && mouse_beg_col < start && mouse_end_col > i)
21550 overlap_hl = DRAW_MOUSE_FACE;
21551 else
21552 overlap_hl = DRAW_NORMAL_TEXT;
21553
21554 j = i;
21555 BUILD_GLYPH_STRINGS (j, start, h, t,
21556 overlap_hl, dummy_x, last_x);
21557 start = i;
21558 compute_overhangs_and_x (t, head->x, 1);
21559 prepend_glyph_string_lists (&head, &tail, h, t);
21560 clip_head = head;
21561 }
21562
21563 /* Prepend glyph strings for glyphs in front of the first glyph
21564 string that overwrite that glyph string because of their
21565 right overhang. For these strings, only the foreground must
21566 be drawn, because it draws over the glyph string at `head'.
21567 The background must not be drawn because this would overwrite
21568 right overhangs of preceding glyphs for which no glyph
21569 strings exist. */
21570 i = left_overwriting (head);
21571 if (i >= 0)
21572 {
21573 enum draw_glyphs_face overlap_hl;
21574
21575 if (check_mouse_face
21576 && mouse_beg_col < start && mouse_end_col > i)
21577 overlap_hl = DRAW_MOUSE_FACE;
21578 else
21579 overlap_hl = DRAW_NORMAL_TEXT;
21580
21581 clip_head = head;
21582 BUILD_GLYPH_STRINGS (i, start, h, t,
21583 overlap_hl, dummy_x, last_x);
21584 for (s = h; s; s = s->next)
21585 s->background_filled_p = 1;
21586 compute_overhangs_and_x (t, head->x, 1);
21587 prepend_glyph_string_lists (&head, &tail, h, t);
21588 }
21589
21590 /* Append glyphs strings for glyphs following the last glyph
21591 string tail that are overwritten by tail. The background of
21592 these strings has to be drawn because tail's foreground draws
21593 over it. */
21594 i = right_overwritten (tail);
21595 if (i >= 0)
21596 {
21597 enum draw_glyphs_face overlap_hl;
21598
21599 if (check_mouse_face
21600 && mouse_beg_col < i && mouse_end_col > end)
21601 overlap_hl = DRAW_MOUSE_FACE;
21602 else
21603 overlap_hl = DRAW_NORMAL_TEXT;
21604
21605 BUILD_GLYPH_STRINGS (end, i, h, t,
21606 overlap_hl, x, last_x);
21607 /* Because BUILD_GLYPH_STRINGS updates the first argument,
21608 we don't have `end = i;' here. */
21609 compute_overhangs_and_x (h, tail->x + tail->width, 0);
21610 append_glyph_string_lists (&head, &tail, h, t);
21611 clip_tail = tail;
21612 }
21613
21614 /* Append glyph strings for glyphs following the last glyph
21615 string tail that overwrite tail. The foreground of such
21616 glyphs has to be drawn because it writes into the background
21617 of tail. The background must not be drawn because it could
21618 paint over the foreground of following glyphs. */
21619 i = right_overwriting (tail);
21620 if (i >= 0)
21621 {
21622 enum draw_glyphs_face overlap_hl;
21623 if (check_mouse_face
21624 && mouse_beg_col < i && mouse_end_col > end)
21625 overlap_hl = DRAW_MOUSE_FACE;
21626 else
21627 overlap_hl = DRAW_NORMAL_TEXT;
21628
21629 clip_tail = tail;
21630 i++; /* We must include the Ith glyph. */
21631 BUILD_GLYPH_STRINGS (end, i, h, t,
21632 overlap_hl, x, last_x);
21633 for (s = h; s; s = s->next)
21634 s->background_filled_p = 1;
21635 compute_overhangs_and_x (h, tail->x + tail->width, 0);
21636 append_glyph_string_lists (&head, &tail, h, t);
21637 }
21638 if (clip_head || clip_tail)
21639 for (s = head; s; s = s->next)
21640 {
21641 s->clip_head = clip_head;
21642 s->clip_tail = clip_tail;
21643 }
21644 }
21645
21646 /* Draw all strings. */
21647 for (s = head; s; s = s->next)
21648 FRAME_RIF (f)->draw_glyph_string (s);
21649
21650 #ifndef HAVE_NS
21651 /* When focus a sole frame and move horizontally, this sets on_p to 0
21652 causing a failure to erase prev cursor position. */
21653 if (area == TEXT_AREA
21654 && !row->full_width_p
21655 /* When drawing overlapping rows, only the glyph strings'
21656 foreground is drawn, which doesn't erase a cursor
21657 completely. */
21658 && !overlaps)
21659 {
21660 int x0 = clip_head ? clip_head->x : (head ? head->x : x);
21661 int x1 = (clip_tail ? clip_tail->x + clip_tail->background_width
21662 : (tail ? tail->x + tail->background_width : x));
21663 x0 -= area_left;
21664 x1 -= area_left;
21665
21666 notice_overwritten_cursor (w, TEXT_AREA, x0, x1,
21667 row->y, MATRIX_ROW_BOTTOM_Y (row));
21668 }
21669 #endif
21670
21671 /* Value is the x-position up to which drawn, relative to AREA of W.
21672 This doesn't include parts drawn because of overhangs. */
21673 if (row->full_width_p)
21674 x_reached = FRAME_TO_WINDOW_PIXEL_X (w, x_reached);
21675 else
21676 x_reached -= area_left;
21677
21678 RELEASE_HDC (hdc, f);
21679
21680 return x_reached;
21681 }
21682
21683 /* Expand row matrix if too narrow. Don't expand if area
21684 is not present. */
21685
21686 #define IT_EXPAND_MATRIX_WIDTH(it, area) \
21687 { \
21688 if (!fonts_changed_p \
21689 && (it->glyph_row->glyphs[area] \
21690 < it->glyph_row->glyphs[area + 1])) \
21691 { \
21692 it->w->ncols_scale_factor++; \
21693 fonts_changed_p = 1; \
21694 } \
21695 }
21696
21697 /* Store one glyph for IT->char_to_display in IT->glyph_row.
21698 Called from x_produce_glyphs when IT->glyph_row is non-null. */
21699
21700 static INLINE void
21701 append_glyph (struct it *it)
21702 {
21703 struct glyph *glyph;
21704 enum glyph_row_area area = it->area;
21705
21706 xassert (it->glyph_row);
21707 xassert (it->char_to_display != '\n' && it->char_to_display != '\t');
21708
21709 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
21710 if (glyph < it->glyph_row->glyphs[area + 1])
21711 {
21712 /* If the glyph row is reversed, we need to prepend the glyph
21713 rather than append it. */
21714 if (it->glyph_row->reversed_p && area == TEXT_AREA)
21715 {
21716 struct glyph *g;
21717
21718 /* Make room for the additional glyph. */
21719 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
21720 g[1] = *g;
21721 glyph = it->glyph_row->glyphs[area];
21722 }
21723 glyph->charpos = CHARPOS (it->position);
21724 glyph->object = it->object;
21725 if (it->pixel_width > 0)
21726 {
21727 glyph->pixel_width = it->pixel_width;
21728 glyph->padding_p = 0;
21729 }
21730 else
21731 {
21732 /* Assure at least 1-pixel width. Otherwise, cursor can't
21733 be displayed correctly. */
21734 glyph->pixel_width = 1;
21735 glyph->padding_p = 1;
21736 }
21737 glyph->ascent = it->ascent;
21738 glyph->descent = it->descent;
21739 glyph->voffset = it->voffset;
21740 glyph->type = CHAR_GLYPH;
21741 glyph->avoid_cursor_p = it->avoid_cursor_p;
21742 glyph->multibyte_p = it->multibyte_p;
21743 glyph->left_box_line_p = it->start_of_box_run_p;
21744 glyph->right_box_line_p = it->end_of_box_run_p;
21745 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
21746 || it->phys_descent > it->descent);
21747 glyph->glyph_not_available_p = it->glyph_not_available_p;
21748 glyph->face_id = it->face_id;
21749 glyph->u.ch = it->char_to_display;
21750 glyph->slice.img = null_glyph_slice;
21751 glyph->font_type = FONT_TYPE_UNKNOWN;
21752 if (it->bidi_p)
21753 {
21754 glyph->resolved_level = it->bidi_it.resolved_level;
21755 if ((it->bidi_it.type & 7) != it->bidi_it.type)
21756 abort ();
21757 glyph->bidi_type = it->bidi_it.type;
21758 }
21759 else
21760 {
21761 glyph->resolved_level = 0;
21762 glyph->bidi_type = UNKNOWN_BT;
21763 }
21764 ++it->glyph_row->used[area];
21765 }
21766 else
21767 IT_EXPAND_MATRIX_WIDTH (it, area);
21768 }
21769
21770 /* Store one glyph for the composition IT->cmp_it.id in
21771 IT->glyph_row. Called from x_produce_glyphs when IT->glyph_row is
21772 non-null. */
21773
21774 static INLINE void
21775 append_composite_glyph (struct it *it)
21776 {
21777 struct glyph *glyph;
21778 enum glyph_row_area area = it->area;
21779
21780 xassert (it->glyph_row);
21781
21782 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
21783 if (glyph < it->glyph_row->glyphs[area + 1])
21784 {
21785 /* If the glyph row is reversed, we need to prepend the glyph
21786 rather than append it. */
21787 if (it->glyph_row->reversed_p && it->area == TEXT_AREA)
21788 {
21789 struct glyph *g;
21790
21791 /* Make room for the new glyph. */
21792 for (g = glyph - 1; g >= it->glyph_row->glyphs[it->area]; g--)
21793 g[1] = *g;
21794 glyph = it->glyph_row->glyphs[it->area];
21795 }
21796 glyph->charpos = it->cmp_it.charpos;
21797 glyph->object = it->object;
21798 glyph->pixel_width = it->pixel_width;
21799 glyph->ascent = it->ascent;
21800 glyph->descent = it->descent;
21801 glyph->voffset = it->voffset;
21802 glyph->type = COMPOSITE_GLYPH;
21803 if (it->cmp_it.ch < 0)
21804 {
21805 glyph->u.cmp.automatic = 0;
21806 glyph->u.cmp.id = it->cmp_it.id;
21807 glyph->slice.cmp.from = glyph->slice.cmp.to = 0;
21808 }
21809 else
21810 {
21811 glyph->u.cmp.automatic = 1;
21812 glyph->u.cmp.id = it->cmp_it.id;
21813 glyph->slice.cmp.from = it->cmp_it.from;
21814 glyph->slice.cmp.to = it->cmp_it.to - 1;
21815 }
21816 glyph->avoid_cursor_p = it->avoid_cursor_p;
21817 glyph->multibyte_p = it->multibyte_p;
21818 glyph->left_box_line_p = it->start_of_box_run_p;
21819 glyph->right_box_line_p = it->end_of_box_run_p;
21820 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
21821 || it->phys_descent > it->descent);
21822 glyph->padding_p = 0;
21823 glyph->glyph_not_available_p = 0;
21824 glyph->face_id = it->face_id;
21825 glyph->font_type = FONT_TYPE_UNKNOWN;
21826 if (it->bidi_p)
21827 {
21828 glyph->resolved_level = it->bidi_it.resolved_level;
21829 if ((it->bidi_it.type & 7) != it->bidi_it.type)
21830 abort ();
21831 glyph->bidi_type = it->bidi_it.type;
21832 }
21833 ++it->glyph_row->used[area];
21834 }
21835 else
21836 IT_EXPAND_MATRIX_WIDTH (it, area);
21837 }
21838
21839
21840 /* Change IT->ascent and IT->height according to the setting of
21841 IT->voffset. */
21842
21843 static INLINE void
21844 take_vertical_position_into_account (struct it *it)
21845 {
21846 if (it->voffset)
21847 {
21848 if (it->voffset < 0)
21849 /* Increase the ascent so that we can display the text higher
21850 in the line. */
21851 it->ascent -= it->voffset;
21852 else
21853 /* Increase the descent so that we can display the text lower
21854 in the line. */
21855 it->descent += it->voffset;
21856 }
21857 }
21858
21859
21860 /* Produce glyphs/get display metrics for the image IT is loaded with.
21861 See the description of struct display_iterator in dispextern.h for
21862 an overview of struct display_iterator. */
21863
21864 static void
21865 produce_image_glyph (struct it *it)
21866 {
21867 struct image *img;
21868 struct face *face;
21869 int glyph_ascent, crop;
21870 struct glyph_slice slice;
21871
21872 xassert (it->what == IT_IMAGE);
21873
21874 face = FACE_FROM_ID (it->f, it->face_id);
21875 xassert (face);
21876 /* Make sure X resources of the face is loaded. */
21877 PREPARE_FACE_FOR_DISPLAY (it->f, face);
21878
21879 if (it->image_id < 0)
21880 {
21881 /* Fringe bitmap. */
21882 it->ascent = it->phys_ascent = 0;
21883 it->descent = it->phys_descent = 0;
21884 it->pixel_width = 0;
21885 it->nglyphs = 0;
21886 return;
21887 }
21888
21889 img = IMAGE_FROM_ID (it->f, it->image_id);
21890 xassert (img);
21891 /* Make sure X resources of the image is loaded. */
21892 prepare_image_for_display (it->f, img);
21893
21894 slice.x = slice.y = 0;
21895 slice.width = img->width;
21896 slice.height = img->height;
21897
21898 if (INTEGERP (it->slice.x))
21899 slice.x = XINT (it->slice.x);
21900 else if (FLOATP (it->slice.x))
21901 slice.x = XFLOAT_DATA (it->slice.x) * img->width;
21902
21903 if (INTEGERP (it->slice.y))
21904 slice.y = XINT (it->slice.y);
21905 else if (FLOATP (it->slice.y))
21906 slice.y = XFLOAT_DATA (it->slice.y) * img->height;
21907
21908 if (INTEGERP (it->slice.width))
21909 slice.width = XINT (it->slice.width);
21910 else if (FLOATP (it->slice.width))
21911 slice.width = XFLOAT_DATA (it->slice.width) * img->width;
21912
21913 if (INTEGERP (it->slice.height))
21914 slice.height = XINT (it->slice.height);
21915 else if (FLOATP (it->slice.height))
21916 slice.height = XFLOAT_DATA (it->slice.height) * img->height;
21917
21918 if (slice.x >= img->width)
21919 slice.x = img->width;
21920 if (slice.y >= img->height)
21921 slice.y = img->height;
21922 if (slice.x + slice.width >= img->width)
21923 slice.width = img->width - slice.x;
21924 if (slice.y + slice.height > img->height)
21925 slice.height = img->height - slice.y;
21926
21927 if (slice.width == 0 || slice.height == 0)
21928 return;
21929
21930 it->ascent = it->phys_ascent = glyph_ascent = image_ascent (img, face, &slice);
21931
21932 it->descent = slice.height - glyph_ascent;
21933 if (slice.y == 0)
21934 it->descent += img->vmargin;
21935 if (slice.y + slice.height == img->height)
21936 it->descent += img->vmargin;
21937 it->phys_descent = it->descent;
21938
21939 it->pixel_width = slice.width;
21940 if (slice.x == 0)
21941 it->pixel_width += img->hmargin;
21942 if (slice.x + slice.width == img->width)
21943 it->pixel_width += img->hmargin;
21944
21945 /* It's quite possible for images to have an ascent greater than
21946 their height, so don't get confused in that case. */
21947 if (it->descent < 0)
21948 it->descent = 0;
21949
21950 it->nglyphs = 1;
21951
21952 if (face->box != FACE_NO_BOX)
21953 {
21954 if (face->box_line_width > 0)
21955 {
21956 if (slice.y == 0)
21957 it->ascent += face->box_line_width;
21958 if (slice.y + slice.height == img->height)
21959 it->descent += face->box_line_width;
21960 }
21961
21962 if (it->start_of_box_run_p && slice.x == 0)
21963 it->pixel_width += eabs (face->box_line_width);
21964 if (it->end_of_box_run_p && slice.x + slice.width == img->width)
21965 it->pixel_width += eabs (face->box_line_width);
21966 }
21967
21968 take_vertical_position_into_account (it);
21969
21970 /* Automatically crop wide image glyphs at right edge so we can
21971 draw the cursor on same display row. */
21972 if ((crop = it->pixel_width - (it->last_visible_x - it->current_x), crop > 0)
21973 && (it->hpos == 0 || it->pixel_width > it->last_visible_x / 4))
21974 {
21975 it->pixel_width -= crop;
21976 slice.width -= crop;
21977 }
21978
21979 if (it->glyph_row)
21980 {
21981 struct glyph *glyph;
21982 enum glyph_row_area area = it->area;
21983
21984 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
21985 if (glyph < it->glyph_row->glyphs[area + 1])
21986 {
21987 glyph->charpos = CHARPOS (it->position);
21988 glyph->object = it->object;
21989 glyph->pixel_width = it->pixel_width;
21990 glyph->ascent = glyph_ascent;
21991 glyph->descent = it->descent;
21992 glyph->voffset = it->voffset;
21993 glyph->type = IMAGE_GLYPH;
21994 glyph->avoid_cursor_p = it->avoid_cursor_p;
21995 glyph->multibyte_p = it->multibyte_p;
21996 glyph->left_box_line_p = it->start_of_box_run_p;
21997 glyph->right_box_line_p = it->end_of_box_run_p;
21998 glyph->overlaps_vertically_p = 0;
21999 glyph->padding_p = 0;
22000 glyph->glyph_not_available_p = 0;
22001 glyph->face_id = it->face_id;
22002 glyph->u.img_id = img->id;
22003 glyph->slice.img = slice;
22004 glyph->font_type = FONT_TYPE_UNKNOWN;
22005 if (it->bidi_p)
22006 {
22007 glyph->resolved_level = it->bidi_it.resolved_level;
22008 if ((it->bidi_it.type & 7) != it->bidi_it.type)
22009 abort ();
22010 glyph->bidi_type = it->bidi_it.type;
22011 }
22012 ++it->glyph_row->used[area];
22013 }
22014 else
22015 IT_EXPAND_MATRIX_WIDTH (it, area);
22016 }
22017 }
22018
22019
22020 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
22021 of the glyph, WIDTH and HEIGHT are the width and height of the
22022 stretch. ASCENT is the ascent of the glyph (0 <= ASCENT <= HEIGHT). */
22023
22024 static void
22025 append_stretch_glyph (struct it *it, Lisp_Object object,
22026 int width, int height, int ascent)
22027 {
22028 struct glyph *glyph;
22029 enum glyph_row_area area = it->area;
22030
22031 xassert (ascent >= 0 && ascent <= height);
22032
22033 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
22034 if (glyph < it->glyph_row->glyphs[area + 1])
22035 {
22036 /* If the glyph row is reversed, we need to prepend the glyph
22037 rather than append it. */
22038 if (it->glyph_row->reversed_p && area == TEXT_AREA)
22039 {
22040 struct glyph *g;
22041
22042 /* Make room for the additional glyph. */
22043 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
22044 g[1] = *g;
22045 glyph = it->glyph_row->glyphs[area];
22046 }
22047 glyph->charpos = CHARPOS (it->position);
22048 glyph->object = object;
22049 glyph->pixel_width = width;
22050 glyph->ascent = ascent;
22051 glyph->descent = height - ascent;
22052 glyph->voffset = it->voffset;
22053 glyph->type = STRETCH_GLYPH;
22054 glyph->avoid_cursor_p = it->avoid_cursor_p;
22055 glyph->multibyte_p = it->multibyte_p;
22056 glyph->left_box_line_p = it->start_of_box_run_p;
22057 glyph->right_box_line_p = it->end_of_box_run_p;
22058 glyph->overlaps_vertically_p = 0;
22059 glyph->padding_p = 0;
22060 glyph->glyph_not_available_p = 0;
22061 glyph->face_id = it->face_id;
22062 glyph->u.stretch.ascent = ascent;
22063 glyph->u.stretch.height = height;
22064 glyph->slice.img = null_glyph_slice;
22065 glyph->font_type = FONT_TYPE_UNKNOWN;
22066 if (it->bidi_p)
22067 {
22068 glyph->resolved_level = it->bidi_it.resolved_level;
22069 if ((it->bidi_it.type & 7) != it->bidi_it.type)
22070 abort ();
22071 glyph->bidi_type = it->bidi_it.type;
22072 }
22073 else
22074 {
22075 glyph->resolved_level = 0;
22076 glyph->bidi_type = UNKNOWN_BT;
22077 }
22078 ++it->glyph_row->used[area];
22079 }
22080 else
22081 IT_EXPAND_MATRIX_WIDTH (it, area);
22082 }
22083
22084
22085 /* Produce a stretch glyph for iterator IT. IT->object is the value
22086 of the glyph property displayed. The value must be a list
22087 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
22088 being recognized:
22089
22090 1. `:width WIDTH' specifies that the space should be WIDTH *
22091 canonical char width wide. WIDTH may be an integer or floating
22092 point number.
22093
22094 2. `:relative-width FACTOR' specifies that the width of the stretch
22095 should be computed from the width of the first character having the
22096 `glyph' property, and should be FACTOR times that width.
22097
22098 3. `:align-to HPOS' specifies that the space should be wide enough
22099 to reach HPOS, a value in canonical character units.
22100
22101 Exactly one of the above pairs must be present.
22102
22103 4. `:height HEIGHT' specifies that the height of the stretch produced
22104 should be HEIGHT, measured in canonical character units.
22105
22106 5. `:relative-height FACTOR' specifies that the height of the
22107 stretch should be FACTOR times the height of the characters having
22108 the glyph property.
22109
22110 Either none or exactly one of 4 or 5 must be present.
22111
22112 6. `:ascent ASCENT' specifies that ASCENT percent of the height
22113 of the stretch should be used for the ascent of the stretch.
22114 ASCENT must be in the range 0 <= ASCENT <= 100. */
22115
22116 static void
22117 produce_stretch_glyph (struct it *it)
22118 {
22119 /* (space :width WIDTH :height HEIGHT ...) */
22120 Lisp_Object prop, plist;
22121 int width = 0, height = 0, align_to = -1;
22122 int zero_width_ok_p = 0, zero_height_ok_p = 0;
22123 int ascent = 0;
22124 double tem;
22125 struct face *face = FACE_FROM_ID (it->f, it->face_id);
22126 struct font *font = face->font ? face->font : FRAME_FONT (it->f);
22127
22128 PREPARE_FACE_FOR_DISPLAY (it->f, face);
22129
22130 /* List should start with `space'. */
22131 xassert (CONSP (it->object) && EQ (XCAR (it->object), Qspace));
22132 plist = XCDR (it->object);
22133
22134 /* Compute the width of the stretch. */
22135 if ((prop = Fplist_get (plist, QCwidth), !NILP (prop))
22136 && calc_pixel_width_or_height (&tem, it, prop, font, 1, 0))
22137 {
22138 /* Absolute width `:width WIDTH' specified and valid. */
22139 zero_width_ok_p = 1;
22140 width = (int)tem;
22141 }
22142 else if (prop = Fplist_get (plist, QCrelative_width),
22143 NUMVAL (prop) > 0)
22144 {
22145 /* Relative width `:relative-width FACTOR' specified and valid.
22146 Compute the width of the characters having the `glyph'
22147 property. */
22148 struct it it2;
22149 unsigned char *p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
22150
22151 it2 = *it;
22152 if (it->multibyte_p)
22153 it2.c = it2.char_to_display = STRING_CHAR_AND_LENGTH (p, it2.len);
22154 else
22155 {
22156 it2.c = it2.char_to_display = *p, it2.len = 1;
22157 if (! ASCII_CHAR_P (it2.c))
22158 it2.char_to_display = BYTE8_TO_CHAR (it2.c);
22159 }
22160
22161 it2.glyph_row = NULL;
22162 it2.what = IT_CHARACTER;
22163 x_produce_glyphs (&it2);
22164 width = NUMVAL (prop) * it2.pixel_width;
22165 }
22166 else if ((prop = Fplist_get (plist, QCalign_to), !NILP (prop))
22167 && calc_pixel_width_or_height (&tem, it, prop, font, 1, &align_to))
22168 {
22169 if (it->glyph_row == NULL || !it->glyph_row->mode_line_p)
22170 align_to = (align_to < 0
22171 ? 0
22172 : align_to - window_box_left_offset (it->w, TEXT_AREA));
22173 else if (align_to < 0)
22174 align_to = window_box_left_offset (it->w, TEXT_AREA);
22175 width = max (0, (int)tem + align_to - it->current_x);
22176 zero_width_ok_p = 1;
22177 }
22178 else
22179 /* Nothing specified -> width defaults to canonical char width. */
22180 width = FRAME_COLUMN_WIDTH (it->f);
22181
22182 if (width <= 0 && (width < 0 || !zero_width_ok_p))
22183 width = 1;
22184
22185 /* Compute height. */
22186 if ((prop = Fplist_get (plist, QCheight), !NILP (prop))
22187 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
22188 {
22189 height = (int)tem;
22190 zero_height_ok_p = 1;
22191 }
22192 else if (prop = Fplist_get (plist, QCrelative_height),
22193 NUMVAL (prop) > 0)
22194 height = FONT_HEIGHT (font) * NUMVAL (prop);
22195 else
22196 height = FONT_HEIGHT (font);
22197
22198 if (height <= 0 && (height < 0 || !zero_height_ok_p))
22199 height = 1;
22200
22201 /* Compute percentage of height used for ascent. If
22202 `:ascent ASCENT' is present and valid, use that. Otherwise,
22203 derive the ascent from the font in use. */
22204 if (prop = Fplist_get (plist, QCascent),
22205 NUMVAL (prop) > 0 && NUMVAL (prop) <= 100)
22206 ascent = height * NUMVAL (prop) / 100.0;
22207 else if (!NILP (prop)
22208 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
22209 ascent = min (max (0, (int)tem), height);
22210 else
22211 ascent = (height * FONT_BASE (font)) / FONT_HEIGHT (font);
22212
22213 if (width > 0 && it->line_wrap != TRUNCATE
22214 && it->current_x + width > it->last_visible_x)
22215 width = it->last_visible_x - it->current_x - 1;
22216
22217 if (width > 0 && height > 0 && it->glyph_row)
22218 {
22219 Lisp_Object object = it->stack[it->sp - 1].string;
22220 if (!STRINGP (object))
22221 object = it->w->buffer;
22222 append_stretch_glyph (it, object, width, height, ascent);
22223 }
22224
22225 it->pixel_width = width;
22226 it->ascent = it->phys_ascent = ascent;
22227 it->descent = it->phys_descent = height - it->ascent;
22228 it->nglyphs = width > 0 && height > 0 ? 1 : 0;
22229
22230 take_vertical_position_into_account (it);
22231 }
22232
22233 /* Calculate line-height and line-spacing properties.
22234 An integer value specifies explicit pixel value.
22235 A float value specifies relative value to current face height.
22236 A cons (float . face-name) specifies relative value to
22237 height of specified face font.
22238
22239 Returns height in pixels, or nil. */
22240
22241
22242 static Lisp_Object
22243 calc_line_height_property (struct it *it, Lisp_Object val, struct font *font,
22244 int boff, int override)
22245 {
22246 Lisp_Object face_name = Qnil;
22247 int ascent, descent, height;
22248
22249 if (NILP (val) || INTEGERP (val) || (override && EQ (val, Qt)))
22250 return val;
22251
22252 if (CONSP (val))
22253 {
22254 face_name = XCAR (val);
22255 val = XCDR (val);
22256 if (!NUMBERP (val))
22257 val = make_number (1);
22258 if (NILP (face_name))
22259 {
22260 height = it->ascent + it->descent;
22261 goto scale;
22262 }
22263 }
22264
22265 if (NILP (face_name))
22266 {
22267 font = FRAME_FONT (it->f);
22268 boff = FRAME_BASELINE_OFFSET (it->f);
22269 }
22270 else if (EQ (face_name, Qt))
22271 {
22272 override = 0;
22273 }
22274 else
22275 {
22276 int face_id;
22277 struct face *face;
22278
22279 face_id = lookup_named_face (it->f, face_name, 0);
22280 if (face_id < 0)
22281 return make_number (-1);
22282
22283 face = FACE_FROM_ID (it->f, face_id);
22284 font = face->font;
22285 if (font == NULL)
22286 return make_number (-1);
22287 boff = font->baseline_offset;
22288 if (font->vertical_centering)
22289 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
22290 }
22291
22292 ascent = FONT_BASE (font) + boff;
22293 descent = FONT_DESCENT (font) - boff;
22294
22295 if (override)
22296 {
22297 it->override_ascent = ascent;
22298 it->override_descent = descent;
22299 it->override_boff = boff;
22300 }
22301
22302 height = ascent + descent;
22303
22304 scale:
22305 if (FLOATP (val))
22306 height = (int)(XFLOAT_DATA (val) * height);
22307 else if (INTEGERP (val))
22308 height *= XINT (val);
22309
22310 return make_number (height);
22311 }
22312
22313
22314 /* Append a glyph for a glyphless character to IT->glyph_row. FACE_ID
22315 is a face ID to be used for the glyph. FOR_NO_FONT is nonzero if
22316 and only if this is for a character for which no font was found.
22317
22318 If the display method (it->glyphless_method) is
22319 GLYPHLESS_DISPLAY_ACRONYM or GLYPHLESS_DISPLAY_HEX_CODE, LEN is a
22320 length of the acronym or the hexadecimal string, UPPER_XOFF and
22321 UPPER_YOFF are pixel offsets for the upper part of the string,
22322 LOWER_XOFF and LOWER_YOFF are for the lower part.
22323
22324 For the other display methods, LEN through LOWER_YOFF are zero. */
22325
22326 static void
22327 append_glyphless_glyph (struct it *it, int face_id, int for_no_font, int len,
22328 short upper_xoff, short upper_yoff,
22329 short lower_xoff, short lower_yoff)
22330 {
22331 struct glyph *glyph;
22332 enum glyph_row_area area = it->area;
22333
22334 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
22335 if (glyph < it->glyph_row->glyphs[area + 1])
22336 {
22337 /* If the glyph row is reversed, we need to prepend the glyph
22338 rather than append it. */
22339 if (it->glyph_row->reversed_p && area == TEXT_AREA)
22340 {
22341 struct glyph *g;
22342
22343 /* Make room for the additional glyph. */
22344 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
22345 g[1] = *g;
22346 glyph = it->glyph_row->glyphs[area];
22347 }
22348 glyph->charpos = CHARPOS (it->position);
22349 glyph->object = it->object;
22350 glyph->pixel_width = it->pixel_width;
22351 glyph->ascent = it->ascent;
22352 glyph->descent = it->descent;
22353 glyph->voffset = it->voffset;
22354 glyph->type = GLYPHLESS_GLYPH;
22355 glyph->u.glyphless.method = it->glyphless_method;
22356 glyph->u.glyphless.for_no_font = for_no_font;
22357 glyph->u.glyphless.len = len;
22358 glyph->u.glyphless.ch = it->c;
22359 glyph->slice.glyphless.upper_xoff = upper_xoff;
22360 glyph->slice.glyphless.upper_yoff = upper_yoff;
22361 glyph->slice.glyphless.lower_xoff = lower_xoff;
22362 glyph->slice.glyphless.lower_yoff = lower_yoff;
22363 glyph->avoid_cursor_p = it->avoid_cursor_p;
22364 glyph->multibyte_p = it->multibyte_p;
22365 glyph->left_box_line_p = it->start_of_box_run_p;
22366 glyph->right_box_line_p = it->end_of_box_run_p;
22367 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
22368 || it->phys_descent > it->descent);
22369 glyph->padding_p = 0;
22370 glyph->glyph_not_available_p = 0;
22371 glyph->face_id = face_id;
22372 glyph->font_type = FONT_TYPE_UNKNOWN;
22373 if (it->bidi_p)
22374 {
22375 glyph->resolved_level = it->bidi_it.resolved_level;
22376 if ((it->bidi_it.type & 7) != it->bidi_it.type)
22377 abort ();
22378 glyph->bidi_type = it->bidi_it.type;
22379 }
22380 ++it->glyph_row->used[area];
22381 }
22382 else
22383 IT_EXPAND_MATRIX_WIDTH (it, area);
22384 }
22385
22386
22387 /* Produce a glyph for a glyphless character for iterator IT.
22388 IT->glyphless_method specifies which method to use for displaying
22389 the character. See the description of enum
22390 glyphless_display_method in dispextern.h for the detail.
22391
22392 FOR_NO_FONT is nonzero if and only if this is for a character for
22393 which no font was found. ACRONYM, if non-nil, is an acronym string
22394 for the character. */
22395
22396 static void
22397 produce_glyphless_glyph (struct it *it, int for_no_font, Lisp_Object acronym)
22398 {
22399 int face_id;
22400 struct face *face;
22401 struct font *font;
22402 int base_width, base_height, width, height;
22403 short upper_xoff, upper_yoff, lower_xoff, lower_yoff;
22404 int len;
22405
22406 /* Get the metrics of the base font. We always refer to the current
22407 ASCII face. */
22408 face = FACE_FROM_ID (it->f, it->face_id)->ascii_face;
22409 font = face->font ? face->font : FRAME_FONT (it->f);
22410 it->ascent = FONT_BASE (font) + font->baseline_offset;
22411 it->descent = FONT_DESCENT (font) - font->baseline_offset;
22412 base_height = it->ascent + it->descent;
22413 base_width = font->average_width;
22414
22415 /* Get a face ID for the glyph by utilizing a cache (the same way as
22416 doen for `escape-glyph' in get_next_display_element). */
22417 if (it->f == last_glyphless_glyph_frame
22418 && it->face_id == last_glyphless_glyph_face_id)
22419 {
22420 face_id = last_glyphless_glyph_merged_face_id;
22421 }
22422 else
22423 {
22424 /* Merge the `glyphless-char' face into the current face. */
22425 face_id = merge_faces (it->f, Qglyphless_char, 0, it->face_id);
22426 last_glyphless_glyph_frame = it->f;
22427 last_glyphless_glyph_face_id = it->face_id;
22428 last_glyphless_glyph_merged_face_id = face_id;
22429 }
22430
22431 if (it->glyphless_method == GLYPHLESS_DISPLAY_THIN_SPACE)
22432 {
22433 it->pixel_width = THIN_SPACE_WIDTH;
22434 len = 0;
22435 upper_xoff = upper_yoff = lower_xoff = lower_yoff = 0;
22436 }
22437 else if (it->glyphless_method == GLYPHLESS_DISPLAY_EMPTY_BOX)
22438 {
22439 width = CHAR_WIDTH (it->c);
22440 if (width == 0)
22441 width = 1;
22442 else if (width > 4)
22443 width = 4;
22444 it->pixel_width = base_width * width;
22445 len = 0;
22446 upper_xoff = upper_yoff = lower_xoff = lower_yoff = 0;
22447 }
22448 else
22449 {
22450 char buf[7];
22451 const char *str;
22452 unsigned int code[6];
22453 int upper_len;
22454 int ascent, descent;
22455 struct font_metrics metrics_upper, metrics_lower;
22456
22457 face = FACE_FROM_ID (it->f, face_id);
22458 font = face->font ? face->font : FRAME_FONT (it->f);
22459 PREPARE_FACE_FOR_DISPLAY (it->f, face);
22460
22461 if (it->glyphless_method == GLYPHLESS_DISPLAY_ACRONYM)
22462 {
22463 if (! STRINGP (acronym) && CHAR_TABLE_P (Vglyphless_char_display))
22464 acronym = CHAR_TABLE_REF (Vglyphless_char_display, it->c);
22465 if (CONSP (acronym))
22466 acronym = XCAR (acronym);
22467 str = STRINGP (acronym) ? SSDATA (acronym) : "";
22468 }
22469 else
22470 {
22471 xassert (it->glyphless_method == GLYPHLESS_DISPLAY_HEX_CODE);
22472 sprintf (buf, "%0*X", it->c < 0x10000 ? 4 : 6, it->c);
22473 str = buf;
22474 }
22475 for (len = 0; str[len] && ASCII_BYTE_P (str[len]); len++)
22476 code[len] = font->driver->encode_char (font, str[len]);
22477 upper_len = (len + 1) / 2;
22478 font->driver->text_extents (font, code, upper_len,
22479 &metrics_upper);
22480 font->driver->text_extents (font, code + upper_len, len - upper_len,
22481 &metrics_lower);
22482
22483
22484
22485 /* +4 is for vertical bars of a box plus 1-pixel spaces at both side. */
22486 width = max (metrics_upper.width, metrics_lower.width) + 4;
22487 upper_xoff = upper_yoff = 2; /* the typical case */
22488 if (base_width >= width)
22489 {
22490 /* Align the upper to the left, the lower to the right. */
22491 it->pixel_width = base_width;
22492 lower_xoff = base_width - 2 - metrics_lower.width;
22493 }
22494 else
22495 {
22496 /* Center the shorter one. */
22497 it->pixel_width = width;
22498 if (metrics_upper.width >= metrics_lower.width)
22499 lower_xoff = (width - metrics_lower.width) / 2;
22500 else
22501 {
22502 /* FIXME: This code doesn't look right. It formerly was
22503 missing the "lower_xoff = 0;", which couldn't have
22504 been right since it left lower_xoff uninitialized. */
22505 lower_xoff = 0;
22506 upper_xoff = (width - metrics_upper.width) / 2;
22507 }
22508 }
22509
22510 /* +5 is for horizontal bars of a box plus 1-pixel spaces at
22511 top, bottom, and between upper and lower strings. */
22512 height = (metrics_upper.ascent + metrics_upper.descent
22513 + metrics_lower.ascent + metrics_lower.descent) + 5;
22514 /* Center vertically.
22515 H:base_height, D:base_descent
22516 h:height, ld:lower_descent, la:lower_ascent, ud:upper_descent
22517
22518 ascent = - (D - H/2 - h/2 + 1); "+ 1" for rounding up
22519 descent = D - H/2 + h/2;
22520 lower_yoff = descent - 2 - ld;
22521 upper_yoff = lower_yoff - la - 1 - ud; */
22522 ascent = - (it->descent - (base_height + height + 1) / 2);
22523 descent = it->descent - (base_height - height) / 2;
22524 lower_yoff = descent - 2 - metrics_lower.descent;
22525 upper_yoff = (lower_yoff - metrics_lower.ascent - 1
22526 - metrics_upper.descent);
22527 /* Don't make the height shorter than the base height. */
22528 if (height > base_height)
22529 {
22530 it->ascent = ascent;
22531 it->descent = descent;
22532 }
22533 }
22534
22535 it->phys_ascent = it->ascent;
22536 it->phys_descent = it->descent;
22537 if (it->glyph_row)
22538 append_glyphless_glyph (it, face_id, for_no_font, len,
22539 upper_xoff, upper_yoff,
22540 lower_xoff, lower_yoff);
22541 it->nglyphs = 1;
22542 take_vertical_position_into_account (it);
22543 }
22544
22545
22546 /* RIF:
22547 Produce glyphs/get display metrics for the display element IT is
22548 loaded with. See the description of struct it in dispextern.h
22549 for an overview of struct it. */
22550
22551 void
22552 x_produce_glyphs (struct it *it)
22553 {
22554 int extra_line_spacing = it->extra_line_spacing;
22555
22556 it->glyph_not_available_p = 0;
22557
22558 if (it->what == IT_CHARACTER)
22559 {
22560 XChar2b char2b;
22561 struct face *face = FACE_FROM_ID (it->f, it->face_id);
22562 struct font *font = face->font;
22563 struct font_metrics *pcm = NULL;
22564 int boff; /* baseline offset */
22565
22566 if (font == NULL)
22567 {
22568 /* When no suitable font is found, display this character by
22569 the method specified in the first extra slot of
22570 Vglyphless_char_display. */
22571 Lisp_Object acronym = lookup_glyphless_char_display (-1, it);
22572
22573 xassert (it->what == IT_GLYPHLESS);
22574 produce_glyphless_glyph (it, 1, STRINGP (acronym) ? acronym : Qnil);
22575 goto done;
22576 }
22577
22578 boff = font->baseline_offset;
22579 if (font->vertical_centering)
22580 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
22581
22582 if (it->char_to_display != '\n' && it->char_to_display != '\t')
22583 {
22584 int stretched_p;
22585
22586 it->nglyphs = 1;
22587
22588 if (it->override_ascent >= 0)
22589 {
22590 it->ascent = it->override_ascent;
22591 it->descent = it->override_descent;
22592 boff = it->override_boff;
22593 }
22594 else
22595 {
22596 it->ascent = FONT_BASE (font) + boff;
22597 it->descent = FONT_DESCENT (font) - boff;
22598 }
22599
22600 if (get_char_glyph_code (it->char_to_display, font, &char2b))
22601 {
22602 pcm = get_per_char_metric (font, &char2b);
22603 if (pcm->width == 0
22604 && pcm->rbearing == 0 && pcm->lbearing == 0)
22605 pcm = NULL;
22606 }
22607
22608 if (pcm)
22609 {
22610 it->phys_ascent = pcm->ascent + boff;
22611 it->phys_descent = pcm->descent - boff;
22612 it->pixel_width = pcm->width;
22613 }
22614 else
22615 {
22616 it->glyph_not_available_p = 1;
22617 it->phys_ascent = it->ascent;
22618 it->phys_descent = it->descent;
22619 it->pixel_width = font->space_width;
22620 }
22621
22622 if (it->constrain_row_ascent_descent_p)
22623 {
22624 if (it->descent > it->max_descent)
22625 {
22626 it->ascent += it->descent - it->max_descent;
22627 it->descent = it->max_descent;
22628 }
22629 if (it->ascent > it->max_ascent)
22630 {
22631 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
22632 it->ascent = it->max_ascent;
22633 }
22634 it->phys_ascent = min (it->phys_ascent, it->ascent);
22635 it->phys_descent = min (it->phys_descent, it->descent);
22636 extra_line_spacing = 0;
22637 }
22638
22639 /* If this is a space inside a region of text with
22640 `space-width' property, change its width. */
22641 stretched_p = it->char_to_display == ' ' && !NILP (it->space_width);
22642 if (stretched_p)
22643 it->pixel_width *= XFLOATINT (it->space_width);
22644
22645 /* If face has a box, add the box thickness to the character
22646 height. If character has a box line to the left and/or
22647 right, add the box line width to the character's width. */
22648 if (face->box != FACE_NO_BOX)
22649 {
22650 int thick = face->box_line_width;
22651
22652 if (thick > 0)
22653 {
22654 it->ascent += thick;
22655 it->descent += thick;
22656 }
22657 else
22658 thick = -thick;
22659
22660 if (it->start_of_box_run_p)
22661 it->pixel_width += thick;
22662 if (it->end_of_box_run_p)
22663 it->pixel_width += thick;
22664 }
22665
22666 /* If face has an overline, add the height of the overline
22667 (1 pixel) and a 1 pixel margin to the character height. */
22668 if (face->overline_p)
22669 it->ascent += overline_margin;
22670
22671 if (it->constrain_row_ascent_descent_p)
22672 {
22673 if (it->ascent > it->max_ascent)
22674 it->ascent = it->max_ascent;
22675 if (it->descent > it->max_descent)
22676 it->descent = it->max_descent;
22677 }
22678
22679 take_vertical_position_into_account (it);
22680
22681 /* If we have to actually produce glyphs, do it. */
22682 if (it->glyph_row)
22683 {
22684 if (stretched_p)
22685 {
22686 /* Translate a space with a `space-width' property
22687 into a stretch glyph. */
22688 int ascent = (((it->ascent + it->descent) * FONT_BASE (font))
22689 / FONT_HEIGHT (font));
22690 append_stretch_glyph (it, it->object, it->pixel_width,
22691 it->ascent + it->descent, ascent);
22692 }
22693 else
22694 append_glyph (it);
22695
22696 /* If characters with lbearing or rbearing are displayed
22697 in this line, record that fact in a flag of the
22698 glyph row. This is used to optimize X output code. */
22699 if (pcm && (pcm->lbearing < 0 || pcm->rbearing > pcm->width))
22700 it->glyph_row->contains_overlapping_glyphs_p = 1;
22701 }
22702 if (! stretched_p && it->pixel_width == 0)
22703 /* We assure that all visible glyphs have at least 1-pixel
22704 width. */
22705 it->pixel_width = 1;
22706 }
22707 else if (it->char_to_display == '\n')
22708 {
22709 /* A newline has no width, but we need the height of the
22710 line. But if previous part of the line sets a height,
22711 don't increase that height */
22712
22713 Lisp_Object height;
22714 Lisp_Object total_height = Qnil;
22715
22716 it->override_ascent = -1;
22717 it->pixel_width = 0;
22718 it->nglyphs = 0;
22719
22720 height = get_it_property (it, Qline_height);
22721 /* Split (line-height total-height) list */
22722 if (CONSP (height)
22723 && CONSP (XCDR (height))
22724 && NILP (XCDR (XCDR (height))))
22725 {
22726 total_height = XCAR (XCDR (height));
22727 height = XCAR (height);
22728 }
22729 height = calc_line_height_property (it, height, font, boff, 1);
22730
22731 if (it->override_ascent >= 0)
22732 {
22733 it->ascent = it->override_ascent;
22734 it->descent = it->override_descent;
22735 boff = it->override_boff;
22736 }
22737 else
22738 {
22739 it->ascent = FONT_BASE (font) + boff;
22740 it->descent = FONT_DESCENT (font) - boff;
22741 }
22742
22743 if (EQ (height, Qt))
22744 {
22745 if (it->descent > it->max_descent)
22746 {
22747 it->ascent += it->descent - it->max_descent;
22748 it->descent = it->max_descent;
22749 }
22750 if (it->ascent > it->max_ascent)
22751 {
22752 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
22753 it->ascent = it->max_ascent;
22754 }
22755 it->phys_ascent = min (it->phys_ascent, it->ascent);
22756 it->phys_descent = min (it->phys_descent, it->descent);
22757 it->constrain_row_ascent_descent_p = 1;
22758 extra_line_spacing = 0;
22759 }
22760 else
22761 {
22762 Lisp_Object spacing;
22763
22764 it->phys_ascent = it->ascent;
22765 it->phys_descent = it->descent;
22766
22767 if ((it->max_ascent > 0 || it->max_descent > 0)
22768 && face->box != FACE_NO_BOX
22769 && face->box_line_width > 0)
22770 {
22771 it->ascent += face->box_line_width;
22772 it->descent += face->box_line_width;
22773 }
22774 if (!NILP (height)
22775 && XINT (height) > it->ascent + it->descent)
22776 it->ascent = XINT (height) - it->descent;
22777
22778 if (!NILP (total_height))
22779 spacing = calc_line_height_property (it, total_height, font, boff, 0);
22780 else
22781 {
22782 spacing = get_it_property (it, Qline_spacing);
22783 spacing = calc_line_height_property (it, spacing, font, boff, 0);
22784 }
22785 if (INTEGERP (spacing))
22786 {
22787 extra_line_spacing = XINT (spacing);
22788 if (!NILP (total_height))
22789 extra_line_spacing -= (it->phys_ascent + it->phys_descent);
22790 }
22791 }
22792 }
22793 else /* i.e. (it->char_to_display == '\t') */
22794 {
22795 if (font->space_width > 0)
22796 {
22797 int tab_width = it->tab_width * font->space_width;
22798 int x = it->current_x + it->continuation_lines_width;
22799 int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width;
22800
22801 /* If the distance from the current position to the next tab
22802 stop is less than a space character width, use the
22803 tab stop after that. */
22804 if (next_tab_x - x < font->space_width)
22805 next_tab_x += tab_width;
22806
22807 it->pixel_width = next_tab_x - x;
22808 it->nglyphs = 1;
22809 it->ascent = it->phys_ascent = FONT_BASE (font) + boff;
22810 it->descent = it->phys_descent = FONT_DESCENT (font) - boff;
22811
22812 if (it->glyph_row)
22813 {
22814 append_stretch_glyph (it, it->object, it->pixel_width,
22815 it->ascent + it->descent, it->ascent);
22816 }
22817 }
22818 else
22819 {
22820 it->pixel_width = 0;
22821 it->nglyphs = 1;
22822 }
22823 }
22824 }
22825 else if (it->what == IT_COMPOSITION && it->cmp_it.ch < 0)
22826 {
22827 /* A static composition.
22828
22829 Note: A composition is represented as one glyph in the
22830 glyph matrix. There are no padding glyphs.
22831
22832 Important note: pixel_width, ascent, and descent are the
22833 values of what is drawn by draw_glyphs (i.e. the values of
22834 the overall glyphs composed). */
22835 struct face *face = FACE_FROM_ID (it->f, it->face_id);
22836 int boff; /* baseline offset */
22837 struct composition *cmp = composition_table[it->cmp_it.id];
22838 int glyph_len = cmp->glyph_len;
22839 struct font *font = face->font;
22840
22841 it->nglyphs = 1;
22842
22843 /* If we have not yet calculated pixel size data of glyphs of
22844 the composition for the current face font, calculate them
22845 now. Theoretically, we have to check all fonts for the
22846 glyphs, but that requires much time and memory space. So,
22847 here we check only the font of the first glyph. This may
22848 lead to incorrect display, but it's very rare, and C-l
22849 (recenter-top-bottom) can correct the display anyway. */
22850 if (! cmp->font || cmp->font != font)
22851 {
22852 /* Ascent and descent of the font of the first character
22853 of this composition (adjusted by baseline offset).
22854 Ascent and descent of overall glyphs should not be less
22855 than these, respectively. */
22856 int font_ascent, font_descent, font_height;
22857 /* Bounding box of the overall glyphs. */
22858 int leftmost, rightmost, lowest, highest;
22859 int lbearing, rbearing;
22860 int i, width, ascent, descent;
22861 int left_padded = 0, right_padded = 0;
22862 int c IF_LINT (= 0); /* cmp->glyph_len can't be zero; see Bug#8512 */
22863 XChar2b char2b;
22864 struct font_metrics *pcm;
22865 int font_not_found_p;
22866 EMACS_INT pos;
22867
22868 for (glyph_len = cmp->glyph_len; glyph_len > 0; glyph_len--)
22869 if ((c = COMPOSITION_GLYPH (cmp, glyph_len - 1)) != '\t')
22870 break;
22871 if (glyph_len < cmp->glyph_len)
22872 right_padded = 1;
22873 for (i = 0; i < glyph_len; i++)
22874 {
22875 if ((c = COMPOSITION_GLYPH (cmp, i)) != '\t')
22876 break;
22877 cmp->offsets[i * 2] = cmp->offsets[i * 2 + 1] = 0;
22878 }
22879 if (i > 0)
22880 left_padded = 1;
22881
22882 pos = (STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
22883 : IT_CHARPOS (*it));
22884 /* If no suitable font is found, use the default font. */
22885 font_not_found_p = font == NULL;
22886 if (font_not_found_p)
22887 {
22888 face = face->ascii_face;
22889 font = face->font;
22890 }
22891 boff = font->baseline_offset;
22892 if (font->vertical_centering)
22893 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
22894 font_ascent = FONT_BASE (font) + boff;
22895 font_descent = FONT_DESCENT (font) - boff;
22896 font_height = FONT_HEIGHT (font);
22897
22898 cmp->font = (void *) font;
22899
22900 pcm = NULL;
22901 if (! font_not_found_p)
22902 {
22903 get_char_face_and_encoding (it->f, c, it->face_id,
22904 &char2b, 0);
22905 pcm = get_per_char_metric (font, &char2b);
22906 }
22907
22908 /* Initialize the bounding box. */
22909 if (pcm)
22910 {
22911 width = pcm->width;
22912 ascent = pcm->ascent;
22913 descent = pcm->descent;
22914 lbearing = pcm->lbearing;
22915 rbearing = pcm->rbearing;
22916 }
22917 else
22918 {
22919 width = font->space_width;
22920 ascent = FONT_BASE (font);
22921 descent = FONT_DESCENT (font);
22922 lbearing = 0;
22923 rbearing = width;
22924 }
22925
22926 rightmost = width;
22927 leftmost = 0;
22928 lowest = - descent + boff;
22929 highest = ascent + boff;
22930
22931 if (! font_not_found_p
22932 && font->default_ascent
22933 && CHAR_TABLE_P (Vuse_default_ascent)
22934 && !NILP (Faref (Vuse_default_ascent,
22935 make_number (it->char_to_display))))
22936 highest = font->default_ascent + boff;
22937
22938 /* Draw the first glyph at the normal position. It may be
22939 shifted to right later if some other glyphs are drawn
22940 at the left. */
22941 cmp->offsets[i * 2] = 0;
22942 cmp->offsets[i * 2 + 1] = boff;
22943 cmp->lbearing = lbearing;
22944 cmp->rbearing = rbearing;
22945
22946 /* Set cmp->offsets for the remaining glyphs. */
22947 for (i++; i < glyph_len; i++)
22948 {
22949 int left, right, btm, top;
22950 int ch = COMPOSITION_GLYPH (cmp, i);
22951 int face_id;
22952 struct face *this_face;
22953
22954 if (ch == '\t')
22955 ch = ' ';
22956 face_id = FACE_FOR_CHAR (it->f, face, ch, pos, it->string);
22957 this_face = FACE_FROM_ID (it->f, face_id);
22958 font = this_face->font;
22959
22960 if (font == NULL)
22961 pcm = NULL;
22962 else
22963 {
22964 get_char_face_and_encoding (it->f, ch, face_id,
22965 &char2b, 0);
22966 pcm = get_per_char_metric (font, &char2b);
22967 }
22968 if (! pcm)
22969 cmp->offsets[i * 2] = cmp->offsets[i * 2 + 1] = 0;
22970 else
22971 {
22972 width = pcm->width;
22973 ascent = pcm->ascent;
22974 descent = pcm->descent;
22975 lbearing = pcm->lbearing;
22976 rbearing = pcm->rbearing;
22977 if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS)
22978 {
22979 /* Relative composition with or without
22980 alternate chars. */
22981 left = (leftmost + rightmost - width) / 2;
22982 btm = - descent + boff;
22983 if (font->relative_compose
22984 && (! CHAR_TABLE_P (Vignore_relative_composition)
22985 || NILP (Faref (Vignore_relative_composition,
22986 make_number (ch)))))
22987 {
22988
22989 if (- descent >= font->relative_compose)
22990 /* One extra pixel between two glyphs. */
22991 btm = highest + 1;
22992 else if (ascent <= 0)
22993 /* One extra pixel between two glyphs. */
22994 btm = lowest - 1 - ascent - descent;
22995 }
22996 }
22997 else
22998 {
22999 /* A composition rule is specified by an integer
23000 value that encodes global and new reference
23001 points (GREF and NREF). GREF and NREF are
23002 specified by numbers as below:
23003
23004 0---1---2 -- ascent
23005 | |
23006 | |
23007 | |
23008 9--10--11 -- center
23009 | |
23010 ---3---4---5--- baseline
23011 | |
23012 6---7---8 -- descent
23013 */
23014 int rule = COMPOSITION_RULE (cmp, i);
23015 int gref, nref, grefx, grefy, nrefx, nrefy, xoff, yoff;
23016
23017 COMPOSITION_DECODE_RULE (rule, gref, nref, xoff, yoff);
23018 grefx = gref % 3, nrefx = nref % 3;
23019 grefy = gref / 3, nrefy = nref / 3;
23020 if (xoff)
23021 xoff = font_height * (xoff - 128) / 256;
23022 if (yoff)
23023 yoff = font_height * (yoff - 128) / 256;
23024
23025 left = (leftmost
23026 + grefx * (rightmost - leftmost) / 2
23027 - nrefx * width / 2
23028 + xoff);
23029
23030 btm = ((grefy == 0 ? highest
23031 : grefy == 1 ? 0
23032 : grefy == 2 ? lowest
23033 : (highest + lowest) / 2)
23034 - (nrefy == 0 ? ascent + descent
23035 : nrefy == 1 ? descent - boff
23036 : nrefy == 2 ? 0
23037 : (ascent + descent) / 2)
23038 + yoff);
23039 }
23040
23041 cmp->offsets[i * 2] = left;
23042 cmp->offsets[i * 2 + 1] = btm + descent;
23043
23044 /* Update the bounding box of the overall glyphs. */
23045 if (width > 0)
23046 {
23047 right = left + width;
23048 if (left < leftmost)
23049 leftmost = left;
23050 if (right > rightmost)
23051 rightmost = right;
23052 }
23053 top = btm + descent + ascent;
23054 if (top > highest)
23055 highest = top;
23056 if (btm < lowest)
23057 lowest = btm;
23058
23059 if (cmp->lbearing > left + lbearing)
23060 cmp->lbearing = left + lbearing;
23061 if (cmp->rbearing < left + rbearing)
23062 cmp->rbearing = left + rbearing;
23063 }
23064 }
23065
23066 /* If there are glyphs whose x-offsets are negative,
23067 shift all glyphs to the right and make all x-offsets
23068 non-negative. */
23069 if (leftmost < 0)
23070 {
23071 for (i = 0; i < cmp->glyph_len; i++)
23072 cmp->offsets[i * 2] -= leftmost;
23073 rightmost -= leftmost;
23074 cmp->lbearing -= leftmost;
23075 cmp->rbearing -= leftmost;
23076 }
23077
23078 if (left_padded && cmp->lbearing < 0)
23079 {
23080 for (i = 0; i < cmp->glyph_len; i++)
23081 cmp->offsets[i * 2] -= cmp->lbearing;
23082 rightmost -= cmp->lbearing;
23083 cmp->rbearing -= cmp->lbearing;
23084 cmp->lbearing = 0;
23085 }
23086 if (right_padded && rightmost < cmp->rbearing)
23087 {
23088 rightmost = cmp->rbearing;
23089 }
23090
23091 cmp->pixel_width = rightmost;
23092 cmp->ascent = highest;
23093 cmp->descent = - lowest;
23094 if (cmp->ascent < font_ascent)
23095 cmp->ascent = font_ascent;
23096 if (cmp->descent < font_descent)
23097 cmp->descent = font_descent;
23098 }
23099
23100 if (it->glyph_row
23101 && (cmp->lbearing < 0
23102 || cmp->rbearing > cmp->pixel_width))
23103 it->glyph_row->contains_overlapping_glyphs_p = 1;
23104
23105 it->pixel_width = cmp->pixel_width;
23106 it->ascent = it->phys_ascent = cmp->ascent;
23107 it->descent = it->phys_descent = cmp->descent;
23108 if (face->box != FACE_NO_BOX)
23109 {
23110 int thick = face->box_line_width;
23111
23112 if (thick > 0)
23113 {
23114 it->ascent += thick;
23115 it->descent += thick;
23116 }
23117 else
23118 thick = - thick;
23119
23120 if (it->start_of_box_run_p)
23121 it->pixel_width += thick;
23122 if (it->end_of_box_run_p)
23123 it->pixel_width += thick;
23124 }
23125
23126 /* If face has an overline, add the height of the overline
23127 (1 pixel) and a 1 pixel margin to the character height. */
23128 if (face->overline_p)
23129 it->ascent += overline_margin;
23130
23131 take_vertical_position_into_account (it);
23132 if (it->ascent < 0)
23133 it->ascent = 0;
23134 if (it->descent < 0)
23135 it->descent = 0;
23136
23137 if (it->glyph_row)
23138 append_composite_glyph (it);
23139 }
23140 else if (it->what == IT_COMPOSITION)
23141 {
23142 /* A dynamic (automatic) composition. */
23143 struct face *face = FACE_FROM_ID (it->f, it->face_id);
23144 Lisp_Object gstring;
23145 struct font_metrics metrics;
23146
23147 gstring = composition_gstring_from_id (it->cmp_it.id);
23148 it->pixel_width
23149 = composition_gstring_width (gstring, it->cmp_it.from, it->cmp_it.to,
23150 &metrics);
23151 if (it->glyph_row
23152 && (metrics.lbearing < 0 || metrics.rbearing > metrics.width))
23153 it->glyph_row->contains_overlapping_glyphs_p = 1;
23154 it->ascent = it->phys_ascent = metrics.ascent;
23155 it->descent = it->phys_descent = metrics.descent;
23156 if (face->box != FACE_NO_BOX)
23157 {
23158 int thick = face->box_line_width;
23159
23160 if (thick > 0)
23161 {
23162 it->ascent += thick;
23163 it->descent += thick;
23164 }
23165 else
23166 thick = - thick;
23167
23168 if (it->start_of_box_run_p)
23169 it->pixel_width += thick;
23170 if (it->end_of_box_run_p)
23171 it->pixel_width += thick;
23172 }
23173 /* If face has an overline, add the height of the overline
23174 (1 pixel) and a 1 pixel margin to the character height. */
23175 if (face->overline_p)
23176 it->ascent += overline_margin;
23177 take_vertical_position_into_account (it);
23178 if (it->ascent < 0)
23179 it->ascent = 0;
23180 if (it->descent < 0)
23181 it->descent = 0;
23182
23183 if (it->glyph_row)
23184 append_composite_glyph (it);
23185 }
23186 else if (it->what == IT_GLYPHLESS)
23187 produce_glyphless_glyph (it, 0, Qnil);
23188 else if (it->what == IT_IMAGE)
23189 produce_image_glyph (it);
23190 else if (it->what == IT_STRETCH)
23191 produce_stretch_glyph (it);
23192
23193 done:
23194 /* Accumulate dimensions. Note: can't assume that it->descent > 0
23195 because this isn't true for images with `:ascent 100'. */
23196 xassert (it->ascent >= 0 && it->descent >= 0);
23197 if (it->area == TEXT_AREA)
23198 it->current_x += it->pixel_width;
23199
23200 if (extra_line_spacing > 0)
23201 {
23202 it->descent += extra_line_spacing;
23203 if (extra_line_spacing > it->max_extra_line_spacing)
23204 it->max_extra_line_spacing = extra_line_spacing;
23205 }
23206
23207 it->max_ascent = max (it->max_ascent, it->ascent);
23208 it->max_descent = max (it->max_descent, it->descent);
23209 it->max_phys_ascent = max (it->max_phys_ascent, it->phys_ascent);
23210 it->max_phys_descent = max (it->max_phys_descent, it->phys_descent);
23211 }
23212
23213 /* EXPORT for RIF:
23214 Output LEN glyphs starting at START at the nominal cursor position.
23215 Advance the nominal cursor over the text. The global variable
23216 updated_window contains the window being updated, updated_row is
23217 the glyph row being updated, and updated_area is the area of that
23218 row being updated. */
23219
23220 void
23221 x_write_glyphs (struct glyph *start, int len)
23222 {
23223 int x, hpos;
23224
23225 xassert (updated_window && updated_row);
23226 BLOCK_INPUT;
23227
23228 /* Write glyphs. */
23229
23230 hpos = start - updated_row->glyphs[updated_area];
23231 x = draw_glyphs (updated_window, output_cursor.x,
23232 updated_row, updated_area,
23233 hpos, hpos + len,
23234 DRAW_NORMAL_TEXT, 0);
23235
23236 /* Invalidate old phys cursor if the glyph at its hpos is redrawn. */
23237 if (updated_area == TEXT_AREA
23238 && updated_window->phys_cursor_on_p
23239 && updated_window->phys_cursor.vpos == output_cursor.vpos
23240 && updated_window->phys_cursor.hpos >= hpos
23241 && updated_window->phys_cursor.hpos < hpos + len)
23242 updated_window->phys_cursor_on_p = 0;
23243
23244 UNBLOCK_INPUT;
23245
23246 /* Advance the output cursor. */
23247 output_cursor.hpos += len;
23248 output_cursor.x = x;
23249 }
23250
23251
23252 /* EXPORT for RIF:
23253 Insert LEN glyphs from START at the nominal cursor position. */
23254
23255 void
23256 x_insert_glyphs (struct glyph *start, int len)
23257 {
23258 struct frame *f;
23259 struct window *w;
23260 int line_height, shift_by_width, shifted_region_width;
23261 struct glyph_row *row;
23262 struct glyph *glyph;
23263 int frame_x, frame_y;
23264 EMACS_INT hpos;
23265
23266 xassert (updated_window && updated_row);
23267 BLOCK_INPUT;
23268 w = updated_window;
23269 f = XFRAME (WINDOW_FRAME (w));
23270
23271 /* Get the height of the line we are in. */
23272 row = updated_row;
23273 line_height = row->height;
23274
23275 /* Get the width of the glyphs to insert. */
23276 shift_by_width = 0;
23277 for (glyph = start; glyph < start + len; ++glyph)
23278 shift_by_width += glyph->pixel_width;
23279
23280 /* Get the width of the region to shift right. */
23281 shifted_region_width = (window_box_width (w, updated_area)
23282 - output_cursor.x
23283 - shift_by_width);
23284
23285 /* Shift right. */
23286 frame_x = window_box_left (w, updated_area) + output_cursor.x;
23287 frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, output_cursor.y);
23288
23289 FRAME_RIF (f)->shift_glyphs_for_insert (f, frame_x, frame_y, shifted_region_width,
23290 line_height, shift_by_width);
23291
23292 /* Write the glyphs. */
23293 hpos = start - row->glyphs[updated_area];
23294 draw_glyphs (w, output_cursor.x, row, updated_area,
23295 hpos, hpos + len,
23296 DRAW_NORMAL_TEXT, 0);
23297
23298 /* Advance the output cursor. */
23299 output_cursor.hpos += len;
23300 output_cursor.x += shift_by_width;
23301 UNBLOCK_INPUT;
23302 }
23303
23304
23305 /* EXPORT for RIF:
23306 Erase the current text line from the nominal cursor position
23307 (inclusive) to pixel column TO_X (exclusive). The idea is that
23308 everything from TO_X onward is already erased.
23309
23310 TO_X is a pixel position relative to updated_area of
23311 updated_window. TO_X == -1 means clear to the end of this area. */
23312
23313 void
23314 x_clear_end_of_line (int to_x)
23315 {
23316 struct frame *f;
23317 struct window *w = updated_window;
23318 int max_x, min_y, max_y;
23319 int from_x, from_y, to_y;
23320
23321 xassert (updated_window && updated_row);
23322 f = XFRAME (w->frame);
23323
23324 if (updated_row->full_width_p)
23325 max_x = WINDOW_TOTAL_WIDTH (w);
23326 else
23327 max_x = window_box_width (w, updated_area);
23328 max_y = window_text_bottom_y (w);
23329
23330 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
23331 of window. For TO_X > 0, truncate to end of drawing area. */
23332 if (to_x == 0)
23333 return;
23334 else if (to_x < 0)
23335 to_x = max_x;
23336 else
23337 to_x = min (to_x, max_x);
23338
23339 to_y = min (max_y, output_cursor.y + updated_row->height);
23340
23341 /* Notice if the cursor will be cleared by this operation. */
23342 if (!updated_row->full_width_p)
23343 notice_overwritten_cursor (w, updated_area,
23344 output_cursor.x, -1,
23345 updated_row->y,
23346 MATRIX_ROW_BOTTOM_Y (updated_row));
23347
23348 from_x = output_cursor.x;
23349
23350 /* Translate to frame coordinates. */
23351 if (updated_row->full_width_p)
23352 {
23353 from_x = WINDOW_TO_FRAME_PIXEL_X (w, from_x);
23354 to_x = WINDOW_TO_FRAME_PIXEL_X (w, to_x);
23355 }
23356 else
23357 {
23358 int area_left = window_box_left (w, updated_area);
23359 from_x += area_left;
23360 to_x += area_left;
23361 }
23362
23363 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
23364 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, max (min_y, output_cursor.y));
23365 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, to_y);
23366
23367 /* Prevent inadvertently clearing to end of the X window. */
23368 if (to_x > from_x && to_y > from_y)
23369 {
23370 BLOCK_INPUT;
23371 FRAME_RIF (f)->clear_frame_area (f, from_x, from_y,
23372 to_x - from_x, to_y - from_y);
23373 UNBLOCK_INPUT;
23374 }
23375 }
23376
23377 #endif /* HAVE_WINDOW_SYSTEM */
23378
23379
23380 \f
23381 /***********************************************************************
23382 Cursor types
23383 ***********************************************************************/
23384
23385 /* Value is the internal representation of the specified cursor type
23386 ARG. If type is BAR_CURSOR, return in *WIDTH the specified width
23387 of the bar cursor. */
23388
23389 static enum text_cursor_kinds
23390 get_specified_cursor_type (Lisp_Object arg, int *width)
23391 {
23392 enum text_cursor_kinds type;
23393
23394 if (NILP (arg))
23395 return NO_CURSOR;
23396
23397 if (EQ (arg, Qbox))
23398 return FILLED_BOX_CURSOR;
23399
23400 if (EQ (arg, Qhollow))
23401 return HOLLOW_BOX_CURSOR;
23402
23403 if (EQ (arg, Qbar))
23404 {
23405 *width = 2;
23406 return BAR_CURSOR;
23407 }
23408
23409 if (CONSP (arg)
23410 && EQ (XCAR (arg), Qbar)
23411 && INTEGERP (XCDR (arg))
23412 && XINT (XCDR (arg)) >= 0)
23413 {
23414 *width = XINT (XCDR (arg));
23415 return BAR_CURSOR;
23416 }
23417
23418 if (EQ (arg, Qhbar))
23419 {
23420 *width = 2;
23421 return HBAR_CURSOR;
23422 }
23423
23424 if (CONSP (arg)
23425 && EQ (XCAR (arg), Qhbar)
23426 && INTEGERP (XCDR (arg))
23427 && XINT (XCDR (arg)) >= 0)
23428 {
23429 *width = XINT (XCDR (arg));
23430 return HBAR_CURSOR;
23431 }
23432
23433 /* Treat anything unknown as "hollow box cursor".
23434 It was bad to signal an error; people have trouble fixing
23435 .Xdefaults with Emacs, when it has something bad in it. */
23436 type = HOLLOW_BOX_CURSOR;
23437
23438 return type;
23439 }
23440
23441 /* Set the default cursor types for specified frame. */
23442 void
23443 set_frame_cursor_types (struct frame *f, Lisp_Object arg)
23444 {
23445 int width = 1;
23446 Lisp_Object tem;
23447
23448 FRAME_DESIRED_CURSOR (f) = get_specified_cursor_type (arg, &width);
23449 FRAME_CURSOR_WIDTH (f) = width;
23450
23451 /* By default, set up the blink-off state depending on the on-state. */
23452
23453 tem = Fassoc (arg, Vblink_cursor_alist);
23454 if (!NILP (tem))
23455 {
23456 FRAME_BLINK_OFF_CURSOR (f)
23457 = get_specified_cursor_type (XCDR (tem), &width);
23458 FRAME_BLINK_OFF_CURSOR_WIDTH (f) = width;
23459 }
23460 else
23461 FRAME_BLINK_OFF_CURSOR (f) = DEFAULT_CURSOR;
23462 }
23463
23464
23465 #ifdef HAVE_WINDOW_SYSTEM
23466
23467 /* Return the cursor we want to be displayed in window W. Return
23468 width of bar/hbar cursor through WIDTH arg. Return with
23469 ACTIVE_CURSOR arg set to 1 if cursor in window W is `active'
23470 (i.e. if the `system caret' should track this cursor).
23471
23472 In a mini-buffer window, we want the cursor only to appear if we
23473 are reading input from this window. For the selected window, we
23474 want the cursor type given by the frame parameter or buffer local
23475 setting of cursor-type. If explicitly marked off, draw no cursor.
23476 In all other cases, we want a hollow box cursor. */
23477
23478 static enum text_cursor_kinds
23479 get_window_cursor_type (struct window *w, struct glyph *glyph, int *width,
23480 int *active_cursor)
23481 {
23482 struct frame *f = XFRAME (w->frame);
23483 struct buffer *b = XBUFFER (w->buffer);
23484 int cursor_type = DEFAULT_CURSOR;
23485 Lisp_Object alt_cursor;
23486 int non_selected = 0;
23487
23488 *active_cursor = 1;
23489
23490 /* Echo area */
23491 if (cursor_in_echo_area
23492 && FRAME_HAS_MINIBUF_P (f)
23493 && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
23494 {
23495 if (w == XWINDOW (echo_area_window))
23496 {
23497 if (EQ (BVAR (b, cursor_type), Qt) || NILP (BVAR (b, cursor_type)))
23498 {
23499 *width = FRAME_CURSOR_WIDTH (f);
23500 return FRAME_DESIRED_CURSOR (f);
23501 }
23502 else
23503 return get_specified_cursor_type (BVAR (b, cursor_type), width);
23504 }
23505
23506 *active_cursor = 0;
23507 non_selected = 1;
23508 }
23509
23510 /* Detect a nonselected window or nonselected frame. */
23511 else if (w != XWINDOW (f->selected_window)
23512 || f != FRAME_X_DISPLAY_INFO (f)->x_highlight_frame)
23513 {
23514 *active_cursor = 0;
23515
23516 if (MINI_WINDOW_P (w) && minibuf_level == 0)
23517 return NO_CURSOR;
23518
23519 non_selected = 1;
23520 }
23521
23522 /* Never display a cursor in a window in which cursor-type is nil. */
23523 if (NILP (BVAR (b, cursor_type)))
23524 return NO_CURSOR;
23525
23526 /* Get the normal cursor type for this window. */
23527 if (EQ (BVAR (b, cursor_type), Qt))
23528 {
23529 cursor_type = FRAME_DESIRED_CURSOR (f);
23530 *width = FRAME_CURSOR_WIDTH (f);
23531 }
23532 else
23533 cursor_type = get_specified_cursor_type (BVAR (b, cursor_type), width);
23534
23535 /* Use cursor-in-non-selected-windows instead
23536 for non-selected window or frame. */
23537 if (non_selected)
23538 {
23539 alt_cursor = BVAR (b, cursor_in_non_selected_windows);
23540 if (!EQ (Qt, alt_cursor))
23541 return get_specified_cursor_type (alt_cursor, width);
23542 /* t means modify the normal cursor type. */
23543 if (cursor_type == FILLED_BOX_CURSOR)
23544 cursor_type = HOLLOW_BOX_CURSOR;
23545 else if (cursor_type == BAR_CURSOR && *width > 1)
23546 --*width;
23547 return cursor_type;
23548 }
23549
23550 /* Use normal cursor if not blinked off. */
23551 if (!w->cursor_off_p)
23552 {
23553 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
23554 {
23555 if (cursor_type == FILLED_BOX_CURSOR)
23556 {
23557 /* Using a block cursor on large images can be very annoying.
23558 So use a hollow cursor for "large" images.
23559 If image is not transparent (no mask), also use hollow cursor. */
23560 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
23561 if (img != NULL && IMAGEP (img->spec))
23562 {
23563 /* Arbitrarily, interpret "Large" as >32x32 and >NxN
23564 where N = size of default frame font size.
23565 This should cover most of the "tiny" icons people may use. */
23566 if (!img->mask
23567 || img->width > max (32, WINDOW_FRAME_COLUMN_WIDTH (w))
23568 || img->height > max (32, WINDOW_FRAME_LINE_HEIGHT (w)))
23569 cursor_type = HOLLOW_BOX_CURSOR;
23570 }
23571 }
23572 else if (cursor_type != NO_CURSOR)
23573 {
23574 /* Display current only supports BOX and HOLLOW cursors for images.
23575 So for now, unconditionally use a HOLLOW cursor when cursor is
23576 not a solid box cursor. */
23577 cursor_type = HOLLOW_BOX_CURSOR;
23578 }
23579 }
23580 return cursor_type;
23581 }
23582
23583 /* Cursor is blinked off, so determine how to "toggle" it. */
23584
23585 /* First look for an entry matching the buffer's cursor-type in blink-cursor-alist. */
23586 if ((alt_cursor = Fassoc (BVAR (b, cursor_type), Vblink_cursor_alist), !NILP (alt_cursor)))
23587 return get_specified_cursor_type (XCDR (alt_cursor), width);
23588
23589 /* Then see if frame has specified a specific blink off cursor type. */
23590 if (FRAME_BLINK_OFF_CURSOR (f) != DEFAULT_CURSOR)
23591 {
23592 *width = FRAME_BLINK_OFF_CURSOR_WIDTH (f);
23593 return FRAME_BLINK_OFF_CURSOR (f);
23594 }
23595
23596 #if 0
23597 /* Some people liked having a permanently visible blinking cursor,
23598 while others had very strong opinions against it. So it was
23599 decided to remove it. KFS 2003-09-03 */
23600
23601 /* Finally perform built-in cursor blinking:
23602 filled box <-> hollow box
23603 wide [h]bar <-> narrow [h]bar
23604 narrow [h]bar <-> no cursor
23605 other type <-> no cursor */
23606
23607 if (cursor_type == FILLED_BOX_CURSOR)
23608 return HOLLOW_BOX_CURSOR;
23609
23610 if ((cursor_type == BAR_CURSOR || cursor_type == HBAR_CURSOR) && *width > 1)
23611 {
23612 *width = 1;
23613 return cursor_type;
23614 }
23615 #endif
23616
23617 return NO_CURSOR;
23618 }
23619
23620
23621 /* Notice when the text cursor of window W has been completely
23622 overwritten by a drawing operation that outputs glyphs in AREA
23623 starting at X0 and ending at X1 in the line starting at Y0 and
23624 ending at Y1. X coordinates are area-relative. X1 < 0 means all
23625 the rest of the line after X0 has been written. Y coordinates
23626 are window-relative. */
23627
23628 static void
23629 notice_overwritten_cursor (struct window *w, enum glyph_row_area area,
23630 int x0, int x1, int y0, int y1)
23631 {
23632 int cx0, cx1, cy0, cy1;
23633 struct glyph_row *row;
23634
23635 if (!w->phys_cursor_on_p)
23636 return;
23637 if (area != TEXT_AREA)
23638 return;
23639
23640 if (w->phys_cursor.vpos < 0
23641 || w->phys_cursor.vpos >= w->current_matrix->nrows
23642 || (row = w->current_matrix->rows + w->phys_cursor.vpos,
23643 !(row->enabled_p && row->displays_text_p)))
23644 return;
23645
23646 if (row->cursor_in_fringe_p)
23647 {
23648 row->cursor_in_fringe_p = 0;
23649 draw_fringe_bitmap (w, row, row->reversed_p);
23650 w->phys_cursor_on_p = 0;
23651 return;
23652 }
23653
23654 cx0 = w->phys_cursor.x;
23655 cx1 = cx0 + w->phys_cursor_width;
23656 if (x0 > cx0 || (x1 >= 0 && x1 < cx1))
23657 return;
23658
23659 /* The cursor image will be completely removed from the
23660 screen if the output area intersects the cursor area in
23661 y-direction. When we draw in [y0 y1[, and some part of
23662 the cursor is at y < y0, that part must have been drawn
23663 before. When scrolling, the cursor is erased before
23664 actually scrolling, so we don't come here. When not
23665 scrolling, the rows above the old cursor row must have
23666 changed, and in this case these rows must have written
23667 over the cursor image.
23668
23669 Likewise if part of the cursor is below y1, with the
23670 exception of the cursor being in the first blank row at
23671 the buffer and window end because update_text_area
23672 doesn't draw that row. (Except when it does, but
23673 that's handled in update_text_area.) */
23674
23675 cy0 = w->phys_cursor.y;
23676 cy1 = cy0 + w->phys_cursor_height;
23677 if ((y0 < cy0 || y0 >= cy1) && (y1 <= cy0 || y1 >= cy1))
23678 return;
23679
23680 w->phys_cursor_on_p = 0;
23681 }
23682
23683 #endif /* HAVE_WINDOW_SYSTEM */
23684
23685 \f
23686 /************************************************************************
23687 Mouse Face
23688 ************************************************************************/
23689
23690 #ifdef HAVE_WINDOW_SYSTEM
23691
23692 /* EXPORT for RIF:
23693 Fix the display of area AREA of overlapping row ROW in window W
23694 with respect to the overlapping part OVERLAPS. */
23695
23696 void
23697 x_fix_overlapping_area (struct window *w, struct glyph_row *row,
23698 enum glyph_row_area area, int overlaps)
23699 {
23700 int i, x;
23701
23702 BLOCK_INPUT;
23703
23704 x = 0;
23705 for (i = 0; i < row->used[area];)
23706 {
23707 if (row->glyphs[area][i].overlaps_vertically_p)
23708 {
23709 int start = i, start_x = x;
23710
23711 do
23712 {
23713 x += row->glyphs[area][i].pixel_width;
23714 ++i;
23715 }
23716 while (i < row->used[area]
23717 && row->glyphs[area][i].overlaps_vertically_p);
23718
23719 draw_glyphs (w, start_x, row, area,
23720 start, i,
23721 DRAW_NORMAL_TEXT, overlaps);
23722 }
23723 else
23724 {
23725 x += row->glyphs[area][i].pixel_width;
23726 ++i;
23727 }
23728 }
23729
23730 UNBLOCK_INPUT;
23731 }
23732
23733
23734 /* EXPORT:
23735 Draw the cursor glyph of window W in glyph row ROW. See the
23736 comment of draw_glyphs for the meaning of HL. */
23737
23738 void
23739 draw_phys_cursor_glyph (struct window *w, struct glyph_row *row,
23740 enum draw_glyphs_face hl)
23741 {
23742 /* If cursor hpos is out of bounds, don't draw garbage. This can
23743 happen in mini-buffer windows when switching between echo area
23744 glyphs and mini-buffer. */
23745 if ((row->reversed_p
23746 ? (w->phys_cursor.hpos >= 0)
23747 : (w->phys_cursor.hpos < row->used[TEXT_AREA])))
23748 {
23749 int on_p = w->phys_cursor_on_p;
23750 int x1;
23751 x1 = draw_glyphs (w, w->phys_cursor.x, row, TEXT_AREA,
23752 w->phys_cursor.hpos, w->phys_cursor.hpos + 1,
23753 hl, 0);
23754 w->phys_cursor_on_p = on_p;
23755
23756 if (hl == DRAW_CURSOR)
23757 w->phys_cursor_width = x1 - w->phys_cursor.x;
23758 /* When we erase the cursor, and ROW is overlapped by other
23759 rows, make sure that these overlapping parts of other rows
23760 are redrawn. */
23761 else if (hl == DRAW_NORMAL_TEXT && row->overlapped_p)
23762 {
23763 w->phys_cursor_width = x1 - w->phys_cursor.x;
23764
23765 if (row > w->current_matrix->rows
23766 && MATRIX_ROW_OVERLAPS_SUCC_P (row - 1))
23767 x_fix_overlapping_area (w, row - 1, TEXT_AREA,
23768 OVERLAPS_ERASED_CURSOR);
23769
23770 if (MATRIX_ROW_BOTTOM_Y (row) < window_text_bottom_y (w)
23771 && MATRIX_ROW_OVERLAPS_PRED_P (row + 1))
23772 x_fix_overlapping_area (w, row + 1, TEXT_AREA,
23773 OVERLAPS_ERASED_CURSOR);
23774 }
23775 }
23776 }
23777
23778
23779 /* EXPORT:
23780 Erase the image of a cursor of window W from the screen. */
23781
23782 void
23783 erase_phys_cursor (struct window *w)
23784 {
23785 struct frame *f = XFRAME (w->frame);
23786 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
23787 int hpos = w->phys_cursor.hpos;
23788 int vpos = w->phys_cursor.vpos;
23789 int mouse_face_here_p = 0;
23790 struct glyph_matrix *active_glyphs = w->current_matrix;
23791 struct glyph_row *cursor_row;
23792 struct glyph *cursor_glyph;
23793 enum draw_glyphs_face hl;
23794
23795 /* No cursor displayed or row invalidated => nothing to do on the
23796 screen. */
23797 if (w->phys_cursor_type == NO_CURSOR)
23798 goto mark_cursor_off;
23799
23800 /* VPOS >= active_glyphs->nrows means that window has been resized.
23801 Don't bother to erase the cursor. */
23802 if (vpos >= active_glyphs->nrows)
23803 goto mark_cursor_off;
23804
23805 /* If row containing cursor is marked invalid, there is nothing we
23806 can do. */
23807 cursor_row = MATRIX_ROW (active_glyphs, vpos);
23808 if (!cursor_row->enabled_p)
23809 goto mark_cursor_off;
23810
23811 /* If line spacing is > 0, old cursor may only be partially visible in
23812 window after split-window. So adjust visible height. */
23813 cursor_row->visible_height = min (cursor_row->visible_height,
23814 window_text_bottom_y (w) - cursor_row->y);
23815
23816 /* If row is completely invisible, don't attempt to delete a cursor which
23817 isn't there. This can happen if cursor is at top of a window, and
23818 we switch to a buffer with a header line in that window. */
23819 if (cursor_row->visible_height <= 0)
23820 goto mark_cursor_off;
23821
23822 /* If cursor is in the fringe, erase by drawing actual bitmap there. */
23823 if (cursor_row->cursor_in_fringe_p)
23824 {
23825 cursor_row->cursor_in_fringe_p = 0;
23826 draw_fringe_bitmap (w, cursor_row, cursor_row->reversed_p);
23827 goto mark_cursor_off;
23828 }
23829
23830 /* This can happen when the new row is shorter than the old one.
23831 In this case, either draw_glyphs or clear_end_of_line
23832 should have cleared the cursor. Note that we wouldn't be
23833 able to erase the cursor in this case because we don't have a
23834 cursor glyph at hand. */
23835 if ((cursor_row->reversed_p
23836 ? (w->phys_cursor.hpos < 0)
23837 : (w->phys_cursor.hpos >= cursor_row->used[TEXT_AREA])))
23838 goto mark_cursor_off;
23839
23840 /* If the cursor is in the mouse face area, redisplay that when
23841 we clear the cursor. */
23842 if (! NILP (hlinfo->mouse_face_window)
23843 && coords_in_mouse_face_p (w, hpos, vpos)
23844 /* Don't redraw the cursor's spot in mouse face if it is at the
23845 end of a line (on a newline). The cursor appears there, but
23846 mouse highlighting does not. */
23847 && cursor_row->used[TEXT_AREA] > hpos && hpos >= 0)
23848 mouse_face_here_p = 1;
23849
23850 /* Maybe clear the display under the cursor. */
23851 if (w->phys_cursor_type == HOLLOW_BOX_CURSOR)
23852 {
23853 int x, y, left_x;
23854 int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
23855 int width;
23856
23857 cursor_glyph = get_phys_cursor_glyph (w);
23858 if (cursor_glyph == NULL)
23859 goto mark_cursor_off;
23860
23861 width = cursor_glyph->pixel_width;
23862 left_x = window_box_left_offset (w, TEXT_AREA);
23863 x = w->phys_cursor.x;
23864 if (x < left_x)
23865 width -= left_x - x;
23866 width = min (width, window_box_width (w, TEXT_AREA) - x);
23867 y = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, cursor_row->y));
23868 x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, max (x, left_x));
23869
23870 if (width > 0)
23871 FRAME_RIF (f)->clear_frame_area (f, x, y, width, cursor_row->visible_height);
23872 }
23873
23874 /* Erase the cursor by redrawing the character underneath it. */
23875 if (mouse_face_here_p)
23876 hl = DRAW_MOUSE_FACE;
23877 else
23878 hl = DRAW_NORMAL_TEXT;
23879 draw_phys_cursor_glyph (w, cursor_row, hl);
23880
23881 mark_cursor_off:
23882 w->phys_cursor_on_p = 0;
23883 w->phys_cursor_type = NO_CURSOR;
23884 }
23885
23886
23887 /* EXPORT:
23888 Display or clear cursor of window W. If ON is zero, clear the
23889 cursor. If it is non-zero, display the cursor. If ON is nonzero,
23890 where to put the cursor is specified by HPOS, VPOS, X and Y. */
23891
23892 void
23893 display_and_set_cursor (struct window *w, int on,
23894 int hpos, int vpos, int x, int y)
23895 {
23896 struct frame *f = XFRAME (w->frame);
23897 int new_cursor_type;
23898 int new_cursor_width;
23899 int active_cursor;
23900 struct glyph_row *glyph_row;
23901 struct glyph *glyph;
23902
23903 /* This is pointless on invisible frames, and dangerous on garbaged
23904 windows and frames; in the latter case, the frame or window may
23905 be in the midst of changing its size, and x and y may be off the
23906 window. */
23907 if (! FRAME_VISIBLE_P (f)
23908 || FRAME_GARBAGED_P (f)
23909 || vpos >= w->current_matrix->nrows
23910 || hpos >= w->current_matrix->matrix_w)
23911 return;
23912
23913 /* If cursor is off and we want it off, return quickly. */
23914 if (!on && !w->phys_cursor_on_p)
23915 return;
23916
23917 glyph_row = MATRIX_ROW (w->current_matrix, vpos);
23918 /* If cursor row is not enabled, we don't really know where to
23919 display the cursor. */
23920 if (!glyph_row->enabled_p)
23921 {
23922 w->phys_cursor_on_p = 0;
23923 return;
23924 }
23925
23926 glyph = NULL;
23927 if (!glyph_row->exact_window_width_line_p
23928 || (0 <= hpos && hpos < glyph_row->used[TEXT_AREA]))
23929 glyph = glyph_row->glyphs[TEXT_AREA] + hpos;
23930
23931 xassert (interrupt_input_blocked);
23932
23933 /* Set new_cursor_type to the cursor we want to be displayed. */
23934 new_cursor_type = get_window_cursor_type (w, glyph,
23935 &new_cursor_width, &active_cursor);
23936
23937 /* If cursor is currently being shown and we don't want it to be or
23938 it is in the wrong place, or the cursor type is not what we want,
23939 erase it. */
23940 if (w->phys_cursor_on_p
23941 && (!on
23942 || w->phys_cursor.x != x
23943 || w->phys_cursor.y != y
23944 || new_cursor_type != w->phys_cursor_type
23945 || ((new_cursor_type == BAR_CURSOR || new_cursor_type == HBAR_CURSOR)
23946 && new_cursor_width != w->phys_cursor_width)))
23947 erase_phys_cursor (w);
23948
23949 /* Don't check phys_cursor_on_p here because that flag is only set
23950 to zero in some cases where we know that the cursor has been
23951 completely erased, to avoid the extra work of erasing the cursor
23952 twice. In other words, phys_cursor_on_p can be 1 and the cursor
23953 still not be visible, or it has only been partly erased. */
23954 if (on)
23955 {
23956 w->phys_cursor_ascent = glyph_row->ascent;
23957 w->phys_cursor_height = glyph_row->height;
23958
23959 /* Set phys_cursor_.* before x_draw_.* is called because some
23960 of them may need the information. */
23961 w->phys_cursor.x = x;
23962 w->phys_cursor.y = glyph_row->y;
23963 w->phys_cursor.hpos = hpos;
23964 w->phys_cursor.vpos = vpos;
23965 }
23966
23967 FRAME_RIF (f)->draw_window_cursor (w, glyph_row, x, y,
23968 new_cursor_type, new_cursor_width,
23969 on, active_cursor);
23970 }
23971
23972
23973 /* Switch the display of W's cursor on or off, according to the value
23974 of ON. */
23975
23976 static void
23977 update_window_cursor (struct window *w, int on)
23978 {
23979 /* Don't update cursor in windows whose frame is in the process
23980 of being deleted. */
23981 if (w->current_matrix)
23982 {
23983 BLOCK_INPUT;
23984 display_and_set_cursor (w, on, w->phys_cursor.hpos, w->phys_cursor.vpos,
23985 w->phys_cursor.x, w->phys_cursor.y);
23986 UNBLOCK_INPUT;
23987 }
23988 }
23989
23990
23991 /* Call update_window_cursor with parameter ON_P on all leaf windows
23992 in the window tree rooted at W. */
23993
23994 static void
23995 update_cursor_in_window_tree (struct window *w, int on_p)
23996 {
23997 while (w)
23998 {
23999 if (!NILP (w->hchild))
24000 update_cursor_in_window_tree (XWINDOW (w->hchild), on_p);
24001 else if (!NILP (w->vchild))
24002 update_cursor_in_window_tree (XWINDOW (w->vchild), on_p);
24003 else
24004 update_window_cursor (w, on_p);
24005
24006 w = NILP (w->next) ? 0 : XWINDOW (w->next);
24007 }
24008 }
24009
24010
24011 /* EXPORT:
24012 Display the cursor on window W, or clear it, according to ON_P.
24013 Don't change the cursor's position. */
24014
24015 void
24016 x_update_cursor (struct frame *f, int on_p)
24017 {
24018 update_cursor_in_window_tree (XWINDOW (f->root_window), on_p);
24019 }
24020
24021
24022 /* EXPORT:
24023 Clear the cursor of window W to background color, and mark the
24024 cursor as not shown. This is used when the text where the cursor
24025 is about to be rewritten. */
24026
24027 void
24028 x_clear_cursor (struct window *w)
24029 {
24030 if (FRAME_VISIBLE_P (XFRAME (w->frame)) && w->phys_cursor_on_p)
24031 update_window_cursor (w, 0);
24032 }
24033
24034 #endif /* HAVE_WINDOW_SYSTEM */
24035
24036 /* Implementation of draw_row_with_mouse_face for GUI sessions, GPM,
24037 and MSDOS. */
24038 static void
24039 draw_row_with_mouse_face (struct window *w, int start_x, struct glyph_row *row,
24040 int start_hpos, int end_hpos,
24041 enum draw_glyphs_face draw)
24042 {
24043 #ifdef HAVE_WINDOW_SYSTEM
24044 if (FRAME_WINDOW_P (XFRAME (w->frame)))
24045 {
24046 draw_glyphs (w, start_x, row, TEXT_AREA, start_hpos, end_hpos, draw, 0);
24047 return;
24048 }
24049 #endif
24050 #if defined (HAVE_GPM) || defined (MSDOS)
24051 tty_draw_row_with_mouse_face (w, row, start_hpos, end_hpos, draw);
24052 #endif
24053 }
24054
24055 /* Display the active region described by mouse_face_* according to DRAW. */
24056
24057 static void
24058 show_mouse_face (Mouse_HLInfo *hlinfo, enum draw_glyphs_face draw)
24059 {
24060 struct window *w = XWINDOW (hlinfo->mouse_face_window);
24061 struct frame *f = XFRAME (WINDOW_FRAME (w));
24062
24063 if (/* If window is in the process of being destroyed, don't bother
24064 to do anything. */
24065 w->current_matrix != NULL
24066 /* Don't update mouse highlight if hidden */
24067 && (draw != DRAW_MOUSE_FACE || !hlinfo->mouse_face_hidden)
24068 /* Recognize when we are called to operate on rows that don't exist
24069 anymore. This can happen when a window is split. */
24070 && hlinfo->mouse_face_end_row < w->current_matrix->nrows)
24071 {
24072 int phys_cursor_on_p = w->phys_cursor_on_p;
24073 struct glyph_row *row, *first, *last;
24074
24075 first = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_beg_row);
24076 last = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_end_row);
24077
24078 for (row = first; row <= last && row->enabled_p; ++row)
24079 {
24080 int start_hpos, end_hpos, start_x;
24081
24082 /* For all but the first row, the highlight starts at column 0. */
24083 if (row == first)
24084 {
24085 /* R2L rows have BEG and END in reversed order, but the
24086 screen drawing geometry is always left to right. So
24087 we need to mirror the beginning and end of the
24088 highlighted area in R2L rows. */
24089 if (!row->reversed_p)
24090 {
24091 start_hpos = hlinfo->mouse_face_beg_col;
24092 start_x = hlinfo->mouse_face_beg_x;
24093 }
24094 else if (row == last)
24095 {
24096 start_hpos = hlinfo->mouse_face_end_col;
24097 start_x = hlinfo->mouse_face_end_x;
24098 }
24099 else
24100 {
24101 start_hpos = 0;
24102 start_x = 0;
24103 }
24104 }
24105 else if (row->reversed_p && row == last)
24106 {
24107 start_hpos = hlinfo->mouse_face_end_col;
24108 start_x = hlinfo->mouse_face_end_x;
24109 }
24110 else
24111 {
24112 start_hpos = 0;
24113 start_x = 0;
24114 }
24115
24116 if (row == last)
24117 {
24118 if (!row->reversed_p)
24119 end_hpos = hlinfo->mouse_face_end_col;
24120 else if (row == first)
24121 end_hpos = hlinfo->mouse_face_beg_col;
24122 else
24123 {
24124 end_hpos = row->used[TEXT_AREA];
24125 if (draw == DRAW_NORMAL_TEXT)
24126 row->fill_line_p = 1; /* Clear to end of line */
24127 }
24128 }
24129 else if (row->reversed_p && row == first)
24130 end_hpos = hlinfo->mouse_face_beg_col;
24131 else
24132 {
24133 end_hpos = row->used[TEXT_AREA];
24134 if (draw == DRAW_NORMAL_TEXT)
24135 row->fill_line_p = 1; /* Clear to end of line */
24136 }
24137
24138 if (end_hpos > start_hpos)
24139 {
24140 draw_row_with_mouse_face (w, start_x, row,
24141 start_hpos, end_hpos, draw);
24142
24143 row->mouse_face_p
24144 = draw == DRAW_MOUSE_FACE || draw == DRAW_IMAGE_RAISED;
24145 }
24146 }
24147
24148 #ifdef HAVE_WINDOW_SYSTEM
24149 /* When we've written over the cursor, arrange for it to
24150 be displayed again. */
24151 if (FRAME_WINDOW_P (f)
24152 && phys_cursor_on_p && !w->phys_cursor_on_p)
24153 {
24154 BLOCK_INPUT;
24155 display_and_set_cursor (w, 1,
24156 w->phys_cursor.hpos, w->phys_cursor.vpos,
24157 w->phys_cursor.x, w->phys_cursor.y);
24158 UNBLOCK_INPUT;
24159 }
24160 #endif /* HAVE_WINDOW_SYSTEM */
24161 }
24162
24163 #ifdef HAVE_WINDOW_SYSTEM
24164 /* Change the mouse cursor. */
24165 if (FRAME_WINDOW_P (f))
24166 {
24167 if (draw == DRAW_NORMAL_TEXT
24168 && !EQ (hlinfo->mouse_face_window, f->tool_bar_window))
24169 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->text_cursor);
24170 else if (draw == DRAW_MOUSE_FACE)
24171 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->hand_cursor);
24172 else
24173 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->nontext_cursor);
24174 }
24175 #endif /* HAVE_WINDOW_SYSTEM */
24176 }
24177
24178 /* EXPORT:
24179 Clear out the mouse-highlighted active region.
24180 Redraw it un-highlighted first. Value is non-zero if mouse
24181 face was actually drawn unhighlighted. */
24182
24183 int
24184 clear_mouse_face (Mouse_HLInfo *hlinfo)
24185 {
24186 int cleared = 0;
24187
24188 if (!hlinfo->mouse_face_hidden && !NILP (hlinfo->mouse_face_window))
24189 {
24190 show_mouse_face (hlinfo, DRAW_NORMAL_TEXT);
24191 cleared = 1;
24192 }
24193
24194 hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
24195 hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
24196 hlinfo->mouse_face_window = Qnil;
24197 hlinfo->mouse_face_overlay = Qnil;
24198 return cleared;
24199 }
24200
24201 /* Return non-zero if the coordinates HPOS and VPOS on windows W are
24202 within the mouse face on that window. */
24203 static int
24204 coords_in_mouse_face_p (struct window *w, int hpos, int vpos)
24205 {
24206 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame));
24207
24208 /* Quickly resolve the easy cases. */
24209 if (!(WINDOWP (hlinfo->mouse_face_window)
24210 && XWINDOW (hlinfo->mouse_face_window) == w))
24211 return 0;
24212 if (vpos < hlinfo->mouse_face_beg_row
24213 || vpos > hlinfo->mouse_face_end_row)
24214 return 0;
24215 if (vpos > hlinfo->mouse_face_beg_row
24216 && vpos < hlinfo->mouse_face_end_row)
24217 return 1;
24218
24219 if (!MATRIX_ROW (w->current_matrix, vpos)->reversed_p)
24220 {
24221 if (hlinfo->mouse_face_beg_row == hlinfo->mouse_face_end_row)
24222 {
24223 if (hlinfo->mouse_face_beg_col <= hpos && hpos < hlinfo->mouse_face_end_col)
24224 return 1;
24225 }
24226 else if ((vpos == hlinfo->mouse_face_beg_row
24227 && hpos >= hlinfo->mouse_face_beg_col)
24228 || (vpos == hlinfo->mouse_face_end_row
24229 && hpos < hlinfo->mouse_face_end_col))
24230 return 1;
24231 }
24232 else
24233 {
24234 if (hlinfo->mouse_face_beg_row == hlinfo->mouse_face_end_row)
24235 {
24236 if (hlinfo->mouse_face_end_col < hpos && hpos <= hlinfo->mouse_face_beg_col)
24237 return 1;
24238 }
24239 else if ((vpos == hlinfo->mouse_face_beg_row
24240 && hpos <= hlinfo->mouse_face_beg_col)
24241 || (vpos == hlinfo->mouse_face_end_row
24242 && hpos > hlinfo->mouse_face_end_col))
24243 return 1;
24244 }
24245 return 0;
24246 }
24247
24248
24249 /* EXPORT:
24250 Non-zero if physical cursor of window W is within mouse face. */
24251
24252 int
24253 cursor_in_mouse_face_p (struct window *w)
24254 {
24255 return coords_in_mouse_face_p (w, w->phys_cursor.hpos, w->phys_cursor.vpos);
24256 }
24257
24258
24259 \f
24260 /* Find the glyph rows START_ROW and END_ROW of window W that display
24261 characters between buffer positions START_CHARPOS and END_CHARPOS
24262 (excluding END_CHARPOS). This is similar to row_containing_pos,
24263 but is more accurate when bidi reordering makes buffer positions
24264 change non-linearly with glyph rows. */
24265 static void
24266 rows_from_pos_range (struct window *w,
24267 EMACS_INT start_charpos, EMACS_INT end_charpos,
24268 struct glyph_row **start, struct glyph_row **end)
24269 {
24270 struct glyph_row *first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
24271 int last_y = window_text_bottom_y (w);
24272 struct glyph_row *row;
24273
24274 *start = NULL;
24275 *end = NULL;
24276
24277 while (!first->enabled_p
24278 && first < MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w))
24279 first++;
24280
24281 /* Find the START row. */
24282 for (row = first;
24283 row->enabled_p && MATRIX_ROW_BOTTOM_Y (row) <= last_y;
24284 row++)
24285 {
24286 /* A row can potentially be the START row if the range of the
24287 characters it displays intersects the range
24288 [START_CHARPOS..END_CHARPOS). */
24289 if (! ((start_charpos < MATRIX_ROW_START_CHARPOS (row)
24290 && end_charpos < MATRIX_ROW_START_CHARPOS (row))
24291 /* See the commentary in row_containing_pos, for the
24292 explanation of the complicated way to check whether
24293 some position is beyond the end of the characters
24294 displayed by a row. */
24295 || ((start_charpos > MATRIX_ROW_END_CHARPOS (row)
24296 || (start_charpos == MATRIX_ROW_END_CHARPOS (row)
24297 && !row->ends_at_zv_p
24298 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
24299 && (end_charpos > MATRIX_ROW_END_CHARPOS (row)
24300 || (end_charpos == MATRIX_ROW_END_CHARPOS (row)
24301 && !row->ends_at_zv_p
24302 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))))))
24303 {
24304 /* Found a candidate row. Now make sure at least one of the
24305 glyphs it displays has a charpos from the range
24306 [START_CHARPOS..END_CHARPOS).
24307
24308 This is not obvious because bidi reordering could make
24309 buffer positions of a row be 1,2,3,102,101,100, and if we
24310 want to highlight characters in [50..60), we don't want
24311 this row, even though [50..60) does intersect [1..103),
24312 the range of character positions given by the row's start
24313 and end positions. */
24314 struct glyph *g = row->glyphs[TEXT_AREA];
24315 struct glyph *e = g + row->used[TEXT_AREA];
24316
24317 while (g < e)
24318 {
24319 if (BUFFERP (g->object)
24320 && start_charpos <= g->charpos && g->charpos < end_charpos)
24321 *start = row;
24322 g++;
24323 }
24324 if (*start)
24325 break;
24326 }
24327 }
24328
24329 /* Find the END row. */
24330 if (!*start
24331 /* If the last row is partially visible, start looking for END
24332 from that row, instead of starting from FIRST. */
24333 && !(row->enabled_p
24334 && row->y < last_y && MATRIX_ROW_BOTTOM_Y (row) > last_y))
24335 row = first;
24336 for ( ; row->enabled_p && MATRIX_ROW_BOTTOM_Y (row) <= last_y; row++)
24337 {
24338 struct glyph_row *next = row + 1;
24339
24340 if (!next->enabled_p
24341 || next >= MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w)
24342 /* The first row >= START whose range of displayed characters
24343 does NOT intersect the range [START_CHARPOS..END_CHARPOS]
24344 is the row END + 1. */
24345 || (start_charpos < MATRIX_ROW_START_CHARPOS (next)
24346 && end_charpos < MATRIX_ROW_START_CHARPOS (next))
24347 || ((start_charpos > MATRIX_ROW_END_CHARPOS (next)
24348 || (start_charpos == MATRIX_ROW_END_CHARPOS (next)
24349 && !next->ends_at_zv_p
24350 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (next)))
24351 && (end_charpos > MATRIX_ROW_END_CHARPOS (next)
24352 || (end_charpos == MATRIX_ROW_END_CHARPOS (next)
24353 && !next->ends_at_zv_p
24354 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (next)))))
24355 {
24356 *end = row;
24357 break;
24358 }
24359 else
24360 {
24361 /* If the next row's edges intersect [START_CHARPOS..END_CHARPOS],
24362 but none of the characters it displays are in the range, it is
24363 also END + 1. */
24364 struct glyph *g = next->glyphs[TEXT_AREA];
24365 struct glyph *e = g + next->used[TEXT_AREA];
24366
24367 while (g < e)
24368 {
24369 if (BUFFERP (g->object)
24370 && start_charpos <= g->charpos && g->charpos < end_charpos)
24371 break;
24372 g++;
24373 }
24374 if (g == e)
24375 {
24376 *end = row;
24377 break;
24378 }
24379 }
24380 }
24381 }
24382
24383 /* This function sets the mouse_face_* elements of HLINFO, assuming
24384 the mouse cursor is on a glyph with buffer charpos MOUSE_CHARPOS in
24385 window WINDOW. START_CHARPOS and END_CHARPOS are buffer positions
24386 for the overlay or run of text properties specifying the mouse
24387 face. BEFORE_STRING and AFTER_STRING, if non-nil, are a
24388 before-string and after-string that must also be highlighted.
24389 COVER_STRING, if non-nil, is a display string that may cover some
24390 or all of the highlighted text. */
24391
24392 static void
24393 mouse_face_from_buffer_pos (Lisp_Object window,
24394 Mouse_HLInfo *hlinfo,
24395 EMACS_INT mouse_charpos,
24396 EMACS_INT start_charpos,
24397 EMACS_INT end_charpos,
24398 Lisp_Object before_string,
24399 Lisp_Object after_string,
24400 Lisp_Object cover_string)
24401 {
24402 struct window *w = XWINDOW (window);
24403 struct glyph_row *first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
24404 struct glyph_row *r1, *r2;
24405 struct glyph *glyph, *end;
24406 EMACS_INT ignore, pos;
24407 int x;
24408
24409 xassert (NILP (cover_string) || STRINGP (cover_string));
24410 xassert (NILP (before_string) || STRINGP (before_string));
24411 xassert (NILP (after_string) || STRINGP (after_string));
24412
24413 /* Find the rows corresponding to START_CHARPOS and END_CHARPOS. */
24414 rows_from_pos_range (w, start_charpos, end_charpos, &r1, &r2);
24415 if (r1 == NULL)
24416 r1 = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
24417 /* If the before-string or display-string contains newlines,
24418 rows_from_pos_range skips to its last row. Move back. */
24419 if (!NILP (before_string) || !NILP (cover_string))
24420 {
24421 struct glyph_row *prev;
24422 while ((prev = r1 - 1, prev >= first)
24423 && MATRIX_ROW_END_CHARPOS (prev) == start_charpos
24424 && prev->used[TEXT_AREA] > 0)
24425 {
24426 struct glyph *beg = prev->glyphs[TEXT_AREA];
24427 glyph = beg + prev->used[TEXT_AREA];
24428 while (--glyph >= beg && INTEGERP (glyph->object));
24429 if (glyph < beg
24430 || !(EQ (glyph->object, before_string)
24431 || EQ (glyph->object, cover_string)))
24432 break;
24433 r1 = prev;
24434 }
24435 }
24436 if (r2 == NULL)
24437 {
24438 r2 = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
24439 hlinfo->mouse_face_past_end = 1;
24440 }
24441 else if (!NILP (after_string))
24442 {
24443 /* If the after-string has newlines, advance to its last row. */
24444 struct glyph_row *next;
24445 struct glyph_row *last
24446 = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
24447
24448 for (next = r2 + 1;
24449 next <= last
24450 && next->used[TEXT_AREA] > 0
24451 && EQ (next->glyphs[TEXT_AREA]->object, after_string);
24452 ++next)
24453 r2 = next;
24454 }
24455 /* The rest of the display engine assumes that mouse_face_beg_row is
24456 either above below mouse_face_end_row or identical to it. But
24457 with bidi-reordered continued lines, the row for START_CHARPOS
24458 could be below the row for END_CHARPOS. If so, swap the rows and
24459 store them in correct order. */
24460 if (r1->y > r2->y)
24461 {
24462 struct glyph_row *tem = r2;
24463
24464 r2 = r1;
24465 r1 = tem;
24466 }
24467
24468 hlinfo->mouse_face_beg_y = r1->y;
24469 hlinfo->mouse_face_beg_row = MATRIX_ROW_VPOS (r1, w->current_matrix);
24470 hlinfo->mouse_face_end_y = r2->y;
24471 hlinfo->mouse_face_end_row = MATRIX_ROW_VPOS (r2, w->current_matrix);
24472
24473 /* For a bidi-reordered row, the positions of BEFORE_STRING,
24474 AFTER_STRING, COVER_STRING, START_CHARPOS, and END_CHARPOS
24475 could be anywhere in the row and in any order. The strategy
24476 below is to find the leftmost and the rightmost glyph that
24477 belongs to either of these 3 strings, or whose position is
24478 between START_CHARPOS and END_CHARPOS, and highlight all the
24479 glyphs between those two. This may cover more than just the text
24480 between START_CHARPOS and END_CHARPOS if the range of characters
24481 strides the bidi level boundary, e.g. if the beginning is in R2L
24482 text while the end is in L2R text or vice versa. */
24483 if (!r1->reversed_p)
24484 {
24485 /* This row is in a left to right paragraph. Scan it left to
24486 right. */
24487 glyph = r1->glyphs[TEXT_AREA];
24488 end = glyph + r1->used[TEXT_AREA];
24489 x = r1->x;
24490
24491 /* Skip truncation glyphs at the start of the glyph row. */
24492 if (r1->displays_text_p)
24493 for (; glyph < end
24494 && INTEGERP (glyph->object)
24495 && glyph->charpos < 0;
24496 ++glyph)
24497 x += glyph->pixel_width;
24498
24499 /* Scan the glyph row, looking for BEFORE_STRING, AFTER_STRING,
24500 or COVER_STRING, and the first glyph from buffer whose
24501 position is between START_CHARPOS and END_CHARPOS. */
24502 for (; glyph < end
24503 && !INTEGERP (glyph->object)
24504 && !EQ (glyph->object, cover_string)
24505 && !(BUFFERP (glyph->object)
24506 && (glyph->charpos >= start_charpos
24507 && glyph->charpos < end_charpos));
24508 ++glyph)
24509 {
24510 /* BEFORE_STRING or AFTER_STRING are only relevant if they
24511 are present at buffer positions between START_CHARPOS and
24512 END_CHARPOS, or if they come from an overlay. */
24513 if (EQ (glyph->object, before_string))
24514 {
24515 pos = string_buffer_position (before_string,
24516 start_charpos);
24517 /* If pos == 0, it means before_string came from an
24518 overlay, not from a buffer position. */
24519 if (!pos || (pos >= start_charpos && pos < end_charpos))
24520 break;
24521 }
24522 else if (EQ (glyph->object, after_string))
24523 {
24524 pos = string_buffer_position (after_string, end_charpos);
24525 if (!pos || (pos >= start_charpos && pos < end_charpos))
24526 break;
24527 }
24528 x += glyph->pixel_width;
24529 }
24530 hlinfo->mouse_face_beg_x = x;
24531 hlinfo->mouse_face_beg_col = glyph - r1->glyphs[TEXT_AREA];
24532 }
24533 else
24534 {
24535 /* This row is in a right to left paragraph. Scan it right to
24536 left. */
24537 struct glyph *g;
24538
24539 end = r1->glyphs[TEXT_AREA] - 1;
24540 glyph = end + r1->used[TEXT_AREA];
24541
24542 /* Skip truncation glyphs at the start of the glyph row. */
24543 if (r1->displays_text_p)
24544 for (; glyph > end
24545 && INTEGERP (glyph->object)
24546 && glyph->charpos < 0;
24547 --glyph)
24548 ;
24549
24550 /* Scan the glyph row, looking for BEFORE_STRING, AFTER_STRING,
24551 or COVER_STRING, and the first glyph from buffer whose
24552 position is between START_CHARPOS and END_CHARPOS. */
24553 for (; glyph > end
24554 && !INTEGERP (glyph->object)
24555 && !EQ (glyph->object, cover_string)
24556 && !(BUFFERP (glyph->object)
24557 && (glyph->charpos >= start_charpos
24558 && glyph->charpos < end_charpos));
24559 --glyph)
24560 {
24561 /* BEFORE_STRING or AFTER_STRING are only relevant if they
24562 are present at buffer positions between START_CHARPOS and
24563 END_CHARPOS, or if they come from an overlay. */
24564 if (EQ (glyph->object, before_string))
24565 {
24566 pos = string_buffer_position (before_string, start_charpos);
24567 /* If pos == 0, it means before_string came from an
24568 overlay, not from a buffer position. */
24569 if (!pos || (pos >= start_charpos && pos < end_charpos))
24570 break;
24571 }
24572 else if (EQ (glyph->object, after_string))
24573 {
24574 pos = string_buffer_position (after_string, end_charpos);
24575 if (!pos || (pos >= start_charpos && pos < end_charpos))
24576 break;
24577 }
24578 }
24579
24580 glyph++; /* first glyph to the right of the highlighted area */
24581 for (g = r1->glyphs[TEXT_AREA], x = r1->x; g < glyph; g++)
24582 x += g->pixel_width;
24583 hlinfo->mouse_face_beg_x = x;
24584 hlinfo->mouse_face_beg_col = glyph - r1->glyphs[TEXT_AREA];
24585 }
24586
24587 /* If the highlight ends in a different row, compute GLYPH and END
24588 for the end row. Otherwise, reuse the values computed above for
24589 the row where the highlight begins. */
24590 if (r2 != r1)
24591 {
24592 if (!r2->reversed_p)
24593 {
24594 glyph = r2->glyphs[TEXT_AREA];
24595 end = glyph + r2->used[TEXT_AREA];
24596 x = r2->x;
24597 }
24598 else
24599 {
24600 end = r2->glyphs[TEXT_AREA] - 1;
24601 glyph = end + r2->used[TEXT_AREA];
24602 }
24603 }
24604
24605 if (!r2->reversed_p)
24606 {
24607 /* Skip truncation and continuation glyphs near the end of the
24608 row, and also blanks and stretch glyphs inserted by
24609 extend_face_to_end_of_line. */
24610 while (end > glyph
24611 && INTEGERP ((end - 1)->object)
24612 && (end - 1)->charpos <= 0)
24613 --end;
24614 /* Scan the rest of the glyph row from the end, looking for the
24615 first glyph that comes from BEFORE_STRING, AFTER_STRING, or
24616 COVER_STRING, or whose position is between START_CHARPOS
24617 and END_CHARPOS */
24618 for (--end;
24619 end > glyph
24620 && !INTEGERP (end->object)
24621 && !EQ (end->object, cover_string)
24622 && !(BUFFERP (end->object)
24623 && (end->charpos >= start_charpos
24624 && end->charpos < end_charpos));
24625 --end)
24626 {
24627 /* BEFORE_STRING or AFTER_STRING are only relevant if they
24628 are present at buffer positions between START_CHARPOS and
24629 END_CHARPOS, or if they come from an overlay. */
24630 if (EQ (end->object, before_string))
24631 {
24632 pos = string_buffer_position (before_string, start_charpos);
24633 if (!pos || (pos >= start_charpos && pos < end_charpos))
24634 break;
24635 }
24636 else if (EQ (end->object, after_string))
24637 {
24638 pos = string_buffer_position (after_string, end_charpos);
24639 if (!pos || (pos >= start_charpos && pos < end_charpos))
24640 break;
24641 }
24642 }
24643 /* Find the X coordinate of the last glyph to be highlighted. */
24644 for (; glyph <= end; ++glyph)
24645 x += glyph->pixel_width;
24646
24647 hlinfo->mouse_face_end_x = x;
24648 hlinfo->mouse_face_end_col = glyph - r2->glyphs[TEXT_AREA];
24649 }
24650 else
24651 {
24652 /* Skip truncation and continuation glyphs near the end of the
24653 row, and also blanks and stretch glyphs inserted by
24654 extend_face_to_end_of_line. */
24655 x = r2->x;
24656 end++;
24657 while (end < glyph
24658 && INTEGERP (end->object)
24659 && end->charpos <= 0)
24660 {
24661 x += end->pixel_width;
24662 ++end;
24663 }
24664 /* Scan the rest of the glyph row from the end, looking for the
24665 first glyph that comes from BEFORE_STRING, AFTER_STRING, or
24666 COVER_STRING, or whose position is between START_CHARPOS
24667 and END_CHARPOS */
24668 for ( ;
24669 end < glyph
24670 && !INTEGERP (end->object)
24671 && !EQ (end->object, cover_string)
24672 && !(BUFFERP (end->object)
24673 && (end->charpos >= start_charpos
24674 && end->charpos < end_charpos));
24675 ++end)
24676 {
24677 /* BEFORE_STRING or AFTER_STRING are only relevant if they
24678 are present at buffer positions between START_CHARPOS and
24679 END_CHARPOS, or if they come from an overlay. */
24680 if (EQ (end->object, before_string))
24681 {
24682 pos = string_buffer_position (before_string, start_charpos);
24683 if (!pos || (pos >= start_charpos && pos < end_charpos))
24684 break;
24685 }
24686 else if (EQ (end->object, after_string))
24687 {
24688 pos = string_buffer_position (after_string, end_charpos);
24689 if (!pos || (pos >= start_charpos && pos < end_charpos))
24690 break;
24691 }
24692 x += end->pixel_width;
24693 }
24694 hlinfo->mouse_face_end_x = x;
24695 hlinfo->mouse_face_end_col = end - r2->glyphs[TEXT_AREA];
24696 }
24697
24698 hlinfo->mouse_face_window = window;
24699 hlinfo->mouse_face_face_id
24700 = face_at_buffer_position (w, mouse_charpos, 0, 0, &ignore,
24701 mouse_charpos + 1,
24702 !hlinfo->mouse_face_hidden, -1);
24703 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
24704 }
24705
24706 /* The following function is not used anymore (replaced with
24707 mouse_face_from_string_pos), but I leave it here for the time
24708 being, in case someone would. */
24709
24710 #if 0 /* not used */
24711
24712 /* Find the position of the glyph for position POS in OBJECT in
24713 window W's current matrix, and return in *X, *Y the pixel
24714 coordinates, and return in *HPOS, *VPOS the column/row of the glyph.
24715
24716 RIGHT_P non-zero means return the position of the right edge of the
24717 glyph, RIGHT_P zero means return the left edge position.
24718
24719 If no glyph for POS exists in the matrix, return the position of
24720 the glyph with the next smaller position that is in the matrix, if
24721 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS
24722 exists in the matrix, return the position of the glyph with the
24723 next larger position in OBJECT.
24724
24725 Value is non-zero if a glyph was found. */
24726
24727 static int
24728 fast_find_string_pos (struct window *w, EMACS_INT pos, Lisp_Object object,
24729 int *hpos, int *vpos, int *x, int *y, int right_p)
24730 {
24731 int yb = window_text_bottom_y (w);
24732 struct glyph_row *r;
24733 struct glyph *best_glyph = NULL;
24734 struct glyph_row *best_row = NULL;
24735 int best_x = 0;
24736
24737 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
24738 r->enabled_p && r->y < yb;
24739 ++r)
24740 {
24741 struct glyph *g = r->glyphs[TEXT_AREA];
24742 struct glyph *e = g + r->used[TEXT_AREA];
24743 int gx;
24744
24745 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
24746 if (EQ (g->object, object))
24747 {
24748 if (g->charpos == pos)
24749 {
24750 best_glyph = g;
24751 best_x = gx;
24752 best_row = r;
24753 goto found;
24754 }
24755 else if (best_glyph == NULL
24756 || ((eabs (g->charpos - pos)
24757 < eabs (best_glyph->charpos - pos))
24758 && (right_p
24759 ? g->charpos < pos
24760 : g->charpos > pos)))
24761 {
24762 best_glyph = g;
24763 best_x = gx;
24764 best_row = r;
24765 }
24766 }
24767 }
24768
24769 found:
24770
24771 if (best_glyph)
24772 {
24773 *x = best_x;
24774 *hpos = best_glyph - best_row->glyphs[TEXT_AREA];
24775
24776 if (right_p)
24777 {
24778 *x += best_glyph->pixel_width;
24779 ++*hpos;
24780 }
24781
24782 *y = best_row->y;
24783 *vpos = best_row - w->current_matrix->rows;
24784 }
24785
24786 return best_glyph != NULL;
24787 }
24788 #endif /* not used */
24789
24790 /* Find the positions of the first and the last glyphs in window W's
24791 current matrix that occlude positions [STARTPOS..ENDPOS] in OBJECT
24792 (assumed to be a string), and return in HLINFO's mouse_face_*
24793 members the pixel and column/row coordinates of those glyphs. */
24794
24795 static void
24796 mouse_face_from_string_pos (struct window *w, Mouse_HLInfo *hlinfo,
24797 Lisp_Object object,
24798 EMACS_INT startpos, EMACS_INT endpos)
24799 {
24800 int yb = window_text_bottom_y (w);
24801 struct glyph_row *r;
24802 struct glyph *g, *e;
24803 int gx;
24804 int found = 0;
24805
24806 /* Find the glyph row with at least one position in the range
24807 [STARTPOS..ENDPOS], and the first glyph in that row whose
24808 position belongs to that range. */
24809 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
24810 r->enabled_p && r->y < yb;
24811 ++r)
24812 {
24813 if (!r->reversed_p)
24814 {
24815 g = r->glyphs[TEXT_AREA];
24816 e = g + r->used[TEXT_AREA];
24817 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
24818 if (EQ (g->object, object)
24819 && startpos <= g->charpos && g->charpos <= endpos)
24820 {
24821 hlinfo->mouse_face_beg_row = r - w->current_matrix->rows;
24822 hlinfo->mouse_face_beg_y = r->y;
24823 hlinfo->mouse_face_beg_col = g - r->glyphs[TEXT_AREA];
24824 hlinfo->mouse_face_beg_x = gx;
24825 found = 1;
24826 break;
24827 }
24828 }
24829 else
24830 {
24831 struct glyph *g1;
24832
24833 e = r->glyphs[TEXT_AREA];
24834 g = e + r->used[TEXT_AREA];
24835 for ( ; g > e; --g)
24836 if (EQ ((g-1)->object, object)
24837 && startpos <= (g-1)->charpos && (g-1)->charpos <= endpos)
24838 {
24839 hlinfo->mouse_face_beg_row = r - w->current_matrix->rows;
24840 hlinfo->mouse_face_beg_y = r->y;
24841 hlinfo->mouse_face_beg_col = g - r->glyphs[TEXT_AREA];
24842 for (gx = r->x, g1 = r->glyphs[TEXT_AREA]; g1 < g; ++g1)
24843 gx += g1->pixel_width;
24844 hlinfo->mouse_face_beg_x = gx;
24845 found = 1;
24846 break;
24847 }
24848 }
24849 if (found)
24850 break;
24851 }
24852
24853 if (!found)
24854 return;
24855
24856 /* Starting with the next row, look for the first row which does NOT
24857 include any glyphs whose positions are in the range. */
24858 for (++r; r->enabled_p && r->y < yb; ++r)
24859 {
24860 g = r->glyphs[TEXT_AREA];
24861 e = g + r->used[TEXT_AREA];
24862 found = 0;
24863 for ( ; g < e; ++g)
24864 if (EQ (g->object, object)
24865 && startpos <= g->charpos && g->charpos <= endpos)
24866 {
24867 found = 1;
24868 break;
24869 }
24870 if (!found)
24871 break;
24872 }
24873
24874 /* The highlighted region ends on the previous row. */
24875 r--;
24876
24877 /* Set the end row and its vertical pixel coordinate. */
24878 hlinfo->mouse_face_end_row = r - w->current_matrix->rows;
24879 hlinfo->mouse_face_end_y = r->y;
24880
24881 /* Compute and set the end column and the end column's horizontal
24882 pixel coordinate. */
24883 if (!r->reversed_p)
24884 {
24885 g = r->glyphs[TEXT_AREA];
24886 e = g + r->used[TEXT_AREA];
24887 for ( ; e > g; --e)
24888 if (EQ ((e-1)->object, object)
24889 && startpos <= (e-1)->charpos && (e-1)->charpos <= endpos)
24890 break;
24891 hlinfo->mouse_face_end_col = e - g;
24892
24893 for (gx = r->x; g < e; ++g)
24894 gx += g->pixel_width;
24895 hlinfo->mouse_face_end_x = gx;
24896 }
24897 else
24898 {
24899 e = r->glyphs[TEXT_AREA];
24900 g = e + r->used[TEXT_AREA];
24901 for (gx = r->x ; e < g; ++e)
24902 {
24903 if (EQ (e->object, object)
24904 && startpos <= e->charpos && e->charpos <= endpos)
24905 break;
24906 gx += e->pixel_width;
24907 }
24908 hlinfo->mouse_face_end_col = e - r->glyphs[TEXT_AREA];
24909 hlinfo->mouse_face_end_x = gx;
24910 }
24911 }
24912
24913 #ifdef HAVE_WINDOW_SYSTEM
24914
24915 /* See if position X, Y is within a hot-spot of an image. */
24916
24917 static int
24918 on_hot_spot_p (Lisp_Object hot_spot, int x, int y)
24919 {
24920 if (!CONSP (hot_spot))
24921 return 0;
24922
24923 if (EQ (XCAR (hot_spot), Qrect))
24924 {
24925 /* CDR is (Top-Left . Bottom-Right) = ((x0 . y0) . (x1 . y1)) */
24926 Lisp_Object rect = XCDR (hot_spot);
24927 Lisp_Object tem;
24928 if (!CONSP (rect))
24929 return 0;
24930 if (!CONSP (XCAR (rect)))
24931 return 0;
24932 if (!CONSP (XCDR (rect)))
24933 return 0;
24934 if (!(tem = XCAR (XCAR (rect)), INTEGERP (tem) && x >= XINT (tem)))
24935 return 0;
24936 if (!(tem = XCDR (XCAR (rect)), INTEGERP (tem) && y >= XINT (tem)))
24937 return 0;
24938 if (!(tem = XCAR (XCDR (rect)), INTEGERP (tem) && x <= XINT (tem)))
24939 return 0;
24940 if (!(tem = XCDR (XCDR (rect)), INTEGERP (tem) && y <= XINT (tem)))
24941 return 0;
24942 return 1;
24943 }
24944 else if (EQ (XCAR (hot_spot), Qcircle))
24945 {
24946 /* CDR is (Center . Radius) = ((x0 . y0) . r) */
24947 Lisp_Object circ = XCDR (hot_spot);
24948 Lisp_Object lr, lx0, ly0;
24949 if (CONSP (circ)
24950 && CONSP (XCAR (circ))
24951 && (lr = XCDR (circ), INTEGERP (lr) || FLOATP (lr))
24952 && (lx0 = XCAR (XCAR (circ)), INTEGERP (lx0))
24953 && (ly0 = XCDR (XCAR (circ)), INTEGERP (ly0)))
24954 {
24955 double r = XFLOATINT (lr);
24956 double dx = XINT (lx0) - x;
24957 double dy = XINT (ly0) - y;
24958 return (dx * dx + dy * dy <= r * r);
24959 }
24960 }
24961 else if (EQ (XCAR (hot_spot), Qpoly))
24962 {
24963 /* CDR is [x0 y0 x1 y1 x2 y2 ...x(n-1) y(n-1)] */
24964 if (VECTORP (XCDR (hot_spot)))
24965 {
24966 struct Lisp_Vector *v = XVECTOR (XCDR (hot_spot));
24967 Lisp_Object *poly = v->contents;
24968 int n = v->header.size;
24969 int i;
24970 int inside = 0;
24971 Lisp_Object lx, ly;
24972 int x0, y0;
24973
24974 /* Need an even number of coordinates, and at least 3 edges. */
24975 if (n < 6 || n & 1)
24976 return 0;
24977
24978 /* Count edge segments intersecting line from (X,Y) to (X,infinity).
24979 If count is odd, we are inside polygon. Pixels on edges
24980 may or may not be included depending on actual geometry of the
24981 polygon. */
24982 if ((lx = poly[n-2], !INTEGERP (lx))
24983 || (ly = poly[n-1], !INTEGERP (lx)))
24984 return 0;
24985 x0 = XINT (lx), y0 = XINT (ly);
24986 for (i = 0; i < n; i += 2)
24987 {
24988 int x1 = x0, y1 = y0;
24989 if ((lx = poly[i], !INTEGERP (lx))
24990 || (ly = poly[i+1], !INTEGERP (ly)))
24991 return 0;
24992 x0 = XINT (lx), y0 = XINT (ly);
24993
24994 /* Does this segment cross the X line? */
24995 if (x0 >= x)
24996 {
24997 if (x1 >= x)
24998 continue;
24999 }
25000 else if (x1 < x)
25001 continue;
25002 if (y > y0 && y > y1)
25003 continue;
25004 if (y < y0 + ((y1 - y0) * (x - x0)) / (x1 - x0))
25005 inside = !inside;
25006 }
25007 return inside;
25008 }
25009 }
25010 return 0;
25011 }
25012
25013 Lisp_Object
25014 find_hot_spot (Lisp_Object map, int x, int y)
25015 {
25016 while (CONSP (map))
25017 {
25018 if (CONSP (XCAR (map))
25019 && on_hot_spot_p (XCAR (XCAR (map)), x, y))
25020 return XCAR (map);
25021 map = XCDR (map);
25022 }
25023
25024 return Qnil;
25025 }
25026
25027 DEFUN ("lookup-image-map", Flookup_image_map, Slookup_image_map,
25028 3, 3, 0,
25029 doc: /* Lookup in image map MAP coordinates X and Y.
25030 An image map is an alist where each element has the format (AREA ID PLIST).
25031 An AREA is specified as either a rectangle, a circle, or a polygon:
25032 A rectangle is a cons (rect . ((x0 . y0) . (x1 . y1))) specifying the
25033 pixel coordinates of the upper left and bottom right corners.
25034 A circle is a cons (circle . ((x0 . y0) . r)) specifying the center
25035 and the radius of the circle; r may be a float or integer.
25036 A polygon is a cons (poly . [x0 y0 x1 y1 ...]) where each pair in the
25037 vector describes one corner in the polygon.
25038 Returns the alist element for the first matching AREA in MAP. */)
25039 (Lisp_Object map, Lisp_Object x, Lisp_Object y)
25040 {
25041 if (NILP (map))
25042 return Qnil;
25043
25044 CHECK_NUMBER (x);
25045 CHECK_NUMBER (y);
25046
25047 return find_hot_spot (map, XINT (x), XINT (y));
25048 }
25049
25050
25051 /* Display frame CURSOR, optionally using shape defined by POINTER. */
25052 static void
25053 define_frame_cursor1 (struct frame *f, Cursor cursor, Lisp_Object pointer)
25054 {
25055 /* Do not change cursor shape while dragging mouse. */
25056 if (!NILP (do_mouse_tracking))
25057 return;
25058
25059 if (!NILP (pointer))
25060 {
25061 if (EQ (pointer, Qarrow))
25062 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
25063 else if (EQ (pointer, Qhand))
25064 cursor = FRAME_X_OUTPUT (f)->hand_cursor;
25065 else if (EQ (pointer, Qtext))
25066 cursor = FRAME_X_OUTPUT (f)->text_cursor;
25067 else if (EQ (pointer, intern ("hdrag")))
25068 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
25069 #ifdef HAVE_X_WINDOWS
25070 else if (EQ (pointer, intern ("vdrag")))
25071 cursor = FRAME_X_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
25072 #endif
25073 else if (EQ (pointer, intern ("hourglass")))
25074 cursor = FRAME_X_OUTPUT (f)->hourglass_cursor;
25075 else if (EQ (pointer, Qmodeline))
25076 cursor = FRAME_X_OUTPUT (f)->modeline_cursor;
25077 else
25078 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
25079 }
25080
25081 if (cursor != No_Cursor)
25082 FRAME_RIF (f)->define_frame_cursor (f, cursor);
25083 }
25084
25085 #endif /* HAVE_WINDOW_SYSTEM */
25086
25087 /* Take proper action when mouse has moved to the mode or header line
25088 or marginal area AREA of window W, x-position X and y-position Y.
25089 X is relative to the start of the text display area of W, so the
25090 width of bitmap areas and scroll bars must be subtracted to get a
25091 position relative to the start of the mode line. */
25092
25093 static void
25094 note_mode_line_or_margin_highlight (Lisp_Object window, int x, int y,
25095 enum window_part area)
25096 {
25097 struct window *w = XWINDOW (window);
25098 struct frame *f = XFRAME (w->frame);
25099 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
25100 #ifdef HAVE_WINDOW_SYSTEM
25101 Display_Info *dpyinfo;
25102 #endif
25103 Cursor cursor = No_Cursor;
25104 Lisp_Object pointer = Qnil;
25105 int dx, dy, width, height;
25106 EMACS_INT charpos;
25107 Lisp_Object string, object = Qnil;
25108 Lisp_Object pos, help;
25109
25110 Lisp_Object mouse_face;
25111 int original_x_pixel = x;
25112 struct glyph * glyph = NULL, * row_start_glyph = NULL;
25113 struct glyph_row *row;
25114
25115 if (area == ON_MODE_LINE || area == ON_HEADER_LINE)
25116 {
25117 int x0;
25118 struct glyph *end;
25119
25120 /* Kludge alert: mode_line_string takes X/Y in pixels, but
25121 returns them in row/column units! */
25122 string = mode_line_string (w, area, &x, &y, &charpos,
25123 &object, &dx, &dy, &width, &height);
25124
25125 row = (area == ON_MODE_LINE
25126 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
25127 : MATRIX_HEADER_LINE_ROW (w->current_matrix));
25128
25129 /* Find the glyph under the mouse pointer. */
25130 if (row->mode_line_p && row->enabled_p)
25131 {
25132 glyph = row_start_glyph = row->glyphs[TEXT_AREA];
25133 end = glyph + row->used[TEXT_AREA];
25134
25135 for (x0 = original_x_pixel;
25136 glyph < end && x0 >= glyph->pixel_width;
25137 ++glyph)
25138 x0 -= glyph->pixel_width;
25139
25140 if (glyph >= end)
25141 glyph = NULL;
25142 }
25143 }
25144 else
25145 {
25146 x -= WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
25147 /* Kludge alert: marginal_area_string takes X/Y in pixels, but
25148 returns them in row/column units! */
25149 string = marginal_area_string (w, area, &x, &y, &charpos,
25150 &object, &dx, &dy, &width, &height);
25151 }
25152
25153 help = Qnil;
25154
25155 #ifdef HAVE_WINDOW_SYSTEM
25156 if (IMAGEP (object))
25157 {
25158 Lisp_Object image_map, hotspot;
25159 if ((image_map = Fplist_get (XCDR (object), QCmap),
25160 !NILP (image_map))
25161 && (hotspot = find_hot_spot (image_map, dx, dy),
25162 CONSP (hotspot))
25163 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
25164 {
25165 Lisp_Object plist;
25166
25167 /* Could check XCAR (hotspot) to see if we enter/leave this hot-spot.
25168 If so, we could look for mouse-enter, mouse-leave
25169 properties in PLIST (and do something...). */
25170 hotspot = XCDR (hotspot);
25171 if (CONSP (hotspot)
25172 && (plist = XCAR (hotspot), CONSP (plist)))
25173 {
25174 pointer = Fplist_get (plist, Qpointer);
25175 if (NILP (pointer))
25176 pointer = Qhand;
25177 help = Fplist_get (plist, Qhelp_echo);
25178 if (!NILP (help))
25179 {
25180 help_echo_string = help;
25181 /* Is this correct? ++kfs */
25182 XSETWINDOW (help_echo_window, w);
25183 help_echo_object = w->buffer;
25184 help_echo_pos = charpos;
25185 }
25186 }
25187 }
25188 if (NILP (pointer))
25189 pointer = Fplist_get (XCDR (object), QCpointer);
25190 }
25191 #endif /* HAVE_WINDOW_SYSTEM */
25192
25193 if (STRINGP (string))
25194 {
25195 pos = make_number (charpos);
25196 /* If we're on a string with `help-echo' text property, arrange
25197 for the help to be displayed. This is done by setting the
25198 global variable help_echo_string to the help string. */
25199 if (NILP (help))
25200 {
25201 help = Fget_text_property (pos, Qhelp_echo, string);
25202 if (!NILP (help))
25203 {
25204 help_echo_string = help;
25205 XSETWINDOW (help_echo_window, w);
25206 help_echo_object = string;
25207 help_echo_pos = charpos;
25208 }
25209 }
25210
25211 #ifdef HAVE_WINDOW_SYSTEM
25212 if (FRAME_WINDOW_P (f))
25213 {
25214 dpyinfo = FRAME_X_DISPLAY_INFO (f);
25215 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
25216 if (NILP (pointer))
25217 pointer = Fget_text_property (pos, Qpointer, string);
25218
25219 /* Change the mouse pointer according to what is under X/Y. */
25220 if (NILP (pointer)
25221 && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE)))
25222 {
25223 Lisp_Object map;
25224 map = Fget_text_property (pos, Qlocal_map, string);
25225 if (!KEYMAPP (map))
25226 map = Fget_text_property (pos, Qkeymap, string);
25227 if (!KEYMAPP (map))
25228 cursor = dpyinfo->vertical_scroll_bar_cursor;
25229 }
25230 }
25231 #endif
25232
25233 /* Change the mouse face according to what is under X/Y. */
25234 mouse_face = Fget_text_property (pos, Qmouse_face, string);
25235 if (!NILP (mouse_face)
25236 && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE))
25237 && glyph)
25238 {
25239 Lisp_Object b, e;
25240
25241 struct glyph * tmp_glyph;
25242
25243 int gpos;
25244 int gseq_length;
25245 int total_pixel_width;
25246 EMACS_INT begpos, endpos, ignore;
25247
25248 int vpos, hpos;
25249
25250 b = Fprevious_single_property_change (make_number (charpos + 1),
25251 Qmouse_face, string, Qnil);
25252 if (NILP (b))
25253 begpos = 0;
25254 else
25255 begpos = XINT (b);
25256
25257 e = Fnext_single_property_change (pos, Qmouse_face, string, Qnil);
25258 if (NILP (e))
25259 endpos = SCHARS (string);
25260 else
25261 endpos = XINT (e);
25262
25263 /* Calculate the glyph position GPOS of GLYPH in the
25264 displayed string, relative to the beginning of the
25265 highlighted part of the string.
25266
25267 Note: GPOS is different from CHARPOS. CHARPOS is the
25268 position of GLYPH in the internal string object. A mode
25269 line string format has structures which are converted to
25270 a flattened string by the Emacs Lisp interpreter. The
25271 internal string is an element of those structures. The
25272 displayed string is the flattened string. */
25273 tmp_glyph = row_start_glyph;
25274 while (tmp_glyph < glyph
25275 && (!(EQ (tmp_glyph->object, glyph->object)
25276 && begpos <= tmp_glyph->charpos
25277 && tmp_glyph->charpos < endpos)))
25278 tmp_glyph++;
25279 gpos = glyph - tmp_glyph;
25280
25281 /* Calculate the length GSEQ_LENGTH of the glyph sequence of
25282 the highlighted part of the displayed string to which
25283 GLYPH belongs. Note: GSEQ_LENGTH is different from
25284 SCHARS (STRING), because the latter returns the length of
25285 the internal string. */
25286 for (tmp_glyph = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
25287 tmp_glyph > glyph
25288 && (!(EQ (tmp_glyph->object, glyph->object)
25289 && begpos <= tmp_glyph->charpos
25290 && tmp_glyph->charpos < endpos));
25291 tmp_glyph--)
25292 ;
25293 gseq_length = gpos + (tmp_glyph - glyph) + 1;
25294
25295 /* Calculate the total pixel width of all the glyphs between
25296 the beginning of the highlighted area and GLYPH. */
25297 total_pixel_width = 0;
25298 for (tmp_glyph = glyph - gpos; tmp_glyph != glyph; tmp_glyph++)
25299 total_pixel_width += tmp_glyph->pixel_width;
25300
25301 /* Pre calculation of re-rendering position. Note: X is in
25302 column units here, after the call to mode_line_string or
25303 marginal_area_string. */
25304 hpos = x - gpos;
25305 vpos = (area == ON_MODE_LINE
25306 ? (w->current_matrix)->nrows - 1
25307 : 0);
25308
25309 /* If GLYPH's position is included in the region that is
25310 already drawn in mouse face, we have nothing to do. */
25311 if ( EQ (window, hlinfo->mouse_face_window)
25312 && (!row->reversed_p
25313 ? (hlinfo->mouse_face_beg_col <= hpos
25314 && hpos < hlinfo->mouse_face_end_col)
25315 /* In R2L rows we swap BEG and END, see below. */
25316 : (hlinfo->mouse_face_end_col <= hpos
25317 && hpos < hlinfo->mouse_face_beg_col))
25318 && hlinfo->mouse_face_beg_row == vpos )
25319 return;
25320
25321 if (clear_mouse_face (hlinfo))
25322 cursor = No_Cursor;
25323
25324 if (!row->reversed_p)
25325 {
25326 hlinfo->mouse_face_beg_col = hpos;
25327 hlinfo->mouse_face_beg_x = original_x_pixel
25328 - (total_pixel_width + dx);
25329 hlinfo->mouse_face_end_col = hpos + gseq_length;
25330 hlinfo->mouse_face_end_x = 0;
25331 }
25332 else
25333 {
25334 /* In R2L rows, show_mouse_face expects BEG and END
25335 coordinates to be swapped. */
25336 hlinfo->mouse_face_end_col = hpos;
25337 hlinfo->mouse_face_end_x = original_x_pixel
25338 - (total_pixel_width + dx);
25339 hlinfo->mouse_face_beg_col = hpos + gseq_length;
25340 hlinfo->mouse_face_beg_x = 0;
25341 }
25342
25343 hlinfo->mouse_face_beg_row = vpos;
25344 hlinfo->mouse_face_end_row = hlinfo->mouse_face_beg_row;
25345 hlinfo->mouse_face_beg_y = 0;
25346 hlinfo->mouse_face_end_y = 0;
25347 hlinfo->mouse_face_past_end = 0;
25348 hlinfo->mouse_face_window = window;
25349
25350 hlinfo->mouse_face_face_id = face_at_string_position (w, string,
25351 charpos,
25352 0, 0, 0,
25353 &ignore,
25354 glyph->face_id,
25355 1);
25356 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
25357
25358 if (NILP (pointer))
25359 pointer = Qhand;
25360 }
25361 else if ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE))
25362 clear_mouse_face (hlinfo);
25363 }
25364 #ifdef HAVE_WINDOW_SYSTEM
25365 if (FRAME_WINDOW_P (f))
25366 define_frame_cursor1 (f, cursor, pointer);
25367 #endif
25368 }
25369
25370
25371 /* EXPORT:
25372 Take proper action when the mouse has moved to position X, Y on
25373 frame F as regards highlighting characters that have mouse-face
25374 properties. Also de-highlighting chars where the mouse was before.
25375 X and Y can be negative or out of range. */
25376
25377 void
25378 note_mouse_highlight (struct frame *f, int x, int y)
25379 {
25380 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
25381 enum window_part part;
25382 Lisp_Object window;
25383 struct window *w;
25384 Cursor cursor = No_Cursor;
25385 Lisp_Object pointer = Qnil; /* Takes precedence over cursor! */
25386 struct buffer *b;
25387
25388 /* When a menu is active, don't highlight because this looks odd. */
25389 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS) || defined (MSDOS)
25390 if (popup_activated ())
25391 return;
25392 #endif
25393
25394 if (NILP (Vmouse_highlight)
25395 || !f->glyphs_initialized_p
25396 || f->pointer_invisible)
25397 return;
25398
25399 hlinfo->mouse_face_mouse_x = x;
25400 hlinfo->mouse_face_mouse_y = y;
25401 hlinfo->mouse_face_mouse_frame = f;
25402
25403 if (hlinfo->mouse_face_defer)
25404 return;
25405
25406 if (gc_in_progress)
25407 {
25408 hlinfo->mouse_face_deferred_gc = 1;
25409 return;
25410 }
25411
25412 /* Which window is that in? */
25413 window = window_from_coordinates (f, x, y, &part, 1);
25414
25415 /* If we were displaying active text in another window, clear that.
25416 Also clear if we move out of text area in same window. */
25417 if (! EQ (window, hlinfo->mouse_face_window)
25418 || (part != ON_TEXT && part != ON_MODE_LINE && part != ON_HEADER_LINE
25419 && !NILP (hlinfo->mouse_face_window)))
25420 clear_mouse_face (hlinfo);
25421
25422 /* Not on a window -> return. */
25423 if (!WINDOWP (window))
25424 return;
25425
25426 /* Reset help_echo_string. It will get recomputed below. */
25427 help_echo_string = Qnil;
25428
25429 /* Convert to window-relative pixel coordinates. */
25430 w = XWINDOW (window);
25431 frame_to_window_pixel_xy (w, &x, &y);
25432
25433 #ifdef HAVE_WINDOW_SYSTEM
25434 /* Handle tool-bar window differently since it doesn't display a
25435 buffer. */
25436 if (EQ (window, f->tool_bar_window))
25437 {
25438 note_tool_bar_highlight (f, x, y);
25439 return;
25440 }
25441 #endif
25442
25443 /* Mouse is on the mode, header line or margin? */
25444 if (part == ON_MODE_LINE || part == ON_HEADER_LINE
25445 || part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
25446 {
25447 note_mode_line_or_margin_highlight (window, x, y, part);
25448 return;
25449 }
25450
25451 #ifdef HAVE_WINDOW_SYSTEM
25452 if (part == ON_VERTICAL_BORDER)
25453 {
25454 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
25455 help_echo_string = build_string ("drag-mouse-1: resize");
25456 }
25457 else if (part == ON_LEFT_FRINGE || part == ON_RIGHT_FRINGE
25458 || part == ON_SCROLL_BAR)
25459 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
25460 else
25461 cursor = FRAME_X_OUTPUT (f)->text_cursor;
25462 #endif
25463
25464 /* Are we in a window whose display is up to date?
25465 And verify the buffer's text has not changed. */
25466 b = XBUFFER (w->buffer);
25467 if (part == ON_TEXT
25468 && EQ (w->window_end_valid, w->buffer)
25469 && XFASTINT (w->last_modified) == BUF_MODIFF (b)
25470 && XFASTINT (w->last_overlay_modified) == BUF_OVERLAY_MODIFF (b))
25471 {
25472 int hpos, vpos, i, dx, dy, area;
25473 EMACS_INT pos;
25474 struct glyph *glyph;
25475 Lisp_Object object;
25476 Lisp_Object mouse_face = Qnil, position;
25477 Lisp_Object *overlay_vec = NULL;
25478 int noverlays;
25479 struct buffer *obuf;
25480 EMACS_INT obegv, ozv;
25481 int same_region;
25482
25483 /* Find the glyph under X/Y. */
25484 glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, &dx, &dy, &area);
25485
25486 #ifdef HAVE_WINDOW_SYSTEM
25487 /* Look for :pointer property on image. */
25488 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
25489 {
25490 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
25491 if (img != NULL && IMAGEP (img->spec))
25492 {
25493 Lisp_Object image_map, hotspot;
25494 if ((image_map = Fplist_get (XCDR (img->spec), QCmap),
25495 !NILP (image_map))
25496 && (hotspot = find_hot_spot (image_map,
25497 glyph->slice.img.x + dx,
25498 glyph->slice.img.y + dy),
25499 CONSP (hotspot))
25500 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
25501 {
25502 Lisp_Object plist;
25503
25504 /* Could check XCAR (hotspot) to see if we enter/leave
25505 this hot-spot.
25506 If so, we could look for mouse-enter, mouse-leave
25507 properties in PLIST (and do something...). */
25508 hotspot = XCDR (hotspot);
25509 if (CONSP (hotspot)
25510 && (plist = XCAR (hotspot), CONSP (plist)))
25511 {
25512 pointer = Fplist_get (plist, Qpointer);
25513 if (NILP (pointer))
25514 pointer = Qhand;
25515 help_echo_string = Fplist_get (plist, Qhelp_echo);
25516 if (!NILP (help_echo_string))
25517 {
25518 help_echo_window = window;
25519 help_echo_object = glyph->object;
25520 help_echo_pos = glyph->charpos;
25521 }
25522 }
25523 }
25524 if (NILP (pointer))
25525 pointer = Fplist_get (XCDR (img->spec), QCpointer);
25526 }
25527 }
25528 #endif /* HAVE_WINDOW_SYSTEM */
25529
25530 /* Clear mouse face if X/Y not over text. */
25531 if (glyph == NULL
25532 || area != TEXT_AREA
25533 || !MATRIX_ROW (w->current_matrix, vpos)->displays_text_p
25534 /* Glyph's OBJECT is an integer for glyphs inserted by the
25535 display engine for its internal purposes, like truncation
25536 and continuation glyphs and blanks beyond the end of
25537 line's text on text terminals. If we are over such a
25538 glyph, we are not over any text. */
25539 || INTEGERP (glyph->object)
25540 /* R2L rows have a stretch glyph at their front, which
25541 stands for no text, whereas L2R rows have no glyphs at
25542 all beyond the end of text. Treat such stretch glyphs
25543 like we do with NULL glyphs in L2R rows. */
25544 || (MATRIX_ROW (w->current_matrix, vpos)->reversed_p
25545 && glyph == MATRIX_ROW (w->current_matrix, vpos)->glyphs[TEXT_AREA]
25546 && glyph->type == STRETCH_GLYPH
25547 && glyph->avoid_cursor_p))
25548 {
25549 if (clear_mouse_face (hlinfo))
25550 cursor = No_Cursor;
25551 #ifdef HAVE_WINDOW_SYSTEM
25552 if (FRAME_WINDOW_P (f) && NILP (pointer))
25553 {
25554 if (area != TEXT_AREA)
25555 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
25556 else
25557 pointer = Vvoid_text_area_pointer;
25558 }
25559 #endif
25560 goto set_cursor;
25561 }
25562
25563 pos = glyph->charpos;
25564 object = glyph->object;
25565 if (!STRINGP (object) && !BUFFERP (object))
25566 goto set_cursor;
25567
25568 /* If we get an out-of-range value, return now; avoid an error. */
25569 if (BUFFERP (object) && pos > BUF_Z (b))
25570 goto set_cursor;
25571
25572 /* Make the window's buffer temporarily current for
25573 overlays_at and compute_char_face. */
25574 obuf = current_buffer;
25575 current_buffer = b;
25576 obegv = BEGV;
25577 ozv = ZV;
25578 BEGV = BEG;
25579 ZV = Z;
25580
25581 /* Is this char mouse-active or does it have help-echo? */
25582 position = make_number (pos);
25583
25584 if (BUFFERP (object))
25585 {
25586 /* Put all the overlays we want in a vector in overlay_vec. */
25587 GET_OVERLAYS_AT (pos, overlay_vec, noverlays, NULL, 0);
25588 /* Sort overlays into increasing priority order. */
25589 noverlays = sort_overlays (overlay_vec, noverlays, w);
25590 }
25591 else
25592 noverlays = 0;
25593
25594 same_region = coords_in_mouse_face_p (w, hpos, vpos);
25595
25596 if (same_region)
25597 cursor = No_Cursor;
25598
25599 /* Check mouse-face highlighting. */
25600 if (! same_region
25601 /* If there exists an overlay with mouse-face overlapping
25602 the one we are currently highlighting, we have to
25603 check if we enter the overlapping overlay, and then
25604 highlight only that. */
25605 || (OVERLAYP (hlinfo->mouse_face_overlay)
25606 && mouse_face_overlay_overlaps (hlinfo->mouse_face_overlay)))
25607 {
25608 /* Find the highest priority overlay with a mouse-face. */
25609 Lisp_Object overlay = Qnil;
25610 for (i = noverlays - 1; i >= 0 && NILP (overlay); --i)
25611 {
25612 mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face);
25613 if (!NILP (mouse_face))
25614 overlay = overlay_vec[i];
25615 }
25616
25617 /* If we're highlighting the same overlay as before, there's
25618 no need to do that again. */
25619 if (!NILP (overlay) && EQ (overlay, hlinfo->mouse_face_overlay))
25620 goto check_help_echo;
25621 hlinfo->mouse_face_overlay = overlay;
25622
25623 /* Clear the display of the old active region, if any. */
25624 if (clear_mouse_face (hlinfo))
25625 cursor = No_Cursor;
25626
25627 /* If no overlay applies, get a text property. */
25628 if (NILP (overlay))
25629 mouse_face = Fget_text_property (position, Qmouse_face, object);
25630
25631 /* Next, compute the bounds of the mouse highlighting and
25632 display it. */
25633 if (!NILP (mouse_face) && STRINGP (object))
25634 {
25635 /* The mouse-highlighting comes from a display string
25636 with a mouse-face. */
25637 Lisp_Object s, e;
25638 EMACS_INT ignore;
25639
25640 s = Fprevious_single_property_change
25641 (make_number (pos + 1), Qmouse_face, object, Qnil);
25642 e = Fnext_single_property_change
25643 (position, Qmouse_face, object, Qnil);
25644 if (NILP (s))
25645 s = make_number (0);
25646 if (NILP (e))
25647 e = make_number (SCHARS (object) - 1);
25648 mouse_face_from_string_pos (w, hlinfo, object,
25649 XINT (s), XINT (e));
25650 hlinfo->mouse_face_past_end = 0;
25651 hlinfo->mouse_face_window = window;
25652 hlinfo->mouse_face_face_id
25653 = face_at_string_position (w, object, pos, 0, 0, 0, &ignore,
25654 glyph->face_id, 1);
25655 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
25656 cursor = No_Cursor;
25657 }
25658 else
25659 {
25660 /* The mouse-highlighting, if any, comes from an overlay
25661 or text property in the buffer. */
25662 Lisp_Object buffer IF_LINT (= Qnil);
25663 Lisp_Object cover_string IF_LINT (= Qnil);
25664
25665 if (STRINGP (object))
25666 {
25667 /* If we are on a display string with no mouse-face,
25668 check if the text under it has one. */
25669 struct glyph_row *r = MATRIX_ROW (w->current_matrix, vpos);
25670 EMACS_INT start = MATRIX_ROW_START_CHARPOS (r);
25671 pos = string_buffer_position (object, start);
25672 if (pos > 0)
25673 {
25674 mouse_face = get_char_property_and_overlay
25675 (make_number (pos), Qmouse_face, w->buffer, &overlay);
25676 buffer = w->buffer;
25677 cover_string = object;
25678 }
25679 }
25680 else
25681 {
25682 buffer = object;
25683 cover_string = Qnil;
25684 }
25685
25686 if (!NILP (mouse_face))
25687 {
25688 Lisp_Object before, after;
25689 Lisp_Object before_string, after_string;
25690 /* To correctly find the limits of mouse highlight
25691 in a bidi-reordered buffer, we must not use the
25692 optimization of limiting the search in
25693 previous-single-property-change and
25694 next-single-property-change, because
25695 rows_from_pos_range needs the real start and end
25696 positions to DTRT in this case. That's because
25697 the first row visible in a window does not
25698 necessarily display the character whose position
25699 is the smallest. */
25700 Lisp_Object lim1 =
25701 NILP (BVAR (XBUFFER (buffer), bidi_display_reordering))
25702 ? Fmarker_position (w->start)
25703 : Qnil;
25704 Lisp_Object lim2 =
25705 NILP (BVAR (XBUFFER (buffer), bidi_display_reordering))
25706 ? make_number (BUF_Z (XBUFFER (buffer))
25707 - XFASTINT (w->window_end_pos))
25708 : Qnil;
25709
25710 if (NILP (overlay))
25711 {
25712 /* Handle the text property case. */
25713 before = Fprevious_single_property_change
25714 (make_number (pos + 1), Qmouse_face, buffer, lim1);
25715 after = Fnext_single_property_change
25716 (make_number (pos), Qmouse_face, buffer, lim2);
25717 before_string = after_string = Qnil;
25718 }
25719 else
25720 {
25721 /* Handle the overlay case. */
25722 before = Foverlay_start (overlay);
25723 after = Foverlay_end (overlay);
25724 before_string = Foverlay_get (overlay, Qbefore_string);
25725 after_string = Foverlay_get (overlay, Qafter_string);
25726
25727 if (!STRINGP (before_string)) before_string = Qnil;
25728 if (!STRINGP (after_string)) after_string = Qnil;
25729 }
25730
25731 mouse_face_from_buffer_pos (window, hlinfo, pos,
25732 XFASTINT (before),
25733 XFASTINT (after),
25734 before_string, after_string,
25735 cover_string);
25736 cursor = No_Cursor;
25737 }
25738 }
25739 }
25740
25741 check_help_echo:
25742
25743 /* Look for a `help-echo' property. */
25744 if (NILP (help_echo_string)) {
25745 Lisp_Object help, overlay;
25746
25747 /* Check overlays first. */
25748 help = overlay = Qnil;
25749 for (i = noverlays - 1; i >= 0 && NILP (help); --i)
25750 {
25751 overlay = overlay_vec[i];
25752 help = Foverlay_get (overlay, Qhelp_echo);
25753 }
25754
25755 if (!NILP (help))
25756 {
25757 help_echo_string = help;
25758 help_echo_window = window;
25759 help_echo_object = overlay;
25760 help_echo_pos = pos;
25761 }
25762 else
25763 {
25764 Lisp_Object obj = glyph->object;
25765 EMACS_INT charpos = glyph->charpos;
25766
25767 /* Try text properties. */
25768 if (STRINGP (obj)
25769 && charpos >= 0
25770 && charpos < SCHARS (obj))
25771 {
25772 help = Fget_text_property (make_number (charpos),
25773 Qhelp_echo, obj);
25774 if (NILP (help))
25775 {
25776 /* If the string itself doesn't specify a help-echo,
25777 see if the buffer text ``under'' it does. */
25778 struct glyph_row *r
25779 = MATRIX_ROW (w->current_matrix, vpos);
25780 EMACS_INT start = MATRIX_ROW_START_CHARPOS (r);
25781 EMACS_INT p = string_buffer_position (obj, start);
25782 if (p > 0)
25783 {
25784 help = Fget_char_property (make_number (p),
25785 Qhelp_echo, w->buffer);
25786 if (!NILP (help))
25787 {
25788 charpos = p;
25789 obj = w->buffer;
25790 }
25791 }
25792 }
25793 }
25794 else if (BUFFERP (obj)
25795 && charpos >= BEGV
25796 && charpos < ZV)
25797 help = Fget_text_property (make_number (charpos), Qhelp_echo,
25798 obj);
25799
25800 if (!NILP (help))
25801 {
25802 help_echo_string = help;
25803 help_echo_window = window;
25804 help_echo_object = obj;
25805 help_echo_pos = charpos;
25806 }
25807 }
25808 }
25809
25810 #ifdef HAVE_WINDOW_SYSTEM
25811 /* Look for a `pointer' property. */
25812 if (FRAME_WINDOW_P (f) && NILP (pointer))
25813 {
25814 /* Check overlays first. */
25815 for (i = noverlays - 1; i >= 0 && NILP (pointer); --i)
25816 pointer = Foverlay_get (overlay_vec[i], Qpointer);
25817
25818 if (NILP (pointer))
25819 {
25820 Lisp_Object obj = glyph->object;
25821 EMACS_INT charpos = glyph->charpos;
25822
25823 /* Try text properties. */
25824 if (STRINGP (obj)
25825 && charpos >= 0
25826 && charpos < SCHARS (obj))
25827 {
25828 pointer = Fget_text_property (make_number (charpos),
25829 Qpointer, obj);
25830 if (NILP (pointer))
25831 {
25832 /* If the string itself doesn't specify a pointer,
25833 see if the buffer text ``under'' it does. */
25834 struct glyph_row *r
25835 = MATRIX_ROW (w->current_matrix, vpos);
25836 EMACS_INT start = MATRIX_ROW_START_CHARPOS (r);
25837 EMACS_INT p = string_buffer_position (obj, start);
25838 if (p > 0)
25839 pointer = Fget_char_property (make_number (p),
25840 Qpointer, w->buffer);
25841 }
25842 }
25843 else if (BUFFERP (obj)
25844 && charpos >= BEGV
25845 && charpos < ZV)
25846 pointer = Fget_text_property (make_number (charpos),
25847 Qpointer, obj);
25848 }
25849 }
25850 #endif /* HAVE_WINDOW_SYSTEM */
25851
25852 BEGV = obegv;
25853 ZV = ozv;
25854 current_buffer = obuf;
25855 }
25856
25857 set_cursor:
25858
25859 #ifdef HAVE_WINDOW_SYSTEM
25860 if (FRAME_WINDOW_P (f))
25861 define_frame_cursor1 (f, cursor, pointer);
25862 #else
25863 /* This is here to prevent a compiler error, about "label at end of
25864 compound statement". */
25865 return;
25866 #endif
25867 }
25868
25869
25870 /* EXPORT for RIF:
25871 Clear any mouse-face on window W. This function is part of the
25872 redisplay interface, and is called from try_window_id and similar
25873 functions to ensure the mouse-highlight is off. */
25874
25875 void
25876 x_clear_window_mouse_face (struct window *w)
25877 {
25878 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame));
25879 Lisp_Object window;
25880
25881 BLOCK_INPUT;
25882 XSETWINDOW (window, w);
25883 if (EQ (window, hlinfo->mouse_face_window))
25884 clear_mouse_face (hlinfo);
25885 UNBLOCK_INPUT;
25886 }
25887
25888
25889 /* EXPORT:
25890 Just discard the mouse face information for frame F, if any.
25891 This is used when the size of F is changed. */
25892
25893 void
25894 cancel_mouse_face (struct frame *f)
25895 {
25896 Lisp_Object window;
25897 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
25898
25899 window = hlinfo->mouse_face_window;
25900 if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f)
25901 {
25902 hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
25903 hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
25904 hlinfo->mouse_face_window = Qnil;
25905 }
25906 }
25907
25908
25909 \f
25910 /***********************************************************************
25911 Exposure Events
25912 ***********************************************************************/
25913
25914 #ifdef HAVE_WINDOW_SYSTEM
25915
25916 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
25917 which intersects rectangle R. R is in window-relative coordinates. */
25918
25919 static void
25920 expose_area (struct window *w, struct glyph_row *row, XRectangle *r,
25921 enum glyph_row_area area)
25922 {
25923 struct glyph *first = row->glyphs[area];
25924 struct glyph *end = row->glyphs[area] + row->used[area];
25925 struct glyph *last;
25926 int first_x, start_x, x;
25927
25928 if (area == TEXT_AREA && row->fill_line_p)
25929 /* If row extends face to end of line write the whole line. */
25930 draw_glyphs (w, 0, row, area,
25931 0, row->used[area],
25932 DRAW_NORMAL_TEXT, 0);
25933 else
25934 {
25935 /* Set START_X to the window-relative start position for drawing glyphs of
25936 AREA. The first glyph of the text area can be partially visible.
25937 The first glyphs of other areas cannot. */
25938 start_x = window_box_left_offset (w, area);
25939 x = start_x;
25940 if (area == TEXT_AREA)
25941 x += row->x;
25942
25943 /* Find the first glyph that must be redrawn. */
25944 while (first < end
25945 && x + first->pixel_width < r->x)
25946 {
25947 x += first->pixel_width;
25948 ++first;
25949 }
25950
25951 /* Find the last one. */
25952 last = first;
25953 first_x = x;
25954 while (last < end
25955 && x < r->x + r->width)
25956 {
25957 x += last->pixel_width;
25958 ++last;
25959 }
25960
25961 /* Repaint. */
25962 if (last > first)
25963 draw_glyphs (w, first_x - start_x, row, area,
25964 first - row->glyphs[area], last - row->glyphs[area],
25965 DRAW_NORMAL_TEXT, 0);
25966 }
25967 }
25968
25969
25970 /* Redraw the parts of the glyph row ROW on window W intersecting
25971 rectangle R. R is in window-relative coordinates. Value is
25972 non-zero if mouse-face was overwritten. */
25973
25974 static int
25975 expose_line (struct window *w, struct glyph_row *row, XRectangle *r)
25976 {
25977 xassert (row->enabled_p);
25978
25979 if (row->mode_line_p || w->pseudo_window_p)
25980 draw_glyphs (w, 0, row, TEXT_AREA,
25981 0, row->used[TEXT_AREA],
25982 DRAW_NORMAL_TEXT, 0);
25983 else
25984 {
25985 if (row->used[LEFT_MARGIN_AREA])
25986 expose_area (w, row, r, LEFT_MARGIN_AREA);
25987 if (row->used[TEXT_AREA])
25988 expose_area (w, row, r, TEXT_AREA);
25989 if (row->used[RIGHT_MARGIN_AREA])
25990 expose_area (w, row, r, RIGHT_MARGIN_AREA);
25991 draw_row_fringe_bitmaps (w, row);
25992 }
25993
25994 return row->mouse_face_p;
25995 }
25996
25997
25998 /* Redraw those parts of glyphs rows during expose event handling that
25999 overlap other rows. Redrawing of an exposed line writes over parts
26000 of lines overlapping that exposed line; this function fixes that.
26001
26002 W is the window being exposed. FIRST_OVERLAPPING_ROW is the first
26003 row in W's current matrix that is exposed and overlaps other rows.
26004 LAST_OVERLAPPING_ROW is the last such row. */
26005
26006 static void
26007 expose_overlaps (struct window *w,
26008 struct glyph_row *first_overlapping_row,
26009 struct glyph_row *last_overlapping_row,
26010 XRectangle *r)
26011 {
26012 struct glyph_row *row;
26013
26014 for (row = first_overlapping_row; row <= last_overlapping_row; ++row)
26015 if (row->overlapping_p)
26016 {
26017 xassert (row->enabled_p && !row->mode_line_p);
26018
26019 row->clip = r;
26020 if (row->used[LEFT_MARGIN_AREA])
26021 x_fix_overlapping_area (w, row, LEFT_MARGIN_AREA, OVERLAPS_BOTH);
26022
26023 if (row->used[TEXT_AREA])
26024 x_fix_overlapping_area (w, row, TEXT_AREA, OVERLAPS_BOTH);
26025
26026 if (row->used[RIGHT_MARGIN_AREA])
26027 x_fix_overlapping_area (w, row, RIGHT_MARGIN_AREA, OVERLAPS_BOTH);
26028 row->clip = NULL;
26029 }
26030 }
26031
26032
26033 /* Return non-zero if W's cursor intersects rectangle R. */
26034
26035 static int
26036 phys_cursor_in_rect_p (struct window *w, XRectangle *r)
26037 {
26038 XRectangle cr, result;
26039 struct glyph *cursor_glyph;
26040 struct glyph_row *row;
26041
26042 if (w->phys_cursor.vpos >= 0
26043 && w->phys_cursor.vpos < w->current_matrix->nrows
26044 && (row = MATRIX_ROW (w->current_matrix, w->phys_cursor.vpos),
26045 row->enabled_p)
26046 && row->cursor_in_fringe_p)
26047 {
26048 /* Cursor is in the fringe. */
26049 cr.x = window_box_right_offset (w,
26050 (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
26051 ? RIGHT_MARGIN_AREA
26052 : TEXT_AREA));
26053 cr.y = row->y;
26054 cr.width = WINDOW_RIGHT_FRINGE_WIDTH (w);
26055 cr.height = row->height;
26056 return x_intersect_rectangles (&cr, r, &result);
26057 }
26058
26059 cursor_glyph = get_phys_cursor_glyph (w);
26060 if (cursor_glyph)
26061 {
26062 /* r is relative to W's box, but w->phys_cursor.x is relative
26063 to left edge of W's TEXT area. Adjust it. */
26064 cr.x = window_box_left_offset (w, TEXT_AREA) + w->phys_cursor.x;
26065 cr.y = w->phys_cursor.y;
26066 cr.width = cursor_glyph->pixel_width;
26067 cr.height = w->phys_cursor_height;
26068 /* ++KFS: W32 version used W32-specific IntersectRect here, but
26069 I assume the effect is the same -- and this is portable. */
26070 return x_intersect_rectangles (&cr, r, &result);
26071 }
26072 /* If we don't understand the format, pretend we're not in the hot-spot. */
26073 return 0;
26074 }
26075
26076
26077 /* EXPORT:
26078 Draw a vertical window border to the right of window W if W doesn't
26079 have vertical scroll bars. */
26080
26081 void
26082 x_draw_vertical_border (struct window *w)
26083 {
26084 struct frame *f = XFRAME (WINDOW_FRAME (w));
26085
26086 /* We could do better, if we knew what type of scroll-bar the adjacent
26087 windows (on either side) have... But we don't :-(
26088 However, I think this works ok. ++KFS 2003-04-25 */
26089
26090 /* Redraw borders between horizontally adjacent windows. Don't
26091 do it for frames with vertical scroll bars because either the
26092 right scroll bar of a window, or the left scroll bar of its
26093 neighbor will suffice as a border. */
26094 if (FRAME_HAS_VERTICAL_SCROLL_BARS (XFRAME (w->frame)))
26095 return;
26096
26097 if (!WINDOW_RIGHTMOST_P (w)
26098 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w))
26099 {
26100 int x0, x1, y0, y1;
26101
26102 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
26103 y1 -= 1;
26104
26105 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
26106 x1 -= 1;
26107
26108 FRAME_RIF (f)->draw_vertical_window_border (w, x1, y0, y1);
26109 }
26110 else if (!WINDOW_LEFTMOST_P (w)
26111 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
26112 {
26113 int x0, x1, y0, y1;
26114
26115 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
26116 y1 -= 1;
26117
26118 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
26119 x0 -= 1;
26120
26121 FRAME_RIF (f)->draw_vertical_window_border (w, x0, y0, y1);
26122 }
26123 }
26124
26125
26126 /* Redraw the part of window W intersection rectangle FR. Pixel
26127 coordinates in FR are frame-relative. Call this function with
26128 input blocked. Value is non-zero if the exposure overwrites
26129 mouse-face. */
26130
26131 static int
26132 expose_window (struct window *w, XRectangle *fr)
26133 {
26134 struct frame *f = XFRAME (w->frame);
26135 XRectangle wr, r;
26136 int mouse_face_overwritten_p = 0;
26137
26138 /* If window is not yet fully initialized, do nothing. This can
26139 happen when toolkit scroll bars are used and a window is split.
26140 Reconfiguring the scroll bar will generate an expose for a newly
26141 created window. */
26142 if (w->current_matrix == NULL)
26143 return 0;
26144
26145 /* When we're currently updating the window, display and current
26146 matrix usually don't agree. Arrange for a thorough display
26147 later. */
26148 if (w == updated_window)
26149 {
26150 SET_FRAME_GARBAGED (f);
26151 return 0;
26152 }
26153
26154 /* Frame-relative pixel rectangle of W. */
26155 wr.x = WINDOW_LEFT_EDGE_X (w);
26156 wr.y = WINDOW_TOP_EDGE_Y (w);
26157 wr.width = WINDOW_TOTAL_WIDTH (w);
26158 wr.height = WINDOW_TOTAL_HEIGHT (w);
26159
26160 if (x_intersect_rectangles (fr, &wr, &r))
26161 {
26162 int yb = window_text_bottom_y (w);
26163 struct glyph_row *row;
26164 int cursor_cleared_p;
26165 struct glyph_row *first_overlapping_row, *last_overlapping_row;
26166
26167 TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n",
26168 r.x, r.y, r.width, r.height));
26169
26170 /* Convert to window coordinates. */
26171 r.x -= WINDOW_LEFT_EDGE_X (w);
26172 r.y -= WINDOW_TOP_EDGE_Y (w);
26173
26174 /* Turn off the cursor. */
26175 if (!w->pseudo_window_p
26176 && phys_cursor_in_rect_p (w, &r))
26177 {
26178 x_clear_cursor (w);
26179 cursor_cleared_p = 1;
26180 }
26181 else
26182 cursor_cleared_p = 0;
26183
26184 /* Update lines intersecting rectangle R. */
26185 first_overlapping_row = last_overlapping_row = NULL;
26186 for (row = w->current_matrix->rows;
26187 row->enabled_p;
26188 ++row)
26189 {
26190 int y0 = row->y;
26191 int y1 = MATRIX_ROW_BOTTOM_Y (row);
26192
26193 if ((y0 >= r.y && y0 < r.y + r.height)
26194 || (y1 > r.y && y1 < r.y + r.height)
26195 || (r.y >= y0 && r.y < y1)
26196 || (r.y + r.height > y0 && r.y + r.height < y1))
26197 {
26198 /* A header line may be overlapping, but there is no need
26199 to fix overlapping areas for them. KFS 2005-02-12 */
26200 if (row->overlapping_p && !row->mode_line_p)
26201 {
26202 if (first_overlapping_row == NULL)
26203 first_overlapping_row = row;
26204 last_overlapping_row = row;
26205 }
26206
26207 row->clip = fr;
26208 if (expose_line (w, row, &r))
26209 mouse_face_overwritten_p = 1;
26210 row->clip = NULL;
26211 }
26212 else if (row->overlapping_p)
26213 {
26214 /* We must redraw a row overlapping the exposed area. */
26215 if (y0 < r.y
26216 ? y0 + row->phys_height > r.y
26217 : y0 + row->ascent - row->phys_ascent < r.y +r.height)
26218 {
26219 if (first_overlapping_row == NULL)
26220 first_overlapping_row = row;
26221 last_overlapping_row = row;
26222 }
26223 }
26224
26225 if (y1 >= yb)
26226 break;
26227 }
26228
26229 /* Display the mode line if there is one. */
26230 if (WINDOW_WANTS_MODELINE_P (w)
26231 && (row = MATRIX_MODE_LINE_ROW (w->current_matrix),
26232 row->enabled_p)
26233 && row->y < r.y + r.height)
26234 {
26235 if (expose_line (w, row, &r))
26236 mouse_face_overwritten_p = 1;
26237 }
26238
26239 if (!w->pseudo_window_p)
26240 {
26241 /* Fix the display of overlapping rows. */
26242 if (first_overlapping_row)
26243 expose_overlaps (w, first_overlapping_row, last_overlapping_row,
26244 fr);
26245
26246 /* Draw border between windows. */
26247 x_draw_vertical_border (w);
26248
26249 /* Turn the cursor on again. */
26250 if (cursor_cleared_p)
26251 update_window_cursor (w, 1);
26252 }
26253 }
26254
26255 return mouse_face_overwritten_p;
26256 }
26257
26258
26259
26260 /* Redraw (parts) of all windows in the window tree rooted at W that
26261 intersect R. R contains frame pixel coordinates. Value is
26262 non-zero if the exposure overwrites mouse-face. */
26263
26264 static int
26265 expose_window_tree (struct window *w, XRectangle *r)
26266 {
26267 struct frame *f = XFRAME (w->frame);
26268 int mouse_face_overwritten_p = 0;
26269
26270 while (w && !FRAME_GARBAGED_P (f))
26271 {
26272 if (!NILP (w->hchild))
26273 mouse_face_overwritten_p
26274 |= expose_window_tree (XWINDOW (w->hchild), r);
26275 else if (!NILP (w->vchild))
26276 mouse_face_overwritten_p
26277 |= expose_window_tree (XWINDOW (w->vchild), r);
26278 else
26279 mouse_face_overwritten_p |= expose_window (w, r);
26280
26281 w = NILP (w->next) ? NULL : XWINDOW (w->next);
26282 }
26283
26284 return mouse_face_overwritten_p;
26285 }
26286
26287
26288 /* EXPORT:
26289 Redisplay an exposed area of frame F. X and Y are the upper-left
26290 corner of the exposed rectangle. W and H are width and height of
26291 the exposed area. All are pixel values. W or H zero means redraw
26292 the entire frame. */
26293
26294 void
26295 expose_frame (struct frame *f, int x, int y, int w, int h)
26296 {
26297 XRectangle r;
26298 int mouse_face_overwritten_p = 0;
26299
26300 TRACE ((stderr, "expose_frame "));
26301
26302 /* No need to redraw if frame will be redrawn soon. */
26303 if (FRAME_GARBAGED_P (f))
26304 {
26305 TRACE ((stderr, " garbaged\n"));
26306 return;
26307 }
26308
26309 /* If basic faces haven't been realized yet, there is no point in
26310 trying to redraw anything. This can happen when we get an expose
26311 event while Emacs is starting, e.g. by moving another window. */
26312 if (FRAME_FACE_CACHE (f) == NULL
26313 || FRAME_FACE_CACHE (f)->used < BASIC_FACE_ID_SENTINEL)
26314 {
26315 TRACE ((stderr, " no faces\n"));
26316 return;
26317 }
26318
26319 if (w == 0 || h == 0)
26320 {
26321 r.x = r.y = 0;
26322 r.width = FRAME_COLUMN_WIDTH (f) * FRAME_COLS (f);
26323 r.height = FRAME_LINE_HEIGHT (f) * FRAME_LINES (f);
26324 }
26325 else
26326 {
26327 r.x = x;
26328 r.y = y;
26329 r.width = w;
26330 r.height = h;
26331 }
26332
26333 TRACE ((stderr, "(%d, %d, %d, %d)\n", r.x, r.y, r.width, r.height));
26334 mouse_face_overwritten_p = expose_window_tree (XWINDOW (f->root_window), &r);
26335
26336 if (WINDOWP (f->tool_bar_window))
26337 mouse_face_overwritten_p
26338 |= expose_window (XWINDOW (f->tool_bar_window), &r);
26339
26340 #ifdef HAVE_X_WINDOWS
26341 #ifndef MSDOS
26342 #ifndef USE_X_TOOLKIT
26343 if (WINDOWP (f->menu_bar_window))
26344 mouse_face_overwritten_p
26345 |= expose_window (XWINDOW (f->menu_bar_window), &r);
26346 #endif /* not USE_X_TOOLKIT */
26347 #endif
26348 #endif
26349
26350 /* Some window managers support a focus-follows-mouse style with
26351 delayed raising of frames. Imagine a partially obscured frame,
26352 and moving the mouse into partially obscured mouse-face on that
26353 frame. The visible part of the mouse-face will be highlighted,
26354 then the WM raises the obscured frame. With at least one WM, KDE
26355 2.1, Emacs is not getting any event for the raising of the frame
26356 (even tried with SubstructureRedirectMask), only Expose events.
26357 These expose events will draw text normally, i.e. not
26358 highlighted. Which means we must redo the highlight here.
26359 Subsume it under ``we love X''. --gerd 2001-08-15 */
26360 /* Included in Windows version because Windows most likely does not
26361 do the right thing if any third party tool offers
26362 focus-follows-mouse with delayed raise. --jason 2001-10-12 */
26363 if (mouse_face_overwritten_p && !FRAME_GARBAGED_P (f))
26364 {
26365 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
26366 if (f == hlinfo->mouse_face_mouse_frame)
26367 {
26368 int mouse_x = hlinfo->mouse_face_mouse_x;
26369 int mouse_y = hlinfo->mouse_face_mouse_y;
26370 clear_mouse_face (hlinfo);
26371 note_mouse_highlight (f, mouse_x, mouse_y);
26372 }
26373 }
26374 }
26375
26376
26377 /* EXPORT:
26378 Determine the intersection of two rectangles R1 and R2. Return
26379 the intersection in *RESULT. Value is non-zero if RESULT is not
26380 empty. */
26381
26382 int
26383 x_intersect_rectangles (XRectangle *r1, XRectangle *r2, XRectangle *result)
26384 {
26385 XRectangle *left, *right;
26386 XRectangle *upper, *lower;
26387 int intersection_p = 0;
26388
26389 /* Rearrange so that R1 is the left-most rectangle. */
26390 if (r1->x < r2->x)
26391 left = r1, right = r2;
26392 else
26393 left = r2, right = r1;
26394
26395 /* X0 of the intersection is right.x0, if this is inside R1,
26396 otherwise there is no intersection. */
26397 if (right->x <= left->x + left->width)
26398 {
26399 result->x = right->x;
26400
26401 /* The right end of the intersection is the minimum of the
26402 the right ends of left and right. */
26403 result->width = (min (left->x + left->width, right->x + right->width)
26404 - result->x);
26405
26406 /* Same game for Y. */
26407 if (r1->y < r2->y)
26408 upper = r1, lower = r2;
26409 else
26410 upper = r2, lower = r1;
26411
26412 /* The upper end of the intersection is lower.y0, if this is inside
26413 of upper. Otherwise, there is no intersection. */
26414 if (lower->y <= upper->y + upper->height)
26415 {
26416 result->y = lower->y;
26417
26418 /* The lower end of the intersection is the minimum of the lower
26419 ends of upper and lower. */
26420 result->height = (min (lower->y + lower->height,
26421 upper->y + upper->height)
26422 - result->y);
26423 intersection_p = 1;
26424 }
26425 }
26426
26427 return intersection_p;
26428 }
26429
26430 #endif /* HAVE_WINDOW_SYSTEM */
26431
26432 \f
26433 /***********************************************************************
26434 Initialization
26435 ***********************************************************************/
26436
26437 void
26438 syms_of_xdisp (void)
26439 {
26440 Vwith_echo_area_save_vector = Qnil;
26441 staticpro (&Vwith_echo_area_save_vector);
26442
26443 Vmessage_stack = Qnil;
26444 staticpro (&Vmessage_stack);
26445
26446 Qinhibit_redisplay = intern_c_string ("inhibit-redisplay");
26447 staticpro (&Qinhibit_redisplay);
26448
26449 message_dolog_marker1 = Fmake_marker ();
26450 staticpro (&message_dolog_marker1);
26451 message_dolog_marker2 = Fmake_marker ();
26452 staticpro (&message_dolog_marker2);
26453 message_dolog_marker3 = Fmake_marker ();
26454 staticpro (&message_dolog_marker3);
26455
26456 #if GLYPH_DEBUG
26457 defsubr (&Sdump_frame_glyph_matrix);
26458 defsubr (&Sdump_glyph_matrix);
26459 defsubr (&Sdump_glyph_row);
26460 defsubr (&Sdump_tool_bar_row);
26461 defsubr (&Strace_redisplay);
26462 defsubr (&Strace_to_stderr);
26463 #endif
26464 #ifdef HAVE_WINDOW_SYSTEM
26465 defsubr (&Stool_bar_lines_needed);
26466 defsubr (&Slookup_image_map);
26467 #endif
26468 defsubr (&Sformat_mode_line);
26469 defsubr (&Sinvisible_p);
26470 defsubr (&Scurrent_bidi_paragraph_direction);
26471
26472 staticpro (&Qmenu_bar_update_hook);
26473 Qmenu_bar_update_hook = intern_c_string ("menu-bar-update-hook");
26474
26475 staticpro (&Qoverriding_terminal_local_map);
26476 Qoverriding_terminal_local_map = intern_c_string ("overriding-terminal-local-map");
26477
26478 staticpro (&Qoverriding_local_map);
26479 Qoverriding_local_map = intern_c_string ("overriding-local-map");
26480
26481 staticpro (&Qwindow_scroll_functions);
26482 Qwindow_scroll_functions = intern_c_string ("window-scroll-functions");
26483
26484 staticpro (&Qwindow_text_change_functions);
26485 Qwindow_text_change_functions = intern_c_string ("window-text-change-functions");
26486
26487 staticpro (&Qredisplay_end_trigger_functions);
26488 Qredisplay_end_trigger_functions = intern_c_string ("redisplay-end-trigger-functions");
26489
26490 staticpro (&Qinhibit_point_motion_hooks);
26491 Qinhibit_point_motion_hooks = intern_c_string ("inhibit-point-motion-hooks");
26492
26493 Qeval = intern_c_string ("eval");
26494 staticpro (&Qeval);
26495
26496 QCdata = intern_c_string (":data");
26497 staticpro (&QCdata);
26498 Qdisplay = intern_c_string ("display");
26499 staticpro (&Qdisplay);
26500 Qspace_width = intern_c_string ("space-width");
26501 staticpro (&Qspace_width);
26502 Qraise = intern_c_string ("raise");
26503 staticpro (&Qraise);
26504 Qslice = intern_c_string ("slice");
26505 staticpro (&Qslice);
26506 Qspace = intern_c_string ("space");
26507 staticpro (&Qspace);
26508 Qmargin = intern_c_string ("margin");
26509 staticpro (&Qmargin);
26510 Qpointer = intern_c_string ("pointer");
26511 staticpro (&Qpointer);
26512 Qleft_margin = intern_c_string ("left-margin");
26513 staticpro (&Qleft_margin);
26514 Qright_margin = intern_c_string ("right-margin");
26515 staticpro (&Qright_margin);
26516 Qcenter = intern_c_string ("center");
26517 staticpro (&Qcenter);
26518 Qline_height = intern_c_string ("line-height");
26519 staticpro (&Qline_height);
26520 QCalign_to = intern_c_string (":align-to");
26521 staticpro (&QCalign_to);
26522 QCrelative_width = intern_c_string (":relative-width");
26523 staticpro (&QCrelative_width);
26524 QCrelative_height = intern_c_string (":relative-height");
26525 staticpro (&QCrelative_height);
26526 QCeval = intern_c_string (":eval");
26527 staticpro (&QCeval);
26528 QCpropertize = intern_c_string (":propertize");
26529 staticpro (&QCpropertize);
26530 QCfile = intern_c_string (":file");
26531 staticpro (&QCfile);
26532 Qfontified = intern_c_string ("fontified");
26533 staticpro (&Qfontified);
26534 Qfontification_functions = intern_c_string ("fontification-functions");
26535 staticpro (&Qfontification_functions);
26536 Qtrailing_whitespace = intern_c_string ("trailing-whitespace");
26537 staticpro (&Qtrailing_whitespace);
26538 Qescape_glyph = intern_c_string ("escape-glyph");
26539 staticpro (&Qescape_glyph);
26540 Qnobreak_space = intern_c_string ("nobreak-space");
26541 staticpro (&Qnobreak_space);
26542 Qimage = intern_c_string ("image");
26543 staticpro (&Qimage);
26544 Qtext = intern_c_string ("text");
26545 staticpro (&Qtext);
26546 Qboth = intern_c_string ("both");
26547 staticpro (&Qboth);
26548 Qboth_horiz = intern_c_string ("both-horiz");
26549 staticpro (&Qboth_horiz);
26550 Qtext_image_horiz = intern_c_string ("text-image-horiz");
26551 staticpro (&Qtext_image_horiz);
26552 QCmap = intern_c_string (":map");
26553 staticpro (&QCmap);
26554 QCpointer = intern_c_string (":pointer");
26555 staticpro (&QCpointer);
26556 Qrect = intern_c_string ("rect");
26557 staticpro (&Qrect);
26558 Qcircle = intern_c_string ("circle");
26559 staticpro (&Qcircle);
26560 Qpoly = intern_c_string ("poly");
26561 staticpro (&Qpoly);
26562 Qmessage_truncate_lines = intern_c_string ("message-truncate-lines");
26563 staticpro (&Qmessage_truncate_lines);
26564 Qgrow_only = intern_c_string ("grow-only");
26565 staticpro (&Qgrow_only);
26566 Qinhibit_menubar_update = intern_c_string ("inhibit-menubar-update");
26567 staticpro (&Qinhibit_menubar_update);
26568 Qinhibit_eval_during_redisplay = intern_c_string ("inhibit-eval-during-redisplay");
26569 staticpro (&Qinhibit_eval_during_redisplay);
26570 Qposition = intern_c_string ("position");
26571 staticpro (&Qposition);
26572 Qbuffer_position = intern_c_string ("buffer-position");
26573 staticpro (&Qbuffer_position);
26574 Qobject = intern_c_string ("object");
26575 staticpro (&Qobject);
26576 Qbar = intern_c_string ("bar");
26577 staticpro (&Qbar);
26578 Qhbar = intern_c_string ("hbar");
26579 staticpro (&Qhbar);
26580 Qbox = intern_c_string ("box");
26581 staticpro (&Qbox);
26582 Qhollow = intern_c_string ("hollow");
26583 staticpro (&Qhollow);
26584 Qhand = intern_c_string ("hand");
26585 staticpro (&Qhand);
26586 Qarrow = intern_c_string ("arrow");
26587 staticpro (&Qarrow);
26588 Qtext = intern_c_string ("text");
26589 staticpro (&Qtext);
26590 Qinhibit_free_realized_faces = intern_c_string ("inhibit-free-realized-faces");
26591 staticpro (&Qinhibit_free_realized_faces);
26592
26593 list_of_error = Fcons (Fcons (intern_c_string ("error"),
26594 Fcons (intern_c_string ("void-variable"), Qnil)),
26595 Qnil);
26596 staticpro (&list_of_error);
26597
26598 Qlast_arrow_position = intern_c_string ("last-arrow-position");
26599 staticpro (&Qlast_arrow_position);
26600 Qlast_arrow_string = intern_c_string ("last-arrow-string");
26601 staticpro (&Qlast_arrow_string);
26602
26603 Qoverlay_arrow_string = intern_c_string ("overlay-arrow-string");
26604 staticpro (&Qoverlay_arrow_string);
26605 Qoverlay_arrow_bitmap = intern_c_string ("overlay-arrow-bitmap");
26606 staticpro (&Qoverlay_arrow_bitmap);
26607
26608 echo_buffer[0] = echo_buffer[1] = Qnil;
26609 staticpro (&echo_buffer[0]);
26610 staticpro (&echo_buffer[1]);
26611
26612 echo_area_buffer[0] = echo_area_buffer[1] = Qnil;
26613 staticpro (&echo_area_buffer[0]);
26614 staticpro (&echo_area_buffer[1]);
26615
26616 Vmessages_buffer_name = make_pure_c_string ("*Messages*");
26617 staticpro (&Vmessages_buffer_name);
26618
26619 mode_line_proptrans_alist = Qnil;
26620 staticpro (&mode_line_proptrans_alist);
26621 mode_line_string_list = Qnil;
26622 staticpro (&mode_line_string_list);
26623 mode_line_string_face = Qnil;
26624 staticpro (&mode_line_string_face);
26625 mode_line_string_face_prop = Qnil;
26626 staticpro (&mode_line_string_face_prop);
26627 Vmode_line_unwind_vector = Qnil;
26628 staticpro (&Vmode_line_unwind_vector);
26629
26630 help_echo_string = Qnil;
26631 staticpro (&help_echo_string);
26632 help_echo_object = Qnil;
26633 staticpro (&help_echo_object);
26634 help_echo_window = Qnil;
26635 staticpro (&help_echo_window);
26636 previous_help_echo_string = Qnil;
26637 staticpro (&previous_help_echo_string);
26638 help_echo_pos = -1;
26639
26640 Qright_to_left = intern_c_string ("right-to-left");
26641 staticpro (&Qright_to_left);
26642 Qleft_to_right = intern_c_string ("left-to-right");
26643 staticpro (&Qleft_to_right);
26644
26645 #ifdef HAVE_WINDOW_SYSTEM
26646 DEFVAR_BOOL ("x-stretch-cursor", x_stretch_cursor_p,
26647 doc: /* *Non-nil means draw block cursor as wide as the glyph under it.
26648 For example, if a block cursor is over a tab, it will be drawn as
26649 wide as that tab on the display. */);
26650 x_stretch_cursor_p = 0;
26651 #endif
26652
26653 DEFVAR_LISP ("show-trailing-whitespace", Vshow_trailing_whitespace,
26654 doc: /* *Non-nil means highlight trailing whitespace.
26655 The face used for trailing whitespace is `trailing-whitespace'. */);
26656 Vshow_trailing_whitespace = Qnil;
26657
26658 DEFVAR_LISP ("nobreak-char-display", Vnobreak_char_display,
26659 doc: /* *Control highlighting of nobreak space and soft hyphen.
26660 A value of t means highlight the character itself (for nobreak space,
26661 use face `nobreak-space').
26662 A value of nil means no highlighting.
26663 Other values mean display the escape glyph followed by an ordinary
26664 space or ordinary hyphen. */);
26665 Vnobreak_char_display = Qt;
26666
26667 DEFVAR_LISP ("void-text-area-pointer", Vvoid_text_area_pointer,
26668 doc: /* *The pointer shape to show in void text areas.
26669 A value of nil means to show the text pointer. Other options are `arrow',
26670 `text', `hand', `vdrag', `hdrag', `modeline', and `hourglass'. */);
26671 Vvoid_text_area_pointer = Qarrow;
26672
26673 DEFVAR_LISP ("inhibit-redisplay", Vinhibit_redisplay,
26674 doc: /* Non-nil means don't actually do any redisplay.
26675 This is used for internal purposes. */);
26676 Vinhibit_redisplay = Qnil;
26677
26678 DEFVAR_LISP ("global-mode-string", Vglobal_mode_string,
26679 doc: /* String (or mode line construct) included (normally) in `mode-line-format'. */);
26680 Vglobal_mode_string = Qnil;
26681
26682 DEFVAR_LISP ("overlay-arrow-position", Voverlay_arrow_position,
26683 doc: /* Marker for where to display an arrow on top of the buffer text.
26684 This must be the beginning of a line in order to work.
26685 See also `overlay-arrow-string'. */);
26686 Voverlay_arrow_position = Qnil;
26687
26688 DEFVAR_LISP ("overlay-arrow-string", Voverlay_arrow_string,
26689 doc: /* String to display as an arrow in non-window frames.
26690 See also `overlay-arrow-position'. */);
26691 Voverlay_arrow_string = make_pure_c_string ("=>");
26692
26693 DEFVAR_LISP ("overlay-arrow-variable-list", Voverlay_arrow_variable_list,
26694 doc: /* List of variables (symbols) which hold markers for overlay arrows.
26695 The symbols on this list are examined during redisplay to determine
26696 where to display overlay arrows. */);
26697 Voverlay_arrow_variable_list
26698 = Fcons (intern_c_string ("overlay-arrow-position"), Qnil);
26699
26700 DEFVAR_INT ("scroll-step", emacs_scroll_step,
26701 doc: /* *The number of lines to try scrolling a window by when point moves out.
26702 If that fails to bring point back on frame, point is centered instead.
26703 If this is zero, point is always centered after it moves off frame.
26704 If you want scrolling to always be a line at a time, you should set
26705 `scroll-conservatively' to a large value rather than set this to 1. */);
26706
26707 DEFVAR_INT ("scroll-conservatively", scroll_conservatively,
26708 doc: /* *Scroll up to this many lines, to bring point back on screen.
26709 If point moves off-screen, redisplay will scroll by up to
26710 `scroll-conservatively' lines in order to bring point just barely
26711 onto the screen again. If that cannot be done, then redisplay
26712 recenters point as usual.
26713
26714 If the value is greater than 100, redisplay will never recenter point,
26715 but will always scroll just enough text to bring point into view, even
26716 if you move far away.
26717
26718 A value of zero means always recenter point if it moves off screen. */);
26719 scroll_conservatively = 0;
26720
26721 DEFVAR_INT ("scroll-margin", scroll_margin,
26722 doc: /* *Number of lines of margin at the top and bottom of a window.
26723 Recenter the window whenever point gets within this many lines
26724 of the top or bottom of the window. */);
26725 scroll_margin = 0;
26726
26727 DEFVAR_LISP ("display-pixels-per-inch", Vdisplay_pixels_per_inch,
26728 doc: /* Pixels per inch value for non-window system displays.
26729 Value is a number or a cons (WIDTH-DPI . HEIGHT-DPI). */);
26730 Vdisplay_pixels_per_inch = make_float (72.0);
26731
26732 #if GLYPH_DEBUG
26733 DEFVAR_INT ("debug-end-pos", debug_end_pos, doc: /* Don't ask. */);
26734 #endif
26735
26736 DEFVAR_LISP ("truncate-partial-width-windows",
26737 Vtruncate_partial_width_windows,
26738 doc: /* Non-nil means truncate lines in windows narrower than the frame.
26739 For an integer value, truncate lines in each window narrower than the
26740 full frame width, provided the window width is less than that integer;
26741 otherwise, respect the value of `truncate-lines'.
26742
26743 For any other non-nil value, truncate lines in all windows that do
26744 not span the full frame width.
26745
26746 A value of nil means to respect the value of `truncate-lines'.
26747
26748 If `word-wrap' is enabled, you might want to reduce this. */);
26749 Vtruncate_partial_width_windows = make_number (50);
26750
26751 DEFVAR_BOOL ("mode-line-inverse-video", mode_line_inverse_video,
26752 doc: /* When nil, display the mode-line/header-line/menu-bar in the default face.
26753 Any other value means to use the appropriate face, `mode-line',
26754 `header-line', or `menu' respectively. */);
26755 mode_line_inverse_video = 1;
26756
26757 DEFVAR_LISP ("line-number-display-limit", Vline_number_display_limit,
26758 doc: /* *Maximum buffer size for which line number should be displayed.
26759 If the buffer is bigger than this, the line number does not appear
26760 in the mode line. A value of nil means no limit. */);
26761 Vline_number_display_limit = Qnil;
26762
26763 DEFVAR_INT ("line-number-display-limit-width",
26764 line_number_display_limit_width,
26765 doc: /* *Maximum line width (in characters) for line number display.
26766 If the average length of the lines near point is bigger than this, then the
26767 line number may be omitted from the mode line. */);
26768 line_number_display_limit_width = 200;
26769
26770 DEFVAR_BOOL ("highlight-nonselected-windows", highlight_nonselected_windows,
26771 doc: /* *Non-nil means highlight region even in nonselected windows. */);
26772 highlight_nonselected_windows = 0;
26773
26774 DEFVAR_BOOL ("multiple-frames", multiple_frames,
26775 doc: /* Non-nil if more than one frame is visible on this display.
26776 Minibuffer-only frames don't count, but iconified frames do.
26777 This variable is not guaranteed to be accurate except while processing
26778 `frame-title-format' and `icon-title-format'. */);
26779
26780 DEFVAR_LISP ("frame-title-format", Vframe_title_format,
26781 doc: /* Template for displaying the title bar of visible frames.
26782 \(Assuming the window manager supports this feature.)
26783
26784 This variable has the same structure as `mode-line-format', except that
26785 the %c and %l constructs are ignored. It is used only on frames for
26786 which no explicit name has been set \(see `modify-frame-parameters'). */);
26787
26788 DEFVAR_LISP ("icon-title-format", Vicon_title_format,
26789 doc: /* Template for displaying the title bar of an iconified frame.
26790 \(Assuming the window manager supports this feature.)
26791 This variable has the same structure as `mode-line-format' (which see),
26792 and is used only on frames for which no explicit name has been set
26793 \(see `modify-frame-parameters'). */);
26794 Vicon_title_format
26795 = Vframe_title_format
26796 = pure_cons (intern_c_string ("multiple-frames"),
26797 pure_cons (make_pure_c_string ("%b"),
26798 pure_cons (pure_cons (empty_unibyte_string,
26799 pure_cons (intern_c_string ("invocation-name"),
26800 pure_cons (make_pure_c_string ("@"),
26801 pure_cons (intern_c_string ("system-name"),
26802 Qnil)))),
26803 Qnil)));
26804
26805 DEFVAR_LISP ("message-log-max", Vmessage_log_max,
26806 doc: /* Maximum number of lines to keep in the message log buffer.
26807 If nil, disable message logging. If t, log messages but don't truncate
26808 the buffer when it becomes large. */);
26809 Vmessage_log_max = make_number (100);
26810
26811 DEFVAR_LISP ("window-size-change-functions", Vwindow_size_change_functions,
26812 doc: /* Functions called before redisplay, if window sizes have changed.
26813 The value should be a list of functions that take one argument.
26814 Just before redisplay, for each frame, if any of its windows have changed
26815 size since the last redisplay, or have been split or deleted,
26816 all the functions in the list are called, with the frame as argument. */);
26817 Vwindow_size_change_functions = Qnil;
26818
26819 DEFVAR_LISP ("window-scroll-functions", Vwindow_scroll_functions,
26820 doc: /* List of functions to call before redisplaying a window with scrolling.
26821 Each function is called with two arguments, the window and its new
26822 display-start position. Note that these functions are also called by
26823 `set-window-buffer'. Also note that the value of `window-end' is not
26824 valid when these functions are called. */);
26825 Vwindow_scroll_functions = Qnil;
26826
26827 DEFVAR_LISP ("window-text-change-functions",
26828 Vwindow_text_change_functions,
26829 doc: /* Functions to call in redisplay when text in the window might change. */);
26830 Vwindow_text_change_functions = Qnil;
26831
26832 DEFVAR_LISP ("redisplay-end-trigger-functions", Vredisplay_end_trigger_functions,
26833 doc: /* Functions called when redisplay of a window reaches the end trigger.
26834 Each function is called with two arguments, the window and the end trigger value.
26835 See `set-window-redisplay-end-trigger'. */);
26836 Vredisplay_end_trigger_functions = Qnil;
26837
26838 DEFVAR_LISP ("mouse-autoselect-window", Vmouse_autoselect_window,
26839 doc: /* *Non-nil means autoselect window with mouse pointer.
26840 If nil, do not autoselect windows.
26841 A positive number means delay autoselection by that many seconds: a
26842 window is autoselected only after the mouse has remained in that
26843 window for the duration of the delay.
26844 A negative number has a similar effect, but causes windows to be
26845 autoselected only after the mouse has stopped moving. \(Because of
26846 the way Emacs compares mouse events, you will occasionally wait twice
26847 that time before the window gets selected.\)
26848 Any other value means to autoselect window instantaneously when the
26849 mouse pointer enters it.
26850
26851 Autoselection selects the minibuffer only if it is active, and never
26852 unselects the minibuffer if it is active.
26853
26854 When customizing this variable make sure that the actual value of
26855 `focus-follows-mouse' matches the behavior of your window manager. */);
26856 Vmouse_autoselect_window = Qnil;
26857
26858 DEFVAR_LISP ("auto-resize-tool-bars", Vauto_resize_tool_bars,
26859 doc: /* *Non-nil means automatically resize tool-bars.
26860 This dynamically changes the tool-bar's height to the minimum height
26861 that is needed to make all tool-bar items visible.
26862 If value is `grow-only', the tool-bar's height is only increased
26863 automatically; to decrease the tool-bar height, use \\[recenter]. */);
26864 Vauto_resize_tool_bars = Qt;
26865
26866 DEFVAR_BOOL ("auto-raise-tool-bar-buttons", auto_raise_tool_bar_buttons_p,
26867 doc: /* *Non-nil means raise tool-bar buttons when the mouse moves over them. */);
26868 auto_raise_tool_bar_buttons_p = 1;
26869
26870 DEFVAR_BOOL ("make-cursor-line-fully-visible", make_cursor_line_fully_visible_p,
26871 doc: /* *Non-nil means to scroll (recenter) cursor line if it is not fully visible. */);
26872 make_cursor_line_fully_visible_p = 1;
26873
26874 DEFVAR_LISP ("tool-bar-border", Vtool_bar_border,
26875 doc: /* *Border below tool-bar in pixels.
26876 If an integer, use it as the height of the border.
26877 If it is one of `internal-border-width' or `border-width', use the
26878 value of the corresponding frame parameter.
26879 Otherwise, no border is added below the tool-bar. */);
26880 Vtool_bar_border = Qinternal_border_width;
26881
26882 DEFVAR_LISP ("tool-bar-button-margin", Vtool_bar_button_margin,
26883 doc: /* *Margin around tool-bar buttons in pixels.
26884 If an integer, use that for both horizontal and vertical margins.
26885 Otherwise, value should be a pair of integers `(HORZ . VERT)' with
26886 HORZ specifying the horizontal margin, and VERT specifying the
26887 vertical margin. */);
26888 Vtool_bar_button_margin = make_number (DEFAULT_TOOL_BAR_BUTTON_MARGIN);
26889
26890 DEFVAR_INT ("tool-bar-button-relief", tool_bar_button_relief,
26891 doc: /* *Relief thickness of tool-bar buttons. */);
26892 tool_bar_button_relief = DEFAULT_TOOL_BAR_BUTTON_RELIEF;
26893
26894 DEFVAR_LISP ("tool-bar-style", Vtool_bar_style,
26895 doc: /* Tool bar style to use.
26896 It can be one of
26897 image - show images only
26898 text - show text only
26899 both - show both, text below image
26900 both-horiz - show text to the right of the image
26901 text-image-horiz - show text to the left of the image
26902 any other - use system default or image if no system default. */);
26903 Vtool_bar_style = Qnil;
26904
26905 DEFVAR_INT ("tool-bar-max-label-size", tool_bar_max_label_size,
26906 doc: /* *Maximum number of characters a label can have to be shown.
26907 The tool bar style must also show labels for this to have any effect, see
26908 `tool-bar-style'. */);
26909 tool_bar_max_label_size = DEFAULT_TOOL_BAR_LABEL_SIZE;
26910
26911 DEFVAR_LISP ("fontification-functions", Vfontification_functions,
26912 doc: /* List of functions to call to fontify regions of text.
26913 Each function is called with one argument POS. Functions must
26914 fontify a region starting at POS in the current buffer, and give
26915 fontified regions the property `fontified'. */);
26916 Vfontification_functions = Qnil;
26917 Fmake_variable_buffer_local (Qfontification_functions);
26918
26919 DEFVAR_BOOL ("unibyte-display-via-language-environment",
26920 unibyte_display_via_language_environment,
26921 doc: /* *Non-nil means display unibyte text according to language environment.
26922 Specifically, this means that raw bytes in the range 160-255 decimal
26923 are displayed by converting them to the equivalent multibyte characters
26924 according to the current language environment. As a result, they are
26925 displayed according to the current fontset.
26926
26927 Note that this variable affects only how these bytes are displayed,
26928 but does not change the fact they are interpreted as raw bytes. */);
26929 unibyte_display_via_language_environment = 0;
26930
26931 DEFVAR_LISP ("max-mini-window-height", Vmax_mini_window_height,
26932 doc: /* *Maximum height for resizing mini-windows.
26933 If a float, it specifies a fraction of the mini-window frame's height.
26934 If an integer, it specifies a number of lines. */);
26935 Vmax_mini_window_height = make_float (0.25);
26936
26937 DEFVAR_LISP ("resize-mini-windows", Vresize_mini_windows,
26938 doc: /* *How to resize mini-windows.
26939 A value of nil means don't automatically resize mini-windows.
26940 A value of t means resize them to fit the text displayed in them.
26941 A value of `grow-only', the default, means let mini-windows grow
26942 only, until their display becomes empty, at which point the windows
26943 go back to their normal size. */);
26944 Vresize_mini_windows = Qgrow_only;
26945
26946 DEFVAR_LISP ("blink-cursor-alist", Vblink_cursor_alist,
26947 doc: /* Alist specifying how to blink the cursor off.
26948 Each element has the form (ON-STATE . OFF-STATE). Whenever the
26949 `cursor-type' frame-parameter or variable equals ON-STATE,
26950 comparing using `equal', Emacs uses OFF-STATE to specify
26951 how to blink it off. ON-STATE and OFF-STATE are values for
26952 the `cursor-type' frame parameter.
26953
26954 If a frame's ON-STATE has no entry in this list,
26955 the frame's other specifications determine how to blink the cursor off. */);
26956 Vblink_cursor_alist = Qnil;
26957
26958 DEFVAR_BOOL ("auto-hscroll-mode", automatic_hscrolling_p,
26959 doc: /* Allow or disallow automatic horizontal scrolling of windows.
26960 If non-nil, windows are automatically scrolled horizontally to make
26961 point visible. */);
26962 automatic_hscrolling_p = 1;
26963 Qauto_hscroll_mode = intern_c_string ("auto-hscroll-mode");
26964 staticpro (&Qauto_hscroll_mode);
26965
26966 DEFVAR_INT ("hscroll-margin", hscroll_margin,
26967 doc: /* *How many columns away from the window edge point is allowed to get
26968 before automatic hscrolling will horizontally scroll the window. */);
26969 hscroll_margin = 5;
26970
26971 DEFVAR_LISP ("hscroll-step", Vhscroll_step,
26972 doc: /* *How many columns to scroll the window when point gets too close to the edge.
26973 When point is less than `hscroll-margin' columns from the window
26974 edge, automatic hscrolling will scroll the window by the amount of columns
26975 determined by this variable. If its value is a positive integer, scroll that
26976 many columns. If it's a positive floating-point number, it specifies the
26977 fraction of the window's width to scroll. If it's nil or zero, point will be
26978 centered horizontally after the scroll. Any other value, including negative
26979 numbers, are treated as if the value were zero.
26980
26981 Automatic hscrolling always moves point outside the scroll margin, so if
26982 point was more than scroll step columns inside the margin, the window will
26983 scroll more than the value given by the scroll step.
26984
26985 Note that the lower bound for automatic hscrolling specified by `scroll-left'
26986 and `scroll-right' overrides this variable's effect. */);
26987 Vhscroll_step = make_number (0);
26988
26989 DEFVAR_BOOL ("message-truncate-lines", message_truncate_lines,
26990 doc: /* If non-nil, messages are truncated instead of resizing the echo area.
26991 Bind this around calls to `message' to let it take effect. */);
26992 message_truncate_lines = 0;
26993
26994 DEFVAR_LISP ("menu-bar-update-hook", Vmenu_bar_update_hook,
26995 doc: /* Normal hook run to update the menu bar definitions.
26996 Redisplay runs this hook before it redisplays the menu bar.
26997 This is used to update submenus such as Buffers,
26998 whose contents depend on various data. */);
26999 Vmenu_bar_update_hook = Qnil;
27000
27001 DEFVAR_LISP ("menu-updating-frame", Vmenu_updating_frame,
27002 doc: /* Frame for which we are updating a menu.
27003 The enable predicate for a menu binding should check this variable. */);
27004 Vmenu_updating_frame = Qnil;
27005
27006 DEFVAR_BOOL ("inhibit-menubar-update", inhibit_menubar_update,
27007 doc: /* Non-nil means don't update menu bars. Internal use only. */);
27008 inhibit_menubar_update = 0;
27009
27010 DEFVAR_LISP ("wrap-prefix", Vwrap_prefix,
27011 doc: /* Prefix prepended to all continuation lines at display time.
27012 The value may be a string, an image, or a stretch-glyph; it is
27013 interpreted in the same way as the value of a `display' text property.
27014
27015 This variable is overridden by any `wrap-prefix' text or overlay
27016 property.
27017
27018 To add a prefix to non-continuation lines, use `line-prefix'. */);
27019 Vwrap_prefix = Qnil;
27020 staticpro (&Qwrap_prefix);
27021 Qwrap_prefix = intern_c_string ("wrap-prefix");
27022 Fmake_variable_buffer_local (Qwrap_prefix);
27023
27024 DEFVAR_LISP ("line-prefix", Vline_prefix,
27025 doc: /* Prefix prepended to all non-continuation lines at display time.
27026 The value may be a string, an image, or a stretch-glyph; it is
27027 interpreted in the same way as the value of a `display' text property.
27028
27029 This variable is overridden by any `line-prefix' text or overlay
27030 property.
27031
27032 To add a prefix to continuation lines, use `wrap-prefix'. */);
27033 Vline_prefix = Qnil;
27034 staticpro (&Qline_prefix);
27035 Qline_prefix = intern_c_string ("line-prefix");
27036 Fmake_variable_buffer_local (Qline_prefix);
27037
27038 DEFVAR_BOOL ("inhibit-eval-during-redisplay", inhibit_eval_during_redisplay,
27039 doc: /* Non-nil means don't eval Lisp during redisplay. */);
27040 inhibit_eval_during_redisplay = 0;
27041
27042 DEFVAR_BOOL ("inhibit-free-realized-faces", inhibit_free_realized_faces,
27043 doc: /* Non-nil means don't free realized faces. Internal use only. */);
27044 inhibit_free_realized_faces = 0;
27045
27046 #if GLYPH_DEBUG
27047 DEFVAR_BOOL ("inhibit-try-window-id", inhibit_try_window_id,
27048 doc: /* Inhibit try_window_id display optimization. */);
27049 inhibit_try_window_id = 0;
27050
27051 DEFVAR_BOOL ("inhibit-try-window-reusing", inhibit_try_window_reusing,
27052 doc: /* Inhibit try_window_reusing display optimization. */);
27053 inhibit_try_window_reusing = 0;
27054
27055 DEFVAR_BOOL ("inhibit-try-cursor-movement", inhibit_try_cursor_movement,
27056 doc: /* Inhibit try_cursor_movement display optimization. */);
27057 inhibit_try_cursor_movement = 0;
27058 #endif /* GLYPH_DEBUG */
27059
27060 DEFVAR_INT ("overline-margin", overline_margin,
27061 doc: /* *Space between overline and text, in pixels.
27062 The default value is 2: the height of the overline (1 pixel) plus 1 pixel
27063 margin to the caracter height. */);
27064 overline_margin = 2;
27065
27066 DEFVAR_INT ("underline-minimum-offset",
27067 underline_minimum_offset,
27068 doc: /* Minimum distance between baseline and underline.
27069 This can improve legibility of underlined text at small font sizes,
27070 particularly when using variable `x-use-underline-position-properties'
27071 with fonts that specify an UNDERLINE_POSITION relatively close to the
27072 baseline. The default value is 1. */);
27073 underline_minimum_offset = 1;
27074
27075 DEFVAR_BOOL ("display-hourglass", display_hourglass_p,
27076 doc: /* Non-nil means show an hourglass pointer, when Emacs is busy.
27077 This feature only works when on a window system that can change
27078 cursor shapes. */);
27079 display_hourglass_p = 1;
27080
27081 DEFVAR_LISP ("hourglass-delay", Vhourglass_delay,
27082 doc: /* *Seconds to wait before displaying an hourglass pointer when Emacs is busy. */);
27083 Vhourglass_delay = make_number (DEFAULT_HOURGLASS_DELAY);
27084
27085 hourglass_atimer = NULL;
27086 hourglass_shown_p = 0;
27087
27088 DEFSYM (Qglyphless_char, "glyphless-char");
27089 DEFSYM (Qhex_code, "hex-code");
27090 DEFSYM (Qempty_box, "empty-box");
27091 DEFSYM (Qthin_space, "thin-space");
27092 DEFSYM (Qzero_width, "zero-width");
27093
27094 DEFSYM (Qglyphless_char_display, "glyphless-char-display");
27095 /* Intern this now in case it isn't already done.
27096 Setting this variable twice is harmless.
27097 But don't staticpro it here--that is done in alloc.c. */
27098 Qchar_table_extra_slots = intern_c_string ("char-table-extra-slots");
27099 Fput (Qglyphless_char_display, Qchar_table_extra_slots, make_number (1));
27100
27101 DEFVAR_LISP ("glyphless-char-display", Vglyphless_char_display,
27102 doc: /* Char-table defining glyphless characters.
27103 Each element, if non-nil, should be one of the following:
27104 an ASCII acronym string: display this string in a box
27105 `hex-code': display the hexadecimal code of a character in a box
27106 `empty-box': display as an empty box
27107 `thin-space': display as 1-pixel width space
27108 `zero-width': don't display
27109 An element may also be a cons cell (GRAPHICAL . TEXT), which specifies the
27110 display method for graphical terminals and text terminals respectively.
27111 GRAPHICAL and TEXT should each have one of the values listed above.
27112
27113 The char-table has one extra slot to control the display of a character for
27114 which no font is found. This slot only takes effect on graphical terminals.
27115 Its value should be an ASCII acronym string, `hex-code', `empty-box', or
27116 `thin-space'. The default is `empty-box'. */);
27117 Vglyphless_char_display = Fmake_char_table (Qglyphless_char_display, Qnil);
27118 Fset_char_table_extra_slot (Vglyphless_char_display, make_number (0),
27119 Qempty_box);
27120 }
27121
27122
27123 /* Initialize this module when Emacs starts. */
27124
27125 void
27126 init_xdisp (void)
27127 {
27128 Lisp_Object root_window;
27129 struct window *mini_w;
27130
27131 current_header_line_height = current_mode_line_height = -1;
27132
27133 CHARPOS (this_line_start_pos) = 0;
27134
27135 mini_w = XWINDOW (minibuf_window);
27136 root_window = FRAME_ROOT_WINDOW (XFRAME (WINDOW_FRAME (mini_w)));
27137 echo_area_window = minibuf_window;
27138
27139 if (!noninteractive)
27140 {
27141 struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (root_window)));
27142 int i;
27143
27144 XWINDOW (root_window)->top_line = make_number (FRAME_TOP_MARGIN (f));
27145 set_window_height (root_window,
27146 FRAME_LINES (f) - 1 - FRAME_TOP_MARGIN (f),
27147 0);
27148 mini_w->top_line = make_number (FRAME_LINES (f) - 1);
27149 set_window_height (minibuf_window, 1, 0);
27150
27151 XWINDOW (root_window)->total_cols = make_number (FRAME_COLS (f));
27152 mini_w->total_cols = make_number (FRAME_COLS (f));
27153
27154 scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs;
27155 scratch_glyph_row.glyphs[TEXT_AREA + 1]
27156 = scratch_glyphs + MAX_SCRATCH_GLYPHS;
27157
27158 /* The default ellipsis glyphs `...'. */
27159 for (i = 0; i < 3; ++i)
27160 default_invis_vector[i] = make_number ('.');
27161 }
27162
27163 {
27164 /* Allocate the buffer for frame titles.
27165 Also used for `format-mode-line'. */
27166 int size = 100;
27167 mode_line_noprop_buf = (char *) xmalloc (size);
27168 mode_line_noprop_buf_end = mode_line_noprop_buf + size;
27169 mode_line_noprop_ptr = mode_line_noprop_buf;
27170 mode_line_target = MODE_LINE_DISPLAY;
27171 }
27172
27173 help_echo_showing_p = 0;
27174 }
27175
27176 /* Since w32 does not support atimers, it defines its own implementation of
27177 the following three functions in w32fns.c. */
27178 #ifndef WINDOWSNT
27179
27180 /* Platform-independent portion of hourglass implementation. */
27181
27182 /* Return non-zero if houglass timer has been started or hourglass is shown. */
27183 int
27184 hourglass_started (void)
27185 {
27186 return hourglass_shown_p || hourglass_atimer != NULL;
27187 }
27188
27189 /* Cancel a currently active hourglass timer, and start a new one. */
27190 void
27191 start_hourglass (void)
27192 {
27193 #if defined (HAVE_WINDOW_SYSTEM)
27194 EMACS_TIME delay;
27195 int secs, usecs = 0;
27196
27197 cancel_hourglass ();
27198
27199 if (INTEGERP (Vhourglass_delay)
27200 && XINT (Vhourglass_delay) > 0)
27201 secs = XFASTINT (Vhourglass_delay);
27202 else if (FLOATP (Vhourglass_delay)
27203 && XFLOAT_DATA (Vhourglass_delay) > 0)
27204 {
27205 Lisp_Object tem;
27206 tem = Ftruncate (Vhourglass_delay, Qnil);
27207 secs = XFASTINT (tem);
27208 usecs = (XFLOAT_DATA (Vhourglass_delay) - secs) * 1000000;
27209 }
27210 else
27211 secs = DEFAULT_HOURGLASS_DELAY;
27212
27213 EMACS_SET_SECS_USECS (delay, secs, usecs);
27214 hourglass_atimer = start_atimer (ATIMER_RELATIVE, delay,
27215 show_hourglass, NULL);
27216 #endif
27217 }
27218
27219
27220 /* Cancel the hourglass cursor timer if active, hide a busy cursor if
27221 shown. */
27222 void
27223 cancel_hourglass (void)
27224 {
27225 #if defined (HAVE_WINDOW_SYSTEM)
27226 if (hourglass_atimer)
27227 {
27228 cancel_atimer (hourglass_atimer);
27229 hourglass_atimer = NULL;
27230 }
27231
27232 if (hourglass_shown_p)
27233 hide_hourglass ();
27234 #endif
27235 }
27236 #endif /* ! WINDOWSNT */