Remove unused external symbols.
[bpt/emacs.git] / src / xdisp.c
1 /* Display generation from window structure and buffer text.
2
3 Copyright (C) 1985-1988, 1993-1995, 1997-2011 Free Software Foundation, Inc.
4
5 This file is part of GNU Emacs.
6
7 GNU Emacs is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
11
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
19
20 /* New redisplay written by Gerd Moellmann <gerd@gnu.org>.
21
22 Redisplay.
23
24 Emacs separates the task of updating the display from code
25 modifying global state, e.g. buffer text. This way functions
26 operating on buffers don't also have to be concerned with updating
27 the display.
28
29 Updating the display is triggered by the Lisp interpreter when it
30 decides it's time to do it. This is done either automatically for
31 you as part of the interpreter's command loop or as the result of
32 calling Lisp functions like `sit-for'. The C function `redisplay'
33 in xdisp.c is the only entry into the inner redisplay code.
34
35 The following diagram shows how redisplay code is invoked. As you
36 can see, Lisp calls redisplay and vice versa. Under window systems
37 like X, some portions of the redisplay code are also called
38 asynchronously during mouse movement or expose events. It is very
39 important that these code parts do NOT use the C library (malloc,
40 free) because many C libraries under Unix are not reentrant. They
41 may also NOT call functions of the Lisp interpreter which could
42 change the interpreter's state. If you don't follow these rules,
43 you will encounter bugs which are very hard to explain.
44
45 +--------------+ redisplay +----------------+
46 | Lisp machine |---------------->| Redisplay code |<--+
47 +--------------+ (xdisp.c) +----------------+ |
48 ^ | |
49 +----------------------------------+ |
50 Don't use this path when called |
51 asynchronously! |
52 |
53 expose_window (asynchronous) |
54 |
55 X expose events -----+
56
57 What does redisplay do? Obviously, it has to figure out somehow what
58 has been changed since the last time the display has been updated,
59 and to make these changes visible. Preferably it would do that in
60 a moderately intelligent way, i.e. fast.
61
62 Changes in buffer text can be deduced from window and buffer
63 structures, and from some global variables like `beg_unchanged' and
64 `end_unchanged'. The contents of the display are additionally
65 recorded in a `glyph matrix', a two-dimensional matrix of glyph
66 structures. Each row in such a matrix corresponds to a line on the
67 display, and each glyph in a row corresponds to a column displaying
68 a character, an image, or what else. This matrix is called the
69 `current glyph matrix' or `current matrix' in redisplay
70 terminology.
71
72 For buffer parts that have been changed since the last update, a
73 second glyph matrix is constructed, the so called `desired glyph
74 matrix' or short `desired matrix'. Current and desired matrix are
75 then compared to find a cheap way to update the display, e.g. by
76 reusing part of the display by scrolling lines.
77
78 You will find a lot of redisplay optimizations when you start
79 looking at the innards of redisplay. The overall goal of all these
80 optimizations is to make redisplay fast because it is done
81 frequently. Some of these optimizations are implemented by the
82 following functions:
83
84 . try_cursor_movement
85
86 This function tries to update the display if the text in the
87 window did not change and did not scroll, only point moved, and
88 it did not move off the displayed portion of the text.
89
90 . try_window_reusing_current_matrix
91
92 This function reuses the current matrix of a window when text
93 has not changed, but the window start changed (e.g., due to
94 scrolling).
95
96 . try_window_id
97
98 This function attempts to redisplay a window by reusing parts of
99 its existing display. It finds and reuses the part that was not
100 changed, and redraws the rest.
101
102 . try_window
103
104 This function performs the full redisplay of a single window
105 assuming that its fonts were not changed and that the cursor
106 will not end up in the scroll margins. (Loading fonts requires
107 re-adjustment of dimensions of glyph matrices, which makes this
108 method impossible to use.)
109
110 These optimizations are tried in sequence (some can be skipped if
111 it is known that they are not applicable). If none of the
112 optimizations were successful, redisplay calls redisplay_windows,
113 which performs a full redisplay of all windows.
114
115 Desired matrices.
116
117 Desired matrices are always built per Emacs window. The function
118 `display_line' is the central function to look at if you are
119 interested. It constructs one row in a desired matrix given an
120 iterator structure containing both a buffer position and a
121 description of the environment in which the text is to be
122 displayed. But this is too early, read on.
123
124 Characters and pixmaps displayed for a range of buffer text depend
125 on various settings of buffers and windows, on overlays and text
126 properties, on display tables, on selective display. The good news
127 is that all this hairy stuff is hidden behind a small set of
128 interface functions taking an iterator structure (struct it)
129 argument.
130
131 Iteration over things to be displayed is then simple. It is
132 started by initializing an iterator with a call to init_iterator,
133 passing it the buffer position where to start iteration. For
134 iteration over strings, pass -1 as the position to init_iterator,
135 and call reseat_to_string when the string is ready, to initialize
136 the iterator for that string. Thereafter, calls to
137 get_next_display_element fill the iterator structure with relevant
138 information about the next thing to display. Calls to
139 set_iterator_to_next move the iterator to the next thing.
140
141 Besides this, an iterator also contains information about the
142 display environment in which glyphs for display elements are to be
143 produced. It has fields for the width and height of the display,
144 the information whether long lines are truncated or continued, a
145 current X and Y position, and lots of other stuff you can better
146 see in dispextern.h.
147
148 Glyphs in a desired matrix are normally constructed in a loop
149 calling get_next_display_element and then PRODUCE_GLYPHS. The call
150 to PRODUCE_GLYPHS will fill the iterator structure with pixel
151 information about the element being displayed and at the same time
152 produce glyphs for it. If the display element fits on the line
153 being displayed, set_iterator_to_next is called next, otherwise the
154 glyphs produced are discarded. The function display_line is the
155 workhorse of filling glyph rows in the desired matrix with glyphs.
156 In addition to producing glyphs, it also handles line truncation
157 and continuation, word wrap, and cursor positioning (for the
158 latter, see also set_cursor_from_row).
159
160 Frame matrices.
161
162 That just couldn't be all, could it? What about terminal types not
163 supporting operations on sub-windows of the screen? To update the
164 display on such a terminal, window-based glyph matrices are not
165 well suited. To be able to reuse part of the display (scrolling
166 lines up and down), we must instead have a view of the whole
167 screen. This is what `frame matrices' are for. They are a trick.
168
169 Frames on terminals like above have a glyph pool. Windows on such
170 a frame sub-allocate their glyph memory from their frame's glyph
171 pool. The frame itself is given its own glyph matrices. By
172 coincidence---or maybe something else---rows in window glyph
173 matrices are slices of corresponding rows in frame matrices. Thus
174 writing to window matrices implicitly updates a frame matrix which
175 provides us with the view of the whole screen that we originally
176 wanted to have without having to move many bytes around. To be
177 honest, there is a little bit more done, but not much more. If you
178 plan to extend that code, take a look at dispnew.c. The function
179 build_frame_matrix is a good starting point.
180
181 Bidirectional display.
182
183 Bidirectional display adds quite some hair to this already complex
184 design. The good news are that a large portion of that hairy stuff
185 is hidden in bidi.c behind only 3 interfaces. bidi.c implements a
186 reordering engine which is called by set_iterator_to_next and
187 returns the next character to display in the visual order. See
188 commentary on bidi.c for more details. As far as redisplay is
189 concerned, the effect of calling bidi_move_to_visually_next, the
190 main interface of the reordering engine, is that the iterator gets
191 magically placed on the buffer or string position that is to be
192 displayed next. In other words, a linear iteration through the
193 buffer/string is replaced with a non-linear one. All the rest of
194 the redisplay is oblivious to the bidi reordering.
195
196 Well, almost oblivious---there are still complications, most of
197 them due to the fact that buffer and string positions no longer
198 change monotonously with glyph indices in a glyph row. Moreover,
199 for continued lines, the buffer positions may not even be
200 monotonously changing with vertical positions. Also, accounting
201 for face changes, overlays, etc. becomes more complex because
202 non-linear iteration could potentially skip many positions with
203 changes, and then cross them again on the way back...
204
205 One other prominent effect of bidirectional display is that some
206 paragraphs of text need to be displayed starting at the right
207 margin of the window---the so-called right-to-left, or R2L
208 paragraphs. R2L paragraphs are displayed with R2L glyph rows,
209 which have their reversed_p flag set. The bidi reordering engine
210 produces characters in such rows starting from the character which
211 should be the rightmost on display. PRODUCE_GLYPHS then reverses
212 the order, when it fills up the glyph row whose reversed_p flag is
213 set, by prepending each new glyph to what is already there, instead
214 of appending it. When the glyph row is complete, the function
215 extend_face_to_end_of_line fills the empty space to the left of the
216 leftmost character with special glyphs, which will display as,
217 well, empty. On text terminals, these special glyphs are simply
218 blank characters. On graphics terminals, there's a single stretch
219 glyph of a suitably computed width. Both the blanks and the
220 stretch glyph are given the face of the background of the line.
221 This way, the terminal-specific back-end can still draw the glyphs
222 left to right, even for R2L lines.
223
224 Bidirectional display and character compositions
225
226 Some scripts cannot be displayed by drawing each character
227 individually, because adjacent characters change each other's shape
228 on display. For example, Arabic and Indic scripts belong to this
229 category.
230
231 Emacs display supports this by providing "character compositions",
232 most of which is implemented in composite.c. During the buffer
233 scan that delivers characters to PRODUCE_GLYPHS, if the next
234 character to be delivered is a composed character, the iteration
235 calls composition_reseat_it and next_element_from_composition. If
236 they succeed to compose the character with one or more of the
237 following characters, the whole sequence of characters that where
238 composed is recorded in the `struct composition_it' object that is
239 part of the buffer iterator. The composed sequence could produce
240 one or more font glyphs (called "grapheme clusters") on the screen.
241 Each of these grapheme clusters is then delivered to PRODUCE_GLYPHS
242 in the direction corresponding to the current bidi scan direction
243 (recorded in the scan_dir member of the `struct bidi_it' object
244 that is part of the buffer iterator). In particular, if the bidi
245 iterator currently scans the buffer backwards, the grapheme
246 clusters are delivered back to front. This reorders the grapheme
247 clusters as appropriate for the current bidi context. Note that
248 this means that the grapheme clusters are always stored in the
249 LGSTRING object (see composite.c) in the logical order.
250
251 Moving an iterator in bidirectional text
252 without producing glyphs
253
254 Note one important detail mentioned above: that the bidi reordering
255 engine, driven by the iterator, produces characters in R2L rows
256 starting at the character that will be the rightmost on display.
257 As far as the iterator is concerned, the geometry of such rows is
258 still left to right, i.e. the iterator "thinks" the first character
259 is at the leftmost pixel position. The iterator does not know that
260 PRODUCE_GLYPHS reverses the order of the glyphs that the iterator
261 delivers. This is important when functions from the move_it_*
262 family are used to get to certain screen position or to match
263 screen coordinates with buffer coordinates: these functions use the
264 iterator geometry, which is left to right even in R2L paragraphs.
265 This works well with most callers of move_it_*, because they need
266 to get to a specific column, and columns are still numbered in the
267 reading order, i.e. the rightmost character in a R2L paragraph is
268 still column zero. But some callers do not get well with this; a
269 notable example is mouse clicks that need to find the character
270 that corresponds to certain pixel coordinates. See
271 buffer_posn_from_coords in dispnew.c for how this is handled. */
272
273 #include <config.h>
274 #include <stdio.h>
275 #include <limits.h>
276 #include <setjmp.h>
277
278 #include "lisp.h"
279 #include "keyboard.h"
280 #include "frame.h"
281 #include "window.h"
282 #include "termchar.h"
283 #include "dispextern.h"
284 #include "buffer.h"
285 #include "character.h"
286 #include "charset.h"
287 #include "indent.h"
288 #include "commands.h"
289 #include "keymap.h"
290 #include "macros.h"
291 #include "disptab.h"
292 #include "termhooks.h"
293 #include "termopts.h"
294 #include "intervals.h"
295 #include "coding.h"
296 #include "process.h"
297 #include "region-cache.h"
298 #include "font.h"
299 #include "fontset.h"
300 #include "blockinput.h"
301
302 #ifdef HAVE_X_WINDOWS
303 #include "xterm.h"
304 #endif
305 #ifdef WINDOWSNT
306 #include "w32term.h"
307 #endif
308 #ifdef HAVE_NS
309 #include "nsterm.h"
310 #endif
311 #ifdef USE_GTK
312 #include "gtkutil.h"
313 #endif
314
315 #include "font.h"
316
317 #ifndef FRAME_X_OUTPUT
318 #define FRAME_X_OUTPUT(f) ((f)->output_data.x)
319 #endif
320
321 #define INFINITY 10000000
322
323 Lisp_Object Qoverriding_local_map, Qoverriding_terminal_local_map;
324 Lisp_Object Qwindow_scroll_functions;
325 static Lisp_Object Qwindow_text_change_functions;
326 static Lisp_Object Qredisplay_end_trigger_functions;
327 Lisp_Object Qinhibit_point_motion_hooks;
328 static Lisp_Object QCeval, QCpropertize;
329 Lisp_Object QCfile, QCdata;
330 static Lisp_Object Qfontified;
331 static Lisp_Object Qgrow_only;
332 static Lisp_Object Qinhibit_eval_during_redisplay;
333 static Lisp_Object Qbuffer_position, Qposition, Qobject;
334 static Lisp_Object Qright_to_left, Qleft_to_right;
335
336 /* Cursor shapes */
337 Lisp_Object Qbar, Qhbar, Qbox, Qhollow;
338
339 /* Pointer shapes */
340 static Lisp_Object Qarrow, Qhand;
341 Lisp_Object Qtext;
342
343 /* Holds the list (error). */
344 static Lisp_Object list_of_error;
345
346 static Lisp_Object Qfontification_functions;
347
348 static Lisp_Object Qwrap_prefix;
349 static Lisp_Object Qline_prefix;
350
351 /* Non-nil means don't actually do any redisplay. */
352
353 Lisp_Object Qinhibit_redisplay;
354
355 /* Names of text properties relevant for redisplay. */
356
357 Lisp_Object Qdisplay;
358
359 Lisp_Object Qspace, QCalign_to;
360 static Lisp_Object QCrelative_width, QCrelative_height;
361 Lisp_Object Qleft_margin, Qright_margin;
362 static Lisp_Object Qspace_width, Qraise;
363 static Lisp_Object Qslice;
364 Lisp_Object Qcenter;
365 static Lisp_Object Qmargin, Qpointer;
366 static Lisp_Object Qline_height;
367
368 #ifdef HAVE_WINDOW_SYSTEM
369
370 /* Test if overflow newline into fringe. Called with iterator IT
371 at or past right window margin, and with IT->current_x set. */
372
373 #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(IT) \
374 (!NILP (Voverflow_newline_into_fringe) \
375 && FRAME_WINDOW_P ((IT)->f) \
376 && ((IT)->bidi_it.paragraph_dir == R2L \
377 ? (WINDOW_LEFT_FRINGE_WIDTH ((IT)->w) > 0) \
378 : (WINDOW_RIGHT_FRINGE_WIDTH ((IT)->w) > 0)) \
379 && (IT)->current_x == (IT)->last_visible_x \
380 && (IT)->line_wrap != WORD_WRAP)
381
382 #else /* !HAVE_WINDOW_SYSTEM */
383 #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(it) 0
384 #endif /* HAVE_WINDOW_SYSTEM */
385
386 /* Test if the display element loaded in IT is a space or tab
387 character. This is used to determine word wrapping. */
388
389 #define IT_DISPLAYING_WHITESPACE(it) \
390 (it->what == IT_CHARACTER && (it->c == ' ' || it->c == '\t'))
391
392 /* Name of the face used to highlight trailing whitespace. */
393
394 static Lisp_Object Qtrailing_whitespace;
395
396 /* Name and number of the face used to highlight escape glyphs. */
397
398 static Lisp_Object Qescape_glyph;
399
400 /* Name and number of the face used to highlight non-breaking spaces. */
401
402 static Lisp_Object Qnobreak_space;
403
404 /* The symbol `image' which is the car of the lists used to represent
405 images in Lisp. Also a tool bar style. */
406
407 Lisp_Object Qimage;
408
409 /* The image map types. */
410 Lisp_Object QCmap;
411 static Lisp_Object QCpointer;
412 static Lisp_Object Qrect, Qcircle, Qpoly;
413
414 /* Tool bar styles */
415 Lisp_Object Qboth, Qboth_horiz, Qtext_image_horiz;
416
417 /* Non-zero means print newline to stdout before next mini-buffer
418 message. */
419
420 int noninteractive_need_newline;
421
422 /* Non-zero means print newline to message log before next message. */
423
424 static int message_log_need_newline;
425
426 /* Three markers that message_dolog uses.
427 It could allocate them itself, but that causes trouble
428 in handling memory-full errors. */
429 static Lisp_Object message_dolog_marker1;
430 static Lisp_Object message_dolog_marker2;
431 static Lisp_Object message_dolog_marker3;
432 \f
433 /* The buffer position of the first character appearing entirely or
434 partially on the line of the selected window which contains the
435 cursor; <= 0 if not known. Set by set_cursor_from_row, used for
436 redisplay optimization in redisplay_internal. */
437
438 static struct text_pos this_line_start_pos;
439
440 /* Number of characters past the end of the line above, including the
441 terminating newline. */
442
443 static struct text_pos this_line_end_pos;
444
445 /* The vertical positions and the height of this line. */
446
447 static int this_line_vpos;
448 static int this_line_y;
449 static int this_line_pixel_height;
450
451 /* X position at which this display line starts. Usually zero;
452 negative if first character is partially visible. */
453
454 static int this_line_start_x;
455
456 /* The smallest character position seen by move_it_* functions as they
457 move across display lines. Used to set MATRIX_ROW_START_CHARPOS of
458 hscrolled lines, see display_line. */
459
460 static struct text_pos this_line_min_pos;
461
462 /* Buffer that this_line_.* variables are referring to. */
463
464 static struct buffer *this_line_buffer;
465
466
467 /* Values of those variables at last redisplay are stored as
468 properties on `overlay-arrow-position' symbol. However, if
469 Voverlay_arrow_position is a marker, last-arrow-position is its
470 numerical position. */
471
472 static Lisp_Object Qlast_arrow_position, Qlast_arrow_string;
473
474 /* Alternative overlay-arrow-string and overlay-arrow-bitmap
475 properties on a symbol in overlay-arrow-variable-list. */
476
477 static Lisp_Object Qoverlay_arrow_string, Qoverlay_arrow_bitmap;
478
479 Lisp_Object Qmenu_bar_update_hook;
480
481 /* Nonzero if an overlay arrow has been displayed in this window. */
482
483 static int overlay_arrow_seen;
484
485 /* Number of windows showing the buffer of the selected window (or
486 another buffer with the same base buffer). keyboard.c refers to
487 this. */
488
489 int buffer_shared;
490
491 /* Vector containing glyphs for an ellipsis `...'. */
492
493 static Lisp_Object default_invis_vector[3];
494
495 /* This is the window where the echo area message was displayed. It
496 is always a mini-buffer window, but it may not be the same window
497 currently active as a mini-buffer. */
498
499 Lisp_Object echo_area_window;
500
501 /* List of pairs (MESSAGE . MULTIBYTE). The function save_message
502 pushes the current message and the value of
503 message_enable_multibyte on the stack, the function restore_message
504 pops the stack and displays MESSAGE again. */
505
506 static Lisp_Object Vmessage_stack;
507
508 /* Nonzero means multibyte characters were enabled when the echo area
509 message was specified. */
510
511 static int message_enable_multibyte;
512
513 /* Nonzero if we should redraw the mode lines on the next redisplay. */
514
515 int update_mode_lines;
516
517 /* Nonzero if window sizes or contents have changed since last
518 redisplay that finished. */
519
520 int windows_or_buffers_changed;
521
522 /* Nonzero means a frame's cursor type has been changed. */
523
524 int cursor_type_changed;
525
526 /* Nonzero after display_mode_line if %l was used and it displayed a
527 line number. */
528
529 static int line_number_displayed;
530
531 /* The name of the *Messages* buffer, a string. */
532
533 static Lisp_Object Vmessages_buffer_name;
534
535 /* Current, index 0, and last displayed echo area message. Either
536 buffers from echo_buffers, or nil to indicate no message. */
537
538 Lisp_Object echo_area_buffer[2];
539
540 /* The buffers referenced from echo_area_buffer. */
541
542 static Lisp_Object echo_buffer[2];
543
544 /* A vector saved used in with_area_buffer to reduce consing. */
545
546 static Lisp_Object Vwith_echo_area_save_vector;
547
548 /* Non-zero means display_echo_area should display the last echo area
549 message again. Set by redisplay_preserve_echo_area. */
550
551 static int display_last_displayed_message_p;
552
553 /* Nonzero if echo area is being used by print; zero if being used by
554 message. */
555
556 static int message_buf_print;
557
558 /* The symbol `inhibit-menubar-update' and its DEFVAR_BOOL variable. */
559
560 static Lisp_Object Qinhibit_menubar_update;
561 static Lisp_Object Qmessage_truncate_lines;
562
563 /* Set to 1 in clear_message to make redisplay_internal aware
564 of an emptied echo area. */
565
566 static int message_cleared_p;
567
568 /* A scratch glyph row with contents used for generating truncation
569 glyphs. Also used in direct_output_for_insert. */
570
571 #define MAX_SCRATCH_GLYPHS 100
572 static struct glyph_row scratch_glyph_row;
573 static struct glyph scratch_glyphs[MAX_SCRATCH_GLYPHS];
574
575 /* Ascent and height of the last line processed by move_it_to. */
576
577 static int last_max_ascent, last_height;
578
579 /* Non-zero if there's a help-echo in the echo area. */
580
581 int help_echo_showing_p;
582
583 /* If >= 0, computed, exact values of mode-line and header-line height
584 to use in the macros CURRENT_MODE_LINE_HEIGHT and
585 CURRENT_HEADER_LINE_HEIGHT. */
586
587 int current_mode_line_height, current_header_line_height;
588
589 /* The maximum distance to look ahead for text properties. Values
590 that are too small let us call compute_char_face and similar
591 functions too often which is expensive. Values that are too large
592 let us call compute_char_face and alike too often because we
593 might not be interested in text properties that far away. */
594
595 #define TEXT_PROP_DISTANCE_LIMIT 100
596
597 /* SAVE_IT and RESTORE_IT are called when we save a snapshot of the
598 iterator state and later restore it. This is needed because the
599 bidi iterator on bidi.c keeps a stacked cache of its states, which
600 is really a singleton. When we use scratch iterator objects to
601 move around the buffer, we can cause the bidi cache to be pushed or
602 popped, and therefore we need to restore the cache state when we
603 return to the original iterator. */
604 #define SAVE_IT(ITCOPY,ITORIG,CACHE) \
605 do { \
606 if (CACHE) \
607 bidi_unshelve_cache (CACHE, 1); \
608 ITCOPY = ITORIG; \
609 CACHE = bidi_shelve_cache (); \
610 } while (0)
611
612 #define RESTORE_IT(pITORIG,pITCOPY,CACHE) \
613 do { \
614 if (pITORIG != pITCOPY) \
615 *(pITORIG) = *(pITCOPY); \
616 bidi_unshelve_cache (CACHE, 0); \
617 CACHE = NULL; \
618 } while (0)
619
620 #if GLYPH_DEBUG
621
622 /* Non-zero means print traces of redisplay if compiled with
623 GLYPH_DEBUG != 0. */
624
625 int trace_redisplay_p;
626
627 #endif /* GLYPH_DEBUG */
628
629 #ifdef DEBUG_TRACE_MOVE
630 /* Non-zero means trace with TRACE_MOVE to stderr. */
631 int trace_move;
632
633 #define TRACE_MOVE(x) if (trace_move) fprintf x; else (void) 0
634 #else
635 #define TRACE_MOVE(x) (void) 0
636 #endif
637
638 static Lisp_Object Qauto_hscroll_mode;
639
640 /* Buffer being redisplayed -- for redisplay_window_error. */
641
642 static struct buffer *displayed_buffer;
643
644 /* Value returned from text property handlers (see below). */
645
646 enum prop_handled
647 {
648 HANDLED_NORMALLY,
649 HANDLED_RECOMPUTE_PROPS,
650 HANDLED_OVERLAY_STRING_CONSUMED,
651 HANDLED_RETURN
652 };
653
654 /* A description of text properties that redisplay is interested
655 in. */
656
657 struct props
658 {
659 /* The name of the property. */
660 Lisp_Object *name;
661
662 /* A unique index for the property. */
663 enum prop_idx idx;
664
665 /* A handler function called to set up iterator IT from the property
666 at IT's current position. Value is used to steer handle_stop. */
667 enum prop_handled (*handler) (struct it *it);
668 };
669
670 static enum prop_handled handle_face_prop (struct it *);
671 static enum prop_handled handle_invisible_prop (struct it *);
672 static enum prop_handled handle_display_prop (struct it *);
673 static enum prop_handled handle_composition_prop (struct it *);
674 static enum prop_handled handle_overlay_change (struct it *);
675 static enum prop_handled handle_fontified_prop (struct it *);
676
677 /* Properties handled by iterators. */
678
679 static struct props it_props[] =
680 {
681 {&Qfontified, FONTIFIED_PROP_IDX, handle_fontified_prop},
682 /* Handle `face' before `display' because some sub-properties of
683 `display' need to know the face. */
684 {&Qface, FACE_PROP_IDX, handle_face_prop},
685 {&Qdisplay, DISPLAY_PROP_IDX, handle_display_prop},
686 {&Qinvisible, INVISIBLE_PROP_IDX, handle_invisible_prop},
687 {&Qcomposition, COMPOSITION_PROP_IDX, handle_composition_prop},
688 {NULL, 0, NULL}
689 };
690
691 /* Value is the position described by X. If X is a marker, value is
692 the marker_position of X. Otherwise, value is X. */
693
694 #define COERCE_MARKER(X) (MARKERP ((X)) ? Fmarker_position (X) : (X))
695
696 /* Enumeration returned by some move_it_.* functions internally. */
697
698 enum move_it_result
699 {
700 /* Not used. Undefined value. */
701 MOVE_UNDEFINED,
702
703 /* Move ended at the requested buffer position or ZV. */
704 MOVE_POS_MATCH_OR_ZV,
705
706 /* Move ended at the requested X pixel position. */
707 MOVE_X_REACHED,
708
709 /* Move within a line ended at the end of a line that must be
710 continued. */
711 MOVE_LINE_CONTINUED,
712
713 /* Move within a line ended at the end of a line that would
714 be displayed truncated. */
715 MOVE_LINE_TRUNCATED,
716
717 /* Move within a line ended at a line end. */
718 MOVE_NEWLINE_OR_CR
719 };
720
721 /* This counter is used to clear the face cache every once in a while
722 in redisplay_internal. It is incremented for each redisplay.
723 Every CLEAR_FACE_CACHE_COUNT full redisplays, the face cache is
724 cleared. */
725
726 #define CLEAR_FACE_CACHE_COUNT 500
727 static int clear_face_cache_count;
728
729 /* Similarly for the image cache. */
730
731 #ifdef HAVE_WINDOW_SYSTEM
732 #define CLEAR_IMAGE_CACHE_COUNT 101
733 static int clear_image_cache_count;
734
735 /* Null glyph slice */
736 static struct glyph_slice null_glyph_slice = { 0, 0, 0, 0 };
737 #endif
738
739 /* Non-zero while redisplay_internal is in progress. */
740
741 int redisplaying_p;
742
743 static Lisp_Object Qinhibit_free_realized_faces;
744
745 /* If a string, XTread_socket generates an event to display that string.
746 (The display is done in read_char.) */
747
748 Lisp_Object help_echo_string;
749 Lisp_Object help_echo_window;
750 Lisp_Object help_echo_object;
751 EMACS_INT help_echo_pos;
752
753 /* Temporary variable for XTread_socket. */
754
755 Lisp_Object previous_help_echo_string;
756
757 /* Platform-independent portion of hourglass implementation. */
758
759 /* Non-zero means an hourglass cursor is currently shown. */
760 int hourglass_shown_p;
761
762 /* If non-null, an asynchronous timer that, when it expires, displays
763 an hourglass cursor on all frames. */
764 struct atimer *hourglass_atimer;
765
766 /* Name of the face used to display glyphless characters. */
767 Lisp_Object Qglyphless_char;
768
769 /* Symbol for the purpose of Vglyphless_char_display. */
770 static Lisp_Object Qglyphless_char_display;
771
772 /* Method symbols for Vglyphless_char_display. */
773 static Lisp_Object Qhex_code, Qempty_box, Qthin_space, Qzero_width;
774
775 /* Default pixel width of `thin-space' display method. */
776 #define THIN_SPACE_WIDTH 1
777
778 /* Default number of seconds to wait before displaying an hourglass
779 cursor. */
780 #define DEFAULT_HOURGLASS_DELAY 1
781
782 \f
783 /* Function prototypes. */
784
785 static void setup_for_ellipsis (struct it *, int);
786 static void set_iterator_to_next (struct it *, int);
787 static void mark_window_display_accurate_1 (struct window *, int);
788 static int single_display_spec_string_p (Lisp_Object, Lisp_Object);
789 static int display_prop_string_p (Lisp_Object, Lisp_Object);
790 static int cursor_row_p (struct glyph_row *);
791 static int redisplay_mode_lines (Lisp_Object, int);
792 static char *decode_mode_spec_coding (Lisp_Object, char *, int);
793
794 static Lisp_Object get_it_property (struct it *it, Lisp_Object prop);
795
796 static void handle_line_prefix (struct it *);
797
798 static void pint2str (char *, int, EMACS_INT);
799 static void pint2hrstr (char *, int, EMACS_INT);
800 static struct text_pos run_window_scroll_functions (Lisp_Object,
801 struct text_pos);
802 static void reconsider_clip_changes (struct window *, struct buffer *);
803 static int text_outside_line_unchanged_p (struct window *,
804 EMACS_INT, EMACS_INT);
805 static void store_mode_line_noprop_char (char);
806 static int store_mode_line_noprop (const char *, int, int);
807 static void handle_stop (struct it *);
808 static void handle_stop_backwards (struct it *, EMACS_INT);
809 static void vmessage (const char *, va_list) ATTRIBUTE_FORMAT_PRINTF (1, 0);
810 static void ensure_echo_area_buffers (void);
811 static Lisp_Object unwind_with_echo_area_buffer (Lisp_Object);
812 static Lisp_Object with_echo_area_buffer_unwind_data (struct window *);
813 static int with_echo_area_buffer (struct window *, int,
814 int (*) (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT),
815 EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT);
816 static void clear_garbaged_frames (void);
817 static int current_message_1 (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT);
818 static void pop_message (void);
819 static int truncate_message_1 (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT);
820 static void set_message (const char *, Lisp_Object, EMACS_INT, int);
821 static int set_message_1 (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT);
822 static int display_echo_area (struct window *);
823 static int display_echo_area_1 (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT);
824 static int resize_mini_window_1 (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT);
825 static Lisp_Object unwind_redisplay (Lisp_Object);
826 static int string_char_and_length (const unsigned char *, int *);
827 static struct text_pos display_prop_end (struct it *, Lisp_Object,
828 struct text_pos);
829 static int compute_window_start_on_continuation_line (struct window *);
830 static Lisp_Object safe_eval_handler (Lisp_Object);
831 static void insert_left_trunc_glyphs (struct it *);
832 static struct glyph_row *get_overlay_arrow_glyph_row (struct window *,
833 Lisp_Object);
834 static void extend_face_to_end_of_line (struct it *);
835 static int append_space_for_newline (struct it *, int);
836 static int cursor_row_fully_visible_p (struct window *, int, int);
837 static int try_scrolling (Lisp_Object, int, EMACS_INT, EMACS_INT, int, int);
838 static int try_cursor_movement (Lisp_Object, struct text_pos, int *);
839 static int trailing_whitespace_p (EMACS_INT);
840 static intmax_t message_log_check_duplicate (EMACS_INT, EMACS_INT);
841 static void push_it (struct it *, struct text_pos *);
842 static void pop_it (struct it *);
843 static void sync_frame_with_window_matrix_rows (struct window *);
844 static void select_frame_for_redisplay (Lisp_Object);
845 static void redisplay_internal (void);
846 static int echo_area_display (int);
847 static void redisplay_windows (Lisp_Object);
848 static void redisplay_window (Lisp_Object, int);
849 static Lisp_Object redisplay_window_error (Lisp_Object);
850 static Lisp_Object redisplay_window_0 (Lisp_Object);
851 static Lisp_Object redisplay_window_1 (Lisp_Object);
852 static int set_cursor_from_row (struct window *, struct glyph_row *,
853 struct glyph_matrix *, EMACS_INT, EMACS_INT,
854 int, int);
855 static int update_menu_bar (struct frame *, int, int);
856 static int try_window_reusing_current_matrix (struct window *);
857 static int try_window_id (struct window *);
858 static int display_line (struct it *);
859 static int display_mode_lines (struct window *);
860 static int display_mode_line (struct window *, enum face_id, Lisp_Object);
861 static int display_mode_element (struct it *, int, int, int, Lisp_Object, Lisp_Object, int);
862 static int store_mode_line_string (const char *, Lisp_Object, int, int, int, Lisp_Object);
863 static const char *decode_mode_spec (struct window *, int, int, Lisp_Object *);
864 static void display_menu_bar (struct window *);
865 static EMACS_INT display_count_lines (EMACS_INT, EMACS_INT, EMACS_INT,
866 EMACS_INT *);
867 static int display_string (const char *, Lisp_Object, Lisp_Object,
868 EMACS_INT, EMACS_INT, struct it *, int, int, int, int);
869 static void compute_line_metrics (struct it *);
870 static void run_redisplay_end_trigger_hook (struct it *);
871 static int get_overlay_strings (struct it *, EMACS_INT);
872 static int get_overlay_strings_1 (struct it *, EMACS_INT, int);
873 static void next_overlay_string (struct it *);
874 static void reseat (struct it *, struct text_pos, int);
875 static void reseat_1 (struct it *, struct text_pos, int);
876 static void back_to_previous_visible_line_start (struct it *);
877 void reseat_at_previous_visible_line_start (struct it *);
878 static void reseat_at_next_visible_line_start (struct it *, int);
879 static int next_element_from_ellipsis (struct it *);
880 static int next_element_from_display_vector (struct it *);
881 static int next_element_from_string (struct it *);
882 static int next_element_from_c_string (struct it *);
883 static int next_element_from_buffer (struct it *);
884 static int next_element_from_composition (struct it *);
885 static int next_element_from_image (struct it *);
886 static int next_element_from_stretch (struct it *);
887 static void load_overlay_strings (struct it *, EMACS_INT);
888 static int init_from_display_pos (struct it *, struct window *,
889 struct display_pos *);
890 static void reseat_to_string (struct it *, const char *,
891 Lisp_Object, EMACS_INT, EMACS_INT, int, int);
892 static int get_next_display_element (struct it *);
893 static enum move_it_result
894 move_it_in_display_line_to (struct it *, EMACS_INT, int,
895 enum move_operation_enum);
896 void move_it_vertically_backward (struct it *, int);
897 static void init_to_row_start (struct it *, struct window *,
898 struct glyph_row *);
899 static int init_to_row_end (struct it *, struct window *,
900 struct glyph_row *);
901 static void back_to_previous_line_start (struct it *);
902 static int forward_to_next_line_start (struct it *, int *, struct bidi_it *);
903 static struct text_pos string_pos_nchars_ahead (struct text_pos,
904 Lisp_Object, EMACS_INT);
905 static struct text_pos string_pos (EMACS_INT, Lisp_Object);
906 static struct text_pos c_string_pos (EMACS_INT, const char *, int);
907 static EMACS_INT number_of_chars (const char *, int);
908 static void compute_stop_pos (struct it *);
909 static void compute_string_pos (struct text_pos *, struct text_pos,
910 Lisp_Object);
911 static int face_before_or_after_it_pos (struct it *, int);
912 static EMACS_INT next_overlay_change (EMACS_INT);
913 static int handle_display_spec (struct it *, Lisp_Object, Lisp_Object,
914 Lisp_Object, struct text_pos *, EMACS_INT, int);
915 static int handle_single_display_spec (struct it *, Lisp_Object,
916 Lisp_Object, Lisp_Object,
917 struct text_pos *, EMACS_INT, int, int);
918 static int underlying_face_id (struct it *);
919 static int in_ellipses_for_invisible_text_p (struct display_pos *,
920 struct window *);
921
922 #define face_before_it_pos(IT) face_before_or_after_it_pos ((IT), 1)
923 #define face_after_it_pos(IT) face_before_or_after_it_pos ((IT), 0)
924
925 #ifdef HAVE_WINDOW_SYSTEM
926
927 static void x_consider_frame_title (Lisp_Object);
928 static int tool_bar_lines_needed (struct frame *, int *);
929 static void update_tool_bar (struct frame *, int);
930 static void build_desired_tool_bar_string (struct frame *f);
931 static int redisplay_tool_bar (struct frame *);
932 static void display_tool_bar_line (struct it *, int);
933 static void notice_overwritten_cursor (struct window *,
934 enum glyph_row_area,
935 int, int, int, int);
936 static void append_stretch_glyph (struct it *, Lisp_Object,
937 int, int, int);
938
939
940 #endif /* HAVE_WINDOW_SYSTEM */
941
942 static void show_mouse_face (Mouse_HLInfo *, enum draw_glyphs_face);
943 static int coords_in_mouse_face_p (struct window *, int, int);
944
945
946 \f
947 /***********************************************************************
948 Window display dimensions
949 ***********************************************************************/
950
951 /* Return the bottom boundary y-position for text lines in window W.
952 This is the first y position at which a line cannot start.
953 It is relative to the top of the window.
954
955 This is the height of W minus the height of a mode line, if any. */
956
957 inline int
958 window_text_bottom_y (struct window *w)
959 {
960 int height = WINDOW_TOTAL_HEIGHT (w);
961
962 if (WINDOW_WANTS_MODELINE_P (w))
963 height -= CURRENT_MODE_LINE_HEIGHT (w);
964 return height;
965 }
966
967 /* Return the pixel width of display area AREA of window W. AREA < 0
968 means return the total width of W, not including fringes to
969 the left and right of the window. */
970
971 inline int
972 window_box_width (struct window *w, int area)
973 {
974 int cols = XFASTINT (w->total_cols);
975 int pixels = 0;
976
977 if (!w->pseudo_window_p)
978 {
979 cols -= WINDOW_SCROLL_BAR_COLS (w);
980
981 if (area == TEXT_AREA)
982 {
983 if (INTEGERP (w->left_margin_cols))
984 cols -= XFASTINT (w->left_margin_cols);
985 if (INTEGERP (w->right_margin_cols))
986 cols -= XFASTINT (w->right_margin_cols);
987 pixels = -WINDOW_TOTAL_FRINGE_WIDTH (w);
988 }
989 else if (area == LEFT_MARGIN_AREA)
990 {
991 cols = (INTEGERP (w->left_margin_cols)
992 ? XFASTINT (w->left_margin_cols) : 0);
993 pixels = 0;
994 }
995 else if (area == RIGHT_MARGIN_AREA)
996 {
997 cols = (INTEGERP (w->right_margin_cols)
998 ? XFASTINT (w->right_margin_cols) : 0);
999 pixels = 0;
1000 }
1001 }
1002
1003 return cols * WINDOW_FRAME_COLUMN_WIDTH (w) + pixels;
1004 }
1005
1006
1007 /* Return the pixel height of the display area of window W, not
1008 including mode lines of W, if any. */
1009
1010 inline int
1011 window_box_height (struct window *w)
1012 {
1013 struct frame *f = XFRAME (w->frame);
1014 int height = WINDOW_TOTAL_HEIGHT (w);
1015
1016 xassert (height >= 0);
1017
1018 /* Note: the code below that determines the mode-line/header-line
1019 height is essentially the same as that contained in the macro
1020 CURRENT_{MODE,HEADER}_LINE_HEIGHT, except that it checks whether
1021 the appropriate glyph row has its `mode_line_p' flag set,
1022 and if it doesn't, uses estimate_mode_line_height instead. */
1023
1024 if (WINDOW_WANTS_MODELINE_P (w))
1025 {
1026 struct glyph_row *ml_row
1027 = (w->current_matrix && w->current_matrix->rows
1028 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
1029 : 0);
1030 if (ml_row && ml_row->mode_line_p)
1031 height -= ml_row->height;
1032 else
1033 height -= estimate_mode_line_height (f, CURRENT_MODE_LINE_FACE_ID (w));
1034 }
1035
1036 if (WINDOW_WANTS_HEADER_LINE_P (w))
1037 {
1038 struct glyph_row *hl_row
1039 = (w->current_matrix && w->current_matrix->rows
1040 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
1041 : 0);
1042 if (hl_row && hl_row->mode_line_p)
1043 height -= hl_row->height;
1044 else
1045 height -= estimate_mode_line_height (f, HEADER_LINE_FACE_ID);
1046 }
1047
1048 /* With a very small font and a mode-line that's taller than
1049 default, we might end up with a negative height. */
1050 return max (0, height);
1051 }
1052
1053 /* Return the window-relative coordinate of the left edge of display
1054 area AREA of window W. AREA < 0 means return the left edge of the
1055 whole window, to the right of the left fringe of W. */
1056
1057 inline int
1058 window_box_left_offset (struct window *w, int area)
1059 {
1060 int x;
1061
1062 if (w->pseudo_window_p)
1063 return 0;
1064
1065 x = WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
1066
1067 if (area == TEXT_AREA)
1068 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1069 + window_box_width (w, LEFT_MARGIN_AREA));
1070 else if (area == RIGHT_MARGIN_AREA)
1071 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1072 + window_box_width (w, LEFT_MARGIN_AREA)
1073 + window_box_width (w, TEXT_AREA)
1074 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
1075 ? 0
1076 : WINDOW_RIGHT_FRINGE_WIDTH (w)));
1077 else if (area == LEFT_MARGIN_AREA
1078 && WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w))
1079 x += WINDOW_LEFT_FRINGE_WIDTH (w);
1080
1081 return x;
1082 }
1083
1084
1085 /* Return the window-relative coordinate of the right edge of display
1086 area AREA of window W. AREA < 0 means return the right edge of the
1087 whole window, to the left of the right fringe of W. */
1088
1089 inline int
1090 window_box_right_offset (struct window *w, int area)
1091 {
1092 return window_box_left_offset (w, area) + window_box_width (w, area);
1093 }
1094
1095 /* Return the frame-relative coordinate of the left edge of display
1096 area AREA of window W. AREA < 0 means return the left edge of the
1097 whole window, to the right of the left fringe of W. */
1098
1099 inline int
1100 window_box_left (struct window *w, int area)
1101 {
1102 struct frame *f = XFRAME (w->frame);
1103 int x;
1104
1105 if (w->pseudo_window_p)
1106 return FRAME_INTERNAL_BORDER_WIDTH (f);
1107
1108 x = (WINDOW_LEFT_EDGE_X (w)
1109 + window_box_left_offset (w, area));
1110
1111 return x;
1112 }
1113
1114
1115 /* Return the frame-relative coordinate of the right edge of display
1116 area AREA of window W. AREA < 0 means return the right edge of the
1117 whole window, to the left of the right fringe of W. */
1118
1119 inline int
1120 window_box_right (struct window *w, int area)
1121 {
1122 return window_box_left (w, area) + window_box_width (w, area);
1123 }
1124
1125 /* Get the bounding box of the display area AREA of window W, without
1126 mode lines, in frame-relative coordinates. AREA < 0 means the
1127 whole window, not including the left and right fringes of
1128 the window. Return in *BOX_X and *BOX_Y the frame-relative pixel
1129 coordinates of the upper-left corner of the box. Return in
1130 *BOX_WIDTH, and *BOX_HEIGHT the pixel width and height of the box. */
1131
1132 inline void
1133 window_box (struct window *w, int area, int *box_x, int *box_y,
1134 int *box_width, int *box_height)
1135 {
1136 if (box_width)
1137 *box_width = window_box_width (w, area);
1138 if (box_height)
1139 *box_height = window_box_height (w);
1140 if (box_x)
1141 *box_x = window_box_left (w, area);
1142 if (box_y)
1143 {
1144 *box_y = WINDOW_TOP_EDGE_Y (w);
1145 if (WINDOW_WANTS_HEADER_LINE_P (w))
1146 *box_y += CURRENT_HEADER_LINE_HEIGHT (w);
1147 }
1148 }
1149
1150
1151 /* Get the bounding box of the display area AREA of window W, without
1152 mode lines. AREA < 0 means the whole window, not including the
1153 left and right fringe of the window. Return in *TOP_LEFT_X
1154 and TOP_LEFT_Y the frame-relative pixel coordinates of the
1155 upper-left corner of the box. Return in *BOTTOM_RIGHT_X, and
1156 *BOTTOM_RIGHT_Y the coordinates of the bottom-right corner of the
1157 box. */
1158
1159 static inline void
1160 window_box_edges (struct window *w, int area, int *top_left_x, int *top_left_y,
1161 int *bottom_right_x, int *bottom_right_y)
1162 {
1163 window_box (w, area, top_left_x, top_left_y, bottom_right_x,
1164 bottom_right_y);
1165 *bottom_right_x += *top_left_x;
1166 *bottom_right_y += *top_left_y;
1167 }
1168
1169
1170 \f
1171 /***********************************************************************
1172 Utilities
1173 ***********************************************************************/
1174
1175 /* Return the bottom y-position of the line the iterator IT is in.
1176 This can modify IT's settings. */
1177
1178 int
1179 line_bottom_y (struct it *it)
1180 {
1181 int line_height = it->max_ascent + it->max_descent;
1182 int line_top_y = it->current_y;
1183
1184 if (line_height == 0)
1185 {
1186 if (last_height)
1187 line_height = last_height;
1188 else if (IT_CHARPOS (*it) < ZV)
1189 {
1190 move_it_by_lines (it, 1);
1191 line_height = (it->max_ascent || it->max_descent
1192 ? it->max_ascent + it->max_descent
1193 : last_height);
1194 }
1195 else
1196 {
1197 struct glyph_row *row = it->glyph_row;
1198
1199 /* Use the default character height. */
1200 it->glyph_row = NULL;
1201 it->what = IT_CHARACTER;
1202 it->c = ' ';
1203 it->len = 1;
1204 PRODUCE_GLYPHS (it);
1205 line_height = it->ascent + it->descent;
1206 it->glyph_row = row;
1207 }
1208 }
1209
1210 return line_top_y + line_height;
1211 }
1212
1213
1214 /* Return 1 if position CHARPOS is visible in window W.
1215 CHARPOS < 0 means return info about WINDOW_END position.
1216 If visible, set *X and *Y to pixel coordinates of top left corner.
1217 Set *RTOP and *RBOT to pixel height of an invisible area of glyph at POS.
1218 Set *ROWH and *VPOS to row's visible height and VPOS (row number). */
1219
1220 int
1221 pos_visible_p (struct window *w, EMACS_INT charpos, int *x, int *y,
1222 int *rtop, int *rbot, int *rowh, int *vpos)
1223 {
1224 struct it it;
1225 void *itdata = bidi_shelve_cache ();
1226 struct text_pos top;
1227 int visible_p = 0;
1228 struct buffer *old_buffer = NULL;
1229
1230 if (FRAME_INITIAL_P (XFRAME (WINDOW_FRAME (w))))
1231 return visible_p;
1232
1233 if (XBUFFER (w->buffer) != current_buffer)
1234 {
1235 old_buffer = current_buffer;
1236 set_buffer_internal_1 (XBUFFER (w->buffer));
1237 }
1238
1239 SET_TEXT_POS_FROM_MARKER (top, w->start);
1240
1241 /* Compute exact mode line heights. */
1242 if (WINDOW_WANTS_MODELINE_P (w))
1243 current_mode_line_height
1244 = display_mode_line (w, CURRENT_MODE_LINE_FACE_ID (w),
1245 BVAR (current_buffer, mode_line_format));
1246
1247 if (WINDOW_WANTS_HEADER_LINE_P (w))
1248 current_header_line_height
1249 = display_mode_line (w, HEADER_LINE_FACE_ID,
1250 BVAR (current_buffer, header_line_format));
1251
1252 start_display (&it, w, top);
1253 move_it_to (&it, charpos, -1, it.last_visible_y-1, -1,
1254 (charpos >= 0 ? MOVE_TO_POS : 0) | MOVE_TO_Y);
1255
1256 if (charpos >= 0
1257 && (((!it.bidi_p || it.bidi_it.scan_dir == 1)
1258 && IT_CHARPOS (it) >= charpos)
1259 /* When scanning backwards under bidi iteration, move_it_to
1260 stops at or _before_ CHARPOS, because it stops at or to
1261 the _right_ of the character at CHARPOS. */
1262 || (it.bidi_p && it.bidi_it.scan_dir == -1
1263 && IT_CHARPOS (it) <= charpos)))
1264 {
1265 /* We have reached CHARPOS, or passed it. How the call to
1266 move_it_to can overshoot: (i) If CHARPOS is on invisible text
1267 or covered by a display property, move_it_to stops at the end
1268 of the invisible text, to the right of CHARPOS. (ii) If
1269 CHARPOS is in a display vector, move_it_to stops on its last
1270 glyph. */
1271 int top_x = it.current_x;
1272 int top_y = it.current_y;
1273 enum it_method it_method = it.method;
1274 /* Calling line_bottom_y may change it.method, it.position, etc. */
1275 int bottom_y = (last_height = 0, line_bottom_y (&it));
1276 int window_top_y = WINDOW_HEADER_LINE_HEIGHT (w);
1277
1278 if (top_y < window_top_y)
1279 visible_p = bottom_y > window_top_y;
1280 else if (top_y < it.last_visible_y)
1281 visible_p = 1;
1282 if (visible_p)
1283 {
1284 if (it_method == GET_FROM_DISPLAY_VECTOR)
1285 {
1286 /* We stopped on the last glyph of a display vector.
1287 Try and recompute. Hack alert! */
1288 if (charpos < 2 || top.charpos >= charpos)
1289 top_x = it.glyph_row->x;
1290 else
1291 {
1292 struct it it2;
1293 start_display (&it2, w, top);
1294 move_it_to (&it2, charpos - 1, -1, -1, -1, MOVE_TO_POS);
1295 get_next_display_element (&it2);
1296 PRODUCE_GLYPHS (&it2);
1297 if (ITERATOR_AT_END_OF_LINE_P (&it2)
1298 || it2.current_x > it2.last_visible_x)
1299 top_x = it.glyph_row->x;
1300 else
1301 {
1302 top_x = it2.current_x;
1303 top_y = it2.current_y;
1304 }
1305 }
1306 }
1307
1308 *x = top_x;
1309 *y = max (top_y + max (0, it.max_ascent - it.ascent), window_top_y);
1310 *rtop = max (0, window_top_y - top_y);
1311 *rbot = max (0, bottom_y - it.last_visible_y);
1312 *rowh = max (0, (min (bottom_y, it.last_visible_y)
1313 - max (top_y, window_top_y)));
1314 *vpos = it.vpos;
1315 }
1316 }
1317 else
1318 {
1319 /* We were asked to provide info about WINDOW_END. */
1320 struct it it2;
1321 void *it2data = NULL;
1322
1323 SAVE_IT (it2, it, it2data);
1324 if (IT_CHARPOS (it) < ZV && FETCH_BYTE (IT_BYTEPOS (it)) != '\n')
1325 move_it_by_lines (&it, 1);
1326 if (charpos < IT_CHARPOS (it)
1327 || (it.what == IT_EOB && charpos == IT_CHARPOS (it)))
1328 {
1329 visible_p = 1;
1330 RESTORE_IT (&it2, &it2, it2data);
1331 move_it_to (&it2, charpos, -1, -1, -1, MOVE_TO_POS);
1332 *x = it2.current_x;
1333 *y = it2.current_y + it2.max_ascent - it2.ascent;
1334 *rtop = max (0, -it2.current_y);
1335 *rbot = max (0, ((it2.current_y + it2.max_ascent + it2.max_descent)
1336 - it.last_visible_y));
1337 *rowh = max (0, (min (it2.current_y + it2.max_ascent + it2.max_descent,
1338 it.last_visible_y)
1339 - max (it2.current_y,
1340 WINDOW_HEADER_LINE_HEIGHT (w))));
1341 *vpos = it2.vpos;
1342 }
1343 else
1344 bidi_unshelve_cache (it2data, 1);
1345 }
1346 bidi_unshelve_cache (itdata, 0);
1347
1348 if (old_buffer)
1349 set_buffer_internal_1 (old_buffer);
1350
1351 current_header_line_height = current_mode_line_height = -1;
1352
1353 if (visible_p && XFASTINT (w->hscroll) > 0)
1354 *x -= XFASTINT (w->hscroll) * WINDOW_FRAME_COLUMN_WIDTH (w);
1355
1356 #if 0
1357 /* Debugging code. */
1358 if (visible_p)
1359 fprintf (stderr, "+pv pt=%d vs=%d --> x=%d y=%d rt=%d rb=%d rh=%d vp=%d\n",
1360 charpos, w->vscroll, *x, *y, *rtop, *rbot, *rowh, *vpos);
1361 else
1362 fprintf (stderr, "-pv pt=%d vs=%d\n", charpos, w->vscroll);
1363 #endif
1364
1365 return visible_p;
1366 }
1367
1368
1369 /* Return the next character from STR. Return in *LEN the length of
1370 the character. This is like STRING_CHAR_AND_LENGTH but never
1371 returns an invalid character. If we find one, we return a `?', but
1372 with the length of the invalid character. */
1373
1374 static inline int
1375 string_char_and_length (const unsigned char *str, int *len)
1376 {
1377 int c;
1378
1379 c = STRING_CHAR_AND_LENGTH (str, *len);
1380 if (!CHAR_VALID_P (c))
1381 /* We may not change the length here because other places in Emacs
1382 don't use this function, i.e. they silently accept invalid
1383 characters. */
1384 c = '?';
1385
1386 return c;
1387 }
1388
1389
1390
1391 /* Given a position POS containing a valid character and byte position
1392 in STRING, return the position NCHARS ahead (NCHARS >= 0). */
1393
1394 static struct text_pos
1395 string_pos_nchars_ahead (struct text_pos pos, Lisp_Object string, EMACS_INT nchars)
1396 {
1397 xassert (STRINGP (string) && nchars >= 0);
1398
1399 if (STRING_MULTIBYTE (string))
1400 {
1401 const unsigned char *p = SDATA (string) + BYTEPOS (pos);
1402 int len;
1403
1404 while (nchars--)
1405 {
1406 string_char_and_length (p, &len);
1407 p += len;
1408 CHARPOS (pos) += 1;
1409 BYTEPOS (pos) += len;
1410 }
1411 }
1412 else
1413 SET_TEXT_POS (pos, CHARPOS (pos) + nchars, BYTEPOS (pos) + nchars);
1414
1415 return pos;
1416 }
1417
1418
1419 /* Value is the text position, i.e. character and byte position,
1420 for character position CHARPOS in STRING. */
1421
1422 static inline struct text_pos
1423 string_pos (EMACS_INT charpos, Lisp_Object string)
1424 {
1425 struct text_pos pos;
1426 xassert (STRINGP (string));
1427 xassert (charpos >= 0);
1428 SET_TEXT_POS (pos, charpos, string_char_to_byte (string, charpos));
1429 return pos;
1430 }
1431
1432
1433 /* Value is a text position, i.e. character and byte position, for
1434 character position CHARPOS in C string S. MULTIBYTE_P non-zero
1435 means recognize multibyte characters. */
1436
1437 static struct text_pos
1438 c_string_pos (EMACS_INT charpos, const char *s, int multibyte_p)
1439 {
1440 struct text_pos pos;
1441
1442 xassert (s != NULL);
1443 xassert (charpos >= 0);
1444
1445 if (multibyte_p)
1446 {
1447 int len;
1448
1449 SET_TEXT_POS (pos, 0, 0);
1450 while (charpos--)
1451 {
1452 string_char_and_length ((const unsigned char *) s, &len);
1453 s += len;
1454 CHARPOS (pos) += 1;
1455 BYTEPOS (pos) += len;
1456 }
1457 }
1458 else
1459 SET_TEXT_POS (pos, charpos, charpos);
1460
1461 return pos;
1462 }
1463
1464
1465 /* Value is the number of characters in C string S. MULTIBYTE_P
1466 non-zero means recognize multibyte characters. */
1467
1468 static EMACS_INT
1469 number_of_chars (const char *s, int multibyte_p)
1470 {
1471 EMACS_INT nchars;
1472
1473 if (multibyte_p)
1474 {
1475 EMACS_INT rest = strlen (s);
1476 int len;
1477 const unsigned char *p = (const unsigned char *) s;
1478
1479 for (nchars = 0; rest > 0; ++nchars)
1480 {
1481 string_char_and_length (p, &len);
1482 rest -= len, p += len;
1483 }
1484 }
1485 else
1486 nchars = strlen (s);
1487
1488 return nchars;
1489 }
1490
1491
1492 /* Compute byte position NEWPOS->bytepos corresponding to
1493 NEWPOS->charpos. POS is a known position in string STRING.
1494 NEWPOS->charpos must be >= POS.charpos. */
1495
1496 static void
1497 compute_string_pos (struct text_pos *newpos, struct text_pos pos, Lisp_Object string)
1498 {
1499 xassert (STRINGP (string));
1500 xassert (CHARPOS (*newpos) >= CHARPOS (pos));
1501
1502 if (STRING_MULTIBYTE (string))
1503 *newpos = string_pos_nchars_ahead (pos, string,
1504 CHARPOS (*newpos) - CHARPOS (pos));
1505 else
1506 BYTEPOS (*newpos) = CHARPOS (*newpos);
1507 }
1508
1509 /* EXPORT:
1510 Return an estimation of the pixel height of mode or header lines on
1511 frame F. FACE_ID specifies what line's height to estimate. */
1512
1513 int
1514 estimate_mode_line_height (struct frame *f, enum face_id face_id)
1515 {
1516 #ifdef HAVE_WINDOW_SYSTEM
1517 if (FRAME_WINDOW_P (f))
1518 {
1519 int height = FONT_HEIGHT (FRAME_FONT (f));
1520
1521 /* This function is called so early when Emacs starts that the face
1522 cache and mode line face are not yet initialized. */
1523 if (FRAME_FACE_CACHE (f))
1524 {
1525 struct face *face = FACE_FROM_ID (f, face_id);
1526 if (face)
1527 {
1528 if (face->font)
1529 height = FONT_HEIGHT (face->font);
1530 if (face->box_line_width > 0)
1531 height += 2 * face->box_line_width;
1532 }
1533 }
1534
1535 return height;
1536 }
1537 #endif
1538
1539 return 1;
1540 }
1541
1542 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
1543 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
1544 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
1545 not force the value into range. */
1546
1547 void
1548 pixel_to_glyph_coords (FRAME_PTR f, register int pix_x, register int pix_y,
1549 int *x, int *y, NativeRectangle *bounds, int noclip)
1550 {
1551
1552 #ifdef HAVE_WINDOW_SYSTEM
1553 if (FRAME_WINDOW_P (f))
1554 {
1555 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to round down
1556 even for negative values. */
1557 if (pix_x < 0)
1558 pix_x -= FRAME_COLUMN_WIDTH (f) - 1;
1559 if (pix_y < 0)
1560 pix_y -= FRAME_LINE_HEIGHT (f) - 1;
1561
1562 pix_x = FRAME_PIXEL_X_TO_COL (f, pix_x);
1563 pix_y = FRAME_PIXEL_Y_TO_LINE (f, pix_y);
1564
1565 if (bounds)
1566 STORE_NATIVE_RECT (*bounds,
1567 FRAME_COL_TO_PIXEL_X (f, pix_x),
1568 FRAME_LINE_TO_PIXEL_Y (f, pix_y),
1569 FRAME_COLUMN_WIDTH (f) - 1,
1570 FRAME_LINE_HEIGHT (f) - 1);
1571
1572 if (!noclip)
1573 {
1574 if (pix_x < 0)
1575 pix_x = 0;
1576 else if (pix_x > FRAME_TOTAL_COLS (f))
1577 pix_x = FRAME_TOTAL_COLS (f);
1578
1579 if (pix_y < 0)
1580 pix_y = 0;
1581 else if (pix_y > FRAME_LINES (f))
1582 pix_y = FRAME_LINES (f);
1583 }
1584 }
1585 #endif
1586
1587 *x = pix_x;
1588 *y = pix_y;
1589 }
1590
1591
1592 /* Find the glyph under window-relative coordinates X/Y in window W.
1593 Consider only glyphs from buffer text, i.e. no glyphs from overlay
1594 strings. Return in *HPOS and *VPOS the row and column number of
1595 the glyph found. Return in *AREA the glyph area containing X.
1596 Value is a pointer to the glyph found or null if X/Y is not on
1597 text, or we can't tell because W's current matrix is not up to
1598 date. */
1599
1600 static
1601 struct glyph *
1602 x_y_to_hpos_vpos (struct window *w, int x, int y, int *hpos, int *vpos,
1603 int *dx, int *dy, int *area)
1604 {
1605 struct glyph *glyph, *end;
1606 struct glyph_row *row = NULL;
1607 int x0, i;
1608
1609 /* Find row containing Y. Give up if some row is not enabled. */
1610 for (i = 0; i < w->current_matrix->nrows; ++i)
1611 {
1612 row = MATRIX_ROW (w->current_matrix, i);
1613 if (!row->enabled_p)
1614 return NULL;
1615 if (y >= row->y && y < MATRIX_ROW_BOTTOM_Y (row))
1616 break;
1617 }
1618
1619 *vpos = i;
1620 *hpos = 0;
1621
1622 /* Give up if Y is not in the window. */
1623 if (i == w->current_matrix->nrows)
1624 return NULL;
1625
1626 /* Get the glyph area containing X. */
1627 if (w->pseudo_window_p)
1628 {
1629 *area = TEXT_AREA;
1630 x0 = 0;
1631 }
1632 else
1633 {
1634 if (x < window_box_left_offset (w, TEXT_AREA))
1635 {
1636 *area = LEFT_MARGIN_AREA;
1637 x0 = window_box_left_offset (w, LEFT_MARGIN_AREA);
1638 }
1639 else if (x < window_box_right_offset (w, TEXT_AREA))
1640 {
1641 *area = TEXT_AREA;
1642 x0 = window_box_left_offset (w, TEXT_AREA) + min (row->x, 0);
1643 }
1644 else
1645 {
1646 *area = RIGHT_MARGIN_AREA;
1647 x0 = window_box_left_offset (w, RIGHT_MARGIN_AREA);
1648 }
1649 }
1650
1651 /* Find glyph containing X. */
1652 glyph = row->glyphs[*area];
1653 end = glyph + row->used[*area];
1654 x -= x0;
1655 while (glyph < end && x >= glyph->pixel_width)
1656 {
1657 x -= glyph->pixel_width;
1658 ++glyph;
1659 }
1660
1661 if (glyph == end)
1662 return NULL;
1663
1664 if (dx)
1665 {
1666 *dx = x;
1667 *dy = y - (row->y + row->ascent - glyph->ascent);
1668 }
1669
1670 *hpos = glyph - row->glyphs[*area];
1671 return glyph;
1672 }
1673
1674 /* Convert frame-relative x/y to coordinates relative to window W.
1675 Takes pseudo-windows into account. */
1676
1677 static void
1678 frame_to_window_pixel_xy (struct window *w, int *x, int *y)
1679 {
1680 if (w->pseudo_window_p)
1681 {
1682 /* A pseudo-window is always full-width, and starts at the
1683 left edge of the frame, plus a frame border. */
1684 struct frame *f = XFRAME (w->frame);
1685 *x -= FRAME_INTERNAL_BORDER_WIDTH (f);
1686 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1687 }
1688 else
1689 {
1690 *x -= WINDOW_LEFT_EDGE_X (w);
1691 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1692 }
1693 }
1694
1695 #ifdef HAVE_WINDOW_SYSTEM
1696
1697 /* EXPORT:
1698 Return in RECTS[] at most N clipping rectangles for glyph string S.
1699 Return the number of stored rectangles. */
1700
1701 int
1702 get_glyph_string_clip_rects (struct glyph_string *s, NativeRectangle *rects, int n)
1703 {
1704 XRectangle r;
1705
1706 if (n <= 0)
1707 return 0;
1708
1709 if (s->row->full_width_p)
1710 {
1711 /* Draw full-width. X coordinates are relative to S->w->left_col. */
1712 r.x = WINDOW_LEFT_EDGE_X (s->w);
1713 r.width = WINDOW_TOTAL_WIDTH (s->w);
1714
1715 /* Unless displaying a mode or menu bar line, which are always
1716 fully visible, clip to the visible part of the row. */
1717 if (s->w->pseudo_window_p)
1718 r.height = s->row->visible_height;
1719 else
1720 r.height = s->height;
1721 }
1722 else
1723 {
1724 /* This is a text line that may be partially visible. */
1725 r.x = window_box_left (s->w, s->area);
1726 r.width = window_box_width (s->w, s->area);
1727 r.height = s->row->visible_height;
1728 }
1729
1730 if (s->clip_head)
1731 if (r.x < s->clip_head->x)
1732 {
1733 if (r.width >= s->clip_head->x - r.x)
1734 r.width -= s->clip_head->x - r.x;
1735 else
1736 r.width = 0;
1737 r.x = s->clip_head->x;
1738 }
1739 if (s->clip_tail)
1740 if (r.x + r.width > s->clip_tail->x + s->clip_tail->background_width)
1741 {
1742 if (s->clip_tail->x + s->clip_tail->background_width >= r.x)
1743 r.width = s->clip_tail->x + s->clip_tail->background_width - r.x;
1744 else
1745 r.width = 0;
1746 }
1747
1748 /* If S draws overlapping rows, it's sufficient to use the top and
1749 bottom of the window for clipping because this glyph string
1750 intentionally draws over other lines. */
1751 if (s->for_overlaps)
1752 {
1753 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
1754 r.height = window_text_bottom_y (s->w) - r.y;
1755
1756 /* Alas, the above simple strategy does not work for the
1757 environments with anti-aliased text: if the same text is
1758 drawn onto the same place multiple times, it gets thicker.
1759 If the overlap we are processing is for the erased cursor, we
1760 take the intersection with the rectagle of the cursor. */
1761 if (s->for_overlaps & OVERLAPS_ERASED_CURSOR)
1762 {
1763 XRectangle rc, r_save = r;
1764
1765 rc.x = WINDOW_TEXT_TO_FRAME_PIXEL_X (s->w, s->w->phys_cursor.x);
1766 rc.y = s->w->phys_cursor.y;
1767 rc.width = s->w->phys_cursor_width;
1768 rc.height = s->w->phys_cursor_height;
1769
1770 x_intersect_rectangles (&r_save, &rc, &r);
1771 }
1772 }
1773 else
1774 {
1775 /* Don't use S->y for clipping because it doesn't take partially
1776 visible lines into account. For example, it can be negative for
1777 partially visible lines at the top of a window. */
1778 if (!s->row->full_width_p
1779 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s->w, s->row))
1780 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
1781 else
1782 r.y = max (0, s->row->y);
1783 }
1784
1785 r.y = WINDOW_TO_FRAME_PIXEL_Y (s->w, r.y);
1786
1787 /* If drawing the cursor, don't let glyph draw outside its
1788 advertised boundaries. Cleartype does this under some circumstances. */
1789 if (s->hl == DRAW_CURSOR)
1790 {
1791 struct glyph *glyph = s->first_glyph;
1792 int height, max_y;
1793
1794 if (s->x > r.x)
1795 {
1796 r.width -= s->x - r.x;
1797 r.x = s->x;
1798 }
1799 r.width = min (r.width, glyph->pixel_width);
1800
1801 /* If r.y is below window bottom, ensure that we still see a cursor. */
1802 height = min (glyph->ascent + glyph->descent,
1803 min (FRAME_LINE_HEIGHT (s->f), s->row->visible_height));
1804 max_y = window_text_bottom_y (s->w) - height;
1805 max_y = WINDOW_TO_FRAME_PIXEL_Y (s->w, max_y);
1806 if (s->ybase - glyph->ascent > max_y)
1807 {
1808 r.y = max_y;
1809 r.height = height;
1810 }
1811 else
1812 {
1813 /* Don't draw cursor glyph taller than our actual glyph. */
1814 height = max (FRAME_LINE_HEIGHT (s->f), glyph->ascent + glyph->descent);
1815 if (height < r.height)
1816 {
1817 max_y = r.y + r.height;
1818 r.y = min (max_y, max (r.y, s->ybase + glyph->descent - height));
1819 r.height = min (max_y - r.y, height);
1820 }
1821 }
1822 }
1823
1824 if (s->row->clip)
1825 {
1826 XRectangle r_save = r;
1827
1828 if (! x_intersect_rectangles (&r_save, s->row->clip, &r))
1829 r.width = 0;
1830 }
1831
1832 if ((s->for_overlaps & OVERLAPS_BOTH) == 0
1833 || ((s->for_overlaps & OVERLAPS_BOTH) == OVERLAPS_BOTH && n == 1))
1834 {
1835 #ifdef CONVERT_FROM_XRECT
1836 CONVERT_FROM_XRECT (r, *rects);
1837 #else
1838 *rects = r;
1839 #endif
1840 return 1;
1841 }
1842 else
1843 {
1844 /* If we are processing overlapping and allowed to return
1845 multiple clipping rectangles, we exclude the row of the glyph
1846 string from the clipping rectangle. This is to avoid drawing
1847 the same text on the environment with anti-aliasing. */
1848 #ifdef CONVERT_FROM_XRECT
1849 XRectangle rs[2];
1850 #else
1851 XRectangle *rs = rects;
1852 #endif
1853 int i = 0, row_y = WINDOW_TO_FRAME_PIXEL_Y (s->w, s->row->y);
1854
1855 if (s->for_overlaps & OVERLAPS_PRED)
1856 {
1857 rs[i] = r;
1858 if (r.y + r.height > row_y)
1859 {
1860 if (r.y < row_y)
1861 rs[i].height = row_y - r.y;
1862 else
1863 rs[i].height = 0;
1864 }
1865 i++;
1866 }
1867 if (s->for_overlaps & OVERLAPS_SUCC)
1868 {
1869 rs[i] = r;
1870 if (r.y < row_y + s->row->visible_height)
1871 {
1872 if (r.y + r.height > row_y + s->row->visible_height)
1873 {
1874 rs[i].y = row_y + s->row->visible_height;
1875 rs[i].height = r.y + r.height - rs[i].y;
1876 }
1877 else
1878 rs[i].height = 0;
1879 }
1880 i++;
1881 }
1882
1883 n = i;
1884 #ifdef CONVERT_FROM_XRECT
1885 for (i = 0; i < n; i++)
1886 CONVERT_FROM_XRECT (rs[i], rects[i]);
1887 #endif
1888 return n;
1889 }
1890 }
1891
1892 /* EXPORT:
1893 Return in *NR the clipping rectangle for glyph string S. */
1894
1895 void
1896 get_glyph_string_clip_rect (struct glyph_string *s, NativeRectangle *nr)
1897 {
1898 get_glyph_string_clip_rects (s, nr, 1);
1899 }
1900
1901
1902 /* EXPORT:
1903 Return the position and height of the phys cursor in window W.
1904 Set w->phys_cursor_width to width of phys cursor.
1905 */
1906
1907 void
1908 get_phys_cursor_geometry (struct window *w, struct glyph_row *row,
1909 struct glyph *glyph, int *xp, int *yp, int *heightp)
1910 {
1911 struct frame *f = XFRAME (WINDOW_FRAME (w));
1912 int x, y, wd, h, h0, y0;
1913
1914 /* Compute the width of the rectangle to draw. If on a stretch
1915 glyph, and `x-stretch-block-cursor' is nil, don't draw a
1916 rectangle as wide as the glyph, but use a canonical character
1917 width instead. */
1918 wd = glyph->pixel_width - 1;
1919 #if defined (HAVE_NTGUI) || defined (HAVE_NS)
1920 wd++; /* Why? */
1921 #endif
1922
1923 x = w->phys_cursor.x;
1924 if (x < 0)
1925 {
1926 wd += x;
1927 x = 0;
1928 }
1929
1930 if (glyph->type == STRETCH_GLYPH
1931 && !x_stretch_cursor_p)
1932 wd = min (FRAME_COLUMN_WIDTH (f), wd);
1933 w->phys_cursor_width = wd;
1934
1935 y = w->phys_cursor.y + row->ascent - glyph->ascent;
1936
1937 /* If y is below window bottom, ensure that we still see a cursor. */
1938 h0 = min (FRAME_LINE_HEIGHT (f), row->visible_height);
1939
1940 h = max (h0, glyph->ascent + glyph->descent);
1941 h0 = min (h0, glyph->ascent + glyph->descent);
1942
1943 y0 = WINDOW_HEADER_LINE_HEIGHT (w);
1944 if (y < y0)
1945 {
1946 h = max (h - (y0 - y) + 1, h0);
1947 y = y0 - 1;
1948 }
1949 else
1950 {
1951 y0 = window_text_bottom_y (w) - h0;
1952 if (y > y0)
1953 {
1954 h += y - y0;
1955 y = y0;
1956 }
1957 }
1958
1959 *xp = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, x);
1960 *yp = WINDOW_TO_FRAME_PIXEL_Y (w, y);
1961 *heightp = h;
1962 }
1963
1964 /*
1965 * Remember which glyph the mouse is over.
1966 */
1967
1968 void
1969 remember_mouse_glyph (struct frame *f, int gx, int gy, NativeRectangle *rect)
1970 {
1971 Lisp_Object window;
1972 struct window *w;
1973 struct glyph_row *r, *gr, *end_row;
1974 enum window_part part;
1975 enum glyph_row_area area;
1976 int x, y, width, height;
1977
1978 /* Try to determine frame pixel position and size of the glyph under
1979 frame pixel coordinates X/Y on frame F. */
1980
1981 if (!f->glyphs_initialized_p
1982 || (window = window_from_coordinates (f, gx, gy, &part, 0),
1983 NILP (window)))
1984 {
1985 width = FRAME_SMALLEST_CHAR_WIDTH (f);
1986 height = FRAME_SMALLEST_FONT_HEIGHT (f);
1987 goto virtual_glyph;
1988 }
1989
1990 w = XWINDOW (window);
1991 width = WINDOW_FRAME_COLUMN_WIDTH (w);
1992 height = WINDOW_FRAME_LINE_HEIGHT (w);
1993
1994 x = window_relative_x_coord (w, part, gx);
1995 y = gy - WINDOW_TOP_EDGE_Y (w);
1996
1997 r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
1998 end_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
1999
2000 if (w->pseudo_window_p)
2001 {
2002 area = TEXT_AREA;
2003 part = ON_MODE_LINE; /* Don't adjust margin. */
2004 goto text_glyph;
2005 }
2006
2007 switch (part)
2008 {
2009 case ON_LEFT_MARGIN:
2010 area = LEFT_MARGIN_AREA;
2011 goto text_glyph;
2012
2013 case ON_RIGHT_MARGIN:
2014 area = RIGHT_MARGIN_AREA;
2015 goto text_glyph;
2016
2017 case ON_HEADER_LINE:
2018 case ON_MODE_LINE:
2019 gr = (part == ON_HEADER_LINE
2020 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
2021 : MATRIX_MODE_LINE_ROW (w->current_matrix));
2022 gy = gr->y;
2023 area = TEXT_AREA;
2024 goto text_glyph_row_found;
2025
2026 case ON_TEXT:
2027 area = TEXT_AREA;
2028
2029 text_glyph:
2030 gr = 0; gy = 0;
2031 for (; r <= end_row && r->enabled_p; ++r)
2032 if (r->y + r->height > y)
2033 {
2034 gr = r; gy = r->y;
2035 break;
2036 }
2037
2038 text_glyph_row_found:
2039 if (gr && gy <= y)
2040 {
2041 struct glyph *g = gr->glyphs[area];
2042 struct glyph *end = g + gr->used[area];
2043
2044 height = gr->height;
2045 for (gx = gr->x; g < end; gx += g->pixel_width, ++g)
2046 if (gx + g->pixel_width > x)
2047 break;
2048
2049 if (g < end)
2050 {
2051 if (g->type == IMAGE_GLYPH)
2052 {
2053 /* Don't remember when mouse is over image, as
2054 image may have hot-spots. */
2055 STORE_NATIVE_RECT (*rect, 0, 0, 0, 0);
2056 return;
2057 }
2058 width = g->pixel_width;
2059 }
2060 else
2061 {
2062 /* Use nominal char spacing at end of line. */
2063 x -= gx;
2064 gx += (x / width) * width;
2065 }
2066
2067 if (part != ON_MODE_LINE && part != ON_HEADER_LINE)
2068 gx += window_box_left_offset (w, area);
2069 }
2070 else
2071 {
2072 /* Use nominal line height at end of window. */
2073 gx = (x / width) * width;
2074 y -= gy;
2075 gy += (y / height) * height;
2076 }
2077 break;
2078
2079 case ON_LEFT_FRINGE:
2080 gx = (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2081 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w)
2082 : window_box_right_offset (w, LEFT_MARGIN_AREA));
2083 width = WINDOW_LEFT_FRINGE_WIDTH (w);
2084 goto row_glyph;
2085
2086 case ON_RIGHT_FRINGE:
2087 gx = (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2088 ? window_box_right_offset (w, RIGHT_MARGIN_AREA)
2089 : window_box_right_offset (w, TEXT_AREA));
2090 width = WINDOW_RIGHT_FRINGE_WIDTH (w);
2091 goto row_glyph;
2092
2093 case ON_SCROLL_BAR:
2094 gx = (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w)
2095 ? 0
2096 : (window_box_right_offset (w, RIGHT_MARGIN_AREA)
2097 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2098 ? WINDOW_RIGHT_FRINGE_WIDTH (w)
2099 : 0)));
2100 width = WINDOW_SCROLL_BAR_AREA_WIDTH (w);
2101
2102 row_glyph:
2103 gr = 0, gy = 0;
2104 for (; r <= end_row && r->enabled_p; ++r)
2105 if (r->y + r->height > y)
2106 {
2107 gr = r; gy = r->y;
2108 break;
2109 }
2110
2111 if (gr && gy <= y)
2112 height = gr->height;
2113 else
2114 {
2115 /* Use nominal line height at end of window. */
2116 y -= gy;
2117 gy += (y / height) * height;
2118 }
2119 break;
2120
2121 default:
2122 ;
2123 virtual_glyph:
2124 /* If there is no glyph under the mouse, then we divide the screen
2125 into a grid of the smallest glyph in the frame, and use that
2126 as our "glyph". */
2127
2128 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to
2129 round down even for negative values. */
2130 if (gx < 0)
2131 gx -= width - 1;
2132 if (gy < 0)
2133 gy -= height - 1;
2134
2135 gx = (gx / width) * width;
2136 gy = (gy / height) * height;
2137
2138 goto store_rect;
2139 }
2140
2141 gx += WINDOW_LEFT_EDGE_X (w);
2142 gy += WINDOW_TOP_EDGE_Y (w);
2143
2144 store_rect:
2145 STORE_NATIVE_RECT (*rect, gx, gy, width, height);
2146
2147 /* Visible feedback for debugging. */
2148 #if 0
2149 #if HAVE_X_WINDOWS
2150 XDrawRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2151 f->output_data.x->normal_gc,
2152 gx, gy, width, height);
2153 #endif
2154 #endif
2155 }
2156
2157
2158 #endif /* HAVE_WINDOW_SYSTEM */
2159
2160 \f
2161 /***********************************************************************
2162 Lisp form evaluation
2163 ***********************************************************************/
2164
2165 /* Error handler for safe_eval and safe_call. */
2166
2167 static Lisp_Object
2168 safe_eval_handler (Lisp_Object arg)
2169 {
2170 add_to_log ("Error during redisplay: %S", arg, Qnil);
2171 return Qnil;
2172 }
2173
2174
2175 /* Evaluate SEXPR and return the result, or nil if something went
2176 wrong. Prevent redisplay during the evaluation. */
2177
2178 /* Call function ARGS[0] with arguments ARGS[1] to ARGS[NARGS - 1].
2179 Return the result, or nil if something went wrong. Prevent
2180 redisplay during the evaluation. */
2181
2182 Lisp_Object
2183 safe_call (ptrdiff_t nargs, Lisp_Object *args)
2184 {
2185 Lisp_Object val;
2186
2187 if (inhibit_eval_during_redisplay)
2188 val = Qnil;
2189 else
2190 {
2191 int count = SPECPDL_INDEX ();
2192 struct gcpro gcpro1;
2193
2194 GCPRO1 (args[0]);
2195 gcpro1.nvars = nargs;
2196 specbind (Qinhibit_redisplay, Qt);
2197 /* Use Qt to ensure debugger does not run,
2198 so there is no possibility of wanting to redisplay. */
2199 val = internal_condition_case_n (Ffuncall, nargs, args, Qt,
2200 safe_eval_handler);
2201 UNGCPRO;
2202 val = unbind_to (count, val);
2203 }
2204
2205 return val;
2206 }
2207
2208
2209 /* Call function FN with one argument ARG.
2210 Return the result, or nil if something went wrong. */
2211
2212 Lisp_Object
2213 safe_call1 (Lisp_Object fn, Lisp_Object arg)
2214 {
2215 Lisp_Object args[2];
2216 args[0] = fn;
2217 args[1] = arg;
2218 return safe_call (2, args);
2219 }
2220
2221 static Lisp_Object Qeval;
2222
2223 Lisp_Object
2224 safe_eval (Lisp_Object sexpr)
2225 {
2226 return safe_call1 (Qeval, sexpr);
2227 }
2228
2229 /* Call function FN with one argument ARG.
2230 Return the result, or nil if something went wrong. */
2231
2232 Lisp_Object
2233 safe_call2 (Lisp_Object fn, Lisp_Object arg1, Lisp_Object arg2)
2234 {
2235 Lisp_Object args[3];
2236 args[0] = fn;
2237 args[1] = arg1;
2238 args[2] = arg2;
2239 return safe_call (3, args);
2240 }
2241
2242
2243 \f
2244 /***********************************************************************
2245 Debugging
2246 ***********************************************************************/
2247
2248 #if 0
2249
2250 /* Define CHECK_IT to perform sanity checks on iterators.
2251 This is for debugging. It is too slow to do unconditionally. */
2252
2253 static void
2254 check_it (struct it *it)
2255 {
2256 if (it->method == GET_FROM_STRING)
2257 {
2258 xassert (STRINGP (it->string));
2259 xassert (IT_STRING_CHARPOS (*it) >= 0);
2260 }
2261 else
2262 {
2263 xassert (IT_STRING_CHARPOS (*it) < 0);
2264 if (it->method == GET_FROM_BUFFER)
2265 {
2266 /* Check that character and byte positions agree. */
2267 xassert (IT_CHARPOS (*it) == BYTE_TO_CHAR (IT_BYTEPOS (*it)));
2268 }
2269 }
2270
2271 if (it->dpvec)
2272 xassert (it->current.dpvec_index >= 0);
2273 else
2274 xassert (it->current.dpvec_index < 0);
2275 }
2276
2277 #define CHECK_IT(IT) check_it ((IT))
2278
2279 #else /* not 0 */
2280
2281 #define CHECK_IT(IT) (void) 0
2282
2283 #endif /* not 0 */
2284
2285
2286 #if GLYPH_DEBUG && XASSERTS
2287
2288 /* Check that the window end of window W is what we expect it
2289 to be---the last row in the current matrix displaying text. */
2290
2291 static void
2292 check_window_end (struct window *w)
2293 {
2294 if (!MINI_WINDOW_P (w)
2295 && !NILP (w->window_end_valid))
2296 {
2297 struct glyph_row *row;
2298 xassert ((row = MATRIX_ROW (w->current_matrix,
2299 XFASTINT (w->window_end_vpos)),
2300 !row->enabled_p
2301 || MATRIX_ROW_DISPLAYS_TEXT_P (row)
2302 || MATRIX_ROW_VPOS (row, w->current_matrix) == 0));
2303 }
2304 }
2305
2306 #define CHECK_WINDOW_END(W) check_window_end ((W))
2307
2308 #else
2309
2310 #define CHECK_WINDOW_END(W) (void) 0
2311
2312 #endif
2313
2314
2315 \f
2316 /***********************************************************************
2317 Iterator initialization
2318 ***********************************************************************/
2319
2320 /* Initialize IT for displaying current_buffer in window W, starting
2321 at character position CHARPOS. CHARPOS < 0 means that no buffer
2322 position is specified which is useful when the iterator is assigned
2323 a position later. BYTEPOS is the byte position corresponding to
2324 CHARPOS. BYTEPOS < 0 means compute it from CHARPOS.
2325
2326 If ROW is not null, calls to produce_glyphs with IT as parameter
2327 will produce glyphs in that row.
2328
2329 BASE_FACE_ID is the id of a base face to use. It must be one of
2330 DEFAULT_FACE_ID for normal text, MODE_LINE_FACE_ID,
2331 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID for displaying
2332 mode lines, or TOOL_BAR_FACE_ID for displaying the tool-bar.
2333
2334 If ROW is null and BASE_FACE_ID is equal to MODE_LINE_FACE_ID,
2335 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID, the iterator
2336 will be initialized to use the corresponding mode line glyph row of
2337 the desired matrix of W. */
2338
2339 void
2340 init_iterator (struct it *it, struct window *w,
2341 EMACS_INT charpos, EMACS_INT bytepos,
2342 struct glyph_row *row, enum face_id base_face_id)
2343 {
2344 int highlight_region_p;
2345 enum face_id remapped_base_face_id = base_face_id;
2346
2347 /* Some precondition checks. */
2348 xassert (w != NULL && it != NULL);
2349 xassert (charpos < 0 || (charpos >= BUF_BEG (current_buffer)
2350 && charpos <= ZV));
2351
2352 /* If face attributes have been changed since the last redisplay,
2353 free realized faces now because they depend on face definitions
2354 that might have changed. Don't free faces while there might be
2355 desired matrices pending which reference these faces. */
2356 if (face_change_count && !inhibit_free_realized_faces)
2357 {
2358 face_change_count = 0;
2359 free_all_realized_faces (Qnil);
2360 }
2361
2362 /* Perhaps remap BASE_FACE_ID to a user-specified alternative. */
2363 if (! NILP (Vface_remapping_alist))
2364 remapped_base_face_id = lookup_basic_face (XFRAME (w->frame), base_face_id);
2365
2366 /* Use one of the mode line rows of W's desired matrix if
2367 appropriate. */
2368 if (row == NULL)
2369 {
2370 if (base_face_id == MODE_LINE_FACE_ID
2371 || base_face_id == MODE_LINE_INACTIVE_FACE_ID)
2372 row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
2373 else if (base_face_id == HEADER_LINE_FACE_ID)
2374 row = MATRIX_HEADER_LINE_ROW (w->desired_matrix);
2375 }
2376
2377 /* Clear IT. */
2378 memset (it, 0, sizeof *it);
2379 it->current.overlay_string_index = -1;
2380 it->current.dpvec_index = -1;
2381 it->base_face_id = remapped_base_face_id;
2382 it->string = Qnil;
2383 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
2384 it->paragraph_embedding = L2R;
2385 it->bidi_it.string.lstring = Qnil;
2386 it->bidi_it.string.s = NULL;
2387 it->bidi_it.string.bufpos = 0;
2388
2389 /* The window in which we iterate over current_buffer: */
2390 XSETWINDOW (it->window, w);
2391 it->w = w;
2392 it->f = XFRAME (w->frame);
2393
2394 it->cmp_it.id = -1;
2395
2396 /* Extra space between lines (on window systems only). */
2397 if (base_face_id == DEFAULT_FACE_ID
2398 && FRAME_WINDOW_P (it->f))
2399 {
2400 if (NATNUMP (BVAR (current_buffer, extra_line_spacing)))
2401 it->extra_line_spacing = XFASTINT (BVAR (current_buffer, extra_line_spacing));
2402 else if (FLOATP (BVAR (current_buffer, extra_line_spacing)))
2403 it->extra_line_spacing = (XFLOAT_DATA (BVAR (current_buffer, extra_line_spacing))
2404 * FRAME_LINE_HEIGHT (it->f));
2405 else if (it->f->extra_line_spacing > 0)
2406 it->extra_line_spacing = it->f->extra_line_spacing;
2407 it->max_extra_line_spacing = 0;
2408 }
2409
2410 /* If realized faces have been removed, e.g. because of face
2411 attribute changes of named faces, recompute them. When running
2412 in batch mode, the face cache of the initial frame is null. If
2413 we happen to get called, make a dummy face cache. */
2414 if (FRAME_FACE_CACHE (it->f) == NULL)
2415 init_frame_faces (it->f);
2416 if (FRAME_FACE_CACHE (it->f)->used == 0)
2417 recompute_basic_faces (it->f);
2418
2419 /* Current value of the `slice', `space-width', and 'height' properties. */
2420 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
2421 it->space_width = Qnil;
2422 it->font_height = Qnil;
2423 it->override_ascent = -1;
2424
2425 /* Are control characters displayed as `^C'? */
2426 it->ctl_arrow_p = !NILP (BVAR (current_buffer, ctl_arrow));
2427
2428 /* -1 means everything between a CR and the following line end
2429 is invisible. >0 means lines indented more than this value are
2430 invisible. */
2431 it->selective = (INTEGERP (BVAR (current_buffer, selective_display))
2432 ? XINT (BVAR (current_buffer, selective_display))
2433 : (!NILP (BVAR (current_buffer, selective_display))
2434 ? -1 : 0));
2435 it->selective_display_ellipsis_p
2436 = !NILP (BVAR (current_buffer, selective_display_ellipses));
2437
2438 /* Display table to use. */
2439 it->dp = window_display_table (w);
2440
2441 /* Are multibyte characters enabled in current_buffer? */
2442 it->multibyte_p = !NILP (BVAR (current_buffer, enable_multibyte_characters));
2443
2444 /* Non-zero if we should highlight the region. */
2445 highlight_region_p
2446 = (!NILP (Vtransient_mark_mode)
2447 && !NILP (BVAR (current_buffer, mark_active))
2448 && XMARKER (BVAR (current_buffer, mark))->buffer != 0);
2449
2450 /* Set IT->region_beg_charpos and IT->region_end_charpos to the
2451 start and end of a visible region in window IT->w. Set both to
2452 -1 to indicate no region. */
2453 if (highlight_region_p
2454 /* Maybe highlight only in selected window. */
2455 && (/* Either show region everywhere. */
2456 highlight_nonselected_windows
2457 /* Or show region in the selected window. */
2458 || w == XWINDOW (selected_window)
2459 /* Or show the region if we are in the mini-buffer and W is
2460 the window the mini-buffer refers to. */
2461 || (MINI_WINDOW_P (XWINDOW (selected_window))
2462 && WINDOWP (minibuf_selected_window)
2463 && w == XWINDOW (minibuf_selected_window))))
2464 {
2465 EMACS_INT markpos = marker_position (BVAR (current_buffer, mark));
2466 it->region_beg_charpos = min (PT, markpos);
2467 it->region_end_charpos = max (PT, markpos);
2468 }
2469 else
2470 it->region_beg_charpos = it->region_end_charpos = -1;
2471
2472 /* Get the position at which the redisplay_end_trigger hook should
2473 be run, if it is to be run at all. */
2474 if (MARKERP (w->redisplay_end_trigger)
2475 && XMARKER (w->redisplay_end_trigger)->buffer != 0)
2476 it->redisplay_end_trigger_charpos
2477 = marker_position (w->redisplay_end_trigger);
2478 else if (INTEGERP (w->redisplay_end_trigger))
2479 it->redisplay_end_trigger_charpos = XINT (w->redisplay_end_trigger);
2480
2481 it->tab_width = SANE_TAB_WIDTH (current_buffer);
2482
2483 /* Are lines in the display truncated? */
2484 if (base_face_id != DEFAULT_FACE_ID
2485 || XINT (it->w->hscroll)
2486 || (! WINDOW_FULL_WIDTH_P (it->w)
2487 && ((!NILP (Vtruncate_partial_width_windows)
2488 && !INTEGERP (Vtruncate_partial_width_windows))
2489 || (INTEGERP (Vtruncate_partial_width_windows)
2490 && (WINDOW_TOTAL_COLS (it->w)
2491 < XINT (Vtruncate_partial_width_windows))))))
2492 it->line_wrap = TRUNCATE;
2493 else if (NILP (BVAR (current_buffer, truncate_lines)))
2494 it->line_wrap = NILP (BVAR (current_buffer, word_wrap))
2495 ? WINDOW_WRAP : WORD_WRAP;
2496 else
2497 it->line_wrap = TRUNCATE;
2498
2499 /* Get dimensions of truncation and continuation glyphs. These are
2500 displayed as fringe bitmaps under X, so we don't need them for such
2501 frames. */
2502 if (!FRAME_WINDOW_P (it->f))
2503 {
2504 if (it->line_wrap == TRUNCATE)
2505 {
2506 /* We will need the truncation glyph. */
2507 xassert (it->glyph_row == NULL);
2508 produce_special_glyphs (it, IT_TRUNCATION);
2509 it->truncation_pixel_width = it->pixel_width;
2510 }
2511 else
2512 {
2513 /* We will need the continuation glyph. */
2514 xassert (it->glyph_row == NULL);
2515 produce_special_glyphs (it, IT_CONTINUATION);
2516 it->continuation_pixel_width = it->pixel_width;
2517 }
2518
2519 /* Reset these values to zero because the produce_special_glyphs
2520 above has changed them. */
2521 it->pixel_width = it->ascent = it->descent = 0;
2522 it->phys_ascent = it->phys_descent = 0;
2523 }
2524
2525 /* Set this after getting the dimensions of truncation and
2526 continuation glyphs, so that we don't produce glyphs when calling
2527 produce_special_glyphs, above. */
2528 it->glyph_row = row;
2529 it->area = TEXT_AREA;
2530
2531 /* Forget any previous info about this row being reversed. */
2532 if (it->glyph_row)
2533 it->glyph_row->reversed_p = 0;
2534
2535 /* Get the dimensions of the display area. The display area
2536 consists of the visible window area plus a horizontally scrolled
2537 part to the left of the window. All x-values are relative to the
2538 start of this total display area. */
2539 if (base_face_id != DEFAULT_FACE_ID)
2540 {
2541 /* Mode lines, menu bar in terminal frames. */
2542 it->first_visible_x = 0;
2543 it->last_visible_x = WINDOW_TOTAL_WIDTH (w);
2544 }
2545 else
2546 {
2547 it->first_visible_x
2548 = XFASTINT (it->w->hscroll) * FRAME_COLUMN_WIDTH (it->f);
2549 it->last_visible_x = (it->first_visible_x
2550 + window_box_width (w, TEXT_AREA));
2551
2552 /* If we truncate lines, leave room for the truncator glyph(s) at
2553 the right margin. Otherwise, leave room for the continuation
2554 glyph(s). Truncation and continuation glyphs are not inserted
2555 for window-based redisplay. */
2556 if (!FRAME_WINDOW_P (it->f))
2557 {
2558 if (it->line_wrap == TRUNCATE)
2559 it->last_visible_x -= it->truncation_pixel_width;
2560 else
2561 it->last_visible_x -= it->continuation_pixel_width;
2562 }
2563
2564 it->header_line_p = WINDOW_WANTS_HEADER_LINE_P (w);
2565 it->current_y = WINDOW_HEADER_LINE_HEIGHT (w) + w->vscroll;
2566 }
2567
2568 /* Leave room for a border glyph. */
2569 if (!FRAME_WINDOW_P (it->f)
2570 && !WINDOW_RIGHTMOST_P (it->w))
2571 it->last_visible_x -= 1;
2572
2573 it->last_visible_y = window_text_bottom_y (w);
2574
2575 /* For mode lines and alike, arrange for the first glyph having a
2576 left box line if the face specifies a box. */
2577 if (base_face_id != DEFAULT_FACE_ID)
2578 {
2579 struct face *face;
2580
2581 it->face_id = remapped_base_face_id;
2582
2583 /* If we have a boxed mode line, make the first character appear
2584 with a left box line. */
2585 face = FACE_FROM_ID (it->f, remapped_base_face_id);
2586 if (face->box != FACE_NO_BOX)
2587 it->start_of_box_run_p = 1;
2588 }
2589
2590 /* If a buffer position was specified, set the iterator there,
2591 getting overlays and face properties from that position. */
2592 if (charpos >= BUF_BEG (current_buffer))
2593 {
2594 it->end_charpos = ZV;
2595 it->face_id = -1;
2596 IT_CHARPOS (*it) = charpos;
2597
2598 /* Compute byte position if not specified. */
2599 if (bytepos < charpos)
2600 IT_BYTEPOS (*it) = CHAR_TO_BYTE (charpos);
2601 else
2602 IT_BYTEPOS (*it) = bytepos;
2603
2604 it->start = it->current;
2605 /* Do we need to reorder bidirectional text? Not if this is a
2606 unibyte buffer: by definition, none of the single-byte
2607 characters are strong R2L, so no reordering is needed. And
2608 bidi.c doesn't support unibyte buffers anyway. */
2609 it->bidi_p =
2610 !NILP (BVAR (current_buffer, bidi_display_reordering))
2611 && it->multibyte_p;
2612
2613 /* If we are to reorder bidirectional text, init the bidi
2614 iterator. */
2615 if (it->bidi_p)
2616 {
2617 /* Note the paragraph direction that this buffer wants to
2618 use. */
2619 if (EQ (BVAR (current_buffer, bidi_paragraph_direction),
2620 Qleft_to_right))
2621 it->paragraph_embedding = L2R;
2622 else if (EQ (BVAR (current_buffer, bidi_paragraph_direction),
2623 Qright_to_left))
2624 it->paragraph_embedding = R2L;
2625 else
2626 it->paragraph_embedding = NEUTRAL_DIR;
2627 bidi_unshelve_cache (NULL, 0);
2628 bidi_init_it (charpos, IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f),
2629 &it->bidi_it);
2630 }
2631
2632 /* Compute faces etc. */
2633 reseat (it, it->current.pos, 1);
2634 }
2635
2636 CHECK_IT (it);
2637 }
2638
2639
2640 /* Initialize IT for the display of window W with window start POS. */
2641
2642 void
2643 start_display (struct it *it, struct window *w, struct text_pos pos)
2644 {
2645 struct glyph_row *row;
2646 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
2647
2648 row = w->desired_matrix->rows + first_vpos;
2649 init_iterator (it, w, CHARPOS (pos), BYTEPOS (pos), row, DEFAULT_FACE_ID);
2650 it->first_vpos = first_vpos;
2651
2652 /* Don't reseat to previous visible line start if current start
2653 position is in a string or image. */
2654 if (it->method == GET_FROM_BUFFER && it->line_wrap != TRUNCATE)
2655 {
2656 int start_at_line_beg_p;
2657 int first_y = it->current_y;
2658
2659 /* If window start is not at a line start, skip forward to POS to
2660 get the correct continuation lines width. */
2661 start_at_line_beg_p = (CHARPOS (pos) == BEGV
2662 || FETCH_BYTE (BYTEPOS (pos) - 1) == '\n');
2663 if (!start_at_line_beg_p)
2664 {
2665 int new_x;
2666
2667 reseat_at_previous_visible_line_start (it);
2668 move_it_to (it, CHARPOS (pos), -1, -1, -1, MOVE_TO_POS);
2669
2670 new_x = it->current_x + it->pixel_width;
2671
2672 /* If lines are continued, this line may end in the middle
2673 of a multi-glyph character (e.g. a control character
2674 displayed as \003, or in the middle of an overlay
2675 string). In this case move_it_to above will not have
2676 taken us to the start of the continuation line but to the
2677 end of the continued line. */
2678 if (it->current_x > 0
2679 && it->line_wrap != TRUNCATE /* Lines are continued. */
2680 && (/* And glyph doesn't fit on the line. */
2681 new_x > it->last_visible_x
2682 /* Or it fits exactly and we're on a window
2683 system frame. */
2684 || (new_x == it->last_visible_x
2685 && FRAME_WINDOW_P (it->f))))
2686 {
2687 if (it->current.dpvec_index >= 0
2688 || it->current.overlay_string_index >= 0)
2689 {
2690 set_iterator_to_next (it, 1);
2691 move_it_in_display_line_to (it, -1, -1, 0);
2692 }
2693
2694 it->continuation_lines_width += it->current_x;
2695 }
2696
2697 /* We're starting a new display line, not affected by the
2698 height of the continued line, so clear the appropriate
2699 fields in the iterator structure. */
2700 it->max_ascent = it->max_descent = 0;
2701 it->max_phys_ascent = it->max_phys_descent = 0;
2702
2703 it->current_y = first_y;
2704 it->vpos = 0;
2705 it->current_x = it->hpos = 0;
2706 }
2707 }
2708 }
2709
2710
2711 /* Return 1 if POS is a position in ellipses displayed for invisible
2712 text. W is the window we display, for text property lookup. */
2713
2714 static int
2715 in_ellipses_for_invisible_text_p (struct display_pos *pos, struct window *w)
2716 {
2717 Lisp_Object prop, window;
2718 int ellipses_p = 0;
2719 EMACS_INT charpos = CHARPOS (pos->pos);
2720
2721 /* If POS specifies a position in a display vector, this might
2722 be for an ellipsis displayed for invisible text. We won't
2723 get the iterator set up for delivering that ellipsis unless
2724 we make sure that it gets aware of the invisible text. */
2725 if (pos->dpvec_index >= 0
2726 && pos->overlay_string_index < 0
2727 && CHARPOS (pos->string_pos) < 0
2728 && charpos > BEGV
2729 && (XSETWINDOW (window, w),
2730 prop = Fget_char_property (make_number (charpos),
2731 Qinvisible, window),
2732 !TEXT_PROP_MEANS_INVISIBLE (prop)))
2733 {
2734 prop = Fget_char_property (make_number (charpos - 1), Qinvisible,
2735 window);
2736 ellipses_p = 2 == TEXT_PROP_MEANS_INVISIBLE (prop);
2737 }
2738
2739 return ellipses_p;
2740 }
2741
2742
2743 /* Initialize IT for stepping through current_buffer in window W,
2744 starting at position POS that includes overlay string and display
2745 vector/ control character translation position information. Value
2746 is zero if there are overlay strings with newlines at POS. */
2747
2748 static int
2749 init_from_display_pos (struct it *it, struct window *w, struct display_pos *pos)
2750 {
2751 EMACS_INT charpos = CHARPOS (pos->pos), bytepos = BYTEPOS (pos->pos);
2752 int i, overlay_strings_with_newlines = 0;
2753
2754 /* If POS specifies a position in a display vector, this might
2755 be for an ellipsis displayed for invisible text. We won't
2756 get the iterator set up for delivering that ellipsis unless
2757 we make sure that it gets aware of the invisible text. */
2758 if (in_ellipses_for_invisible_text_p (pos, w))
2759 {
2760 --charpos;
2761 bytepos = 0;
2762 }
2763
2764 /* Keep in mind: the call to reseat in init_iterator skips invisible
2765 text, so we might end up at a position different from POS. This
2766 is only a problem when POS is a row start after a newline and an
2767 overlay starts there with an after-string, and the overlay has an
2768 invisible property. Since we don't skip invisible text in
2769 display_line and elsewhere immediately after consuming the
2770 newline before the row start, such a POS will not be in a string,
2771 but the call to init_iterator below will move us to the
2772 after-string. */
2773 init_iterator (it, w, charpos, bytepos, NULL, DEFAULT_FACE_ID);
2774
2775 /* This only scans the current chunk -- it should scan all chunks.
2776 However, OVERLAY_STRING_CHUNK_SIZE has been increased from 3 in 21.1
2777 to 16 in 22.1 to make this a lesser problem. */
2778 for (i = 0; i < it->n_overlay_strings && i < OVERLAY_STRING_CHUNK_SIZE; ++i)
2779 {
2780 const char *s = SSDATA (it->overlay_strings[i]);
2781 const char *e = s + SBYTES (it->overlay_strings[i]);
2782
2783 while (s < e && *s != '\n')
2784 ++s;
2785
2786 if (s < e)
2787 {
2788 overlay_strings_with_newlines = 1;
2789 break;
2790 }
2791 }
2792
2793 /* If position is within an overlay string, set up IT to the right
2794 overlay string. */
2795 if (pos->overlay_string_index >= 0)
2796 {
2797 int relative_index;
2798
2799 /* If the first overlay string happens to have a `display'
2800 property for an image, the iterator will be set up for that
2801 image, and we have to undo that setup first before we can
2802 correct the overlay string index. */
2803 if (it->method == GET_FROM_IMAGE)
2804 pop_it (it);
2805
2806 /* We already have the first chunk of overlay strings in
2807 IT->overlay_strings. Load more until the one for
2808 pos->overlay_string_index is in IT->overlay_strings. */
2809 if (pos->overlay_string_index >= OVERLAY_STRING_CHUNK_SIZE)
2810 {
2811 int n = pos->overlay_string_index / OVERLAY_STRING_CHUNK_SIZE;
2812 it->current.overlay_string_index = 0;
2813 while (n--)
2814 {
2815 load_overlay_strings (it, 0);
2816 it->current.overlay_string_index += OVERLAY_STRING_CHUNK_SIZE;
2817 }
2818 }
2819
2820 it->current.overlay_string_index = pos->overlay_string_index;
2821 relative_index = (it->current.overlay_string_index
2822 % OVERLAY_STRING_CHUNK_SIZE);
2823 it->string = it->overlay_strings[relative_index];
2824 xassert (STRINGP (it->string));
2825 it->current.string_pos = pos->string_pos;
2826 it->method = GET_FROM_STRING;
2827 }
2828
2829 if (CHARPOS (pos->string_pos) >= 0)
2830 {
2831 /* Recorded position is not in an overlay string, but in another
2832 string. This can only be a string from a `display' property.
2833 IT should already be filled with that string. */
2834 it->current.string_pos = pos->string_pos;
2835 xassert (STRINGP (it->string));
2836 }
2837
2838 /* Restore position in display vector translations, control
2839 character translations or ellipses. */
2840 if (pos->dpvec_index >= 0)
2841 {
2842 if (it->dpvec == NULL)
2843 get_next_display_element (it);
2844 xassert (it->dpvec && it->current.dpvec_index == 0);
2845 it->current.dpvec_index = pos->dpvec_index;
2846 }
2847
2848 CHECK_IT (it);
2849 return !overlay_strings_with_newlines;
2850 }
2851
2852
2853 /* Initialize IT for stepping through current_buffer in window W
2854 starting at ROW->start. */
2855
2856 static void
2857 init_to_row_start (struct it *it, struct window *w, struct glyph_row *row)
2858 {
2859 init_from_display_pos (it, w, &row->start);
2860 it->start = row->start;
2861 it->continuation_lines_width = row->continuation_lines_width;
2862 CHECK_IT (it);
2863 }
2864
2865
2866 /* Initialize IT for stepping through current_buffer in window W
2867 starting in the line following ROW, i.e. starting at ROW->end.
2868 Value is zero if there are overlay strings with newlines at ROW's
2869 end position. */
2870
2871 static int
2872 init_to_row_end (struct it *it, struct window *w, struct glyph_row *row)
2873 {
2874 int success = 0;
2875
2876 if (init_from_display_pos (it, w, &row->end))
2877 {
2878 if (row->continued_p)
2879 it->continuation_lines_width
2880 = row->continuation_lines_width + row->pixel_width;
2881 CHECK_IT (it);
2882 success = 1;
2883 }
2884
2885 return success;
2886 }
2887
2888
2889
2890 \f
2891 /***********************************************************************
2892 Text properties
2893 ***********************************************************************/
2894
2895 /* Called when IT reaches IT->stop_charpos. Handle text property and
2896 overlay changes. Set IT->stop_charpos to the next position where
2897 to stop. */
2898
2899 static void
2900 handle_stop (struct it *it)
2901 {
2902 enum prop_handled handled;
2903 int handle_overlay_change_p;
2904 struct props *p;
2905
2906 it->dpvec = NULL;
2907 it->current.dpvec_index = -1;
2908 handle_overlay_change_p = !it->ignore_overlay_strings_at_pos_p;
2909 it->ignore_overlay_strings_at_pos_p = 0;
2910 it->ellipsis_p = 0;
2911
2912 /* Use face of preceding text for ellipsis (if invisible) */
2913 if (it->selective_display_ellipsis_p)
2914 it->saved_face_id = it->face_id;
2915
2916 do
2917 {
2918 handled = HANDLED_NORMALLY;
2919
2920 /* Call text property handlers. */
2921 for (p = it_props; p->handler; ++p)
2922 {
2923 handled = p->handler (it);
2924
2925 if (handled == HANDLED_RECOMPUTE_PROPS)
2926 break;
2927 else if (handled == HANDLED_RETURN)
2928 {
2929 /* We still want to show before and after strings from
2930 overlays even if the actual buffer text is replaced. */
2931 if (!handle_overlay_change_p
2932 || it->sp > 1
2933 || !get_overlay_strings_1 (it, 0, 0))
2934 {
2935 if (it->ellipsis_p)
2936 setup_for_ellipsis (it, 0);
2937 /* When handling a display spec, we might load an
2938 empty string. In that case, discard it here. We
2939 used to discard it in handle_single_display_spec,
2940 but that causes get_overlay_strings_1, above, to
2941 ignore overlay strings that we must check. */
2942 if (STRINGP (it->string) && !SCHARS (it->string))
2943 pop_it (it);
2944 return;
2945 }
2946 else if (STRINGP (it->string) && !SCHARS (it->string))
2947 pop_it (it);
2948 else
2949 {
2950 it->ignore_overlay_strings_at_pos_p = 1;
2951 it->string_from_display_prop_p = 0;
2952 it->from_disp_prop_p = 0;
2953 handle_overlay_change_p = 0;
2954 }
2955 handled = HANDLED_RECOMPUTE_PROPS;
2956 break;
2957 }
2958 else if (handled == HANDLED_OVERLAY_STRING_CONSUMED)
2959 handle_overlay_change_p = 0;
2960 }
2961
2962 if (handled != HANDLED_RECOMPUTE_PROPS)
2963 {
2964 /* Don't check for overlay strings below when set to deliver
2965 characters from a display vector. */
2966 if (it->method == GET_FROM_DISPLAY_VECTOR)
2967 handle_overlay_change_p = 0;
2968
2969 /* Handle overlay changes.
2970 This sets HANDLED to HANDLED_RECOMPUTE_PROPS
2971 if it finds overlays. */
2972 if (handle_overlay_change_p)
2973 handled = handle_overlay_change (it);
2974 }
2975
2976 if (it->ellipsis_p)
2977 {
2978 setup_for_ellipsis (it, 0);
2979 break;
2980 }
2981 }
2982 while (handled == HANDLED_RECOMPUTE_PROPS);
2983
2984 /* Determine where to stop next. */
2985 if (handled == HANDLED_NORMALLY)
2986 compute_stop_pos (it);
2987 }
2988
2989
2990 /* Compute IT->stop_charpos from text property and overlay change
2991 information for IT's current position. */
2992
2993 static void
2994 compute_stop_pos (struct it *it)
2995 {
2996 register INTERVAL iv, next_iv;
2997 Lisp_Object object, limit, position;
2998 EMACS_INT charpos, bytepos;
2999
3000 /* If nowhere else, stop at the end. */
3001 it->stop_charpos = it->end_charpos;
3002
3003 if (STRINGP (it->string))
3004 {
3005 /* Strings are usually short, so don't limit the search for
3006 properties. */
3007 object = it->string;
3008 limit = Qnil;
3009 charpos = IT_STRING_CHARPOS (*it);
3010 bytepos = IT_STRING_BYTEPOS (*it);
3011 }
3012 else
3013 {
3014 EMACS_INT pos;
3015
3016 /* If next overlay change is in front of the current stop pos
3017 (which is IT->end_charpos), stop there. Note: value of
3018 next_overlay_change is point-max if no overlay change
3019 follows. */
3020 charpos = IT_CHARPOS (*it);
3021 bytepos = IT_BYTEPOS (*it);
3022 pos = next_overlay_change (charpos);
3023 if (pos < it->stop_charpos)
3024 it->stop_charpos = pos;
3025
3026 /* If showing the region, we have to stop at the region
3027 start or end because the face might change there. */
3028 if (it->region_beg_charpos > 0)
3029 {
3030 if (IT_CHARPOS (*it) < it->region_beg_charpos)
3031 it->stop_charpos = min (it->stop_charpos, it->region_beg_charpos);
3032 else if (IT_CHARPOS (*it) < it->region_end_charpos)
3033 it->stop_charpos = min (it->stop_charpos, it->region_end_charpos);
3034 }
3035
3036 /* Set up variables for computing the stop position from text
3037 property changes. */
3038 XSETBUFFER (object, current_buffer);
3039 limit = make_number (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT);
3040 }
3041
3042 /* Get the interval containing IT's position. Value is a null
3043 interval if there isn't such an interval. */
3044 position = make_number (charpos);
3045 iv = validate_interval_range (object, &position, &position, 0);
3046 if (!NULL_INTERVAL_P (iv))
3047 {
3048 Lisp_Object values_here[LAST_PROP_IDX];
3049 struct props *p;
3050
3051 /* Get properties here. */
3052 for (p = it_props; p->handler; ++p)
3053 values_here[p->idx] = textget (iv->plist, *p->name);
3054
3055 /* Look for an interval following iv that has different
3056 properties. */
3057 for (next_iv = next_interval (iv);
3058 (!NULL_INTERVAL_P (next_iv)
3059 && (NILP (limit)
3060 || XFASTINT (limit) > next_iv->position));
3061 next_iv = next_interval (next_iv))
3062 {
3063 for (p = it_props; p->handler; ++p)
3064 {
3065 Lisp_Object new_value;
3066
3067 new_value = textget (next_iv->plist, *p->name);
3068 if (!EQ (values_here[p->idx], new_value))
3069 break;
3070 }
3071
3072 if (p->handler)
3073 break;
3074 }
3075
3076 if (!NULL_INTERVAL_P (next_iv))
3077 {
3078 if (INTEGERP (limit)
3079 && next_iv->position >= XFASTINT (limit))
3080 /* No text property change up to limit. */
3081 it->stop_charpos = min (XFASTINT (limit), it->stop_charpos);
3082 else
3083 /* Text properties change in next_iv. */
3084 it->stop_charpos = min (it->stop_charpos, next_iv->position);
3085 }
3086 }
3087
3088 if (it->cmp_it.id < 0)
3089 {
3090 EMACS_INT stoppos = it->end_charpos;
3091
3092 if (it->bidi_p && it->bidi_it.scan_dir < 0)
3093 stoppos = -1;
3094 composition_compute_stop_pos (&it->cmp_it, charpos, bytepos,
3095 stoppos, it->string);
3096 }
3097
3098 xassert (STRINGP (it->string)
3099 || (it->stop_charpos >= BEGV
3100 && it->stop_charpos >= IT_CHARPOS (*it)));
3101 }
3102
3103
3104 /* Return the position of the next overlay change after POS in
3105 current_buffer. Value is point-max if no overlay change
3106 follows. This is like `next-overlay-change' but doesn't use
3107 xmalloc. */
3108
3109 static EMACS_INT
3110 next_overlay_change (EMACS_INT pos)
3111 {
3112 ptrdiff_t i, noverlays;
3113 EMACS_INT endpos;
3114 Lisp_Object *overlays;
3115
3116 /* Get all overlays at the given position. */
3117 GET_OVERLAYS_AT (pos, overlays, noverlays, &endpos, 1);
3118
3119 /* If any of these overlays ends before endpos,
3120 use its ending point instead. */
3121 for (i = 0; i < noverlays; ++i)
3122 {
3123 Lisp_Object oend;
3124 EMACS_INT oendpos;
3125
3126 oend = OVERLAY_END (overlays[i]);
3127 oendpos = OVERLAY_POSITION (oend);
3128 endpos = min (endpos, oendpos);
3129 }
3130
3131 return endpos;
3132 }
3133
3134 /* How many characters forward to search for a display property or
3135 display string. Searching too far forward makes the bidi display
3136 sluggish, especially in small windows. */
3137 #define MAX_DISP_SCAN 250
3138
3139 /* Return the character position of a display string at or after
3140 position specified by POSITION. If no display string exists at or
3141 after POSITION, return ZV. A display string is either an overlay
3142 with `display' property whose value is a string, or a `display'
3143 text property whose value is a string. STRING is data about the
3144 string to iterate; if STRING->lstring is nil, we are iterating a
3145 buffer. FRAME_WINDOW_P is non-zero when we are displaying a window
3146 on a GUI frame. DISP_PROP is set to zero if we searched
3147 MAX_DISP_SCAN characters forward without finding any display
3148 strings, non-zero otherwise. It is set to 2 if the display string
3149 uses any kind of `(space ...)' spec that will produce a stretch of
3150 white space in the text area. */
3151 EMACS_INT
3152 compute_display_string_pos (struct text_pos *position,
3153 struct bidi_string_data *string,
3154 int frame_window_p, int *disp_prop)
3155 {
3156 /* OBJECT = nil means current buffer. */
3157 Lisp_Object object =
3158 (string && STRINGP (string->lstring)) ? string->lstring : Qnil;
3159 Lisp_Object pos, spec, limpos;
3160 int string_p = (string && (STRINGP (string->lstring) || string->s));
3161 EMACS_INT eob = string_p ? string->schars : ZV;
3162 EMACS_INT begb = string_p ? 0 : BEGV;
3163 EMACS_INT bufpos, charpos = CHARPOS (*position);
3164 EMACS_INT lim =
3165 (charpos < eob - MAX_DISP_SCAN) ? charpos + MAX_DISP_SCAN : eob;
3166 struct text_pos tpos;
3167 int rv = 0;
3168
3169 *disp_prop = 1;
3170
3171 if (charpos >= eob
3172 /* We don't support display properties whose values are strings
3173 that have display string properties. */
3174 || string->from_disp_str
3175 /* C strings cannot have display properties. */
3176 || (string->s && !STRINGP (object)))
3177 {
3178 *disp_prop = 0;
3179 return eob;
3180 }
3181
3182 /* If the character at CHARPOS is where the display string begins,
3183 return CHARPOS. */
3184 pos = make_number (charpos);
3185 if (STRINGP (object))
3186 bufpos = string->bufpos;
3187 else
3188 bufpos = charpos;
3189 tpos = *position;
3190 if (!NILP (spec = Fget_char_property (pos, Qdisplay, object))
3191 && (charpos <= begb
3192 || !EQ (Fget_char_property (make_number (charpos - 1), Qdisplay,
3193 object),
3194 spec))
3195 && (rv = handle_display_spec (NULL, spec, object, Qnil, &tpos, bufpos,
3196 frame_window_p)))
3197 {
3198 if (rv == 2)
3199 *disp_prop = 2;
3200 return charpos;
3201 }
3202
3203 /* Look forward for the first character with a `display' property
3204 that will replace the underlying text when displayed. */
3205 limpos = make_number (lim);
3206 do {
3207 pos = Fnext_single_char_property_change (pos, Qdisplay, object, limpos);
3208 CHARPOS (tpos) = XFASTINT (pos);
3209 if (CHARPOS (tpos) >= lim)
3210 {
3211 *disp_prop = 0;
3212 break;
3213 }
3214 if (STRINGP (object))
3215 BYTEPOS (tpos) = string_char_to_byte (object, CHARPOS (tpos));
3216 else
3217 BYTEPOS (tpos) = CHAR_TO_BYTE (CHARPOS (tpos));
3218 spec = Fget_char_property (pos, Qdisplay, object);
3219 if (!STRINGP (object))
3220 bufpos = CHARPOS (tpos);
3221 } while (NILP (spec)
3222 || !(rv = handle_display_spec (NULL, spec, object, Qnil, &tpos,
3223 bufpos, frame_window_p)));
3224 if (rv == 2)
3225 *disp_prop = 2;
3226
3227 return CHARPOS (tpos);
3228 }
3229
3230 /* Return the character position of the end of the display string that
3231 started at CHARPOS. A display string is either an overlay with
3232 `display' property whose value is a string or a `display' text
3233 property whose value is a string. */
3234 EMACS_INT
3235 compute_display_string_end (EMACS_INT charpos, struct bidi_string_data *string)
3236 {
3237 /* OBJECT = nil means current buffer. */
3238 Lisp_Object object =
3239 (string && STRINGP (string->lstring)) ? string->lstring : Qnil;
3240 Lisp_Object pos = make_number (charpos);
3241 EMACS_INT eob =
3242 (STRINGP (object) || (string && string->s)) ? string->schars : ZV;
3243
3244 if (charpos >= eob || (string->s && !STRINGP (object)))
3245 return eob;
3246
3247 if (NILP (Fget_char_property (pos, Qdisplay, object)))
3248 abort ();
3249
3250 /* Look forward for the first character where the `display' property
3251 changes. */
3252 pos = Fnext_single_char_property_change (pos, Qdisplay, object, Qnil);
3253
3254 return XFASTINT (pos);
3255 }
3256
3257
3258 \f
3259 /***********************************************************************
3260 Fontification
3261 ***********************************************************************/
3262
3263 /* Handle changes in the `fontified' property of the current buffer by
3264 calling hook functions from Qfontification_functions to fontify
3265 regions of text. */
3266
3267 static enum prop_handled
3268 handle_fontified_prop (struct it *it)
3269 {
3270 Lisp_Object prop, pos;
3271 enum prop_handled handled = HANDLED_NORMALLY;
3272
3273 if (!NILP (Vmemory_full))
3274 return handled;
3275
3276 /* Get the value of the `fontified' property at IT's current buffer
3277 position. (The `fontified' property doesn't have a special
3278 meaning in strings.) If the value is nil, call functions from
3279 Qfontification_functions. */
3280 if (!STRINGP (it->string)
3281 && it->s == NULL
3282 && !NILP (Vfontification_functions)
3283 && !NILP (Vrun_hooks)
3284 && (pos = make_number (IT_CHARPOS (*it)),
3285 prop = Fget_char_property (pos, Qfontified, Qnil),
3286 /* Ignore the special cased nil value always present at EOB since
3287 no amount of fontifying will be able to change it. */
3288 NILP (prop) && IT_CHARPOS (*it) < Z))
3289 {
3290 int count = SPECPDL_INDEX ();
3291 Lisp_Object val;
3292 struct buffer *obuf = current_buffer;
3293 int begv = BEGV, zv = ZV;
3294 int old_clip_changed = current_buffer->clip_changed;
3295
3296 val = Vfontification_functions;
3297 specbind (Qfontification_functions, Qnil);
3298
3299 xassert (it->end_charpos == ZV);
3300
3301 if (!CONSP (val) || EQ (XCAR (val), Qlambda))
3302 safe_call1 (val, pos);
3303 else
3304 {
3305 Lisp_Object fns, fn;
3306 struct gcpro gcpro1, gcpro2;
3307
3308 fns = Qnil;
3309 GCPRO2 (val, fns);
3310
3311 for (; CONSP (val); val = XCDR (val))
3312 {
3313 fn = XCAR (val);
3314
3315 if (EQ (fn, Qt))
3316 {
3317 /* A value of t indicates this hook has a local
3318 binding; it means to run the global binding too.
3319 In a global value, t should not occur. If it
3320 does, we must ignore it to avoid an endless
3321 loop. */
3322 for (fns = Fdefault_value (Qfontification_functions);
3323 CONSP (fns);
3324 fns = XCDR (fns))
3325 {
3326 fn = XCAR (fns);
3327 if (!EQ (fn, Qt))
3328 safe_call1 (fn, pos);
3329 }
3330 }
3331 else
3332 safe_call1 (fn, pos);
3333 }
3334
3335 UNGCPRO;
3336 }
3337
3338 unbind_to (count, Qnil);
3339
3340 /* Fontification functions routinely call `save-restriction'.
3341 Normally, this tags clip_changed, which can confuse redisplay
3342 (see discussion in Bug#6671). Since we don't perform any
3343 special handling of fontification changes in the case where
3344 `save-restriction' isn't called, there's no point doing so in
3345 this case either. So, if the buffer's restrictions are
3346 actually left unchanged, reset clip_changed. */
3347 if (obuf == current_buffer)
3348 {
3349 if (begv == BEGV && zv == ZV)
3350 current_buffer->clip_changed = old_clip_changed;
3351 }
3352 /* There isn't much we can reasonably do to protect against
3353 misbehaving fontification, but here's a fig leaf. */
3354 else if (!NILP (BVAR (obuf, name)))
3355 set_buffer_internal_1 (obuf);
3356
3357 /* The fontification code may have added/removed text.
3358 It could do even a lot worse, but let's at least protect against
3359 the most obvious case where only the text past `pos' gets changed',
3360 as is/was done in grep.el where some escapes sequences are turned
3361 into face properties (bug#7876). */
3362 it->end_charpos = ZV;
3363
3364 /* Return HANDLED_RECOMPUTE_PROPS only if function fontified
3365 something. This avoids an endless loop if they failed to
3366 fontify the text for which reason ever. */
3367 if (!NILP (Fget_char_property (pos, Qfontified, Qnil)))
3368 handled = HANDLED_RECOMPUTE_PROPS;
3369 }
3370
3371 return handled;
3372 }
3373
3374
3375 \f
3376 /***********************************************************************
3377 Faces
3378 ***********************************************************************/
3379
3380 /* Set up iterator IT from face properties at its current position.
3381 Called from handle_stop. */
3382
3383 static enum prop_handled
3384 handle_face_prop (struct it *it)
3385 {
3386 int new_face_id;
3387 EMACS_INT next_stop;
3388
3389 if (!STRINGP (it->string))
3390 {
3391 new_face_id
3392 = face_at_buffer_position (it->w,
3393 IT_CHARPOS (*it),
3394 it->region_beg_charpos,
3395 it->region_end_charpos,
3396 &next_stop,
3397 (IT_CHARPOS (*it)
3398 + TEXT_PROP_DISTANCE_LIMIT),
3399 0, it->base_face_id);
3400
3401 /* Is this a start of a run of characters with box face?
3402 Caveat: this can be called for a freshly initialized
3403 iterator; face_id is -1 in this case. We know that the new
3404 face will not change until limit, i.e. if the new face has a
3405 box, all characters up to limit will have one. But, as
3406 usual, we don't know whether limit 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
3411 /* If new face has a box but old face has not, this is
3412 the start of a run of characters with box, i.e. it has
3413 a shadow on the left side. The value of face_id of the
3414 iterator will be -1 if this is the initial call that gets
3415 the face. In this case, we have to look in front of IT's
3416 position and see whether there is a face != new_face_id. */
3417 it->start_of_box_run_p
3418 = (new_face->box != FACE_NO_BOX
3419 && (it->face_id >= 0
3420 || IT_CHARPOS (*it) == BEG
3421 || new_face_id != face_before_it_pos (it)));
3422 it->face_box_p = new_face->box != FACE_NO_BOX;
3423 }
3424 }
3425 else
3426 {
3427 int base_face_id;
3428 EMACS_INT bufpos;
3429 int i;
3430 Lisp_Object from_overlay
3431 = (it->current.overlay_string_index >= 0
3432 ? it->string_overlays[it->current.overlay_string_index]
3433 : Qnil);
3434
3435 /* See if we got to this string directly or indirectly from
3436 an overlay property. That includes the before-string or
3437 after-string of an overlay, strings in display properties
3438 provided by an overlay, their text properties, etc.
3439
3440 FROM_OVERLAY is the overlay that brought us here, or nil if none. */
3441 if (! NILP (from_overlay))
3442 for (i = it->sp - 1; i >= 0; i--)
3443 {
3444 if (it->stack[i].current.overlay_string_index >= 0)
3445 from_overlay
3446 = it->string_overlays[it->stack[i].current.overlay_string_index];
3447 else if (! NILP (it->stack[i].from_overlay))
3448 from_overlay = it->stack[i].from_overlay;
3449
3450 if (!NILP (from_overlay))
3451 break;
3452 }
3453
3454 if (! NILP (from_overlay))
3455 {
3456 bufpos = IT_CHARPOS (*it);
3457 /* For a string from an overlay, the base face depends
3458 only on text properties and ignores overlays. */
3459 base_face_id
3460 = face_for_overlay_string (it->w,
3461 IT_CHARPOS (*it),
3462 it->region_beg_charpos,
3463 it->region_end_charpos,
3464 &next_stop,
3465 (IT_CHARPOS (*it)
3466 + TEXT_PROP_DISTANCE_LIMIT),
3467 0,
3468 from_overlay);
3469 }
3470 else
3471 {
3472 bufpos = 0;
3473
3474 /* For strings from a `display' property, use the face at
3475 IT's current buffer position as the base face to merge
3476 with, so that overlay strings appear in the same face as
3477 surrounding text, unless they specify their own
3478 faces. */
3479 base_face_id = underlying_face_id (it);
3480 }
3481
3482 new_face_id = face_at_string_position (it->w,
3483 it->string,
3484 IT_STRING_CHARPOS (*it),
3485 bufpos,
3486 it->region_beg_charpos,
3487 it->region_end_charpos,
3488 &next_stop,
3489 base_face_id, 0);
3490
3491 /* Is this a start of a run of characters with box? Caveat:
3492 this can be called for a freshly allocated iterator; face_id
3493 is -1 is this case. We know that the new face will not
3494 change until the next check pos, i.e. if the new face has a
3495 box, all characters up to that position will have a
3496 box. But, as usual, we don't know whether that position
3497 is really the end. */
3498 if (new_face_id != it->face_id)
3499 {
3500 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
3501 struct face *old_face = FACE_FROM_ID (it->f, it->face_id);
3502
3503 /* If new face has a box but old face hasn't, this is the
3504 start of a run of characters with box, i.e. it has a
3505 shadow on the left side. */
3506 it->start_of_box_run_p
3507 = new_face->box && (old_face == NULL || !old_face->box);
3508 it->face_box_p = new_face->box != FACE_NO_BOX;
3509 }
3510 }
3511
3512 it->face_id = new_face_id;
3513 return HANDLED_NORMALLY;
3514 }
3515
3516
3517 /* Return the ID of the face ``underlying'' IT's current position,
3518 which is in a string. If the iterator is associated with a
3519 buffer, return the face at IT's current buffer position.
3520 Otherwise, use the iterator's base_face_id. */
3521
3522 static int
3523 underlying_face_id (struct it *it)
3524 {
3525 int face_id = it->base_face_id, i;
3526
3527 xassert (STRINGP (it->string));
3528
3529 for (i = it->sp - 1; i >= 0; --i)
3530 if (NILP (it->stack[i].string))
3531 face_id = it->stack[i].face_id;
3532
3533 return face_id;
3534 }
3535
3536
3537 /* Compute the face one character before or after the current position
3538 of IT, in the visual order. BEFORE_P non-zero means get the face
3539 in front (to the left in L2R paragraphs, to the right in R2L
3540 paragraphs) of IT's screen position. Value is the ID of the face. */
3541
3542 static int
3543 face_before_or_after_it_pos (struct it *it, int before_p)
3544 {
3545 int face_id, limit;
3546 EMACS_INT next_check_charpos;
3547 struct it it_copy;
3548 void *it_copy_data = NULL;
3549
3550 xassert (it->s == NULL);
3551
3552 if (STRINGP (it->string))
3553 {
3554 EMACS_INT bufpos, charpos;
3555 int base_face_id;
3556
3557 /* No face change past the end of the string (for the case
3558 we are padding with spaces). No face change before the
3559 string start. */
3560 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string)
3561 || (IT_STRING_CHARPOS (*it) == 0 && before_p))
3562 return it->face_id;
3563
3564 if (!it->bidi_p)
3565 {
3566 /* Set charpos to the position before or after IT's current
3567 position, in the logical order, which in the non-bidi
3568 case is the same as the visual order. */
3569 if (before_p)
3570 charpos = IT_STRING_CHARPOS (*it) - 1;
3571 else if (it->what == IT_COMPOSITION)
3572 /* For composition, we must check the character after the
3573 composition. */
3574 charpos = IT_STRING_CHARPOS (*it) + it->cmp_it.nchars;
3575 else
3576 charpos = IT_STRING_CHARPOS (*it) + 1;
3577 }
3578 else
3579 {
3580 if (before_p)
3581 {
3582 /* With bidi iteration, the character before the current
3583 in the visual order cannot be found by simple
3584 iteration, because "reverse" reordering is not
3585 supported. Instead, we need to use the move_it_*
3586 family of functions. */
3587 /* Ignore face changes before the first visible
3588 character on this display line. */
3589 if (it->current_x <= it->first_visible_x)
3590 return it->face_id;
3591 SAVE_IT (it_copy, *it, it_copy_data);
3592 /* Implementation note: Since move_it_in_display_line
3593 works in the iterator geometry, and thinks the first
3594 character is always the leftmost, even in R2L lines,
3595 we don't need to distinguish between the R2L and L2R
3596 cases here. */
3597 move_it_in_display_line (&it_copy, SCHARS (it_copy.string),
3598 it_copy.current_x - 1, MOVE_TO_X);
3599 charpos = IT_STRING_CHARPOS (it_copy);
3600 RESTORE_IT (it, it, it_copy_data);
3601 }
3602 else
3603 {
3604 /* Set charpos to the string position of the character
3605 that comes after IT's current position in the visual
3606 order. */
3607 int n = (it->what == IT_COMPOSITION ? it->cmp_it.nchars : 1);
3608
3609 it_copy = *it;
3610 while (n--)
3611 bidi_move_to_visually_next (&it_copy.bidi_it);
3612
3613 charpos = it_copy.bidi_it.charpos;
3614 }
3615 }
3616 xassert (0 <= charpos && charpos <= SCHARS (it->string));
3617
3618 if (it->current.overlay_string_index >= 0)
3619 bufpos = IT_CHARPOS (*it);
3620 else
3621 bufpos = 0;
3622
3623 base_face_id = underlying_face_id (it);
3624
3625 /* Get the face for ASCII, or unibyte. */
3626 face_id = face_at_string_position (it->w,
3627 it->string,
3628 charpos,
3629 bufpos,
3630 it->region_beg_charpos,
3631 it->region_end_charpos,
3632 &next_check_charpos,
3633 base_face_id, 0);
3634
3635 /* Correct the face for charsets different from ASCII. Do it
3636 for the multibyte case only. The face returned above is
3637 suitable for unibyte text if IT->string is unibyte. */
3638 if (STRING_MULTIBYTE (it->string))
3639 {
3640 struct text_pos pos1 = string_pos (charpos, it->string);
3641 const unsigned char *p = SDATA (it->string) + BYTEPOS (pos1);
3642 int c, len;
3643 struct face *face = FACE_FROM_ID (it->f, face_id);
3644
3645 c = string_char_and_length (p, &len);
3646 face_id = FACE_FOR_CHAR (it->f, face, c, charpos, it->string);
3647 }
3648 }
3649 else
3650 {
3651 struct text_pos pos;
3652
3653 if ((IT_CHARPOS (*it) >= ZV && !before_p)
3654 || (IT_CHARPOS (*it) <= BEGV && before_p))
3655 return it->face_id;
3656
3657 limit = IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT;
3658 pos = it->current.pos;
3659
3660 if (!it->bidi_p)
3661 {
3662 if (before_p)
3663 DEC_TEXT_POS (pos, it->multibyte_p);
3664 else
3665 {
3666 if (it->what == IT_COMPOSITION)
3667 {
3668 /* For composition, we must check the position after
3669 the composition. */
3670 pos.charpos += it->cmp_it.nchars;
3671 pos.bytepos += it->len;
3672 }
3673 else
3674 INC_TEXT_POS (pos, it->multibyte_p);
3675 }
3676 }
3677 else
3678 {
3679 if (before_p)
3680 {
3681 /* With bidi iteration, the character before the current
3682 in the visual order cannot be found by simple
3683 iteration, because "reverse" reordering is not
3684 supported. Instead, we need to use the move_it_*
3685 family of functions. */
3686 /* Ignore face changes before the first visible
3687 character on this display line. */
3688 if (it->current_x <= it->first_visible_x)
3689 return it->face_id;
3690 SAVE_IT (it_copy, *it, it_copy_data);
3691 /* Implementation note: Since move_it_in_display_line
3692 works in the iterator geometry, and thinks the first
3693 character is always the leftmost, even in R2L lines,
3694 we don't need to distinguish between the R2L and L2R
3695 cases here. */
3696 move_it_in_display_line (&it_copy, ZV,
3697 it_copy.current_x - 1, MOVE_TO_X);
3698 pos = it_copy.current.pos;
3699 RESTORE_IT (it, it, it_copy_data);
3700 }
3701 else
3702 {
3703 /* Set charpos to the buffer position of the character
3704 that comes after IT's current position in the visual
3705 order. */
3706 int n = (it->what == IT_COMPOSITION ? it->cmp_it.nchars : 1);
3707
3708 it_copy = *it;
3709 while (n--)
3710 bidi_move_to_visually_next (&it_copy.bidi_it);
3711
3712 SET_TEXT_POS (pos,
3713 it_copy.bidi_it.charpos, it_copy.bidi_it.bytepos);
3714 }
3715 }
3716 xassert (BEGV <= CHARPOS (pos) && CHARPOS (pos) <= ZV);
3717
3718 /* Determine face for CHARSET_ASCII, or unibyte. */
3719 face_id = face_at_buffer_position (it->w,
3720 CHARPOS (pos),
3721 it->region_beg_charpos,
3722 it->region_end_charpos,
3723 &next_check_charpos,
3724 limit, 0, -1);
3725
3726 /* Correct the face for charsets different from ASCII. Do it
3727 for the multibyte case only. The face returned above is
3728 suitable for unibyte text if current_buffer is unibyte. */
3729 if (it->multibyte_p)
3730 {
3731 int c = FETCH_MULTIBYTE_CHAR (BYTEPOS (pos));
3732 struct face *face = FACE_FROM_ID (it->f, face_id);
3733 face_id = FACE_FOR_CHAR (it->f, face, c, CHARPOS (pos), Qnil);
3734 }
3735 }
3736
3737 return face_id;
3738 }
3739
3740
3741 \f
3742 /***********************************************************************
3743 Invisible text
3744 ***********************************************************************/
3745
3746 /* Set up iterator IT from invisible properties at its current
3747 position. Called from handle_stop. */
3748
3749 static enum prop_handled
3750 handle_invisible_prop (struct it *it)
3751 {
3752 enum prop_handled handled = HANDLED_NORMALLY;
3753
3754 if (STRINGP (it->string))
3755 {
3756 Lisp_Object prop, end_charpos, limit, charpos;
3757
3758 /* Get the value of the invisible text property at the
3759 current position. Value will be nil if there is no such
3760 property. */
3761 charpos = make_number (IT_STRING_CHARPOS (*it));
3762 prop = Fget_text_property (charpos, Qinvisible, it->string);
3763
3764 if (!NILP (prop)
3765 && IT_STRING_CHARPOS (*it) < it->end_charpos)
3766 {
3767 EMACS_INT endpos;
3768
3769 handled = HANDLED_RECOMPUTE_PROPS;
3770
3771 /* Get the position at which the next change of the
3772 invisible text property can be found in IT->string.
3773 Value will be nil if the property value is the same for
3774 all the rest of IT->string. */
3775 XSETINT (limit, SCHARS (it->string));
3776 end_charpos = Fnext_single_property_change (charpos, Qinvisible,
3777 it->string, limit);
3778
3779 /* Text at current position is invisible. The next
3780 change in the property is at position end_charpos.
3781 Move IT's current position to that position. */
3782 if (INTEGERP (end_charpos)
3783 && (endpos = XFASTINT (end_charpos)) < XFASTINT (limit))
3784 {
3785 struct text_pos old;
3786 EMACS_INT oldpos;
3787
3788 old = it->current.string_pos;
3789 oldpos = CHARPOS (old);
3790 if (it->bidi_p)
3791 {
3792 if (it->bidi_it.first_elt
3793 && it->bidi_it.charpos < SCHARS (it->string))
3794 bidi_paragraph_init (it->paragraph_embedding,
3795 &it->bidi_it, 1);
3796 /* Bidi-iterate out of the invisible text. */
3797 do
3798 {
3799 bidi_move_to_visually_next (&it->bidi_it);
3800 }
3801 while (oldpos <= it->bidi_it.charpos
3802 && it->bidi_it.charpos < endpos);
3803
3804 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
3805 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
3806 if (IT_CHARPOS (*it) >= endpos)
3807 it->prev_stop = endpos;
3808 }
3809 else
3810 {
3811 IT_STRING_CHARPOS (*it) = XFASTINT (end_charpos);
3812 compute_string_pos (&it->current.string_pos, old, it->string);
3813 }
3814 }
3815 else
3816 {
3817 /* The rest of the string is invisible. If this is an
3818 overlay string, proceed with the next overlay string
3819 or whatever comes and return a character from there. */
3820 if (it->current.overlay_string_index >= 0)
3821 {
3822 next_overlay_string (it);
3823 /* Don't check for overlay strings when we just
3824 finished processing them. */
3825 handled = HANDLED_OVERLAY_STRING_CONSUMED;
3826 }
3827 else
3828 {
3829 IT_STRING_CHARPOS (*it) = SCHARS (it->string);
3830 IT_STRING_BYTEPOS (*it) = SBYTES (it->string);
3831 }
3832 }
3833 }
3834 }
3835 else
3836 {
3837 int invis_p;
3838 EMACS_INT newpos, next_stop, start_charpos, tem;
3839 Lisp_Object pos, prop, overlay;
3840
3841 /* First of all, is there invisible text at this position? */
3842 tem = start_charpos = IT_CHARPOS (*it);
3843 pos = make_number (tem);
3844 prop = get_char_property_and_overlay (pos, Qinvisible, it->window,
3845 &overlay);
3846 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
3847
3848 /* If we are on invisible text, skip over it. */
3849 if (invis_p && start_charpos < it->end_charpos)
3850 {
3851 /* Record whether we have to display an ellipsis for the
3852 invisible text. */
3853 int display_ellipsis_p = invis_p == 2;
3854
3855 handled = HANDLED_RECOMPUTE_PROPS;
3856
3857 /* Loop skipping over invisible text. The loop is left at
3858 ZV or with IT on the first char being visible again. */
3859 do
3860 {
3861 /* Try to skip some invisible text. Return value is the
3862 position reached which can be equal to where we start
3863 if there is nothing invisible there. This skips both
3864 over invisible text properties and overlays with
3865 invisible property. */
3866 newpos = skip_invisible (tem, &next_stop, ZV, it->window);
3867
3868 /* If we skipped nothing at all we weren't at invisible
3869 text in the first place. If everything to the end of
3870 the buffer was skipped, end the loop. */
3871 if (newpos == tem || newpos >= ZV)
3872 invis_p = 0;
3873 else
3874 {
3875 /* We skipped some characters but not necessarily
3876 all there are. Check if we ended up on visible
3877 text. Fget_char_property returns the property of
3878 the char before the given position, i.e. if we
3879 get invis_p = 0, this means that the char at
3880 newpos is visible. */
3881 pos = make_number (newpos);
3882 prop = Fget_char_property (pos, Qinvisible, it->window);
3883 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
3884 }
3885
3886 /* If we ended up on invisible text, proceed to
3887 skip starting with next_stop. */
3888 if (invis_p)
3889 tem = next_stop;
3890
3891 /* If there are adjacent invisible texts, don't lose the
3892 second one's ellipsis. */
3893 if (invis_p == 2)
3894 display_ellipsis_p = 1;
3895 }
3896 while (invis_p);
3897
3898 /* The position newpos is now either ZV or on visible text. */
3899 if (it->bidi_p && newpos < ZV)
3900 {
3901 /* With bidi iteration, the region of invisible text
3902 could start and/or end in the middle of a non-base
3903 embedding level. Therefore, we need to skip
3904 invisible text using the bidi iterator, starting at
3905 IT's current position, until we find ourselves
3906 outside the invisible text. Skipping invisible text
3907 _after_ bidi iteration avoids affecting the visual
3908 order of the displayed text when invisible properties
3909 are added or removed. */
3910 if (it->bidi_it.first_elt && it->bidi_it.charpos < ZV)
3911 {
3912 /* If we were `reseat'ed to a new paragraph,
3913 determine the paragraph base direction. We need
3914 to do it now because next_element_from_buffer may
3915 not have a chance to do it, if we are going to
3916 skip any text at the beginning, which resets the
3917 FIRST_ELT flag. */
3918 bidi_paragraph_init (it->paragraph_embedding,
3919 &it->bidi_it, 1);
3920 }
3921 do
3922 {
3923 bidi_move_to_visually_next (&it->bidi_it);
3924 }
3925 while (it->stop_charpos <= it->bidi_it.charpos
3926 && it->bidi_it.charpos < newpos);
3927 IT_CHARPOS (*it) = it->bidi_it.charpos;
3928 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
3929 /* If we overstepped NEWPOS, record its position in the
3930 iterator, so that we skip invisible text if later the
3931 bidi iteration lands us in the invisible region
3932 again. */
3933 if (IT_CHARPOS (*it) >= newpos)
3934 it->prev_stop = newpos;
3935 }
3936 else
3937 {
3938 IT_CHARPOS (*it) = newpos;
3939 IT_BYTEPOS (*it) = CHAR_TO_BYTE (newpos);
3940 }
3941
3942 /* If there are before-strings at the start of invisible
3943 text, and the text is invisible because of a text
3944 property, arrange to show before-strings because 20.x did
3945 it that way. (If the text is invisible because of an
3946 overlay property instead of a text property, this is
3947 already handled in the overlay code.) */
3948 if (NILP (overlay)
3949 && get_overlay_strings (it, it->stop_charpos))
3950 {
3951 handled = HANDLED_RECOMPUTE_PROPS;
3952 it->stack[it->sp - 1].display_ellipsis_p = display_ellipsis_p;
3953 }
3954 else if (display_ellipsis_p)
3955 {
3956 /* Make sure that the glyphs of the ellipsis will get
3957 correct `charpos' values. If we would not update
3958 it->position here, the glyphs would belong to the
3959 last visible character _before_ the invisible
3960 text, which confuses `set_cursor_from_row'.
3961
3962 We use the last invisible position instead of the
3963 first because this way the cursor is always drawn on
3964 the first "." of the ellipsis, whenever PT is inside
3965 the invisible text. Otherwise the cursor would be
3966 placed _after_ the ellipsis when the point is after the
3967 first invisible character. */
3968 if (!STRINGP (it->object))
3969 {
3970 it->position.charpos = newpos - 1;
3971 it->position.bytepos = CHAR_TO_BYTE (it->position.charpos);
3972 }
3973 it->ellipsis_p = 1;
3974 /* Let the ellipsis display before
3975 considering any properties of the following char.
3976 Fixes jasonr@gnu.org 01 Oct 07 bug. */
3977 handled = HANDLED_RETURN;
3978 }
3979 }
3980 }
3981
3982 return handled;
3983 }
3984
3985
3986 /* Make iterator IT return `...' next.
3987 Replaces LEN characters from buffer. */
3988
3989 static void
3990 setup_for_ellipsis (struct it *it, int len)
3991 {
3992 /* Use the display table definition for `...'. Invalid glyphs
3993 will be handled by the method returning elements from dpvec. */
3994 if (it->dp && VECTORP (DISP_INVIS_VECTOR (it->dp)))
3995 {
3996 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
3997 it->dpvec = v->contents;
3998 it->dpend = v->contents + v->header.size;
3999 }
4000 else
4001 {
4002 /* Default `...'. */
4003 it->dpvec = default_invis_vector;
4004 it->dpend = default_invis_vector + 3;
4005 }
4006
4007 it->dpvec_char_len = len;
4008 it->current.dpvec_index = 0;
4009 it->dpvec_face_id = -1;
4010
4011 /* Remember the current face id in case glyphs specify faces.
4012 IT's face is restored in set_iterator_to_next.
4013 saved_face_id was set to preceding char's face in handle_stop. */
4014 if (it->saved_face_id < 0 || it->saved_face_id != it->face_id)
4015 it->saved_face_id = it->face_id = DEFAULT_FACE_ID;
4016
4017 it->method = GET_FROM_DISPLAY_VECTOR;
4018 it->ellipsis_p = 1;
4019 }
4020
4021
4022 \f
4023 /***********************************************************************
4024 'display' property
4025 ***********************************************************************/
4026
4027 /* Set up iterator IT from `display' property at its current position.
4028 Called from handle_stop.
4029 We return HANDLED_RETURN if some part of the display property
4030 overrides the display of the buffer text itself.
4031 Otherwise we return HANDLED_NORMALLY. */
4032
4033 static enum prop_handled
4034 handle_display_prop (struct it *it)
4035 {
4036 Lisp_Object propval, object, overlay;
4037 struct text_pos *position;
4038 EMACS_INT bufpos;
4039 /* Nonzero if some property replaces the display of the text itself. */
4040 int display_replaced_p = 0;
4041
4042 if (STRINGP (it->string))
4043 {
4044 object = it->string;
4045 position = &it->current.string_pos;
4046 bufpos = CHARPOS (it->current.pos);
4047 }
4048 else
4049 {
4050 XSETWINDOW (object, it->w);
4051 position = &it->current.pos;
4052 bufpos = CHARPOS (*position);
4053 }
4054
4055 /* Reset those iterator values set from display property values. */
4056 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
4057 it->space_width = Qnil;
4058 it->font_height = Qnil;
4059 it->voffset = 0;
4060
4061 /* We don't support recursive `display' properties, i.e. string
4062 values that have a string `display' property, that have a string
4063 `display' property etc. */
4064 if (!it->string_from_display_prop_p)
4065 it->area = TEXT_AREA;
4066
4067 propval = get_char_property_and_overlay (make_number (position->charpos),
4068 Qdisplay, object, &overlay);
4069 if (NILP (propval))
4070 return HANDLED_NORMALLY;
4071 /* Now OVERLAY is the overlay that gave us this property, or nil
4072 if it was a text property. */
4073
4074 if (!STRINGP (it->string))
4075 object = it->w->buffer;
4076
4077 display_replaced_p = handle_display_spec (it, propval, object, overlay,
4078 position, bufpos,
4079 FRAME_WINDOW_P (it->f));
4080
4081 return display_replaced_p ? HANDLED_RETURN : HANDLED_NORMALLY;
4082 }
4083
4084 /* Subroutine of handle_display_prop. Returns non-zero if the display
4085 specification in SPEC is a replacing specification, i.e. it would
4086 replace the text covered by `display' property with something else,
4087 such as an image or a display string. If SPEC includes any kind or
4088 `(space ...) specification, the value is 2; this is used by
4089 compute_display_string_pos, which see.
4090
4091 See handle_single_display_spec for documentation of arguments.
4092 frame_window_p is non-zero if the window being redisplayed is on a
4093 GUI frame; this argument is used only if IT is NULL, see below.
4094
4095 IT can be NULL, if this is called by the bidi reordering code
4096 through compute_display_string_pos, which see. In that case, this
4097 function only examines SPEC, but does not otherwise "handle" it, in
4098 the sense that it doesn't set up members of IT from the display
4099 spec. */
4100 static int
4101 handle_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
4102 Lisp_Object overlay, struct text_pos *position,
4103 EMACS_INT bufpos, int frame_window_p)
4104 {
4105 int replacing_p = 0;
4106 int rv;
4107
4108 if (CONSP (spec)
4109 /* Simple specerties. */
4110 && !EQ (XCAR (spec), Qimage)
4111 && !EQ (XCAR (spec), Qspace)
4112 && !EQ (XCAR (spec), Qwhen)
4113 && !EQ (XCAR (spec), Qslice)
4114 && !EQ (XCAR (spec), Qspace_width)
4115 && !EQ (XCAR (spec), Qheight)
4116 && !EQ (XCAR (spec), Qraise)
4117 /* Marginal area specifications. */
4118 && !(CONSP (XCAR (spec)) && EQ (XCAR (XCAR (spec)), Qmargin))
4119 && !EQ (XCAR (spec), Qleft_fringe)
4120 && !EQ (XCAR (spec), Qright_fringe)
4121 && !NILP (XCAR (spec)))
4122 {
4123 for (; CONSP (spec); spec = XCDR (spec))
4124 {
4125 if ((rv = handle_single_display_spec (it, XCAR (spec), object,
4126 overlay, position, bufpos,
4127 replacing_p, frame_window_p)))
4128 {
4129 replacing_p = rv;
4130 /* If some text in a string is replaced, `position' no
4131 longer points to the position of `object'. */
4132 if (!it || STRINGP (object))
4133 break;
4134 }
4135 }
4136 }
4137 else if (VECTORP (spec))
4138 {
4139 int i;
4140 for (i = 0; i < ASIZE (spec); ++i)
4141 if ((rv = handle_single_display_spec (it, AREF (spec, i), object,
4142 overlay, position, bufpos,
4143 replacing_p, frame_window_p)))
4144 {
4145 replacing_p = rv;
4146 /* If some text in a string is replaced, `position' no
4147 longer points to the position of `object'. */
4148 if (!it || STRINGP (object))
4149 break;
4150 }
4151 }
4152 else
4153 {
4154 if ((rv = handle_single_display_spec (it, spec, object, overlay,
4155 position, bufpos, 0,
4156 frame_window_p)))
4157 replacing_p = rv;
4158 }
4159
4160 return replacing_p;
4161 }
4162
4163 /* Value is the position of the end of the `display' property starting
4164 at START_POS in OBJECT. */
4165
4166 static struct text_pos
4167 display_prop_end (struct it *it, Lisp_Object object, struct text_pos start_pos)
4168 {
4169 Lisp_Object end;
4170 struct text_pos end_pos;
4171
4172 end = Fnext_single_char_property_change (make_number (CHARPOS (start_pos)),
4173 Qdisplay, object, Qnil);
4174 CHARPOS (end_pos) = XFASTINT (end);
4175 if (STRINGP (object))
4176 compute_string_pos (&end_pos, start_pos, it->string);
4177 else
4178 BYTEPOS (end_pos) = CHAR_TO_BYTE (XFASTINT (end));
4179
4180 return end_pos;
4181 }
4182
4183
4184 /* Set up IT from a single `display' property specification SPEC. OBJECT
4185 is the object in which the `display' property was found. *POSITION
4186 is the position in OBJECT at which the `display' property was found.
4187 BUFPOS is the buffer position of OBJECT (different from POSITION if
4188 OBJECT is not a buffer). DISPLAY_REPLACED_P non-zero means that we
4189 previously saw a display specification which already replaced text
4190 display with something else, for example an image; we ignore such
4191 properties after the first one has been processed.
4192
4193 OVERLAY is the overlay this `display' property came from,
4194 or nil if it was a text property.
4195
4196 If SPEC is a `space' or `image' specification, and in some other
4197 cases too, set *POSITION to the position where the `display'
4198 property ends.
4199
4200 If IT is NULL, only examine the property specification in SPEC, but
4201 don't set up IT. In that case, FRAME_WINDOW_P non-zero means SPEC
4202 is intended to be displayed in a window on a GUI frame.
4203
4204 Value is non-zero if something was found which replaces the display
4205 of buffer or string text. */
4206
4207 static int
4208 handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
4209 Lisp_Object overlay, struct text_pos *position,
4210 EMACS_INT bufpos, int display_replaced_p,
4211 int frame_window_p)
4212 {
4213 Lisp_Object form;
4214 Lisp_Object location, value;
4215 struct text_pos start_pos = *position;
4216 int valid_p;
4217
4218 /* If SPEC is a list of the form `(when FORM . VALUE)', evaluate FORM.
4219 If the result is non-nil, use VALUE instead of SPEC. */
4220 form = Qt;
4221 if (CONSP (spec) && EQ (XCAR (spec), Qwhen))
4222 {
4223 spec = XCDR (spec);
4224 if (!CONSP (spec))
4225 return 0;
4226 form = XCAR (spec);
4227 spec = XCDR (spec);
4228 }
4229
4230 if (!NILP (form) && !EQ (form, Qt))
4231 {
4232 int count = SPECPDL_INDEX ();
4233 struct gcpro gcpro1;
4234
4235 /* Bind `object' to the object having the `display' property, a
4236 buffer or string. Bind `position' to the position in the
4237 object where the property was found, and `buffer-position'
4238 to the current position in the buffer. */
4239
4240 if (NILP (object))
4241 XSETBUFFER (object, current_buffer);
4242 specbind (Qobject, object);
4243 specbind (Qposition, make_number (CHARPOS (*position)));
4244 specbind (Qbuffer_position, make_number (bufpos));
4245 GCPRO1 (form);
4246 form = safe_eval (form);
4247 UNGCPRO;
4248 unbind_to (count, Qnil);
4249 }
4250
4251 if (NILP (form))
4252 return 0;
4253
4254 /* Handle `(height HEIGHT)' specifications. */
4255 if (CONSP (spec)
4256 && EQ (XCAR (spec), Qheight)
4257 && CONSP (XCDR (spec)))
4258 {
4259 if (it)
4260 {
4261 if (!FRAME_WINDOW_P (it->f))
4262 return 0;
4263
4264 it->font_height = XCAR (XCDR (spec));
4265 if (!NILP (it->font_height))
4266 {
4267 struct face *face = FACE_FROM_ID (it->f, it->face_id);
4268 int new_height = -1;
4269
4270 if (CONSP (it->font_height)
4271 && (EQ (XCAR (it->font_height), Qplus)
4272 || EQ (XCAR (it->font_height), Qminus))
4273 && CONSP (XCDR (it->font_height))
4274 && INTEGERP (XCAR (XCDR (it->font_height))))
4275 {
4276 /* `(+ N)' or `(- N)' where N is an integer. */
4277 int steps = XINT (XCAR (XCDR (it->font_height)));
4278 if (EQ (XCAR (it->font_height), Qplus))
4279 steps = - steps;
4280 it->face_id = smaller_face (it->f, it->face_id, steps);
4281 }
4282 else if (FUNCTIONP (it->font_height))
4283 {
4284 /* Call function with current height as argument.
4285 Value is the new height. */
4286 Lisp_Object height;
4287 height = safe_call1 (it->font_height,
4288 face->lface[LFACE_HEIGHT_INDEX]);
4289 if (NUMBERP (height))
4290 new_height = XFLOATINT (height);
4291 }
4292 else if (NUMBERP (it->font_height))
4293 {
4294 /* Value is a multiple of the canonical char height. */
4295 struct face *f;
4296
4297 f = FACE_FROM_ID (it->f,
4298 lookup_basic_face (it->f, DEFAULT_FACE_ID));
4299 new_height = (XFLOATINT (it->font_height)
4300 * XINT (f->lface[LFACE_HEIGHT_INDEX]));
4301 }
4302 else
4303 {
4304 /* Evaluate IT->font_height with `height' bound to the
4305 current specified height to get the new height. */
4306 int count = SPECPDL_INDEX ();
4307
4308 specbind (Qheight, face->lface[LFACE_HEIGHT_INDEX]);
4309 value = safe_eval (it->font_height);
4310 unbind_to (count, Qnil);
4311
4312 if (NUMBERP (value))
4313 new_height = XFLOATINT (value);
4314 }
4315
4316 if (new_height > 0)
4317 it->face_id = face_with_height (it->f, it->face_id, new_height);
4318 }
4319 }
4320
4321 return 0;
4322 }
4323
4324 /* Handle `(space-width WIDTH)'. */
4325 if (CONSP (spec)
4326 && EQ (XCAR (spec), Qspace_width)
4327 && CONSP (XCDR (spec)))
4328 {
4329 if (it)
4330 {
4331 if (!FRAME_WINDOW_P (it->f))
4332 return 0;
4333
4334 value = XCAR (XCDR (spec));
4335 if (NUMBERP (value) && XFLOATINT (value) > 0)
4336 it->space_width = value;
4337 }
4338
4339 return 0;
4340 }
4341
4342 /* Handle `(slice X Y WIDTH HEIGHT)'. */
4343 if (CONSP (spec)
4344 && EQ (XCAR (spec), Qslice))
4345 {
4346 Lisp_Object tem;
4347
4348 if (it)
4349 {
4350 if (!FRAME_WINDOW_P (it->f))
4351 return 0;
4352
4353 if (tem = XCDR (spec), CONSP (tem))
4354 {
4355 it->slice.x = XCAR (tem);
4356 if (tem = XCDR (tem), CONSP (tem))
4357 {
4358 it->slice.y = XCAR (tem);
4359 if (tem = XCDR (tem), CONSP (tem))
4360 {
4361 it->slice.width = XCAR (tem);
4362 if (tem = XCDR (tem), CONSP (tem))
4363 it->slice.height = XCAR (tem);
4364 }
4365 }
4366 }
4367 }
4368
4369 return 0;
4370 }
4371
4372 /* Handle `(raise FACTOR)'. */
4373 if (CONSP (spec)
4374 && EQ (XCAR (spec), Qraise)
4375 && CONSP (XCDR (spec)))
4376 {
4377 if (it)
4378 {
4379 if (!FRAME_WINDOW_P (it->f))
4380 return 0;
4381
4382 #ifdef HAVE_WINDOW_SYSTEM
4383 value = XCAR (XCDR (spec));
4384 if (NUMBERP (value))
4385 {
4386 struct face *face = FACE_FROM_ID (it->f, it->face_id);
4387 it->voffset = - (XFLOATINT (value)
4388 * (FONT_HEIGHT (face->font)));
4389 }
4390 #endif /* HAVE_WINDOW_SYSTEM */
4391 }
4392
4393 return 0;
4394 }
4395
4396 /* Don't handle the other kinds of display specifications
4397 inside a string that we got from a `display' property. */
4398 if (it && it->string_from_display_prop_p)
4399 return 0;
4400
4401 /* Characters having this form of property are not displayed, so
4402 we have to find the end of the property. */
4403 if (it)
4404 {
4405 start_pos = *position;
4406 *position = display_prop_end (it, object, start_pos);
4407 }
4408 value = Qnil;
4409
4410 /* Stop the scan at that end position--we assume that all
4411 text properties change there. */
4412 if (it)
4413 it->stop_charpos = position->charpos;
4414
4415 /* Handle `(left-fringe BITMAP [FACE])'
4416 and `(right-fringe BITMAP [FACE])'. */
4417 if (CONSP (spec)
4418 && (EQ (XCAR (spec), Qleft_fringe)
4419 || EQ (XCAR (spec), Qright_fringe))
4420 && CONSP (XCDR (spec)))
4421 {
4422 int fringe_bitmap;
4423
4424 if (it)
4425 {
4426 if (!FRAME_WINDOW_P (it->f))
4427 /* If we return here, POSITION has been advanced
4428 across the text with this property. */
4429 return 0;
4430 }
4431 else if (!frame_window_p)
4432 return 0;
4433
4434 #ifdef HAVE_WINDOW_SYSTEM
4435 value = XCAR (XCDR (spec));
4436 if (!SYMBOLP (value)
4437 || !(fringe_bitmap = lookup_fringe_bitmap (value)))
4438 /* If we return here, POSITION has been advanced
4439 across the text with this property. */
4440 return 0;
4441
4442 if (it)
4443 {
4444 int face_id = lookup_basic_face (it->f, DEFAULT_FACE_ID);;
4445
4446 if (CONSP (XCDR (XCDR (spec))))
4447 {
4448 Lisp_Object face_name = XCAR (XCDR (XCDR (spec)));
4449 int face_id2 = lookup_derived_face (it->f, face_name,
4450 FRINGE_FACE_ID, 0);
4451 if (face_id2 >= 0)
4452 face_id = face_id2;
4453 }
4454
4455 /* Save current settings of IT so that we can restore them
4456 when we are finished with the glyph property value. */
4457 push_it (it, position);
4458
4459 it->area = TEXT_AREA;
4460 it->what = IT_IMAGE;
4461 it->image_id = -1; /* no image */
4462 it->position = start_pos;
4463 it->object = NILP (object) ? it->w->buffer : object;
4464 it->method = GET_FROM_IMAGE;
4465 it->from_overlay = Qnil;
4466 it->face_id = face_id;
4467 it->from_disp_prop_p = 1;
4468
4469 /* Say that we haven't consumed the characters with
4470 `display' property yet. The call to pop_it in
4471 set_iterator_to_next will clean this up. */
4472 *position = start_pos;
4473
4474 if (EQ (XCAR (spec), Qleft_fringe))
4475 {
4476 it->left_user_fringe_bitmap = fringe_bitmap;
4477 it->left_user_fringe_face_id = face_id;
4478 }
4479 else
4480 {
4481 it->right_user_fringe_bitmap = fringe_bitmap;
4482 it->right_user_fringe_face_id = face_id;
4483 }
4484 }
4485 #endif /* HAVE_WINDOW_SYSTEM */
4486 return 1;
4487 }
4488
4489 /* Prepare to handle `((margin left-margin) ...)',
4490 `((margin right-margin) ...)' and `((margin nil) ...)'
4491 prefixes for display specifications. */
4492 location = Qunbound;
4493 if (CONSP (spec) && CONSP (XCAR (spec)))
4494 {
4495 Lisp_Object tem;
4496
4497 value = XCDR (spec);
4498 if (CONSP (value))
4499 value = XCAR (value);
4500
4501 tem = XCAR (spec);
4502 if (EQ (XCAR (tem), Qmargin)
4503 && (tem = XCDR (tem),
4504 tem = CONSP (tem) ? XCAR (tem) : Qnil,
4505 (NILP (tem)
4506 || EQ (tem, Qleft_margin)
4507 || EQ (tem, Qright_margin))))
4508 location = tem;
4509 }
4510
4511 if (EQ (location, Qunbound))
4512 {
4513 location = Qnil;
4514 value = spec;
4515 }
4516
4517 /* After this point, VALUE is the property after any
4518 margin prefix has been stripped. It must be a string,
4519 an image specification, or `(space ...)'.
4520
4521 LOCATION specifies where to display: `left-margin',
4522 `right-margin' or nil. */
4523
4524 valid_p = (STRINGP (value)
4525 #ifdef HAVE_WINDOW_SYSTEM
4526 || ((it ? FRAME_WINDOW_P (it->f) : frame_window_p)
4527 && valid_image_p (value))
4528 #endif /* not HAVE_WINDOW_SYSTEM */
4529 || (CONSP (value) && EQ (XCAR (value), Qspace)));
4530
4531 if (valid_p && !display_replaced_p)
4532 {
4533 int retval = 1;
4534
4535 if (!it)
4536 {
4537 /* Callers need to know whether the display spec is any kind
4538 of `(space ...)' spec that is about to affect text-area
4539 display. */
4540 if (CONSP (value) && EQ (XCAR (value), Qspace) && NILP (location))
4541 retval = 2;
4542 return retval;
4543 }
4544
4545 /* Save current settings of IT so that we can restore them
4546 when we are finished with the glyph property value. */
4547 push_it (it, position);
4548 it->from_overlay = overlay;
4549 it->from_disp_prop_p = 1;
4550
4551 if (NILP (location))
4552 it->area = TEXT_AREA;
4553 else if (EQ (location, Qleft_margin))
4554 it->area = LEFT_MARGIN_AREA;
4555 else
4556 it->area = RIGHT_MARGIN_AREA;
4557
4558 if (STRINGP (value))
4559 {
4560 it->string = value;
4561 it->multibyte_p = STRING_MULTIBYTE (it->string);
4562 it->current.overlay_string_index = -1;
4563 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
4564 it->end_charpos = it->string_nchars = SCHARS (it->string);
4565 it->method = GET_FROM_STRING;
4566 it->stop_charpos = 0;
4567 it->prev_stop = 0;
4568 it->base_level_stop = 0;
4569 it->string_from_display_prop_p = 1;
4570 /* Say that we haven't consumed the characters with
4571 `display' property yet. The call to pop_it in
4572 set_iterator_to_next will clean this up. */
4573 if (BUFFERP (object))
4574 *position = start_pos;
4575
4576 /* Force paragraph direction to be that of the parent
4577 object. If the parent object's paragraph direction is
4578 not yet determined, default to L2R. */
4579 if (it->bidi_p && it->bidi_it.paragraph_dir == R2L)
4580 it->paragraph_embedding = it->bidi_it.paragraph_dir;
4581 else
4582 it->paragraph_embedding = L2R;
4583
4584 /* Set up the bidi iterator for this display string. */
4585 if (it->bidi_p)
4586 {
4587 it->bidi_it.string.lstring = it->string;
4588 it->bidi_it.string.s = NULL;
4589 it->bidi_it.string.schars = it->end_charpos;
4590 it->bidi_it.string.bufpos = bufpos;
4591 it->bidi_it.string.from_disp_str = 1;
4592 it->bidi_it.string.unibyte = !it->multibyte_p;
4593 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
4594 }
4595 }
4596 else if (CONSP (value) && EQ (XCAR (value), Qspace))
4597 {
4598 it->method = GET_FROM_STRETCH;
4599 it->object = value;
4600 *position = it->position = start_pos;
4601 retval = 1 + (it->area == TEXT_AREA);
4602 }
4603 #ifdef HAVE_WINDOW_SYSTEM
4604 else
4605 {
4606 it->what = IT_IMAGE;
4607 it->image_id = lookup_image (it->f, value);
4608 it->position = start_pos;
4609 it->object = NILP (object) ? it->w->buffer : object;
4610 it->method = GET_FROM_IMAGE;
4611
4612 /* Say that we haven't consumed the characters with
4613 `display' property yet. The call to pop_it in
4614 set_iterator_to_next will clean this up. */
4615 *position = start_pos;
4616 }
4617 #endif /* HAVE_WINDOW_SYSTEM */
4618
4619 return retval;
4620 }
4621
4622 /* Invalid property or property not supported. Restore
4623 POSITION to what it was before. */
4624 *position = start_pos;
4625 return 0;
4626 }
4627
4628 /* Check if PROP is a display property value whose text should be
4629 treated as intangible. OVERLAY is the overlay from which PROP
4630 came, or nil if it came from a text property. CHARPOS and BYTEPOS
4631 specify the buffer position covered by PROP. */
4632
4633 int
4634 display_prop_intangible_p (Lisp_Object prop, Lisp_Object overlay,
4635 EMACS_INT charpos, EMACS_INT bytepos)
4636 {
4637 int frame_window_p = FRAME_WINDOW_P (XFRAME (selected_frame));
4638 struct text_pos position;
4639
4640 SET_TEXT_POS (position, charpos, bytepos);
4641 return handle_display_spec (NULL, prop, Qnil, overlay,
4642 &position, charpos, frame_window_p);
4643 }
4644
4645
4646 /* Return 1 if PROP is a display sub-property value containing STRING.
4647
4648 Implementation note: this and the following function are really
4649 special cases of handle_display_spec and
4650 handle_single_display_spec, and should ideally use the same code.
4651 Until they do, these two pairs must be consistent and must be
4652 modified in sync. */
4653
4654 static int
4655 single_display_spec_string_p (Lisp_Object prop, Lisp_Object string)
4656 {
4657 if (EQ (string, prop))
4658 return 1;
4659
4660 /* Skip over `when FORM'. */
4661 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
4662 {
4663 prop = XCDR (prop);
4664 if (!CONSP (prop))
4665 return 0;
4666 /* Actually, the condition following `when' should be eval'ed,
4667 like handle_single_display_spec does, and we should return
4668 zero if it evaluates to nil. However, this function is
4669 called only when the buffer was already displayed and some
4670 glyph in the glyph matrix was found to come from a display
4671 string. Therefore, the condition was already evaluated, and
4672 the result was non-nil, otherwise the display string wouldn't
4673 have been displayed and we would have never been called for
4674 this property. Thus, we can skip the evaluation and assume
4675 its result is non-nil. */
4676 prop = XCDR (prop);
4677 }
4678
4679 if (CONSP (prop))
4680 /* Skip over `margin LOCATION'. */
4681 if (EQ (XCAR (prop), Qmargin))
4682 {
4683 prop = XCDR (prop);
4684 if (!CONSP (prop))
4685 return 0;
4686
4687 prop = XCDR (prop);
4688 if (!CONSP (prop))
4689 return 0;
4690 }
4691
4692 return EQ (prop, string) || (CONSP (prop) && EQ (XCAR (prop), string));
4693 }
4694
4695
4696 /* Return 1 if STRING appears in the `display' property PROP. */
4697
4698 static int
4699 display_prop_string_p (Lisp_Object prop, Lisp_Object string)
4700 {
4701 if (CONSP (prop)
4702 && !EQ (XCAR (prop), Qwhen)
4703 && !(CONSP (XCAR (prop)) && EQ (Qmargin, XCAR (XCAR (prop)))))
4704 {
4705 /* A list of sub-properties. */
4706 while (CONSP (prop))
4707 {
4708 if (single_display_spec_string_p (XCAR (prop), string))
4709 return 1;
4710 prop = XCDR (prop);
4711 }
4712 }
4713 else if (VECTORP (prop))
4714 {
4715 /* A vector of sub-properties. */
4716 int i;
4717 for (i = 0; i < ASIZE (prop); ++i)
4718 if (single_display_spec_string_p (AREF (prop, i), string))
4719 return 1;
4720 }
4721 else
4722 return single_display_spec_string_p (prop, string);
4723
4724 return 0;
4725 }
4726
4727 /* Look for STRING in overlays and text properties in the current
4728 buffer, between character positions FROM and TO (excluding TO).
4729 BACK_P non-zero means look back (in this case, TO is supposed to be
4730 less than FROM).
4731 Value is the first character position where STRING was found, or
4732 zero if it wasn't found before hitting TO.
4733
4734 This function may only use code that doesn't eval because it is
4735 called asynchronously from note_mouse_highlight. */
4736
4737 static EMACS_INT
4738 string_buffer_position_lim (Lisp_Object string,
4739 EMACS_INT from, EMACS_INT to, int back_p)
4740 {
4741 Lisp_Object limit, prop, pos;
4742 int found = 0;
4743
4744 pos = make_number (from);
4745
4746 if (!back_p) /* looking forward */
4747 {
4748 limit = make_number (min (to, ZV));
4749 while (!found && !EQ (pos, limit))
4750 {
4751 prop = Fget_char_property (pos, Qdisplay, Qnil);
4752 if (!NILP (prop) && display_prop_string_p (prop, string))
4753 found = 1;
4754 else
4755 pos = Fnext_single_char_property_change (pos, Qdisplay, Qnil,
4756 limit);
4757 }
4758 }
4759 else /* looking back */
4760 {
4761 limit = make_number (max (to, BEGV));
4762 while (!found && !EQ (pos, limit))
4763 {
4764 prop = Fget_char_property (pos, Qdisplay, Qnil);
4765 if (!NILP (prop) && display_prop_string_p (prop, string))
4766 found = 1;
4767 else
4768 pos = Fprevious_single_char_property_change (pos, Qdisplay, Qnil,
4769 limit);
4770 }
4771 }
4772
4773 return found ? XINT (pos) : 0;
4774 }
4775
4776 /* Determine which buffer position in current buffer STRING comes from.
4777 AROUND_CHARPOS is an approximate position where it could come from.
4778 Value is the buffer position or 0 if it couldn't be determined.
4779
4780 This function is necessary because we don't record buffer positions
4781 in glyphs generated from strings (to keep struct glyph small).
4782 This function may only use code that doesn't eval because it is
4783 called asynchronously from note_mouse_highlight. */
4784
4785 static EMACS_INT
4786 string_buffer_position (Lisp_Object string, EMACS_INT around_charpos)
4787 {
4788 const int MAX_DISTANCE = 1000;
4789 EMACS_INT found = string_buffer_position_lim (string, around_charpos,
4790 around_charpos + MAX_DISTANCE,
4791 0);
4792
4793 if (!found)
4794 found = string_buffer_position_lim (string, around_charpos,
4795 around_charpos - MAX_DISTANCE, 1);
4796 return found;
4797 }
4798
4799
4800 \f
4801 /***********************************************************************
4802 `composition' property
4803 ***********************************************************************/
4804
4805 /* Set up iterator IT from `composition' property at its current
4806 position. Called from handle_stop. */
4807
4808 static enum prop_handled
4809 handle_composition_prop (struct it *it)
4810 {
4811 Lisp_Object prop, string;
4812 EMACS_INT pos, pos_byte, start, end;
4813
4814 if (STRINGP (it->string))
4815 {
4816 unsigned char *s;
4817
4818 pos = IT_STRING_CHARPOS (*it);
4819 pos_byte = IT_STRING_BYTEPOS (*it);
4820 string = it->string;
4821 s = SDATA (string) + pos_byte;
4822 it->c = STRING_CHAR (s);
4823 }
4824 else
4825 {
4826 pos = IT_CHARPOS (*it);
4827 pos_byte = IT_BYTEPOS (*it);
4828 string = Qnil;
4829 it->c = FETCH_CHAR (pos_byte);
4830 }
4831
4832 /* If there's a valid composition and point is not inside of the
4833 composition (in the case that the composition is from the current
4834 buffer), draw a glyph composed from the composition components. */
4835 if (find_composition (pos, -1, &start, &end, &prop, string)
4836 && COMPOSITION_VALID_P (start, end, prop)
4837 && (STRINGP (it->string) || (PT <= start || PT >= end)))
4838 {
4839 if (start < pos)
4840 /* As we can't handle this situation (perhaps font-lock added
4841 a new composition), we just return here hoping that next
4842 redisplay will detect this composition much earlier. */
4843 return HANDLED_NORMALLY;
4844 if (start != pos)
4845 {
4846 if (STRINGP (it->string))
4847 pos_byte = string_char_to_byte (it->string, start);
4848 else
4849 pos_byte = CHAR_TO_BYTE (start);
4850 }
4851 it->cmp_it.id = get_composition_id (start, pos_byte, end - start,
4852 prop, string);
4853
4854 if (it->cmp_it.id >= 0)
4855 {
4856 it->cmp_it.ch = -1;
4857 it->cmp_it.nchars = COMPOSITION_LENGTH (prop);
4858 it->cmp_it.nglyphs = -1;
4859 }
4860 }
4861
4862 return HANDLED_NORMALLY;
4863 }
4864
4865
4866 \f
4867 /***********************************************************************
4868 Overlay strings
4869 ***********************************************************************/
4870
4871 /* The following structure is used to record overlay strings for
4872 later sorting in load_overlay_strings. */
4873
4874 struct overlay_entry
4875 {
4876 Lisp_Object overlay;
4877 Lisp_Object string;
4878 int priority;
4879 int after_string_p;
4880 };
4881
4882
4883 /* Set up iterator IT from overlay strings at its current position.
4884 Called from handle_stop. */
4885
4886 static enum prop_handled
4887 handle_overlay_change (struct it *it)
4888 {
4889 if (!STRINGP (it->string) && get_overlay_strings (it, 0))
4890 return HANDLED_RECOMPUTE_PROPS;
4891 else
4892 return HANDLED_NORMALLY;
4893 }
4894
4895
4896 /* Set up the next overlay string for delivery by IT, if there is an
4897 overlay string to deliver. Called by set_iterator_to_next when the
4898 end of the current overlay string is reached. If there are more
4899 overlay strings to display, IT->string and
4900 IT->current.overlay_string_index are set appropriately here.
4901 Otherwise IT->string is set to nil. */
4902
4903 static void
4904 next_overlay_string (struct it *it)
4905 {
4906 ++it->current.overlay_string_index;
4907 if (it->current.overlay_string_index == it->n_overlay_strings)
4908 {
4909 /* No more overlay strings. Restore IT's settings to what
4910 they were before overlay strings were processed, and
4911 continue to deliver from current_buffer. */
4912
4913 it->ellipsis_p = (it->stack[it->sp - 1].display_ellipsis_p != 0);
4914 pop_it (it);
4915 xassert (it->sp > 0
4916 || (NILP (it->string)
4917 && it->method == GET_FROM_BUFFER
4918 && it->stop_charpos >= BEGV
4919 && it->stop_charpos <= it->end_charpos));
4920 it->current.overlay_string_index = -1;
4921 it->n_overlay_strings = 0;
4922 it->overlay_strings_charpos = -1;
4923
4924 /* If we're at the end of the buffer, record that we have
4925 processed the overlay strings there already, so that
4926 next_element_from_buffer doesn't try it again. */
4927 if (NILP (it->string) && IT_CHARPOS (*it) >= it->end_charpos)
4928 it->overlay_strings_at_end_processed_p = 1;
4929 }
4930 else
4931 {
4932 /* There are more overlay strings to process. If
4933 IT->current.overlay_string_index has advanced to a position
4934 where we must load IT->overlay_strings with more strings, do
4935 it. We must load at the IT->overlay_strings_charpos where
4936 IT->n_overlay_strings was originally computed; when invisible
4937 text is present, this might not be IT_CHARPOS (Bug#7016). */
4938 int i = it->current.overlay_string_index % OVERLAY_STRING_CHUNK_SIZE;
4939
4940 if (it->current.overlay_string_index && i == 0)
4941 load_overlay_strings (it, it->overlay_strings_charpos);
4942
4943 /* Initialize IT to deliver display elements from the overlay
4944 string. */
4945 it->string = it->overlay_strings[i];
4946 it->multibyte_p = STRING_MULTIBYTE (it->string);
4947 SET_TEXT_POS (it->current.string_pos, 0, 0);
4948 it->method = GET_FROM_STRING;
4949 it->stop_charpos = 0;
4950 if (it->cmp_it.stop_pos >= 0)
4951 it->cmp_it.stop_pos = 0;
4952 it->prev_stop = 0;
4953 it->base_level_stop = 0;
4954
4955 /* Set up the bidi iterator for this overlay string. */
4956 if (it->bidi_p)
4957 {
4958 it->bidi_it.string.lstring = it->string;
4959 it->bidi_it.string.s = NULL;
4960 it->bidi_it.string.schars = SCHARS (it->string);
4961 it->bidi_it.string.bufpos = it->overlay_strings_charpos;
4962 it->bidi_it.string.from_disp_str = it->string_from_display_prop_p;
4963 it->bidi_it.string.unibyte = !it->multibyte_p;
4964 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
4965 }
4966 }
4967
4968 CHECK_IT (it);
4969 }
4970
4971
4972 /* Compare two overlay_entry structures E1 and E2. Used as a
4973 comparison function for qsort in load_overlay_strings. Overlay
4974 strings for the same position are sorted so that
4975
4976 1. All after-strings come in front of before-strings, except
4977 when they come from the same overlay.
4978
4979 2. Within after-strings, strings are sorted so that overlay strings
4980 from overlays with higher priorities come first.
4981
4982 2. Within before-strings, strings are sorted so that overlay
4983 strings from overlays with higher priorities come last.
4984
4985 Value is analogous to strcmp. */
4986
4987
4988 static int
4989 compare_overlay_entries (const void *e1, const void *e2)
4990 {
4991 struct overlay_entry *entry1 = (struct overlay_entry *) e1;
4992 struct overlay_entry *entry2 = (struct overlay_entry *) e2;
4993 int result;
4994
4995 if (entry1->after_string_p != entry2->after_string_p)
4996 {
4997 /* Let after-strings appear in front of before-strings if
4998 they come from different overlays. */
4999 if (EQ (entry1->overlay, entry2->overlay))
5000 result = entry1->after_string_p ? 1 : -1;
5001 else
5002 result = entry1->after_string_p ? -1 : 1;
5003 }
5004 else if (entry1->after_string_p)
5005 /* After-strings sorted in order of decreasing priority. */
5006 result = entry2->priority - entry1->priority;
5007 else
5008 /* Before-strings sorted in order of increasing priority. */
5009 result = entry1->priority - entry2->priority;
5010
5011 return result;
5012 }
5013
5014
5015 /* Load the vector IT->overlay_strings with overlay strings from IT's
5016 current buffer position, or from CHARPOS if that is > 0. Set
5017 IT->n_overlays to the total number of overlay strings found.
5018
5019 Overlay strings are processed OVERLAY_STRING_CHUNK_SIZE strings at
5020 a time. On entry into load_overlay_strings,
5021 IT->current.overlay_string_index gives the number of overlay
5022 strings that have already been loaded by previous calls to this
5023 function.
5024
5025 IT->add_overlay_start contains an additional overlay start
5026 position to consider for taking overlay strings from, if non-zero.
5027 This position comes into play when the overlay has an `invisible'
5028 property, and both before and after-strings. When we've skipped to
5029 the end of the overlay, because of its `invisible' property, we
5030 nevertheless want its before-string to appear.
5031 IT->add_overlay_start will contain the overlay start position
5032 in this case.
5033
5034 Overlay strings are sorted so that after-string strings come in
5035 front of before-string strings. Within before and after-strings,
5036 strings are sorted by overlay priority. See also function
5037 compare_overlay_entries. */
5038
5039 static void
5040 load_overlay_strings (struct it *it, EMACS_INT charpos)
5041 {
5042 Lisp_Object overlay, window, str, invisible;
5043 struct Lisp_Overlay *ov;
5044 EMACS_INT start, end;
5045 int size = 20;
5046 int n = 0, i, j, invis_p;
5047 struct overlay_entry *entries
5048 = (struct overlay_entry *) alloca (size * sizeof *entries);
5049
5050 if (charpos <= 0)
5051 charpos = IT_CHARPOS (*it);
5052
5053 /* Append the overlay string STRING of overlay OVERLAY to vector
5054 `entries' which has size `size' and currently contains `n'
5055 elements. AFTER_P non-zero means STRING is an after-string of
5056 OVERLAY. */
5057 #define RECORD_OVERLAY_STRING(OVERLAY, STRING, AFTER_P) \
5058 do \
5059 { \
5060 Lisp_Object priority; \
5061 \
5062 if (n == size) \
5063 { \
5064 int new_size = 2 * size; \
5065 struct overlay_entry *old = entries; \
5066 entries = \
5067 (struct overlay_entry *) alloca (new_size \
5068 * sizeof *entries); \
5069 memcpy (entries, old, size * sizeof *entries); \
5070 size = new_size; \
5071 } \
5072 \
5073 entries[n].string = (STRING); \
5074 entries[n].overlay = (OVERLAY); \
5075 priority = Foverlay_get ((OVERLAY), Qpriority); \
5076 entries[n].priority = INTEGERP (priority) ? XINT (priority) : 0; \
5077 entries[n].after_string_p = (AFTER_P); \
5078 ++n; \
5079 } \
5080 while (0)
5081
5082 /* Process overlay before the overlay center. */
5083 for (ov = current_buffer->overlays_before; ov; ov = ov->next)
5084 {
5085 XSETMISC (overlay, ov);
5086 xassert (OVERLAYP (overlay));
5087 start = OVERLAY_POSITION (OVERLAY_START (overlay));
5088 end = OVERLAY_POSITION (OVERLAY_END (overlay));
5089
5090 if (end < charpos)
5091 break;
5092
5093 /* Skip this overlay if it doesn't start or end at IT's current
5094 position. */
5095 if (end != charpos && start != charpos)
5096 continue;
5097
5098 /* Skip this overlay if it doesn't apply to IT->w. */
5099 window = Foverlay_get (overlay, Qwindow);
5100 if (WINDOWP (window) && XWINDOW (window) != it->w)
5101 continue;
5102
5103 /* If the text ``under'' the overlay is invisible, both before-
5104 and after-strings from this overlay are visible; start and
5105 end position are indistinguishable. */
5106 invisible = Foverlay_get (overlay, Qinvisible);
5107 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
5108
5109 /* If overlay has a non-empty before-string, record it. */
5110 if ((start == charpos || (end == charpos && invis_p))
5111 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
5112 && SCHARS (str))
5113 RECORD_OVERLAY_STRING (overlay, str, 0);
5114
5115 /* If overlay has a non-empty after-string, record it. */
5116 if ((end == charpos || (start == charpos && invis_p))
5117 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
5118 && SCHARS (str))
5119 RECORD_OVERLAY_STRING (overlay, str, 1);
5120 }
5121
5122 /* Process overlays after the overlay center. */
5123 for (ov = current_buffer->overlays_after; ov; ov = ov->next)
5124 {
5125 XSETMISC (overlay, ov);
5126 xassert (OVERLAYP (overlay));
5127 start = OVERLAY_POSITION (OVERLAY_START (overlay));
5128 end = OVERLAY_POSITION (OVERLAY_END (overlay));
5129
5130 if (start > charpos)
5131 break;
5132
5133 /* Skip this overlay if it doesn't start or end at IT's current
5134 position. */
5135 if (end != charpos && start != charpos)
5136 continue;
5137
5138 /* Skip this overlay if it doesn't apply to IT->w. */
5139 window = Foverlay_get (overlay, Qwindow);
5140 if (WINDOWP (window) && XWINDOW (window) != it->w)
5141 continue;
5142
5143 /* If the text ``under'' the overlay is invisible, it has a zero
5144 dimension, and both before- and after-strings apply. */
5145 invisible = Foverlay_get (overlay, Qinvisible);
5146 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
5147
5148 /* If overlay has a non-empty before-string, record it. */
5149 if ((start == charpos || (end == charpos && invis_p))
5150 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
5151 && SCHARS (str))
5152 RECORD_OVERLAY_STRING (overlay, str, 0);
5153
5154 /* If overlay has a non-empty after-string, record it. */
5155 if ((end == charpos || (start == charpos && invis_p))
5156 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
5157 && SCHARS (str))
5158 RECORD_OVERLAY_STRING (overlay, str, 1);
5159 }
5160
5161 #undef RECORD_OVERLAY_STRING
5162
5163 /* Sort entries. */
5164 if (n > 1)
5165 qsort (entries, n, sizeof *entries, compare_overlay_entries);
5166
5167 /* Record number of overlay strings, and where we computed it. */
5168 it->n_overlay_strings = n;
5169 it->overlay_strings_charpos = charpos;
5170
5171 /* IT->current.overlay_string_index is the number of overlay strings
5172 that have already been consumed by IT. Copy some of the
5173 remaining overlay strings to IT->overlay_strings. */
5174 i = 0;
5175 j = it->current.overlay_string_index;
5176 while (i < OVERLAY_STRING_CHUNK_SIZE && j < n)
5177 {
5178 it->overlay_strings[i] = entries[j].string;
5179 it->string_overlays[i++] = entries[j++].overlay;
5180 }
5181
5182 CHECK_IT (it);
5183 }
5184
5185
5186 /* Get the first chunk of overlay strings at IT's current buffer
5187 position, or at CHARPOS if that is > 0. Value is non-zero if at
5188 least one overlay string was found. */
5189
5190 static int
5191 get_overlay_strings_1 (struct it *it, EMACS_INT charpos, int compute_stop_p)
5192 {
5193 /* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to
5194 process. This fills IT->overlay_strings with strings, and sets
5195 IT->n_overlay_strings to the total number of strings to process.
5196 IT->pos.overlay_string_index has to be set temporarily to zero
5197 because load_overlay_strings needs this; it must be set to -1
5198 when no overlay strings are found because a zero value would
5199 indicate a position in the first overlay string. */
5200 it->current.overlay_string_index = 0;
5201 load_overlay_strings (it, charpos);
5202
5203 /* If we found overlay strings, set up IT to deliver display
5204 elements from the first one. Otherwise set up IT to deliver
5205 from current_buffer. */
5206 if (it->n_overlay_strings)
5207 {
5208 /* Make sure we know settings in current_buffer, so that we can
5209 restore meaningful values when we're done with the overlay
5210 strings. */
5211 if (compute_stop_p)
5212 compute_stop_pos (it);
5213 xassert (it->face_id >= 0);
5214
5215 /* Save IT's settings. They are restored after all overlay
5216 strings have been processed. */
5217 xassert (!compute_stop_p || it->sp == 0);
5218
5219 /* When called from handle_stop, there might be an empty display
5220 string loaded. In that case, don't bother saving it. */
5221 if (!STRINGP (it->string) || SCHARS (it->string))
5222 push_it (it, NULL);
5223
5224 /* Set up IT to deliver display elements from the first overlay
5225 string. */
5226 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
5227 it->string = it->overlay_strings[0];
5228 it->from_overlay = Qnil;
5229 it->stop_charpos = 0;
5230 xassert (STRINGP (it->string));
5231 it->end_charpos = SCHARS (it->string);
5232 it->prev_stop = 0;
5233 it->base_level_stop = 0;
5234 it->multibyte_p = STRING_MULTIBYTE (it->string);
5235 it->method = GET_FROM_STRING;
5236 it->from_disp_prop_p = 0;
5237
5238 /* Force paragraph direction to be that of the parent
5239 buffer. */
5240 if (it->bidi_p && it->bidi_it.paragraph_dir == R2L)
5241 it->paragraph_embedding = it->bidi_it.paragraph_dir;
5242 else
5243 it->paragraph_embedding = L2R;
5244
5245 /* Set up the bidi iterator for this overlay string. */
5246 if (it->bidi_p)
5247 {
5248 EMACS_INT pos = (charpos > 0 ? charpos : IT_CHARPOS (*it));
5249
5250 it->bidi_it.string.lstring = it->string;
5251 it->bidi_it.string.s = NULL;
5252 it->bidi_it.string.schars = SCHARS (it->string);
5253 it->bidi_it.string.bufpos = pos;
5254 it->bidi_it.string.from_disp_str = it->string_from_display_prop_p;
5255 it->bidi_it.string.unibyte = !it->multibyte_p;
5256 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
5257 }
5258 return 1;
5259 }
5260
5261 it->current.overlay_string_index = -1;
5262 return 0;
5263 }
5264
5265 static int
5266 get_overlay_strings (struct it *it, EMACS_INT charpos)
5267 {
5268 it->string = Qnil;
5269 it->method = GET_FROM_BUFFER;
5270
5271 (void) get_overlay_strings_1 (it, charpos, 1);
5272
5273 CHECK_IT (it);
5274
5275 /* Value is non-zero if we found at least one overlay string. */
5276 return STRINGP (it->string);
5277 }
5278
5279
5280 \f
5281 /***********************************************************************
5282 Saving and restoring state
5283 ***********************************************************************/
5284
5285 /* Save current settings of IT on IT->stack. Called, for example,
5286 before setting up IT for an overlay string, to be able to restore
5287 IT's settings to what they were after the overlay string has been
5288 processed. If POSITION is non-NULL, it is the position to save on
5289 the stack instead of IT->position. */
5290
5291 static void
5292 push_it (struct it *it, struct text_pos *position)
5293 {
5294 struct iterator_stack_entry *p;
5295
5296 xassert (it->sp < IT_STACK_SIZE);
5297 p = it->stack + it->sp;
5298
5299 p->stop_charpos = it->stop_charpos;
5300 p->prev_stop = it->prev_stop;
5301 p->base_level_stop = it->base_level_stop;
5302 p->cmp_it = it->cmp_it;
5303 xassert (it->face_id >= 0);
5304 p->face_id = it->face_id;
5305 p->string = it->string;
5306 p->method = it->method;
5307 p->from_overlay = it->from_overlay;
5308 switch (p->method)
5309 {
5310 case GET_FROM_IMAGE:
5311 p->u.image.object = it->object;
5312 p->u.image.image_id = it->image_id;
5313 p->u.image.slice = it->slice;
5314 break;
5315 case GET_FROM_STRETCH:
5316 p->u.stretch.object = it->object;
5317 break;
5318 }
5319 p->position = position ? *position : it->position;
5320 p->current = it->current;
5321 p->end_charpos = it->end_charpos;
5322 p->string_nchars = it->string_nchars;
5323 p->area = it->area;
5324 p->multibyte_p = it->multibyte_p;
5325 p->avoid_cursor_p = it->avoid_cursor_p;
5326 p->space_width = it->space_width;
5327 p->font_height = it->font_height;
5328 p->voffset = it->voffset;
5329 p->string_from_display_prop_p = it->string_from_display_prop_p;
5330 p->display_ellipsis_p = 0;
5331 p->line_wrap = it->line_wrap;
5332 p->bidi_p = it->bidi_p;
5333 p->paragraph_embedding = it->paragraph_embedding;
5334 p->from_disp_prop_p = it->from_disp_prop_p;
5335 ++it->sp;
5336
5337 /* Save the state of the bidi iterator as well. */
5338 if (it->bidi_p)
5339 bidi_push_it (&it->bidi_it);
5340 }
5341
5342 static void
5343 iterate_out_of_display_property (struct it *it)
5344 {
5345 int buffer_p = BUFFERP (it->object);
5346 EMACS_INT eob = (buffer_p ? ZV : it->end_charpos);
5347 EMACS_INT bob = (buffer_p ? BEGV : 0);
5348
5349 xassert (eob >= CHARPOS (it->position) && CHARPOS (it->position) >= bob);
5350
5351 /* Maybe initialize paragraph direction. If we are at the beginning
5352 of a new paragraph, next_element_from_buffer may not have a
5353 chance to do that. */
5354 if (it->bidi_it.first_elt && it->bidi_it.charpos < eob)
5355 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1);
5356 /* prev_stop can be zero, so check against BEGV as well. */
5357 while (it->bidi_it.charpos >= bob
5358 && it->prev_stop <= it->bidi_it.charpos
5359 && it->bidi_it.charpos < CHARPOS (it->position)
5360 && it->bidi_it.charpos < eob)
5361 bidi_move_to_visually_next (&it->bidi_it);
5362 /* Record the stop_pos we just crossed, for when we cross it
5363 back, maybe. */
5364 if (it->bidi_it.charpos > CHARPOS (it->position))
5365 it->prev_stop = CHARPOS (it->position);
5366 /* If we ended up not where pop_it put us, resync IT's
5367 positional members with the bidi iterator. */
5368 if (it->bidi_it.charpos != CHARPOS (it->position))
5369 SET_TEXT_POS (it->position, it->bidi_it.charpos, it->bidi_it.bytepos);
5370 if (buffer_p)
5371 it->current.pos = it->position;
5372 else
5373 it->current.string_pos = it->position;
5374 }
5375
5376 /* Restore IT's settings from IT->stack. Called, for example, when no
5377 more overlay strings must be processed, and we return to delivering
5378 display elements from a buffer, or when the end of a string from a
5379 `display' property is reached and we return to delivering display
5380 elements from an overlay string, or from a buffer. */
5381
5382 static void
5383 pop_it (struct it *it)
5384 {
5385 struct iterator_stack_entry *p;
5386 int from_display_prop = it->from_disp_prop_p;
5387
5388 xassert (it->sp > 0);
5389 --it->sp;
5390 p = it->stack + it->sp;
5391 it->stop_charpos = p->stop_charpos;
5392 it->prev_stop = p->prev_stop;
5393 it->base_level_stop = p->base_level_stop;
5394 it->cmp_it = p->cmp_it;
5395 it->face_id = p->face_id;
5396 it->current = p->current;
5397 it->position = p->position;
5398 it->string = p->string;
5399 it->from_overlay = p->from_overlay;
5400 if (NILP (it->string))
5401 SET_TEXT_POS (it->current.string_pos, -1, -1);
5402 it->method = p->method;
5403 switch (it->method)
5404 {
5405 case GET_FROM_IMAGE:
5406 it->image_id = p->u.image.image_id;
5407 it->object = p->u.image.object;
5408 it->slice = p->u.image.slice;
5409 break;
5410 case GET_FROM_STRETCH:
5411 it->object = p->u.stretch.object;
5412 break;
5413 case GET_FROM_BUFFER:
5414 it->object = it->w->buffer;
5415 break;
5416 case GET_FROM_STRING:
5417 it->object = it->string;
5418 break;
5419 case GET_FROM_DISPLAY_VECTOR:
5420 if (it->s)
5421 it->method = GET_FROM_C_STRING;
5422 else if (STRINGP (it->string))
5423 it->method = GET_FROM_STRING;
5424 else
5425 {
5426 it->method = GET_FROM_BUFFER;
5427 it->object = it->w->buffer;
5428 }
5429 }
5430 it->end_charpos = p->end_charpos;
5431 it->string_nchars = p->string_nchars;
5432 it->area = p->area;
5433 it->multibyte_p = p->multibyte_p;
5434 it->avoid_cursor_p = p->avoid_cursor_p;
5435 it->space_width = p->space_width;
5436 it->font_height = p->font_height;
5437 it->voffset = p->voffset;
5438 it->string_from_display_prop_p = p->string_from_display_prop_p;
5439 it->line_wrap = p->line_wrap;
5440 it->bidi_p = p->bidi_p;
5441 it->paragraph_embedding = p->paragraph_embedding;
5442 it->from_disp_prop_p = p->from_disp_prop_p;
5443 if (it->bidi_p)
5444 {
5445 bidi_pop_it (&it->bidi_it);
5446 /* Bidi-iterate until we get out of the portion of text, if any,
5447 covered by a `display' text property or by an overlay with
5448 `display' property. (We cannot just jump there, because the
5449 internal coherency of the bidi iterator state can not be
5450 preserved across such jumps.) We also must determine the
5451 paragraph base direction if the overlay we just processed is
5452 at the beginning of a new paragraph. */
5453 if (from_display_prop
5454 && (it->method == GET_FROM_BUFFER || it->method == GET_FROM_STRING))
5455 iterate_out_of_display_property (it);
5456
5457 xassert ((BUFFERP (it->object)
5458 && IT_CHARPOS (*it) == it->bidi_it.charpos
5459 && IT_BYTEPOS (*it) == it->bidi_it.bytepos)
5460 || (STRINGP (it->object)
5461 && IT_STRING_CHARPOS (*it) == it->bidi_it.charpos
5462 && IT_STRING_BYTEPOS (*it) == it->bidi_it.bytepos));
5463 }
5464 }
5465
5466
5467 \f
5468 /***********************************************************************
5469 Moving over lines
5470 ***********************************************************************/
5471
5472 /* Set IT's current position to the previous line start. */
5473
5474 static void
5475 back_to_previous_line_start (struct it *it)
5476 {
5477 IT_CHARPOS (*it) = find_next_newline_no_quit (IT_CHARPOS (*it) - 1, -1);
5478 IT_BYTEPOS (*it) = CHAR_TO_BYTE (IT_CHARPOS (*it));
5479 }
5480
5481
5482 /* Move IT to the next line start.
5483
5484 Value is non-zero if a newline was found. Set *SKIPPED_P to 1 if
5485 we skipped over part of the text (as opposed to moving the iterator
5486 continuously over the text). Otherwise, don't change the value
5487 of *SKIPPED_P.
5488
5489 If BIDI_IT_PREV is non-NULL, store into it the state of the bidi
5490 iterator on the newline, if it was found.
5491
5492 Newlines may come from buffer text, overlay strings, or strings
5493 displayed via the `display' property. That's the reason we can't
5494 simply use find_next_newline_no_quit.
5495
5496 Note that this function may not skip over invisible text that is so
5497 because of text properties and immediately follows a newline. If
5498 it would, function reseat_at_next_visible_line_start, when called
5499 from set_iterator_to_next, would effectively make invisible
5500 characters following a newline part of the wrong glyph row, which
5501 leads to wrong cursor motion. */
5502
5503 static int
5504 forward_to_next_line_start (struct it *it, int *skipped_p,
5505 struct bidi_it *bidi_it_prev)
5506 {
5507 EMACS_INT old_selective;
5508 int newline_found_p, n;
5509 const int MAX_NEWLINE_DISTANCE = 500;
5510
5511 /* If already on a newline, just consume it to avoid unintended
5512 skipping over invisible text below. */
5513 if (it->what == IT_CHARACTER
5514 && it->c == '\n'
5515 && CHARPOS (it->position) == IT_CHARPOS (*it))
5516 {
5517 if (it->bidi_p && bidi_it_prev)
5518 *bidi_it_prev = it->bidi_it;
5519 set_iterator_to_next (it, 0);
5520 it->c = 0;
5521 return 1;
5522 }
5523
5524 /* Don't handle selective display in the following. It's (a)
5525 unnecessary because it's done by the caller, and (b) leads to an
5526 infinite recursion because next_element_from_ellipsis indirectly
5527 calls this function. */
5528 old_selective = it->selective;
5529 it->selective = 0;
5530
5531 /* Scan for a newline within MAX_NEWLINE_DISTANCE display elements
5532 from buffer text. */
5533 for (n = newline_found_p = 0;
5534 !newline_found_p && n < MAX_NEWLINE_DISTANCE;
5535 n += STRINGP (it->string) ? 0 : 1)
5536 {
5537 if (!get_next_display_element (it))
5538 return 0;
5539 newline_found_p = it->what == IT_CHARACTER && it->c == '\n';
5540 if (newline_found_p && it->bidi_p && bidi_it_prev)
5541 *bidi_it_prev = it->bidi_it;
5542 set_iterator_to_next (it, 0);
5543 }
5544
5545 /* If we didn't find a newline near enough, see if we can use a
5546 short-cut. */
5547 if (!newline_found_p)
5548 {
5549 EMACS_INT start = IT_CHARPOS (*it);
5550 EMACS_INT limit = find_next_newline_no_quit (start, 1);
5551 Lisp_Object pos;
5552
5553 xassert (!STRINGP (it->string));
5554
5555 /* If there isn't any `display' property in sight, and no
5556 overlays, we can just use the position of the newline in
5557 buffer text. */
5558 if (it->stop_charpos >= limit
5559 || ((pos = Fnext_single_property_change (make_number (start),
5560 Qdisplay, Qnil,
5561 make_number (limit)),
5562 NILP (pos))
5563 && next_overlay_change (start) == ZV))
5564 {
5565 if (!it->bidi_p)
5566 {
5567 IT_CHARPOS (*it) = limit;
5568 IT_BYTEPOS (*it) = CHAR_TO_BYTE (limit);
5569 }
5570 else
5571 {
5572 struct bidi_it bprev;
5573
5574 /* Help bidi.c avoid expensive searches for display
5575 properties and overlays, by telling it that there are
5576 none up to `limit'. */
5577 if (it->bidi_it.disp_pos < limit)
5578 {
5579 it->bidi_it.disp_pos = limit;
5580 it->bidi_it.disp_prop = 0;
5581 }
5582 do {
5583 bprev = it->bidi_it;
5584 bidi_move_to_visually_next (&it->bidi_it);
5585 } while (it->bidi_it.charpos != limit);
5586 IT_CHARPOS (*it) = limit;
5587 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
5588 if (bidi_it_prev)
5589 *bidi_it_prev = bprev;
5590 }
5591 *skipped_p = newline_found_p = 1;
5592 }
5593 else
5594 {
5595 while (get_next_display_element (it)
5596 && !newline_found_p)
5597 {
5598 newline_found_p = ITERATOR_AT_END_OF_LINE_P (it);
5599 if (newline_found_p && it->bidi_p && bidi_it_prev)
5600 *bidi_it_prev = it->bidi_it;
5601 set_iterator_to_next (it, 0);
5602 }
5603 }
5604 }
5605
5606 it->selective = old_selective;
5607 return newline_found_p;
5608 }
5609
5610
5611 /* Set IT's current position to the previous visible line start. Skip
5612 invisible text that is so either due to text properties or due to
5613 selective display. Caution: this does not change IT->current_x and
5614 IT->hpos. */
5615
5616 static void
5617 back_to_previous_visible_line_start (struct it *it)
5618 {
5619 while (IT_CHARPOS (*it) > BEGV)
5620 {
5621 back_to_previous_line_start (it);
5622
5623 if (IT_CHARPOS (*it) <= BEGV)
5624 break;
5625
5626 /* If selective > 0, then lines indented more than its value are
5627 invisible. */
5628 if (it->selective > 0
5629 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
5630 it->selective))
5631 continue;
5632
5633 /* Check the newline before point for invisibility. */
5634 {
5635 Lisp_Object prop;
5636 prop = Fget_char_property (make_number (IT_CHARPOS (*it) - 1),
5637 Qinvisible, it->window);
5638 if (TEXT_PROP_MEANS_INVISIBLE (prop))
5639 continue;
5640 }
5641
5642 if (IT_CHARPOS (*it) <= BEGV)
5643 break;
5644
5645 {
5646 struct it it2;
5647 void *it2data = NULL;
5648 EMACS_INT pos;
5649 EMACS_INT beg, end;
5650 Lisp_Object val, overlay;
5651
5652 SAVE_IT (it2, *it, it2data);
5653
5654 /* If newline is part of a composition, continue from start of composition */
5655 if (find_composition (IT_CHARPOS (*it), -1, &beg, &end, &val, Qnil)
5656 && beg < IT_CHARPOS (*it))
5657 goto replaced;
5658
5659 /* If newline is replaced by a display property, find start of overlay
5660 or interval and continue search from that point. */
5661 pos = --IT_CHARPOS (it2);
5662 --IT_BYTEPOS (it2);
5663 it2.sp = 0;
5664 bidi_unshelve_cache (NULL, 0);
5665 it2.string_from_display_prop_p = 0;
5666 it2.from_disp_prop_p = 0;
5667 if (handle_display_prop (&it2) == HANDLED_RETURN
5668 && !NILP (val = get_char_property_and_overlay
5669 (make_number (pos), Qdisplay, Qnil, &overlay))
5670 && (OVERLAYP (overlay)
5671 ? (beg = OVERLAY_POSITION (OVERLAY_START (overlay)))
5672 : get_property_and_range (pos, Qdisplay, &val, &beg, &end, Qnil)))
5673 {
5674 RESTORE_IT (it, it, it2data);
5675 goto replaced;
5676 }
5677
5678 /* Newline is not replaced by anything -- so we are done. */
5679 RESTORE_IT (it, it, it2data);
5680 break;
5681
5682 replaced:
5683 if (beg < BEGV)
5684 beg = BEGV;
5685 IT_CHARPOS (*it) = beg;
5686 IT_BYTEPOS (*it) = buf_charpos_to_bytepos (current_buffer, beg);
5687 }
5688 }
5689
5690 it->continuation_lines_width = 0;
5691
5692 xassert (IT_CHARPOS (*it) >= BEGV);
5693 xassert (IT_CHARPOS (*it) == BEGV
5694 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
5695 CHECK_IT (it);
5696 }
5697
5698
5699 /* Reseat iterator IT at the previous visible line start. Skip
5700 invisible text that is so either due to text properties or due to
5701 selective display. At the end, update IT's overlay information,
5702 face information etc. */
5703
5704 void
5705 reseat_at_previous_visible_line_start (struct it *it)
5706 {
5707 back_to_previous_visible_line_start (it);
5708 reseat (it, it->current.pos, 1);
5709 CHECK_IT (it);
5710 }
5711
5712
5713 /* Reseat iterator IT on the next visible line start in the current
5714 buffer. ON_NEWLINE_P non-zero means position IT on the newline
5715 preceding the line start. Skip over invisible text that is so
5716 because of selective display. Compute faces, overlays etc at the
5717 new position. Note that this function does not skip over text that
5718 is invisible because of text properties. */
5719
5720 static void
5721 reseat_at_next_visible_line_start (struct it *it, int on_newline_p)
5722 {
5723 int newline_found_p, skipped_p = 0;
5724 struct bidi_it bidi_it_prev;
5725
5726 newline_found_p = forward_to_next_line_start (it, &skipped_p, &bidi_it_prev);
5727
5728 /* Skip over lines that are invisible because they are indented
5729 more than the value of IT->selective. */
5730 if (it->selective > 0)
5731 while (IT_CHARPOS (*it) < ZV
5732 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
5733 it->selective))
5734 {
5735 xassert (IT_BYTEPOS (*it) == BEGV
5736 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
5737 newline_found_p =
5738 forward_to_next_line_start (it, &skipped_p, &bidi_it_prev);
5739 }
5740
5741 /* Position on the newline if that's what's requested. */
5742 if (on_newline_p && newline_found_p)
5743 {
5744 if (STRINGP (it->string))
5745 {
5746 if (IT_STRING_CHARPOS (*it) > 0)
5747 {
5748 if (!it->bidi_p)
5749 {
5750 --IT_STRING_CHARPOS (*it);
5751 --IT_STRING_BYTEPOS (*it);
5752 }
5753 else
5754 {
5755 /* We need to restore the bidi iterator to the state
5756 it had on the newline, and resync the IT's
5757 position with that. */
5758 it->bidi_it = bidi_it_prev;
5759 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
5760 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
5761 }
5762 }
5763 }
5764 else if (IT_CHARPOS (*it) > BEGV)
5765 {
5766 if (!it->bidi_p)
5767 {
5768 --IT_CHARPOS (*it);
5769 --IT_BYTEPOS (*it);
5770 }
5771 else
5772 {
5773 /* We need to restore the bidi iterator to the state it
5774 had on the newline and resync IT with that. */
5775 it->bidi_it = bidi_it_prev;
5776 IT_CHARPOS (*it) = it->bidi_it.charpos;
5777 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
5778 }
5779 reseat (it, it->current.pos, 0);
5780 }
5781 }
5782 else if (skipped_p)
5783 reseat (it, it->current.pos, 0);
5784
5785 CHECK_IT (it);
5786 }
5787
5788
5789 \f
5790 /***********************************************************************
5791 Changing an iterator's position
5792 ***********************************************************************/
5793
5794 /* Change IT's current position to POS in current_buffer. If FORCE_P
5795 is non-zero, always check for text properties at the new position.
5796 Otherwise, text properties are only looked up if POS >=
5797 IT->check_charpos of a property. */
5798
5799 static void
5800 reseat (struct it *it, struct text_pos pos, int force_p)
5801 {
5802 EMACS_INT original_pos = IT_CHARPOS (*it);
5803
5804 reseat_1 (it, pos, 0);
5805
5806 /* Determine where to check text properties. Avoid doing it
5807 where possible because text property lookup is very expensive. */
5808 if (force_p
5809 || CHARPOS (pos) > it->stop_charpos
5810 || CHARPOS (pos) < original_pos)
5811 {
5812 if (it->bidi_p)
5813 {
5814 /* For bidi iteration, we need to prime prev_stop and
5815 base_level_stop with our best estimations. */
5816 /* Implementation note: Of course, POS is not necessarily a
5817 stop position, so assigning prev_pos to it is a lie; we
5818 should have called compute_stop_backwards. However, if
5819 the current buffer does not include any R2L characters,
5820 that call would be a waste of cycles, because the
5821 iterator will never move back, and thus never cross this
5822 "fake" stop position. So we delay that backward search
5823 until the time we really need it, in next_element_from_buffer. */
5824 if (CHARPOS (pos) != it->prev_stop)
5825 it->prev_stop = CHARPOS (pos);
5826 if (CHARPOS (pos) < it->base_level_stop)
5827 it->base_level_stop = 0; /* meaning it's unknown */
5828 handle_stop (it);
5829 }
5830 else
5831 {
5832 handle_stop (it);
5833 it->prev_stop = it->base_level_stop = 0;
5834 }
5835
5836 }
5837
5838 CHECK_IT (it);
5839 }
5840
5841
5842 /* Change IT's buffer position to POS. SET_STOP_P non-zero means set
5843 IT->stop_pos to POS, also. */
5844
5845 static void
5846 reseat_1 (struct it *it, struct text_pos pos, int set_stop_p)
5847 {
5848 /* Don't call this function when scanning a C string. */
5849 xassert (it->s == NULL);
5850
5851 /* POS must be a reasonable value. */
5852 xassert (CHARPOS (pos) >= BEGV && CHARPOS (pos) <= ZV);
5853
5854 it->current.pos = it->position = pos;
5855 it->end_charpos = ZV;
5856 it->dpvec = NULL;
5857 it->current.dpvec_index = -1;
5858 it->current.overlay_string_index = -1;
5859 IT_STRING_CHARPOS (*it) = -1;
5860 IT_STRING_BYTEPOS (*it) = -1;
5861 it->string = Qnil;
5862 it->method = GET_FROM_BUFFER;
5863 it->object = it->w->buffer;
5864 it->area = TEXT_AREA;
5865 it->multibyte_p = !NILP (BVAR (current_buffer, enable_multibyte_characters));
5866 it->sp = 0;
5867 it->string_from_display_prop_p = 0;
5868 it->from_disp_prop_p = 0;
5869 it->face_before_selective_p = 0;
5870 if (it->bidi_p)
5871 {
5872 bidi_init_it (IT_CHARPOS (*it), IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f),
5873 &it->bidi_it);
5874 bidi_unshelve_cache (NULL, 0);
5875 it->bidi_it.paragraph_dir = NEUTRAL_DIR;
5876 it->bidi_it.string.s = NULL;
5877 it->bidi_it.string.lstring = Qnil;
5878 it->bidi_it.string.bufpos = 0;
5879 it->bidi_it.string.unibyte = 0;
5880 }
5881
5882 if (set_stop_p)
5883 {
5884 it->stop_charpos = CHARPOS (pos);
5885 it->base_level_stop = CHARPOS (pos);
5886 }
5887 }
5888
5889
5890 /* Set up IT for displaying a string, starting at CHARPOS in window W.
5891 If S is non-null, it is a C string to iterate over. Otherwise,
5892 STRING gives a Lisp string to iterate over.
5893
5894 If PRECISION > 0, don't return more then PRECISION number of
5895 characters from the string.
5896
5897 If FIELD_WIDTH > 0, return padding spaces until FIELD_WIDTH
5898 characters have been returned. FIELD_WIDTH < 0 means an infinite
5899 field width.
5900
5901 MULTIBYTE = 0 means disable processing of multibyte characters,
5902 MULTIBYTE > 0 means enable it,
5903 MULTIBYTE < 0 means use IT->multibyte_p.
5904
5905 IT must be initialized via a prior call to init_iterator before
5906 calling this function. */
5907
5908 static void
5909 reseat_to_string (struct it *it, const char *s, Lisp_Object string,
5910 EMACS_INT charpos, EMACS_INT precision, int field_width,
5911 int multibyte)
5912 {
5913 /* No region in strings. */
5914 it->region_beg_charpos = it->region_end_charpos = -1;
5915
5916 /* No text property checks performed by default, but see below. */
5917 it->stop_charpos = -1;
5918
5919 /* Set iterator position and end position. */
5920 memset (&it->current, 0, sizeof it->current);
5921 it->current.overlay_string_index = -1;
5922 it->current.dpvec_index = -1;
5923 xassert (charpos >= 0);
5924
5925 /* If STRING is specified, use its multibyteness, otherwise use the
5926 setting of MULTIBYTE, if specified. */
5927 if (multibyte >= 0)
5928 it->multibyte_p = multibyte > 0;
5929
5930 /* Bidirectional reordering of strings is controlled by the default
5931 value of bidi-display-reordering. */
5932 it->bidi_p = !NILP (BVAR (&buffer_defaults, bidi_display_reordering));
5933
5934 if (s == NULL)
5935 {
5936 xassert (STRINGP (string));
5937 it->string = string;
5938 it->s = NULL;
5939 it->end_charpos = it->string_nchars = SCHARS (string);
5940 it->method = GET_FROM_STRING;
5941 it->current.string_pos = string_pos (charpos, string);
5942
5943 if (it->bidi_p)
5944 {
5945 it->bidi_it.string.lstring = string;
5946 it->bidi_it.string.s = NULL;
5947 it->bidi_it.string.schars = it->end_charpos;
5948 it->bidi_it.string.bufpos = 0;
5949 it->bidi_it.string.from_disp_str = 0;
5950 it->bidi_it.string.unibyte = !it->multibyte_p;
5951 bidi_init_it (charpos, IT_STRING_BYTEPOS (*it),
5952 FRAME_WINDOW_P (it->f), &it->bidi_it);
5953 }
5954 }
5955 else
5956 {
5957 it->s = (const unsigned char *) s;
5958 it->string = Qnil;
5959
5960 /* Note that we use IT->current.pos, not it->current.string_pos,
5961 for displaying C strings. */
5962 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
5963 if (it->multibyte_p)
5964 {
5965 it->current.pos = c_string_pos (charpos, s, 1);
5966 it->end_charpos = it->string_nchars = number_of_chars (s, 1);
5967 }
5968 else
5969 {
5970 IT_CHARPOS (*it) = IT_BYTEPOS (*it) = charpos;
5971 it->end_charpos = it->string_nchars = strlen (s);
5972 }
5973
5974 if (it->bidi_p)
5975 {
5976 it->bidi_it.string.lstring = Qnil;
5977 it->bidi_it.string.s = (const unsigned char *) s;
5978 it->bidi_it.string.schars = it->end_charpos;
5979 it->bidi_it.string.bufpos = 0;
5980 it->bidi_it.string.from_disp_str = 0;
5981 it->bidi_it.string.unibyte = !it->multibyte_p;
5982 bidi_init_it (charpos, IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f),
5983 &it->bidi_it);
5984 }
5985 it->method = GET_FROM_C_STRING;
5986 }
5987
5988 /* PRECISION > 0 means don't return more than PRECISION characters
5989 from the string. */
5990 if (precision > 0 && it->end_charpos - charpos > precision)
5991 {
5992 it->end_charpos = it->string_nchars = charpos + precision;
5993 if (it->bidi_p)
5994 it->bidi_it.string.schars = it->end_charpos;
5995 }
5996
5997 /* FIELD_WIDTH > 0 means pad with spaces until FIELD_WIDTH
5998 characters have been returned. FIELD_WIDTH == 0 means don't pad,
5999 FIELD_WIDTH < 0 means infinite field width. This is useful for
6000 padding with `-' at the end of a mode line. */
6001 if (field_width < 0)
6002 field_width = INFINITY;
6003 /* Implementation note: We deliberately don't enlarge
6004 it->bidi_it.string.schars here to fit it->end_charpos, because
6005 the bidi iterator cannot produce characters out of thin air. */
6006 if (field_width > it->end_charpos - charpos)
6007 it->end_charpos = charpos + field_width;
6008
6009 /* Use the standard display table for displaying strings. */
6010 if (DISP_TABLE_P (Vstandard_display_table))
6011 it->dp = XCHAR_TABLE (Vstandard_display_table);
6012
6013 it->stop_charpos = charpos;
6014 it->prev_stop = charpos;
6015 it->base_level_stop = 0;
6016 if (it->bidi_p)
6017 {
6018 it->bidi_it.first_elt = 1;
6019 it->bidi_it.paragraph_dir = NEUTRAL_DIR;
6020 it->bidi_it.disp_pos = -1;
6021 }
6022 if (s == NULL && it->multibyte_p)
6023 {
6024 EMACS_INT endpos = SCHARS (it->string);
6025 if (endpos > it->end_charpos)
6026 endpos = it->end_charpos;
6027 composition_compute_stop_pos (&it->cmp_it, charpos, -1, endpos,
6028 it->string);
6029 }
6030 CHECK_IT (it);
6031 }
6032
6033
6034 \f
6035 /***********************************************************************
6036 Iteration
6037 ***********************************************************************/
6038
6039 /* Map enum it_method value to corresponding next_element_from_* function. */
6040
6041 static int (* get_next_element[NUM_IT_METHODS]) (struct it *it) =
6042 {
6043 next_element_from_buffer,
6044 next_element_from_display_vector,
6045 next_element_from_string,
6046 next_element_from_c_string,
6047 next_element_from_image,
6048 next_element_from_stretch
6049 };
6050
6051 #define GET_NEXT_DISPLAY_ELEMENT(it) (*get_next_element[(it)->method]) (it)
6052
6053
6054 /* Return 1 iff a character at CHARPOS (and BYTEPOS) is composed
6055 (possibly with the following characters). */
6056
6057 #define CHAR_COMPOSED_P(IT,CHARPOS,BYTEPOS,END_CHARPOS) \
6058 ((IT)->cmp_it.id >= 0 \
6059 || ((IT)->cmp_it.stop_pos == (CHARPOS) \
6060 && composition_reseat_it (&(IT)->cmp_it, CHARPOS, BYTEPOS, \
6061 END_CHARPOS, (IT)->w, \
6062 FACE_FROM_ID ((IT)->f, (IT)->face_id), \
6063 (IT)->string)))
6064
6065
6066 /* Lookup the char-table Vglyphless_char_display for character C (-1
6067 if we want information for no-font case), and return the display
6068 method symbol. By side-effect, update it->what and
6069 it->glyphless_method. This function is called from
6070 get_next_display_element for each character element, and from
6071 x_produce_glyphs when no suitable font was found. */
6072
6073 Lisp_Object
6074 lookup_glyphless_char_display (int c, struct it *it)
6075 {
6076 Lisp_Object glyphless_method = Qnil;
6077
6078 if (CHAR_TABLE_P (Vglyphless_char_display)
6079 && CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (Vglyphless_char_display)) >= 1)
6080 {
6081 if (c >= 0)
6082 {
6083 glyphless_method = CHAR_TABLE_REF (Vglyphless_char_display, c);
6084 if (CONSP (glyphless_method))
6085 glyphless_method = FRAME_WINDOW_P (it->f)
6086 ? XCAR (glyphless_method)
6087 : XCDR (glyphless_method);
6088 }
6089 else
6090 glyphless_method = XCHAR_TABLE (Vglyphless_char_display)->extras[0];
6091 }
6092
6093 retry:
6094 if (NILP (glyphless_method))
6095 {
6096 if (c >= 0)
6097 /* The default is to display the character by a proper font. */
6098 return Qnil;
6099 /* The default for the no-font case is to display an empty box. */
6100 glyphless_method = Qempty_box;
6101 }
6102 if (EQ (glyphless_method, Qzero_width))
6103 {
6104 if (c >= 0)
6105 return glyphless_method;
6106 /* This method can't be used for the no-font case. */
6107 glyphless_method = Qempty_box;
6108 }
6109 if (EQ (glyphless_method, Qthin_space))
6110 it->glyphless_method = GLYPHLESS_DISPLAY_THIN_SPACE;
6111 else if (EQ (glyphless_method, Qempty_box))
6112 it->glyphless_method = GLYPHLESS_DISPLAY_EMPTY_BOX;
6113 else if (EQ (glyphless_method, Qhex_code))
6114 it->glyphless_method = GLYPHLESS_DISPLAY_HEX_CODE;
6115 else if (STRINGP (glyphless_method))
6116 it->glyphless_method = GLYPHLESS_DISPLAY_ACRONYM;
6117 else
6118 {
6119 /* Invalid value. We use the default method. */
6120 glyphless_method = Qnil;
6121 goto retry;
6122 }
6123 it->what = IT_GLYPHLESS;
6124 return glyphless_method;
6125 }
6126
6127 /* Load IT's display element fields with information about the next
6128 display element from the current position of IT. Value is zero if
6129 end of buffer (or C string) is reached. */
6130
6131 static struct frame *last_escape_glyph_frame = NULL;
6132 static unsigned last_escape_glyph_face_id = (1 << FACE_ID_BITS);
6133 static int last_escape_glyph_merged_face_id = 0;
6134
6135 struct frame *last_glyphless_glyph_frame = NULL;
6136 unsigned last_glyphless_glyph_face_id = (1 << FACE_ID_BITS);
6137 int last_glyphless_glyph_merged_face_id = 0;
6138
6139 static int
6140 get_next_display_element (struct it *it)
6141 {
6142 /* Non-zero means that we found a display element. Zero means that
6143 we hit the end of what we iterate over. Performance note: the
6144 function pointer `method' used here turns out to be faster than
6145 using a sequence of if-statements. */
6146 int success_p;
6147
6148 get_next:
6149 success_p = GET_NEXT_DISPLAY_ELEMENT (it);
6150
6151 if (it->what == IT_CHARACTER)
6152 {
6153 /* UAX#9, L4: "A character is depicted by a mirrored glyph if
6154 and only if (a) the resolved directionality of that character
6155 is R..." */
6156 /* FIXME: Do we need an exception for characters from display
6157 tables? */
6158 if (it->bidi_p && it->bidi_it.type == STRONG_R)
6159 it->c = bidi_mirror_char (it->c);
6160 /* Map via display table or translate control characters.
6161 IT->c, IT->len etc. have been set to the next character by
6162 the function call above. If we have a display table, and it
6163 contains an entry for IT->c, translate it. Don't do this if
6164 IT->c itself comes from a display table, otherwise we could
6165 end up in an infinite recursion. (An alternative could be to
6166 count the recursion depth of this function and signal an
6167 error when a certain maximum depth is reached.) Is it worth
6168 it? */
6169 if (success_p && it->dpvec == NULL)
6170 {
6171 Lisp_Object dv;
6172 struct charset *unibyte = CHARSET_FROM_ID (charset_unibyte);
6173 enum { char_is_other = 0, char_is_nbsp, char_is_soft_hyphen }
6174 nbsp_or_shy = char_is_other;
6175 int c = it->c; /* This is the character to display. */
6176
6177 if (! it->multibyte_p && ! ASCII_CHAR_P (c))
6178 {
6179 xassert (SINGLE_BYTE_CHAR_P (c));
6180 if (unibyte_display_via_language_environment)
6181 {
6182 c = DECODE_CHAR (unibyte, c);
6183 if (c < 0)
6184 c = BYTE8_TO_CHAR (it->c);
6185 }
6186 else
6187 c = BYTE8_TO_CHAR (it->c);
6188 }
6189
6190 if (it->dp
6191 && (dv = DISP_CHAR_VECTOR (it->dp, c),
6192 VECTORP (dv)))
6193 {
6194 struct Lisp_Vector *v = XVECTOR (dv);
6195
6196 /* Return the first character from the display table
6197 entry, if not empty. If empty, don't display the
6198 current character. */
6199 if (v->header.size)
6200 {
6201 it->dpvec_char_len = it->len;
6202 it->dpvec = v->contents;
6203 it->dpend = v->contents + v->header.size;
6204 it->current.dpvec_index = 0;
6205 it->dpvec_face_id = -1;
6206 it->saved_face_id = it->face_id;
6207 it->method = GET_FROM_DISPLAY_VECTOR;
6208 it->ellipsis_p = 0;
6209 }
6210 else
6211 {
6212 set_iterator_to_next (it, 0);
6213 }
6214 goto get_next;
6215 }
6216
6217 if (! NILP (lookup_glyphless_char_display (c, it)))
6218 {
6219 if (it->what == IT_GLYPHLESS)
6220 goto done;
6221 /* Don't display this character. */
6222 set_iterator_to_next (it, 0);
6223 goto get_next;
6224 }
6225
6226 if (! ASCII_CHAR_P (c) && ! NILP (Vnobreak_char_display))
6227 nbsp_or_shy = (c == 0xA0 ? char_is_nbsp
6228 : c == 0xAD ? char_is_soft_hyphen
6229 : char_is_other);
6230
6231 /* Translate control characters into `\003' or `^C' form.
6232 Control characters coming from a display table entry are
6233 currently not translated because we use IT->dpvec to hold
6234 the translation. This could easily be changed but I
6235 don't believe that it is worth doing.
6236
6237 NBSP and SOFT-HYPEN are property translated too.
6238
6239 Non-printable characters and raw-byte characters are also
6240 translated to octal form. */
6241 if (((c < ' ' || c == 127) /* ASCII control chars */
6242 ? (it->area != TEXT_AREA
6243 /* In mode line, treat \n, \t like other crl chars. */
6244 || (c != '\t'
6245 && it->glyph_row
6246 && (it->glyph_row->mode_line_p || it->avoid_cursor_p))
6247 || (c != '\n' && c != '\t'))
6248 : (nbsp_or_shy
6249 || CHAR_BYTE8_P (c)
6250 || ! CHAR_PRINTABLE_P (c))))
6251 {
6252 /* C is a control character, NBSP, SOFT-HYPEN, raw-byte,
6253 or a non-printable character which must be displayed
6254 either as '\003' or as `^C' where the '\\' and '^'
6255 can be defined in the display table. Fill
6256 IT->ctl_chars with glyphs for what we have to
6257 display. Then, set IT->dpvec to these glyphs. */
6258 Lisp_Object gc;
6259 int ctl_len;
6260 int face_id;
6261 EMACS_INT lface_id = 0;
6262 int escape_glyph;
6263
6264 /* Handle control characters with ^. */
6265
6266 if (ASCII_CHAR_P (c) && it->ctl_arrow_p)
6267 {
6268 int g;
6269
6270 g = '^'; /* default glyph for Control */
6271 /* Set IT->ctl_chars[0] to the glyph for `^'. */
6272 if (it->dp
6273 && (gc = DISP_CTRL_GLYPH (it->dp), GLYPH_CODE_P (gc))
6274 && GLYPH_CODE_CHAR_VALID_P (gc))
6275 {
6276 g = GLYPH_CODE_CHAR (gc);
6277 lface_id = GLYPH_CODE_FACE (gc);
6278 }
6279 if (lface_id)
6280 {
6281 face_id = merge_faces (it->f, Qt, lface_id, it->face_id);
6282 }
6283 else if (it->f == last_escape_glyph_frame
6284 && it->face_id == last_escape_glyph_face_id)
6285 {
6286 face_id = last_escape_glyph_merged_face_id;
6287 }
6288 else
6289 {
6290 /* Merge the escape-glyph face into the current face. */
6291 face_id = merge_faces (it->f, Qescape_glyph, 0,
6292 it->face_id);
6293 last_escape_glyph_frame = it->f;
6294 last_escape_glyph_face_id = it->face_id;
6295 last_escape_glyph_merged_face_id = face_id;
6296 }
6297
6298 XSETINT (it->ctl_chars[0], g);
6299 XSETINT (it->ctl_chars[1], c ^ 0100);
6300 ctl_len = 2;
6301 goto display_control;
6302 }
6303
6304 /* Handle non-break space in the mode where it only gets
6305 highlighting. */
6306
6307 if (EQ (Vnobreak_char_display, Qt)
6308 && nbsp_or_shy == char_is_nbsp)
6309 {
6310 /* Merge the no-break-space face into the current face. */
6311 face_id = merge_faces (it->f, Qnobreak_space, 0,
6312 it->face_id);
6313
6314 c = ' ';
6315 XSETINT (it->ctl_chars[0], ' ');
6316 ctl_len = 1;
6317 goto display_control;
6318 }
6319
6320 /* Handle sequences that start with the "escape glyph". */
6321
6322 /* the default escape glyph is \. */
6323 escape_glyph = '\\';
6324
6325 if (it->dp
6326 && (gc = DISP_ESCAPE_GLYPH (it->dp), GLYPH_CODE_P (gc))
6327 && GLYPH_CODE_CHAR_VALID_P (gc))
6328 {
6329 escape_glyph = GLYPH_CODE_CHAR (gc);
6330 lface_id = GLYPH_CODE_FACE (gc);
6331 }
6332 if (lface_id)
6333 {
6334 /* The display table specified a face.
6335 Merge it into face_id and also into escape_glyph. */
6336 face_id = merge_faces (it->f, Qt, lface_id,
6337 it->face_id);
6338 }
6339 else if (it->f == last_escape_glyph_frame
6340 && it->face_id == last_escape_glyph_face_id)
6341 {
6342 face_id = last_escape_glyph_merged_face_id;
6343 }
6344 else
6345 {
6346 /* Merge the escape-glyph face into the current face. */
6347 face_id = merge_faces (it->f, Qescape_glyph, 0,
6348 it->face_id);
6349 last_escape_glyph_frame = it->f;
6350 last_escape_glyph_face_id = it->face_id;
6351 last_escape_glyph_merged_face_id = face_id;
6352 }
6353
6354 /* Handle soft hyphens in the mode where they only get
6355 highlighting. */
6356
6357 if (EQ (Vnobreak_char_display, Qt)
6358 && nbsp_or_shy == char_is_soft_hyphen)
6359 {
6360 XSETINT (it->ctl_chars[0], '-');
6361 ctl_len = 1;
6362 goto display_control;
6363 }
6364
6365 /* Handle non-break space and soft hyphen
6366 with the escape glyph. */
6367
6368 if (nbsp_or_shy)
6369 {
6370 XSETINT (it->ctl_chars[0], escape_glyph);
6371 c = (nbsp_or_shy == char_is_nbsp ? ' ' : '-');
6372 XSETINT (it->ctl_chars[1], c);
6373 ctl_len = 2;
6374 goto display_control;
6375 }
6376
6377 {
6378 char str[10];
6379 int len, i;
6380
6381 if (CHAR_BYTE8_P (c))
6382 /* Display \200 instead of \17777600. */
6383 c = CHAR_TO_BYTE8 (c);
6384 len = sprintf (str, "%03o", c);
6385
6386 XSETINT (it->ctl_chars[0], escape_glyph);
6387 for (i = 0; i < len; i++)
6388 XSETINT (it->ctl_chars[i + 1], str[i]);
6389 ctl_len = len + 1;
6390 }
6391
6392 display_control:
6393 /* Set up IT->dpvec and return first character from it. */
6394 it->dpvec_char_len = it->len;
6395 it->dpvec = it->ctl_chars;
6396 it->dpend = it->dpvec + ctl_len;
6397 it->current.dpvec_index = 0;
6398 it->dpvec_face_id = face_id;
6399 it->saved_face_id = it->face_id;
6400 it->method = GET_FROM_DISPLAY_VECTOR;
6401 it->ellipsis_p = 0;
6402 goto get_next;
6403 }
6404 it->char_to_display = c;
6405 }
6406 else if (success_p)
6407 {
6408 it->char_to_display = it->c;
6409 }
6410 }
6411
6412 /* Adjust face id for a multibyte character. There are no multibyte
6413 character in unibyte text. */
6414 if ((it->what == IT_CHARACTER || it->what == IT_COMPOSITION)
6415 && it->multibyte_p
6416 && success_p
6417 && FRAME_WINDOW_P (it->f))
6418 {
6419 struct face *face = FACE_FROM_ID (it->f, it->face_id);
6420
6421 if (it->what == IT_COMPOSITION && it->cmp_it.ch >= 0)
6422 {
6423 /* Automatic composition with glyph-string. */
6424 Lisp_Object gstring = composition_gstring_from_id (it->cmp_it.id);
6425
6426 it->face_id = face_for_font (it->f, LGSTRING_FONT (gstring), face);
6427 }
6428 else
6429 {
6430 EMACS_INT pos = (it->s ? -1
6431 : STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
6432 : IT_CHARPOS (*it));
6433 int c;
6434
6435 if (it->what == IT_CHARACTER)
6436 c = it->char_to_display;
6437 else
6438 {
6439 struct composition *cmp = composition_table[it->cmp_it.id];
6440 int i;
6441
6442 c = ' ';
6443 for (i = 0; i < cmp->glyph_len; i++)
6444 if ((c = COMPOSITION_GLYPH (cmp, i)) != '\t')
6445 break;
6446 }
6447 it->face_id = FACE_FOR_CHAR (it->f, face, c, pos, it->string);
6448 }
6449 }
6450
6451 done:
6452 /* Is this character the last one of a run of characters with
6453 box? If yes, set IT->end_of_box_run_p to 1. */
6454 if (it->face_box_p
6455 && it->s == NULL)
6456 {
6457 if (it->method == GET_FROM_STRING && it->sp)
6458 {
6459 int face_id = underlying_face_id (it);
6460 struct face *face = FACE_FROM_ID (it->f, face_id);
6461
6462 if (face)
6463 {
6464 if (face->box == FACE_NO_BOX)
6465 {
6466 /* If the box comes from face properties in a
6467 display string, check faces in that string. */
6468 int string_face_id = face_after_it_pos (it);
6469 it->end_of_box_run_p
6470 = (FACE_FROM_ID (it->f, string_face_id)->box
6471 == FACE_NO_BOX);
6472 }
6473 /* Otherwise, the box comes from the underlying face.
6474 If this is the last string character displayed, check
6475 the next buffer location. */
6476 else if ((IT_STRING_CHARPOS (*it) >= SCHARS (it->string) - 1)
6477 && (it->current.overlay_string_index
6478 == it->n_overlay_strings - 1))
6479 {
6480 EMACS_INT ignore;
6481 int next_face_id;
6482 struct text_pos pos = it->current.pos;
6483 INC_TEXT_POS (pos, it->multibyte_p);
6484
6485 next_face_id = face_at_buffer_position
6486 (it->w, CHARPOS (pos), it->region_beg_charpos,
6487 it->region_end_charpos, &ignore,
6488 (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT), 0,
6489 -1);
6490 it->end_of_box_run_p
6491 = (FACE_FROM_ID (it->f, next_face_id)->box
6492 == FACE_NO_BOX);
6493 }
6494 }
6495 }
6496 else
6497 {
6498 int face_id = face_after_it_pos (it);
6499 it->end_of_box_run_p
6500 = (face_id != it->face_id
6501 && FACE_FROM_ID (it->f, face_id)->box == FACE_NO_BOX);
6502 }
6503 }
6504
6505 /* Value is 0 if end of buffer or string reached. */
6506 return success_p;
6507 }
6508
6509
6510 /* Move IT to the next display element.
6511
6512 RESEAT_P non-zero means if called on a newline in buffer text,
6513 skip to the next visible line start.
6514
6515 Functions get_next_display_element and set_iterator_to_next are
6516 separate because I find this arrangement easier to handle than a
6517 get_next_display_element function that also increments IT's
6518 position. The way it is we can first look at an iterator's current
6519 display element, decide whether it fits on a line, and if it does,
6520 increment the iterator position. The other way around we probably
6521 would either need a flag indicating whether the iterator has to be
6522 incremented the next time, or we would have to implement a
6523 decrement position function which would not be easy to write. */
6524
6525 void
6526 set_iterator_to_next (struct it *it, int reseat_p)
6527 {
6528 /* Reset flags indicating start and end of a sequence of characters
6529 with box. Reset them at the start of this function because
6530 moving the iterator to a new position might set them. */
6531 it->start_of_box_run_p = it->end_of_box_run_p = 0;
6532
6533 switch (it->method)
6534 {
6535 case GET_FROM_BUFFER:
6536 /* The current display element of IT is a character from
6537 current_buffer. Advance in the buffer, and maybe skip over
6538 invisible lines that are so because of selective display. */
6539 if (ITERATOR_AT_END_OF_LINE_P (it) && reseat_p)
6540 reseat_at_next_visible_line_start (it, 0);
6541 else if (it->cmp_it.id >= 0)
6542 {
6543 /* We are currently getting glyphs from a composition. */
6544 int i;
6545
6546 if (! it->bidi_p)
6547 {
6548 IT_CHARPOS (*it) += it->cmp_it.nchars;
6549 IT_BYTEPOS (*it) += it->cmp_it.nbytes;
6550 if (it->cmp_it.to < it->cmp_it.nglyphs)
6551 {
6552 it->cmp_it.from = it->cmp_it.to;
6553 }
6554 else
6555 {
6556 it->cmp_it.id = -1;
6557 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
6558 IT_BYTEPOS (*it),
6559 it->end_charpos, Qnil);
6560 }
6561 }
6562 else if (! it->cmp_it.reversed_p)
6563 {
6564 /* Composition created while scanning forward. */
6565 /* Update IT's char/byte positions to point to the first
6566 character of the next grapheme cluster, or to the
6567 character visually after the current composition. */
6568 for (i = 0; i < it->cmp_it.nchars; i++)
6569 bidi_move_to_visually_next (&it->bidi_it);
6570 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
6571 IT_CHARPOS (*it) = it->bidi_it.charpos;
6572
6573 if (it->cmp_it.to < it->cmp_it.nglyphs)
6574 {
6575 /* Proceed to the next grapheme cluster. */
6576 it->cmp_it.from = it->cmp_it.to;
6577 }
6578 else
6579 {
6580 /* No more grapheme clusters in this composition.
6581 Find the next stop position. */
6582 EMACS_INT stop = it->end_charpos;
6583 if (it->bidi_it.scan_dir < 0)
6584 /* Now we are scanning backward and don't know
6585 where to stop. */
6586 stop = -1;
6587 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
6588 IT_BYTEPOS (*it), stop, Qnil);
6589 }
6590 }
6591 else
6592 {
6593 /* Composition created while scanning backward. */
6594 /* Update IT's char/byte positions to point to the last
6595 character of the previous grapheme cluster, or the
6596 character visually after the current composition. */
6597 for (i = 0; i < it->cmp_it.nchars; i++)
6598 bidi_move_to_visually_next (&it->bidi_it);
6599 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
6600 IT_CHARPOS (*it) = it->bidi_it.charpos;
6601 if (it->cmp_it.from > 0)
6602 {
6603 /* Proceed to the previous grapheme cluster. */
6604 it->cmp_it.to = it->cmp_it.from;
6605 }
6606 else
6607 {
6608 /* No more grapheme clusters in this composition.
6609 Find the next stop position. */
6610 EMACS_INT stop = it->end_charpos;
6611 if (it->bidi_it.scan_dir < 0)
6612 /* Now we are scanning backward and don't know
6613 where to stop. */
6614 stop = -1;
6615 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
6616 IT_BYTEPOS (*it), stop, Qnil);
6617 }
6618 }
6619 }
6620 else
6621 {
6622 xassert (it->len != 0);
6623
6624 if (!it->bidi_p)
6625 {
6626 IT_BYTEPOS (*it) += it->len;
6627 IT_CHARPOS (*it) += 1;
6628 }
6629 else
6630 {
6631 int prev_scan_dir = it->bidi_it.scan_dir;
6632 /* If this is a new paragraph, determine its base
6633 direction (a.k.a. its base embedding level). */
6634 if (it->bidi_it.new_paragraph)
6635 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 0);
6636 bidi_move_to_visually_next (&it->bidi_it);
6637 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
6638 IT_CHARPOS (*it) = it->bidi_it.charpos;
6639 if (prev_scan_dir != it->bidi_it.scan_dir)
6640 {
6641 /* As the scan direction was changed, we must
6642 re-compute the stop position for composition. */
6643 EMACS_INT stop = it->end_charpos;
6644 if (it->bidi_it.scan_dir < 0)
6645 stop = -1;
6646 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
6647 IT_BYTEPOS (*it), stop, Qnil);
6648 }
6649 }
6650 xassert (IT_BYTEPOS (*it) == CHAR_TO_BYTE (IT_CHARPOS (*it)));
6651 }
6652 break;
6653
6654 case GET_FROM_C_STRING:
6655 /* Current display element of IT is from a C string. */
6656 if (!it->bidi_p
6657 /* If the string position is beyond string's end, it means
6658 next_element_from_c_string is padding the string with
6659 blanks, in which case we bypass the bidi iterator,
6660 because it cannot deal with such virtual characters. */
6661 || IT_CHARPOS (*it) >= it->bidi_it.string.schars)
6662 {
6663 IT_BYTEPOS (*it) += it->len;
6664 IT_CHARPOS (*it) += 1;
6665 }
6666 else
6667 {
6668 bidi_move_to_visually_next (&it->bidi_it);
6669 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
6670 IT_CHARPOS (*it) = it->bidi_it.charpos;
6671 }
6672 break;
6673
6674 case GET_FROM_DISPLAY_VECTOR:
6675 /* Current display element of IT is from a display table entry.
6676 Advance in the display table definition. Reset it to null if
6677 end reached, and continue with characters from buffers/
6678 strings. */
6679 ++it->current.dpvec_index;
6680
6681 /* Restore face of the iterator to what they were before the
6682 display vector entry (these entries may contain faces). */
6683 it->face_id = it->saved_face_id;
6684
6685 if (it->dpvec + it->current.dpvec_index == it->dpend)
6686 {
6687 int recheck_faces = it->ellipsis_p;
6688
6689 if (it->s)
6690 it->method = GET_FROM_C_STRING;
6691 else if (STRINGP (it->string))
6692 it->method = GET_FROM_STRING;
6693 else
6694 {
6695 it->method = GET_FROM_BUFFER;
6696 it->object = it->w->buffer;
6697 }
6698
6699 it->dpvec = NULL;
6700 it->current.dpvec_index = -1;
6701
6702 /* Skip over characters which were displayed via IT->dpvec. */
6703 if (it->dpvec_char_len < 0)
6704 reseat_at_next_visible_line_start (it, 1);
6705 else if (it->dpvec_char_len > 0)
6706 {
6707 if (it->method == GET_FROM_STRING
6708 && it->n_overlay_strings > 0)
6709 it->ignore_overlay_strings_at_pos_p = 1;
6710 it->len = it->dpvec_char_len;
6711 set_iterator_to_next (it, reseat_p);
6712 }
6713
6714 /* Maybe recheck faces after display vector */
6715 if (recheck_faces)
6716 it->stop_charpos = IT_CHARPOS (*it);
6717 }
6718 break;
6719
6720 case GET_FROM_STRING:
6721 /* Current display element is a character from a Lisp string. */
6722 xassert (it->s == NULL && STRINGP (it->string));
6723 if (it->cmp_it.id >= 0)
6724 {
6725 int i;
6726
6727 if (! it->bidi_p)
6728 {
6729 IT_STRING_CHARPOS (*it) += it->cmp_it.nchars;
6730 IT_STRING_BYTEPOS (*it) += it->cmp_it.nbytes;
6731 if (it->cmp_it.to < it->cmp_it.nglyphs)
6732 it->cmp_it.from = it->cmp_it.to;
6733 else
6734 {
6735 it->cmp_it.id = -1;
6736 composition_compute_stop_pos (&it->cmp_it,
6737 IT_STRING_CHARPOS (*it),
6738 IT_STRING_BYTEPOS (*it),
6739 it->end_charpos, it->string);
6740 }
6741 }
6742 else if (! it->cmp_it.reversed_p)
6743 {
6744 for (i = 0; i < it->cmp_it.nchars; i++)
6745 bidi_move_to_visually_next (&it->bidi_it);
6746 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
6747 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
6748
6749 if (it->cmp_it.to < it->cmp_it.nglyphs)
6750 it->cmp_it.from = it->cmp_it.to;
6751 else
6752 {
6753 EMACS_INT stop = it->end_charpos;
6754 if (it->bidi_it.scan_dir < 0)
6755 stop = -1;
6756 composition_compute_stop_pos (&it->cmp_it,
6757 IT_STRING_CHARPOS (*it),
6758 IT_STRING_BYTEPOS (*it), stop,
6759 it->string);
6760 }
6761 }
6762 else
6763 {
6764 for (i = 0; i < it->cmp_it.nchars; i++)
6765 bidi_move_to_visually_next (&it->bidi_it);
6766 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
6767 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
6768 if (it->cmp_it.from > 0)
6769 it->cmp_it.to = it->cmp_it.from;
6770 else
6771 {
6772 EMACS_INT stop = it->end_charpos;
6773 if (it->bidi_it.scan_dir < 0)
6774 stop = -1;
6775 composition_compute_stop_pos (&it->cmp_it,
6776 IT_STRING_CHARPOS (*it),
6777 IT_STRING_BYTEPOS (*it), stop,
6778 it->string);
6779 }
6780 }
6781 }
6782 else
6783 {
6784 if (!it->bidi_p
6785 /* If the string position is beyond string's end, it
6786 means next_element_from_string is padding the string
6787 with blanks, in which case we bypass the bidi
6788 iterator, because it cannot deal with such virtual
6789 characters. */
6790 || IT_STRING_CHARPOS (*it) >= it->bidi_it.string.schars)
6791 {
6792 IT_STRING_BYTEPOS (*it) += it->len;
6793 IT_STRING_CHARPOS (*it) += 1;
6794 }
6795 else
6796 {
6797 int prev_scan_dir = it->bidi_it.scan_dir;
6798
6799 bidi_move_to_visually_next (&it->bidi_it);
6800 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
6801 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
6802 if (prev_scan_dir != it->bidi_it.scan_dir)
6803 {
6804 EMACS_INT stop = it->end_charpos;
6805
6806 if (it->bidi_it.scan_dir < 0)
6807 stop = -1;
6808 composition_compute_stop_pos (&it->cmp_it,
6809 IT_STRING_CHARPOS (*it),
6810 IT_STRING_BYTEPOS (*it), stop,
6811 it->string);
6812 }
6813 }
6814 }
6815
6816 consider_string_end:
6817
6818 if (it->current.overlay_string_index >= 0)
6819 {
6820 /* IT->string is an overlay string. Advance to the
6821 next, if there is one. */
6822 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
6823 {
6824 it->ellipsis_p = 0;
6825 next_overlay_string (it);
6826 if (it->ellipsis_p)
6827 setup_for_ellipsis (it, 0);
6828 }
6829 }
6830 else
6831 {
6832 /* IT->string is not an overlay string. If we reached
6833 its end, and there is something on IT->stack, proceed
6834 with what is on the stack. This can be either another
6835 string, this time an overlay string, or a buffer. */
6836 if (IT_STRING_CHARPOS (*it) == SCHARS (it->string)
6837 && it->sp > 0)
6838 {
6839 pop_it (it);
6840 if (it->method == GET_FROM_STRING)
6841 goto consider_string_end;
6842 }
6843 }
6844 break;
6845
6846 case GET_FROM_IMAGE:
6847 case GET_FROM_STRETCH:
6848 /* The position etc with which we have to proceed are on
6849 the stack. The position may be at the end of a string,
6850 if the `display' property takes up the whole string. */
6851 xassert (it->sp > 0);
6852 pop_it (it);
6853 if (it->method == GET_FROM_STRING)
6854 goto consider_string_end;
6855 break;
6856
6857 default:
6858 /* There are no other methods defined, so this should be a bug. */
6859 abort ();
6860 }
6861
6862 xassert (it->method != GET_FROM_STRING
6863 || (STRINGP (it->string)
6864 && IT_STRING_CHARPOS (*it) >= 0));
6865 }
6866
6867 /* Load IT's display element fields with information about the next
6868 display element which comes from a display table entry or from the
6869 result of translating a control character to one of the forms `^C'
6870 or `\003'.
6871
6872 IT->dpvec holds the glyphs to return as characters.
6873 IT->saved_face_id holds the face id before the display vector--it
6874 is restored into IT->face_id in set_iterator_to_next. */
6875
6876 static int
6877 next_element_from_display_vector (struct it *it)
6878 {
6879 Lisp_Object gc;
6880
6881 /* Precondition. */
6882 xassert (it->dpvec && it->current.dpvec_index >= 0);
6883
6884 it->face_id = it->saved_face_id;
6885
6886 /* KFS: This code used to check ip->dpvec[0] instead of the current element.
6887 That seemed totally bogus - so I changed it... */
6888 gc = it->dpvec[it->current.dpvec_index];
6889
6890 if (GLYPH_CODE_P (gc) && GLYPH_CODE_CHAR_VALID_P (gc))
6891 {
6892 it->c = GLYPH_CODE_CHAR (gc);
6893 it->len = CHAR_BYTES (it->c);
6894
6895 /* The entry may contain a face id to use. Such a face id is
6896 the id of a Lisp face, not a realized face. A face id of
6897 zero means no face is specified. */
6898 if (it->dpvec_face_id >= 0)
6899 it->face_id = it->dpvec_face_id;
6900 else
6901 {
6902 EMACS_INT lface_id = GLYPH_CODE_FACE (gc);
6903 if (lface_id > 0)
6904 it->face_id = merge_faces (it->f, Qt, lface_id,
6905 it->saved_face_id);
6906 }
6907 }
6908 else
6909 /* Display table entry is invalid. Return a space. */
6910 it->c = ' ', it->len = 1;
6911
6912 /* Don't change position and object of the iterator here. They are
6913 still the values of the character that had this display table
6914 entry or was translated, and that's what we want. */
6915 it->what = IT_CHARACTER;
6916 return 1;
6917 }
6918
6919 /* Get the first element of string/buffer in the visual order, after
6920 being reseated to a new position in a string or a buffer. */
6921 static void
6922 get_visually_first_element (struct it *it)
6923 {
6924 int string_p = STRINGP (it->string) || it->s;
6925 EMACS_INT eob = (string_p ? it->bidi_it.string.schars : ZV);
6926 EMACS_INT bob = (string_p ? 0 : BEGV);
6927
6928 if (STRINGP (it->string))
6929 {
6930 it->bidi_it.charpos = IT_STRING_CHARPOS (*it);
6931 it->bidi_it.bytepos = IT_STRING_BYTEPOS (*it);
6932 }
6933 else
6934 {
6935 it->bidi_it.charpos = IT_CHARPOS (*it);
6936 it->bidi_it.bytepos = IT_BYTEPOS (*it);
6937 }
6938
6939 if (it->bidi_it.charpos == eob)
6940 {
6941 /* Nothing to do, but reset the FIRST_ELT flag, like
6942 bidi_paragraph_init does, because we are not going to
6943 call it. */
6944 it->bidi_it.first_elt = 0;
6945 }
6946 else if (it->bidi_it.charpos == bob
6947 || (!string_p
6948 /* FIXME: Should support all Unicode line separators. */
6949 && (FETCH_CHAR (it->bidi_it.bytepos - 1) == '\n'
6950 || FETCH_CHAR (it->bidi_it.bytepos) == '\n')))
6951 {
6952 /* If we are at the beginning of a line/string, we can produce
6953 the next element right away. */
6954 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1);
6955 bidi_move_to_visually_next (&it->bidi_it);
6956 }
6957 else
6958 {
6959 EMACS_INT orig_bytepos = it->bidi_it.bytepos;
6960
6961 /* We need to prime the bidi iterator starting at the line's or
6962 string's beginning, before we will be able to produce the
6963 next element. */
6964 if (string_p)
6965 it->bidi_it.charpos = it->bidi_it.bytepos = 0;
6966 else
6967 {
6968 it->bidi_it.charpos = find_next_newline_no_quit (IT_CHARPOS (*it),
6969 -1);
6970 it->bidi_it.bytepos = CHAR_TO_BYTE (it->bidi_it.charpos);
6971 }
6972 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1);
6973 do
6974 {
6975 /* Now return to buffer/string position where we were asked
6976 to get the next display element, and produce that. */
6977 bidi_move_to_visually_next (&it->bidi_it);
6978 }
6979 while (it->bidi_it.bytepos != orig_bytepos
6980 && it->bidi_it.charpos < eob);
6981 }
6982
6983 /* Adjust IT's position information to where we ended up. */
6984 if (STRINGP (it->string))
6985 {
6986 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
6987 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
6988 }
6989 else
6990 {
6991 IT_CHARPOS (*it) = it->bidi_it.charpos;
6992 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
6993 }
6994
6995 if (STRINGP (it->string) || !it->s)
6996 {
6997 EMACS_INT stop, charpos, bytepos;
6998
6999 if (STRINGP (it->string))
7000 {
7001 xassert (!it->s);
7002 stop = SCHARS (it->string);
7003 if (stop > it->end_charpos)
7004 stop = it->end_charpos;
7005 charpos = IT_STRING_CHARPOS (*it);
7006 bytepos = IT_STRING_BYTEPOS (*it);
7007 }
7008 else
7009 {
7010 stop = it->end_charpos;
7011 charpos = IT_CHARPOS (*it);
7012 bytepos = IT_BYTEPOS (*it);
7013 }
7014 if (it->bidi_it.scan_dir < 0)
7015 stop = -1;
7016 composition_compute_stop_pos (&it->cmp_it, charpos, bytepos, stop,
7017 it->string);
7018 }
7019 }
7020
7021 /* Load IT with the next display element from Lisp string IT->string.
7022 IT->current.string_pos is the current position within the string.
7023 If IT->current.overlay_string_index >= 0, the Lisp string is an
7024 overlay string. */
7025
7026 static int
7027 next_element_from_string (struct it *it)
7028 {
7029 struct text_pos position;
7030
7031 xassert (STRINGP (it->string));
7032 xassert (!it->bidi_p || EQ (it->string, it->bidi_it.string.lstring));
7033 xassert (IT_STRING_CHARPOS (*it) >= 0);
7034 position = it->current.string_pos;
7035
7036 /* With bidi reordering, the character to display might not be the
7037 character at IT_STRING_CHARPOS. BIDI_IT.FIRST_ELT non-zero means
7038 that we were reseat()ed to a new string, whose paragraph
7039 direction is not known. */
7040 if (it->bidi_p && it->bidi_it.first_elt)
7041 {
7042 get_visually_first_element (it);
7043 SET_TEXT_POS (position, IT_STRING_CHARPOS (*it), IT_STRING_BYTEPOS (*it));
7044 }
7045
7046 /* Time to check for invisible text? */
7047 if (IT_STRING_CHARPOS (*it) < it->end_charpos)
7048 {
7049 if (IT_STRING_CHARPOS (*it) >= it->stop_charpos)
7050 {
7051 if (!(!it->bidi_p
7052 || BIDI_AT_BASE_LEVEL (it->bidi_it)
7053 || IT_STRING_CHARPOS (*it) == it->stop_charpos))
7054 {
7055 /* With bidi non-linear iteration, we could find
7056 ourselves far beyond the last computed stop_charpos,
7057 with several other stop positions in between that we
7058 missed. Scan them all now, in buffer's logical
7059 order, until we find and handle the last stop_charpos
7060 that precedes our current position. */
7061 handle_stop_backwards (it, it->stop_charpos);
7062 return GET_NEXT_DISPLAY_ELEMENT (it);
7063 }
7064 else
7065 {
7066 if (it->bidi_p)
7067 {
7068 /* Take note of the stop position we just moved
7069 across, for when we will move back across it. */
7070 it->prev_stop = it->stop_charpos;
7071 /* If we are at base paragraph embedding level, take
7072 note of the last stop position seen at this
7073 level. */
7074 if (BIDI_AT_BASE_LEVEL (it->bidi_it))
7075 it->base_level_stop = it->stop_charpos;
7076 }
7077 handle_stop (it);
7078
7079 /* Since a handler may have changed IT->method, we must
7080 recurse here. */
7081 return GET_NEXT_DISPLAY_ELEMENT (it);
7082 }
7083 }
7084 else if (it->bidi_p
7085 /* If we are before prev_stop, we may have overstepped
7086 on our way backwards a stop_pos, and if so, we need
7087 to handle that stop_pos. */
7088 && IT_STRING_CHARPOS (*it) < it->prev_stop
7089 /* We can sometimes back up for reasons that have nothing
7090 to do with bidi reordering. E.g., compositions. The
7091 code below is only needed when we are above the base
7092 embedding level, so test for that explicitly. */
7093 && !BIDI_AT_BASE_LEVEL (it->bidi_it))
7094 {
7095 /* If we lost track of base_level_stop, we have no better
7096 place for handle_stop_backwards to start from than string
7097 beginning. This happens, e.g., when we were reseated to
7098 the previous screenful of text by vertical-motion. */
7099 if (it->base_level_stop <= 0
7100 || IT_STRING_CHARPOS (*it) < it->base_level_stop)
7101 it->base_level_stop = 0;
7102 handle_stop_backwards (it, it->base_level_stop);
7103 return GET_NEXT_DISPLAY_ELEMENT (it);
7104 }
7105 }
7106
7107 if (it->current.overlay_string_index >= 0)
7108 {
7109 /* Get the next character from an overlay string. In overlay
7110 strings, There is no field width or padding with spaces to
7111 do. */
7112 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
7113 {
7114 it->what = IT_EOB;
7115 return 0;
7116 }
7117 else if (CHAR_COMPOSED_P (it, IT_STRING_CHARPOS (*it),
7118 IT_STRING_BYTEPOS (*it),
7119 it->bidi_it.scan_dir < 0
7120 ? -1
7121 : SCHARS (it->string))
7122 && next_element_from_composition (it))
7123 {
7124 return 1;
7125 }
7126 else if (STRING_MULTIBYTE (it->string))
7127 {
7128 const unsigned char *s = (SDATA (it->string)
7129 + IT_STRING_BYTEPOS (*it));
7130 it->c = string_char_and_length (s, &it->len);
7131 }
7132 else
7133 {
7134 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
7135 it->len = 1;
7136 }
7137 }
7138 else
7139 {
7140 /* Get the next character from a Lisp string that is not an
7141 overlay string. Such strings come from the mode line, for
7142 example. We may have to pad with spaces, or truncate the
7143 string. See also next_element_from_c_string. */
7144 if (IT_STRING_CHARPOS (*it) >= it->end_charpos)
7145 {
7146 it->what = IT_EOB;
7147 return 0;
7148 }
7149 else if (IT_STRING_CHARPOS (*it) >= it->string_nchars)
7150 {
7151 /* Pad with spaces. */
7152 it->c = ' ', it->len = 1;
7153 CHARPOS (position) = BYTEPOS (position) = -1;
7154 }
7155 else if (CHAR_COMPOSED_P (it, IT_STRING_CHARPOS (*it),
7156 IT_STRING_BYTEPOS (*it),
7157 it->bidi_it.scan_dir < 0
7158 ? -1
7159 : it->string_nchars)
7160 && next_element_from_composition (it))
7161 {
7162 return 1;
7163 }
7164 else if (STRING_MULTIBYTE (it->string))
7165 {
7166 const unsigned char *s = (SDATA (it->string)
7167 + IT_STRING_BYTEPOS (*it));
7168 it->c = string_char_and_length (s, &it->len);
7169 }
7170 else
7171 {
7172 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
7173 it->len = 1;
7174 }
7175 }
7176
7177 /* Record what we have and where it came from. */
7178 it->what = IT_CHARACTER;
7179 it->object = it->string;
7180 it->position = position;
7181 return 1;
7182 }
7183
7184
7185 /* Load IT with next display element from C string IT->s.
7186 IT->string_nchars is the maximum number of characters to return
7187 from the string. IT->end_charpos may be greater than
7188 IT->string_nchars when this function is called, in which case we
7189 may have to return padding spaces. Value is zero if end of string
7190 reached, including padding spaces. */
7191
7192 static int
7193 next_element_from_c_string (struct it *it)
7194 {
7195 int success_p = 1;
7196
7197 xassert (it->s);
7198 xassert (!it->bidi_p || it->s == it->bidi_it.string.s);
7199 it->what = IT_CHARACTER;
7200 BYTEPOS (it->position) = CHARPOS (it->position) = 0;
7201 it->object = Qnil;
7202
7203 /* With bidi reordering, the character to display might not be the
7204 character at IT_CHARPOS. BIDI_IT.FIRST_ELT non-zero means that
7205 we were reseated to a new string, whose paragraph direction is
7206 not known. */
7207 if (it->bidi_p && it->bidi_it.first_elt)
7208 get_visually_first_element (it);
7209
7210 /* IT's position can be greater than IT->string_nchars in case a
7211 field width or precision has been specified when the iterator was
7212 initialized. */
7213 if (IT_CHARPOS (*it) >= it->end_charpos)
7214 {
7215 /* End of the game. */
7216 it->what = IT_EOB;
7217 success_p = 0;
7218 }
7219 else if (IT_CHARPOS (*it) >= it->string_nchars)
7220 {
7221 /* Pad with spaces. */
7222 it->c = ' ', it->len = 1;
7223 BYTEPOS (it->position) = CHARPOS (it->position) = -1;
7224 }
7225 else if (it->multibyte_p)
7226 it->c = string_char_and_length (it->s + IT_BYTEPOS (*it), &it->len);
7227 else
7228 it->c = it->s[IT_BYTEPOS (*it)], it->len = 1;
7229
7230 return success_p;
7231 }
7232
7233
7234 /* Set up IT to return characters from an ellipsis, if appropriate.
7235 The definition of the ellipsis glyphs may come from a display table
7236 entry. This function fills IT with the first glyph from the
7237 ellipsis if an ellipsis is to be displayed. */
7238
7239 static int
7240 next_element_from_ellipsis (struct it *it)
7241 {
7242 if (it->selective_display_ellipsis_p)
7243 setup_for_ellipsis (it, it->len);
7244 else
7245 {
7246 /* The face at the current position may be different from the
7247 face we find after the invisible text. Remember what it
7248 was in IT->saved_face_id, and signal that it's there by
7249 setting face_before_selective_p. */
7250 it->saved_face_id = it->face_id;
7251 it->method = GET_FROM_BUFFER;
7252 it->object = it->w->buffer;
7253 reseat_at_next_visible_line_start (it, 1);
7254 it->face_before_selective_p = 1;
7255 }
7256
7257 return GET_NEXT_DISPLAY_ELEMENT (it);
7258 }
7259
7260
7261 /* Deliver an image display element. The iterator IT is already
7262 filled with image information (done in handle_display_prop). Value
7263 is always 1. */
7264
7265
7266 static int
7267 next_element_from_image (struct it *it)
7268 {
7269 it->what = IT_IMAGE;
7270 it->ignore_overlay_strings_at_pos_p = 0;
7271 return 1;
7272 }
7273
7274
7275 /* Fill iterator IT with next display element from a stretch glyph
7276 property. IT->object is the value of the text property. Value is
7277 always 1. */
7278
7279 static int
7280 next_element_from_stretch (struct it *it)
7281 {
7282 it->what = IT_STRETCH;
7283 return 1;
7284 }
7285
7286 /* Scan backwards from IT's current position until we find a stop
7287 position, or until BEGV. This is called when we find ourself
7288 before both the last known prev_stop and base_level_stop while
7289 reordering bidirectional text. */
7290
7291 static void
7292 compute_stop_pos_backwards (struct it *it)
7293 {
7294 const int SCAN_BACK_LIMIT = 1000;
7295 struct text_pos pos;
7296 struct display_pos save_current = it->current;
7297 struct text_pos save_position = it->position;
7298 EMACS_INT charpos = IT_CHARPOS (*it);
7299 EMACS_INT where_we_are = charpos;
7300 EMACS_INT save_stop_pos = it->stop_charpos;
7301 EMACS_INT save_end_pos = it->end_charpos;
7302
7303 xassert (NILP (it->string) && !it->s);
7304 xassert (it->bidi_p);
7305 it->bidi_p = 0;
7306 do
7307 {
7308 it->end_charpos = min (charpos + 1, ZV);
7309 charpos = max (charpos - SCAN_BACK_LIMIT, BEGV);
7310 SET_TEXT_POS (pos, charpos, BYTE_TO_CHAR (charpos));
7311 reseat_1 (it, pos, 0);
7312 compute_stop_pos (it);
7313 /* We must advance forward, right? */
7314 if (it->stop_charpos <= charpos)
7315 abort ();
7316 }
7317 while (charpos > BEGV && it->stop_charpos >= it->end_charpos);
7318
7319 if (it->stop_charpos <= where_we_are)
7320 it->prev_stop = it->stop_charpos;
7321 else
7322 it->prev_stop = BEGV;
7323 it->bidi_p = 1;
7324 it->current = save_current;
7325 it->position = save_position;
7326 it->stop_charpos = save_stop_pos;
7327 it->end_charpos = save_end_pos;
7328 }
7329
7330 /* Scan forward from CHARPOS in the current buffer/string, until we
7331 find a stop position > current IT's position. Then handle the stop
7332 position before that. This is called when we bump into a stop
7333 position while reordering bidirectional text. CHARPOS should be
7334 the last previously processed stop_pos (or BEGV/0, if none were
7335 processed yet) whose position is less that IT's current
7336 position. */
7337
7338 static void
7339 handle_stop_backwards (struct it *it, EMACS_INT charpos)
7340 {
7341 int bufp = !STRINGP (it->string);
7342 EMACS_INT where_we_are = (bufp ? IT_CHARPOS (*it) : IT_STRING_CHARPOS (*it));
7343 struct display_pos save_current = it->current;
7344 struct text_pos save_position = it->position;
7345 struct text_pos pos1;
7346 EMACS_INT next_stop;
7347
7348 /* Scan in strict logical order. */
7349 xassert (it->bidi_p);
7350 it->bidi_p = 0;
7351 do
7352 {
7353 it->prev_stop = charpos;
7354 if (bufp)
7355 {
7356 SET_TEXT_POS (pos1, charpos, CHAR_TO_BYTE (charpos));
7357 reseat_1 (it, pos1, 0);
7358 }
7359 else
7360 it->current.string_pos = string_pos (charpos, it->string);
7361 compute_stop_pos (it);
7362 /* We must advance forward, right? */
7363 if (it->stop_charpos <= it->prev_stop)
7364 abort ();
7365 charpos = it->stop_charpos;
7366 }
7367 while (charpos <= where_we_are);
7368
7369 it->bidi_p = 1;
7370 it->current = save_current;
7371 it->position = save_position;
7372 next_stop = it->stop_charpos;
7373 it->stop_charpos = it->prev_stop;
7374 handle_stop (it);
7375 it->stop_charpos = next_stop;
7376 }
7377
7378 /* Load IT with the next display element from current_buffer. Value
7379 is zero if end of buffer reached. IT->stop_charpos is the next
7380 position at which to stop and check for text properties or buffer
7381 end. */
7382
7383 static int
7384 next_element_from_buffer (struct it *it)
7385 {
7386 int success_p = 1;
7387
7388 xassert (IT_CHARPOS (*it) >= BEGV);
7389 xassert (NILP (it->string) && !it->s);
7390 xassert (!it->bidi_p
7391 || (EQ (it->bidi_it.string.lstring, Qnil)
7392 && it->bidi_it.string.s == NULL));
7393
7394 /* With bidi reordering, the character to display might not be the
7395 character at IT_CHARPOS. BIDI_IT.FIRST_ELT non-zero means that
7396 we were reseat()ed to a new buffer position, which is potentially
7397 a different paragraph. */
7398 if (it->bidi_p && it->bidi_it.first_elt)
7399 {
7400 get_visually_first_element (it);
7401 SET_TEXT_POS (it->position, IT_CHARPOS (*it), IT_BYTEPOS (*it));
7402 }
7403
7404 if (IT_CHARPOS (*it) >= it->stop_charpos)
7405 {
7406 if (IT_CHARPOS (*it) >= it->end_charpos)
7407 {
7408 int overlay_strings_follow_p;
7409
7410 /* End of the game, except when overlay strings follow that
7411 haven't been returned yet. */
7412 if (it->overlay_strings_at_end_processed_p)
7413 overlay_strings_follow_p = 0;
7414 else
7415 {
7416 it->overlay_strings_at_end_processed_p = 1;
7417 overlay_strings_follow_p = get_overlay_strings (it, 0);
7418 }
7419
7420 if (overlay_strings_follow_p)
7421 success_p = GET_NEXT_DISPLAY_ELEMENT (it);
7422 else
7423 {
7424 it->what = IT_EOB;
7425 it->position = it->current.pos;
7426 success_p = 0;
7427 }
7428 }
7429 else if (!(!it->bidi_p
7430 || BIDI_AT_BASE_LEVEL (it->bidi_it)
7431 || IT_CHARPOS (*it) == it->stop_charpos))
7432 {
7433 /* With bidi non-linear iteration, we could find ourselves
7434 far beyond the last computed stop_charpos, with several
7435 other stop positions in between that we missed. Scan
7436 them all now, in buffer's logical order, until we find
7437 and handle the last stop_charpos that precedes our
7438 current position. */
7439 handle_stop_backwards (it, it->stop_charpos);
7440 return GET_NEXT_DISPLAY_ELEMENT (it);
7441 }
7442 else
7443 {
7444 if (it->bidi_p)
7445 {
7446 /* Take note of the stop position we just moved across,
7447 for when we will move back across it. */
7448 it->prev_stop = it->stop_charpos;
7449 /* If we are at base paragraph embedding level, take
7450 note of the last stop position seen at this
7451 level. */
7452 if (BIDI_AT_BASE_LEVEL (it->bidi_it))
7453 it->base_level_stop = it->stop_charpos;
7454 }
7455 handle_stop (it);
7456 return GET_NEXT_DISPLAY_ELEMENT (it);
7457 }
7458 }
7459 else if (it->bidi_p
7460 /* If we are before prev_stop, we may have overstepped on
7461 our way backwards a stop_pos, and if so, we need to
7462 handle that stop_pos. */
7463 && IT_CHARPOS (*it) < it->prev_stop
7464 /* We can sometimes back up for reasons that have nothing
7465 to do with bidi reordering. E.g., compositions. The
7466 code below is only needed when we are above the base
7467 embedding level, so test for that explicitly. */
7468 && !BIDI_AT_BASE_LEVEL (it->bidi_it))
7469 {
7470 if (it->base_level_stop <= 0
7471 || IT_CHARPOS (*it) < it->base_level_stop)
7472 {
7473 /* If we lost track of base_level_stop, we need to find
7474 prev_stop by looking backwards. This happens, e.g., when
7475 we were reseated to the previous screenful of text by
7476 vertical-motion. */
7477 it->base_level_stop = BEGV;
7478 compute_stop_pos_backwards (it);
7479 handle_stop_backwards (it, it->prev_stop);
7480 }
7481 else
7482 handle_stop_backwards (it, it->base_level_stop);
7483 return GET_NEXT_DISPLAY_ELEMENT (it);
7484 }
7485 else
7486 {
7487 /* No face changes, overlays etc. in sight, so just return a
7488 character from current_buffer. */
7489 unsigned char *p;
7490 EMACS_INT stop;
7491
7492 /* Maybe run the redisplay end trigger hook. Performance note:
7493 This doesn't seem to cost measurable time. */
7494 if (it->redisplay_end_trigger_charpos
7495 && it->glyph_row
7496 && IT_CHARPOS (*it) >= it->redisplay_end_trigger_charpos)
7497 run_redisplay_end_trigger_hook (it);
7498
7499 stop = it->bidi_it.scan_dir < 0 ? -1 : it->end_charpos;
7500 if (CHAR_COMPOSED_P (it, IT_CHARPOS (*it), IT_BYTEPOS (*it),
7501 stop)
7502 && next_element_from_composition (it))
7503 {
7504 return 1;
7505 }
7506
7507 /* Get the next character, maybe multibyte. */
7508 p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
7509 if (it->multibyte_p && !ASCII_BYTE_P (*p))
7510 it->c = STRING_CHAR_AND_LENGTH (p, it->len);
7511 else
7512 it->c = *p, it->len = 1;
7513
7514 /* Record what we have and where it came from. */
7515 it->what = IT_CHARACTER;
7516 it->object = it->w->buffer;
7517 it->position = it->current.pos;
7518
7519 /* Normally we return the character found above, except when we
7520 really want to return an ellipsis for selective display. */
7521 if (it->selective)
7522 {
7523 if (it->c == '\n')
7524 {
7525 /* A value of selective > 0 means hide lines indented more
7526 than that number of columns. */
7527 if (it->selective > 0
7528 && IT_CHARPOS (*it) + 1 < ZV
7529 && indented_beyond_p (IT_CHARPOS (*it) + 1,
7530 IT_BYTEPOS (*it) + 1,
7531 it->selective))
7532 {
7533 success_p = next_element_from_ellipsis (it);
7534 it->dpvec_char_len = -1;
7535 }
7536 }
7537 else if (it->c == '\r' && it->selective == -1)
7538 {
7539 /* A value of selective == -1 means that everything from the
7540 CR to the end of the line is invisible, with maybe an
7541 ellipsis displayed for it. */
7542 success_p = next_element_from_ellipsis (it);
7543 it->dpvec_char_len = -1;
7544 }
7545 }
7546 }
7547
7548 /* Value is zero if end of buffer reached. */
7549 xassert (!success_p || it->what != IT_CHARACTER || it->len > 0);
7550 return success_p;
7551 }
7552
7553
7554 /* Run the redisplay end trigger hook for IT. */
7555
7556 static void
7557 run_redisplay_end_trigger_hook (struct it *it)
7558 {
7559 Lisp_Object args[3];
7560
7561 /* IT->glyph_row should be non-null, i.e. we should be actually
7562 displaying something, or otherwise we should not run the hook. */
7563 xassert (it->glyph_row);
7564
7565 /* Set up hook arguments. */
7566 args[0] = Qredisplay_end_trigger_functions;
7567 args[1] = it->window;
7568 XSETINT (args[2], it->redisplay_end_trigger_charpos);
7569 it->redisplay_end_trigger_charpos = 0;
7570
7571 /* Since we are *trying* to run these functions, don't try to run
7572 them again, even if they get an error. */
7573 it->w->redisplay_end_trigger = Qnil;
7574 Frun_hook_with_args (3, args);
7575
7576 /* Notice if it changed the face of the character we are on. */
7577 handle_face_prop (it);
7578 }
7579
7580
7581 /* Deliver a composition display element. Unlike the other
7582 next_element_from_XXX, this function is not registered in the array
7583 get_next_element[]. It is called from next_element_from_buffer and
7584 next_element_from_string when necessary. */
7585
7586 static int
7587 next_element_from_composition (struct it *it)
7588 {
7589 it->what = IT_COMPOSITION;
7590 it->len = it->cmp_it.nbytes;
7591 if (STRINGP (it->string))
7592 {
7593 if (it->c < 0)
7594 {
7595 IT_STRING_CHARPOS (*it) += it->cmp_it.nchars;
7596 IT_STRING_BYTEPOS (*it) += it->cmp_it.nbytes;
7597 return 0;
7598 }
7599 it->position = it->current.string_pos;
7600 it->object = it->string;
7601 it->c = composition_update_it (&it->cmp_it, IT_STRING_CHARPOS (*it),
7602 IT_STRING_BYTEPOS (*it), it->string);
7603 }
7604 else
7605 {
7606 if (it->c < 0)
7607 {
7608 IT_CHARPOS (*it) += it->cmp_it.nchars;
7609 IT_BYTEPOS (*it) += it->cmp_it.nbytes;
7610 if (it->bidi_p)
7611 {
7612 if (it->bidi_it.new_paragraph)
7613 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 0);
7614 /* Resync the bidi iterator with IT's new position.
7615 FIXME: this doesn't support bidirectional text. */
7616 while (it->bidi_it.charpos < IT_CHARPOS (*it))
7617 bidi_move_to_visually_next (&it->bidi_it);
7618 }
7619 return 0;
7620 }
7621 it->position = it->current.pos;
7622 it->object = it->w->buffer;
7623 it->c = composition_update_it (&it->cmp_it, IT_CHARPOS (*it),
7624 IT_BYTEPOS (*it), Qnil);
7625 }
7626 return 1;
7627 }
7628
7629
7630 \f
7631 /***********************************************************************
7632 Moving an iterator without producing glyphs
7633 ***********************************************************************/
7634
7635 /* Check if iterator is at a position corresponding to a valid buffer
7636 position after some move_it_ call. */
7637
7638 #define IT_POS_VALID_AFTER_MOVE_P(it) \
7639 ((it)->method == GET_FROM_STRING \
7640 ? IT_STRING_CHARPOS (*it) == 0 \
7641 : 1)
7642
7643
7644 /* Move iterator IT to a specified buffer or X position within one
7645 line on the display without producing glyphs.
7646
7647 OP should be a bit mask including some or all of these bits:
7648 MOVE_TO_X: Stop upon reaching x-position TO_X.
7649 MOVE_TO_POS: Stop upon reaching buffer or string position TO_CHARPOS.
7650 Regardless of OP's value, stop upon reaching the end of the display line.
7651
7652 TO_X is normally a value 0 <= TO_X <= IT->last_visible_x.
7653 This means, in particular, that TO_X includes window's horizontal
7654 scroll amount.
7655
7656 The return value has several possible values that
7657 say what condition caused the scan to stop:
7658
7659 MOVE_POS_MATCH_OR_ZV
7660 - when TO_POS or ZV was reached.
7661
7662 MOVE_X_REACHED
7663 -when TO_X was reached before TO_POS or ZV were reached.
7664
7665 MOVE_LINE_CONTINUED
7666 - when we reached the end of the display area and the line must
7667 be continued.
7668
7669 MOVE_LINE_TRUNCATED
7670 - when we reached the end of the display area and the line is
7671 truncated.
7672
7673 MOVE_NEWLINE_OR_CR
7674 - when we stopped at a line end, i.e. a newline or a CR and selective
7675 display is on. */
7676
7677 static enum move_it_result
7678 move_it_in_display_line_to (struct it *it,
7679 EMACS_INT to_charpos, int to_x,
7680 enum move_operation_enum op)
7681 {
7682 enum move_it_result result = MOVE_UNDEFINED;
7683 struct glyph_row *saved_glyph_row;
7684 struct it wrap_it, atpos_it, atx_it, ppos_it;
7685 void *wrap_data = NULL, *atpos_data = NULL, *atx_data = NULL;
7686 void *ppos_data = NULL;
7687 int may_wrap = 0;
7688 enum it_method prev_method = it->method;
7689 EMACS_INT prev_pos = IT_CHARPOS (*it);
7690 int saw_smaller_pos = prev_pos < to_charpos;
7691
7692 /* Don't produce glyphs in produce_glyphs. */
7693 saved_glyph_row = it->glyph_row;
7694 it->glyph_row = NULL;
7695
7696 /* Use wrap_it to save a copy of IT wherever a word wrap could
7697 occur. Use atpos_it to save a copy of IT at the desired buffer
7698 position, if found, so that we can scan ahead and check if the
7699 word later overshoots the window edge. Use atx_it similarly, for
7700 pixel positions. */
7701 wrap_it.sp = -1;
7702 atpos_it.sp = -1;
7703 atx_it.sp = -1;
7704
7705 /* Use ppos_it under bidi reordering to save a copy of IT for the
7706 position > CHARPOS that is the closest to CHARPOS. We restore
7707 that position in IT when we have scanned the entire display line
7708 without finding a match for CHARPOS and all the character
7709 positions are greater than CHARPOS. */
7710 if (it->bidi_p)
7711 {
7712 SAVE_IT (ppos_it, *it, ppos_data);
7713 SET_TEXT_POS (ppos_it.current.pos, ZV, ZV_BYTE);
7714 if ((op & MOVE_TO_POS) && IT_CHARPOS (*it) >= to_charpos)
7715 SAVE_IT (ppos_it, *it, ppos_data);
7716 }
7717
7718 #define BUFFER_POS_REACHED_P() \
7719 ((op & MOVE_TO_POS) != 0 \
7720 && BUFFERP (it->object) \
7721 && (IT_CHARPOS (*it) == to_charpos \
7722 || (!it->bidi_p && IT_CHARPOS (*it) > to_charpos) \
7723 || (it->what == IT_COMPOSITION \
7724 && ((IT_CHARPOS (*it) > to_charpos \
7725 && to_charpos >= it->cmp_it.charpos) \
7726 || (IT_CHARPOS (*it) < to_charpos \
7727 && to_charpos <= it->cmp_it.charpos)))) \
7728 && (it->method == GET_FROM_BUFFER \
7729 || (it->method == GET_FROM_DISPLAY_VECTOR \
7730 && it->dpvec + it->current.dpvec_index + 1 >= it->dpend)))
7731
7732 /* If there's a line-/wrap-prefix, handle it. */
7733 if (it->hpos == 0 && it->method == GET_FROM_BUFFER
7734 && it->current_y < it->last_visible_y)
7735 handle_line_prefix (it);
7736
7737 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
7738 SET_TEXT_POS (this_line_min_pos, IT_CHARPOS (*it), IT_BYTEPOS (*it));
7739
7740 while (1)
7741 {
7742 int x, i, ascent = 0, descent = 0;
7743
7744 /* Utility macro to reset an iterator with x, ascent, and descent. */
7745 #define IT_RESET_X_ASCENT_DESCENT(IT) \
7746 ((IT)->current_x = x, (IT)->max_ascent = ascent, \
7747 (IT)->max_descent = descent)
7748
7749 /* Stop if we move beyond TO_CHARPOS (after an image or a
7750 display string or stretch glyph). */
7751 if ((op & MOVE_TO_POS) != 0
7752 && BUFFERP (it->object)
7753 && it->method == GET_FROM_BUFFER
7754 && ((!it->bidi_p && IT_CHARPOS (*it) > to_charpos)
7755 || (it->bidi_p
7756 && (prev_method == GET_FROM_IMAGE
7757 || prev_method == GET_FROM_STRETCH
7758 || prev_method == GET_FROM_STRING)
7759 /* Passed TO_CHARPOS from left to right. */
7760 && ((prev_pos < to_charpos
7761 && IT_CHARPOS (*it) > to_charpos)
7762 /* Passed TO_CHARPOS from right to left. */
7763 || (prev_pos > to_charpos
7764 && IT_CHARPOS (*it) < to_charpos)))))
7765 {
7766 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
7767 {
7768 result = MOVE_POS_MATCH_OR_ZV;
7769 break;
7770 }
7771 else if (it->line_wrap == WORD_WRAP && atpos_it.sp < 0)
7772 /* If wrap_it is valid, the current position might be in a
7773 word that is wrapped. So, save the iterator in
7774 atpos_it and continue to see if wrapping happens. */
7775 SAVE_IT (atpos_it, *it, atpos_data);
7776 }
7777
7778 /* Stop when ZV reached.
7779 We used to stop here when TO_CHARPOS reached as well, but that is
7780 too soon if this glyph does not fit on this line. So we handle it
7781 explicitly below. */
7782 if (!get_next_display_element (it))
7783 {
7784 result = MOVE_POS_MATCH_OR_ZV;
7785 break;
7786 }
7787
7788 if (it->line_wrap == TRUNCATE)
7789 {
7790 if (BUFFER_POS_REACHED_P ())
7791 {
7792 result = MOVE_POS_MATCH_OR_ZV;
7793 break;
7794 }
7795 }
7796 else
7797 {
7798 if (it->line_wrap == WORD_WRAP)
7799 {
7800 if (IT_DISPLAYING_WHITESPACE (it))
7801 may_wrap = 1;
7802 else if (may_wrap)
7803 {
7804 /* We have reached a glyph that follows one or more
7805 whitespace characters. If the position is
7806 already found, we are done. */
7807 if (atpos_it.sp >= 0)
7808 {
7809 RESTORE_IT (it, &atpos_it, atpos_data);
7810 result = MOVE_POS_MATCH_OR_ZV;
7811 goto done;
7812 }
7813 if (atx_it.sp >= 0)
7814 {
7815 RESTORE_IT (it, &atx_it, atx_data);
7816 result = MOVE_X_REACHED;
7817 goto done;
7818 }
7819 /* Otherwise, we can wrap here. */
7820 SAVE_IT (wrap_it, *it, wrap_data);
7821 may_wrap = 0;
7822 }
7823 }
7824 }
7825
7826 /* Remember the line height for the current line, in case
7827 the next element doesn't fit on the line. */
7828 ascent = it->max_ascent;
7829 descent = it->max_descent;
7830
7831 /* The call to produce_glyphs will get the metrics of the
7832 display element IT is loaded with. Record the x-position
7833 before this display element, in case it doesn't fit on the
7834 line. */
7835 x = it->current_x;
7836
7837 PRODUCE_GLYPHS (it);
7838
7839 if (it->area != TEXT_AREA)
7840 {
7841 prev_method = it->method;
7842 if (it->method == GET_FROM_BUFFER)
7843 prev_pos = IT_CHARPOS (*it);
7844 set_iterator_to_next (it, 1);
7845 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
7846 SET_TEXT_POS (this_line_min_pos,
7847 IT_CHARPOS (*it), IT_BYTEPOS (*it));
7848 if (it->bidi_p
7849 && (op & MOVE_TO_POS)
7850 && IT_CHARPOS (*it) > to_charpos
7851 && IT_CHARPOS (*it) < IT_CHARPOS (ppos_it))
7852 SAVE_IT (ppos_it, *it, ppos_data);
7853 continue;
7854 }
7855
7856 /* The number of glyphs we get back in IT->nglyphs will normally
7857 be 1 except when IT->c is (i) a TAB, or (ii) a multi-glyph
7858 character on a terminal frame, or (iii) a line end. For the
7859 second case, IT->nglyphs - 1 padding glyphs will be present.
7860 (On X frames, there is only one glyph produced for a
7861 composite character.)
7862
7863 The behavior implemented below means, for continuation lines,
7864 that as many spaces of a TAB as fit on the current line are
7865 displayed there. For terminal frames, as many glyphs of a
7866 multi-glyph character are displayed in the current line, too.
7867 This is what the old redisplay code did, and we keep it that
7868 way. Under X, the whole shape of a complex character must
7869 fit on the line or it will be completely displayed in the
7870 next line.
7871
7872 Note that both for tabs and padding glyphs, all glyphs have
7873 the same width. */
7874 if (it->nglyphs)
7875 {
7876 /* More than one glyph or glyph doesn't fit on line. All
7877 glyphs have the same width. */
7878 int single_glyph_width = it->pixel_width / it->nglyphs;
7879 int new_x;
7880 int x_before_this_char = x;
7881 int hpos_before_this_char = it->hpos;
7882
7883 for (i = 0; i < it->nglyphs; ++i, x = new_x)
7884 {
7885 new_x = x + single_glyph_width;
7886
7887 /* We want to leave anything reaching TO_X to the caller. */
7888 if ((op & MOVE_TO_X) && new_x > to_x)
7889 {
7890 if (BUFFER_POS_REACHED_P ())
7891 {
7892 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
7893 goto buffer_pos_reached;
7894 if (atpos_it.sp < 0)
7895 {
7896 SAVE_IT (atpos_it, *it, atpos_data);
7897 IT_RESET_X_ASCENT_DESCENT (&atpos_it);
7898 }
7899 }
7900 else
7901 {
7902 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
7903 {
7904 it->current_x = x;
7905 result = MOVE_X_REACHED;
7906 break;
7907 }
7908 if (atx_it.sp < 0)
7909 {
7910 SAVE_IT (atx_it, *it, atx_data);
7911 IT_RESET_X_ASCENT_DESCENT (&atx_it);
7912 }
7913 }
7914 }
7915
7916 if (/* Lines are continued. */
7917 it->line_wrap != TRUNCATE
7918 && (/* And glyph doesn't fit on the line. */
7919 new_x > it->last_visible_x
7920 /* Or it fits exactly and we're on a window
7921 system frame. */
7922 || (new_x == it->last_visible_x
7923 && FRAME_WINDOW_P (it->f))))
7924 {
7925 if (/* IT->hpos == 0 means the very first glyph
7926 doesn't fit on the line, e.g. a wide image. */
7927 it->hpos == 0
7928 || (new_x == it->last_visible_x
7929 && FRAME_WINDOW_P (it->f)))
7930 {
7931 ++it->hpos;
7932 it->current_x = new_x;
7933
7934 /* The character's last glyph just barely fits
7935 in this row. */
7936 if (i == it->nglyphs - 1)
7937 {
7938 /* If this is the destination position,
7939 return a position *before* it in this row,
7940 now that we know it fits in this row. */
7941 if (BUFFER_POS_REACHED_P ())
7942 {
7943 if (it->line_wrap != WORD_WRAP
7944 || wrap_it.sp < 0)
7945 {
7946 it->hpos = hpos_before_this_char;
7947 it->current_x = x_before_this_char;
7948 result = MOVE_POS_MATCH_OR_ZV;
7949 break;
7950 }
7951 if (it->line_wrap == WORD_WRAP
7952 && atpos_it.sp < 0)
7953 {
7954 SAVE_IT (atpos_it, *it, atpos_data);
7955 atpos_it.current_x = x_before_this_char;
7956 atpos_it.hpos = hpos_before_this_char;
7957 }
7958 }
7959
7960 prev_method = it->method;
7961 if (it->method == GET_FROM_BUFFER)
7962 prev_pos = IT_CHARPOS (*it);
7963 set_iterator_to_next (it, 1);
7964 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
7965 SET_TEXT_POS (this_line_min_pos,
7966 IT_CHARPOS (*it), IT_BYTEPOS (*it));
7967 /* On graphical terminals, newlines may
7968 "overflow" into the fringe if
7969 overflow-newline-into-fringe is non-nil.
7970 On text-only terminals, newlines may
7971 overflow into the last glyph on the
7972 display line.*/
7973 if (!FRAME_WINDOW_P (it->f)
7974 || IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
7975 {
7976 if (!get_next_display_element (it))
7977 {
7978 result = MOVE_POS_MATCH_OR_ZV;
7979 break;
7980 }
7981 if (BUFFER_POS_REACHED_P ())
7982 {
7983 if (ITERATOR_AT_END_OF_LINE_P (it))
7984 result = MOVE_POS_MATCH_OR_ZV;
7985 else
7986 result = MOVE_LINE_CONTINUED;
7987 break;
7988 }
7989 if (ITERATOR_AT_END_OF_LINE_P (it))
7990 {
7991 result = MOVE_NEWLINE_OR_CR;
7992 break;
7993 }
7994 }
7995 }
7996 }
7997 else
7998 IT_RESET_X_ASCENT_DESCENT (it);
7999
8000 if (wrap_it.sp >= 0)
8001 {
8002 RESTORE_IT (it, &wrap_it, wrap_data);
8003 atpos_it.sp = -1;
8004 atx_it.sp = -1;
8005 }
8006
8007 TRACE_MOVE ((stderr, "move_it_in: continued at %d\n",
8008 IT_CHARPOS (*it)));
8009 result = MOVE_LINE_CONTINUED;
8010 break;
8011 }
8012
8013 if (BUFFER_POS_REACHED_P ())
8014 {
8015 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
8016 goto buffer_pos_reached;
8017 if (it->line_wrap == WORD_WRAP && atpos_it.sp < 0)
8018 {
8019 SAVE_IT (atpos_it, *it, atpos_data);
8020 IT_RESET_X_ASCENT_DESCENT (&atpos_it);
8021 }
8022 }
8023
8024 if (new_x > it->first_visible_x)
8025 {
8026 /* Glyph is visible. Increment number of glyphs that
8027 would be displayed. */
8028 ++it->hpos;
8029 }
8030 }
8031
8032 if (result != MOVE_UNDEFINED)
8033 break;
8034 }
8035 else if (BUFFER_POS_REACHED_P ())
8036 {
8037 buffer_pos_reached:
8038 IT_RESET_X_ASCENT_DESCENT (it);
8039 result = MOVE_POS_MATCH_OR_ZV;
8040 break;
8041 }
8042 else if ((op & MOVE_TO_X) && it->current_x >= to_x)
8043 {
8044 /* Stop when TO_X specified and reached. This check is
8045 necessary here because of lines consisting of a line end,
8046 only. The line end will not produce any glyphs and we
8047 would never get MOVE_X_REACHED. */
8048 xassert (it->nglyphs == 0);
8049 result = MOVE_X_REACHED;
8050 break;
8051 }
8052
8053 /* Is this a line end? If yes, we're done. */
8054 if (ITERATOR_AT_END_OF_LINE_P (it))
8055 {
8056 /* If we are past TO_CHARPOS, but never saw any character
8057 positions smaller than TO_CHARPOS, return
8058 MOVE_POS_MATCH_OR_ZV, like the unidirectional display
8059 did. */
8060 if (it->bidi_p && (op & MOVE_TO_POS) != 0)
8061 {
8062 if (!saw_smaller_pos && IT_CHARPOS (*it) > to_charpos)
8063 {
8064 if (IT_CHARPOS (ppos_it) < ZV)
8065 {
8066 RESTORE_IT (it, &ppos_it, ppos_data);
8067 result = MOVE_POS_MATCH_OR_ZV;
8068 }
8069 else
8070 goto buffer_pos_reached;
8071 }
8072 else if (it->line_wrap == WORD_WRAP && atpos_it.sp >= 0
8073 && IT_CHARPOS (*it) > to_charpos)
8074 goto buffer_pos_reached;
8075 else
8076 result = MOVE_NEWLINE_OR_CR;
8077 }
8078 else
8079 result = MOVE_NEWLINE_OR_CR;
8080 break;
8081 }
8082
8083 prev_method = it->method;
8084 if (it->method == GET_FROM_BUFFER)
8085 prev_pos = IT_CHARPOS (*it);
8086 /* The current display element has been consumed. Advance
8087 to the next. */
8088 set_iterator_to_next (it, 1);
8089 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
8090 SET_TEXT_POS (this_line_min_pos, IT_CHARPOS (*it), IT_BYTEPOS (*it));
8091 if (IT_CHARPOS (*it) < to_charpos)
8092 saw_smaller_pos = 1;
8093 if (it->bidi_p
8094 && (op & MOVE_TO_POS)
8095 && IT_CHARPOS (*it) >= to_charpos
8096 && IT_CHARPOS (*it) < IT_CHARPOS (ppos_it))
8097 SAVE_IT (ppos_it, *it, ppos_data);
8098
8099 /* Stop if lines are truncated and IT's current x-position is
8100 past the right edge of the window now. */
8101 if (it->line_wrap == TRUNCATE
8102 && it->current_x >= it->last_visible_x)
8103 {
8104 if (!FRAME_WINDOW_P (it->f)
8105 || IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
8106 {
8107 int at_eob_p = 0;
8108
8109 if ((at_eob_p = !get_next_display_element (it))
8110 || BUFFER_POS_REACHED_P ()
8111 /* If we are past TO_CHARPOS, but never saw any
8112 character positions smaller than TO_CHARPOS,
8113 return MOVE_POS_MATCH_OR_ZV, like the
8114 unidirectional display did. */
8115 || (it->bidi_p && (op & MOVE_TO_POS) != 0
8116 && !saw_smaller_pos
8117 && IT_CHARPOS (*it) > to_charpos))
8118 {
8119 if (it->bidi_p
8120 && !at_eob_p && IT_CHARPOS (ppos_it) < ZV)
8121 RESTORE_IT (it, &ppos_it, ppos_data);
8122 result = MOVE_POS_MATCH_OR_ZV;
8123 break;
8124 }
8125 if (ITERATOR_AT_END_OF_LINE_P (it))
8126 {
8127 result = MOVE_NEWLINE_OR_CR;
8128 break;
8129 }
8130 }
8131 else if (it->bidi_p && (op & MOVE_TO_POS) != 0
8132 && !saw_smaller_pos
8133 && IT_CHARPOS (*it) > to_charpos)
8134 {
8135 if (IT_CHARPOS (ppos_it) < ZV)
8136 RESTORE_IT (it, &ppos_it, ppos_data);
8137 result = MOVE_POS_MATCH_OR_ZV;
8138 break;
8139 }
8140 result = MOVE_LINE_TRUNCATED;
8141 break;
8142 }
8143 #undef IT_RESET_X_ASCENT_DESCENT
8144 }
8145
8146 #undef BUFFER_POS_REACHED_P
8147
8148 /* If we scanned beyond to_pos and didn't find a point to wrap at,
8149 restore the saved iterator. */
8150 if (atpos_it.sp >= 0)
8151 RESTORE_IT (it, &atpos_it, atpos_data);
8152 else if (atx_it.sp >= 0)
8153 RESTORE_IT (it, &atx_it, atx_data);
8154
8155 done:
8156
8157 if (atpos_data)
8158 bidi_unshelve_cache (atpos_data, 1);
8159 if (atx_data)
8160 bidi_unshelve_cache (atx_data, 1);
8161 if (wrap_data)
8162 bidi_unshelve_cache (wrap_data, 1);
8163 if (ppos_data)
8164 bidi_unshelve_cache (ppos_data, 1);
8165
8166 /* Restore the iterator settings altered at the beginning of this
8167 function. */
8168 it->glyph_row = saved_glyph_row;
8169 return result;
8170 }
8171
8172 /* For external use. */
8173 void
8174 move_it_in_display_line (struct it *it,
8175 EMACS_INT to_charpos, int to_x,
8176 enum move_operation_enum op)
8177 {
8178 if (it->line_wrap == WORD_WRAP
8179 && (op & MOVE_TO_X))
8180 {
8181 struct it save_it;
8182 void *save_data = NULL;
8183 int skip;
8184
8185 SAVE_IT (save_it, *it, save_data);
8186 skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
8187 /* When word-wrap is on, TO_X may lie past the end
8188 of a wrapped line. Then it->current is the
8189 character on the next line, so backtrack to the
8190 space before the wrap point. */
8191 if (skip == MOVE_LINE_CONTINUED)
8192 {
8193 int prev_x = max (it->current_x - 1, 0);
8194 RESTORE_IT (it, &save_it, save_data);
8195 move_it_in_display_line_to
8196 (it, -1, prev_x, MOVE_TO_X);
8197 }
8198 else
8199 bidi_unshelve_cache (save_data, 1);
8200 }
8201 else
8202 move_it_in_display_line_to (it, to_charpos, to_x, op);
8203 }
8204
8205
8206 /* Move IT forward until it satisfies one or more of the criteria in
8207 TO_CHARPOS, TO_X, TO_Y, and TO_VPOS.
8208
8209 OP is a bit-mask that specifies where to stop, and in particular,
8210 which of those four position arguments makes a difference. See the
8211 description of enum move_operation_enum.
8212
8213 If TO_CHARPOS is in invisible text, e.g. a truncated part of a
8214 screen line, this function will set IT to the next position that is
8215 displayed to the right of TO_CHARPOS on the screen. */
8216
8217 void
8218 move_it_to (struct it *it, EMACS_INT to_charpos, int to_x, int to_y, int to_vpos, int op)
8219 {
8220 enum move_it_result skip, skip2 = MOVE_X_REACHED;
8221 int line_height, line_start_x = 0, reached = 0;
8222 void *backup_data = NULL;
8223
8224 for (;;)
8225 {
8226 if (op & MOVE_TO_VPOS)
8227 {
8228 /* If no TO_CHARPOS and no TO_X specified, stop at the
8229 start of the line TO_VPOS. */
8230 if ((op & (MOVE_TO_X | MOVE_TO_POS)) == 0)
8231 {
8232 if (it->vpos == to_vpos)
8233 {
8234 reached = 1;
8235 break;
8236 }
8237 else
8238 skip = move_it_in_display_line_to (it, -1, -1, 0);
8239 }
8240 else
8241 {
8242 /* TO_VPOS >= 0 means stop at TO_X in the line at
8243 TO_VPOS, or at TO_POS, whichever comes first. */
8244 if (it->vpos == to_vpos)
8245 {
8246 reached = 2;
8247 break;
8248 }
8249
8250 skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
8251
8252 if (skip == MOVE_POS_MATCH_OR_ZV || it->vpos == to_vpos)
8253 {
8254 reached = 3;
8255 break;
8256 }
8257 else if (skip == MOVE_X_REACHED && it->vpos != to_vpos)
8258 {
8259 /* We have reached TO_X but not in the line we want. */
8260 skip = move_it_in_display_line_to (it, to_charpos,
8261 -1, MOVE_TO_POS);
8262 if (skip == MOVE_POS_MATCH_OR_ZV)
8263 {
8264 reached = 4;
8265 break;
8266 }
8267 }
8268 }
8269 }
8270 else if (op & MOVE_TO_Y)
8271 {
8272 struct it it_backup;
8273
8274 if (it->line_wrap == WORD_WRAP)
8275 SAVE_IT (it_backup, *it, backup_data);
8276
8277 /* TO_Y specified means stop at TO_X in the line containing
8278 TO_Y---or at TO_CHARPOS if this is reached first. The
8279 problem is that we can't really tell whether the line
8280 contains TO_Y before we have completely scanned it, and
8281 this may skip past TO_X. What we do is to first scan to
8282 TO_X.
8283
8284 If TO_X is not specified, use a TO_X of zero. The reason
8285 is to make the outcome of this function more predictable.
8286 If we didn't use TO_X == 0, we would stop at the end of
8287 the line which is probably not what a caller would expect
8288 to happen. */
8289 skip = move_it_in_display_line_to
8290 (it, to_charpos, ((op & MOVE_TO_X) ? to_x : 0),
8291 (MOVE_TO_X | (op & MOVE_TO_POS)));
8292
8293 /* If TO_CHARPOS is reached or ZV, we don't have to do more. */
8294 if (skip == MOVE_POS_MATCH_OR_ZV)
8295 reached = 5;
8296 else if (skip == MOVE_X_REACHED)
8297 {
8298 /* If TO_X was reached, we want to know whether TO_Y is
8299 in the line. We know this is the case if the already
8300 scanned glyphs make the line tall enough. Otherwise,
8301 we must check by scanning the rest of the line. */
8302 line_height = it->max_ascent + it->max_descent;
8303 if (to_y >= it->current_y
8304 && to_y < it->current_y + line_height)
8305 {
8306 reached = 6;
8307 break;
8308 }
8309 SAVE_IT (it_backup, *it, backup_data);
8310 TRACE_MOVE ((stderr, "move_it: from %d\n", IT_CHARPOS (*it)));
8311 skip2 = move_it_in_display_line_to (it, to_charpos, -1,
8312 op & MOVE_TO_POS);
8313 TRACE_MOVE ((stderr, "move_it: to %d\n", IT_CHARPOS (*it)));
8314 line_height = it->max_ascent + it->max_descent;
8315 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
8316
8317 if (to_y >= it->current_y
8318 && to_y < it->current_y + line_height)
8319 {
8320 /* If TO_Y is in this line and TO_X was reached
8321 above, we scanned too far. We have to restore
8322 IT's settings to the ones before skipping. */
8323 RESTORE_IT (it, &it_backup, backup_data);
8324 reached = 6;
8325 }
8326 else
8327 {
8328 skip = skip2;
8329 if (skip == MOVE_POS_MATCH_OR_ZV)
8330 reached = 7;
8331 }
8332 }
8333 else
8334 {
8335 /* Check whether TO_Y is in this line. */
8336 line_height = it->max_ascent + it->max_descent;
8337 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
8338
8339 if (to_y >= it->current_y
8340 && to_y < it->current_y + line_height)
8341 {
8342 /* When word-wrap is on, TO_X may lie past the end
8343 of a wrapped line. Then it->current is the
8344 character on the next line, so backtrack to the
8345 space before the wrap point. */
8346 if (skip == MOVE_LINE_CONTINUED
8347 && it->line_wrap == WORD_WRAP)
8348 {
8349 int prev_x = max (it->current_x - 1, 0);
8350 RESTORE_IT (it, &it_backup, backup_data);
8351 skip = move_it_in_display_line_to
8352 (it, -1, prev_x, MOVE_TO_X);
8353 }
8354 reached = 6;
8355 }
8356 }
8357
8358 if (reached)
8359 break;
8360 }
8361 else if (BUFFERP (it->object)
8362 && (it->method == GET_FROM_BUFFER
8363 || it->method == GET_FROM_STRETCH)
8364 && IT_CHARPOS (*it) >= to_charpos
8365 /* Under bidi iteration, a call to set_iterator_to_next
8366 can scan far beyond to_charpos if the initial
8367 portion of the next line needs to be reordered. In
8368 that case, give move_it_in_display_line_to another
8369 chance below. */
8370 && !(it->bidi_p
8371 && it->bidi_it.scan_dir == -1))
8372 skip = MOVE_POS_MATCH_OR_ZV;
8373 else
8374 skip = move_it_in_display_line_to (it, to_charpos, -1, MOVE_TO_POS);
8375
8376 switch (skip)
8377 {
8378 case MOVE_POS_MATCH_OR_ZV:
8379 reached = 8;
8380 goto out;
8381
8382 case MOVE_NEWLINE_OR_CR:
8383 set_iterator_to_next (it, 1);
8384 it->continuation_lines_width = 0;
8385 break;
8386
8387 case MOVE_LINE_TRUNCATED:
8388 it->continuation_lines_width = 0;
8389 reseat_at_next_visible_line_start (it, 0);
8390 if ((op & MOVE_TO_POS) != 0
8391 && IT_CHARPOS (*it) > to_charpos)
8392 {
8393 reached = 9;
8394 goto out;
8395 }
8396 break;
8397
8398 case MOVE_LINE_CONTINUED:
8399 /* For continued lines ending in a tab, some of the glyphs
8400 associated with the tab are displayed on the current
8401 line. Since it->current_x does not include these glyphs,
8402 we use it->last_visible_x instead. */
8403 if (it->c == '\t')
8404 {
8405 it->continuation_lines_width += it->last_visible_x;
8406 /* When moving by vpos, ensure that the iterator really
8407 advances to the next line (bug#847, bug#969). Fixme:
8408 do we need to do this in other circumstances? */
8409 if (it->current_x != it->last_visible_x
8410 && (op & MOVE_TO_VPOS)
8411 && !(op & (MOVE_TO_X | MOVE_TO_POS)))
8412 {
8413 line_start_x = it->current_x + it->pixel_width
8414 - it->last_visible_x;
8415 set_iterator_to_next (it, 0);
8416 }
8417 }
8418 else
8419 it->continuation_lines_width += it->current_x;
8420 break;
8421
8422 default:
8423 abort ();
8424 }
8425
8426 /* Reset/increment for the next run. */
8427 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
8428 it->current_x = line_start_x;
8429 line_start_x = 0;
8430 it->hpos = 0;
8431 it->current_y += it->max_ascent + it->max_descent;
8432 ++it->vpos;
8433 last_height = it->max_ascent + it->max_descent;
8434 last_max_ascent = it->max_ascent;
8435 it->max_ascent = it->max_descent = 0;
8436 }
8437
8438 out:
8439
8440 /* On text terminals, we may stop at the end of a line in the middle
8441 of a multi-character glyph. If the glyph itself is continued,
8442 i.e. it is actually displayed on the next line, don't treat this
8443 stopping point as valid; move to the next line instead (unless
8444 that brings us offscreen). */
8445 if (!FRAME_WINDOW_P (it->f)
8446 && op & MOVE_TO_POS
8447 && IT_CHARPOS (*it) == to_charpos
8448 && it->what == IT_CHARACTER
8449 && it->nglyphs > 1
8450 && it->line_wrap == WINDOW_WRAP
8451 && it->current_x == it->last_visible_x - 1
8452 && it->c != '\n'
8453 && it->c != '\t'
8454 && it->vpos < XFASTINT (it->w->window_end_vpos))
8455 {
8456 it->continuation_lines_width += it->current_x;
8457 it->current_x = it->hpos = it->max_ascent = it->max_descent = 0;
8458 it->current_y += it->max_ascent + it->max_descent;
8459 ++it->vpos;
8460 last_height = it->max_ascent + it->max_descent;
8461 last_max_ascent = it->max_ascent;
8462 }
8463
8464 if (backup_data)
8465 bidi_unshelve_cache (backup_data, 1);
8466
8467 TRACE_MOVE ((stderr, "move_it_to: reached %d\n", reached));
8468 }
8469
8470
8471 /* Move iterator IT backward by a specified y-distance DY, DY >= 0.
8472
8473 If DY > 0, move IT backward at least that many pixels. DY = 0
8474 means move IT backward to the preceding line start or BEGV. This
8475 function may move over more than DY pixels if IT->current_y - DY
8476 ends up in the middle of a line; in this case IT->current_y will be
8477 set to the top of the line moved to. */
8478
8479 void
8480 move_it_vertically_backward (struct it *it, int dy)
8481 {
8482 int nlines, h;
8483 struct it it2, it3;
8484 void *it2data = NULL, *it3data = NULL;
8485 EMACS_INT start_pos;
8486
8487 move_further_back:
8488 xassert (dy >= 0);
8489
8490 start_pos = IT_CHARPOS (*it);
8491
8492 /* Estimate how many newlines we must move back. */
8493 nlines = max (1, dy / FRAME_LINE_HEIGHT (it->f));
8494
8495 /* Set the iterator's position that many lines back. */
8496 while (nlines-- && IT_CHARPOS (*it) > BEGV)
8497 back_to_previous_visible_line_start (it);
8498
8499 /* Reseat the iterator here. When moving backward, we don't want
8500 reseat to skip forward over invisible text, set up the iterator
8501 to deliver from overlay strings at the new position etc. So,
8502 use reseat_1 here. */
8503 reseat_1 (it, it->current.pos, 1);
8504
8505 /* We are now surely at a line start. */
8506 it->current_x = it->hpos = 0; /* FIXME: this is incorrect when bidi
8507 reordering is in effect. */
8508 it->continuation_lines_width = 0;
8509
8510 /* Move forward and see what y-distance we moved. First move to the
8511 start of the next line so that we get its height. We need this
8512 height to be able to tell whether we reached the specified
8513 y-distance. */
8514 SAVE_IT (it2, *it, it2data);
8515 it2.max_ascent = it2.max_descent = 0;
8516 do
8517 {
8518 move_it_to (&it2, start_pos, -1, -1, it2.vpos + 1,
8519 MOVE_TO_POS | MOVE_TO_VPOS);
8520 }
8521 while (!IT_POS_VALID_AFTER_MOVE_P (&it2));
8522 xassert (IT_CHARPOS (*it) >= BEGV);
8523 SAVE_IT (it3, it2, it3data);
8524
8525 move_it_to (&it2, start_pos, -1, -1, -1, MOVE_TO_POS);
8526 xassert (IT_CHARPOS (*it) >= BEGV);
8527 /* H is the actual vertical distance from the position in *IT
8528 and the starting position. */
8529 h = it2.current_y - it->current_y;
8530 /* NLINES is the distance in number of lines. */
8531 nlines = it2.vpos - it->vpos;
8532
8533 /* Correct IT's y and vpos position
8534 so that they are relative to the starting point. */
8535 it->vpos -= nlines;
8536 it->current_y -= h;
8537
8538 if (dy == 0)
8539 {
8540 /* DY == 0 means move to the start of the screen line. The
8541 value of nlines is > 0 if continuation lines were involved,
8542 or if the original IT position was at start of a line. */
8543 RESTORE_IT (it, it, it2data);
8544 if (nlines > 0)
8545 move_it_by_lines (it, nlines);
8546 /* The above code moves us to some position NLINES down,
8547 usually to its first glyph (leftmost in an L2R line), but
8548 that's not necessarily the start of the line, under bidi
8549 reordering. We want to get to the character position
8550 that is immediately after the newline of the previous
8551 line. */
8552 if (it->bidi_p && IT_CHARPOS (*it) > BEGV
8553 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
8554 {
8555 EMACS_INT nl_pos =
8556 find_next_newline_no_quit (IT_CHARPOS (*it) - 1, -1);
8557
8558 move_it_to (it, nl_pos, -1, -1, -1, MOVE_TO_POS);
8559 }
8560 bidi_unshelve_cache (it3data, 1);
8561 }
8562 else
8563 {
8564 /* The y-position we try to reach, relative to *IT.
8565 Note that H has been subtracted in front of the if-statement. */
8566 int target_y = it->current_y + h - dy;
8567 int y0 = it3.current_y;
8568 int y1;
8569 int line_height;
8570
8571 RESTORE_IT (&it3, &it3, it3data);
8572 y1 = line_bottom_y (&it3);
8573 line_height = y1 - y0;
8574 RESTORE_IT (it, it, it2data);
8575 /* If we did not reach target_y, try to move further backward if
8576 we can. If we moved too far backward, try to move forward. */
8577 if (target_y < it->current_y
8578 /* This is heuristic. In a window that's 3 lines high, with
8579 a line height of 13 pixels each, recentering with point
8580 on the bottom line will try to move -39/2 = 19 pixels
8581 backward. Try to avoid moving into the first line. */
8582 && (it->current_y - target_y
8583 > min (window_box_height (it->w), line_height * 2 / 3))
8584 && IT_CHARPOS (*it) > BEGV)
8585 {
8586 TRACE_MOVE ((stderr, " not far enough -> move_vert %d\n",
8587 target_y - it->current_y));
8588 dy = it->current_y - target_y;
8589 goto move_further_back;
8590 }
8591 else if (target_y >= it->current_y + line_height
8592 && IT_CHARPOS (*it) < ZV)
8593 {
8594 /* Should move forward by at least one line, maybe more.
8595
8596 Note: Calling move_it_by_lines can be expensive on
8597 terminal frames, where compute_motion is used (via
8598 vmotion) to do the job, when there are very long lines
8599 and truncate-lines is nil. That's the reason for
8600 treating terminal frames specially here. */
8601
8602 if (!FRAME_WINDOW_P (it->f))
8603 move_it_vertically (it, target_y - (it->current_y + line_height));
8604 else
8605 {
8606 do
8607 {
8608 move_it_by_lines (it, 1);
8609 }
8610 while (target_y >= line_bottom_y (it) && IT_CHARPOS (*it) < ZV);
8611 }
8612 }
8613 }
8614 }
8615
8616
8617 /* Move IT by a specified amount of pixel lines DY. DY negative means
8618 move backwards. DY = 0 means move to start of screen line. At the
8619 end, IT will be on the start of a screen line. */
8620
8621 void
8622 move_it_vertically (struct it *it, int dy)
8623 {
8624 if (dy <= 0)
8625 move_it_vertically_backward (it, -dy);
8626 else
8627 {
8628 TRACE_MOVE ((stderr, "move_it_v: from %d, %d\n", IT_CHARPOS (*it), dy));
8629 move_it_to (it, ZV, -1, it->current_y + dy, -1,
8630 MOVE_TO_POS | MOVE_TO_Y);
8631 TRACE_MOVE ((stderr, "move_it_v: to %d\n", IT_CHARPOS (*it)));
8632
8633 /* If buffer ends in ZV without a newline, move to the start of
8634 the line to satisfy the post-condition. */
8635 if (IT_CHARPOS (*it) == ZV
8636 && ZV > BEGV
8637 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
8638 move_it_by_lines (it, 0);
8639 }
8640 }
8641
8642
8643 /* Move iterator IT past the end of the text line it is in. */
8644
8645 void
8646 move_it_past_eol (struct it *it)
8647 {
8648 enum move_it_result rc;
8649
8650 rc = move_it_in_display_line_to (it, Z, 0, MOVE_TO_POS);
8651 if (rc == MOVE_NEWLINE_OR_CR)
8652 set_iterator_to_next (it, 0);
8653 }
8654
8655
8656 /* Move IT by a specified number DVPOS of screen lines down. DVPOS
8657 negative means move up. DVPOS == 0 means move to the start of the
8658 screen line.
8659
8660 Optimization idea: If we would know that IT->f doesn't use
8661 a face with proportional font, we could be faster for
8662 truncate-lines nil. */
8663
8664 void
8665 move_it_by_lines (struct it *it, int dvpos)
8666 {
8667
8668 /* The commented-out optimization uses vmotion on terminals. This
8669 gives bad results, because elements like it->what, on which
8670 callers such as pos_visible_p rely, aren't updated. */
8671 /* struct position pos;
8672 if (!FRAME_WINDOW_P (it->f))
8673 {
8674 struct text_pos textpos;
8675
8676 pos = *vmotion (IT_CHARPOS (*it), dvpos, it->w);
8677 SET_TEXT_POS (textpos, pos.bufpos, pos.bytepos);
8678 reseat (it, textpos, 1);
8679 it->vpos += pos.vpos;
8680 it->current_y += pos.vpos;
8681 }
8682 else */
8683
8684 if (dvpos == 0)
8685 {
8686 /* DVPOS == 0 means move to the start of the screen line. */
8687 move_it_vertically_backward (it, 0);
8688 xassert (it->current_x == 0 && it->hpos == 0);
8689 /* Let next call to line_bottom_y calculate real line height */
8690 last_height = 0;
8691 }
8692 else if (dvpos > 0)
8693 {
8694 move_it_to (it, -1, -1, -1, it->vpos + dvpos, MOVE_TO_VPOS);
8695 if (!IT_POS_VALID_AFTER_MOVE_P (it))
8696 move_it_to (it, IT_CHARPOS (*it) + 1, -1, -1, -1, MOVE_TO_POS);
8697 }
8698 else
8699 {
8700 struct it it2;
8701 void *it2data = NULL;
8702 EMACS_INT start_charpos, i;
8703
8704 /* Start at the beginning of the screen line containing IT's
8705 position. This may actually move vertically backwards,
8706 in case of overlays, so adjust dvpos accordingly. */
8707 dvpos += it->vpos;
8708 move_it_vertically_backward (it, 0);
8709 dvpos -= it->vpos;
8710
8711 /* Go back -DVPOS visible lines and reseat the iterator there. */
8712 start_charpos = IT_CHARPOS (*it);
8713 for (i = -dvpos; i > 0 && IT_CHARPOS (*it) > BEGV; --i)
8714 back_to_previous_visible_line_start (it);
8715 reseat (it, it->current.pos, 1);
8716
8717 /* Move further back if we end up in a string or an image. */
8718 while (!IT_POS_VALID_AFTER_MOVE_P (it))
8719 {
8720 /* First try to move to start of display line. */
8721 dvpos += it->vpos;
8722 move_it_vertically_backward (it, 0);
8723 dvpos -= it->vpos;
8724 if (IT_POS_VALID_AFTER_MOVE_P (it))
8725 break;
8726 /* If start of line is still in string or image,
8727 move further back. */
8728 back_to_previous_visible_line_start (it);
8729 reseat (it, it->current.pos, 1);
8730 dvpos--;
8731 }
8732
8733 it->current_x = it->hpos = 0;
8734
8735 /* Above call may have moved too far if continuation lines
8736 are involved. Scan forward and see if it did. */
8737 SAVE_IT (it2, *it, it2data);
8738 it2.vpos = it2.current_y = 0;
8739 move_it_to (&it2, start_charpos, -1, -1, -1, MOVE_TO_POS);
8740 it->vpos -= it2.vpos;
8741 it->current_y -= it2.current_y;
8742 it->current_x = it->hpos = 0;
8743
8744 /* If we moved too far back, move IT some lines forward. */
8745 if (it2.vpos > -dvpos)
8746 {
8747 int delta = it2.vpos + dvpos;
8748
8749 RESTORE_IT (&it2, &it2, it2data);
8750 SAVE_IT (it2, *it, it2data);
8751 move_it_to (it, -1, -1, -1, it->vpos + delta, MOVE_TO_VPOS);
8752 /* Move back again if we got too far ahead. */
8753 if (IT_CHARPOS (*it) >= start_charpos)
8754 RESTORE_IT (it, &it2, it2data);
8755 else
8756 bidi_unshelve_cache (it2data, 1);
8757 }
8758 else
8759 RESTORE_IT (it, it, it2data);
8760 }
8761 }
8762
8763 /* Return 1 if IT points into the middle of a display vector. */
8764
8765 int
8766 in_display_vector_p (struct it *it)
8767 {
8768 return (it->method == GET_FROM_DISPLAY_VECTOR
8769 && it->current.dpvec_index > 0
8770 && it->dpvec + it->current.dpvec_index != it->dpend);
8771 }
8772
8773 \f
8774 /***********************************************************************
8775 Messages
8776 ***********************************************************************/
8777
8778
8779 /* Add a message with format string FORMAT and arguments ARG1 and ARG2
8780 to *Messages*. */
8781
8782 void
8783 add_to_log (const char *format, Lisp_Object arg1, Lisp_Object arg2)
8784 {
8785 Lisp_Object args[3];
8786 Lisp_Object msg, fmt;
8787 char *buffer;
8788 EMACS_INT len;
8789 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
8790 USE_SAFE_ALLOCA;
8791
8792 /* Do nothing if called asynchronously. Inserting text into
8793 a buffer may call after-change-functions and alike and
8794 that would means running Lisp asynchronously. */
8795 if (handling_signal)
8796 return;
8797
8798 fmt = msg = Qnil;
8799 GCPRO4 (fmt, msg, arg1, arg2);
8800
8801 args[0] = fmt = build_string (format);
8802 args[1] = arg1;
8803 args[2] = arg2;
8804 msg = Fformat (3, args);
8805
8806 len = SBYTES (msg) + 1;
8807 SAFE_ALLOCA (buffer, char *, len);
8808 memcpy (buffer, SDATA (msg), len);
8809
8810 message_dolog (buffer, len - 1, 1, 0);
8811 SAFE_FREE ();
8812
8813 UNGCPRO;
8814 }
8815
8816
8817 /* Output a newline in the *Messages* buffer if "needs" one. */
8818
8819 void
8820 message_log_maybe_newline (void)
8821 {
8822 if (message_log_need_newline)
8823 message_dolog ("", 0, 1, 0);
8824 }
8825
8826
8827 /* Add a string M of length NBYTES to the message log, optionally
8828 terminated with a newline when NLFLAG is non-zero. MULTIBYTE, if
8829 nonzero, means interpret the contents of M as multibyte. This
8830 function calls low-level routines in order to bypass text property
8831 hooks, etc. which might not be safe to run.
8832
8833 This may GC (insert may run before/after change hooks),
8834 so the buffer M must NOT point to a Lisp string. */
8835
8836 void
8837 message_dolog (const char *m, EMACS_INT nbytes, int nlflag, int multibyte)
8838 {
8839 const unsigned char *msg = (const unsigned char *) m;
8840
8841 if (!NILP (Vmemory_full))
8842 return;
8843
8844 if (!NILP (Vmessage_log_max))
8845 {
8846 struct buffer *oldbuf;
8847 Lisp_Object oldpoint, oldbegv, oldzv;
8848 int old_windows_or_buffers_changed = windows_or_buffers_changed;
8849 EMACS_INT point_at_end = 0;
8850 EMACS_INT zv_at_end = 0;
8851 Lisp_Object old_deactivate_mark, tem;
8852 struct gcpro gcpro1;
8853
8854 old_deactivate_mark = Vdeactivate_mark;
8855 oldbuf = current_buffer;
8856 Fset_buffer (Fget_buffer_create (Vmessages_buffer_name));
8857 BVAR (current_buffer, undo_list) = Qt;
8858
8859 oldpoint = message_dolog_marker1;
8860 set_marker_restricted (oldpoint, make_number (PT), Qnil);
8861 oldbegv = message_dolog_marker2;
8862 set_marker_restricted (oldbegv, make_number (BEGV), Qnil);
8863 oldzv = message_dolog_marker3;
8864 set_marker_restricted (oldzv, make_number (ZV), Qnil);
8865 GCPRO1 (old_deactivate_mark);
8866
8867 if (PT == Z)
8868 point_at_end = 1;
8869 if (ZV == Z)
8870 zv_at_end = 1;
8871
8872 BEGV = BEG;
8873 BEGV_BYTE = BEG_BYTE;
8874 ZV = Z;
8875 ZV_BYTE = Z_BYTE;
8876 TEMP_SET_PT_BOTH (Z, Z_BYTE);
8877
8878 /* Insert the string--maybe converting multibyte to single byte
8879 or vice versa, so that all the text fits the buffer. */
8880 if (multibyte
8881 && NILP (BVAR (current_buffer, enable_multibyte_characters)))
8882 {
8883 EMACS_INT i;
8884 int c, char_bytes;
8885 char work[1];
8886
8887 /* Convert a multibyte string to single-byte
8888 for the *Message* buffer. */
8889 for (i = 0; i < nbytes; i += char_bytes)
8890 {
8891 c = string_char_and_length (msg + i, &char_bytes);
8892 work[0] = (ASCII_CHAR_P (c)
8893 ? c
8894 : multibyte_char_to_unibyte (c));
8895 insert_1_both (work, 1, 1, 1, 0, 0);
8896 }
8897 }
8898 else if (! multibyte
8899 && ! NILP (BVAR (current_buffer, enable_multibyte_characters)))
8900 {
8901 EMACS_INT i;
8902 int c, char_bytes;
8903 unsigned char str[MAX_MULTIBYTE_LENGTH];
8904 /* Convert a single-byte string to multibyte
8905 for the *Message* buffer. */
8906 for (i = 0; i < nbytes; i++)
8907 {
8908 c = msg[i];
8909 MAKE_CHAR_MULTIBYTE (c);
8910 char_bytes = CHAR_STRING (c, str);
8911 insert_1_both ((char *) str, 1, char_bytes, 1, 0, 0);
8912 }
8913 }
8914 else if (nbytes)
8915 insert_1 (m, nbytes, 1, 0, 0);
8916
8917 if (nlflag)
8918 {
8919 EMACS_INT this_bol, this_bol_byte, prev_bol, prev_bol_byte;
8920 printmax_t dups;
8921 insert_1 ("\n", 1, 1, 0, 0);
8922
8923 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE, -2, 0);
8924 this_bol = PT;
8925 this_bol_byte = PT_BYTE;
8926
8927 /* See if this line duplicates the previous one.
8928 If so, combine duplicates. */
8929 if (this_bol > BEG)
8930 {
8931 scan_newline (PT, PT_BYTE, BEG, BEG_BYTE, -2, 0);
8932 prev_bol = PT;
8933 prev_bol_byte = PT_BYTE;
8934
8935 dups = message_log_check_duplicate (prev_bol_byte,
8936 this_bol_byte);
8937 if (dups)
8938 {
8939 del_range_both (prev_bol, prev_bol_byte,
8940 this_bol, this_bol_byte, 0);
8941 if (dups > 1)
8942 {
8943 char dupstr[sizeof " [ times]"
8944 + INT_STRLEN_BOUND (printmax_t)];
8945 int duplen;
8946
8947 /* If you change this format, don't forget to also
8948 change message_log_check_duplicate. */
8949 sprintf (dupstr, " [%"pMd" times]", dups);
8950 duplen = strlen (dupstr);
8951 TEMP_SET_PT_BOTH (Z - 1, Z_BYTE - 1);
8952 insert_1 (dupstr, duplen, 1, 0, 1);
8953 }
8954 }
8955 }
8956
8957 /* If we have more than the desired maximum number of lines
8958 in the *Messages* buffer now, delete the oldest ones.
8959 This is safe because we don't have undo in this buffer. */
8960
8961 if (NATNUMP (Vmessage_log_max))
8962 {
8963 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE,
8964 -XFASTINT (Vmessage_log_max) - 1, 0);
8965 del_range_both (BEG, BEG_BYTE, PT, PT_BYTE, 0);
8966 }
8967 }
8968 BEGV = XMARKER (oldbegv)->charpos;
8969 BEGV_BYTE = marker_byte_position (oldbegv);
8970
8971 if (zv_at_end)
8972 {
8973 ZV = Z;
8974 ZV_BYTE = Z_BYTE;
8975 }
8976 else
8977 {
8978 ZV = XMARKER (oldzv)->charpos;
8979 ZV_BYTE = marker_byte_position (oldzv);
8980 }
8981
8982 if (point_at_end)
8983 TEMP_SET_PT_BOTH (Z, Z_BYTE);
8984 else
8985 /* We can't do Fgoto_char (oldpoint) because it will run some
8986 Lisp code. */
8987 TEMP_SET_PT_BOTH (XMARKER (oldpoint)->charpos,
8988 XMARKER (oldpoint)->bytepos);
8989
8990 UNGCPRO;
8991 unchain_marker (XMARKER (oldpoint));
8992 unchain_marker (XMARKER (oldbegv));
8993 unchain_marker (XMARKER (oldzv));
8994
8995 tem = Fget_buffer_window (Fcurrent_buffer (), Qt);
8996 set_buffer_internal (oldbuf);
8997 if (NILP (tem))
8998 windows_or_buffers_changed = old_windows_or_buffers_changed;
8999 message_log_need_newline = !nlflag;
9000 Vdeactivate_mark = old_deactivate_mark;
9001 }
9002 }
9003
9004
9005 /* We are at the end of the buffer after just having inserted a newline.
9006 (Note: We depend on the fact we won't be crossing the gap.)
9007 Check to see if the most recent message looks a lot like the previous one.
9008 Return 0 if different, 1 if the new one should just replace it, or a
9009 value N > 1 if we should also append " [N times]". */
9010
9011 static intmax_t
9012 message_log_check_duplicate (EMACS_INT prev_bol_byte, EMACS_INT this_bol_byte)
9013 {
9014 EMACS_INT i;
9015 EMACS_INT len = Z_BYTE - 1 - this_bol_byte;
9016 int seen_dots = 0;
9017 unsigned char *p1 = BUF_BYTE_ADDRESS (current_buffer, prev_bol_byte);
9018 unsigned char *p2 = BUF_BYTE_ADDRESS (current_buffer, this_bol_byte);
9019
9020 for (i = 0; i < len; i++)
9021 {
9022 if (i >= 3 && p1[i-3] == '.' && p1[i-2] == '.' && p1[i-1] == '.')
9023 seen_dots = 1;
9024 if (p1[i] != p2[i])
9025 return seen_dots;
9026 }
9027 p1 += len;
9028 if (*p1 == '\n')
9029 return 2;
9030 if (*p1++ == ' ' && *p1++ == '[')
9031 {
9032 char *pend;
9033 intmax_t n = strtoimax ((char *) p1, &pend, 10);
9034 if (0 < n && n < INTMAX_MAX && strncmp (pend, " times]\n", 8) == 0)
9035 return n+1;
9036 }
9037 return 0;
9038 }
9039 \f
9040
9041 /* Display an echo area message M with a specified length of NBYTES
9042 bytes. The string may include null characters. If M is 0, clear
9043 out any existing message, and let the mini-buffer text show
9044 through.
9045
9046 This may GC, so the buffer M must NOT point to a Lisp string. */
9047
9048 void
9049 message2 (const char *m, EMACS_INT nbytes, int multibyte)
9050 {
9051 /* First flush out any partial line written with print. */
9052 message_log_maybe_newline ();
9053 if (m)
9054 message_dolog (m, nbytes, 1, multibyte);
9055 message2_nolog (m, nbytes, multibyte);
9056 }
9057
9058
9059 /* The non-logging counterpart of message2. */
9060
9061 void
9062 message2_nolog (const char *m, EMACS_INT nbytes, int multibyte)
9063 {
9064 struct frame *sf = SELECTED_FRAME ();
9065 message_enable_multibyte = multibyte;
9066
9067 if (FRAME_INITIAL_P (sf))
9068 {
9069 if (noninteractive_need_newline)
9070 putc ('\n', stderr);
9071 noninteractive_need_newline = 0;
9072 if (m)
9073 fwrite (m, nbytes, 1, stderr);
9074 if (cursor_in_echo_area == 0)
9075 fprintf (stderr, "\n");
9076 fflush (stderr);
9077 }
9078 /* A null message buffer means that the frame hasn't really been
9079 initialized yet. Error messages get reported properly by
9080 cmd_error, so this must be just an informative message; toss it. */
9081 else if (INTERACTIVE
9082 && sf->glyphs_initialized_p
9083 && FRAME_MESSAGE_BUF (sf))
9084 {
9085 Lisp_Object mini_window;
9086 struct frame *f;
9087
9088 /* Get the frame containing the mini-buffer
9089 that the selected frame is using. */
9090 mini_window = FRAME_MINIBUF_WINDOW (sf);
9091 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
9092
9093 FRAME_SAMPLE_VISIBILITY (f);
9094 if (FRAME_VISIBLE_P (sf)
9095 && ! FRAME_VISIBLE_P (f))
9096 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (mini_window)));
9097
9098 if (m)
9099 {
9100 set_message (m, Qnil, nbytes, multibyte);
9101 if (minibuffer_auto_raise)
9102 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
9103 }
9104 else
9105 clear_message (1, 1);
9106
9107 do_pending_window_change (0);
9108 echo_area_display (1);
9109 do_pending_window_change (0);
9110 if (FRAME_TERMINAL (f)->frame_up_to_date_hook != 0 && ! gc_in_progress)
9111 (*FRAME_TERMINAL (f)->frame_up_to_date_hook) (f);
9112 }
9113 }
9114
9115
9116 /* Display an echo area message M with a specified length of NBYTES
9117 bytes. The string may include null characters. If M is not a
9118 string, clear out any existing message, and let the mini-buffer
9119 text show through.
9120
9121 This function cancels echoing. */
9122
9123 void
9124 message3 (Lisp_Object m, EMACS_INT nbytes, int multibyte)
9125 {
9126 struct gcpro gcpro1;
9127
9128 GCPRO1 (m);
9129 clear_message (1,1);
9130 cancel_echoing ();
9131
9132 /* First flush out any partial line written with print. */
9133 message_log_maybe_newline ();
9134 if (STRINGP (m))
9135 {
9136 char *buffer;
9137 USE_SAFE_ALLOCA;
9138
9139 SAFE_ALLOCA (buffer, char *, nbytes);
9140 memcpy (buffer, SDATA (m), nbytes);
9141 message_dolog (buffer, nbytes, 1, multibyte);
9142 SAFE_FREE ();
9143 }
9144 message3_nolog (m, nbytes, multibyte);
9145
9146 UNGCPRO;
9147 }
9148
9149
9150 /* The non-logging version of message3.
9151 This does not cancel echoing, because it is used for echoing.
9152 Perhaps we need to make a separate function for echoing
9153 and make this cancel echoing. */
9154
9155 void
9156 message3_nolog (Lisp_Object m, EMACS_INT nbytes, int multibyte)
9157 {
9158 struct frame *sf = SELECTED_FRAME ();
9159 message_enable_multibyte = multibyte;
9160
9161 if (FRAME_INITIAL_P (sf))
9162 {
9163 if (noninteractive_need_newline)
9164 putc ('\n', stderr);
9165 noninteractive_need_newline = 0;
9166 if (STRINGP (m))
9167 fwrite (SDATA (m), nbytes, 1, stderr);
9168 if (cursor_in_echo_area == 0)
9169 fprintf (stderr, "\n");
9170 fflush (stderr);
9171 }
9172 /* A null message buffer means that the frame hasn't really been
9173 initialized yet. Error messages get reported properly by
9174 cmd_error, so this must be just an informative message; toss it. */
9175 else if (INTERACTIVE
9176 && sf->glyphs_initialized_p
9177 && FRAME_MESSAGE_BUF (sf))
9178 {
9179 Lisp_Object mini_window;
9180 Lisp_Object frame;
9181 struct frame *f;
9182
9183 /* Get the frame containing the mini-buffer
9184 that the selected frame is using. */
9185 mini_window = FRAME_MINIBUF_WINDOW (sf);
9186 frame = XWINDOW (mini_window)->frame;
9187 f = XFRAME (frame);
9188
9189 FRAME_SAMPLE_VISIBILITY (f);
9190 if (FRAME_VISIBLE_P (sf)
9191 && !FRAME_VISIBLE_P (f))
9192 Fmake_frame_visible (frame);
9193
9194 if (STRINGP (m) && SCHARS (m) > 0)
9195 {
9196 set_message (NULL, m, nbytes, multibyte);
9197 if (minibuffer_auto_raise)
9198 Fraise_frame (frame);
9199 /* Assume we are not echoing.
9200 (If we are, echo_now will override this.) */
9201 echo_message_buffer = Qnil;
9202 }
9203 else
9204 clear_message (1, 1);
9205
9206 do_pending_window_change (0);
9207 echo_area_display (1);
9208 do_pending_window_change (0);
9209 if (FRAME_TERMINAL (f)->frame_up_to_date_hook != 0 && ! gc_in_progress)
9210 (*FRAME_TERMINAL (f)->frame_up_to_date_hook) (f);
9211 }
9212 }
9213
9214
9215 /* Display a null-terminated echo area message M. If M is 0, clear
9216 out any existing message, and let the mini-buffer text show through.
9217
9218 The buffer M must continue to exist until after the echo area gets
9219 cleared or some other message gets displayed there. Do not pass
9220 text that is stored in a Lisp string. Do not pass text in a buffer
9221 that was alloca'd. */
9222
9223 void
9224 message1 (const char *m)
9225 {
9226 message2 (m, (m ? strlen (m) : 0), 0);
9227 }
9228
9229
9230 /* The non-logging counterpart of message1. */
9231
9232 void
9233 message1_nolog (const char *m)
9234 {
9235 message2_nolog (m, (m ? strlen (m) : 0), 0);
9236 }
9237
9238 /* Display a message M which contains a single %s
9239 which gets replaced with STRING. */
9240
9241 void
9242 message_with_string (const char *m, Lisp_Object string, int log)
9243 {
9244 CHECK_STRING (string);
9245
9246 if (noninteractive)
9247 {
9248 if (m)
9249 {
9250 if (noninteractive_need_newline)
9251 putc ('\n', stderr);
9252 noninteractive_need_newline = 0;
9253 fprintf (stderr, m, SDATA (string));
9254 if (!cursor_in_echo_area)
9255 fprintf (stderr, "\n");
9256 fflush (stderr);
9257 }
9258 }
9259 else if (INTERACTIVE)
9260 {
9261 /* The frame whose minibuffer we're going to display the message on.
9262 It may be larger than the selected frame, so we need
9263 to use its buffer, not the selected frame's buffer. */
9264 Lisp_Object mini_window;
9265 struct frame *f, *sf = SELECTED_FRAME ();
9266
9267 /* Get the frame containing the minibuffer
9268 that the selected frame is using. */
9269 mini_window = FRAME_MINIBUF_WINDOW (sf);
9270 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
9271
9272 /* A null message buffer means that the frame hasn't really been
9273 initialized yet. Error messages get reported properly by
9274 cmd_error, so this must be just an informative message; toss it. */
9275 if (FRAME_MESSAGE_BUF (f))
9276 {
9277 Lisp_Object args[2], msg;
9278 struct gcpro gcpro1, gcpro2;
9279
9280 args[0] = build_string (m);
9281 args[1] = msg = string;
9282 GCPRO2 (args[0], msg);
9283 gcpro1.nvars = 2;
9284
9285 msg = Fformat (2, args);
9286
9287 if (log)
9288 message3 (msg, SBYTES (msg), STRING_MULTIBYTE (msg));
9289 else
9290 message3_nolog (msg, SBYTES (msg), STRING_MULTIBYTE (msg));
9291
9292 UNGCPRO;
9293
9294 /* Print should start at the beginning of the message
9295 buffer next time. */
9296 message_buf_print = 0;
9297 }
9298 }
9299 }
9300
9301
9302 /* Dump an informative message to the minibuf. If M is 0, clear out
9303 any existing message, and let the mini-buffer text show through. */
9304
9305 static void
9306 vmessage (const char *m, va_list ap)
9307 {
9308 if (noninteractive)
9309 {
9310 if (m)
9311 {
9312 if (noninteractive_need_newline)
9313 putc ('\n', stderr);
9314 noninteractive_need_newline = 0;
9315 vfprintf (stderr, m, ap);
9316 if (cursor_in_echo_area == 0)
9317 fprintf (stderr, "\n");
9318 fflush (stderr);
9319 }
9320 }
9321 else if (INTERACTIVE)
9322 {
9323 /* The frame whose mini-buffer we're going to display the message
9324 on. It may be larger than the selected frame, so we need to
9325 use its buffer, not the selected frame's buffer. */
9326 Lisp_Object mini_window;
9327 struct frame *f, *sf = SELECTED_FRAME ();
9328
9329 /* Get the frame containing the mini-buffer
9330 that the selected frame is using. */
9331 mini_window = FRAME_MINIBUF_WINDOW (sf);
9332 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
9333
9334 /* A null message buffer means that the frame hasn't really been
9335 initialized yet. Error messages get reported properly by
9336 cmd_error, so this must be just an informative message; toss
9337 it. */
9338 if (FRAME_MESSAGE_BUF (f))
9339 {
9340 if (m)
9341 {
9342 ptrdiff_t len;
9343
9344 len = doprnt (FRAME_MESSAGE_BUF (f),
9345 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, ap);
9346
9347 message2 (FRAME_MESSAGE_BUF (f), len, 0);
9348 }
9349 else
9350 message1 (0);
9351
9352 /* Print should start at the beginning of the message
9353 buffer next time. */
9354 message_buf_print = 0;
9355 }
9356 }
9357 }
9358
9359 void
9360 message (const char *m, ...)
9361 {
9362 va_list ap;
9363 va_start (ap, m);
9364 vmessage (m, ap);
9365 va_end (ap);
9366 }
9367
9368
9369 #if 0
9370 /* The non-logging version of message. */
9371
9372 void
9373 message_nolog (const char *m, ...)
9374 {
9375 Lisp_Object old_log_max;
9376 va_list ap;
9377 va_start (ap, m);
9378 old_log_max = Vmessage_log_max;
9379 Vmessage_log_max = Qnil;
9380 vmessage (m, ap);
9381 Vmessage_log_max = old_log_max;
9382 va_end (ap);
9383 }
9384 #endif
9385
9386
9387 /* Display the current message in the current mini-buffer. This is
9388 only called from error handlers in process.c, and is not time
9389 critical. */
9390
9391 void
9392 update_echo_area (void)
9393 {
9394 if (!NILP (echo_area_buffer[0]))
9395 {
9396 Lisp_Object string;
9397 string = Fcurrent_message ();
9398 message3 (string, SBYTES (string),
9399 !NILP (BVAR (current_buffer, enable_multibyte_characters)));
9400 }
9401 }
9402
9403
9404 /* Make sure echo area buffers in `echo_buffers' are live.
9405 If they aren't, make new ones. */
9406
9407 static void
9408 ensure_echo_area_buffers (void)
9409 {
9410 int i;
9411
9412 for (i = 0; i < 2; ++i)
9413 if (!BUFFERP (echo_buffer[i])
9414 || NILP (BVAR (XBUFFER (echo_buffer[i]), name)))
9415 {
9416 char name[30];
9417 Lisp_Object old_buffer;
9418 int j;
9419
9420 old_buffer = echo_buffer[i];
9421 sprintf (name, " *Echo Area %d*", i);
9422 echo_buffer[i] = Fget_buffer_create (build_string (name));
9423 BVAR (XBUFFER (echo_buffer[i]), truncate_lines) = Qnil;
9424 /* to force word wrap in echo area -
9425 it was decided to postpone this*/
9426 /* XBUFFER (echo_buffer[i])->word_wrap = Qt; */
9427
9428 for (j = 0; j < 2; ++j)
9429 if (EQ (old_buffer, echo_area_buffer[j]))
9430 echo_area_buffer[j] = echo_buffer[i];
9431 }
9432 }
9433
9434
9435 /* Call FN with args A1..A4 with either the current or last displayed
9436 echo_area_buffer as current buffer.
9437
9438 WHICH zero means use the current message buffer
9439 echo_area_buffer[0]. If that is nil, choose a suitable buffer
9440 from echo_buffer[] and clear it.
9441
9442 WHICH > 0 means use echo_area_buffer[1]. If that is nil, choose a
9443 suitable buffer from echo_buffer[] and clear it.
9444
9445 If WHICH < 0, set echo_area_buffer[1] to echo_area_buffer[0], so
9446 that the current message becomes the last displayed one, make
9447 choose a suitable buffer for echo_area_buffer[0], and clear it.
9448
9449 Value is what FN returns. */
9450
9451 static int
9452 with_echo_area_buffer (struct window *w, int which,
9453 int (*fn) (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT),
9454 EMACS_INT a1, Lisp_Object a2, EMACS_INT a3, EMACS_INT a4)
9455 {
9456 Lisp_Object buffer;
9457 int this_one, the_other, clear_buffer_p, rc;
9458 int count = SPECPDL_INDEX ();
9459
9460 /* If buffers aren't live, make new ones. */
9461 ensure_echo_area_buffers ();
9462
9463 clear_buffer_p = 0;
9464
9465 if (which == 0)
9466 this_one = 0, the_other = 1;
9467 else if (which > 0)
9468 this_one = 1, the_other = 0;
9469 else
9470 {
9471 this_one = 0, the_other = 1;
9472 clear_buffer_p = 1;
9473
9474 /* We need a fresh one in case the current echo buffer equals
9475 the one containing the last displayed echo area message. */
9476 if (!NILP (echo_area_buffer[this_one])
9477 && EQ (echo_area_buffer[this_one], echo_area_buffer[the_other]))
9478 echo_area_buffer[this_one] = Qnil;
9479 }
9480
9481 /* Choose a suitable buffer from echo_buffer[] is we don't
9482 have one. */
9483 if (NILP (echo_area_buffer[this_one]))
9484 {
9485 echo_area_buffer[this_one]
9486 = (EQ (echo_area_buffer[the_other], echo_buffer[this_one])
9487 ? echo_buffer[the_other]
9488 : echo_buffer[this_one]);
9489 clear_buffer_p = 1;
9490 }
9491
9492 buffer = echo_area_buffer[this_one];
9493
9494 /* Don't get confused by reusing the buffer used for echoing
9495 for a different purpose. */
9496 if (echo_kboard == NULL && EQ (buffer, echo_message_buffer))
9497 cancel_echoing ();
9498
9499 record_unwind_protect (unwind_with_echo_area_buffer,
9500 with_echo_area_buffer_unwind_data (w));
9501
9502 /* Make the echo area buffer current. Note that for display
9503 purposes, it is not necessary that the displayed window's buffer
9504 == current_buffer, except for text property lookup. So, let's
9505 only set that buffer temporarily here without doing a full
9506 Fset_window_buffer. We must also change w->pointm, though,
9507 because otherwise an assertions in unshow_buffer fails, and Emacs
9508 aborts. */
9509 set_buffer_internal_1 (XBUFFER (buffer));
9510 if (w)
9511 {
9512 w->buffer = buffer;
9513 set_marker_both (w->pointm, buffer, BEG, BEG_BYTE);
9514 }
9515
9516 BVAR (current_buffer, undo_list) = Qt;
9517 BVAR (current_buffer, read_only) = Qnil;
9518 specbind (Qinhibit_read_only, Qt);
9519 specbind (Qinhibit_modification_hooks, Qt);
9520
9521 if (clear_buffer_p && Z > BEG)
9522 del_range (BEG, Z);
9523
9524 xassert (BEGV >= BEG);
9525 xassert (ZV <= Z && ZV >= BEGV);
9526
9527 rc = fn (a1, a2, a3, a4);
9528
9529 xassert (BEGV >= BEG);
9530 xassert (ZV <= Z && ZV >= BEGV);
9531
9532 unbind_to (count, Qnil);
9533 return rc;
9534 }
9535
9536
9537 /* Save state that should be preserved around the call to the function
9538 FN called in with_echo_area_buffer. */
9539
9540 static Lisp_Object
9541 with_echo_area_buffer_unwind_data (struct window *w)
9542 {
9543 int i = 0;
9544 Lisp_Object vector, tmp;
9545
9546 /* Reduce consing by keeping one vector in
9547 Vwith_echo_area_save_vector. */
9548 vector = Vwith_echo_area_save_vector;
9549 Vwith_echo_area_save_vector = Qnil;
9550
9551 if (NILP (vector))
9552 vector = Fmake_vector (make_number (7), Qnil);
9553
9554 XSETBUFFER (tmp, current_buffer); ASET (vector, i, tmp); ++i;
9555 ASET (vector, i, Vdeactivate_mark); ++i;
9556 ASET (vector, i, make_number (windows_or_buffers_changed)); ++i;
9557
9558 if (w)
9559 {
9560 XSETWINDOW (tmp, w); ASET (vector, i, tmp); ++i;
9561 ASET (vector, i, w->buffer); ++i;
9562 ASET (vector, i, make_number (XMARKER (w->pointm)->charpos)); ++i;
9563 ASET (vector, i, make_number (XMARKER (w->pointm)->bytepos)); ++i;
9564 }
9565 else
9566 {
9567 int end = i + 4;
9568 for (; i < end; ++i)
9569 ASET (vector, i, Qnil);
9570 }
9571
9572 xassert (i == ASIZE (vector));
9573 return vector;
9574 }
9575
9576
9577 /* Restore global state from VECTOR which was created by
9578 with_echo_area_buffer_unwind_data. */
9579
9580 static Lisp_Object
9581 unwind_with_echo_area_buffer (Lisp_Object vector)
9582 {
9583 set_buffer_internal_1 (XBUFFER (AREF (vector, 0)));
9584 Vdeactivate_mark = AREF (vector, 1);
9585 windows_or_buffers_changed = XFASTINT (AREF (vector, 2));
9586
9587 if (WINDOWP (AREF (vector, 3)))
9588 {
9589 struct window *w;
9590 Lisp_Object buffer, charpos, bytepos;
9591
9592 w = XWINDOW (AREF (vector, 3));
9593 buffer = AREF (vector, 4);
9594 charpos = AREF (vector, 5);
9595 bytepos = AREF (vector, 6);
9596
9597 w->buffer = buffer;
9598 set_marker_both (w->pointm, buffer,
9599 XFASTINT (charpos), XFASTINT (bytepos));
9600 }
9601
9602 Vwith_echo_area_save_vector = vector;
9603 return Qnil;
9604 }
9605
9606
9607 /* Set up the echo area for use by print functions. MULTIBYTE_P
9608 non-zero means we will print multibyte. */
9609
9610 void
9611 setup_echo_area_for_printing (int multibyte_p)
9612 {
9613 /* If we can't find an echo area any more, exit. */
9614 if (! FRAME_LIVE_P (XFRAME (selected_frame)))
9615 Fkill_emacs (Qnil);
9616
9617 ensure_echo_area_buffers ();
9618
9619 if (!message_buf_print)
9620 {
9621 /* A message has been output since the last time we printed.
9622 Choose a fresh echo area buffer. */
9623 if (EQ (echo_area_buffer[1], echo_buffer[0]))
9624 echo_area_buffer[0] = echo_buffer[1];
9625 else
9626 echo_area_buffer[0] = echo_buffer[0];
9627
9628 /* Switch to that buffer and clear it. */
9629 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
9630 BVAR (current_buffer, truncate_lines) = Qnil;
9631
9632 if (Z > BEG)
9633 {
9634 int count = SPECPDL_INDEX ();
9635 specbind (Qinhibit_read_only, Qt);
9636 /* Note that undo recording is always disabled. */
9637 del_range (BEG, Z);
9638 unbind_to (count, Qnil);
9639 }
9640 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
9641
9642 /* Set up the buffer for the multibyteness we need. */
9643 if (multibyte_p
9644 != !NILP (BVAR (current_buffer, enable_multibyte_characters)))
9645 Fset_buffer_multibyte (multibyte_p ? Qt : Qnil);
9646
9647 /* Raise the frame containing the echo area. */
9648 if (minibuffer_auto_raise)
9649 {
9650 struct frame *sf = SELECTED_FRAME ();
9651 Lisp_Object mini_window;
9652 mini_window = FRAME_MINIBUF_WINDOW (sf);
9653 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
9654 }
9655
9656 message_log_maybe_newline ();
9657 message_buf_print = 1;
9658 }
9659 else
9660 {
9661 if (NILP (echo_area_buffer[0]))
9662 {
9663 if (EQ (echo_area_buffer[1], echo_buffer[0]))
9664 echo_area_buffer[0] = echo_buffer[1];
9665 else
9666 echo_area_buffer[0] = echo_buffer[0];
9667 }
9668
9669 if (current_buffer != XBUFFER (echo_area_buffer[0]))
9670 {
9671 /* Someone switched buffers between print requests. */
9672 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
9673 BVAR (current_buffer, truncate_lines) = Qnil;
9674 }
9675 }
9676 }
9677
9678
9679 /* Display an echo area message in window W. Value is non-zero if W's
9680 height is changed. If display_last_displayed_message_p is
9681 non-zero, display the message that was last displayed, otherwise
9682 display the current message. */
9683
9684 static int
9685 display_echo_area (struct window *w)
9686 {
9687 int i, no_message_p, window_height_changed_p, count;
9688
9689 /* Temporarily disable garbage collections while displaying the echo
9690 area. This is done because a GC can print a message itself.
9691 That message would modify the echo area buffer's contents while a
9692 redisplay of the buffer is going on, and seriously confuse
9693 redisplay. */
9694 count = inhibit_garbage_collection ();
9695
9696 /* If there is no message, we must call display_echo_area_1
9697 nevertheless because it resizes the window. But we will have to
9698 reset the echo_area_buffer in question to nil at the end because
9699 with_echo_area_buffer will sets it to an empty buffer. */
9700 i = display_last_displayed_message_p ? 1 : 0;
9701 no_message_p = NILP (echo_area_buffer[i]);
9702
9703 window_height_changed_p
9704 = with_echo_area_buffer (w, display_last_displayed_message_p,
9705 display_echo_area_1,
9706 (intptr_t) w, Qnil, 0, 0);
9707
9708 if (no_message_p)
9709 echo_area_buffer[i] = Qnil;
9710
9711 unbind_to (count, Qnil);
9712 return window_height_changed_p;
9713 }
9714
9715
9716 /* Helper for display_echo_area. Display the current buffer which
9717 contains the current echo area message in window W, a mini-window,
9718 a pointer to which is passed in A1. A2..A4 are currently not used.
9719 Change the height of W so that all of the message is displayed.
9720 Value is non-zero if height of W was changed. */
9721
9722 static int
9723 display_echo_area_1 (EMACS_INT a1, Lisp_Object a2, EMACS_INT a3, EMACS_INT a4)
9724 {
9725 intptr_t i1 = a1;
9726 struct window *w = (struct window *) i1;
9727 Lisp_Object window;
9728 struct text_pos start;
9729 int window_height_changed_p = 0;
9730
9731 /* Do this before displaying, so that we have a large enough glyph
9732 matrix for the display. If we can't get enough space for the
9733 whole text, display the last N lines. That works by setting w->start. */
9734 window_height_changed_p = resize_mini_window (w, 0);
9735
9736 /* Use the starting position chosen by resize_mini_window. */
9737 SET_TEXT_POS_FROM_MARKER (start, w->start);
9738
9739 /* Display. */
9740 clear_glyph_matrix (w->desired_matrix);
9741 XSETWINDOW (window, w);
9742 try_window (window, start, 0);
9743
9744 return window_height_changed_p;
9745 }
9746
9747
9748 /* Resize the echo area window to exactly the size needed for the
9749 currently displayed message, if there is one. If a mini-buffer
9750 is active, don't shrink it. */
9751
9752 void
9753 resize_echo_area_exactly (void)
9754 {
9755 if (BUFFERP (echo_area_buffer[0])
9756 && WINDOWP (echo_area_window))
9757 {
9758 struct window *w = XWINDOW (echo_area_window);
9759 int resized_p;
9760 Lisp_Object resize_exactly;
9761
9762 if (minibuf_level == 0)
9763 resize_exactly = Qt;
9764 else
9765 resize_exactly = Qnil;
9766
9767 resized_p = with_echo_area_buffer (w, 0, resize_mini_window_1,
9768 (intptr_t) w, resize_exactly,
9769 0, 0);
9770 if (resized_p)
9771 {
9772 ++windows_or_buffers_changed;
9773 ++update_mode_lines;
9774 redisplay_internal ();
9775 }
9776 }
9777 }
9778
9779
9780 /* Callback function for with_echo_area_buffer, when used from
9781 resize_echo_area_exactly. A1 contains a pointer to the window to
9782 resize, EXACTLY non-nil means resize the mini-window exactly to the
9783 size of the text displayed. A3 and A4 are not used. Value is what
9784 resize_mini_window returns. */
9785
9786 static int
9787 resize_mini_window_1 (EMACS_INT a1, Lisp_Object exactly, EMACS_INT a3, EMACS_INT a4)
9788 {
9789 intptr_t i1 = a1;
9790 return resize_mini_window ((struct window *) i1, !NILP (exactly));
9791 }
9792
9793
9794 /* Resize mini-window W to fit the size of its contents. EXACT_P
9795 means size the window exactly to the size needed. Otherwise, it's
9796 only enlarged until W's buffer is empty.
9797
9798 Set W->start to the right place to begin display. If the whole
9799 contents fit, start at the beginning. Otherwise, start so as
9800 to make the end of the contents appear. This is particularly
9801 important for y-or-n-p, but seems desirable generally.
9802
9803 Value is non-zero if the window height has been changed. */
9804
9805 int
9806 resize_mini_window (struct window *w, int exact_p)
9807 {
9808 struct frame *f = XFRAME (w->frame);
9809 int window_height_changed_p = 0;
9810
9811 xassert (MINI_WINDOW_P (w));
9812
9813 /* By default, start display at the beginning. */
9814 set_marker_both (w->start, w->buffer,
9815 BUF_BEGV (XBUFFER (w->buffer)),
9816 BUF_BEGV_BYTE (XBUFFER (w->buffer)));
9817
9818 /* Don't resize windows while redisplaying a window; it would
9819 confuse redisplay functions when the size of the window they are
9820 displaying changes from under them. Such a resizing can happen,
9821 for instance, when which-func prints a long message while
9822 we are running fontification-functions. We're running these
9823 functions with safe_call which binds inhibit-redisplay to t. */
9824 if (!NILP (Vinhibit_redisplay))
9825 return 0;
9826
9827 /* Nil means don't try to resize. */
9828 if (NILP (Vresize_mini_windows)
9829 || (FRAME_X_P (f) && FRAME_X_OUTPUT (f) == NULL))
9830 return 0;
9831
9832 if (!FRAME_MINIBUF_ONLY_P (f))
9833 {
9834 struct it it;
9835 struct window *root = XWINDOW (FRAME_ROOT_WINDOW (f));
9836 int total_height = WINDOW_TOTAL_LINES (root) + WINDOW_TOTAL_LINES (w);
9837 int height, max_height;
9838 int unit = FRAME_LINE_HEIGHT (f);
9839 struct text_pos start;
9840 struct buffer *old_current_buffer = NULL;
9841
9842 if (current_buffer != XBUFFER (w->buffer))
9843 {
9844 old_current_buffer = current_buffer;
9845 set_buffer_internal (XBUFFER (w->buffer));
9846 }
9847
9848 init_iterator (&it, w, BEGV, BEGV_BYTE, NULL, DEFAULT_FACE_ID);
9849
9850 /* Compute the max. number of lines specified by the user. */
9851 if (FLOATP (Vmax_mini_window_height))
9852 max_height = XFLOATINT (Vmax_mini_window_height) * FRAME_LINES (f);
9853 else if (INTEGERP (Vmax_mini_window_height))
9854 max_height = XINT (Vmax_mini_window_height);
9855 else
9856 max_height = total_height / 4;
9857
9858 /* Correct that max. height if it's bogus. */
9859 max_height = max (1, max_height);
9860 max_height = min (total_height, max_height);
9861
9862 /* Find out the height of the text in the window. */
9863 if (it.line_wrap == TRUNCATE)
9864 height = 1;
9865 else
9866 {
9867 last_height = 0;
9868 move_it_to (&it, ZV, -1, -1, -1, MOVE_TO_POS);
9869 if (it.max_ascent == 0 && it.max_descent == 0)
9870 height = it.current_y + last_height;
9871 else
9872 height = it.current_y + it.max_ascent + it.max_descent;
9873 height -= min (it.extra_line_spacing, it.max_extra_line_spacing);
9874 height = (height + unit - 1) / unit;
9875 }
9876
9877 /* Compute a suitable window start. */
9878 if (height > max_height)
9879 {
9880 height = max_height;
9881 init_iterator (&it, w, ZV, ZV_BYTE, NULL, DEFAULT_FACE_ID);
9882 move_it_vertically_backward (&it, (height - 1) * unit);
9883 start = it.current.pos;
9884 }
9885 else
9886 SET_TEXT_POS (start, BEGV, BEGV_BYTE);
9887 SET_MARKER_FROM_TEXT_POS (w->start, start);
9888
9889 if (EQ (Vresize_mini_windows, Qgrow_only))
9890 {
9891 /* Let it grow only, until we display an empty message, in which
9892 case the window shrinks again. */
9893 if (height > WINDOW_TOTAL_LINES (w))
9894 {
9895 int old_height = WINDOW_TOTAL_LINES (w);
9896 freeze_window_starts (f, 1);
9897 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
9898 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
9899 }
9900 else if (height < WINDOW_TOTAL_LINES (w)
9901 && (exact_p || BEGV == ZV))
9902 {
9903 int old_height = WINDOW_TOTAL_LINES (w);
9904 freeze_window_starts (f, 0);
9905 shrink_mini_window (w);
9906 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
9907 }
9908 }
9909 else
9910 {
9911 /* Always resize to exact size needed. */
9912 if (height > WINDOW_TOTAL_LINES (w))
9913 {
9914 int old_height = WINDOW_TOTAL_LINES (w);
9915 freeze_window_starts (f, 1);
9916 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
9917 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
9918 }
9919 else if (height < WINDOW_TOTAL_LINES (w))
9920 {
9921 int old_height = WINDOW_TOTAL_LINES (w);
9922 freeze_window_starts (f, 0);
9923 shrink_mini_window (w);
9924
9925 if (height)
9926 {
9927 freeze_window_starts (f, 1);
9928 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
9929 }
9930
9931 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
9932 }
9933 }
9934
9935 if (old_current_buffer)
9936 set_buffer_internal (old_current_buffer);
9937 }
9938
9939 return window_height_changed_p;
9940 }
9941
9942
9943 /* Value is the current message, a string, or nil if there is no
9944 current message. */
9945
9946 Lisp_Object
9947 current_message (void)
9948 {
9949 Lisp_Object msg;
9950
9951 if (!BUFFERP (echo_area_buffer[0]))
9952 msg = Qnil;
9953 else
9954 {
9955 with_echo_area_buffer (0, 0, current_message_1,
9956 (intptr_t) &msg, Qnil, 0, 0);
9957 if (NILP (msg))
9958 echo_area_buffer[0] = Qnil;
9959 }
9960
9961 return msg;
9962 }
9963
9964
9965 static int
9966 current_message_1 (EMACS_INT a1, Lisp_Object a2, EMACS_INT a3, EMACS_INT a4)
9967 {
9968 intptr_t i1 = a1;
9969 Lisp_Object *msg = (Lisp_Object *) i1;
9970
9971 if (Z > BEG)
9972 *msg = make_buffer_string (BEG, Z, 1);
9973 else
9974 *msg = Qnil;
9975 return 0;
9976 }
9977
9978
9979 /* Push the current message on Vmessage_stack for later restauration
9980 by restore_message. Value is non-zero if the current message isn't
9981 empty. This is a relatively infrequent operation, so it's not
9982 worth optimizing. */
9983
9984 int
9985 push_message (void)
9986 {
9987 Lisp_Object msg;
9988 msg = current_message ();
9989 Vmessage_stack = Fcons (msg, Vmessage_stack);
9990 return STRINGP (msg);
9991 }
9992
9993
9994 /* Restore message display from the top of Vmessage_stack. */
9995
9996 void
9997 restore_message (void)
9998 {
9999 Lisp_Object msg;
10000
10001 xassert (CONSP (Vmessage_stack));
10002 msg = XCAR (Vmessage_stack);
10003 if (STRINGP (msg))
10004 message3_nolog (msg, SBYTES (msg), STRING_MULTIBYTE (msg));
10005 else
10006 message3_nolog (msg, 0, 0);
10007 }
10008
10009
10010 /* Handler for record_unwind_protect calling pop_message. */
10011
10012 Lisp_Object
10013 pop_message_unwind (Lisp_Object dummy)
10014 {
10015 pop_message ();
10016 return Qnil;
10017 }
10018
10019 /* Pop the top-most entry off Vmessage_stack. */
10020
10021 static void
10022 pop_message (void)
10023 {
10024 xassert (CONSP (Vmessage_stack));
10025 Vmessage_stack = XCDR (Vmessage_stack);
10026 }
10027
10028
10029 /* Check that Vmessage_stack is nil. Called from emacs.c when Emacs
10030 exits. If the stack is not empty, we have a missing pop_message
10031 somewhere. */
10032
10033 void
10034 check_message_stack (void)
10035 {
10036 if (!NILP (Vmessage_stack))
10037 abort ();
10038 }
10039
10040
10041 /* Truncate to NCHARS what will be displayed in the echo area the next
10042 time we display it---but don't redisplay it now. */
10043
10044 void
10045 truncate_echo_area (EMACS_INT nchars)
10046 {
10047 if (nchars == 0)
10048 echo_area_buffer[0] = Qnil;
10049 /* A null message buffer means that the frame hasn't really been
10050 initialized yet. Error messages get reported properly by
10051 cmd_error, so this must be just an informative message; toss it. */
10052 else if (!noninteractive
10053 && INTERACTIVE
10054 && !NILP (echo_area_buffer[0]))
10055 {
10056 struct frame *sf = SELECTED_FRAME ();
10057 if (FRAME_MESSAGE_BUF (sf))
10058 with_echo_area_buffer (0, 0, truncate_message_1, nchars, Qnil, 0, 0);
10059 }
10060 }
10061
10062
10063 /* Helper function for truncate_echo_area. Truncate the current
10064 message to at most NCHARS characters. */
10065
10066 static int
10067 truncate_message_1 (EMACS_INT nchars, Lisp_Object a2, EMACS_INT a3, EMACS_INT a4)
10068 {
10069 if (BEG + nchars < Z)
10070 del_range (BEG + nchars, Z);
10071 if (Z == BEG)
10072 echo_area_buffer[0] = Qnil;
10073 return 0;
10074 }
10075
10076
10077 /* Set the current message to a substring of S or STRING.
10078
10079 If STRING is a Lisp string, set the message to the first NBYTES
10080 bytes from STRING. NBYTES zero means use the whole string. If
10081 STRING is multibyte, the message will be displayed multibyte.
10082
10083 If S is not null, set the message to the first LEN bytes of S. LEN
10084 zero means use the whole string. MULTIBYTE_P non-zero means S is
10085 multibyte. Display the message multibyte in that case.
10086
10087 Doesn't GC, as with_echo_area_buffer binds Qinhibit_modification_hooks
10088 to t before calling set_message_1 (which calls insert).
10089 */
10090
10091 static void
10092 set_message (const char *s, Lisp_Object string,
10093 EMACS_INT nbytes, int multibyte_p)
10094 {
10095 message_enable_multibyte
10096 = ((s && multibyte_p)
10097 || (STRINGP (string) && STRING_MULTIBYTE (string)));
10098
10099 with_echo_area_buffer (0, -1, set_message_1,
10100 (intptr_t) s, string, nbytes, multibyte_p);
10101 message_buf_print = 0;
10102 help_echo_showing_p = 0;
10103 }
10104
10105
10106 /* Helper function for set_message. Arguments have the same meaning
10107 as there, with A1 corresponding to S and A2 corresponding to STRING
10108 This function is called with the echo area buffer being
10109 current. */
10110
10111 static int
10112 set_message_1 (EMACS_INT a1, Lisp_Object a2, EMACS_INT nbytes, EMACS_INT multibyte_p)
10113 {
10114 intptr_t i1 = a1;
10115 const char *s = (const char *) i1;
10116 const unsigned char *msg = (const unsigned char *) s;
10117 Lisp_Object string = a2;
10118
10119 /* Change multibyteness of the echo buffer appropriately. */
10120 if (message_enable_multibyte
10121 != !NILP (BVAR (current_buffer, enable_multibyte_characters)))
10122 Fset_buffer_multibyte (message_enable_multibyte ? Qt : Qnil);
10123
10124 BVAR (current_buffer, truncate_lines) = message_truncate_lines ? Qt : Qnil;
10125 if (!NILP (BVAR (current_buffer, bidi_display_reordering)))
10126 BVAR (current_buffer, bidi_paragraph_direction) = Qleft_to_right;
10127
10128 /* Insert new message at BEG. */
10129 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
10130
10131 if (STRINGP (string))
10132 {
10133 EMACS_INT nchars;
10134
10135 if (nbytes == 0)
10136 nbytes = SBYTES (string);
10137 nchars = string_byte_to_char (string, nbytes);
10138
10139 /* This function takes care of single/multibyte conversion. We
10140 just have to ensure that the echo area buffer has the right
10141 setting of enable_multibyte_characters. */
10142 insert_from_string (string, 0, 0, nchars, nbytes, 1);
10143 }
10144 else if (s)
10145 {
10146 if (nbytes == 0)
10147 nbytes = strlen (s);
10148
10149 if (multibyte_p && NILP (BVAR (current_buffer, enable_multibyte_characters)))
10150 {
10151 /* Convert from multi-byte to single-byte. */
10152 EMACS_INT i;
10153 int c, n;
10154 char work[1];
10155
10156 /* Convert a multibyte string to single-byte. */
10157 for (i = 0; i < nbytes; i += n)
10158 {
10159 c = string_char_and_length (msg + i, &n);
10160 work[0] = (ASCII_CHAR_P (c)
10161 ? c
10162 : multibyte_char_to_unibyte (c));
10163 insert_1_both (work, 1, 1, 1, 0, 0);
10164 }
10165 }
10166 else if (!multibyte_p
10167 && !NILP (BVAR (current_buffer, enable_multibyte_characters)))
10168 {
10169 /* Convert from single-byte to multi-byte. */
10170 EMACS_INT i;
10171 int c, n;
10172 unsigned char str[MAX_MULTIBYTE_LENGTH];
10173
10174 /* Convert a single-byte string to multibyte. */
10175 for (i = 0; i < nbytes; i++)
10176 {
10177 c = msg[i];
10178 MAKE_CHAR_MULTIBYTE (c);
10179 n = CHAR_STRING (c, str);
10180 insert_1_both ((char *) str, 1, n, 1, 0, 0);
10181 }
10182 }
10183 else
10184 insert_1 (s, nbytes, 1, 0, 0);
10185 }
10186
10187 return 0;
10188 }
10189
10190
10191 /* Clear messages. CURRENT_P non-zero means clear the current
10192 message. LAST_DISPLAYED_P non-zero means clear the message
10193 last displayed. */
10194
10195 void
10196 clear_message (int current_p, int last_displayed_p)
10197 {
10198 if (current_p)
10199 {
10200 echo_area_buffer[0] = Qnil;
10201 message_cleared_p = 1;
10202 }
10203
10204 if (last_displayed_p)
10205 echo_area_buffer[1] = Qnil;
10206
10207 message_buf_print = 0;
10208 }
10209
10210 /* Clear garbaged frames.
10211
10212 This function is used where the old redisplay called
10213 redraw_garbaged_frames which in turn called redraw_frame which in
10214 turn called clear_frame. The call to clear_frame was a source of
10215 flickering. I believe a clear_frame is not necessary. It should
10216 suffice in the new redisplay to invalidate all current matrices,
10217 and ensure a complete redisplay of all windows. */
10218
10219 static void
10220 clear_garbaged_frames (void)
10221 {
10222 if (frame_garbaged)
10223 {
10224 Lisp_Object tail, frame;
10225 int changed_count = 0;
10226
10227 FOR_EACH_FRAME (tail, frame)
10228 {
10229 struct frame *f = XFRAME (frame);
10230
10231 if (FRAME_VISIBLE_P (f) && FRAME_GARBAGED_P (f))
10232 {
10233 if (f->resized_p)
10234 {
10235 Fredraw_frame (frame);
10236 f->force_flush_display_p = 1;
10237 }
10238 clear_current_matrices (f);
10239 changed_count++;
10240 f->garbaged = 0;
10241 f->resized_p = 0;
10242 }
10243 }
10244
10245 frame_garbaged = 0;
10246 if (changed_count)
10247 ++windows_or_buffers_changed;
10248 }
10249 }
10250
10251
10252 /* Redisplay the echo area of the selected frame. If UPDATE_FRAME_P
10253 is non-zero update selected_frame. Value is non-zero if the
10254 mini-windows height has been changed. */
10255
10256 static int
10257 echo_area_display (int update_frame_p)
10258 {
10259 Lisp_Object mini_window;
10260 struct window *w;
10261 struct frame *f;
10262 int window_height_changed_p = 0;
10263 struct frame *sf = SELECTED_FRAME ();
10264
10265 mini_window = FRAME_MINIBUF_WINDOW (sf);
10266 w = XWINDOW (mini_window);
10267 f = XFRAME (WINDOW_FRAME (w));
10268
10269 /* Don't display if frame is invisible or not yet initialized. */
10270 if (!FRAME_VISIBLE_P (f) || !f->glyphs_initialized_p)
10271 return 0;
10272
10273 #ifdef HAVE_WINDOW_SYSTEM
10274 /* When Emacs starts, selected_frame may be the initial terminal
10275 frame. If we let this through, a message would be displayed on
10276 the terminal. */
10277 if (FRAME_INITIAL_P (XFRAME (selected_frame)))
10278 return 0;
10279 #endif /* HAVE_WINDOW_SYSTEM */
10280
10281 /* Redraw garbaged frames. */
10282 if (frame_garbaged)
10283 clear_garbaged_frames ();
10284
10285 if (!NILP (echo_area_buffer[0]) || minibuf_level == 0)
10286 {
10287 echo_area_window = mini_window;
10288 window_height_changed_p = display_echo_area (w);
10289 w->must_be_updated_p = 1;
10290
10291 /* Update the display, unless called from redisplay_internal.
10292 Also don't update the screen during redisplay itself. The
10293 update will happen at the end of redisplay, and an update
10294 here could cause confusion. */
10295 if (update_frame_p && !redisplaying_p)
10296 {
10297 int n = 0;
10298
10299 /* If the display update has been interrupted by pending
10300 input, update mode lines in the frame. Due to the
10301 pending input, it might have been that redisplay hasn't
10302 been called, so that mode lines above the echo area are
10303 garbaged. This looks odd, so we prevent it here. */
10304 if (!display_completed)
10305 n = redisplay_mode_lines (FRAME_ROOT_WINDOW (f), 0);
10306
10307 if (window_height_changed_p
10308 /* Don't do this if Emacs is shutting down. Redisplay
10309 needs to run hooks. */
10310 && !NILP (Vrun_hooks))
10311 {
10312 /* Must update other windows. Likewise as in other
10313 cases, don't let this update be interrupted by
10314 pending input. */
10315 int count = SPECPDL_INDEX ();
10316 specbind (Qredisplay_dont_pause, Qt);
10317 windows_or_buffers_changed = 1;
10318 redisplay_internal ();
10319 unbind_to (count, Qnil);
10320 }
10321 else if (FRAME_WINDOW_P (f) && n == 0)
10322 {
10323 /* Window configuration is the same as before.
10324 Can do with a display update of the echo area,
10325 unless we displayed some mode lines. */
10326 update_single_window (w, 1);
10327 FRAME_RIF (f)->flush_display (f);
10328 }
10329 else
10330 update_frame (f, 1, 1);
10331
10332 /* If cursor is in the echo area, make sure that the next
10333 redisplay displays the minibuffer, so that the cursor will
10334 be replaced with what the minibuffer wants. */
10335 if (cursor_in_echo_area)
10336 ++windows_or_buffers_changed;
10337 }
10338 }
10339 else if (!EQ (mini_window, selected_window))
10340 windows_or_buffers_changed++;
10341
10342 /* Last displayed message is now the current message. */
10343 echo_area_buffer[1] = echo_area_buffer[0];
10344 /* Inform read_char that we're not echoing. */
10345 echo_message_buffer = Qnil;
10346
10347 /* Prevent redisplay optimization in redisplay_internal by resetting
10348 this_line_start_pos. This is done because the mini-buffer now
10349 displays the message instead of its buffer text. */
10350 if (EQ (mini_window, selected_window))
10351 CHARPOS (this_line_start_pos) = 0;
10352
10353 return window_height_changed_p;
10354 }
10355
10356
10357 \f
10358 /***********************************************************************
10359 Mode Lines and Frame Titles
10360 ***********************************************************************/
10361
10362 /* A buffer for constructing non-propertized mode-line strings and
10363 frame titles in it; allocated from the heap in init_xdisp and
10364 resized as needed in store_mode_line_noprop_char. */
10365
10366 static char *mode_line_noprop_buf;
10367
10368 /* The buffer's end, and a current output position in it. */
10369
10370 static char *mode_line_noprop_buf_end;
10371 static char *mode_line_noprop_ptr;
10372
10373 #define MODE_LINE_NOPROP_LEN(start) \
10374 ((mode_line_noprop_ptr - mode_line_noprop_buf) - start)
10375
10376 static enum {
10377 MODE_LINE_DISPLAY = 0,
10378 MODE_LINE_TITLE,
10379 MODE_LINE_NOPROP,
10380 MODE_LINE_STRING
10381 } mode_line_target;
10382
10383 /* Alist that caches the results of :propertize.
10384 Each element is (PROPERTIZED-STRING . PROPERTY-LIST). */
10385 static Lisp_Object mode_line_proptrans_alist;
10386
10387 /* List of strings making up the mode-line. */
10388 static Lisp_Object mode_line_string_list;
10389
10390 /* Base face property when building propertized mode line string. */
10391 static Lisp_Object mode_line_string_face;
10392 static Lisp_Object mode_line_string_face_prop;
10393
10394
10395 /* Unwind data for mode line strings */
10396
10397 static Lisp_Object Vmode_line_unwind_vector;
10398
10399 static Lisp_Object
10400 format_mode_line_unwind_data (struct buffer *obuf,
10401 Lisp_Object owin,
10402 int save_proptrans)
10403 {
10404 Lisp_Object vector, tmp;
10405
10406 /* Reduce consing by keeping one vector in
10407 Vwith_echo_area_save_vector. */
10408 vector = Vmode_line_unwind_vector;
10409 Vmode_line_unwind_vector = Qnil;
10410
10411 if (NILP (vector))
10412 vector = Fmake_vector (make_number (8), Qnil);
10413
10414 ASET (vector, 0, make_number (mode_line_target));
10415 ASET (vector, 1, make_number (MODE_LINE_NOPROP_LEN (0)));
10416 ASET (vector, 2, mode_line_string_list);
10417 ASET (vector, 3, save_proptrans ? mode_line_proptrans_alist : Qt);
10418 ASET (vector, 4, mode_line_string_face);
10419 ASET (vector, 5, mode_line_string_face_prop);
10420
10421 if (obuf)
10422 XSETBUFFER (tmp, obuf);
10423 else
10424 tmp = Qnil;
10425 ASET (vector, 6, tmp);
10426 ASET (vector, 7, owin);
10427
10428 return vector;
10429 }
10430
10431 static Lisp_Object
10432 unwind_format_mode_line (Lisp_Object vector)
10433 {
10434 mode_line_target = XINT (AREF (vector, 0));
10435 mode_line_noprop_ptr = mode_line_noprop_buf + XINT (AREF (vector, 1));
10436 mode_line_string_list = AREF (vector, 2);
10437 if (! EQ (AREF (vector, 3), Qt))
10438 mode_line_proptrans_alist = AREF (vector, 3);
10439 mode_line_string_face = AREF (vector, 4);
10440 mode_line_string_face_prop = AREF (vector, 5);
10441
10442 if (!NILP (AREF (vector, 7)))
10443 /* Select window before buffer, since it may change the buffer. */
10444 Fselect_window (AREF (vector, 7), Qt);
10445
10446 if (!NILP (AREF (vector, 6)))
10447 {
10448 set_buffer_internal_1 (XBUFFER (AREF (vector, 6)));
10449 ASET (vector, 6, Qnil);
10450 }
10451
10452 Vmode_line_unwind_vector = vector;
10453 return Qnil;
10454 }
10455
10456
10457 /* Store a single character C for the frame title in mode_line_noprop_buf.
10458 Re-allocate mode_line_noprop_buf if necessary. */
10459
10460 static void
10461 store_mode_line_noprop_char (char c)
10462 {
10463 /* If output position has reached the end of the allocated buffer,
10464 increase the buffer's size. */
10465 if (mode_line_noprop_ptr == mode_line_noprop_buf_end)
10466 {
10467 ptrdiff_t len = MODE_LINE_NOPROP_LEN (0);
10468 ptrdiff_t size = len;
10469 mode_line_noprop_buf =
10470 xpalloc (mode_line_noprop_buf, &size, 1, STRING_BYTES_BOUND, 1);
10471 mode_line_noprop_buf_end = mode_line_noprop_buf + size;
10472 mode_line_noprop_ptr = mode_line_noprop_buf + len;
10473 }
10474
10475 *mode_line_noprop_ptr++ = c;
10476 }
10477
10478
10479 /* Store part of a frame title in mode_line_noprop_buf, beginning at
10480 mode_line_noprop_ptr. STRING is the string to store. Do not copy
10481 characters that yield more columns than PRECISION; PRECISION <= 0
10482 means copy the whole string. Pad with spaces until FIELD_WIDTH
10483 number of characters have been copied; FIELD_WIDTH <= 0 means don't
10484 pad. Called from display_mode_element when it is used to build a
10485 frame title. */
10486
10487 static int
10488 store_mode_line_noprop (const char *string, int field_width, int precision)
10489 {
10490 const unsigned char *str = (const unsigned char *) string;
10491 int n = 0;
10492 EMACS_INT dummy, nbytes;
10493
10494 /* Copy at most PRECISION chars from STR. */
10495 nbytes = strlen (string);
10496 n += c_string_width (str, nbytes, precision, &dummy, &nbytes);
10497 while (nbytes--)
10498 store_mode_line_noprop_char (*str++);
10499
10500 /* Fill up with spaces until FIELD_WIDTH reached. */
10501 while (field_width > 0
10502 && n < field_width)
10503 {
10504 store_mode_line_noprop_char (' ');
10505 ++n;
10506 }
10507
10508 return n;
10509 }
10510
10511 /***********************************************************************
10512 Frame Titles
10513 ***********************************************************************/
10514
10515 #ifdef HAVE_WINDOW_SYSTEM
10516
10517 /* Set the title of FRAME, if it has changed. The title format is
10518 Vicon_title_format if FRAME is iconified, otherwise it is
10519 frame_title_format. */
10520
10521 static void
10522 x_consider_frame_title (Lisp_Object frame)
10523 {
10524 struct frame *f = XFRAME (frame);
10525
10526 if (FRAME_WINDOW_P (f)
10527 || FRAME_MINIBUF_ONLY_P (f)
10528 || f->explicit_name)
10529 {
10530 /* Do we have more than one visible frame on this X display? */
10531 Lisp_Object tail;
10532 Lisp_Object fmt;
10533 ptrdiff_t title_start;
10534 char *title;
10535 ptrdiff_t len;
10536 struct it it;
10537 int count = SPECPDL_INDEX ();
10538
10539 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
10540 {
10541 Lisp_Object other_frame = XCAR (tail);
10542 struct frame *tf = XFRAME (other_frame);
10543
10544 if (tf != f
10545 && FRAME_KBOARD (tf) == FRAME_KBOARD (f)
10546 && !FRAME_MINIBUF_ONLY_P (tf)
10547 && !EQ (other_frame, tip_frame)
10548 && (FRAME_VISIBLE_P (tf) || FRAME_ICONIFIED_P (tf)))
10549 break;
10550 }
10551
10552 /* Set global variable indicating that multiple frames exist. */
10553 multiple_frames = CONSP (tail);
10554
10555 /* Switch to the buffer of selected window of the frame. Set up
10556 mode_line_target so that display_mode_element will output into
10557 mode_line_noprop_buf; then display the title. */
10558 record_unwind_protect (unwind_format_mode_line,
10559 format_mode_line_unwind_data
10560 (current_buffer, selected_window, 0));
10561
10562 Fselect_window (f->selected_window, Qt);
10563 set_buffer_internal_1 (XBUFFER (XWINDOW (f->selected_window)->buffer));
10564 fmt = FRAME_ICONIFIED_P (f) ? Vicon_title_format : Vframe_title_format;
10565
10566 mode_line_target = MODE_LINE_TITLE;
10567 title_start = MODE_LINE_NOPROP_LEN (0);
10568 init_iterator (&it, XWINDOW (f->selected_window), -1, -1,
10569 NULL, DEFAULT_FACE_ID);
10570 display_mode_element (&it, 0, -1, -1, fmt, Qnil, 0);
10571 len = MODE_LINE_NOPROP_LEN (title_start);
10572 title = mode_line_noprop_buf + title_start;
10573 unbind_to (count, Qnil);
10574
10575 /* Set the title only if it's changed. This avoids consing in
10576 the common case where it hasn't. (If it turns out that we've
10577 already wasted too much time by walking through the list with
10578 display_mode_element, then we might need to optimize at a
10579 higher level than this.) */
10580 if (! STRINGP (f->name)
10581 || SBYTES (f->name) != len
10582 || memcmp (title, SDATA (f->name), len) != 0)
10583 x_implicitly_set_name (f, make_string (title, len), Qnil);
10584 }
10585 }
10586
10587 #endif /* not HAVE_WINDOW_SYSTEM */
10588
10589
10590
10591 \f
10592 /***********************************************************************
10593 Menu Bars
10594 ***********************************************************************/
10595
10596
10597 /* Prepare for redisplay by updating menu-bar item lists when
10598 appropriate. This can call eval. */
10599
10600 void
10601 prepare_menu_bars (void)
10602 {
10603 int all_windows;
10604 struct gcpro gcpro1, gcpro2;
10605 struct frame *f;
10606 Lisp_Object tooltip_frame;
10607
10608 #ifdef HAVE_WINDOW_SYSTEM
10609 tooltip_frame = tip_frame;
10610 #else
10611 tooltip_frame = Qnil;
10612 #endif
10613
10614 /* Update all frame titles based on their buffer names, etc. We do
10615 this before the menu bars so that the buffer-menu will show the
10616 up-to-date frame titles. */
10617 #ifdef HAVE_WINDOW_SYSTEM
10618 if (windows_or_buffers_changed || update_mode_lines)
10619 {
10620 Lisp_Object tail, frame;
10621
10622 FOR_EACH_FRAME (tail, frame)
10623 {
10624 f = XFRAME (frame);
10625 if (!EQ (frame, tooltip_frame)
10626 && (FRAME_VISIBLE_P (f) || FRAME_ICONIFIED_P (f)))
10627 x_consider_frame_title (frame);
10628 }
10629 }
10630 #endif /* HAVE_WINDOW_SYSTEM */
10631
10632 /* Update the menu bar item lists, if appropriate. This has to be
10633 done before any actual redisplay or generation of display lines. */
10634 all_windows = (update_mode_lines
10635 || buffer_shared > 1
10636 || windows_or_buffers_changed);
10637 if (all_windows)
10638 {
10639 Lisp_Object tail, frame;
10640 int count = SPECPDL_INDEX ();
10641 /* 1 means that update_menu_bar has run its hooks
10642 so any further calls to update_menu_bar shouldn't do so again. */
10643 int menu_bar_hooks_run = 0;
10644
10645 record_unwind_save_match_data ();
10646
10647 FOR_EACH_FRAME (tail, frame)
10648 {
10649 f = XFRAME (frame);
10650
10651 /* Ignore tooltip frame. */
10652 if (EQ (frame, tooltip_frame))
10653 continue;
10654
10655 /* If a window on this frame changed size, report that to
10656 the user and clear the size-change flag. */
10657 if (FRAME_WINDOW_SIZES_CHANGED (f))
10658 {
10659 Lisp_Object functions;
10660
10661 /* Clear flag first in case we get an error below. */
10662 FRAME_WINDOW_SIZES_CHANGED (f) = 0;
10663 functions = Vwindow_size_change_functions;
10664 GCPRO2 (tail, functions);
10665
10666 while (CONSP (functions))
10667 {
10668 if (!EQ (XCAR (functions), Qt))
10669 call1 (XCAR (functions), frame);
10670 functions = XCDR (functions);
10671 }
10672 UNGCPRO;
10673 }
10674
10675 GCPRO1 (tail);
10676 menu_bar_hooks_run = update_menu_bar (f, 0, menu_bar_hooks_run);
10677 #ifdef HAVE_WINDOW_SYSTEM
10678 update_tool_bar (f, 0);
10679 #endif
10680 #ifdef HAVE_NS
10681 if (windows_or_buffers_changed
10682 && FRAME_NS_P (f))
10683 ns_set_doc_edited (f, Fbuffer_modified_p
10684 (XWINDOW (f->selected_window)->buffer));
10685 #endif
10686 UNGCPRO;
10687 }
10688
10689 unbind_to (count, Qnil);
10690 }
10691 else
10692 {
10693 struct frame *sf = SELECTED_FRAME ();
10694 update_menu_bar (sf, 1, 0);
10695 #ifdef HAVE_WINDOW_SYSTEM
10696 update_tool_bar (sf, 1);
10697 #endif
10698 }
10699 }
10700
10701
10702 /* Update the menu bar item list for frame F. This has to be done
10703 before we start to fill in any display lines, because it can call
10704 eval.
10705
10706 If SAVE_MATCH_DATA is non-zero, we must save and restore it here.
10707
10708 If HOOKS_RUN is 1, that means a previous call to update_menu_bar
10709 already ran the menu bar hooks for this redisplay, so there
10710 is no need to run them again. The return value is the
10711 updated value of this flag, to pass to the next call. */
10712
10713 static int
10714 update_menu_bar (struct frame *f, int save_match_data, int hooks_run)
10715 {
10716 Lisp_Object window;
10717 register struct window *w;
10718
10719 /* If called recursively during a menu update, do nothing. This can
10720 happen when, for instance, an activate-menubar-hook causes a
10721 redisplay. */
10722 if (inhibit_menubar_update)
10723 return hooks_run;
10724
10725 window = FRAME_SELECTED_WINDOW (f);
10726 w = XWINDOW (window);
10727
10728 if (FRAME_WINDOW_P (f)
10729 ?
10730 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
10731 || defined (HAVE_NS) || defined (USE_GTK)
10732 FRAME_EXTERNAL_MENU_BAR (f)
10733 #else
10734 FRAME_MENU_BAR_LINES (f) > 0
10735 #endif
10736 : FRAME_MENU_BAR_LINES (f) > 0)
10737 {
10738 /* If the user has switched buffers or windows, we need to
10739 recompute to reflect the new bindings. But we'll
10740 recompute when update_mode_lines is set too; that means
10741 that people can use force-mode-line-update to request
10742 that the menu bar be recomputed. The adverse effect on
10743 the rest of the redisplay algorithm is about the same as
10744 windows_or_buffers_changed anyway. */
10745 if (windows_or_buffers_changed
10746 /* This used to test w->update_mode_line, but we believe
10747 there is no need to recompute the menu in that case. */
10748 || update_mode_lines
10749 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
10750 < BUF_MODIFF (XBUFFER (w->buffer)))
10751 != !NILP (w->last_had_star))
10752 || ((!NILP (Vtransient_mark_mode)
10753 && !NILP (BVAR (XBUFFER (w->buffer), mark_active)))
10754 != !NILP (w->region_showing)))
10755 {
10756 struct buffer *prev = current_buffer;
10757 int count = SPECPDL_INDEX ();
10758
10759 specbind (Qinhibit_menubar_update, Qt);
10760
10761 set_buffer_internal_1 (XBUFFER (w->buffer));
10762 if (save_match_data)
10763 record_unwind_save_match_data ();
10764 if (NILP (Voverriding_local_map_menu_flag))
10765 {
10766 specbind (Qoverriding_terminal_local_map, Qnil);
10767 specbind (Qoverriding_local_map, Qnil);
10768 }
10769
10770 if (!hooks_run)
10771 {
10772 /* Run the Lucid hook. */
10773 safe_run_hooks (Qactivate_menubar_hook);
10774
10775 /* If it has changed current-menubar from previous value,
10776 really recompute the menu-bar from the value. */
10777 if (! NILP (Vlucid_menu_bar_dirty_flag))
10778 call0 (Qrecompute_lucid_menubar);
10779
10780 safe_run_hooks (Qmenu_bar_update_hook);
10781
10782 hooks_run = 1;
10783 }
10784
10785 XSETFRAME (Vmenu_updating_frame, f);
10786 FRAME_MENU_BAR_ITEMS (f) = menu_bar_items (FRAME_MENU_BAR_ITEMS (f));
10787
10788 /* Redisplay the menu bar in case we changed it. */
10789 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
10790 || defined (HAVE_NS) || defined (USE_GTK)
10791 if (FRAME_WINDOW_P (f))
10792 {
10793 #if defined (HAVE_NS)
10794 /* All frames on Mac OS share the same menubar. So only
10795 the selected frame should be allowed to set it. */
10796 if (f == SELECTED_FRAME ())
10797 #endif
10798 set_frame_menubar (f, 0, 0);
10799 }
10800 else
10801 /* On a terminal screen, the menu bar is an ordinary screen
10802 line, and this makes it get updated. */
10803 w->update_mode_line = Qt;
10804 #else /* ! (USE_X_TOOLKIT || HAVE_NTGUI || HAVE_NS || USE_GTK) */
10805 /* In the non-toolkit version, the menu bar is an ordinary screen
10806 line, and this makes it get updated. */
10807 w->update_mode_line = Qt;
10808 #endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI || HAVE_NS || USE_GTK) */
10809
10810 unbind_to (count, Qnil);
10811 set_buffer_internal_1 (prev);
10812 }
10813 }
10814
10815 return hooks_run;
10816 }
10817
10818
10819 \f
10820 /***********************************************************************
10821 Output Cursor
10822 ***********************************************************************/
10823
10824 #ifdef HAVE_WINDOW_SYSTEM
10825
10826 /* EXPORT:
10827 Nominal cursor position -- where to draw output.
10828 HPOS and VPOS are window relative glyph matrix coordinates.
10829 X and Y are window relative pixel coordinates. */
10830
10831 struct cursor_pos output_cursor;
10832
10833
10834 /* EXPORT:
10835 Set the global variable output_cursor to CURSOR. All cursor
10836 positions are relative to updated_window. */
10837
10838 void
10839 set_output_cursor (struct cursor_pos *cursor)
10840 {
10841 output_cursor.hpos = cursor->hpos;
10842 output_cursor.vpos = cursor->vpos;
10843 output_cursor.x = cursor->x;
10844 output_cursor.y = cursor->y;
10845 }
10846
10847
10848 /* EXPORT for RIF:
10849 Set a nominal cursor position.
10850
10851 HPOS and VPOS are column/row positions in a window glyph matrix. X
10852 and Y are window text area relative pixel positions.
10853
10854 If this is done during an update, updated_window will contain the
10855 window that is being updated and the position is the future output
10856 cursor position for that window. If updated_window is null, use
10857 selected_window and display the cursor at the given position. */
10858
10859 void
10860 x_cursor_to (int vpos, int hpos, int y, int x)
10861 {
10862 struct window *w;
10863
10864 /* If updated_window is not set, work on selected_window. */
10865 if (updated_window)
10866 w = updated_window;
10867 else
10868 w = XWINDOW (selected_window);
10869
10870 /* Set the output cursor. */
10871 output_cursor.hpos = hpos;
10872 output_cursor.vpos = vpos;
10873 output_cursor.x = x;
10874 output_cursor.y = y;
10875
10876 /* If not called as part of an update, really display the cursor.
10877 This will also set the cursor position of W. */
10878 if (updated_window == NULL)
10879 {
10880 BLOCK_INPUT;
10881 display_and_set_cursor (w, 1, hpos, vpos, x, y);
10882 if (FRAME_RIF (SELECTED_FRAME ())->flush_display_optional)
10883 FRAME_RIF (SELECTED_FRAME ())->flush_display_optional (SELECTED_FRAME ());
10884 UNBLOCK_INPUT;
10885 }
10886 }
10887
10888 #endif /* HAVE_WINDOW_SYSTEM */
10889
10890 \f
10891 /***********************************************************************
10892 Tool-bars
10893 ***********************************************************************/
10894
10895 #ifdef HAVE_WINDOW_SYSTEM
10896
10897 /* Where the mouse was last time we reported a mouse event. */
10898
10899 FRAME_PTR last_mouse_frame;
10900
10901 /* Tool-bar item index of the item on which a mouse button was pressed
10902 or -1. */
10903
10904 int last_tool_bar_item;
10905
10906
10907 static Lisp_Object
10908 update_tool_bar_unwind (Lisp_Object frame)
10909 {
10910 selected_frame = frame;
10911 return Qnil;
10912 }
10913
10914 /* Update the tool-bar item list for frame F. This has to be done
10915 before we start to fill in any display lines. Called from
10916 prepare_menu_bars. If SAVE_MATCH_DATA is non-zero, we must save
10917 and restore it here. */
10918
10919 static void
10920 update_tool_bar (struct frame *f, int save_match_data)
10921 {
10922 #if defined (USE_GTK) || defined (HAVE_NS)
10923 int do_update = FRAME_EXTERNAL_TOOL_BAR (f);
10924 #else
10925 int do_update = WINDOWP (f->tool_bar_window)
10926 && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)) > 0;
10927 #endif
10928
10929 if (do_update)
10930 {
10931 Lisp_Object window;
10932 struct window *w;
10933
10934 window = FRAME_SELECTED_WINDOW (f);
10935 w = XWINDOW (window);
10936
10937 /* If the user has switched buffers or windows, we need to
10938 recompute to reflect the new bindings. But we'll
10939 recompute when update_mode_lines is set too; that means
10940 that people can use force-mode-line-update to request
10941 that the menu bar be recomputed. The adverse effect on
10942 the rest of the redisplay algorithm is about the same as
10943 windows_or_buffers_changed anyway. */
10944 if (windows_or_buffers_changed
10945 || !NILP (w->update_mode_line)
10946 || update_mode_lines
10947 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
10948 < BUF_MODIFF (XBUFFER (w->buffer)))
10949 != !NILP (w->last_had_star))
10950 || ((!NILP (Vtransient_mark_mode)
10951 && !NILP (BVAR (XBUFFER (w->buffer), mark_active)))
10952 != !NILP (w->region_showing)))
10953 {
10954 struct buffer *prev = current_buffer;
10955 int count = SPECPDL_INDEX ();
10956 Lisp_Object frame, new_tool_bar;
10957 int new_n_tool_bar;
10958 struct gcpro gcpro1;
10959
10960 /* Set current_buffer to the buffer of the selected
10961 window of the frame, so that we get the right local
10962 keymaps. */
10963 set_buffer_internal_1 (XBUFFER (w->buffer));
10964
10965 /* Save match data, if we must. */
10966 if (save_match_data)
10967 record_unwind_save_match_data ();
10968
10969 /* Make sure that we don't accidentally use bogus keymaps. */
10970 if (NILP (Voverriding_local_map_menu_flag))
10971 {
10972 specbind (Qoverriding_terminal_local_map, Qnil);
10973 specbind (Qoverriding_local_map, Qnil);
10974 }
10975
10976 GCPRO1 (new_tool_bar);
10977
10978 /* We must temporarily set the selected frame to this frame
10979 before calling tool_bar_items, because the calculation of
10980 the tool-bar keymap uses the selected frame (see
10981 `tool-bar-make-keymap' in tool-bar.el). */
10982 record_unwind_protect (update_tool_bar_unwind, selected_frame);
10983 XSETFRAME (frame, f);
10984 selected_frame = frame;
10985
10986 /* Build desired tool-bar items from keymaps. */
10987 new_tool_bar = tool_bar_items (Fcopy_sequence (f->tool_bar_items),
10988 &new_n_tool_bar);
10989
10990 /* Redisplay the tool-bar if we changed it. */
10991 if (new_n_tool_bar != f->n_tool_bar_items
10992 || NILP (Fequal (new_tool_bar, f->tool_bar_items)))
10993 {
10994 /* Redisplay that happens asynchronously due to an expose event
10995 may access f->tool_bar_items. Make sure we update both
10996 variables within BLOCK_INPUT so no such event interrupts. */
10997 BLOCK_INPUT;
10998 f->tool_bar_items = new_tool_bar;
10999 f->n_tool_bar_items = new_n_tool_bar;
11000 w->update_mode_line = Qt;
11001 UNBLOCK_INPUT;
11002 }
11003
11004 UNGCPRO;
11005
11006 unbind_to (count, Qnil);
11007 set_buffer_internal_1 (prev);
11008 }
11009 }
11010 }
11011
11012
11013 /* Set F->desired_tool_bar_string to a Lisp string representing frame
11014 F's desired tool-bar contents. F->tool_bar_items must have
11015 been set up previously by calling prepare_menu_bars. */
11016
11017 static void
11018 build_desired_tool_bar_string (struct frame *f)
11019 {
11020 int i, size, size_needed;
11021 struct gcpro gcpro1, gcpro2, gcpro3;
11022 Lisp_Object image, plist, props;
11023
11024 image = plist = props = Qnil;
11025 GCPRO3 (image, plist, props);
11026
11027 /* Prepare F->desired_tool_bar_string. If we can reuse it, do so.
11028 Otherwise, make a new string. */
11029
11030 /* The size of the string we might be able to reuse. */
11031 size = (STRINGP (f->desired_tool_bar_string)
11032 ? SCHARS (f->desired_tool_bar_string)
11033 : 0);
11034
11035 /* We need one space in the string for each image. */
11036 size_needed = f->n_tool_bar_items;
11037
11038 /* Reuse f->desired_tool_bar_string, if possible. */
11039 if (size < size_needed || NILP (f->desired_tool_bar_string))
11040 f->desired_tool_bar_string = Fmake_string (make_number (size_needed),
11041 make_number (' '));
11042 else
11043 {
11044 props = list4 (Qdisplay, Qnil, Qmenu_item, Qnil);
11045 Fremove_text_properties (make_number (0), make_number (size),
11046 props, f->desired_tool_bar_string);
11047 }
11048
11049 /* Put a `display' property on the string for the images to display,
11050 put a `menu_item' property on tool-bar items with a value that
11051 is the index of the item in F's tool-bar item vector. */
11052 for (i = 0; i < f->n_tool_bar_items; ++i)
11053 {
11054 #define PROP(IDX) AREF (f->tool_bar_items, i * TOOL_BAR_ITEM_NSLOTS + (IDX))
11055
11056 int enabled_p = !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P));
11057 int selected_p = !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P));
11058 int hmargin, vmargin, relief, idx, end;
11059
11060 /* If image is a vector, choose the image according to the
11061 button state. */
11062 image = PROP (TOOL_BAR_ITEM_IMAGES);
11063 if (VECTORP (image))
11064 {
11065 if (enabled_p)
11066 idx = (selected_p
11067 ? TOOL_BAR_IMAGE_ENABLED_SELECTED
11068 : TOOL_BAR_IMAGE_ENABLED_DESELECTED);
11069 else
11070 idx = (selected_p
11071 ? TOOL_BAR_IMAGE_DISABLED_SELECTED
11072 : TOOL_BAR_IMAGE_DISABLED_DESELECTED);
11073
11074 xassert (ASIZE (image) >= idx);
11075 image = AREF (image, idx);
11076 }
11077 else
11078 idx = -1;
11079
11080 /* Ignore invalid image specifications. */
11081 if (!valid_image_p (image))
11082 continue;
11083
11084 /* Display the tool-bar button pressed, or depressed. */
11085 plist = Fcopy_sequence (XCDR (image));
11086
11087 /* Compute margin and relief to draw. */
11088 relief = (tool_bar_button_relief >= 0
11089 ? tool_bar_button_relief
11090 : DEFAULT_TOOL_BAR_BUTTON_RELIEF);
11091 hmargin = vmargin = relief;
11092
11093 if (INTEGERP (Vtool_bar_button_margin)
11094 && XINT (Vtool_bar_button_margin) > 0)
11095 {
11096 hmargin += XFASTINT (Vtool_bar_button_margin);
11097 vmargin += XFASTINT (Vtool_bar_button_margin);
11098 }
11099 else if (CONSP (Vtool_bar_button_margin))
11100 {
11101 if (INTEGERP (XCAR (Vtool_bar_button_margin))
11102 && XINT (XCAR (Vtool_bar_button_margin)) > 0)
11103 hmargin += XFASTINT (XCAR (Vtool_bar_button_margin));
11104
11105 if (INTEGERP (XCDR (Vtool_bar_button_margin))
11106 && XINT (XCDR (Vtool_bar_button_margin)) > 0)
11107 vmargin += XFASTINT (XCDR (Vtool_bar_button_margin));
11108 }
11109
11110 if (auto_raise_tool_bar_buttons_p)
11111 {
11112 /* Add a `:relief' property to the image spec if the item is
11113 selected. */
11114 if (selected_p)
11115 {
11116 plist = Fplist_put (plist, QCrelief, make_number (-relief));
11117 hmargin -= relief;
11118 vmargin -= relief;
11119 }
11120 }
11121 else
11122 {
11123 /* If image is selected, display it pressed, i.e. with a
11124 negative relief. If it's not selected, display it with a
11125 raised relief. */
11126 plist = Fplist_put (plist, QCrelief,
11127 (selected_p
11128 ? make_number (-relief)
11129 : make_number (relief)));
11130 hmargin -= relief;
11131 vmargin -= relief;
11132 }
11133
11134 /* Put a margin around the image. */
11135 if (hmargin || vmargin)
11136 {
11137 if (hmargin == vmargin)
11138 plist = Fplist_put (plist, QCmargin, make_number (hmargin));
11139 else
11140 plist = Fplist_put (plist, QCmargin,
11141 Fcons (make_number (hmargin),
11142 make_number (vmargin)));
11143 }
11144
11145 /* If button is not enabled, and we don't have special images
11146 for the disabled state, make the image appear disabled by
11147 applying an appropriate algorithm to it. */
11148 if (!enabled_p && idx < 0)
11149 plist = Fplist_put (plist, QCconversion, Qdisabled);
11150
11151 /* Put a `display' text property on the string for the image to
11152 display. Put a `menu-item' property on the string that gives
11153 the start of this item's properties in the tool-bar items
11154 vector. */
11155 image = Fcons (Qimage, plist);
11156 props = list4 (Qdisplay, image,
11157 Qmenu_item, make_number (i * TOOL_BAR_ITEM_NSLOTS));
11158
11159 /* Let the last image hide all remaining spaces in the tool bar
11160 string. The string can be longer than needed when we reuse a
11161 previous string. */
11162 if (i + 1 == f->n_tool_bar_items)
11163 end = SCHARS (f->desired_tool_bar_string);
11164 else
11165 end = i + 1;
11166 Fadd_text_properties (make_number (i), make_number (end),
11167 props, f->desired_tool_bar_string);
11168 #undef PROP
11169 }
11170
11171 UNGCPRO;
11172 }
11173
11174
11175 /* Display one line of the tool-bar of frame IT->f.
11176
11177 HEIGHT specifies the desired height of the tool-bar line.
11178 If the actual height of the glyph row is less than HEIGHT, the
11179 row's height is increased to HEIGHT, and the icons are centered
11180 vertically in the new height.
11181
11182 If HEIGHT is -1, we are counting needed tool-bar lines, so don't
11183 count a final empty row in case the tool-bar width exactly matches
11184 the window width.
11185 */
11186
11187 static void
11188 display_tool_bar_line (struct it *it, int height)
11189 {
11190 struct glyph_row *row = it->glyph_row;
11191 int max_x = it->last_visible_x;
11192 struct glyph *last;
11193
11194 prepare_desired_row (row);
11195 row->y = it->current_y;
11196
11197 /* Note that this isn't made use of if the face hasn't a box,
11198 so there's no need to check the face here. */
11199 it->start_of_box_run_p = 1;
11200
11201 while (it->current_x < max_x)
11202 {
11203 int x, n_glyphs_before, i, nglyphs;
11204 struct it it_before;
11205
11206 /* Get the next display element. */
11207 if (!get_next_display_element (it))
11208 {
11209 /* Don't count empty row if we are counting needed tool-bar lines. */
11210 if (height < 0 && !it->hpos)
11211 return;
11212 break;
11213 }
11214
11215 /* Produce glyphs. */
11216 n_glyphs_before = row->used[TEXT_AREA];
11217 it_before = *it;
11218
11219 PRODUCE_GLYPHS (it);
11220
11221 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
11222 i = 0;
11223 x = it_before.current_x;
11224 while (i < nglyphs)
11225 {
11226 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
11227
11228 if (x + glyph->pixel_width > max_x)
11229 {
11230 /* Glyph doesn't fit on line. Backtrack. */
11231 row->used[TEXT_AREA] = n_glyphs_before;
11232 *it = it_before;
11233 /* If this is the only glyph on this line, it will never fit on the
11234 tool-bar, so skip it. But ensure there is at least one glyph,
11235 so we don't accidentally disable the tool-bar. */
11236 if (n_glyphs_before == 0
11237 && (it->vpos > 0 || IT_STRING_CHARPOS (*it) < it->end_charpos-1))
11238 break;
11239 goto out;
11240 }
11241
11242 ++it->hpos;
11243 x += glyph->pixel_width;
11244 ++i;
11245 }
11246
11247 /* Stop at line end. */
11248 if (ITERATOR_AT_END_OF_LINE_P (it))
11249 break;
11250
11251 set_iterator_to_next (it, 1);
11252 }
11253
11254 out:;
11255
11256 row->displays_text_p = row->used[TEXT_AREA] != 0;
11257
11258 /* Use default face for the border below the tool bar.
11259
11260 FIXME: When auto-resize-tool-bars is grow-only, there is
11261 no additional border below the possibly empty tool-bar lines.
11262 So to make the extra empty lines look "normal", we have to
11263 use the tool-bar face for the border too. */
11264 if (!row->displays_text_p && !EQ (Vauto_resize_tool_bars, Qgrow_only))
11265 it->face_id = DEFAULT_FACE_ID;
11266
11267 extend_face_to_end_of_line (it);
11268 last = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
11269 last->right_box_line_p = 1;
11270 if (last == row->glyphs[TEXT_AREA])
11271 last->left_box_line_p = 1;
11272
11273 /* Make line the desired height and center it vertically. */
11274 if ((height -= it->max_ascent + it->max_descent) > 0)
11275 {
11276 /* Don't add more than one line height. */
11277 height %= FRAME_LINE_HEIGHT (it->f);
11278 it->max_ascent += height / 2;
11279 it->max_descent += (height + 1) / 2;
11280 }
11281
11282 compute_line_metrics (it);
11283
11284 /* If line is empty, make it occupy the rest of the tool-bar. */
11285 if (!row->displays_text_p)
11286 {
11287 row->height = row->phys_height = it->last_visible_y - row->y;
11288 row->visible_height = row->height;
11289 row->ascent = row->phys_ascent = 0;
11290 row->extra_line_spacing = 0;
11291 }
11292
11293 row->full_width_p = 1;
11294 row->continued_p = 0;
11295 row->truncated_on_left_p = 0;
11296 row->truncated_on_right_p = 0;
11297
11298 it->current_x = it->hpos = 0;
11299 it->current_y += row->height;
11300 ++it->vpos;
11301 ++it->glyph_row;
11302 }
11303
11304
11305 /* Max tool-bar height. */
11306
11307 #define MAX_FRAME_TOOL_BAR_HEIGHT(f) \
11308 ((FRAME_LINE_HEIGHT (f) * FRAME_LINES (f)))
11309
11310 /* Value is the number of screen lines needed to make all tool-bar
11311 items of frame F visible. The number of actual rows needed is
11312 returned in *N_ROWS if non-NULL. */
11313
11314 static int
11315 tool_bar_lines_needed (struct frame *f, int *n_rows)
11316 {
11317 struct window *w = XWINDOW (f->tool_bar_window);
11318 struct it it;
11319 /* tool_bar_lines_needed is called from redisplay_tool_bar after building
11320 the desired matrix, so use (unused) mode-line row as temporary row to
11321 avoid destroying the first tool-bar row. */
11322 struct glyph_row *temp_row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
11323
11324 /* Initialize an iterator for iteration over
11325 F->desired_tool_bar_string in the tool-bar window of frame F. */
11326 init_iterator (&it, w, -1, -1, temp_row, TOOL_BAR_FACE_ID);
11327 it.first_visible_x = 0;
11328 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
11329 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
11330 it.paragraph_embedding = L2R;
11331
11332 while (!ITERATOR_AT_END_P (&it))
11333 {
11334 clear_glyph_row (temp_row);
11335 it.glyph_row = temp_row;
11336 display_tool_bar_line (&it, -1);
11337 }
11338 clear_glyph_row (temp_row);
11339
11340 /* f->n_tool_bar_rows == 0 means "unknown"; -1 means no tool-bar. */
11341 if (n_rows)
11342 *n_rows = it.vpos > 0 ? it.vpos : -1;
11343
11344 return (it.current_y + FRAME_LINE_HEIGHT (f) - 1) / FRAME_LINE_HEIGHT (f);
11345 }
11346
11347
11348 DEFUN ("tool-bar-lines-needed", Ftool_bar_lines_needed, Stool_bar_lines_needed,
11349 0, 1, 0,
11350 doc: /* Return the number of lines occupied by the tool bar of FRAME. */)
11351 (Lisp_Object frame)
11352 {
11353 struct frame *f;
11354 struct window *w;
11355 int nlines = 0;
11356
11357 if (NILP (frame))
11358 frame = selected_frame;
11359 else
11360 CHECK_FRAME (frame);
11361 f = XFRAME (frame);
11362
11363 if (WINDOWP (f->tool_bar_window)
11364 && (w = XWINDOW (f->tool_bar_window),
11365 WINDOW_TOTAL_LINES (w) > 0))
11366 {
11367 update_tool_bar (f, 1);
11368 if (f->n_tool_bar_items)
11369 {
11370 build_desired_tool_bar_string (f);
11371 nlines = tool_bar_lines_needed (f, NULL);
11372 }
11373 }
11374
11375 return make_number (nlines);
11376 }
11377
11378
11379 /* Display the tool-bar of frame F. Value is non-zero if tool-bar's
11380 height should be changed. */
11381
11382 static int
11383 redisplay_tool_bar (struct frame *f)
11384 {
11385 struct window *w;
11386 struct it it;
11387 struct glyph_row *row;
11388
11389 #if defined (USE_GTK) || defined (HAVE_NS)
11390 if (FRAME_EXTERNAL_TOOL_BAR (f))
11391 update_frame_tool_bar (f);
11392 return 0;
11393 #endif
11394
11395 /* If frame hasn't a tool-bar window or if it is zero-height, don't
11396 do anything. This means you must start with tool-bar-lines
11397 non-zero to get the auto-sizing effect. Or in other words, you
11398 can turn off tool-bars by specifying tool-bar-lines zero. */
11399 if (!WINDOWP (f->tool_bar_window)
11400 || (w = XWINDOW (f->tool_bar_window),
11401 WINDOW_TOTAL_LINES (w) == 0))
11402 return 0;
11403
11404 /* Set up an iterator for the tool-bar window. */
11405 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
11406 it.first_visible_x = 0;
11407 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
11408 row = it.glyph_row;
11409
11410 /* Build a string that represents the contents of the tool-bar. */
11411 build_desired_tool_bar_string (f);
11412 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
11413 /* FIXME: This should be controlled by a user option. But it
11414 doesn't make sense to have an R2L tool bar if the menu bar cannot
11415 be drawn also R2L, and making the menu bar R2L is tricky due
11416 toolkit-specific code that implements it. If an R2L tool bar is
11417 ever supported, display_tool_bar_line should also be augmented to
11418 call unproduce_glyphs like display_line and display_string
11419 do. */
11420 it.paragraph_embedding = L2R;
11421
11422 if (f->n_tool_bar_rows == 0)
11423 {
11424 int nlines;
11425
11426 if ((nlines = tool_bar_lines_needed (f, &f->n_tool_bar_rows),
11427 nlines != WINDOW_TOTAL_LINES (w)))
11428 {
11429 Lisp_Object frame;
11430 int old_height = WINDOW_TOTAL_LINES (w);
11431
11432 XSETFRAME (frame, f);
11433 Fmodify_frame_parameters (frame,
11434 Fcons (Fcons (Qtool_bar_lines,
11435 make_number (nlines)),
11436 Qnil));
11437 if (WINDOW_TOTAL_LINES (w) != old_height)
11438 {
11439 clear_glyph_matrix (w->desired_matrix);
11440 fonts_changed_p = 1;
11441 return 1;
11442 }
11443 }
11444 }
11445
11446 /* Display as many lines as needed to display all tool-bar items. */
11447
11448 if (f->n_tool_bar_rows > 0)
11449 {
11450 int border, rows, height, extra;
11451
11452 if (INTEGERP (Vtool_bar_border))
11453 border = XINT (Vtool_bar_border);
11454 else if (EQ (Vtool_bar_border, Qinternal_border_width))
11455 border = FRAME_INTERNAL_BORDER_WIDTH (f);
11456 else if (EQ (Vtool_bar_border, Qborder_width))
11457 border = f->border_width;
11458 else
11459 border = 0;
11460 if (border < 0)
11461 border = 0;
11462
11463 rows = f->n_tool_bar_rows;
11464 height = max (1, (it.last_visible_y - border) / rows);
11465 extra = it.last_visible_y - border - height * rows;
11466
11467 while (it.current_y < it.last_visible_y)
11468 {
11469 int h = 0;
11470 if (extra > 0 && rows-- > 0)
11471 {
11472 h = (extra + rows - 1) / rows;
11473 extra -= h;
11474 }
11475 display_tool_bar_line (&it, height + h);
11476 }
11477 }
11478 else
11479 {
11480 while (it.current_y < it.last_visible_y)
11481 display_tool_bar_line (&it, 0);
11482 }
11483
11484 /* It doesn't make much sense to try scrolling in the tool-bar
11485 window, so don't do it. */
11486 w->desired_matrix->no_scrolling_p = 1;
11487 w->must_be_updated_p = 1;
11488
11489 if (!NILP (Vauto_resize_tool_bars))
11490 {
11491 int max_tool_bar_height = MAX_FRAME_TOOL_BAR_HEIGHT (f);
11492 int change_height_p = 0;
11493
11494 /* If we couldn't display everything, change the tool-bar's
11495 height if there is room for more. */
11496 if (IT_STRING_CHARPOS (it) < it.end_charpos
11497 && it.current_y < max_tool_bar_height)
11498 change_height_p = 1;
11499
11500 row = it.glyph_row - 1;
11501
11502 /* If there are blank lines at the end, except for a partially
11503 visible blank line at the end that is smaller than
11504 FRAME_LINE_HEIGHT, change the tool-bar's height. */
11505 if (!row->displays_text_p
11506 && row->height >= FRAME_LINE_HEIGHT (f))
11507 change_height_p = 1;
11508
11509 /* If row displays tool-bar items, but is partially visible,
11510 change the tool-bar's height. */
11511 if (row->displays_text_p
11512 && MATRIX_ROW_BOTTOM_Y (row) > it.last_visible_y
11513 && MATRIX_ROW_BOTTOM_Y (row) < max_tool_bar_height)
11514 change_height_p = 1;
11515
11516 /* Resize windows as needed by changing the `tool-bar-lines'
11517 frame parameter. */
11518 if (change_height_p)
11519 {
11520 Lisp_Object frame;
11521 int old_height = WINDOW_TOTAL_LINES (w);
11522 int nrows;
11523 int nlines = tool_bar_lines_needed (f, &nrows);
11524
11525 change_height_p = ((EQ (Vauto_resize_tool_bars, Qgrow_only)
11526 && !f->minimize_tool_bar_window_p)
11527 ? (nlines > old_height)
11528 : (nlines != old_height));
11529 f->minimize_tool_bar_window_p = 0;
11530
11531 if (change_height_p)
11532 {
11533 XSETFRAME (frame, f);
11534 Fmodify_frame_parameters (frame,
11535 Fcons (Fcons (Qtool_bar_lines,
11536 make_number (nlines)),
11537 Qnil));
11538 if (WINDOW_TOTAL_LINES (w) != old_height)
11539 {
11540 clear_glyph_matrix (w->desired_matrix);
11541 f->n_tool_bar_rows = nrows;
11542 fonts_changed_p = 1;
11543 return 1;
11544 }
11545 }
11546 }
11547 }
11548
11549 f->minimize_tool_bar_window_p = 0;
11550 return 0;
11551 }
11552
11553
11554 /* Get information about the tool-bar item which is displayed in GLYPH
11555 on frame F. Return in *PROP_IDX the index where tool-bar item
11556 properties start in F->tool_bar_items. Value is zero if
11557 GLYPH doesn't display a tool-bar item. */
11558
11559 static int
11560 tool_bar_item_info (struct frame *f, struct glyph *glyph, int *prop_idx)
11561 {
11562 Lisp_Object prop;
11563 int success_p;
11564 int charpos;
11565
11566 /* This function can be called asynchronously, which means we must
11567 exclude any possibility that Fget_text_property signals an
11568 error. */
11569 charpos = min (SCHARS (f->current_tool_bar_string), glyph->charpos);
11570 charpos = max (0, charpos);
11571
11572 /* Get the text property `menu-item' at pos. The value of that
11573 property is the start index of this item's properties in
11574 F->tool_bar_items. */
11575 prop = Fget_text_property (make_number (charpos),
11576 Qmenu_item, f->current_tool_bar_string);
11577 if (INTEGERP (prop))
11578 {
11579 *prop_idx = XINT (prop);
11580 success_p = 1;
11581 }
11582 else
11583 success_p = 0;
11584
11585 return success_p;
11586 }
11587
11588 \f
11589 /* Get information about the tool-bar item at position X/Y on frame F.
11590 Return in *GLYPH a pointer to the glyph of the tool-bar item in
11591 the current matrix of the tool-bar window of F, or NULL if not
11592 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
11593 item in F->tool_bar_items. Value is
11594
11595 -1 if X/Y is not on a tool-bar item
11596 0 if X/Y is on the same item that was highlighted before.
11597 1 otherwise. */
11598
11599 static int
11600 get_tool_bar_item (struct frame *f, int x, int y, struct glyph **glyph,
11601 int *hpos, int *vpos, int *prop_idx)
11602 {
11603 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
11604 struct window *w = XWINDOW (f->tool_bar_window);
11605 int area;
11606
11607 /* Find the glyph under X/Y. */
11608 *glyph = x_y_to_hpos_vpos (w, x, y, hpos, vpos, 0, 0, &area);
11609 if (*glyph == NULL)
11610 return -1;
11611
11612 /* Get the start of this tool-bar item's properties in
11613 f->tool_bar_items. */
11614 if (!tool_bar_item_info (f, *glyph, prop_idx))
11615 return -1;
11616
11617 /* Is mouse on the highlighted item? */
11618 if (EQ (f->tool_bar_window, hlinfo->mouse_face_window)
11619 && *vpos >= hlinfo->mouse_face_beg_row
11620 && *vpos <= hlinfo->mouse_face_end_row
11621 && (*vpos > hlinfo->mouse_face_beg_row
11622 || *hpos >= hlinfo->mouse_face_beg_col)
11623 && (*vpos < hlinfo->mouse_face_end_row
11624 || *hpos < hlinfo->mouse_face_end_col
11625 || hlinfo->mouse_face_past_end))
11626 return 0;
11627
11628 return 1;
11629 }
11630
11631
11632 /* EXPORT:
11633 Handle mouse button event on the tool-bar of frame F, at
11634 frame-relative coordinates X/Y. DOWN_P is 1 for a button press,
11635 0 for button release. MODIFIERS is event modifiers for button
11636 release. */
11637
11638 void
11639 handle_tool_bar_click (struct frame *f, int x, int y, int down_p,
11640 unsigned int modifiers)
11641 {
11642 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
11643 struct window *w = XWINDOW (f->tool_bar_window);
11644 int hpos, vpos, prop_idx;
11645 struct glyph *glyph;
11646 Lisp_Object enabled_p;
11647
11648 /* If not on the highlighted tool-bar item, return. */
11649 frame_to_window_pixel_xy (w, &x, &y);
11650 if (get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx) != 0)
11651 return;
11652
11653 /* If item is disabled, do nothing. */
11654 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
11655 if (NILP (enabled_p))
11656 return;
11657
11658 if (down_p)
11659 {
11660 /* Show item in pressed state. */
11661 show_mouse_face (hlinfo, DRAW_IMAGE_SUNKEN);
11662 hlinfo->mouse_face_image_state = DRAW_IMAGE_SUNKEN;
11663 last_tool_bar_item = prop_idx;
11664 }
11665 else
11666 {
11667 Lisp_Object key, frame;
11668 struct input_event event;
11669 EVENT_INIT (event);
11670
11671 /* Show item in released state. */
11672 show_mouse_face (hlinfo, DRAW_IMAGE_RAISED);
11673 hlinfo->mouse_face_image_state = DRAW_IMAGE_RAISED;
11674
11675 key = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_KEY);
11676
11677 XSETFRAME (frame, f);
11678 event.kind = TOOL_BAR_EVENT;
11679 event.frame_or_window = frame;
11680 event.arg = frame;
11681 kbd_buffer_store_event (&event);
11682
11683 event.kind = TOOL_BAR_EVENT;
11684 event.frame_or_window = frame;
11685 event.arg = key;
11686 event.modifiers = modifiers;
11687 kbd_buffer_store_event (&event);
11688 last_tool_bar_item = -1;
11689 }
11690 }
11691
11692
11693 /* Possibly highlight a tool-bar item on frame F when mouse moves to
11694 tool-bar window-relative coordinates X/Y. Called from
11695 note_mouse_highlight. */
11696
11697 static void
11698 note_tool_bar_highlight (struct frame *f, int x, int y)
11699 {
11700 Lisp_Object window = f->tool_bar_window;
11701 struct window *w = XWINDOW (window);
11702 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
11703 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
11704 int hpos, vpos;
11705 struct glyph *glyph;
11706 struct glyph_row *row;
11707 int i;
11708 Lisp_Object enabled_p;
11709 int prop_idx;
11710 enum draw_glyphs_face draw = DRAW_IMAGE_RAISED;
11711 int mouse_down_p, rc;
11712
11713 /* Function note_mouse_highlight is called with negative X/Y
11714 values when mouse moves outside of the frame. */
11715 if (x <= 0 || y <= 0)
11716 {
11717 clear_mouse_face (hlinfo);
11718 return;
11719 }
11720
11721 rc = get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx);
11722 if (rc < 0)
11723 {
11724 /* Not on tool-bar item. */
11725 clear_mouse_face (hlinfo);
11726 return;
11727 }
11728 else if (rc == 0)
11729 /* On same tool-bar item as before. */
11730 goto set_help_echo;
11731
11732 clear_mouse_face (hlinfo);
11733
11734 /* Mouse is down, but on different tool-bar item? */
11735 mouse_down_p = (dpyinfo->grabbed
11736 && f == last_mouse_frame
11737 && FRAME_LIVE_P (f));
11738 if (mouse_down_p
11739 && last_tool_bar_item != prop_idx)
11740 return;
11741
11742 hlinfo->mouse_face_image_state = DRAW_NORMAL_TEXT;
11743 draw = mouse_down_p ? DRAW_IMAGE_SUNKEN : DRAW_IMAGE_RAISED;
11744
11745 /* If tool-bar item is not enabled, don't highlight it. */
11746 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
11747 if (!NILP (enabled_p))
11748 {
11749 /* Compute the x-position of the glyph. In front and past the
11750 image is a space. We include this in the highlighted area. */
11751 row = MATRIX_ROW (w->current_matrix, vpos);
11752 for (i = x = 0; i < hpos; ++i)
11753 x += row->glyphs[TEXT_AREA][i].pixel_width;
11754
11755 /* Record this as the current active region. */
11756 hlinfo->mouse_face_beg_col = hpos;
11757 hlinfo->mouse_face_beg_row = vpos;
11758 hlinfo->mouse_face_beg_x = x;
11759 hlinfo->mouse_face_beg_y = row->y;
11760 hlinfo->mouse_face_past_end = 0;
11761
11762 hlinfo->mouse_face_end_col = hpos + 1;
11763 hlinfo->mouse_face_end_row = vpos;
11764 hlinfo->mouse_face_end_x = x + glyph->pixel_width;
11765 hlinfo->mouse_face_end_y = row->y;
11766 hlinfo->mouse_face_window = window;
11767 hlinfo->mouse_face_face_id = TOOL_BAR_FACE_ID;
11768
11769 /* Display it as active. */
11770 show_mouse_face (hlinfo, draw);
11771 hlinfo->mouse_face_image_state = draw;
11772 }
11773
11774 set_help_echo:
11775
11776 /* Set help_echo_string to a help string to display for this tool-bar item.
11777 XTread_socket does the rest. */
11778 help_echo_object = help_echo_window = Qnil;
11779 help_echo_pos = -1;
11780 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_HELP);
11781 if (NILP (help_echo_string))
11782 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_CAPTION);
11783 }
11784
11785 #endif /* HAVE_WINDOW_SYSTEM */
11786
11787
11788 \f
11789 /************************************************************************
11790 Horizontal scrolling
11791 ************************************************************************/
11792
11793 static int hscroll_window_tree (Lisp_Object);
11794 static int hscroll_windows (Lisp_Object);
11795
11796 /* For all leaf windows in the window tree rooted at WINDOW, set their
11797 hscroll value so that PT is (i) visible in the window, and (ii) so
11798 that it is not within a certain margin at the window's left and
11799 right border. Value is non-zero if any window's hscroll has been
11800 changed. */
11801
11802 static int
11803 hscroll_window_tree (Lisp_Object window)
11804 {
11805 int hscrolled_p = 0;
11806 int hscroll_relative_p = FLOATP (Vhscroll_step);
11807 int hscroll_step_abs = 0;
11808 double hscroll_step_rel = 0;
11809
11810 if (hscroll_relative_p)
11811 {
11812 hscroll_step_rel = XFLOAT_DATA (Vhscroll_step);
11813 if (hscroll_step_rel < 0)
11814 {
11815 hscroll_relative_p = 0;
11816 hscroll_step_abs = 0;
11817 }
11818 }
11819 else if (INTEGERP (Vhscroll_step))
11820 {
11821 hscroll_step_abs = XINT (Vhscroll_step);
11822 if (hscroll_step_abs < 0)
11823 hscroll_step_abs = 0;
11824 }
11825 else
11826 hscroll_step_abs = 0;
11827
11828 while (WINDOWP (window))
11829 {
11830 struct window *w = XWINDOW (window);
11831
11832 if (WINDOWP (w->hchild))
11833 hscrolled_p |= hscroll_window_tree (w->hchild);
11834 else if (WINDOWP (w->vchild))
11835 hscrolled_p |= hscroll_window_tree (w->vchild);
11836 else if (w->cursor.vpos >= 0)
11837 {
11838 int h_margin;
11839 int text_area_width;
11840 struct glyph_row *current_cursor_row
11841 = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
11842 struct glyph_row *desired_cursor_row
11843 = MATRIX_ROW (w->desired_matrix, w->cursor.vpos);
11844 struct glyph_row *cursor_row
11845 = (desired_cursor_row->enabled_p
11846 ? desired_cursor_row
11847 : current_cursor_row);
11848
11849 text_area_width = window_box_width (w, TEXT_AREA);
11850
11851 /* Scroll when cursor is inside this scroll margin. */
11852 h_margin = hscroll_margin * WINDOW_FRAME_COLUMN_WIDTH (w);
11853
11854 if (!NILP (Fbuffer_local_value (Qauto_hscroll_mode, w->buffer))
11855 && ((XFASTINT (w->hscroll)
11856 && w->cursor.x <= h_margin)
11857 || (cursor_row->enabled_p
11858 && cursor_row->truncated_on_right_p
11859 && (w->cursor.x >= text_area_width - h_margin))))
11860 {
11861 struct it it;
11862 int hscroll;
11863 struct buffer *saved_current_buffer;
11864 EMACS_INT pt;
11865 int wanted_x;
11866
11867 /* Find point in a display of infinite width. */
11868 saved_current_buffer = current_buffer;
11869 current_buffer = XBUFFER (w->buffer);
11870
11871 if (w == XWINDOW (selected_window))
11872 pt = PT;
11873 else
11874 {
11875 pt = marker_position (w->pointm);
11876 pt = max (BEGV, pt);
11877 pt = min (ZV, pt);
11878 }
11879
11880 /* Move iterator to pt starting at cursor_row->start in
11881 a line with infinite width. */
11882 init_to_row_start (&it, w, cursor_row);
11883 it.last_visible_x = INFINITY;
11884 move_it_in_display_line_to (&it, pt, -1, MOVE_TO_POS);
11885 current_buffer = saved_current_buffer;
11886
11887 /* Position cursor in window. */
11888 if (!hscroll_relative_p && hscroll_step_abs == 0)
11889 hscroll = max (0, (it.current_x
11890 - (ITERATOR_AT_END_OF_LINE_P (&it)
11891 ? (text_area_width - 4 * FRAME_COLUMN_WIDTH (it.f))
11892 : (text_area_width / 2))))
11893 / FRAME_COLUMN_WIDTH (it.f);
11894 else if (w->cursor.x >= text_area_width - h_margin)
11895 {
11896 if (hscroll_relative_p)
11897 wanted_x = text_area_width * (1 - hscroll_step_rel)
11898 - h_margin;
11899 else
11900 wanted_x = text_area_width
11901 - hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
11902 - h_margin;
11903 hscroll
11904 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
11905 }
11906 else
11907 {
11908 if (hscroll_relative_p)
11909 wanted_x = text_area_width * hscroll_step_rel
11910 + h_margin;
11911 else
11912 wanted_x = hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
11913 + h_margin;
11914 hscroll
11915 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
11916 }
11917 hscroll = max (hscroll, XFASTINT (w->min_hscroll));
11918
11919 /* Don't call Fset_window_hscroll if value hasn't
11920 changed because it will prevent redisplay
11921 optimizations. */
11922 if (XFASTINT (w->hscroll) != hscroll)
11923 {
11924 XBUFFER (w->buffer)->prevent_redisplay_optimizations_p = 1;
11925 w->hscroll = make_number (hscroll);
11926 hscrolled_p = 1;
11927 }
11928 }
11929 }
11930
11931 window = w->next;
11932 }
11933
11934 /* Value is non-zero if hscroll of any leaf window has been changed. */
11935 return hscrolled_p;
11936 }
11937
11938
11939 /* Set hscroll so that cursor is visible and not inside horizontal
11940 scroll margins for all windows in the tree rooted at WINDOW. See
11941 also hscroll_window_tree above. Value is non-zero if any window's
11942 hscroll has been changed. If it has, desired matrices on the frame
11943 of WINDOW are cleared. */
11944
11945 static int
11946 hscroll_windows (Lisp_Object window)
11947 {
11948 int hscrolled_p = hscroll_window_tree (window);
11949 if (hscrolled_p)
11950 clear_desired_matrices (XFRAME (WINDOW_FRAME (XWINDOW (window))));
11951 return hscrolled_p;
11952 }
11953
11954
11955 \f
11956 /************************************************************************
11957 Redisplay
11958 ************************************************************************/
11959
11960 /* Variables holding some state of redisplay if GLYPH_DEBUG is defined
11961 to a non-zero value. This is sometimes handy to have in a debugger
11962 session. */
11963
11964 #if GLYPH_DEBUG
11965
11966 /* First and last unchanged row for try_window_id. */
11967
11968 static int debug_first_unchanged_at_end_vpos;
11969 static int debug_last_unchanged_at_beg_vpos;
11970
11971 /* Delta vpos and y. */
11972
11973 static int debug_dvpos, debug_dy;
11974
11975 /* Delta in characters and bytes for try_window_id. */
11976
11977 static EMACS_INT debug_delta, debug_delta_bytes;
11978
11979 /* Values of window_end_pos and window_end_vpos at the end of
11980 try_window_id. */
11981
11982 static EMACS_INT debug_end_vpos;
11983
11984 /* Append a string to W->desired_matrix->method. FMT is a printf
11985 format string. If trace_redisplay_p is non-zero also printf the
11986 resulting string to stderr. */
11987
11988 static void debug_method_add (struct window *, char const *, ...)
11989 ATTRIBUTE_FORMAT_PRINTF (2, 3);
11990
11991 static void
11992 debug_method_add (struct window *w, char const *fmt, ...)
11993 {
11994 char buffer[512];
11995 char *method = w->desired_matrix->method;
11996 int len = strlen (method);
11997 int size = sizeof w->desired_matrix->method;
11998 int remaining = size - len - 1;
11999 va_list ap;
12000
12001 va_start (ap, fmt);
12002 vsprintf (buffer, fmt, ap);
12003 va_end (ap);
12004 if (len && remaining)
12005 {
12006 method[len] = '|';
12007 --remaining, ++len;
12008 }
12009
12010 strncpy (method + len, buffer, remaining);
12011
12012 if (trace_redisplay_p)
12013 fprintf (stderr, "%p (%s): %s\n",
12014 w,
12015 ((BUFFERP (w->buffer)
12016 && STRINGP (BVAR (XBUFFER (w->buffer), name)))
12017 ? SSDATA (BVAR (XBUFFER (w->buffer), name))
12018 : "no buffer"),
12019 buffer);
12020 }
12021
12022 #endif /* GLYPH_DEBUG */
12023
12024
12025 /* Value is non-zero if all changes in window W, which displays
12026 current_buffer, are in the text between START and END. START is a
12027 buffer position, END is given as a distance from Z. Used in
12028 redisplay_internal for display optimization. */
12029
12030 static inline int
12031 text_outside_line_unchanged_p (struct window *w,
12032 EMACS_INT start, EMACS_INT end)
12033 {
12034 int unchanged_p = 1;
12035
12036 /* If text or overlays have changed, see where. */
12037 if (XFASTINT (w->last_modified) < MODIFF
12038 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
12039 {
12040 /* Gap in the line? */
12041 if (GPT < start || Z - GPT < end)
12042 unchanged_p = 0;
12043
12044 /* Changes start in front of the line, or end after it? */
12045 if (unchanged_p
12046 && (BEG_UNCHANGED < start - 1
12047 || END_UNCHANGED < end))
12048 unchanged_p = 0;
12049
12050 /* If selective display, can't optimize if changes start at the
12051 beginning of the line. */
12052 if (unchanged_p
12053 && INTEGERP (BVAR (current_buffer, selective_display))
12054 && XINT (BVAR (current_buffer, selective_display)) > 0
12055 && (BEG_UNCHANGED < start || GPT <= start))
12056 unchanged_p = 0;
12057
12058 /* If there are overlays at the start or end of the line, these
12059 may have overlay strings with newlines in them. A change at
12060 START, for instance, may actually concern the display of such
12061 overlay strings as well, and they are displayed on different
12062 lines. So, quickly rule out this case. (For the future, it
12063 might be desirable to implement something more telling than
12064 just BEG/END_UNCHANGED.) */
12065 if (unchanged_p)
12066 {
12067 if (BEG + BEG_UNCHANGED == start
12068 && overlay_touches_p (start))
12069 unchanged_p = 0;
12070 if (END_UNCHANGED == end
12071 && overlay_touches_p (Z - end))
12072 unchanged_p = 0;
12073 }
12074
12075 /* Under bidi reordering, adding or deleting a character in the
12076 beginning of a paragraph, before the first strong directional
12077 character, can change the base direction of the paragraph (unless
12078 the buffer specifies a fixed paragraph direction), which will
12079 require to redisplay the whole paragraph. It might be worthwhile
12080 to find the paragraph limits and widen the range of redisplayed
12081 lines to that, but for now just give up this optimization. */
12082 if (!NILP (BVAR (XBUFFER (w->buffer), bidi_display_reordering))
12083 && NILP (BVAR (XBUFFER (w->buffer), bidi_paragraph_direction)))
12084 unchanged_p = 0;
12085 }
12086
12087 return unchanged_p;
12088 }
12089
12090
12091 /* Do a frame update, taking possible shortcuts into account. This is
12092 the main external entry point for redisplay.
12093
12094 If the last redisplay displayed an echo area message and that message
12095 is no longer requested, we clear the echo area or bring back the
12096 mini-buffer if that is in use. */
12097
12098 void
12099 redisplay (void)
12100 {
12101 redisplay_internal ();
12102 }
12103
12104
12105 static Lisp_Object
12106 overlay_arrow_string_or_property (Lisp_Object var)
12107 {
12108 Lisp_Object val;
12109
12110 if (val = Fget (var, Qoverlay_arrow_string), STRINGP (val))
12111 return val;
12112
12113 return Voverlay_arrow_string;
12114 }
12115
12116 /* Return 1 if there are any overlay-arrows in current_buffer. */
12117 static int
12118 overlay_arrow_in_current_buffer_p (void)
12119 {
12120 Lisp_Object vlist;
12121
12122 for (vlist = Voverlay_arrow_variable_list;
12123 CONSP (vlist);
12124 vlist = XCDR (vlist))
12125 {
12126 Lisp_Object var = XCAR (vlist);
12127 Lisp_Object val;
12128
12129 if (!SYMBOLP (var))
12130 continue;
12131 val = find_symbol_value (var);
12132 if (MARKERP (val)
12133 && current_buffer == XMARKER (val)->buffer)
12134 return 1;
12135 }
12136 return 0;
12137 }
12138
12139
12140 /* Return 1 if any overlay_arrows have moved or overlay-arrow-string
12141 has changed. */
12142
12143 static int
12144 overlay_arrows_changed_p (void)
12145 {
12146 Lisp_Object vlist;
12147
12148 for (vlist = Voverlay_arrow_variable_list;
12149 CONSP (vlist);
12150 vlist = XCDR (vlist))
12151 {
12152 Lisp_Object var = XCAR (vlist);
12153 Lisp_Object val, pstr;
12154
12155 if (!SYMBOLP (var))
12156 continue;
12157 val = find_symbol_value (var);
12158 if (!MARKERP (val))
12159 continue;
12160 if (! EQ (COERCE_MARKER (val),
12161 Fget (var, Qlast_arrow_position))
12162 || ! (pstr = overlay_arrow_string_or_property (var),
12163 EQ (pstr, Fget (var, Qlast_arrow_string))))
12164 return 1;
12165 }
12166 return 0;
12167 }
12168
12169 /* Mark overlay arrows to be updated on next redisplay. */
12170
12171 static void
12172 update_overlay_arrows (int up_to_date)
12173 {
12174 Lisp_Object vlist;
12175
12176 for (vlist = Voverlay_arrow_variable_list;
12177 CONSP (vlist);
12178 vlist = XCDR (vlist))
12179 {
12180 Lisp_Object var = XCAR (vlist);
12181
12182 if (!SYMBOLP (var))
12183 continue;
12184
12185 if (up_to_date > 0)
12186 {
12187 Lisp_Object val = find_symbol_value (var);
12188 Fput (var, Qlast_arrow_position,
12189 COERCE_MARKER (val));
12190 Fput (var, Qlast_arrow_string,
12191 overlay_arrow_string_or_property (var));
12192 }
12193 else if (up_to_date < 0
12194 || !NILP (Fget (var, Qlast_arrow_position)))
12195 {
12196 Fput (var, Qlast_arrow_position, Qt);
12197 Fput (var, Qlast_arrow_string, Qt);
12198 }
12199 }
12200 }
12201
12202
12203 /* Return overlay arrow string to display at row.
12204 Return integer (bitmap number) for arrow bitmap in left fringe.
12205 Return nil if no overlay arrow. */
12206
12207 static Lisp_Object
12208 overlay_arrow_at_row (struct it *it, struct glyph_row *row)
12209 {
12210 Lisp_Object vlist;
12211
12212 for (vlist = Voverlay_arrow_variable_list;
12213 CONSP (vlist);
12214 vlist = XCDR (vlist))
12215 {
12216 Lisp_Object var = XCAR (vlist);
12217 Lisp_Object val;
12218
12219 if (!SYMBOLP (var))
12220 continue;
12221
12222 val = find_symbol_value (var);
12223
12224 if (MARKERP (val)
12225 && current_buffer == XMARKER (val)->buffer
12226 && (MATRIX_ROW_START_CHARPOS (row) == marker_position (val)))
12227 {
12228 if (FRAME_WINDOW_P (it->f)
12229 /* FIXME: if ROW->reversed_p is set, this should test
12230 the right fringe, not the left one. */
12231 && WINDOW_LEFT_FRINGE_WIDTH (it->w) > 0)
12232 {
12233 #ifdef HAVE_WINDOW_SYSTEM
12234 if (val = Fget (var, Qoverlay_arrow_bitmap), SYMBOLP (val))
12235 {
12236 int fringe_bitmap;
12237 if ((fringe_bitmap = lookup_fringe_bitmap (val)) != 0)
12238 return make_number (fringe_bitmap);
12239 }
12240 #endif
12241 return make_number (-1); /* Use default arrow bitmap */
12242 }
12243 return overlay_arrow_string_or_property (var);
12244 }
12245 }
12246
12247 return Qnil;
12248 }
12249
12250 /* Return 1 if point moved out of or into a composition. Otherwise
12251 return 0. PREV_BUF and PREV_PT are the last point buffer and
12252 position. BUF and PT are the current point buffer and position. */
12253
12254 static int
12255 check_point_in_composition (struct buffer *prev_buf, EMACS_INT prev_pt,
12256 struct buffer *buf, EMACS_INT pt)
12257 {
12258 EMACS_INT start, end;
12259 Lisp_Object prop;
12260 Lisp_Object buffer;
12261
12262 XSETBUFFER (buffer, buf);
12263 /* Check a composition at the last point if point moved within the
12264 same buffer. */
12265 if (prev_buf == buf)
12266 {
12267 if (prev_pt == pt)
12268 /* Point didn't move. */
12269 return 0;
12270
12271 if (prev_pt > BUF_BEGV (buf) && prev_pt < BUF_ZV (buf)
12272 && find_composition (prev_pt, -1, &start, &end, &prop, buffer)
12273 && COMPOSITION_VALID_P (start, end, prop)
12274 && start < prev_pt && end > prev_pt)
12275 /* The last point was within the composition. Return 1 iff
12276 point moved out of the composition. */
12277 return (pt <= start || pt >= end);
12278 }
12279
12280 /* Check a composition at the current point. */
12281 return (pt > BUF_BEGV (buf) && pt < BUF_ZV (buf)
12282 && find_composition (pt, -1, &start, &end, &prop, buffer)
12283 && COMPOSITION_VALID_P (start, end, prop)
12284 && start < pt && end > pt);
12285 }
12286
12287
12288 /* Reconsider the setting of B->clip_changed which is displayed
12289 in window W. */
12290
12291 static inline void
12292 reconsider_clip_changes (struct window *w, struct buffer *b)
12293 {
12294 if (b->clip_changed
12295 && !NILP (w->window_end_valid)
12296 && w->current_matrix->buffer == b
12297 && w->current_matrix->zv == BUF_ZV (b)
12298 && w->current_matrix->begv == BUF_BEGV (b))
12299 b->clip_changed = 0;
12300
12301 /* If display wasn't paused, and W is not a tool bar window, see if
12302 point has been moved into or out of a composition. In that case,
12303 we set b->clip_changed to 1 to force updating the screen. If
12304 b->clip_changed has already been set to 1, we can skip this
12305 check. */
12306 if (!b->clip_changed
12307 && BUFFERP (w->buffer) && !NILP (w->window_end_valid))
12308 {
12309 EMACS_INT pt;
12310
12311 if (w == XWINDOW (selected_window))
12312 pt = PT;
12313 else
12314 pt = marker_position (w->pointm);
12315
12316 if ((w->current_matrix->buffer != XBUFFER (w->buffer)
12317 || pt != XINT (w->last_point))
12318 && check_point_in_composition (w->current_matrix->buffer,
12319 XINT (w->last_point),
12320 XBUFFER (w->buffer), pt))
12321 b->clip_changed = 1;
12322 }
12323 }
12324 \f
12325
12326 /* Select FRAME to forward the values of frame-local variables into C
12327 variables so that the redisplay routines can access those values
12328 directly. */
12329
12330 static void
12331 select_frame_for_redisplay (Lisp_Object frame)
12332 {
12333 Lisp_Object tail, tem;
12334 Lisp_Object old = selected_frame;
12335 struct Lisp_Symbol *sym;
12336
12337 xassert (FRAMEP (frame) && FRAME_LIVE_P (XFRAME (frame)));
12338
12339 selected_frame = frame;
12340
12341 do {
12342 for (tail = XFRAME (frame)->param_alist; CONSP (tail); tail = XCDR (tail))
12343 if (CONSP (XCAR (tail))
12344 && (tem = XCAR (XCAR (tail)),
12345 SYMBOLP (tem))
12346 && (sym = indirect_variable (XSYMBOL (tem)),
12347 sym->redirect == SYMBOL_LOCALIZED)
12348 && sym->val.blv->frame_local)
12349 /* Use find_symbol_value rather than Fsymbol_value
12350 to avoid an error if it is void. */
12351 find_symbol_value (tem);
12352 } while (!EQ (frame, old) && (frame = old, 1));
12353 }
12354
12355
12356 #define STOP_POLLING \
12357 do { if (! polling_stopped_here) stop_polling (); \
12358 polling_stopped_here = 1; } while (0)
12359
12360 #define RESUME_POLLING \
12361 do { if (polling_stopped_here) start_polling (); \
12362 polling_stopped_here = 0; } while (0)
12363
12364
12365 /* Perhaps in the future avoid recentering windows if it
12366 is not necessary; currently that causes some problems. */
12367
12368 static void
12369 redisplay_internal (void)
12370 {
12371 struct window *w = XWINDOW (selected_window);
12372 struct window *sw;
12373 struct frame *fr;
12374 int pending;
12375 int must_finish = 0;
12376 struct text_pos tlbufpos, tlendpos;
12377 int number_of_visible_frames;
12378 int count, count1;
12379 struct frame *sf;
12380 int polling_stopped_here = 0;
12381 Lisp_Object old_frame = selected_frame;
12382
12383 /* Non-zero means redisplay has to consider all windows on all
12384 frames. Zero means, only selected_window is considered. */
12385 int consider_all_windows_p;
12386
12387 TRACE ((stderr, "redisplay_internal %d\n", redisplaying_p));
12388
12389 /* No redisplay if running in batch mode or frame is not yet fully
12390 initialized, or redisplay is explicitly turned off by setting
12391 Vinhibit_redisplay. */
12392 if (FRAME_INITIAL_P (SELECTED_FRAME ())
12393 || !NILP (Vinhibit_redisplay))
12394 return;
12395
12396 /* Don't examine these until after testing Vinhibit_redisplay.
12397 When Emacs is shutting down, perhaps because its connection to
12398 X has dropped, we should not look at them at all. */
12399 fr = XFRAME (w->frame);
12400 sf = SELECTED_FRAME ();
12401
12402 if (!fr->glyphs_initialized_p)
12403 return;
12404
12405 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS)
12406 if (popup_activated ())
12407 return;
12408 #endif
12409
12410 /* I don't think this happens but let's be paranoid. */
12411 if (redisplaying_p)
12412 return;
12413
12414 /* Record a function that resets redisplaying_p to its old value
12415 when we leave this function. */
12416 count = SPECPDL_INDEX ();
12417 record_unwind_protect (unwind_redisplay,
12418 Fcons (make_number (redisplaying_p), selected_frame));
12419 ++redisplaying_p;
12420 specbind (Qinhibit_free_realized_faces, Qnil);
12421
12422 {
12423 Lisp_Object tail, frame;
12424
12425 FOR_EACH_FRAME (tail, frame)
12426 {
12427 struct frame *f = XFRAME (frame);
12428 f->already_hscrolled_p = 0;
12429 }
12430 }
12431
12432 retry:
12433 /* Remember the currently selected window. */
12434 sw = w;
12435
12436 if (!EQ (old_frame, selected_frame)
12437 && FRAME_LIVE_P (XFRAME (old_frame)))
12438 /* When running redisplay, we play a bit fast-and-loose and allow e.g.
12439 selected_frame and selected_window to be temporarily out-of-sync so
12440 when we come back here via `goto retry', we need to resync because we
12441 may need to run Elisp code (via prepare_menu_bars). */
12442 select_frame_for_redisplay (old_frame);
12443
12444 pending = 0;
12445 reconsider_clip_changes (w, current_buffer);
12446 last_escape_glyph_frame = NULL;
12447 last_escape_glyph_face_id = (1 << FACE_ID_BITS);
12448 last_glyphless_glyph_frame = NULL;
12449 last_glyphless_glyph_face_id = (1 << FACE_ID_BITS);
12450
12451 /* If new fonts have been loaded that make a glyph matrix adjustment
12452 necessary, do it. */
12453 if (fonts_changed_p)
12454 {
12455 adjust_glyphs (NULL);
12456 ++windows_or_buffers_changed;
12457 fonts_changed_p = 0;
12458 }
12459
12460 /* If face_change_count is non-zero, init_iterator will free all
12461 realized faces, which includes the faces referenced from current
12462 matrices. So, we can't reuse current matrices in this case. */
12463 if (face_change_count)
12464 ++windows_or_buffers_changed;
12465
12466 if ((FRAME_TERMCAP_P (sf) || FRAME_MSDOS_P (sf))
12467 && FRAME_TTY (sf)->previous_frame != sf)
12468 {
12469 /* Since frames on a single ASCII terminal share the same
12470 display area, displaying a different frame means redisplay
12471 the whole thing. */
12472 windows_or_buffers_changed++;
12473 SET_FRAME_GARBAGED (sf);
12474 #ifndef DOS_NT
12475 set_tty_color_mode (FRAME_TTY (sf), sf);
12476 #endif
12477 FRAME_TTY (sf)->previous_frame = sf;
12478 }
12479
12480 /* Set the visible flags for all frames. Do this before checking
12481 for resized or garbaged frames; they want to know if their frames
12482 are visible. See the comment in frame.h for
12483 FRAME_SAMPLE_VISIBILITY. */
12484 {
12485 Lisp_Object tail, frame;
12486
12487 number_of_visible_frames = 0;
12488
12489 FOR_EACH_FRAME (tail, frame)
12490 {
12491 struct frame *f = XFRAME (frame);
12492
12493 FRAME_SAMPLE_VISIBILITY (f);
12494 if (FRAME_VISIBLE_P (f))
12495 ++number_of_visible_frames;
12496 clear_desired_matrices (f);
12497 }
12498 }
12499
12500 /* Notice any pending interrupt request to change frame size. */
12501 do_pending_window_change (1);
12502
12503 /* do_pending_window_change could change the selected_window due to
12504 frame resizing which makes the selected window too small. */
12505 if (WINDOWP (selected_window) && (w = XWINDOW (selected_window)) != sw)
12506 {
12507 sw = w;
12508 reconsider_clip_changes (w, current_buffer);
12509 }
12510
12511 /* Clear frames marked as garbaged. */
12512 if (frame_garbaged)
12513 clear_garbaged_frames ();
12514
12515 /* Build menubar and tool-bar items. */
12516 if (NILP (Vmemory_full))
12517 prepare_menu_bars ();
12518
12519 if (windows_or_buffers_changed)
12520 update_mode_lines++;
12521
12522 /* Detect case that we need to write or remove a star in the mode line. */
12523 if ((SAVE_MODIFF < MODIFF) != !NILP (w->last_had_star))
12524 {
12525 w->update_mode_line = Qt;
12526 if (buffer_shared > 1)
12527 update_mode_lines++;
12528 }
12529
12530 /* Avoid invocation of point motion hooks by `current_column' below. */
12531 count1 = SPECPDL_INDEX ();
12532 specbind (Qinhibit_point_motion_hooks, Qt);
12533
12534 /* If %c is in the mode line, update it if needed. */
12535 if (!NILP (w->column_number_displayed)
12536 /* This alternative quickly identifies a common case
12537 where no change is needed. */
12538 && !(PT == XFASTINT (w->last_point)
12539 && XFASTINT (w->last_modified) >= MODIFF
12540 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
12541 && (XFASTINT (w->column_number_displayed) != current_column ()))
12542 w->update_mode_line = Qt;
12543
12544 unbind_to (count1, Qnil);
12545
12546 FRAME_SCROLL_BOTTOM_VPOS (XFRAME (w->frame)) = -1;
12547
12548 /* The variable buffer_shared is set in redisplay_window and
12549 indicates that we redisplay a buffer in different windows. See
12550 there. */
12551 consider_all_windows_p = (update_mode_lines || buffer_shared > 1
12552 || cursor_type_changed);
12553
12554 /* If specs for an arrow have changed, do thorough redisplay
12555 to ensure we remove any arrow that should no longer exist. */
12556 if (overlay_arrows_changed_p ())
12557 consider_all_windows_p = windows_or_buffers_changed = 1;
12558
12559 /* Normally the message* functions will have already displayed and
12560 updated the echo area, but the frame may have been trashed, or
12561 the update may have been preempted, so display the echo area
12562 again here. Checking message_cleared_p captures the case that
12563 the echo area should be cleared. */
12564 if ((!NILP (echo_area_buffer[0]) && !display_last_displayed_message_p)
12565 || (!NILP (echo_area_buffer[1]) && display_last_displayed_message_p)
12566 || (message_cleared_p
12567 && minibuf_level == 0
12568 /* If the mini-window is currently selected, this means the
12569 echo-area doesn't show through. */
12570 && !MINI_WINDOW_P (XWINDOW (selected_window))))
12571 {
12572 int window_height_changed_p = echo_area_display (0);
12573 must_finish = 1;
12574
12575 /* If we don't display the current message, don't clear the
12576 message_cleared_p flag, because, if we did, we wouldn't clear
12577 the echo area in the next redisplay which doesn't preserve
12578 the echo area. */
12579 if (!display_last_displayed_message_p)
12580 message_cleared_p = 0;
12581
12582 if (fonts_changed_p)
12583 goto retry;
12584 else if (window_height_changed_p)
12585 {
12586 consider_all_windows_p = 1;
12587 ++update_mode_lines;
12588 ++windows_or_buffers_changed;
12589
12590 /* If window configuration was changed, frames may have been
12591 marked garbaged. Clear them or we will experience
12592 surprises wrt scrolling. */
12593 if (frame_garbaged)
12594 clear_garbaged_frames ();
12595 }
12596 }
12597 else if (EQ (selected_window, minibuf_window)
12598 && (current_buffer->clip_changed
12599 || XFASTINT (w->last_modified) < MODIFF
12600 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
12601 && resize_mini_window (w, 0))
12602 {
12603 /* Resized active mini-window to fit the size of what it is
12604 showing if its contents might have changed. */
12605 must_finish = 1;
12606 /* FIXME: this causes all frames to be updated, which seems unnecessary
12607 since only the current frame needs to be considered. This function needs
12608 to be rewritten with two variables, consider_all_windows and
12609 consider_all_frames. */
12610 consider_all_windows_p = 1;
12611 ++windows_or_buffers_changed;
12612 ++update_mode_lines;
12613
12614 /* If window configuration was changed, frames may have been
12615 marked garbaged. Clear them or we will experience
12616 surprises wrt scrolling. */
12617 if (frame_garbaged)
12618 clear_garbaged_frames ();
12619 }
12620
12621
12622 /* If showing the region, and mark has changed, we must redisplay
12623 the whole window. The assignment to this_line_start_pos prevents
12624 the optimization directly below this if-statement. */
12625 if (((!NILP (Vtransient_mark_mode)
12626 && !NILP (BVAR (XBUFFER (w->buffer), mark_active)))
12627 != !NILP (w->region_showing))
12628 || (!NILP (w->region_showing)
12629 && !EQ (w->region_showing,
12630 Fmarker_position (BVAR (XBUFFER (w->buffer), mark)))))
12631 CHARPOS (this_line_start_pos) = 0;
12632
12633 /* Optimize the case that only the line containing the cursor in the
12634 selected window has changed. Variables starting with this_ are
12635 set in display_line and record information about the line
12636 containing the cursor. */
12637 tlbufpos = this_line_start_pos;
12638 tlendpos = this_line_end_pos;
12639 if (!consider_all_windows_p
12640 && CHARPOS (tlbufpos) > 0
12641 && NILP (w->update_mode_line)
12642 && !current_buffer->clip_changed
12643 && !current_buffer->prevent_redisplay_optimizations_p
12644 && FRAME_VISIBLE_P (XFRAME (w->frame))
12645 && !FRAME_OBSCURED_P (XFRAME (w->frame))
12646 /* Make sure recorded data applies to current buffer, etc. */
12647 && this_line_buffer == current_buffer
12648 && current_buffer == XBUFFER (w->buffer)
12649 && NILP (w->force_start)
12650 && NILP (w->optional_new_start)
12651 /* Point must be on the line that we have info recorded about. */
12652 && PT >= CHARPOS (tlbufpos)
12653 && PT <= Z - CHARPOS (tlendpos)
12654 /* All text outside that line, including its final newline,
12655 must be unchanged. */
12656 && text_outside_line_unchanged_p (w, CHARPOS (tlbufpos),
12657 CHARPOS (tlendpos)))
12658 {
12659 if (CHARPOS (tlbufpos) > BEGV
12660 && FETCH_BYTE (BYTEPOS (tlbufpos) - 1) != '\n'
12661 && (CHARPOS (tlbufpos) == ZV
12662 || FETCH_BYTE (BYTEPOS (tlbufpos)) == '\n'))
12663 /* Former continuation line has disappeared by becoming empty. */
12664 goto cancel;
12665 else if (XFASTINT (w->last_modified) < MODIFF
12666 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF
12667 || MINI_WINDOW_P (w))
12668 {
12669 /* We have to handle the case of continuation around a
12670 wide-column character (see the comment in indent.c around
12671 line 1340).
12672
12673 For instance, in the following case:
12674
12675 -------- Insert --------
12676 K_A_N_\\ `a' K_A_N_a\ `X_' are wide-column chars.
12677 J_I_ ==> J_I_ `^^' are cursors.
12678 ^^ ^^
12679 -------- --------
12680
12681 As we have to redraw the line above, we cannot use this
12682 optimization. */
12683
12684 struct it it;
12685 int line_height_before = this_line_pixel_height;
12686
12687 /* Note that start_display will handle the case that the
12688 line starting at tlbufpos is a continuation line. */
12689 start_display (&it, w, tlbufpos);
12690
12691 /* Implementation note: It this still necessary? */
12692 if (it.current_x != this_line_start_x)
12693 goto cancel;
12694
12695 TRACE ((stderr, "trying display optimization 1\n"));
12696 w->cursor.vpos = -1;
12697 overlay_arrow_seen = 0;
12698 it.vpos = this_line_vpos;
12699 it.current_y = this_line_y;
12700 it.glyph_row = MATRIX_ROW (w->desired_matrix, this_line_vpos);
12701 display_line (&it);
12702
12703 /* If line contains point, is not continued,
12704 and ends at same distance from eob as before, we win. */
12705 if (w->cursor.vpos >= 0
12706 /* Line is not continued, otherwise this_line_start_pos
12707 would have been set to 0 in display_line. */
12708 && CHARPOS (this_line_start_pos)
12709 /* Line ends as before. */
12710 && CHARPOS (this_line_end_pos) == CHARPOS (tlendpos)
12711 /* Line has same height as before. Otherwise other lines
12712 would have to be shifted up or down. */
12713 && this_line_pixel_height == line_height_before)
12714 {
12715 /* If this is not the window's last line, we must adjust
12716 the charstarts of the lines below. */
12717 if (it.current_y < it.last_visible_y)
12718 {
12719 struct glyph_row *row
12720 = MATRIX_ROW (w->current_matrix, this_line_vpos + 1);
12721 EMACS_INT delta, delta_bytes;
12722
12723 /* We used to distinguish between two cases here,
12724 conditioned by Z - CHARPOS (tlendpos) == ZV, for
12725 when the line ends in a newline or the end of the
12726 buffer's accessible portion. But both cases did
12727 the same, so they were collapsed. */
12728 delta = (Z
12729 - CHARPOS (tlendpos)
12730 - MATRIX_ROW_START_CHARPOS (row));
12731 delta_bytes = (Z_BYTE
12732 - BYTEPOS (tlendpos)
12733 - MATRIX_ROW_START_BYTEPOS (row));
12734
12735 increment_matrix_positions (w->current_matrix,
12736 this_line_vpos + 1,
12737 w->current_matrix->nrows,
12738 delta, delta_bytes);
12739 }
12740
12741 /* If this row displays text now but previously didn't,
12742 or vice versa, w->window_end_vpos may have to be
12743 adjusted. */
12744 if ((it.glyph_row - 1)->displays_text_p)
12745 {
12746 if (XFASTINT (w->window_end_vpos) < this_line_vpos)
12747 XSETINT (w->window_end_vpos, this_line_vpos);
12748 }
12749 else if (XFASTINT (w->window_end_vpos) == this_line_vpos
12750 && this_line_vpos > 0)
12751 XSETINT (w->window_end_vpos, this_line_vpos - 1);
12752 w->window_end_valid = Qnil;
12753
12754 /* Update hint: No need to try to scroll in update_window. */
12755 w->desired_matrix->no_scrolling_p = 1;
12756
12757 #if GLYPH_DEBUG
12758 *w->desired_matrix->method = 0;
12759 debug_method_add (w, "optimization 1");
12760 #endif
12761 #ifdef HAVE_WINDOW_SYSTEM
12762 update_window_fringes (w, 0);
12763 #endif
12764 goto update;
12765 }
12766 else
12767 goto cancel;
12768 }
12769 else if (/* Cursor position hasn't changed. */
12770 PT == XFASTINT (w->last_point)
12771 /* Make sure the cursor was last displayed
12772 in this window. Otherwise we have to reposition it. */
12773 && 0 <= w->cursor.vpos
12774 && WINDOW_TOTAL_LINES (w) > w->cursor.vpos)
12775 {
12776 if (!must_finish)
12777 {
12778 do_pending_window_change (1);
12779 /* If selected_window changed, redisplay again. */
12780 if (WINDOWP (selected_window)
12781 && (w = XWINDOW (selected_window)) != sw)
12782 goto retry;
12783
12784 /* We used to always goto end_of_redisplay here, but this
12785 isn't enough if we have a blinking cursor. */
12786 if (w->cursor_off_p == w->last_cursor_off_p)
12787 goto end_of_redisplay;
12788 }
12789 goto update;
12790 }
12791 /* If highlighting the region, or if the cursor is in the echo area,
12792 then we can't just move the cursor. */
12793 else if (! (!NILP (Vtransient_mark_mode)
12794 && !NILP (BVAR (current_buffer, mark_active)))
12795 && (EQ (selected_window, BVAR (current_buffer, last_selected_window))
12796 || highlight_nonselected_windows)
12797 && NILP (w->region_showing)
12798 && NILP (Vshow_trailing_whitespace)
12799 && !cursor_in_echo_area)
12800 {
12801 struct it it;
12802 struct glyph_row *row;
12803
12804 /* Skip from tlbufpos to PT and see where it is. Note that
12805 PT may be in invisible text. If so, we will end at the
12806 next visible position. */
12807 init_iterator (&it, w, CHARPOS (tlbufpos), BYTEPOS (tlbufpos),
12808 NULL, DEFAULT_FACE_ID);
12809 it.current_x = this_line_start_x;
12810 it.current_y = this_line_y;
12811 it.vpos = this_line_vpos;
12812
12813 /* The call to move_it_to stops in front of PT, but
12814 moves over before-strings. */
12815 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
12816
12817 if (it.vpos == this_line_vpos
12818 && (row = MATRIX_ROW (w->current_matrix, this_line_vpos),
12819 row->enabled_p))
12820 {
12821 xassert (this_line_vpos == it.vpos);
12822 xassert (this_line_y == it.current_y);
12823 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
12824 #if GLYPH_DEBUG
12825 *w->desired_matrix->method = 0;
12826 debug_method_add (w, "optimization 3");
12827 #endif
12828 goto update;
12829 }
12830 else
12831 goto cancel;
12832 }
12833
12834 cancel:
12835 /* Text changed drastically or point moved off of line. */
12836 SET_MATRIX_ROW_ENABLED_P (w->desired_matrix, this_line_vpos, 0);
12837 }
12838
12839 CHARPOS (this_line_start_pos) = 0;
12840 consider_all_windows_p |= buffer_shared > 1;
12841 ++clear_face_cache_count;
12842 #ifdef HAVE_WINDOW_SYSTEM
12843 ++clear_image_cache_count;
12844 #endif
12845
12846 /* Build desired matrices, and update the display. If
12847 consider_all_windows_p is non-zero, do it for all windows on all
12848 frames. Otherwise do it for selected_window, only. */
12849
12850 if (consider_all_windows_p)
12851 {
12852 Lisp_Object tail, frame;
12853
12854 FOR_EACH_FRAME (tail, frame)
12855 XFRAME (frame)->updated_p = 0;
12856
12857 /* Recompute # windows showing selected buffer. This will be
12858 incremented each time such a window is displayed. */
12859 buffer_shared = 0;
12860
12861 FOR_EACH_FRAME (tail, frame)
12862 {
12863 struct frame *f = XFRAME (frame);
12864
12865 if (FRAME_WINDOW_P (f) || FRAME_TERMCAP_P (f) || f == sf)
12866 {
12867 if (! EQ (frame, selected_frame))
12868 /* Select the frame, for the sake of frame-local
12869 variables. */
12870 select_frame_for_redisplay (frame);
12871
12872 /* Mark all the scroll bars to be removed; we'll redeem
12873 the ones we want when we redisplay their windows. */
12874 if (FRAME_TERMINAL (f)->condemn_scroll_bars_hook)
12875 FRAME_TERMINAL (f)->condemn_scroll_bars_hook (f);
12876
12877 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
12878 redisplay_windows (FRAME_ROOT_WINDOW (f));
12879
12880 /* The X error handler may have deleted that frame. */
12881 if (!FRAME_LIVE_P (f))
12882 continue;
12883
12884 /* Any scroll bars which redisplay_windows should have
12885 nuked should now go away. */
12886 if (FRAME_TERMINAL (f)->judge_scroll_bars_hook)
12887 FRAME_TERMINAL (f)->judge_scroll_bars_hook (f);
12888
12889 /* If fonts changed, display again. */
12890 /* ??? rms: I suspect it is a mistake to jump all the way
12891 back to retry here. It should just retry this frame. */
12892 if (fonts_changed_p)
12893 goto retry;
12894
12895 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
12896 {
12897 /* See if we have to hscroll. */
12898 if (!f->already_hscrolled_p)
12899 {
12900 f->already_hscrolled_p = 1;
12901 if (hscroll_windows (f->root_window))
12902 goto retry;
12903 }
12904
12905 /* Prevent various kinds of signals during display
12906 update. stdio is not robust about handling
12907 signals, which can cause an apparent I/O
12908 error. */
12909 if (interrupt_input)
12910 unrequest_sigio ();
12911 STOP_POLLING;
12912
12913 /* Update the display. */
12914 set_window_update_flags (XWINDOW (f->root_window), 1);
12915 pending |= update_frame (f, 0, 0);
12916 f->updated_p = 1;
12917 }
12918 }
12919 }
12920
12921 if (!EQ (old_frame, selected_frame)
12922 && FRAME_LIVE_P (XFRAME (old_frame)))
12923 /* We played a bit fast-and-loose above and allowed selected_frame
12924 and selected_window to be temporarily out-of-sync but let's make
12925 sure this stays contained. */
12926 select_frame_for_redisplay (old_frame);
12927 eassert (EQ (XFRAME (selected_frame)->selected_window, selected_window));
12928
12929 if (!pending)
12930 {
12931 /* Do the mark_window_display_accurate after all windows have
12932 been redisplayed because this call resets flags in buffers
12933 which are needed for proper redisplay. */
12934 FOR_EACH_FRAME (tail, frame)
12935 {
12936 struct frame *f = XFRAME (frame);
12937 if (f->updated_p)
12938 {
12939 mark_window_display_accurate (f->root_window, 1);
12940 if (FRAME_TERMINAL (f)->frame_up_to_date_hook)
12941 FRAME_TERMINAL (f)->frame_up_to_date_hook (f);
12942 }
12943 }
12944 }
12945 }
12946 else if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
12947 {
12948 Lisp_Object mini_window;
12949 struct frame *mini_frame;
12950
12951 displayed_buffer = XBUFFER (XWINDOW (selected_window)->buffer);
12952 /* Use list_of_error, not Qerror, so that
12953 we catch only errors and don't run the debugger. */
12954 internal_condition_case_1 (redisplay_window_1, selected_window,
12955 list_of_error,
12956 redisplay_window_error);
12957
12958 /* Compare desired and current matrices, perform output. */
12959
12960 update:
12961 /* If fonts changed, display again. */
12962 if (fonts_changed_p)
12963 goto retry;
12964
12965 /* Prevent various kinds of signals during display update.
12966 stdio is not robust about handling signals,
12967 which can cause an apparent I/O error. */
12968 if (interrupt_input)
12969 unrequest_sigio ();
12970 STOP_POLLING;
12971
12972 if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
12973 {
12974 if (hscroll_windows (selected_window))
12975 goto retry;
12976
12977 XWINDOW (selected_window)->must_be_updated_p = 1;
12978 pending = update_frame (sf, 0, 0);
12979 }
12980
12981 /* We may have called echo_area_display at the top of this
12982 function. If the echo area is on another frame, that may
12983 have put text on a frame other than the selected one, so the
12984 above call to update_frame would not have caught it. Catch
12985 it here. */
12986 mini_window = FRAME_MINIBUF_WINDOW (sf);
12987 mini_frame = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
12988
12989 if (mini_frame != sf && FRAME_WINDOW_P (mini_frame))
12990 {
12991 XWINDOW (mini_window)->must_be_updated_p = 1;
12992 pending |= update_frame (mini_frame, 0, 0);
12993 if (!pending && hscroll_windows (mini_window))
12994 goto retry;
12995 }
12996 }
12997
12998 /* If display was paused because of pending input, make sure we do a
12999 thorough update the next time. */
13000 if (pending)
13001 {
13002 /* Prevent the optimization at the beginning of
13003 redisplay_internal that tries a single-line update of the
13004 line containing the cursor in the selected window. */
13005 CHARPOS (this_line_start_pos) = 0;
13006
13007 /* Let the overlay arrow be updated the next time. */
13008 update_overlay_arrows (0);
13009
13010 /* If we pause after scrolling, some rows in the current
13011 matrices of some windows are not valid. */
13012 if (!WINDOW_FULL_WIDTH_P (w)
13013 && !FRAME_WINDOW_P (XFRAME (w->frame)))
13014 update_mode_lines = 1;
13015 }
13016 else
13017 {
13018 if (!consider_all_windows_p)
13019 {
13020 /* This has already been done above if
13021 consider_all_windows_p is set. */
13022 mark_window_display_accurate_1 (w, 1);
13023
13024 /* Say overlay arrows are up to date. */
13025 update_overlay_arrows (1);
13026
13027 if (FRAME_TERMINAL (sf)->frame_up_to_date_hook != 0)
13028 FRAME_TERMINAL (sf)->frame_up_to_date_hook (sf);
13029 }
13030
13031 update_mode_lines = 0;
13032 windows_or_buffers_changed = 0;
13033 cursor_type_changed = 0;
13034 }
13035
13036 /* Start SIGIO interrupts coming again. Having them off during the
13037 code above makes it less likely one will discard output, but not
13038 impossible, since there might be stuff in the system buffer here.
13039 But it is much hairier to try to do anything about that. */
13040 if (interrupt_input)
13041 request_sigio ();
13042 RESUME_POLLING;
13043
13044 /* If a frame has become visible which was not before, redisplay
13045 again, so that we display it. Expose events for such a frame
13046 (which it gets when becoming visible) don't call the parts of
13047 redisplay constructing glyphs, so simply exposing a frame won't
13048 display anything in this case. So, we have to display these
13049 frames here explicitly. */
13050 if (!pending)
13051 {
13052 Lisp_Object tail, frame;
13053 int new_count = 0;
13054
13055 FOR_EACH_FRAME (tail, frame)
13056 {
13057 int this_is_visible = 0;
13058
13059 if (XFRAME (frame)->visible)
13060 this_is_visible = 1;
13061 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
13062 if (XFRAME (frame)->visible)
13063 this_is_visible = 1;
13064
13065 if (this_is_visible)
13066 new_count++;
13067 }
13068
13069 if (new_count != number_of_visible_frames)
13070 windows_or_buffers_changed++;
13071 }
13072
13073 /* Change frame size now if a change is pending. */
13074 do_pending_window_change (1);
13075
13076 /* If we just did a pending size change, or have additional
13077 visible frames, or selected_window changed, redisplay again. */
13078 if ((windows_or_buffers_changed && !pending)
13079 || (WINDOWP (selected_window) && (w = XWINDOW (selected_window)) != sw))
13080 goto retry;
13081
13082 /* Clear the face and image caches.
13083
13084 We used to do this only if consider_all_windows_p. But the cache
13085 needs to be cleared if a timer creates images in the current
13086 buffer (e.g. the test case in Bug#6230). */
13087
13088 if (clear_face_cache_count > CLEAR_FACE_CACHE_COUNT)
13089 {
13090 clear_face_cache (0);
13091 clear_face_cache_count = 0;
13092 }
13093
13094 #ifdef HAVE_WINDOW_SYSTEM
13095 if (clear_image_cache_count > CLEAR_IMAGE_CACHE_COUNT)
13096 {
13097 clear_image_caches (Qnil);
13098 clear_image_cache_count = 0;
13099 }
13100 #endif /* HAVE_WINDOW_SYSTEM */
13101
13102 end_of_redisplay:
13103 unbind_to (count, Qnil);
13104 RESUME_POLLING;
13105 }
13106
13107
13108 /* Redisplay, but leave alone any recent echo area message unless
13109 another message has been requested in its place.
13110
13111 This is useful in situations where you need to redisplay but no
13112 user action has occurred, making it inappropriate for the message
13113 area to be cleared. See tracking_off and
13114 wait_reading_process_output for examples of these situations.
13115
13116 FROM_WHERE is an integer saying from where this function was
13117 called. This is useful for debugging. */
13118
13119 void
13120 redisplay_preserve_echo_area (int from_where)
13121 {
13122 TRACE ((stderr, "redisplay_preserve_echo_area (%d)\n", from_where));
13123
13124 if (!NILP (echo_area_buffer[1]))
13125 {
13126 /* We have a previously displayed message, but no current
13127 message. Redisplay the previous message. */
13128 display_last_displayed_message_p = 1;
13129 redisplay_internal ();
13130 display_last_displayed_message_p = 0;
13131 }
13132 else
13133 redisplay_internal ();
13134
13135 if (FRAME_RIF (SELECTED_FRAME ()) != NULL
13136 && FRAME_RIF (SELECTED_FRAME ())->flush_display_optional)
13137 FRAME_RIF (SELECTED_FRAME ())->flush_display_optional (NULL);
13138 }
13139
13140
13141 /* Function registered with record_unwind_protect in
13142 redisplay_internal. Reset redisplaying_p to the value it had
13143 before redisplay_internal was called, and clear
13144 prevent_freeing_realized_faces_p. It also selects the previously
13145 selected frame, unless it has been deleted (by an X connection
13146 failure during redisplay, for example). */
13147
13148 static Lisp_Object
13149 unwind_redisplay (Lisp_Object val)
13150 {
13151 Lisp_Object old_redisplaying_p, old_frame;
13152
13153 old_redisplaying_p = XCAR (val);
13154 redisplaying_p = XFASTINT (old_redisplaying_p);
13155 old_frame = XCDR (val);
13156 if (! EQ (old_frame, selected_frame)
13157 && FRAME_LIVE_P (XFRAME (old_frame)))
13158 select_frame_for_redisplay (old_frame);
13159 return Qnil;
13160 }
13161
13162
13163 /* Mark the display of window W as accurate or inaccurate. If
13164 ACCURATE_P is non-zero mark display of W as accurate. If
13165 ACCURATE_P is zero, arrange for W to be redisplayed the next time
13166 redisplay_internal is called. */
13167
13168 static void
13169 mark_window_display_accurate_1 (struct window *w, int accurate_p)
13170 {
13171 if (BUFFERP (w->buffer))
13172 {
13173 struct buffer *b = XBUFFER (w->buffer);
13174
13175 w->last_modified
13176 = make_number (accurate_p ? BUF_MODIFF (b) : 0);
13177 w->last_overlay_modified
13178 = make_number (accurate_p ? BUF_OVERLAY_MODIFF (b) : 0);
13179 w->last_had_star
13180 = BUF_MODIFF (b) > BUF_SAVE_MODIFF (b) ? Qt : Qnil;
13181
13182 if (accurate_p)
13183 {
13184 b->clip_changed = 0;
13185 b->prevent_redisplay_optimizations_p = 0;
13186
13187 BUF_UNCHANGED_MODIFIED (b) = BUF_MODIFF (b);
13188 BUF_OVERLAY_UNCHANGED_MODIFIED (b) = BUF_OVERLAY_MODIFF (b);
13189 BUF_BEG_UNCHANGED (b) = BUF_GPT (b) - BUF_BEG (b);
13190 BUF_END_UNCHANGED (b) = BUF_Z (b) - BUF_GPT (b);
13191
13192 w->current_matrix->buffer = b;
13193 w->current_matrix->begv = BUF_BEGV (b);
13194 w->current_matrix->zv = BUF_ZV (b);
13195
13196 w->last_cursor = w->cursor;
13197 w->last_cursor_off_p = w->cursor_off_p;
13198
13199 if (w == XWINDOW (selected_window))
13200 w->last_point = make_number (BUF_PT (b));
13201 else
13202 w->last_point = make_number (XMARKER (w->pointm)->charpos);
13203 }
13204 }
13205
13206 if (accurate_p)
13207 {
13208 w->window_end_valid = w->buffer;
13209 w->update_mode_line = Qnil;
13210 }
13211 }
13212
13213
13214 /* Mark the display of windows in the window tree rooted at WINDOW as
13215 accurate or inaccurate. If ACCURATE_P is non-zero mark display of
13216 windows as accurate. If ACCURATE_P is zero, arrange for windows to
13217 be redisplayed the next time redisplay_internal is called. */
13218
13219 void
13220 mark_window_display_accurate (Lisp_Object window, int accurate_p)
13221 {
13222 struct window *w;
13223
13224 for (; !NILP (window); window = w->next)
13225 {
13226 w = XWINDOW (window);
13227 mark_window_display_accurate_1 (w, accurate_p);
13228
13229 if (!NILP (w->vchild))
13230 mark_window_display_accurate (w->vchild, accurate_p);
13231 if (!NILP (w->hchild))
13232 mark_window_display_accurate (w->hchild, accurate_p);
13233 }
13234
13235 if (accurate_p)
13236 {
13237 update_overlay_arrows (1);
13238 }
13239 else
13240 {
13241 /* Force a thorough redisplay the next time by setting
13242 last_arrow_position and last_arrow_string to t, which is
13243 unequal to any useful value of Voverlay_arrow_... */
13244 update_overlay_arrows (-1);
13245 }
13246 }
13247
13248
13249 /* Return value in display table DP (Lisp_Char_Table *) for character
13250 C. Since a display table doesn't have any parent, we don't have to
13251 follow parent. Do not call this function directly but use the
13252 macro DISP_CHAR_VECTOR. */
13253
13254 Lisp_Object
13255 disp_char_vector (struct Lisp_Char_Table *dp, int c)
13256 {
13257 Lisp_Object val;
13258
13259 if (ASCII_CHAR_P (c))
13260 {
13261 val = dp->ascii;
13262 if (SUB_CHAR_TABLE_P (val))
13263 val = XSUB_CHAR_TABLE (val)->contents[c];
13264 }
13265 else
13266 {
13267 Lisp_Object table;
13268
13269 XSETCHAR_TABLE (table, dp);
13270 val = char_table_ref (table, c);
13271 }
13272 if (NILP (val))
13273 val = dp->defalt;
13274 return val;
13275 }
13276
13277
13278 \f
13279 /***********************************************************************
13280 Window Redisplay
13281 ***********************************************************************/
13282
13283 /* Redisplay all leaf windows in the window tree rooted at WINDOW. */
13284
13285 static void
13286 redisplay_windows (Lisp_Object window)
13287 {
13288 while (!NILP (window))
13289 {
13290 struct window *w = XWINDOW (window);
13291
13292 if (!NILP (w->hchild))
13293 redisplay_windows (w->hchild);
13294 else if (!NILP (w->vchild))
13295 redisplay_windows (w->vchild);
13296 else if (!NILP (w->buffer))
13297 {
13298 displayed_buffer = XBUFFER (w->buffer);
13299 /* Use list_of_error, not Qerror, so that
13300 we catch only errors and don't run the debugger. */
13301 internal_condition_case_1 (redisplay_window_0, window,
13302 list_of_error,
13303 redisplay_window_error);
13304 }
13305
13306 window = w->next;
13307 }
13308 }
13309
13310 static Lisp_Object
13311 redisplay_window_error (Lisp_Object ignore)
13312 {
13313 displayed_buffer->display_error_modiff = BUF_MODIFF (displayed_buffer);
13314 return Qnil;
13315 }
13316
13317 static Lisp_Object
13318 redisplay_window_0 (Lisp_Object window)
13319 {
13320 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
13321 redisplay_window (window, 0);
13322 return Qnil;
13323 }
13324
13325 static Lisp_Object
13326 redisplay_window_1 (Lisp_Object window)
13327 {
13328 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
13329 redisplay_window (window, 1);
13330 return Qnil;
13331 }
13332 \f
13333
13334 /* Set cursor position of W. PT is assumed to be displayed in ROW.
13335 DELTA and DELTA_BYTES are the numbers of characters and bytes by
13336 which positions recorded in ROW differ from current buffer
13337 positions.
13338
13339 Return 0 if cursor is not on this row, 1 otherwise. */
13340
13341 static int
13342 set_cursor_from_row (struct window *w, struct glyph_row *row,
13343 struct glyph_matrix *matrix,
13344 EMACS_INT delta, EMACS_INT delta_bytes,
13345 int dy, int dvpos)
13346 {
13347 struct glyph *glyph = row->glyphs[TEXT_AREA];
13348 struct glyph *end = glyph + row->used[TEXT_AREA];
13349 struct glyph *cursor = NULL;
13350 /* The last known character position in row. */
13351 EMACS_INT last_pos = MATRIX_ROW_START_CHARPOS (row) + delta;
13352 int x = row->x;
13353 EMACS_INT pt_old = PT - delta;
13354 EMACS_INT pos_before = MATRIX_ROW_START_CHARPOS (row) + delta;
13355 EMACS_INT pos_after = MATRIX_ROW_END_CHARPOS (row) + delta;
13356 struct glyph *glyph_before = glyph - 1, *glyph_after = end;
13357 /* A glyph beyond the edge of TEXT_AREA which we should never
13358 touch. */
13359 struct glyph *glyphs_end = end;
13360 /* Non-zero means we've found a match for cursor position, but that
13361 glyph has the avoid_cursor_p flag set. */
13362 int match_with_avoid_cursor = 0;
13363 /* Non-zero means we've seen at least one glyph that came from a
13364 display string. */
13365 int string_seen = 0;
13366 /* Largest and smalles buffer positions seen so far during scan of
13367 glyph row. */
13368 EMACS_INT bpos_max = pos_before;
13369 EMACS_INT bpos_min = pos_after;
13370 /* Last buffer position covered by an overlay string with an integer
13371 `cursor' property. */
13372 EMACS_INT bpos_covered = 0;
13373 /* Non-zero means the display string on which to display the cursor
13374 comes from a text property, not from an overlay. */
13375 int string_from_text_prop = 0;
13376
13377 /* Skip over glyphs not having an object at the start and the end of
13378 the row. These are special glyphs like truncation marks on
13379 terminal frames. */
13380 if (row->displays_text_p)
13381 {
13382 if (!row->reversed_p)
13383 {
13384 while (glyph < end
13385 && INTEGERP (glyph->object)
13386 && glyph->charpos < 0)
13387 {
13388 x += glyph->pixel_width;
13389 ++glyph;
13390 }
13391 while (end > glyph
13392 && INTEGERP ((end - 1)->object)
13393 /* CHARPOS is zero for blanks and stretch glyphs
13394 inserted by extend_face_to_end_of_line. */
13395 && (end - 1)->charpos <= 0)
13396 --end;
13397 glyph_before = glyph - 1;
13398 glyph_after = end;
13399 }
13400 else
13401 {
13402 struct glyph *g;
13403
13404 /* If the glyph row is reversed, we need to process it from back
13405 to front, so swap the edge pointers. */
13406 glyphs_end = end = glyph - 1;
13407 glyph += row->used[TEXT_AREA] - 1;
13408
13409 while (glyph > end + 1
13410 && INTEGERP (glyph->object)
13411 && glyph->charpos < 0)
13412 {
13413 --glyph;
13414 x -= glyph->pixel_width;
13415 }
13416 if (INTEGERP (glyph->object) && glyph->charpos < 0)
13417 --glyph;
13418 /* By default, in reversed rows we put the cursor on the
13419 rightmost (first in the reading order) glyph. */
13420 for (g = end + 1; g < glyph; g++)
13421 x += g->pixel_width;
13422 while (end < glyph
13423 && INTEGERP ((end + 1)->object)
13424 && (end + 1)->charpos <= 0)
13425 ++end;
13426 glyph_before = glyph + 1;
13427 glyph_after = end;
13428 }
13429 }
13430 else if (row->reversed_p)
13431 {
13432 /* In R2L rows that don't display text, put the cursor on the
13433 rightmost glyph. Case in point: an empty last line that is
13434 part of an R2L paragraph. */
13435 cursor = end - 1;
13436 /* Avoid placing the cursor on the last glyph of the row, where
13437 on terminal frames we hold the vertical border between
13438 adjacent windows. */
13439 if (!FRAME_WINDOW_P (WINDOW_XFRAME (w))
13440 && !WINDOW_RIGHTMOST_P (w)
13441 && cursor == row->glyphs[LAST_AREA] - 1)
13442 cursor--;
13443 x = -1; /* will be computed below, at label compute_x */
13444 }
13445
13446 /* Step 1: Try to find the glyph whose character position
13447 corresponds to point. If that's not possible, find 2 glyphs
13448 whose character positions are the closest to point, one before
13449 point, the other after it. */
13450 if (!row->reversed_p)
13451 while (/* not marched to end of glyph row */
13452 glyph < end
13453 /* glyph was not inserted by redisplay for internal purposes */
13454 && !INTEGERP (glyph->object))
13455 {
13456 if (BUFFERP (glyph->object))
13457 {
13458 EMACS_INT dpos = glyph->charpos - pt_old;
13459
13460 if (glyph->charpos > bpos_max)
13461 bpos_max = glyph->charpos;
13462 if (glyph->charpos < bpos_min)
13463 bpos_min = glyph->charpos;
13464 if (!glyph->avoid_cursor_p)
13465 {
13466 /* If we hit point, we've found the glyph on which to
13467 display the cursor. */
13468 if (dpos == 0)
13469 {
13470 match_with_avoid_cursor = 0;
13471 break;
13472 }
13473 /* See if we've found a better approximation to
13474 POS_BEFORE or to POS_AFTER. Note that we want the
13475 first (leftmost) glyph of all those that are the
13476 closest from below, and the last (rightmost) of all
13477 those from above. */
13478 if (0 > dpos && dpos > pos_before - pt_old)
13479 {
13480 pos_before = glyph->charpos;
13481 glyph_before = glyph;
13482 }
13483 else if (0 < dpos && dpos <= pos_after - pt_old)
13484 {
13485 pos_after = glyph->charpos;
13486 glyph_after = glyph;
13487 }
13488 }
13489 else if (dpos == 0)
13490 match_with_avoid_cursor = 1;
13491 }
13492 else if (STRINGP (glyph->object))
13493 {
13494 Lisp_Object chprop;
13495 EMACS_INT glyph_pos = glyph->charpos;
13496
13497 chprop = Fget_char_property (make_number (glyph_pos), Qcursor,
13498 glyph->object);
13499 if (INTEGERP (chprop))
13500 {
13501 bpos_covered = bpos_max + XINT (chprop);
13502 /* If the `cursor' property covers buffer positions up
13503 to and including point, we should display cursor on
13504 this glyph. Note that overlays and text properties
13505 with string values stop bidi reordering, so every
13506 buffer position to the left of the string is always
13507 smaller than any position to the right of the
13508 string. Therefore, if a `cursor' property on one
13509 of the string's characters has an integer value, we
13510 will break out of the loop below _before_ we get to
13511 the position match above. IOW, integer values of
13512 the `cursor' property override the "exact match for
13513 point" strategy of positioning the cursor. */
13514 /* Implementation note: bpos_max == pt_old when, e.g.,
13515 we are in an empty line, where bpos_max is set to
13516 MATRIX_ROW_START_CHARPOS, see above. */
13517 if (bpos_max <= pt_old && bpos_covered >= pt_old)
13518 {
13519 cursor = glyph;
13520 break;
13521 }
13522 }
13523
13524 string_seen = 1;
13525 }
13526 x += glyph->pixel_width;
13527 ++glyph;
13528 }
13529 else if (glyph > end) /* row is reversed */
13530 while (!INTEGERP (glyph->object))
13531 {
13532 if (BUFFERP (glyph->object))
13533 {
13534 EMACS_INT dpos = glyph->charpos - pt_old;
13535
13536 if (glyph->charpos > bpos_max)
13537 bpos_max = glyph->charpos;
13538 if (glyph->charpos < bpos_min)
13539 bpos_min = glyph->charpos;
13540 if (!glyph->avoid_cursor_p)
13541 {
13542 if (dpos == 0)
13543 {
13544 match_with_avoid_cursor = 0;
13545 break;
13546 }
13547 if (0 > dpos && dpos > pos_before - pt_old)
13548 {
13549 pos_before = glyph->charpos;
13550 glyph_before = glyph;
13551 }
13552 else if (0 < dpos && dpos <= pos_after - pt_old)
13553 {
13554 pos_after = glyph->charpos;
13555 glyph_after = glyph;
13556 }
13557 }
13558 else if (dpos == 0)
13559 match_with_avoid_cursor = 1;
13560 }
13561 else if (STRINGP (glyph->object))
13562 {
13563 Lisp_Object chprop;
13564 EMACS_INT glyph_pos = glyph->charpos;
13565
13566 chprop = Fget_char_property (make_number (glyph_pos), Qcursor,
13567 glyph->object);
13568 if (INTEGERP (chprop))
13569 {
13570 bpos_covered = bpos_max + XINT (chprop);
13571 /* If the `cursor' property covers buffer positions up
13572 to and including point, we should display cursor on
13573 this glyph. */
13574 if (bpos_max <= pt_old && bpos_covered >= pt_old)
13575 {
13576 cursor = glyph;
13577 break;
13578 }
13579 }
13580 string_seen = 1;
13581 }
13582 --glyph;
13583 if (glyph == glyphs_end) /* don't dereference outside TEXT_AREA */
13584 {
13585 x--; /* can't use any pixel_width */
13586 break;
13587 }
13588 x -= glyph->pixel_width;
13589 }
13590
13591 /* Step 2: If we didn't find an exact match for point, we need to
13592 look for a proper place to put the cursor among glyphs between
13593 GLYPH_BEFORE and GLYPH_AFTER. */
13594 if (!((row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end)
13595 && BUFFERP (glyph->object) && glyph->charpos == pt_old)
13596 && bpos_covered < pt_old)
13597 {
13598 /* An empty line has a single glyph whose OBJECT is zero and
13599 whose CHARPOS is the position of a newline on that line.
13600 Note that on a TTY, there are more glyphs after that, which
13601 were produced by extend_face_to_end_of_line, but their
13602 CHARPOS is zero or negative. */
13603 int empty_line_p =
13604 (row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end)
13605 && INTEGERP (glyph->object) && glyph->charpos > 0;
13606
13607 if (row->ends_in_ellipsis_p && pos_after == last_pos)
13608 {
13609 EMACS_INT ellipsis_pos;
13610
13611 /* Scan back over the ellipsis glyphs. */
13612 if (!row->reversed_p)
13613 {
13614 ellipsis_pos = (glyph - 1)->charpos;
13615 while (glyph > row->glyphs[TEXT_AREA]
13616 && (glyph - 1)->charpos == ellipsis_pos)
13617 glyph--, x -= glyph->pixel_width;
13618 /* That loop always goes one position too far, including
13619 the glyph before the ellipsis. So scan forward over
13620 that one. */
13621 x += glyph->pixel_width;
13622 glyph++;
13623 }
13624 else /* row is reversed */
13625 {
13626 ellipsis_pos = (glyph + 1)->charpos;
13627 while (glyph < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1
13628 && (glyph + 1)->charpos == ellipsis_pos)
13629 glyph++, x += glyph->pixel_width;
13630 x -= glyph->pixel_width;
13631 glyph--;
13632 }
13633 }
13634 else if (match_with_avoid_cursor
13635 /* A truncated row may not include PT among its
13636 character positions. Setting the cursor inside the
13637 scroll margin will trigger recalculation of hscroll
13638 in hscroll_window_tree. */
13639 || (row->truncated_on_left_p && pt_old < bpos_min)
13640 || (row->truncated_on_right_p && pt_old > bpos_max)
13641 /* Zero-width characters produce no glyphs. */
13642 || (!string_seen
13643 && !empty_line_p
13644 && (row->reversed_p
13645 ? glyph_after > glyphs_end
13646 : glyph_after < glyphs_end)))
13647 {
13648 cursor = glyph_after;
13649 x = -1;
13650 }
13651 else if (string_seen)
13652 {
13653 int incr = row->reversed_p ? -1 : +1;
13654
13655 /* Need to find the glyph that came out of a string which is
13656 present at point. That glyph is somewhere between
13657 GLYPH_BEFORE and GLYPH_AFTER, and it came from a string
13658 positioned between POS_BEFORE and POS_AFTER in the
13659 buffer. */
13660 struct glyph *start, *stop;
13661 EMACS_INT pos = pos_before;
13662
13663 x = -1;
13664
13665 /* GLYPH_BEFORE and GLYPH_AFTER are the glyphs that
13666 correspond to POS_BEFORE and POS_AFTER, respectively. We
13667 need START and STOP in the order that corresponds to the
13668 row's direction as given by its reversed_p flag. If the
13669 directionality of characters between POS_BEFORE and
13670 POS_AFTER is the opposite of the row's base direction,
13671 these characters will have been reordered for display,
13672 and we need to reverse START and STOP. */
13673 if (!row->reversed_p)
13674 {
13675 start = min (glyph_before, glyph_after);
13676 stop = max (glyph_before, glyph_after);
13677 }
13678 else
13679 {
13680 start = max (glyph_before, glyph_after);
13681 stop = min (glyph_before, glyph_after);
13682 }
13683 for (glyph = start + incr;
13684 row->reversed_p ? glyph > stop : glyph < stop; )
13685 {
13686
13687 /* Any glyphs that come from the buffer are here because
13688 of bidi reordering. Skip them, and only pay
13689 attention to glyphs that came from some string. */
13690 if (STRINGP (glyph->object))
13691 {
13692 Lisp_Object str;
13693 EMACS_INT tem;
13694 /* If the display property covers the newline, we
13695 need to search for it one position farther. */
13696 EMACS_INT lim = pos_after
13697 + (pos_after == MATRIX_ROW_END_CHARPOS (row) + delta);
13698
13699 string_from_text_prop = 0;
13700 str = glyph->object;
13701 tem = string_buffer_position_lim (str, pos, lim, 0);
13702 if (tem == 0 /* from overlay */
13703 || pos <= tem)
13704 {
13705 /* If the string from which this glyph came is
13706 found in the buffer at point, then we've
13707 found the glyph we've been looking for. If
13708 it comes from an overlay (tem == 0), and it
13709 has the `cursor' property on one of its
13710 glyphs, record that glyph as a candidate for
13711 displaying the cursor. (As in the
13712 unidirectional version, we will display the
13713 cursor on the last candidate we find.) */
13714 if (tem == 0 || tem == pt_old)
13715 {
13716 /* The glyphs from this string could have
13717 been reordered. Find the one with the
13718 smallest string position. Or there could
13719 be a character in the string with the
13720 `cursor' property, which means display
13721 cursor on that character's glyph. */
13722 EMACS_INT strpos = glyph->charpos;
13723
13724 if (tem)
13725 {
13726 cursor = glyph;
13727 string_from_text_prop = 1;
13728 }
13729 for ( ;
13730 (row->reversed_p ? glyph > stop : glyph < stop)
13731 && EQ (glyph->object, str);
13732 glyph += incr)
13733 {
13734 Lisp_Object cprop;
13735 EMACS_INT gpos = glyph->charpos;
13736
13737 cprop = Fget_char_property (make_number (gpos),
13738 Qcursor,
13739 glyph->object);
13740 if (!NILP (cprop))
13741 {
13742 cursor = glyph;
13743 break;
13744 }
13745 if (tem && glyph->charpos < strpos)
13746 {
13747 strpos = glyph->charpos;
13748 cursor = glyph;
13749 }
13750 }
13751
13752 if (tem == pt_old)
13753 goto compute_x;
13754 }
13755 if (tem)
13756 pos = tem + 1; /* don't find previous instances */
13757 }
13758 /* This string is not what we want; skip all of the
13759 glyphs that came from it. */
13760 while ((row->reversed_p ? glyph > stop : glyph < stop)
13761 && EQ (glyph->object, str))
13762 glyph += incr;
13763 }
13764 else
13765 glyph += incr;
13766 }
13767
13768 /* If we reached the end of the line, and END was from a string,
13769 the cursor is not on this line. */
13770 if (cursor == NULL
13771 && (row->reversed_p ? glyph <= end : glyph >= end)
13772 && STRINGP (end->object)
13773 && row->continued_p)
13774 return 0;
13775 }
13776 }
13777
13778 compute_x:
13779 if (cursor != NULL)
13780 glyph = cursor;
13781 if (x < 0)
13782 {
13783 struct glyph *g;
13784
13785 /* Need to compute x that corresponds to GLYPH. */
13786 for (g = row->glyphs[TEXT_AREA], x = row->x; g < glyph; g++)
13787 {
13788 if (g >= row->glyphs[TEXT_AREA] + row->used[TEXT_AREA])
13789 abort ();
13790 x += g->pixel_width;
13791 }
13792 }
13793
13794 /* ROW could be part of a continued line, which, under bidi
13795 reordering, might have other rows whose start and end charpos
13796 occlude point. Only set w->cursor if we found a better
13797 approximation to the cursor position than we have from previously
13798 examined candidate rows belonging to the same continued line. */
13799 if (/* we already have a candidate row */
13800 w->cursor.vpos >= 0
13801 /* that candidate is not the row we are processing */
13802 && MATRIX_ROW (matrix, w->cursor.vpos) != row
13803 /* Make sure cursor.vpos specifies a row whose start and end
13804 charpos occlude point, and it is valid candidate for being a
13805 cursor-row. This is because some callers of this function
13806 leave cursor.vpos at the row where the cursor was displayed
13807 during the last redisplay cycle. */
13808 && MATRIX_ROW_START_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos)) <= pt_old
13809 && pt_old <= MATRIX_ROW_END_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))
13810 && cursor_row_p (MATRIX_ROW (matrix, w->cursor.vpos)))
13811 {
13812 struct glyph *g1 =
13813 MATRIX_ROW_GLYPH_START (matrix, w->cursor.vpos) + w->cursor.hpos;
13814
13815 /* Don't consider glyphs that are outside TEXT_AREA. */
13816 if (!(row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end))
13817 return 0;
13818 /* Keep the candidate whose buffer position is the closest to
13819 point or has the `cursor' property. */
13820 if (/* previous candidate is a glyph in TEXT_AREA of that row */
13821 w->cursor.hpos >= 0
13822 && w->cursor.hpos < MATRIX_ROW_USED (matrix, w->cursor.vpos)
13823 && ((BUFFERP (g1->object)
13824 && (g1->charpos == pt_old /* an exact match always wins */
13825 || (BUFFERP (glyph->object)
13826 && eabs (g1->charpos - pt_old)
13827 < eabs (glyph->charpos - pt_old))))
13828 /* previous candidate is a glyph from a string that has
13829 a non-nil `cursor' property */
13830 || (STRINGP (g1->object)
13831 && (!NILP (Fget_char_property (make_number (g1->charpos),
13832 Qcursor, g1->object))
13833 /* pevious candidate is from the same display
13834 string as this one, and the display string
13835 came from a text property */
13836 || (EQ (g1->object, glyph->object)
13837 && string_from_text_prop)
13838 /* this candidate is from newline and its
13839 position is not an exact match */
13840 || (INTEGERP (glyph->object)
13841 && glyph->charpos != pt_old)))))
13842 return 0;
13843 /* If this candidate gives an exact match, use that. */
13844 if (!((BUFFERP (glyph->object) && glyph->charpos == pt_old)
13845 /* If this candidate is a glyph created for the
13846 terminating newline of a line, and point is on that
13847 newline, it wins because it's an exact match. */
13848 || (!row->continued_p
13849 && INTEGERP (glyph->object)
13850 && glyph->charpos == 0
13851 && pt_old == MATRIX_ROW_END_CHARPOS (row) - 1))
13852 /* Otherwise, keep the candidate that comes from a row
13853 spanning less buffer positions. This may win when one or
13854 both candidate positions are on glyphs that came from
13855 display strings, for which we cannot compare buffer
13856 positions. */
13857 && MATRIX_ROW_END_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))
13858 - MATRIX_ROW_START_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))
13859 < MATRIX_ROW_END_CHARPOS (row) - MATRIX_ROW_START_CHARPOS (row))
13860 return 0;
13861 }
13862 w->cursor.hpos = glyph - row->glyphs[TEXT_AREA];
13863 w->cursor.x = x;
13864 w->cursor.vpos = MATRIX_ROW_VPOS (row, matrix) + dvpos;
13865 w->cursor.y = row->y + dy;
13866
13867 if (w == XWINDOW (selected_window))
13868 {
13869 if (!row->continued_p
13870 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
13871 && row->x == 0)
13872 {
13873 this_line_buffer = XBUFFER (w->buffer);
13874
13875 CHARPOS (this_line_start_pos)
13876 = MATRIX_ROW_START_CHARPOS (row) + delta;
13877 BYTEPOS (this_line_start_pos)
13878 = MATRIX_ROW_START_BYTEPOS (row) + delta_bytes;
13879
13880 CHARPOS (this_line_end_pos)
13881 = Z - (MATRIX_ROW_END_CHARPOS (row) + delta);
13882 BYTEPOS (this_line_end_pos)
13883 = Z_BYTE - (MATRIX_ROW_END_BYTEPOS (row) + delta_bytes);
13884
13885 this_line_y = w->cursor.y;
13886 this_line_pixel_height = row->height;
13887 this_line_vpos = w->cursor.vpos;
13888 this_line_start_x = row->x;
13889 }
13890 else
13891 CHARPOS (this_line_start_pos) = 0;
13892 }
13893
13894 return 1;
13895 }
13896
13897
13898 /* Run window scroll functions, if any, for WINDOW with new window
13899 start STARTP. Sets the window start of WINDOW to that position.
13900
13901 We assume that the window's buffer is really current. */
13902
13903 static inline struct text_pos
13904 run_window_scroll_functions (Lisp_Object window, struct text_pos startp)
13905 {
13906 struct window *w = XWINDOW (window);
13907 SET_MARKER_FROM_TEXT_POS (w->start, startp);
13908
13909 if (current_buffer != XBUFFER (w->buffer))
13910 abort ();
13911
13912 if (!NILP (Vwindow_scroll_functions))
13913 {
13914 run_hook_with_args_2 (Qwindow_scroll_functions, window,
13915 make_number (CHARPOS (startp)));
13916 SET_TEXT_POS_FROM_MARKER (startp, w->start);
13917 /* In case the hook functions switch buffers. */
13918 if (current_buffer != XBUFFER (w->buffer))
13919 set_buffer_internal_1 (XBUFFER (w->buffer));
13920 }
13921
13922 return startp;
13923 }
13924
13925
13926 /* Make sure the line containing the cursor is fully visible.
13927 A value of 1 means there is nothing to be done.
13928 (Either the line is fully visible, or it cannot be made so,
13929 or we cannot tell.)
13930
13931 If FORCE_P is non-zero, return 0 even if partial visible cursor row
13932 is higher than window.
13933
13934 A value of 0 means the caller should do scrolling
13935 as if point had gone off the screen. */
13936
13937 static int
13938 cursor_row_fully_visible_p (struct window *w, int force_p, int current_matrix_p)
13939 {
13940 struct glyph_matrix *matrix;
13941 struct glyph_row *row;
13942 int window_height;
13943
13944 if (!make_cursor_line_fully_visible_p)
13945 return 1;
13946
13947 /* It's not always possible to find the cursor, e.g, when a window
13948 is full of overlay strings. Don't do anything in that case. */
13949 if (w->cursor.vpos < 0)
13950 return 1;
13951
13952 matrix = current_matrix_p ? w->current_matrix : w->desired_matrix;
13953 row = MATRIX_ROW (matrix, w->cursor.vpos);
13954
13955 /* If the cursor row is not partially visible, there's nothing to do. */
13956 if (!MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row))
13957 return 1;
13958
13959 /* If the row the cursor is in is taller than the window's height,
13960 it's not clear what to do, so do nothing. */
13961 window_height = window_box_height (w);
13962 if (row->height >= window_height)
13963 {
13964 if (!force_p || MINI_WINDOW_P (w)
13965 || w->vscroll || w->cursor.vpos == 0)
13966 return 1;
13967 }
13968 return 0;
13969 }
13970
13971
13972 /* Try scrolling PT into view in window WINDOW. JUST_THIS_ONE_P
13973 non-zero means only WINDOW is redisplayed in redisplay_internal.
13974 TEMP_SCROLL_STEP has the same meaning as emacs_scroll_step, and is used
13975 in redisplay_window to bring a partially visible line into view in
13976 the case that only the cursor has moved.
13977
13978 LAST_LINE_MISFIT should be nonzero if we're scrolling because the
13979 last screen line's vertical height extends past the end of the screen.
13980
13981 Value is
13982
13983 1 if scrolling succeeded
13984
13985 0 if scrolling didn't find point.
13986
13987 -1 if new fonts have been loaded so that we must interrupt
13988 redisplay, adjust glyph matrices, and try again. */
13989
13990 enum
13991 {
13992 SCROLLING_SUCCESS,
13993 SCROLLING_FAILED,
13994 SCROLLING_NEED_LARGER_MATRICES
13995 };
13996
13997 /* If scroll-conservatively is more than this, never recenter.
13998
13999 If you change this, don't forget to update the doc string of
14000 `scroll-conservatively' and the Emacs manual. */
14001 #define SCROLL_LIMIT 100
14002
14003 static int
14004 try_scrolling (Lisp_Object window, int just_this_one_p,
14005 EMACS_INT arg_scroll_conservatively, EMACS_INT scroll_step,
14006 int temp_scroll_step, int last_line_misfit)
14007 {
14008 struct window *w = XWINDOW (window);
14009 struct frame *f = XFRAME (w->frame);
14010 struct text_pos pos, startp;
14011 struct it it;
14012 int this_scroll_margin, scroll_max, rc, height;
14013 int dy = 0, amount_to_scroll = 0, scroll_down_p = 0;
14014 int extra_scroll_margin_lines = last_line_misfit ? 1 : 0;
14015 Lisp_Object aggressive;
14016 /* We will never try scrolling more than this number of lines. */
14017 int scroll_limit = SCROLL_LIMIT;
14018
14019 #if GLYPH_DEBUG
14020 debug_method_add (w, "try_scrolling");
14021 #endif
14022
14023 SET_TEXT_POS_FROM_MARKER (startp, w->start);
14024
14025 /* Compute scroll margin height in pixels. We scroll when point is
14026 within this distance from the top or bottom of the window. */
14027 if (scroll_margin > 0)
14028 this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4)
14029 * FRAME_LINE_HEIGHT (f);
14030 else
14031 this_scroll_margin = 0;
14032
14033 /* Force arg_scroll_conservatively to have a reasonable value, to
14034 avoid scrolling too far away with slow move_it_* functions. Note
14035 that the user can supply scroll-conservatively equal to
14036 `most-positive-fixnum', which can be larger than INT_MAX. */
14037 if (arg_scroll_conservatively > scroll_limit)
14038 {
14039 arg_scroll_conservatively = scroll_limit + 1;
14040 scroll_max = scroll_limit * FRAME_LINE_HEIGHT (f);
14041 }
14042 else if (scroll_step || arg_scroll_conservatively || temp_scroll_step)
14043 /* Compute how much we should try to scroll maximally to bring
14044 point into view. */
14045 scroll_max = (max (scroll_step,
14046 max (arg_scroll_conservatively, temp_scroll_step))
14047 * FRAME_LINE_HEIGHT (f));
14048 else if (NUMBERP (BVAR (current_buffer, scroll_down_aggressively))
14049 || NUMBERP (BVAR (current_buffer, scroll_up_aggressively)))
14050 /* We're trying to scroll because of aggressive scrolling but no
14051 scroll_step is set. Choose an arbitrary one. */
14052 scroll_max = 10 * FRAME_LINE_HEIGHT (f);
14053 else
14054 scroll_max = 0;
14055
14056 too_near_end:
14057
14058 /* Decide whether to scroll down. */
14059 if (PT > CHARPOS (startp))
14060 {
14061 int scroll_margin_y;
14062
14063 /* Compute the pixel ypos of the scroll margin, then move it to
14064 either that ypos or PT, whichever comes first. */
14065 start_display (&it, w, startp);
14066 scroll_margin_y = it.last_visible_y - this_scroll_margin
14067 - FRAME_LINE_HEIGHT (f) * extra_scroll_margin_lines;
14068 move_it_to (&it, PT, -1, scroll_margin_y - 1, -1,
14069 (MOVE_TO_POS | MOVE_TO_Y));
14070
14071 if (PT > CHARPOS (it.current.pos))
14072 {
14073 int y0 = line_bottom_y (&it);
14074 /* Compute how many pixels below window bottom to stop searching
14075 for PT. This avoids costly search for PT that is far away if
14076 the user limited scrolling by a small number of lines, but
14077 always finds PT if scroll_conservatively is set to a large
14078 number, such as most-positive-fixnum. */
14079 int slack = max (scroll_max, 10 * FRAME_LINE_HEIGHT (f));
14080 int y_to_move = it.last_visible_y + slack;
14081
14082 /* Compute the distance from the scroll margin to PT or to
14083 the scroll limit, whichever comes first. This should
14084 include the height of the cursor line, to make that line
14085 fully visible. */
14086 move_it_to (&it, PT, -1, y_to_move,
14087 -1, MOVE_TO_POS | MOVE_TO_Y);
14088 dy = line_bottom_y (&it) - y0;
14089
14090 if (dy > scroll_max)
14091 return SCROLLING_FAILED;
14092
14093 scroll_down_p = 1;
14094 }
14095 }
14096
14097 if (scroll_down_p)
14098 {
14099 /* Point is in or below the bottom scroll margin, so move the
14100 window start down. If scrolling conservatively, move it just
14101 enough down to make point visible. If scroll_step is set,
14102 move it down by scroll_step. */
14103 if (arg_scroll_conservatively)
14104 amount_to_scroll
14105 = min (max (dy, FRAME_LINE_HEIGHT (f)),
14106 FRAME_LINE_HEIGHT (f) * arg_scroll_conservatively);
14107 else if (scroll_step || temp_scroll_step)
14108 amount_to_scroll = scroll_max;
14109 else
14110 {
14111 aggressive = BVAR (current_buffer, scroll_up_aggressively);
14112 height = WINDOW_BOX_TEXT_HEIGHT (w);
14113 if (NUMBERP (aggressive))
14114 {
14115 double float_amount = XFLOATINT (aggressive) * height;
14116 amount_to_scroll = float_amount;
14117 if (amount_to_scroll == 0 && float_amount > 0)
14118 amount_to_scroll = 1;
14119 /* Don't let point enter the scroll margin near top of
14120 the window. */
14121 if (amount_to_scroll > height - 2*this_scroll_margin + dy)
14122 amount_to_scroll = height - 2*this_scroll_margin + dy;
14123 }
14124 }
14125
14126 if (amount_to_scroll <= 0)
14127 return SCROLLING_FAILED;
14128
14129 start_display (&it, w, startp);
14130 if (arg_scroll_conservatively <= scroll_limit)
14131 move_it_vertically (&it, amount_to_scroll);
14132 else
14133 {
14134 /* Extra precision for users who set scroll-conservatively
14135 to a large number: make sure the amount we scroll
14136 the window start is never less than amount_to_scroll,
14137 which was computed as distance from window bottom to
14138 point. This matters when lines at window top and lines
14139 below window bottom have different height. */
14140 struct it it1;
14141 void *it1data = NULL;
14142 /* We use a temporary it1 because line_bottom_y can modify
14143 its argument, if it moves one line down; see there. */
14144 int start_y;
14145
14146 SAVE_IT (it1, it, it1data);
14147 start_y = line_bottom_y (&it1);
14148 do {
14149 RESTORE_IT (&it, &it, it1data);
14150 move_it_by_lines (&it, 1);
14151 SAVE_IT (it1, it, it1data);
14152 } while (line_bottom_y (&it1) - start_y < amount_to_scroll);
14153 }
14154
14155 /* If STARTP is unchanged, move it down another screen line. */
14156 if (CHARPOS (it.current.pos) == CHARPOS (startp))
14157 move_it_by_lines (&it, 1);
14158 startp = it.current.pos;
14159 }
14160 else
14161 {
14162 struct text_pos scroll_margin_pos = startp;
14163
14164 /* See if point is inside the scroll margin at the top of the
14165 window. */
14166 if (this_scroll_margin)
14167 {
14168 start_display (&it, w, startp);
14169 move_it_vertically (&it, this_scroll_margin);
14170 scroll_margin_pos = it.current.pos;
14171 }
14172
14173 if (PT < CHARPOS (scroll_margin_pos))
14174 {
14175 /* Point is in the scroll margin at the top of the window or
14176 above what is displayed in the window. */
14177 int y0, y_to_move;
14178
14179 /* Compute the vertical distance from PT to the scroll
14180 margin position. Move as far as scroll_max allows, or
14181 one screenful, or 10 screen lines, whichever is largest.
14182 Give up if distance is greater than scroll_max. */
14183 SET_TEXT_POS (pos, PT, PT_BYTE);
14184 start_display (&it, w, pos);
14185 y0 = it.current_y;
14186 y_to_move = max (it.last_visible_y,
14187 max (scroll_max, 10 * FRAME_LINE_HEIGHT (f)));
14188 move_it_to (&it, CHARPOS (scroll_margin_pos), 0,
14189 y_to_move, -1,
14190 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
14191 dy = it.current_y - y0;
14192 if (dy > scroll_max)
14193 return SCROLLING_FAILED;
14194
14195 /* Compute new window start. */
14196 start_display (&it, w, startp);
14197
14198 if (arg_scroll_conservatively)
14199 amount_to_scroll = max (dy, FRAME_LINE_HEIGHT (f) *
14200 max (scroll_step, temp_scroll_step));
14201 else if (scroll_step || temp_scroll_step)
14202 amount_to_scroll = scroll_max;
14203 else
14204 {
14205 aggressive = BVAR (current_buffer, scroll_down_aggressively);
14206 height = WINDOW_BOX_TEXT_HEIGHT (w);
14207 if (NUMBERP (aggressive))
14208 {
14209 double float_amount = XFLOATINT (aggressive) * height;
14210 amount_to_scroll = float_amount;
14211 if (amount_to_scroll == 0 && float_amount > 0)
14212 amount_to_scroll = 1;
14213 amount_to_scroll -=
14214 this_scroll_margin - dy - FRAME_LINE_HEIGHT (f);
14215 /* Don't let point enter the scroll margin near
14216 bottom of the window. */
14217 if (amount_to_scroll > height - 2*this_scroll_margin + dy)
14218 amount_to_scroll = height - 2*this_scroll_margin + dy;
14219 }
14220 }
14221
14222 if (amount_to_scroll <= 0)
14223 return SCROLLING_FAILED;
14224
14225 move_it_vertically_backward (&it, amount_to_scroll);
14226 startp = it.current.pos;
14227 }
14228 }
14229
14230 /* Run window scroll functions. */
14231 startp = run_window_scroll_functions (window, startp);
14232
14233 /* Display the window. Give up if new fonts are loaded, or if point
14234 doesn't appear. */
14235 if (!try_window (window, startp, 0))
14236 rc = SCROLLING_NEED_LARGER_MATRICES;
14237 else if (w->cursor.vpos < 0)
14238 {
14239 clear_glyph_matrix (w->desired_matrix);
14240 rc = SCROLLING_FAILED;
14241 }
14242 else
14243 {
14244 /* Maybe forget recorded base line for line number display. */
14245 if (!just_this_one_p
14246 || current_buffer->clip_changed
14247 || BEG_UNCHANGED < CHARPOS (startp))
14248 w->base_line_number = Qnil;
14249
14250 /* If cursor ends up on a partially visible line,
14251 treat that as being off the bottom of the screen. */
14252 if (! cursor_row_fully_visible_p (w, extra_scroll_margin_lines <= 1, 0)
14253 /* It's possible that the cursor is on the first line of the
14254 buffer, which is partially obscured due to a vscroll
14255 (Bug#7537). In that case, avoid looping forever . */
14256 && extra_scroll_margin_lines < w->desired_matrix->nrows - 1)
14257 {
14258 clear_glyph_matrix (w->desired_matrix);
14259 ++extra_scroll_margin_lines;
14260 goto too_near_end;
14261 }
14262 rc = SCROLLING_SUCCESS;
14263 }
14264
14265 return rc;
14266 }
14267
14268
14269 /* Compute a suitable window start for window W if display of W starts
14270 on a continuation line. Value is non-zero if a new window start
14271 was computed.
14272
14273 The new window start will be computed, based on W's width, starting
14274 from the start of the continued line. It is the start of the
14275 screen line with the minimum distance from the old start W->start. */
14276
14277 static int
14278 compute_window_start_on_continuation_line (struct window *w)
14279 {
14280 struct text_pos pos, start_pos;
14281 int window_start_changed_p = 0;
14282
14283 SET_TEXT_POS_FROM_MARKER (start_pos, w->start);
14284
14285 /* If window start is on a continuation line... Window start may be
14286 < BEGV in case there's invisible text at the start of the
14287 buffer (M-x rmail, for example). */
14288 if (CHARPOS (start_pos) > BEGV
14289 && FETCH_BYTE (BYTEPOS (start_pos) - 1) != '\n')
14290 {
14291 struct it it;
14292 struct glyph_row *row;
14293
14294 /* Handle the case that the window start is out of range. */
14295 if (CHARPOS (start_pos) < BEGV)
14296 SET_TEXT_POS (start_pos, BEGV, BEGV_BYTE);
14297 else if (CHARPOS (start_pos) > ZV)
14298 SET_TEXT_POS (start_pos, ZV, ZV_BYTE);
14299
14300 /* Find the start of the continued line. This should be fast
14301 because scan_buffer is fast (newline cache). */
14302 row = w->desired_matrix->rows + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0);
14303 init_iterator (&it, w, CHARPOS (start_pos), BYTEPOS (start_pos),
14304 row, DEFAULT_FACE_ID);
14305 reseat_at_previous_visible_line_start (&it);
14306
14307 /* If the line start is "too far" away from the window start,
14308 say it takes too much time to compute a new window start. */
14309 if (CHARPOS (start_pos) - IT_CHARPOS (it)
14310 < WINDOW_TOTAL_LINES (w) * WINDOW_TOTAL_COLS (w))
14311 {
14312 int min_distance, distance;
14313
14314 /* Move forward by display lines to find the new window
14315 start. If window width was enlarged, the new start can
14316 be expected to be > the old start. If window width was
14317 decreased, the new window start will be < the old start.
14318 So, we're looking for the display line start with the
14319 minimum distance from the old window start. */
14320 pos = it.current.pos;
14321 min_distance = INFINITY;
14322 while ((distance = eabs (CHARPOS (start_pos) - IT_CHARPOS (it))),
14323 distance < min_distance)
14324 {
14325 min_distance = distance;
14326 pos = it.current.pos;
14327 move_it_by_lines (&it, 1);
14328 }
14329
14330 /* Set the window start there. */
14331 SET_MARKER_FROM_TEXT_POS (w->start, pos);
14332 window_start_changed_p = 1;
14333 }
14334 }
14335
14336 return window_start_changed_p;
14337 }
14338
14339
14340 /* Try cursor movement in case text has not changed in window WINDOW,
14341 with window start STARTP. Value is
14342
14343 CURSOR_MOVEMENT_SUCCESS if successful
14344
14345 CURSOR_MOVEMENT_CANNOT_BE_USED if this method cannot be used
14346
14347 CURSOR_MOVEMENT_MUST_SCROLL if we know we have to scroll the
14348 display. *SCROLL_STEP is set to 1, under certain circumstances, if
14349 we want to scroll as if scroll-step were set to 1. See the code.
14350
14351 CURSOR_MOVEMENT_NEED_LARGER_MATRICES if we need larger matrices, in
14352 which case we have to abort this redisplay, and adjust matrices
14353 first. */
14354
14355 enum
14356 {
14357 CURSOR_MOVEMENT_SUCCESS,
14358 CURSOR_MOVEMENT_CANNOT_BE_USED,
14359 CURSOR_MOVEMENT_MUST_SCROLL,
14360 CURSOR_MOVEMENT_NEED_LARGER_MATRICES
14361 };
14362
14363 static int
14364 try_cursor_movement (Lisp_Object window, struct text_pos startp, int *scroll_step)
14365 {
14366 struct window *w = XWINDOW (window);
14367 struct frame *f = XFRAME (w->frame);
14368 int rc = CURSOR_MOVEMENT_CANNOT_BE_USED;
14369
14370 #if GLYPH_DEBUG
14371 if (inhibit_try_cursor_movement)
14372 return rc;
14373 #endif
14374
14375 /* Handle case where text has not changed, only point, and it has
14376 not moved off the frame. */
14377 if (/* Point may be in this window. */
14378 PT >= CHARPOS (startp)
14379 /* Selective display hasn't changed. */
14380 && !current_buffer->clip_changed
14381 /* Function force-mode-line-update is used to force a thorough
14382 redisplay. It sets either windows_or_buffers_changed or
14383 update_mode_lines. So don't take a shortcut here for these
14384 cases. */
14385 && !update_mode_lines
14386 && !windows_or_buffers_changed
14387 && !cursor_type_changed
14388 /* Can't use this case if highlighting a region. When a
14389 region exists, cursor movement has to do more than just
14390 set the cursor. */
14391 && !(!NILP (Vtransient_mark_mode)
14392 && !NILP (BVAR (current_buffer, mark_active)))
14393 && NILP (w->region_showing)
14394 && NILP (Vshow_trailing_whitespace)
14395 /* Right after splitting windows, last_point may be nil. */
14396 && INTEGERP (w->last_point)
14397 /* This code is not used for mini-buffer for the sake of the case
14398 of redisplaying to replace an echo area message; since in
14399 that case the mini-buffer contents per se are usually
14400 unchanged. This code is of no real use in the mini-buffer
14401 since the handling of this_line_start_pos, etc., in redisplay
14402 handles the same cases. */
14403 && !EQ (window, minibuf_window)
14404 /* When splitting windows or for new windows, it happens that
14405 redisplay is called with a nil window_end_vpos or one being
14406 larger than the window. This should really be fixed in
14407 window.c. I don't have this on my list, now, so we do
14408 approximately the same as the old redisplay code. --gerd. */
14409 && INTEGERP (w->window_end_vpos)
14410 && XFASTINT (w->window_end_vpos) < w->current_matrix->nrows
14411 && (FRAME_WINDOW_P (f)
14412 || !overlay_arrow_in_current_buffer_p ()))
14413 {
14414 int this_scroll_margin, top_scroll_margin;
14415 struct glyph_row *row = NULL;
14416
14417 #if GLYPH_DEBUG
14418 debug_method_add (w, "cursor movement");
14419 #endif
14420
14421 /* Scroll if point within this distance from the top or bottom
14422 of the window. This is a pixel value. */
14423 if (scroll_margin > 0)
14424 {
14425 this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
14426 this_scroll_margin *= FRAME_LINE_HEIGHT (f);
14427 }
14428 else
14429 this_scroll_margin = 0;
14430
14431 top_scroll_margin = this_scroll_margin;
14432 if (WINDOW_WANTS_HEADER_LINE_P (w))
14433 top_scroll_margin += CURRENT_HEADER_LINE_HEIGHT (w);
14434
14435 /* Start with the row the cursor was displayed during the last
14436 not paused redisplay. Give up if that row is not valid. */
14437 if (w->last_cursor.vpos < 0
14438 || w->last_cursor.vpos >= w->current_matrix->nrows)
14439 rc = CURSOR_MOVEMENT_MUST_SCROLL;
14440 else
14441 {
14442 row = MATRIX_ROW (w->current_matrix, w->last_cursor.vpos);
14443 if (row->mode_line_p)
14444 ++row;
14445 if (!row->enabled_p)
14446 rc = CURSOR_MOVEMENT_MUST_SCROLL;
14447 }
14448
14449 if (rc == CURSOR_MOVEMENT_CANNOT_BE_USED)
14450 {
14451 int scroll_p = 0, must_scroll = 0;
14452 int last_y = window_text_bottom_y (w) - this_scroll_margin;
14453
14454 if (PT > XFASTINT (w->last_point))
14455 {
14456 /* Point has moved forward. */
14457 while (MATRIX_ROW_END_CHARPOS (row) < PT
14458 && MATRIX_ROW_BOTTOM_Y (row) < last_y)
14459 {
14460 xassert (row->enabled_p);
14461 ++row;
14462 }
14463
14464 /* If the end position of a row equals the start
14465 position of the next row, and PT is at that position,
14466 we would rather display cursor in the next line. */
14467 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
14468 && MATRIX_ROW_END_CHARPOS (row) == PT
14469 && row < w->current_matrix->rows
14470 + w->current_matrix->nrows - 1
14471 && MATRIX_ROW_START_CHARPOS (row+1) == PT
14472 && !cursor_row_p (row))
14473 ++row;
14474
14475 /* If within the scroll margin, scroll. Note that
14476 MATRIX_ROW_BOTTOM_Y gives the pixel position at which
14477 the next line would be drawn, and that
14478 this_scroll_margin can be zero. */
14479 if (MATRIX_ROW_BOTTOM_Y (row) > last_y
14480 || PT > MATRIX_ROW_END_CHARPOS (row)
14481 /* Line is completely visible last line in window
14482 and PT is to be set in the next line. */
14483 || (MATRIX_ROW_BOTTOM_Y (row) == last_y
14484 && PT == MATRIX_ROW_END_CHARPOS (row)
14485 && !row->ends_at_zv_p
14486 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
14487 scroll_p = 1;
14488 }
14489 else if (PT < XFASTINT (w->last_point))
14490 {
14491 /* Cursor has to be moved backward. Note that PT >=
14492 CHARPOS (startp) because of the outer if-statement. */
14493 while (!row->mode_line_p
14494 && (MATRIX_ROW_START_CHARPOS (row) > PT
14495 || (MATRIX_ROW_START_CHARPOS (row) == PT
14496 && (MATRIX_ROW_STARTS_IN_MIDDLE_OF_CHAR_P (row)
14497 || (/* STARTS_IN_MIDDLE_OF_STRING_P (row) */
14498 row > w->current_matrix->rows
14499 && (row-1)->ends_in_newline_from_string_p))))
14500 && (row->y > top_scroll_margin
14501 || CHARPOS (startp) == BEGV))
14502 {
14503 xassert (row->enabled_p);
14504 --row;
14505 }
14506
14507 /* Consider the following case: Window starts at BEGV,
14508 there is invisible, intangible text at BEGV, so that
14509 display starts at some point START > BEGV. It can
14510 happen that we are called with PT somewhere between
14511 BEGV and START. Try to handle that case. */
14512 if (row < w->current_matrix->rows
14513 || row->mode_line_p)
14514 {
14515 row = w->current_matrix->rows;
14516 if (row->mode_line_p)
14517 ++row;
14518 }
14519
14520 /* Due to newlines in overlay strings, we may have to
14521 skip forward over overlay strings. */
14522 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
14523 && MATRIX_ROW_END_CHARPOS (row) == PT
14524 && !cursor_row_p (row))
14525 ++row;
14526
14527 /* If within the scroll margin, scroll. */
14528 if (row->y < top_scroll_margin
14529 && CHARPOS (startp) != BEGV)
14530 scroll_p = 1;
14531 }
14532 else
14533 {
14534 /* Cursor did not move. So don't scroll even if cursor line
14535 is partially visible, as it was so before. */
14536 rc = CURSOR_MOVEMENT_SUCCESS;
14537 }
14538
14539 if (PT < MATRIX_ROW_START_CHARPOS (row)
14540 || PT > MATRIX_ROW_END_CHARPOS (row))
14541 {
14542 /* if PT is not in the glyph row, give up. */
14543 rc = CURSOR_MOVEMENT_MUST_SCROLL;
14544 must_scroll = 1;
14545 }
14546 else if (rc != CURSOR_MOVEMENT_SUCCESS
14547 && !NILP (BVAR (XBUFFER (w->buffer), bidi_display_reordering)))
14548 {
14549 /* If rows are bidi-reordered and point moved, back up
14550 until we find a row that does not belong to a
14551 continuation line. This is because we must consider
14552 all rows of a continued line as candidates for the
14553 new cursor positioning, since row start and end
14554 positions change non-linearly with vertical position
14555 in such rows. */
14556 /* FIXME: Revisit this when glyph ``spilling'' in
14557 continuation lines' rows is implemented for
14558 bidi-reordered rows. */
14559 while (MATRIX_ROW_CONTINUATION_LINE_P (row))
14560 {
14561 xassert (row->enabled_p);
14562 --row;
14563 /* If we hit the beginning of the displayed portion
14564 without finding the first row of a continued
14565 line, give up. */
14566 if (row <= w->current_matrix->rows)
14567 {
14568 rc = CURSOR_MOVEMENT_MUST_SCROLL;
14569 break;
14570 }
14571
14572 }
14573 }
14574 if (must_scroll)
14575 ;
14576 else if (rc != CURSOR_MOVEMENT_SUCCESS
14577 && MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row)
14578 && make_cursor_line_fully_visible_p)
14579 {
14580 if (PT == MATRIX_ROW_END_CHARPOS (row)
14581 && !row->ends_at_zv_p
14582 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
14583 rc = CURSOR_MOVEMENT_MUST_SCROLL;
14584 else if (row->height > window_box_height (w))
14585 {
14586 /* If we end up in a partially visible line, let's
14587 make it fully visible, except when it's taller
14588 than the window, in which case we can't do much
14589 about it. */
14590 *scroll_step = 1;
14591 rc = CURSOR_MOVEMENT_MUST_SCROLL;
14592 }
14593 else
14594 {
14595 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
14596 if (!cursor_row_fully_visible_p (w, 0, 1))
14597 rc = CURSOR_MOVEMENT_MUST_SCROLL;
14598 else
14599 rc = CURSOR_MOVEMENT_SUCCESS;
14600 }
14601 }
14602 else if (scroll_p)
14603 rc = CURSOR_MOVEMENT_MUST_SCROLL;
14604 else if (rc != CURSOR_MOVEMENT_SUCCESS
14605 && !NILP (BVAR (XBUFFER (w->buffer), bidi_display_reordering)))
14606 {
14607 /* With bidi-reordered rows, there could be more than
14608 one candidate row whose start and end positions
14609 occlude point. We need to let set_cursor_from_row
14610 find the best candidate. */
14611 /* FIXME: Revisit this when glyph ``spilling'' in
14612 continuation lines' rows is implemented for
14613 bidi-reordered rows. */
14614 int rv = 0;
14615
14616 do
14617 {
14618 int at_zv_p = 0, exact_match_p = 0;
14619
14620 if (MATRIX_ROW_START_CHARPOS (row) <= PT
14621 && PT <= MATRIX_ROW_END_CHARPOS (row)
14622 && cursor_row_p (row))
14623 rv |= set_cursor_from_row (w, row, w->current_matrix,
14624 0, 0, 0, 0);
14625 /* As soon as we've found the exact match for point,
14626 or the first suitable row whose ends_at_zv_p flag
14627 is set, we are done. */
14628 at_zv_p =
14629 MATRIX_ROW (w->current_matrix, w->cursor.vpos)->ends_at_zv_p;
14630 if (!at_zv_p)
14631 {
14632 struct glyph_row *candidate =
14633 MATRIX_ROW (w->current_matrix, w->cursor.vpos);
14634 struct glyph *g =
14635 candidate->glyphs[TEXT_AREA] + w->cursor.hpos;
14636 EMACS_INT endpos = MATRIX_ROW_END_CHARPOS (candidate);
14637
14638 exact_match_p =
14639 (BUFFERP (g->object) && g->charpos == PT)
14640 || (INTEGERP (g->object)
14641 && (g->charpos == PT
14642 || (g->charpos == 0 && endpos - 1 == PT)));
14643 }
14644 if (rv && (at_zv_p || exact_match_p))
14645 {
14646 rc = CURSOR_MOVEMENT_SUCCESS;
14647 break;
14648 }
14649 if (MATRIX_ROW_BOTTOM_Y (row) == last_y)
14650 break;
14651 ++row;
14652 }
14653 while (((MATRIX_ROW_CONTINUATION_LINE_P (row)
14654 || row->continued_p)
14655 && MATRIX_ROW_BOTTOM_Y (row) <= last_y)
14656 || (MATRIX_ROW_START_CHARPOS (row) == PT
14657 && MATRIX_ROW_BOTTOM_Y (row) < last_y));
14658 /* If we didn't find any candidate rows, or exited the
14659 loop before all the candidates were examined, signal
14660 to the caller that this method failed. */
14661 if (rc != CURSOR_MOVEMENT_SUCCESS
14662 && !(rv
14663 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
14664 && !row->continued_p))
14665 rc = CURSOR_MOVEMENT_MUST_SCROLL;
14666 else if (rv)
14667 rc = CURSOR_MOVEMENT_SUCCESS;
14668 }
14669 else
14670 {
14671 do
14672 {
14673 if (set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0))
14674 {
14675 rc = CURSOR_MOVEMENT_SUCCESS;
14676 break;
14677 }
14678 ++row;
14679 }
14680 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
14681 && MATRIX_ROW_START_CHARPOS (row) == PT
14682 && cursor_row_p (row));
14683 }
14684 }
14685 }
14686
14687 return rc;
14688 }
14689
14690 #if !defined USE_TOOLKIT_SCROLL_BARS || defined USE_GTK
14691 static
14692 #endif
14693 void
14694 set_vertical_scroll_bar (struct window *w)
14695 {
14696 EMACS_INT start, end, whole;
14697
14698 /* Calculate the start and end positions for the current window.
14699 At some point, it would be nice to choose between scrollbars
14700 which reflect the whole buffer size, with special markers
14701 indicating narrowing, and scrollbars which reflect only the
14702 visible region.
14703
14704 Note that mini-buffers sometimes aren't displaying any text. */
14705 if (!MINI_WINDOW_P (w)
14706 || (w == XWINDOW (minibuf_window)
14707 && NILP (echo_area_buffer[0])))
14708 {
14709 struct buffer *buf = XBUFFER (w->buffer);
14710 whole = BUF_ZV (buf) - BUF_BEGV (buf);
14711 start = marker_position (w->start) - BUF_BEGV (buf);
14712 /* I don't think this is guaranteed to be right. For the
14713 moment, we'll pretend it is. */
14714 end = BUF_Z (buf) - XFASTINT (w->window_end_pos) - BUF_BEGV (buf);
14715
14716 if (end < start)
14717 end = start;
14718 if (whole < (end - start))
14719 whole = end - start;
14720 }
14721 else
14722 start = end = whole = 0;
14723
14724 /* Indicate what this scroll bar ought to be displaying now. */
14725 if (FRAME_TERMINAL (XFRAME (w->frame))->set_vertical_scroll_bar_hook)
14726 (*FRAME_TERMINAL (XFRAME (w->frame))->set_vertical_scroll_bar_hook)
14727 (w, end - start, whole, start);
14728 }
14729
14730
14731 /* Redisplay leaf window WINDOW. JUST_THIS_ONE_P non-zero means only
14732 selected_window is redisplayed.
14733
14734 We can return without actually redisplaying the window if
14735 fonts_changed_p is nonzero. In that case, redisplay_internal will
14736 retry. */
14737
14738 static void
14739 redisplay_window (Lisp_Object window, int just_this_one_p)
14740 {
14741 struct window *w = XWINDOW (window);
14742 struct frame *f = XFRAME (w->frame);
14743 struct buffer *buffer = XBUFFER (w->buffer);
14744 struct buffer *old = current_buffer;
14745 struct text_pos lpoint, opoint, startp;
14746 int update_mode_line;
14747 int tem;
14748 struct it it;
14749 /* Record it now because it's overwritten. */
14750 int current_matrix_up_to_date_p = 0;
14751 int used_current_matrix_p = 0;
14752 /* This is less strict than current_matrix_up_to_date_p.
14753 It indictes that the buffer contents and narrowing are unchanged. */
14754 int buffer_unchanged_p = 0;
14755 int temp_scroll_step = 0;
14756 int count = SPECPDL_INDEX ();
14757 int rc;
14758 int centering_position = -1;
14759 int last_line_misfit = 0;
14760 EMACS_INT beg_unchanged, end_unchanged;
14761
14762 SET_TEXT_POS (lpoint, PT, PT_BYTE);
14763 opoint = lpoint;
14764
14765 /* W must be a leaf window here. */
14766 xassert (!NILP (w->buffer));
14767 #if GLYPH_DEBUG
14768 *w->desired_matrix->method = 0;
14769 #endif
14770
14771 restart:
14772 reconsider_clip_changes (w, buffer);
14773
14774 /* Has the mode line to be updated? */
14775 update_mode_line = (!NILP (w->update_mode_line)
14776 || update_mode_lines
14777 || buffer->clip_changed
14778 || buffer->prevent_redisplay_optimizations_p);
14779
14780 if (MINI_WINDOW_P (w))
14781 {
14782 if (w == XWINDOW (echo_area_window)
14783 && !NILP (echo_area_buffer[0]))
14784 {
14785 if (update_mode_line)
14786 /* We may have to update a tty frame's menu bar or a
14787 tool-bar. Example `M-x C-h C-h C-g'. */
14788 goto finish_menu_bars;
14789 else
14790 /* We've already displayed the echo area glyphs in this window. */
14791 goto finish_scroll_bars;
14792 }
14793 else if ((w != XWINDOW (minibuf_window)
14794 || minibuf_level == 0)
14795 /* When buffer is nonempty, redisplay window normally. */
14796 && BUF_Z (XBUFFER (w->buffer)) == BUF_BEG (XBUFFER (w->buffer))
14797 /* Quail displays non-mini buffers in minibuffer window.
14798 In that case, redisplay the window normally. */
14799 && !NILP (Fmemq (w->buffer, Vminibuffer_list)))
14800 {
14801 /* W is a mini-buffer window, but it's not active, so clear
14802 it. */
14803 int yb = window_text_bottom_y (w);
14804 struct glyph_row *row;
14805 int y;
14806
14807 for (y = 0, row = w->desired_matrix->rows;
14808 y < yb;
14809 y += row->height, ++row)
14810 blank_row (w, row, y);
14811 goto finish_scroll_bars;
14812 }
14813
14814 clear_glyph_matrix (w->desired_matrix);
14815 }
14816
14817 /* Otherwise set up data on this window; select its buffer and point
14818 value. */
14819 /* Really select the buffer, for the sake of buffer-local
14820 variables. */
14821 set_buffer_internal_1 (XBUFFER (w->buffer));
14822
14823 current_matrix_up_to_date_p
14824 = (!NILP (w->window_end_valid)
14825 && !current_buffer->clip_changed
14826 && !current_buffer->prevent_redisplay_optimizations_p
14827 && XFASTINT (w->last_modified) >= MODIFF
14828 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
14829
14830 /* Run the window-bottom-change-functions
14831 if it is possible that the text on the screen has changed
14832 (either due to modification of the text, or any other reason). */
14833 if (!current_matrix_up_to_date_p
14834 && !NILP (Vwindow_text_change_functions))
14835 {
14836 safe_run_hooks (Qwindow_text_change_functions);
14837 goto restart;
14838 }
14839
14840 beg_unchanged = BEG_UNCHANGED;
14841 end_unchanged = END_UNCHANGED;
14842
14843 SET_TEXT_POS (opoint, PT, PT_BYTE);
14844
14845 specbind (Qinhibit_point_motion_hooks, Qt);
14846
14847 buffer_unchanged_p
14848 = (!NILP (w->window_end_valid)
14849 && !current_buffer->clip_changed
14850 && XFASTINT (w->last_modified) >= MODIFF
14851 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
14852
14853 /* When windows_or_buffers_changed is non-zero, we can't rely on
14854 the window end being valid, so set it to nil there. */
14855 if (windows_or_buffers_changed)
14856 {
14857 /* If window starts on a continuation line, maybe adjust the
14858 window start in case the window's width changed. */
14859 if (XMARKER (w->start)->buffer == current_buffer)
14860 compute_window_start_on_continuation_line (w);
14861
14862 w->window_end_valid = Qnil;
14863 }
14864
14865 /* Some sanity checks. */
14866 CHECK_WINDOW_END (w);
14867 if (Z == Z_BYTE && CHARPOS (opoint) != BYTEPOS (opoint))
14868 abort ();
14869 if (BYTEPOS (opoint) < CHARPOS (opoint))
14870 abort ();
14871
14872 /* If %c is in mode line, update it if needed. */
14873 if (!NILP (w->column_number_displayed)
14874 /* This alternative quickly identifies a common case
14875 where no change is needed. */
14876 && !(PT == XFASTINT (w->last_point)
14877 && XFASTINT (w->last_modified) >= MODIFF
14878 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
14879 && (XFASTINT (w->column_number_displayed) != current_column ()))
14880 update_mode_line = 1;
14881
14882 /* Count number of windows showing the selected buffer. An indirect
14883 buffer counts as its base buffer. */
14884 if (!just_this_one_p)
14885 {
14886 struct buffer *current_base, *window_base;
14887 current_base = current_buffer;
14888 window_base = XBUFFER (XWINDOW (selected_window)->buffer);
14889 if (current_base->base_buffer)
14890 current_base = current_base->base_buffer;
14891 if (window_base->base_buffer)
14892 window_base = window_base->base_buffer;
14893 if (current_base == window_base)
14894 buffer_shared++;
14895 }
14896
14897 /* Point refers normally to the selected window. For any other
14898 window, set up appropriate value. */
14899 if (!EQ (window, selected_window))
14900 {
14901 EMACS_INT new_pt = XMARKER (w->pointm)->charpos;
14902 EMACS_INT new_pt_byte = marker_byte_position (w->pointm);
14903 if (new_pt < BEGV)
14904 {
14905 new_pt = BEGV;
14906 new_pt_byte = BEGV_BYTE;
14907 set_marker_both (w->pointm, Qnil, BEGV, BEGV_BYTE);
14908 }
14909 else if (new_pt > (ZV - 1))
14910 {
14911 new_pt = ZV;
14912 new_pt_byte = ZV_BYTE;
14913 set_marker_both (w->pointm, Qnil, ZV, ZV_BYTE);
14914 }
14915
14916 /* We don't use SET_PT so that the point-motion hooks don't run. */
14917 TEMP_SET_PT_BOTH (new_pt, new_pt_byte);
14918 }
14919
14920 /* If any of the character widths specified in the display table
14921 have changed, invalidate the width run cache. It's true that
14922 this may be a bit late to catch such changes, but the rest of
14923 redisplay goes (non-fatally) haywire when the display table is
14924 changed, so why should we worry about doing any better? */
14925 if (current_buffer->width_run_cache)
14926 {
14927 struct Lisp_Char_Table *disptab = buffer_display_table ();
14928
14929 if (! disptab_matches_widthtab (disptab,
14930 XVECTOR (BVAR (current_buffer, width_table))))
14931 {
14932 invalidate_region_cache (current_buffer,
14933 current_buffer->width_run_cache,
14934 BEG, Z);
14935 recompute_width_table (current_buffer, disptab);
14936 }
14937 }
14938
14939 /* If window-start is screwed up, choose a new one. */
14940 if (XMARKER (w->start)->buffer != current_buffer)
14941 goto recenter;
14942
14943 SET_TEXT_POS_FROM_MARKER (startp, w->start);
14944
14945 /* If someone specified a new starting point but did not insist,
14946 check whether it can be used. */
14947 if (!NILP (w->optional_new_start)
14948 && CHARPOS (startp) >= BEGV
14949 && CHARPOS (startp) <= ZV)
14950 {
14951 w->optional_new_start = Qnil;
14952 start_display (&it, w, startp);
14953 move_it_to (&it, PT, 0, it.last_visible_y, -1,
14954 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
14955 if (IT_CHARPOS (it) == PT)
14956 w->force_start = Qt;
14957 /* IT may overshoot PT if text at PT is invisible. */
14958 else if (IT_CHARPOS (it) > PT && CHARPOS (startp) <= PT)
14959 w->force_start = Qt;
14960 }
14961
14962 force_start:
14963
14964 /* Handle case where place to start displaying has been specified,
14965 unless the specified location is outside the accessible range. */
14966 if (!NILP (w->force_start)
14967 || w->frozen_window_start_p)
14968 {
14969 /* We set this later on if we have to adjust point. */
14970 int new_vpos = -1;
14971
14972 w->force_start = Qnil;
14973 w->vscroll = 0;
14974 w->window_end_valid = Qnil;
14975
14976 /* Forget any recorded base line for line number display. */
14977 if (!buffer_unchanged_p)
14978 w->base_line_number = Qnil;
14979
14980 /* Redisplay the mode line. Select the buffer properly for that.
14981 Also, run the hook window-scroll-functions
14982 because we have scrolled. */
14983 /* Note, we do this after clearing force_start because
14984 if there's an error, it is better to forget about force_start
14985 than to get into an infinite loop calling the hook functions
14986 and having them get more errors. */
14987 if (!update_mode_line
14988 || ! NILP (Vwindow_scroll_functions))
14989 {
14990 update_mode_line = 1;
14991 w->update_mode_line = Qt;
14992 startp = run_window_scroll_functions (window, startp);
14993 }
14994
14995 w->last_modified = make_number (0);
14996 w->last_overlay_modified = make_number (0);
14997 if (CHARPOS (startp) < BEGV)
14998 SET_TEXT_POS (startp, BEGV, BEGV_BYTE);
14999 else if (CHARPOS (startp) > ZV)
15000 SET_TEXT_POS (startp, ZV, ZV_BYTE);
15001
15002 /* Redisplay, then check if cursor has been set during the
15003 redisplay. Give up if new fonts were loaded. */
15004 /* We used to issue a CHECK_MARGINS argument to try_window here,
15005 but this causes scrolling to fail when point begins inside
15006 the scroll margin (bug#148) -- cyd */
15007 if (!try_window (window, startp, 0))
15008 {
15009 w->force_start = Qt;
15010 clear_glyph_matrix (w->desired_matrix);
15011 goto need_larger_matrices;
15012 }
15013
15014 if (w->cursor.vpos < 0 && !w->frozen_window_start_p)
15015 {
15016 /* If point does not appear, try to move point so it does
15017 appear. The desired matrix has been built above, so we
15018 can use it here. */
15019 new_vpos = window_box_height (w) / 2;
15020 }
15021
15022 if (!cursor_row_fully_visible_p (w, 0, 0))
15023 {
15024 /* Point does appear, but on a line partly visible at end of window.
15025 Move it back to a fully-visible line. */
15026 new_vpos = window_box_height (w);
15027 }
15028
15029 /* If we need to move point for either of the above reasons,
15030 now actually do it. */
15031 if (new_vpos >= 0)
15032 {
15033 struct glyph_row *row;
15034
15035 row = MATRIX_FIRST_TEXT_ROW (w->desired_matrix);
15036 while (MATRIX_ROW_BOTTOM_Y (row) < new_vpos)
15037 ++row;
15038
15039 TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row),
15040 MATRIX_ROW_START_BYTEPOS (row));
15041
15042 if (w != XWINDOW (selected_window))
15043 set_marker_both (w->pointm, Qnil, PT, PT_BYTE);
15044 else if (current_buffer == old)
15045 SET_TEXT_POS (lpoint, PT, PT_BYTE);
15046
15047 set_cursor_from_row (w, row, w->desired_matrix, 0, 0, 0, 0);
15048
15049 /* If we are highlighting the region, then we just changed
15050 the region, so redisplay to show it. */
15051 if (!NILP (Vtransient_mark_mode)
15052 && !NILP (BVAR (current_buffer, mark_active)))
15053 {
15054 clear_glyph_matrix (w->desired_matrix);
15055 if (!try_window (window, startp, 0))
15056 goto need_larger_matrices;
15057 }
15058 }
15059
15060 #if GLYPH_DEBUG
15061 debug_method_add (w, "forced window start");
15062 #endif
15063 goto done;
15064 }
15065
15066 /* Handle case where text has not changed, only point, and it has
15067 not moved off the frame, and we are not retrying after hscroll.
15068 (current_matrix_up_to_date_p is nonzero when retrying.) */
15069 if (current_matrix_up_to_date_p
15070 && (rc = try_cursor_movement (window, startp, &temp_scroll_step),
15071 rc != CURSOR_MOVEMENT_CANNOT_BE_USED))
15072 {
15073 switch (rc)
15074 {
15075 case CURSOR_MOVEMENT_SUCCESS:
15076 used_current_matrix_p = 1;
15077 goto done;
15078
15079 case CURSOR_MOVEMENT_MUST_SCROLL:
15080 goto try_to_scroll;
15081
15082 default:
15083 abort ();
15084 }
15085 }
15086 /* If current starting point was originally the beginning of a line
15087 but no longer is, find a new starting point. */
15088 else if (!NILP (w->start_at_line_beg)
15089 && !(CHARPOS (startp) <= BEGV
15090 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n'))
15091 {
15092 #if GLYPH_DEBUG
15093 debug_method_add (w, "recenter 1");
15094 #endif
15095 goto recenter;
15096 }
15097
15098 /* Try scrolling with try_window_id. Value is > 0 if update has
15099 been done, it is -1 if we know that the same window start will
15100 not work. It is 0 if unsuccessful for some other reason. */
15101 else if ((tem = try_window_id (w)) != 0)
15102 {
15103 #if GLYPH_DEBUG
15104 debug_method_add (w, "try_window_id %d", tem);
15105 #endif
15106
15107 if (fonts_changed_p)
15108 goto need_larger_matrices;
15109 if (tem > 0)
15110 goto done;
15111
15112 /* Otherwise try_window_id has returned -1 which means that we
15113 don't want the alternative below this comment to execute. */
15114 }
15115 else if (CHARPOS (startp) >= BEGV
15116 && CHARPOS (startp) <= ZV
15117 && PT >= CHARPOS (startp)
15118 && (CHARPOS (startp) < ZV
15119 /* Avoid starting at end of buffer. */
15120 || CHARPOS (startp) == BEGV
15121 || (XFASTINT (w->last_modified) >= MODIFF
15122 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)))
15123 {
15124 int d1, d2, d3, d4, d5, d6;
15125
15126 /* If first window line is a continuation line, and window start
15127 is inside the modified region, but the first change is before
15128 current window start, we must select a new window start.
15129
15130 However, if this is the result of a down-mouse event (e.g. by
15131 extending the mouse-drag-overlay), we don't want to select a
15132 new window start, since that would change the position under
15133 the mouse, resulting in an unwanted mouse-movement rather
15134 than a simple mouse-click. */
15135 if (NILP (w->start_at_line_beg)
15136 && NILP (do_mouse_tracking)
15137 && CHARPOS (startp) > BEGV
15138 && CHARPOS (startp) > BEG + beg_unchanged
15139 && CHARPOS (startp) <= Z - end_unchanged
15140 /* Even if w->start_at_line_beg is nil, a new window may
15141 start at a line_beg, since that's how set_buffer_window
15142 sets it. So, we need to check the return value of
15143 compute_window_start_on_continuation_line. (See also
15144 bug#197). */
15145 && XMARKER (w->start)->buffer == current_buffer
15146 && compute_window_start_on_continuation_line (w)
15147 /* It doesn't make sense to force the window start like we
15148 do at label force_start if it is already known that point
15149 will not be visible in the resulting window, because
15150 doing so will move point from its correct position
15151 instead of scrolling the window to bring point into view.
15152 See bug#9324. */
15153 && pos_visible_p (w, PT, &d1, &d2, &d3, &d4, &d5, &d6))
15154 {
15155 w->force_start = Qt;
15156 SET_TEXT_POS_FROM_MARKER (startp, w->start);
15157 goto force_start;
15158 }
15159
15160 #if GLYPH_DEBUG
15161 debug_method_add (w, "same window start");
15162 #endif
15163
15164 /* Try to redisplay starting at same place as before.
15165 If point has not moved off frame, accept the results. */
15166 if (!current_matrix_up_to_date_p
15167 /* Don't use try_window_reusing_current_matrix in this case
15168 because a window scroll function can have changed the
15169 buffer. */
15170 || !NILP (Vwindow_scroll_functions)
15171 || MINI_WINDOW_P (w)
15172 || !(used_current_matrix_p
15173 = try_window_reusing_current_matrix (w)))
15174 {
15175 IF_DEBUG (debug_method_add (w, "1"));
15176 if (try_window (window, startp, TRY_WINDOW_CHECK_MARGINS) < 0)
15177 /* -1 means we need to scroll.
15178 0 means we need new matrices, but fonts_changed_p
15179 is set in that case, so we will detect it below. */
15180 goto try_to_scroll;
15181 }
15182
15183 if (fonts_changed_p)
15184 goto need_larger_matrices;
15185
15186 if (w->cursor.vpos >= 0)
15187 {
15188 if (!just_this_one_p
15189 || current_buffer->clip_changed
15190 || BEG_UNCHANGED < CHARPOS (startp))
15191 /* Forget any recorded base line for line number display. */
15192 w->base_line_number = Qnil;
15193
15194 if (!cursor_row_fully_visible_p (w, 1, 0))
15195 {
15196 clear_glyph_matrix (w->desired_matrix);
15197 last_line_misfit = 1;
15198 }
15199 /* Drop through and scroll. */
15200 else
15201 goto done;
15202 }
15203 else
15204 clear_glyph_matrix (w->desired_matrix);
15205 }
15206
15207 try_to_scroll:
15208
15209 w->last_modified = make_number (0);
15210 w->last_overlay_modified = make_number (0);
15211
15212 /* Redisplay the mode line. Select the buffer properly for that. */
15213 if (!update_mode_line)
15214 {
15215 update_mode_line = 1;
15216 w->update_mode_line = Qt;
15217 }
15218
15219 /* Try to scroll by specified few lines. */
15220 if ((scroll_conservatively
15221 || emacs_scroll_step
15222 || temp_scroll_step
15223 || NUMBERP (BVAR (current_buffer, scroll_up_aggressively))
15224 || NUMBERP (BVAR (current_buffer, scroll_down_aggressively)))
15225 && CHARPOS (startp) >= BEGV
15226 && CHARPOS (startp) <= ZV)
15227 {
15228 /* The function returns -1 if new fonts were loaded, 1 if
15229 successful, 0 if not successful. */
15230 int ss = try_scrolling (window, just_this_one_p,
15231 scroll_conservatively,
15232 emacs_scroll_step,
15233 temp_scroll_step, last_line_misfit);
15234 switch (ss)
15235 {
15236 case SCROLLING_SUCCESS:
15237 goto done;
15238
15239 case SCROLLING_NEED_LARGER_MATRICES:
15240 goto need_larger_matrices;
15241
15242 case SCROLLING_FAILED:
15243 break;
15244
15245 default:
15246 abort ();
15247 }
15248 }
15249
15250 /* Finally, just choose a place to start which positions point
15251 according to user preferences. */
15252
15253 recenter:
15254
15255 #if GLYPH_DEBUG
15256 debug_method_add (w, "recenter");
15257 #endif
15258
15259 /* w->vscroll = 0; */
15260
15261 /* Forget any previously recorded base line for line number display. */
15262 if (!buffer_unchanged_p)
15263 w->base_line_number = Qnil;
15264
15265 /* Determine the window start relative to point. */
15266 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
15267 it.current_y = it.last_visible_y;
15268 if (centering_position < 0)
15269 {
15270 int margin =
15271 scroll_margin > 0
15272 ? min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4)
15273 : 0;
15274 EMACS_INT margin_pos = CHARPOS (startp);
15275 int scrolling_up;
15276 Lisp_Object aggressive;
15277
15278 /* If there is a scroll margin at the top of the window, find
15279 its character position. */
15280 if (margin
15281 /* Cannot call start_display if startp is not in the
15282 accessible region of the buffer. This can happen when we
15283 have just switched to a different buffer and/or changed
15284 its restriction. In that case, startp is initialized to
15285 the character position 1 (BEG) because we did not yet
15286 have chance to display the buffer even once. */
15287 && BEGV <= CHARPOS (startp) && CHARPOS (startp) <= ZV)
15288 {
15289 struct it it1;
15290 void *it1data = NULL;
15291
15292 SAVE_IT (it1, it, it1data);
15293 start_display (&it1, w, startp);
15294 move_it_vertically (&it1, margin);
15295 margin_pos = IT_CHARPOS (it1);
15296 RESTORE_IT (&it, &it, it1data);
15297 }
15298 scrolling_up = PT > margin_pos;
15299 aggressive =
15300 scrolling_up
15301 ? BVAR (current_buffer, scroll_up_aggressively)
15302 : BVAR (current_buffer, scroll_down_aggressively);
15303
15304 if (!MINI_WINDOW_P (w)
15305 && (scroll_conservatively > SCROLL_LIMIT || NUMBERP (aggressive)))
15306 {
15307 int pt_offset = 0;
15308
15309 /* Setting scroll-conservatively overrides
15310 scroll-*-aggressively. */
15311 if (!scroll_conservatively && NUMBERP (aggressive))
15312 {
15313 double float_amount = XFLOATINT (aggressive);
15314
15315 pt_offset = float_amount * WINDOW_BOX_TEXT_HEIGHT (w);
15316 if (pt_offset == 0 && float_amount > 0)
15317 pt_offset = 1;
15318 if (pt_offset)
15319 margin -= 1;
15320 }
15321 /* Compute how much to move the window start backward from
15322 point so that point will be displayed where the user
15323 wants it. */
15324 if (scrolling_up)
15325 {
15326 centering_position = it.last_visible_y;
15327 if (pt_offset)
15328 centering_position -= pt_offset;
15329 centering_position -=
15330 FRAME_LINE_HEIGHT (f) * (1 + margin + (last_line_misfit != 0))
15331 + WINDOW_HEADER_LINE_HEIGHT (w);
15332 /* Don't let point enter the scroll margin near top of
15333 the window. */
15334 if (centering_position < margin * FRAME_LINE_HEIGHT (f))
15335 centering_position = margin * FRAME_LINE_HEIGHT (f);
15336 }
15337 else
15338 centering_position = margin * FRAME_LINE_HEIGHT (f) + pt_offset;
15339 }
15340 else
15341 /* Set the window start half the height of the window backward
15342 from point. */
15343 centering_position = window_box_height (w) / 2;
15344 }
15345 move_it_vertically_backward (&it, centering_position);
15346
15347 xassert (IT_CHARPOS (it) >= BEGV);
15348
15349 /* The function move_it_vertically_backward may move over more
15350 than the specified y-distance. If it->w is small, e.g. a
15351 mini-buffer window, we may end up in front of the window's
15352 display area. Start displaying at the start of the line
15353 containing PT in this case. */
15354 if (it.current_y <= 0)
15355 {
15356 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
15357 move_it_vertically_backward (&it, 0);
15358 it.current_y = 0;
15359 }
15360
15361 it.current_x = it.hpos = 0;
15362
15363 /* Set the window start position here explicitly, to avoid an
15364 infinite loop in case the functions in window-scroll-functions
15365 get errors. */
15366 set_marker_both (w->start, Qnil, IT_CHARPOS (it), IT_BYTEPOS (it));
15367
15368 /* Run scroll hooks. */
15369 startp = run_window_scroll_functions (window, it.current.pos);
15370
15371 /* Redisplay the window. */
15372 if (!current_matrix_up_to_date_p
15373 || windows_or_buffers_changed
15374 || cursor_type_changed
15375 /* Don't use try_window_reusing_current_matrix in this case
15376 because it can have changed the buffer. */
15377 || !NILP (Vwindow_scroll_functions)
15378 || !just_this_one_p
15379 || MINI_WINDOW_P (w)
15380 || !(used_current_matrix_p
15381 = try_window_reusing_current_matrix (w)))
15382 try_window (window, startp, 0);
15383
15384 /* If new fonts have been loaded (due to fontsets), give up. We
15385 have to start a new redisplay since we need to re-adjust glyph
15386 matrices. */
15387 if (fonts_changed_p)
15388 goto need_larger_matrices;
15389
15390 /* If cursor did not appear assume that the middle of the window is
15391 in the first line of the window. Do it again with the next line.
15392 (Imagine a window of height 100, displaying two lines of height
15393 60. Moving back 50 from it->last_visible_y will end in the first
15394 line.) */
15395 if (w->cursor.vpos < 0)
15396 {
15397 if (!NILP (w->window_end_valid)
15398 && PT >= Z - XFASTINT (w->window_end_pos))
15399 {
15400 clear_glyph_matrix (w->desired_matrix);
15401 move_it_by_lines (&it, 1);
15402 try_window (window, it.current.pos, 0);
15403 }
15404 else if (PT < IT_CHARPOS (it))
15405 {
15406 clear_glyph_matrix (w->desired_matrix);
15407 move_it_by_lines (&it, -1);
15408 try_window (window, it.current.pos, 0);
15409 }
15410 else
15411 {
15412 /* Not much we can do about it. */
15413 }
15414 }
15415
15416 /* Consider the following case: Window starts at BEGV, there is
15417 invisible, intangible text at BEGV, so that display starts at
15418 some point START > BEGV. It can happen that we are called with
15419 PT somewhere between BEGV and START. Try to handle that case. */
15420 if (w->cursor.vpos < 0)
15421 {
15422 struct glyph_row *row = w->current_matrix->rows;
15423 if (row->mode_line_p)
15424 ++row;
15425 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
15426 }
15427
15428 if (!cursor_row_fully_visible_p (w, 0, 0))
15429 {
15430 /* If vscroll is enabled, disable it and try again. */
15431 if (w->vscroll)
15432 {
15433 w->vscroll = 0;
15434 clear_glyph_matrix (w->desired_matrix);
15435 goto recenter;
15436 }
15437
15438 /* If centering point failed to make the whole line visible,
15439 put point at the top instead. That has to make the whole line
15440 visible, if it can be done. */
15441 if (centering_position == 0)
15442 goto done;
15443
15444 clear_glyph_matrix (w->desired_matrix);
15445 centering_position = 0;
15446 goto recenter;
15447 }
15448
15449 done:
15450
15451 SET_TEXT_POS_FROM_MARKER (startp, w->start);
15452 w->start_at_line_beg = ((CHARPOS (startp) == BEGV
15453 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n')
15454 ? Qt : Qnil);
15455
15456 /* Display the mode line, if we must. */
15457 if ((update_mode_line
15458 /* If window not full width, must redo its mode line
15459 if (a) the window to its side is being redone and
15460 (b) we do a frame-based redisplay. This is a consequence
15461 of how inverted lines are drawn in frame-based redisplay. */
15462 || (!just_this_one_p
15463 && !FRAME_WINDOW_P (f)
15464 && !WINDOW_FULL_WIDTH_P (w))
15465 /* Line number to display. */
15466 || INTEGERP (w->base_line_pos)
15467 /* Column number is displayed and different from the one displayed. */
15468 || (!NILP (w->column_number_displayed)
15469 && (XFASTINT (w->column_number_displayed) != current_column ())))
15470 /* This means that the window has a mode line. */
15471 && (WINDOW_WANTS_MODELINE_P (w)
15472 || WINDOW_WANTS_HEADER_LINE_P (w)))
15473 {
15474 display_mode_lines (w);
15475
15476 /* If mode line height has changed, arrange for a thorough
15477 immediate redisplay using the correct mode line height. */
15478 if (WINDOW_WANTS_MODELINE_P (w)
15479 && CURRENT_MODE_LINE_HEIGHT (w) != DESIRED_MODE_LINE_HEIGHT (w))
15480 {
15481 fonts_changed_p = 1;
15482 MATRIX_MODE_LINE_ROW (w->current_matrix)->height
15483 = DESIRED_MODE_LINE_HEIGHT (w);
15484 }
15485
15486 /* If header line height has changed, arrange for a thorough
15487 immediate redisplay using the correct header line height. */
15488 if (WINDOW_WANTS_HEADER_LINE_P (w)
15489 && CURRENT_HEADER_LINE_HEIGHT (w) != DESIRED_HEADER_LINE_HEIGHT (w))
15490 {
15491 fonts_changed_p = 1;
15492 MATRIX_HEADER_LINE_ROW (w->current_matrix)->height
15493 = DESIRED_HEADER_LINE_HEIGHT (w);
15494 }
15495
15496 if (fonts_changed_p)
15497 goto need_larger_matrices;
15498 }
15499
15500 if (!line_number_displayed
15501 && !BUFFERP (w->base_line_pos))
15502 {
15503 w->base_line_pos = Qnil;
15504 w->base_line_number = Qnil;
15505 }
15506
15507 finish_menu_bars:
15508
15509 /* When we reach a frame's selected window, redo the frame's menu bar. */
15510 if (update_mode_line
15511 && EQ (FRAME_SELECTED_WINDOW (f), window))
15512 {
15513 int redisplay_menu_p = 0;
15514
15515 if (FRAME_WINDOW_P (f))
15516 {
15517 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
15518 || defined (HAVE_NS) || defined (USE_GTK)
15519 redisplay_menu_p = FRAME_EXTERNAL_MENU_BAR (f);
15520 #else
15521 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
15522 #endif
15523 }
15524 else
15525 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
15526
15527 if (redisplay_menu_p)
15528 display_menu_bar (w);
15529
15530 #ifdef HAVE_WINDOW_SYSTEM
15531 if (FRAME_WINDOW_P (f))
15532 {
15533 #if defined (USE_GTK) || defined (HAVE_NS)
15534 if (FRAME_EXTERNAL_TOOL_BAR (f))
15535 redisplay_tool_bar (f);
15536 #else
15537 if (WINDOWP (f->tool_bar_window)
15538 && (FRAME_TOOL_BAR_LINES (f) > 0
15539 || !NILP (Vauto_resize_tool_bars))
15540 && redisplay_tool_bar (f))
15541 ignore_mouse_drag_p = 1;
15542 #endif
15543 }
15544 #endif
15545 }
15546
15547 #ifdef HAVE_WINDOW_SYSTEM
15548 if (FRAME_WINDOW_P (f)
15549 && update_window_fringes (w, (just_this_one_p
15550 || (!used_current_matrix_p && !overlay_arrow_seen)
15551 || w->pseudo_window_p)))
15552 {
15553 update_begin (f);
15554 BLOCK_INPUT;
15555 if (draw_window_fringes (w, 1))
15556 x_draw_vertical_border (w);
15557 UNBLOCK_INPUT;
15558 update_end (f);
15559 }
15560 #endif /* HAVE_WINDOW_SYSTEM */
15561
15562 /* We go to this label, with fonts_changed_p nonzero,
15563 if it is necessary to try again using larger glyph matrices.
15564 We have to redeem the scroll bar even in this case,
15565 because the loop in redisplay_internal expects that. */
15566 need_larger_matrices:
15567 ;
15568 finish_scroll_bars:
15569
15570 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
15571 {
15572 /* Set the thumb's position and size. */
15573 set_vertical_scroll_bar (w);
15574
15575 /* Note that we actually used the scroll bar attached to this
15576 window, so it shouldn't be deleted at the end of redisplay. */
15577 if (FRAME_TERMINAL (f)->redeem_scroll_bar_hook)
15578 (*FRAME_TERMINAL (f)->redeem_scroll_bar_hook) (w);
15579 }
15580
15581 /* Restore current_buffer and value of point in it. The window
15582 update may have changed the buffer, so first make sure `opoint'
15583 is still valid (Bug#6177). */
15584 if (CHARPOS (opoint) < BEGV)
15585 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
15586 else if (CHARPOS (opoint) > ZV)
15587 TEMP_SET_PT_BOTH (Z, Z_BYTE);
15588 else
15589 TEMP_SET_PT_BOTH (CHARPOS (opoint), BYTEPOS (opoint));
15590
15591 set_buffer_internal_1 (old);
15592 /* Avoid an abort in TEMP_SET_PT_BOTH if the buffer has become
15593 shorter. This can be caused by log truncation in *Messages*. */
15594 if (CHARPOS (lpoint) <= ZV)
15595 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
15596
15597 unbind_to (count, Qnil);
15598 }
15599
15600
15601 /* Build the complete desired matrix of WINDOW with a window start
15602 buffer position POS.
15603
15604 Value is 1 if successful. It is zero if fonts were loaded during
15605 redisplay which makes re-adjusting glyph matrices necessary, and -1
15606 if point would appear in the scroll margins.
15607 (We check the former only if TRY_WINDOW_IGNORE_FONTS_CHANGE is
15608 unset in FLAGS, and the latter only if TRY_WINDOW_CHECK_MARGINS is
15609 set in FLAGS.) */
15610
15611 int
15612 try_window (Lisp_Object window, struct text_pos pos, int flags)
15613 {
15614 struct window *w = XWINDOW (window);
15615 struct it it;
15616 struct glyph_row *last_text_row = NULL;
15617 struct frame *f = XFRAME (w->frame);
15618
15619 /* Make POS the new window start. */
15620 set_marker_both (w->start, Qnil, CHARPOS (pos), BYTEPOS (pos));
15621
15622 /* Mark cursor position as unknown. No overlay arrow seen. */
15623 w->cursor.vpos = -1;
15624 overlay_arrow_seen = 0;
15625
15626 /* Initialize iterator and info to start at POS. */
15627 start_display (&it, w, pos);
15628
15629 /* Display all lines of W. */
15630 while (it.current_y < it.last_visible_y)
15631 {
15632 if (display_line (&it))
15633 last_text_row = it.glyph_row - 1;
15634 if (fonts_changed_p && !(flags & TRY_WINDOW_IGNORE_FONTS_CHANGE))
15635 return 0;
15636 }
15637
15638 /* Don't let the cursor end in the scroll margins. */
15639 if ((flags & TRY_WINDOW_CHECK_MARGINS)
15640 && !MINI_WINDOW_P (w))
15641 {
15642 int this_scroll_margin;
15643
15644 if (scroll_margin > 0)
15645 {
15646 this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
15647 this_scroll_margin *= FRAME_LINE_HEIGHT (f);
15648 }
15649 else
15650 this_scroll_margin = 0;
15651
15652 if ((w->cursor.y >= 0 /* not vscrolled */
15653 && w->cursor.y < this_scroll_margin
15654 && CHARPOS (pos) > BEGV
15655 && IT_CHARPOS (it) < ZV)
15656 /* rms: considering make_cursor_line_fully_visible_p here
15657 seems to give wrong results. We don't want to recenter
15658 when the last line is partly visible, we want to allow
15659 that case to be handled in the usual way. */
15660 || w->cursor.y > it.last_visible_y - this_scroll_margin - 1)
15661 {
15662 w->cursor.vpos = -1;
15663 clear_glyph_matrix (w->desired_matrix);
15664 return -1;
15665 }
15666 }
15667
15668 /* If bottom moved off end of frame, change mode line percentage. */
15669 if (XFASTINT (w->window_end_pos) <= 0
15670 && Z != IT_CHARPOS (it))
15671 w->update_mode_line = Qt;
15672
15673 /* Set window_end_pos to the offset of the last character displayed
15674 on the window from the end of current_buffer. Set
15675 window_end_vpos to its row number. */
15676 if (last_text_row)
15677 {
15678 xassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row));
15679 w->window_end_bytepos
15680 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
15681 w->window_end_pos
15682 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
15683 w->window_end_vpos
15684 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
15685 xassert (MATRIX_ROW (w->desired_matrix, XFASTINT (w->window_end_vpos))
15686 ->displays_text_p);
15687 }
15688 else
15689 {
15690 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
15691 w->window_end_pos = make_number (Z - ZV);
15692 w->window_end_vpos = make_number (0);
15693 }
15694
15695 /* But that is not valid info until redisplay finishes. */
15696 w->window_end_valid = Qnil;
15697 return 1;
15698 }
15699
15700
15701 \f
15702 /************************************************************************
15703 Window redisplay reusing current matrix when buffer has not changed
15704 ************************************************************************/
15705
15706 /* Try redisplay of window W showing an unchanged buffer with a
15707 different window start than the last time it was displayed by
15708 reusing its current matrix. Value is non-zero if successful.
15709 W->start is the new window start. */
15710
15711 static int
15712 try_window_reusing_current_matrix (struct window *w)
15713 {
15714 struct frame *f = XFRAME (w->frame);
15715 struct glyph_row *bottom_row;
15716 struct it it;
15717 struct run run;
15718 struct text_pos start, new_start;
15719 int nrows_scrolled, i;
15720 struct glyph_row *last_text_row;
15721 struct glyph_row *last_reused_text_row;
15722 struct glyph_row *start_row;
15723 int start_vpos, min_y, max_y;
15724
15725 #if GLYPH_DEBUG
15726 if (inhibit_try_window_reusing)
15727 return 0;
15728 #endif
15729
15730 if (/* This function doesn't handle terminal frames. */
15731 !FRAME_WINDOW_P (f)
15732 /* Don't try to reuse the display if windows have been split
15733 or such. */
15734 || windows_or_buffers_changed
15735 || cursor_type_changed)
15736 return 0;
15737
15738 /* Can't do this if region may have changed. */
15739 if ((!NILP (Vtransient_mark_mode)
15740 && !NILP (BVAR (current_buffer, mark_active)))
15741 || !NILP (w->region_showing)
15742 || !NILP (Vshow_trailing_whitespace))
15743 return 0;
15744
15745 /* If top-line visibility has changed, give up. */
15746 if (WINDOW_WANTS_HEADER_LINE_P (w)
15747 != MATRIX_HEADER_LINE_ROW (w->current_matrix)->mode_line_p)
15748 return 0;
15749
15750 /* Give up if old or new display is scrolled vertically. We could
15751 make this function handle this, but right now it doesn't. */
15752 start_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
15753 if (w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row))
15754 return 0;
15755
15756 /* The variable new_start now holds the new window start. The old
15757 start `start' can be determined from the current matrix. */
15758 SET_TEXT_POS_FROM_MARKER (new_start, w->start);
15759 start = start_row->minpos;
15760 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
15761
15762 /* Clear the desired matrix for the display below. */
15763 clear_glyph_matrix (w->desired_matrix);
15764
15765 if (CHARPOS (new_start) <= CHARPOS (start))
15766 {
15767 /* Don't use this method if the display starts with an ellipsis
15768 displayed for invisible text. It's not easy to handle that case
15769 below, and it's certainly not worth the effort since this is
15770 not a frequent case. */
15771 if (in_ellipses_for_invisible_text_p (&start_row->start, w))
15772 return 0;
15773
15774 IF_DEBUG (debug_method_add (w, "twu1"));
15775
15776 /* Display up to a row that can be reused. The variable
15777 last_text_row is set to the last row displayed that displays
15778 text. Note that it.vpos == 0 if or if not there is a
15779 header-line; it's not the same as the MATRIX_ROW_VPOS! */
15780 start_display (&it, w, new_start);
15781 w->cursor.vpos = -1;
15782 last_text_row = last_reused_text_row = NULL;
15783
15784 while (it.current_y < it.last_visible_y
15785 && !fonts_changed_p)
15786 {
15787 /* If we have reached into the characters in the START row,
15788 that means the line boundaries have changed. So we
15789 can't start copying with the row START. Maybe it will
15790 work to start copying with the following row. */
15791 while (IT_CHARPOS (it) > CHARPOS (start))
15792 {
15793 /* Advance to the next row as the "start". */
15794 start_row++;
15795 start = start_row->minpos;
15796 /* If there are no more rows to try, or just one, give up. */
15797 if (start_row == MATRIX_MODE_LINE_ROW (w->current_matrix) - 1
15798 || w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row)
15799 || CHARPOS (start) == ZV)
15800 {
15801 clear_glyph_matrix (w->desired_matrix);
15802 return 0;
15803 }
15804
15805 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
15806 }
15807 /* If we have reached alignment,
15808 we can copy the rest of the rows. */
15809 if (IT_CHARPOS (it) == CHARPOS (start))
15810 break;
15811
15812 if (display_line (&it))
15813 last_text_row = it.glyph_row - 1;
15814 }
15815
15816 /* A value of current_y < last_visible_y means that we stopped
15817 at the previous window start, which in turn means that we
15818 have at least one reusable row. */
15819 if (it.current_y < it.last_visible_y)
15820 {
15821 struct glyph_row *row;
15822
15823 /* IT.vpos always starts from 0; it counts text lines. */
15824 nrows_scrolled = it.vpos - (start_row - MATRIX_FIRST_TEXT_ROW (w->current_matrix));
15825
15826 /* Find PT if not already found in the lines displayed. */
15827 if (w->cursor.vpos < 0)
15828 {
15829 int dy = it.current_y - start_row->y;
15830
15831 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
15832 row = row_containing_pos (w, PT, row, NULL, dy);
15833 if (row)
15834 set_cursor_from_row (w, row, w->current_matrix, 0, 0,
15835 dy, nrows_scrolled);
15836 else
15837 {
15838 clear_glyph_matrix (w->desired_matrix);
15839 return 0;
15840 }
15841 }
15842
15843 /* Scroll the display. Do it before the current matrix is
15844 changed. The problem here is that update has not yet
15845 run, i.e. part of the current matrix is not up to date.
15846 scroll_run_hook will clear the cursor, and use the
15847 current matrix to get the height of the row the cursor is
15848 in. */
15849 run.current_y = start_row->y;
15850 run.desired_y = it.current_y;
15851 run.height = it.last_visible_y - it.current_y;
15852
15853 if (run.height > 0 && run.current_y != run.desired_y)
15854 {
15855 update_begin (f);
15856 FRAME_RIF (f)->update_window_begin_hook (w);
15857 FRAME_RIF (f)->clear_window_mouse_face (w);
15858 FRAME_RIF (f)->scroll_run_hook (w, &run);
15859 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
15860 update_end (f);
15861 }
15862
15863 /* Shift current matrix down by nrows_scrolled lines. */
15864 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
15865 rotate_matrix (w->current_matrix,
15866 start_vpos,
15867 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
15868 nrows_scrolled);
15869
15870 /* Disable lines that must be updated. */
15871 for (i = 0; i < nrows_scrolled; ++i)
15872 (start_row + i)->enabled_p = 0;
15873
15874 /* Re-compute Y positions. */
15875 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
15876 max_y = it.last_visible_y;
15877 for (row = start_row + nrows_scrolled;
15878 row < bottom_row;
15879 ++row)
15880 {
15881 row->y = it.current_y;
15882 row->visible_height = row->height;
15883
15884 if (row->y < min_y)
15885 row->visible_height -= min_y - row->y;
15886 if (row->y + row->height > max_y)
15887 row->visible_height -= row->y + row->height - max_y;
15888 if (row->fringe_bitmap_periodic_p)
15889 row->redraw_fringe_bitmaps_p = 1;
15890
15891 it.current_y += row->height;
15892
15893 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
15894 last_reused_text_row = row;
15895 if (MATRIX_ROW_BOTTOM_Y (row) >= it.last_visible_y)
15896 break;
15897 }
15898
15899 /* Disable lines in the current matrix which are now
15900 below the window. */
15901 for (++row; row < bottom_row; ++row)
15902 row->enabled_p = row->mode_line_p = 0;
15903 }
15904
15905 /* Update window_end_pos etc.; last_reused_text_row is the last
15906 reused row from the current matrix containing text, if any.
15907 The value of last_text_row is the last displayed line
15908 containing text. */
15909 if (last_reused_text_row)
15910 {
15911 w->window_end_bytepos
15912 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_reused_text_row);
15913 w->window_end_pos
15914 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_reused_text_row));
15915 w->window_end_vpos
15916 = make_number (MATRIX_ROW_VPOS (last_reused_text_row,
15917 w->current_matrix));
15918 }
15919 else if (last_text_row)
15920 {
15921 w->window_end_bytepos
15922 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
15923 w->window_end_pos
15924 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
15925 w->window_end_vpos
15926 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
15927 }
15928 else
15929 {
15930 /* This window must be completely empty. */
15931 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
15932 w->window_end_pos = make_number (Z - ZV);
15933 w->window_end_vpos = make_number (0);
15934 }
15935 w->window_end_valid = Qnil;
15936
15937 /* Update hint: don't try scrolling again in update_window. */
15938 w->desired_matrix->no_scrolling_p = 1;
15939
15940 #if GLYPH_DEBUG
15941 debug_method_add (w, "try_window_reusing_current_matrix 1");
15942 #endif
15943 return 1;
15944 }
15945 else if (CHARPOS (new_start) > CHARPOS (start))
15946 {
15947 struct glyph_row *pt_row, *row;
15948 struct glyph_row *first_reusable_row;
15949 struct glyph_row *first_row_to_display;
15950 int dy;
15951 int yb = window_text_bottom_y (w);
15952
15953 /* Find the row starting at new_start, if there is one. Don't
15954 reuse a partially visible line at the end. */
15955 first_reusable_row = start_row;
15956 while (first_reusable_row->enabled_p
15957 && MATRIX_ROW_BOTTOM_Y (first_reusable_row) < yb
15958 && (MATRIX_ROW_START_CHARPOS (first_reusable_row)
15959 < CHARPOS (new_start)))
15960 ++first_reusable_row;
15961
15962 /* Give up if there is no row to reuse. */
15963 if (MATRIX_ROW_BOTTOM_Y (first_reusable_row) >= yb
15964 || !first_reusable_row->enabled_p
15965 || (MATRIX_ROW_START_CHARPOS (first_reusable_row)
15966 != CHARPOS (new_start)))
15967 return 0;
15968
15969 /* We can reuse fully visible rows beginning with
15970 first_reusable_row to the end of the window. Set
15971 first_row_to_display to the first row that cannot be reused.
15972 Set pt_row to the row containing point, if there is any. */
15973 pt_row = NULL;
15974 for (first_row_to_display = first_reusable_row;
15975 MATRIX_ROW_BOTTOM_Y (first_row_to_display) < yb;
15976 ++first_row_to_display)
15977 {
15978 if (PT >= MATRIX_ROW_START_CHARPOS (first_row_to_display)
15979 && PT < MATRIX_ROW_END_CHARPOS (first_row_to_display))
15980 pt_row = first_row_to_display;
15981 }
15982
15983 /* Start displaying at the start of first_row_to_display. */
15984 xassert (first_row_to_display->y < yb);
15985 init_to_row_start (&it, w, first_row_to_display);
15986
15987 nrows_scrolled = (MATRIX_ROW_VPOS (first_reusable_row, w->current_matrix)
15988 - start_vpos);
15989 it.vpos = (MATRIX_ROW_VPOS (first_row_to_display, w->current_matrix)
15990 - nrows_scrolled);
15991 it.current_y = (first_row_to_display->y - first_reusable_row->y
15992 + WINDOW_HEADER_LINE_HEIGHT (w));
15993
15994 /* Display lines beginning with first_row_to_display in the
15995 desired matrix. Set last_text_row to the last row displayed
15996 that displays text. */
15997 it.glyph_row = MATRIX_ROW (w->desired_matrix, it.vpos);
15998 if (pt_row == NULL)
15999 w->cursor.vpos = -1;
16000 last_text_row = NULL;
16001 while (it.current_y < it.last_visible_y && !fonts_changed_p)
16002 if (display_line (&it))
16003 last_text_row = it.glyph_row - 1;
16004
16005 /* If point is in a reused row, adjust y and vpos of the cursor
16006 position. */
16007 if (pt_row)
16008 {
16009 w->cursor.vpos -= nrows_scrolled;
16010 w->cursor.y -= first_reusable_row->y - start_row->y;
16011 }
16012
16013 /* Give up if point isn't in a row displayed or reused. (This
16014 also handles the case where w->cursor.vpos < nrows_scrolled
16015 after the calls to display_line, which can happen with scroll
16016 margins. See bug#1295.) */
16017 if (w->cursor.vpos < 0)
16018 {
16019 clear_glyph_matrix (w->desired_matrix);
16020 return 0;
16021 }
16022
16023 /* Scroll the display. */
16024 run.current_y = first_reusable_row->y;
16025 run.desired_y = WINDOW_HEADER_LINE_HEIGHT (w);
16026 run.height = it.last_visible_y - run.current_y;
16027 dy = run.current_y - run.desired_y;
16028
16029 if (run.height)
16030 {
16031 update_begin (f);
16032 FRAME_RIF (f)->update_window_begin_hook (w);
16033 FRAME_RIF (f)->clear_window_mouse_face (w);
16034 FRAME_RIF (f)->scroll_run_hook (w, &run);
16035 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
16036 update_end (f);
16037 }
16038
16039 /* Adjust Y positions of reused rows. */
16040 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
16041 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
16042 max_y = it.last_visible_y;
16043 for (row = first_reusable_row; row < first_row_to_display; ++row)
16044 {
16045 row->y -= dy;
16046 row->visible_height = row->height;
16047 if (row->y < min_y)
16048 row->visible_height -= min_y - row->y;
16049 if (row->y + row->height > max_y)
16050 row->visible_height -= row->y + row->height - max_y;
16051 if (row->fringe_bitmap_periodic_p)
16052 row->redraw_fringe_bitmaps_p = 1;
16053 }
16054
16055 /* Scroll the current matrix. */
16056 xassert (nrows_scrolled > 0);
16057 rotate_matrix (w->current_matrix,
16058 start_vpos,
16059 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
16060 -nrows_scrolled);
16061
16062 /* Disable rows not reused. */
16063 for (row -= nrows_scrolled; row < bottom_row; ++row)
16064 row->enabled_p = 0;
16065
16066 /* Point may have moved to a different line, so we cannot assume that
16067 the previous cursor position is valid; locate the correct row. */
16068 if (pt_row)
16069 {
16070 for (row = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
16071 row < bottom_row && PT >= MATRIX_ROW_END_CHARPOS (row);
16072 row++)
16073 {
16074 w->cursor.vpos++;
16075 w->cursor.y = row->y;
16076 }
16077 if (row < bottom_row)
16078 {
16079 struct glyph *glyph = row->glyphs[TEXT_AREA] + w->cursor.hpos;
16080 struct glyph *end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
16081
16082 /* Can't use this optimization with bidi-reordered glyph
16083 rows, unless cursor is already at point. */
16084 if (!NILP (BVAR (XBUFFER (w->buffer), bidi_display_reordering)))
16085 {
16086 if (!(w->cursor.hpos >= 0
16087 && w->cursor.hpos < row->used[TEXT_AREA]
16088 && BUFFERP (glyph->object)
16089 && glyph->charpos == PT))
16090 return 0;
16091 }
16092 else
16093 for (; glyph < end
16094 && (!BUFFERP (glyph->object)
16095 || glyph->charpos < PT);
16096 glyph++)
16097 {
16098 w->cursor.hpos++;
16099 w->cursor.x += glyph->pixel_width;
16100 }
16101 }
16102 }
16103
16104 /* Adjust window end. A null value of last_text_row means that
16105 the window end is in reused rows which in turn means that
16106 only its vpos can have changed. */
16107 if (last_text_row)
16108 {
16109 w->window_end_bytepos
16110 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
16111 w->window_end_pos
16112 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
16113 w->window_end_vpos
16114 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
16115 }
16116 else
16117 {
16118 w->window_end_vpos
16119 = make_number (XFASTINT (w->window_end_vpos) - nrows_scrolled);
16120 }
16121
16122 w->window_end_valid = Qnil;
16123 w->desired_matrix->no_scrolling_p = 1;
16124
16125 #if GLYPH_DEBUG
16126 debug_method_add (w, "try_window_reusing_current_matrix 2");
16127 #endif
16128 return 1;
16129 }
16130
16131 return 0;
16132 }
16133
16134
16135 \f
16136 /************************************************************************
16137 Window redisplay reusing current matrix when buffer has changed
16138 ************************************************************************/
16139
16140 static struct glyph_row *find_last_unchanged_at_beg_row (struct window *);
16141 static struct glyph_row *find_first_unchanged_at_end_row (struct window *,
16142 EMACS_INT *, EMACS_INT *);
16143 static struct glyph_row *
16144 find_last_row_displaying_text (struct glyph_matrix *, struct it *,
16145 struct glyph_row *);
16146
16147
16148 /* Return the last row in MATRIX displaying text. If row START is
16149 non-null, start searching with that row. IT gives the dimensions
16150 of the display. Value is null if matrix is empty; otherwise it is
16151 a pointer to the row found. */
16152
16153 static struct glyph_row *
16154 find_last_row_displaying_text (struct glyph_matrix *matrix, struct it *it,
16155 struct glyph_row *start)
16156 {
16157 struct glyph_row *row, *row_found;
16158
16159 /* Set row_found to the last row in IT->w's current matrix
16160 displaying text. The loop looks funny but think of partially
16161 visible lines. */
16162 row_found = NULL;
16163 row = start ? start : MATRIX_FIRST_TEXT_ROW (matrix);
16164 while (MATRIX_ROW_DISPLAYS_TEXT_P (row))
16165 {
16166 xassert (row->enabled_p);
16167 row_found = row;
16168 if (MATRIX_ROW_BOTTOM_Y (row) >= it->last_visible_y)
16169 break;
16170 ++row;
16171 }
16172
16173 return row_found;
16174 }
16175
16176
16177 /* Return the last row in the current matrix of W that is not affected
16178 by changes at the start of current_buffer that occurred since W's
16179 current matrix was built. Value is null if no such row exists.
16180
16181 BEG_UNCHANGED us the number of characters unchanged at the start of
16182 current_buffer. BEG + BEG_UNCHANGED is the buffer position of the
16183 first changed character in current_buffer. Characters at positions <
16184 BEG + BEG_UNCHANGED are at the same buffer positions as they were
16185 when the current matrix was built. */
16186
16187 static struct glyph_row *
16188 find_last_unchanged_at_beg_row (struct window *w)
16189 {
16190 EMACS_INT first_changed_pos = BEG + BEG_UNCHANGED;
16191 struct glyph_row *row;
16192 struct glyph_row *row_found = NULL;
16193 int yb = window_text_bottom_y (w);
16194
16195 /* Find the last row displaying unchanged text. */
16196 for (row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
16197 MATRIX_ROW_DISPLAYS_TEXT_P (row)
16198 && MATRIX_ROW_START_CHARPOS (row) < first_changed_pos;
16199 ++row)
16200 {
16201 if (/* If row ends before first_changed_pos, it is unchanged,
16202 except in some case. */
16203 MATRIX_ROW_END_CHARPOS (row) <= first_changed_pos
16204 /* When row ends in ZV and we write at ZV it is not
16205 unchanged. */
16206 && !row->ends_at_zv_p
16207 /* When first_changed_pos is the end of a continued line,
16208 row is not unchanged because it may be no longer
16209 continued. */
16210 && !(MATRIX_ROW_END_CHARPOS (row) == first_changed_pos
16211 && (row->continued_p
16212 || row->exact_window_width_line_p)))
16213 row_found = row;
16214
16215 /* Stop if last visible row. */
16216 if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
16217 break;
16218 }
16219
16220 return row_found;
16221 }
16222
16223
16224 /* Find the first glyph row in the current matrix of W that is not
16225 affected by changes at the end of current_buffer since the
16226 time W's current matrix was built.
16227
16228 Return in *DELTA the number of chars by which buffer positions in
16229 unchanged text at the end of current_buffer must be adjusted.
16230
16231 Return in *DELTA_BYTES the corresponding number of bytes.
16232
16233 Value is null if no such row exists, i.e. all rows are affected by
16234 changes. */
16235
16236 static struct glyph_row *
16237 find_first_unchanged_at_end_row (struct window *w,
16238 EMACS_INT *delta, EMACS_INT *delta_bytes)
16239 {
16240 struct glyph_row *row;
16241 struct glyph_row *row_found = NULL;
16242
16243 *delta = *delta_bytes = 0;
16244
16245 /* Display must not have been paused, otherwise the current matrix
16246 is not up to date. */
16247 eassert (!NILP (w->window_end_valid));
16248
16249 /* A value of window_end_pos >= END_UNCHANGED means that the window
16250 end is in the range of changed text. If so, there is no
16251 unchanged row at the end of W's current matrix. */
16252 if (XFASTINT (w->window_end_pos) >= END_UNCHANGED)
16253 return NULL;
16254
16255 /* Set row to the last row in W's current matrix displaying text. */
16256 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
16257
16258 /* If matrix is entirely empty, no unchanged row exists. */
16259 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
16260 {
16261 /* The value of row is the last glyph row in the matrix having a
16262 meaningful buffer position in it. The end position of row
16263 corresponds to window_end_pos. This allows us to translate
16264 buffer positions in the current matrix to current buffer
16265 positions for characters not in changed text. */
16266 EMACS_INT Z_old =
16267 MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
16268 EMACS_INT Z_BYTE_old =
16269 MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
16270 EMACS_INT last_unchanged_pos, last_unchanged_pos_old;
16271 struct glyph_row *first_text_row
16272 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
16273
16274 *delta = Z - Z_old;
16275 *delta_bytes = Z_BYTE - Z_BYTE_old;
16276
16277 /* Set last_unchanged_pos to the buffer position of the last
16278 character in the buffer that has not been changed. Z is the
16279 index + 1 of the last character in current_buffer, i.e. by
16280 subtracting END_UNCHANGED we get the index of the last
16281 unchanged character, and we have to add BEG to get its buffer
16282 position. */
16283 last_unchanged_pos = Z - END_UNCHANGED + BEG;
16284 last_unchanged_pos_old = last_unchanged_pos - *delta;
16285
16286 /* Search backward from ROW for a row displaying a line that
16287 starts at a minimum position >= last_unchanged_pos_old. */
16288 for (; row > first_text_row; --row)
16289 {
16290 /* This used to abort, but it can happen.
16291 It is ok to just stop the search instead here. KFS. */
16292 if (!row->enabled_p || !MATRIX_ROW_DISPLAYS_TEXT_P (row))
16293 break;
16294
16295 if (MATRIX_ROW_START_CHARPOS (row) >= last_unchanged_pos_old)
16296 row_found = row;
16297 }
16298 }
16299
16300 eassert (!row_found || MATRIX_ROW_DISPLAYS_TEXT_P (row_found));
16301
16302 return row_found;
16303 }
16304
16305
16306 /* Make sure that glyph rows in the current matrix of window W
16307 reference the same glyph memory as corresponding rows in the
16308 frame's frame matrix. This function is called after scrolling W's
16309 current matrix on a terminal frame in try_window_id and
16310 try_window_reusing_current_matrix. */
16311
16312 static void
16313 sync_frame_with_window_matrix_rows (struct window *w)
16314 {
16315 struct frame *f = XFRAME (w->frame);
16316 struct glyph_row *window_row, *window_row_end, *frame_row;
16317
16318 /* Preconditions: W must be a leaf window and full-width. Its frame
16319 must have a frame matrix. */
16320 xassert (NILP (w->hchild) && NILP (w->vchild));
16321 xassert (WINDOW_FULL_WIDTH_P (w));
16322 xassert (!FRAME_WINDOW_P (f));
16323
16324 /* If W is a full-width window, glyph pointers in W's current matrix
16325 have, by definition, to be the same as glyph pointers in the
16326 corresponding frame matrix. Note that frame matrices have no
16327 marginal areas (see build_frame_matrix). */
16328 window_row = w->current_matrix->rows;
16329 window_row_end = window_row + w->current_matrix->nrows;
16330 frame_row = f->current_matrix->rows + WINDOW_TOP_EDGE_LINE (w);
16331 while (window_row < window_row_end)
16332 {
16333 struct glyph *start = window_row->glyphs[LEFT_MARGIN_AREA];
16334 struct glyph *end = window_row->glyphs[LAST_AREA];
16335
16336 frame_row->glyphs[LEFT_MARGIN_AREA] = start;
16337 frame_row->glyphs[TEXT_AREA] = start;
16338 frame_row->glyphs[RIGHT_MARGIN_AREA] = end;
16339 frame_row->glyphs[LAST_AREA] = end;
16340
16341 /* Disable frame rows whose corresponding window rows have
16342 been disabled in try_window_id. */
16343 if (!window_row->enabled_p)
16344 frame_row->enabled_p = 0;
16345
16346 ++window_row, ++frame_row;
16347 }
16348 }
16349
16350
16351 /* Find the glyph row in window W containing CHARPOS. Consider all
16352 rows between START and END (not inclusive). END null means search
16353 all rows to the end of the display area of W. Value is the row
16354 containing CHARPOS or null. */
16355
16356 struct glyph_row *
16357 row_containing_pos (struct window *w, EMACS_INT charpos,
16358 struct glyph_row *start, struct glyph_row *end, int dy)
16359 {
16360 struct glyph_row *row = start;
16361 struct glyph_row *best_row = NULL;
16362 EMACS_INT mindif = BUF_ZV (XBUFFER (w->buffer)) + 1;
16363 int last_y;
16364
16365 /* If we happen to start on a header-line, skip that. */
16366 if (row->mode_line_p)
16367 ++row;
16368
16369 if ((end && row >= end) || !row->enabled_p)
16370 return NULL;
16371
16372 last_y = window_text_bottom_y (w) - dy;
16373
16374 while (1)
16375 {
16376 /* Give up if we have gone too far. */
16377 if (end && row >= end)
16378 return NULL;
16379 /* This formerly returned if they were equal.
16380 I think that both quantities are of a "last plus one" type;
16381 if so, when they are equal, the row is within the screen. -- rms. */
16382 if (MATRIX_ROW_BOTTOM_Y (row) > last_y)
16383 return NULL;
16384
16385 /* If it is in this row, return this row. */
16386 if (! (MATRIX_ROW_END_CHARPOS (row) < charpos
16387 || (MATRIX_ROW_END_CHARPOS (row) == charpos
16388 /* The end position of a row equals the start
16389 position of the next row. If CHARPOS is there, we
16390 would rather display it in the next line, except
16391 when this line ends in ZV. */
16392 && !row->ends_at_zv_p
16393 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
16394 && charpos >= MATRIX_ROW_START_CHARPOS (row))
16395 {
16396 struct glyph *g;
16397
16398 if (NILP (BVAR (XBUFFER (w->buffer), bidi_display_reordering))
16399 || (!best_row && !row->continued_p))
16400 return row;
16401 /* In bidi-reordered rows, there could be several rows
16402 occluding point, all of them belonging to the same
16403 continued line. We need to find the row which fits
16404 CHARPOS the best. */
16405 for (g = row->glyphs[TEXT_AREA];
16406 g < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
16407 g++)
16408 {
16409 if (!STRINGP (g->object))
16410 {
16411 if (g->charpos > 0 && eabs (g->charpos - charpos) < mindif)
16412 {
16413 mindif = eabs (g->charpos - charpos);
16414 best_row = row;
16415 /* Exact match always wins. */
16416 if (mindif == 0)
16417 return best_row;
16418 }
16419 }
16420 }
16421 }
16422 else if (best_row && !row->continued_p)
16423 return best_row;
16424 ++row;
16425 }
16426 }
16427
16428
16429 /* Try to redisplay window W by reusing its existing display. W's
16430 current matrix must be up to date when this function is called,
16431 i.e. window_end_valid must not be nil.
16432
16433 Value is
16434
16435 1 if display has been updated
16436 0 if otherwise unsuccessful
16437 -1 if redisplay with same window start is known not to succeed
16438
16439 The following steps are performed:
16440
16441 1. Find the last row in the current matrix of W that is not
16442 affected by changes at the start of current_buffer. If no such row
16443 is found, give up.
16444
16445 2. Find the first row in W's current matrix that is not affected by
16446 changes at the end of current_buffer. Maybe there is no such row.
16447
16448 3. Display lines beginning with the row + 1 found in step 1 to the
16449 row found in step 2 or, if step 2 didn't find a row, to the end of
16450 the window.
16451
16452 4. If cursor is not known to appear on the window, give up.
16453
16454 5. If display stopped at the row found in step 2, scroll the
16455 display and current matrix as needed.
16456
16457 6. Maybe display some lines at the end of W, if we must. This can
16458 happen under various circumstances, like a partially visible line
16459 becoming fully visible, or because newly displayed lines are displayed
16460 in smaller font sizes.
16461
16462 7. Update W's window end information. */
16463
16464 static int
16465 try_window_id (struct window *w)
16466 {
16467 struct frame *f = XFRAME (w->frame);
16468 struct glyph_matrix *current_matrix = w->current_matrix;
16469 struct glyph_matrix *desired_matrix = w->desired_matrix;
16470 struct glyph_row *last_unchanged_at_beg_row;
16471 struct glyph_row *first_unchanged_at_end_row;
16472 struct glyph_row *row;
16473 struct glyph_row *bottom_row;
16474 int bottom_vpos;
16475 struct it it;
16476 EMACS_INT delta = 0, delta_bytes = 0, stop_pos;
16477 int dvpos, dy;
16478 struct text_pos start_pos;
16479 struct run run;
16480 int first_unchanged_at_end_vpos = 0;
16481 struct glyph_row *last_text_row, *last_text_row_at_end;
16482 struct text_pos start;
16483 EMACS_INT first_changed_charpos, last_changed_charpos;
16484
16485 #if GLYPH_DEBUG
16486 if (inhibit_try_window_id)
16487 return 0;
16488 #endif
16489
16490 /* This is handy for debugging. */
16491 #if 0
16492 #define GIVE_UP(X) \
16493 do { \
16494 fprintf (stderr, "try_window_id give up %d\n", (X)); \
16495 return 0; \
16496 } while (0)
16497 #else
16498 #define GIVE_UP(X) return 0
16499 #endif
16500
16501 SET_TEXT_POS_FROM_MARKER (start, w->start);
16502
16503 /* Don't use this for mini-windows because these can show
16504 messages and mini-buffers, and we don't handle that here. */
16505 if (MINI_WINDOW_P (w))
16506 GIVE_UP (1);
16507
16508 /* This flag is used to prevent redisplay optimizations. */
16509 if (windows_or_buffers_changed || cursor_type_changed)
16510 GIVE_UP (2);
16511
16512 /* Verify that narrowing has not changed.
16513 Also verify that we were not told to prevent redisplay optimizations.
16514 It would be nice to further
16515 reduce the number of cases where this prevents try_window_id. */
16516 if (current_buffer->clip_changed
16517 || current_buffer->prevent_redisplay_optimizations_p)
16518 GIVE_UP (3);
16519
16520 /* Window must either use window-based redisplay or be full width. */
16521 if (!FRAME_WINDOW_P (f)
16522 && (!FRAME_LINE_INS_DEL_OK (f)
16523 || !WINDOW_FULL_WIDTH_P (w)))
16524 GIVE_UP (4);
16525
16526 /* Give up if point is known NOT to appear in W. */
16527 if (PT < CHARPOS (start))
16528 GIVE_UP (5);
16529
16530 /* Another way to prevent redisplay optimizations. */
16531 if (XFASTINT (w->last_modified) == 0)
16532 GIVE_UP (6);
16533
16534 /* Verify that window is not hscrolled. */
16535 if (XFASTINT (w->hscroll) != 0)
16536 GIVE_UP (7);
16537
16538 /* Verify that display wasn't paused. */
16539 if (NILP (w->window_end_valid))
16540 GIVE_UP (8);
16541
16542 /* Can't use this if highlighting a region because a cursor movement
16543 will do more than just set the cursor. */
16544 if (!NILP (Vtransient_mark_mode)
16545 && !NILP (BVAR (current_buffer, mark_active)))
16546 GIVE_UP (9);
16547
16548 /* Likewise if highlighting trailing whitespace. */
16549 if (!NILP (Vshow_trailing_whitespace))
16550 GIVE_UP (11);
16551
16552 /* Likewise if showing a region. */
16553 if (!NILP (w->region_showing))
16554 GIVE_UP (10);
16555
16556 /* Can't use this if overlay arrow position and/or string have
16557 changed. */
16558 if (overlay_arrows_changed_p ())
16559 GIVE_UP (12);
16560
16561 /* When word-wrap is on, adding a space to the first word of a
16562 wrapped line can change the wrap position, altering the line
16563 above it. It might be worthwhile to handle this more
16564 intelligently, but for now just redisplay from scratch. */
16565 if (!NILP (BVAR (XBUFFER (w->buffer), word_wrap)))
16566 GIVE_UP (21);
16567
16568 /* Under bidi reordering, adding or deleting a character in the
16569 beginning of a paragraph, before the first strong directional
16570 character, can change the base direction of the paragraph (unless
16571 the buffer specifies a fixed paragraph direction), which will
16572 require to redisplay the whole paragraph. It might be worthwhile
16573 to find the paragraph limits and widen the range of redisplayed
16574 lines to that, but for now just give up this optimization and
16575 redisplay from scratch. */
16576 if (!NILP (BVAR (XBUFFER (w->buffer), bidi_display_reordering))
16577 && NILP (BVAR (XBUFFER (w->buffer), bidi_paragraph_direction)))
16578 GIVE_UP (22);
16579
16580 /* Make sure beg_unchanged and end_unchanged are up to date. Do it
16581 only if buffer has really changed. The reason is that the gap is
16582 initially at Z for freshly visited files. The code below would
16583 set end_unchanged to 0 in that case. */
16584 if (MODIFF > SAVE_MODIFF
16585 /* This seems to happen sometimes after saving a buffer. */
16586 || BEG_UNCHANGED + END_UNCHANGED > Z_BYTE)
16587 {
16588 if (GPT - BEG < BEG_UNCHANGED)
16589 BEG_UNCHANGED = GPT - BEG;
16590 if (Z - GPT < END_UNCHANGED)
16591 END_UNCHANGED = Z - GPT;
16592 }
16593
16594 /* The position of the first and last character that has been changed. */
16595 first_changed_charpos = BEG + BEG_UNCHANGED;
16596 last_changed_charpos = Z - END_UNCHANGED;
16597
16598 /* If window starts after a line end, and the last change is in
16599 front of that newline, then changes don't affect the display.
16600 This case happens with stealth-fontification. Note that although
16601 the display is unchanged, glyph positions in the matrix have to
16602 be adjusted, of course. */
16603 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
16604 if (MATRIX_ROW_DISPLAYS_TEXT_P (row)
16605 && ((last_changed_charpos < CHARPOS (start)
16606 && CHARPOS (start) == BEGV)
16607 || (last_changed_charpos < CHARPOS (start) - 1
16608 && FETCH_BYTE (BYTEPOS (start) - 1) == '\n')))
16609 {
16610 EMACS_INT Z_old, Z_delta, Z_BYTE_old, Z_delta_bytes;
16611 struct glyph_row *r0;
16612
16613 /* Compute how many chars/bytes have been added to or removed
16614 from the buffer. */
16615 Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
16616 Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
16617 Z_delta = Z - Z_old;
16618 Z_delta_bytes = Z_BYTE - Z_BYTE_old;
16619
16620 /* Give up if PT is not in the window. Note that it already has
16621 been checked at the start of try_window_id that PT is not in
16622 front of the window start. */
16623 if (PT >= MATRIX_ROW_END_CHARPOS (row) + Z_delta)
16624 GIVE_UP (13);
16625
16626 /* If window start is unchanged, we can reuse the whole matrix
16627 as is, after adjusting glyph positions. No need to compute
16628 the window end again, since its offset from Z hasn't changed. */
16629 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
16630 if (CHARPOS (start) == MATRIX_ROW_START_CHARPOS (r0) + Z_delta
16631 && BYTEPOS (start) == MATRIX_ROW_START_BYTEPOS (r0) + Z_delta_bytes
16632 /* PT must not be in a partially visible line. */
16633 && !(PT >= MATRIX_ROW_START_CHARPOS (row) + Z_delta
16634 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
16635 {
16636 /* Adjust positions in the glyph matrix. */
16637 if (Z_delta || Z_delta_bytes)
16638 {
16639 struct glyph_row *r1
16640 = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
16641 increment_matrix_positions (w->current_matrix,
16642 MATRIX_ROW_VPOS (r0, current_matrix),
16643 MATRIX_ROW_VPOS (r1, current_matrix),
16644 Z_delta, Z_delta_bytes);
16645 }
16646
16647 /* Set the cursor. */
16648 row = row_containing_pos (w, PT, r0, NULL, 0);
16649 if (row)
16650 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
16651 else
16652 abort ();
16653 return 1;
16654 }
16655 }
16656
16657 /* Handle the case that changes are all below what is displayed in
16658 the window, and that PT is in the window. This shortcut cannot
16659 be taken if ZV is visible in the window, and text has been added
16660 there that is visible in the window. */
16661 if (first_changed_charpos >= MATRIX_ROW_END_CHARPOS (row)
16662 /* ZV is not visible in the window, or there are no
16663 changes at ZV, actually. */
16664 && (current_matrix->zv > MATRIX_ROW_END_CHARPOS (row)
16665 || first_changed_charpos == last_changed_charpos))
16666 {
16667 struct glyph_row *r0;
16668
16669 /* Give up if PT is not in the window. Note that it already has
16670 been checked at the start of try_window_id that PT is not in
16671 front of the window start. */
16672 if (PT >= MATRIX_ROW_END_CHARPOS (row))
16673 GIVE_UP (14);
16674
16675 /* If window start is unchanged, we can reuse the whole matrix
16676 as is, without changing glyph positions since no text has
16677 been added/removed in front of the window end. */
16678 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
16679 if (TEXT_POS_EQUAL_P (start, r0->minpos)
16680 /* PT must not be in a partially visible line. */
16681 && !(PT >= MATRIX_ROW_START_CHARPOS (row)
16682 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
16683 {
16684 /* We have to compute the window end anew since text
16685 could have been added/removed after it. */
16686 w->window_end_pos
16687 = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
16688 w->window_end_bytepos
16689 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
16690
16691 /* Set the cursor. */
16692 row = row_containing_pos (w, PT, r0, NULL, 0);
16693 if (row)
16694 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
16695 else
16696 abort ();
16697 return 2;
16698 }
16699 }
16700
16701 /* Give up if window start is in the changed area.
16702
16703 The condition used to read
16704
16705 (BEG_UNCHANGED + END_UNCHANGED != Z - BEG && ...)
16706
16707 but why that was tested escapes me at the moment. */
16708 if (CHARPOS (start) >= first_changed_charpos
16709 && CHARPOS (start) <= last_changed_charpos)
16710 GIVE_UP (15);
16711
16712 /* Check that window start agrees with the start of the first glyph
16713 row in its current matrix. Check this after we know the window
16714 start is not in changed text, otherwise positions would not be
16715 comparable. */
16716 row = MATRIX_FIRST_TEXT_ROW (current_matrix);
16717 if (!TEXT_POS_EQUAL_P (start, row->minpos))
16718 GIVE_UP (16);
16719
16720 /* Give up if the window ends in strings. Overlay strings
16721 at the end are difficult to handle, so don't try. */
16722 row = MATRIX_ROW (current_matrix, XFASTINT (w->window_end_vpos));
16723 if (MATRIX_ROW_START_CHARPOS (row) == MATRIX_ROW_END_CHARPOS (row))
16724 GIVE_UP (20);
16725
16726 /* Compute the position at which we have to start displaying new
16727 lines. Some of the lines at the top of the window might be
16728 reusable because they are not displaying changed text. Find the
16729 last row in W's current matrix not affected by changes at the
16730 start of current_buffer. Value is null if changes start in the
16731 first line of window. */
16732 last_unchanged_at_beg_row = find_last_unchanged_at_beg_row (w);
16733 if (last_unchanged_at_beg_row)
16734 {
16735 /* Avoid starting to display in the moddle of a character, a TAB
16736 for instance. This is easier than to set up the iterator
16737 exactly, and it's not a frequent case, so the additional
16738 effort wouldn't really pay off. */
16739 while ((MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row)
16740 || last_unchanged_at_beg_row->ends_in_newline_from_string_p)
16741 && last_unchanged_at_beg_row > w->current_matrix->rows)
16742 --last_unchanged_at_beg_row;
16743
16744 if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row))
16745 GIVE_UP (17);
16746
16747 if (init_to_row_end (&it, w, last_unchanged_at_beg_row) == 0)
16748 GIVE_UP (18);
16749 start_pos = it.current.pos;
16750
16751 /* Start displaying new lines in the desired matrix at the same
16752 vpos we would use in the current matrix, i.e. below
16753 last_unchanged_at_beg_row. */
16754 it.vpos = 1 + MATRIX_ROW_VPOS (last_unchanged_at_beg_row,
16755 current_matrix);
16756 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
16757 it.current_y = MATRIX_ROW_BOTTOM_Y (last_unchanged_at_beg_row);
16758
16759 xassert (it.hpos == 0 && it.current_x == 0);
16760 }
16761 else
16762 {
16763 /* There are no reusable lines at the start of the window.
16764 Start displaying in the first text line. */
16765 start_display (&it, w, start);
16766 it.vpos = it.first_vpos;
16767 start_pos = it.current.pos;
16768 }
16769
16770 /* Find the first row that is not affected by changes at the end of
16771 the buffer. Value will be null if there is no unchanged row, in
16772 which case we must redisplay to the end of the window. delta
16773 will be set to the value by which buffer positions beginning with
16774 first_unchanged_at_end_row have to be adjusted due to text
16775 changes. */
16776 first_unchanged_at_end_row
16777 = find_first_unchanged_at_end_row (w, &delta, &delta_bytes);
16778 IF_DEBUG (debug_delta = delta);
16779 IF_DEBUG (debug_delta_bytes = delta_bytes);
16780
16781 /* Set stop_pos to the buffer position up to which we will have to
16782 display new lines. If first_unchanged_at_end_row != NULL, this
16783 is the buffer position of the start of the line displayed in that
16784 row. For first_unchanged_at_end_row == NULL, use 0 to indicate
16785 that we don't stop at a buffer position. */
16786 stop_pos = 0;
16787 if (first_unchanged_at_end_row)
16788 {
16789 xassert (last_unchanged_at_beg_row == NULL
16790 || first_unchanged_at_end_row >= last_unchanged_at_beg_row);
16791
16792 /* If this is a continuation line, move forward to the next one
16793 that isn't. Changes in lines above affect this line.
16794 Caution: this may move first_unchanged_at_end_row to a row
16795 not displaying text. */
16796 while (MATRIX_ROW_CONTINUATION_LINE_P (first_unchanged_at_end_row)
16797 && MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
16798 && (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
16799 < it.last_visible_y))
16800 ++first_unchanged_at_end_row;
16801
16802 if (!MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
16803 || (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
16804 >= it.last_visible_y))
16805 first_unchanged_at_end_row = NULL;
16806 else
16807 {
16808 stop_pos = (MATRIX_ROW_START_CHARPOS (first_unchanged_at_end_row)
16809 + delta);
16810 first_unchanged_at_end_vpos
16811 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, current_matrix);
16812 xassert (stop_pos >= Z - END_UNCHANGED);
16813 }
16814 }
16815 else if (last_unchanged_at_beg_row == NULL)
16816 GIVE_UP (19);
16817
16818
16819 #if GLYPH_DEBUG
16820
16821 /* Either there is no unchanged row at the end, or the one we have
16822 now displays text. This is a necessary condition for the window
16823 end pos calculation at the end of this function. */
16824 xassert (first_unchanged_at_end_row == NULL
16825 || MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
16826
16827 debug_last_unchanged_at_beg_vpos
16828 = (last_unchanged_at_beg_row
16829 ? MATRIX_ROW_VPOS (last_unchanged_at_beg_row, current_matrix)
16830 : -1);
16831 debug_first_unchanged_at_end_vpos = first_unchanged_at_end_vpos;
16832
16833 #endif /* GLYPH_DEBUG != 0 */
16834
16835
16836 /* Display new lines. Set last_text_row to the last new line
16837 displayed which has text on it, i.e. might end up as being the
16838 line where the window_end_vpos is. */
16839 w->cursor.vpos = -1;
16840 last_text_row = NULL;
16841 overlay_arrow_seen = 0;
16842 while (it.current_y < it.last_visible_y
16843 && !fonts_changed_p
16844 && (first_unchanged_at_end_row == NULL
16845 || IT_CHARPOS (it) < stop_pos))
16846 {
16847 if (display_line (&it))
16848 last_text_row = it.glyph_row - 1;
16849 }
16850
16851 if (fonts_changed_p)
16852 return -1;
16853
16854
16855 /* Compute differences in buffer positions, y-positions etc. for
16856 lines reused at the bottom of the window. Compute what we can
16857 scroll. */
16858 if (first_unchanged_at_end_row
16859 /* No lines reused because we displayed everything up to the
16860 bottom of the window. */
16861 && it.current_y < it.last_visible_y)
16862 {
16863 dvpos = (it.vpos
16864 - MATRIX_ROW_VPOS (first_unchanged_at_end_row,
16865 current_matrix));
16866 dy = it.current_y - first_unchanged_at_end_row->y;
16867 run.current_y = first_unchanged_at_end_row->y;
16868 run.desired_y = run.current_y + dy;
16869 run.height = it.last_visible_y - max (run.current_y, run.desired_y);
16870 }
16871 else
16872 {
16873 delta = delta_bytes = dvpos = dy
16874 = run.current_y = run.desired_y = run.height = 0;
16875 first_unchanged_at_end_row = NULL;
16876 }
16877 IF_DEBUG (debug_dvpos = dvpos; debug_dy = dy);
16878
16879
16880 /* Find the cursor if not already found. We have to decide whether
16881 PT will appear on this window (it sometimes doesn't, but this is
16882 not a very frequent case.) This decision has to be made before
16883 the current matrix is altered. A value of cursor.vpos < 0 means
16884 that PT is either in one of the lines beginning at
16885 first_unchanged_at_end_row or below the window. Don't care for
16886 lines that might be displayed later at the window end; as
16887 mentioned, this is not a frequent case. */
16888 if (w->cursor.vpos < 0)
16889 {
16890 /* Cursor in unchanged rows at the top? */
16891 if (PT < CHARPOS (start_pos)
16892 && last_unchanged_at_beg_row)
16893 {
16894 row = row_containing_pos (w, PT,
16895 MATRIX_FIRST_TEXT_ROW (w->current_matrix),
16896 last_unchanged_at_beg_row + 1, 0);
16897 if (row)
16898 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
16899 }
16900
16901 /* Start from first_unchanged_at_end_row looking for PT. */
16902 else if (first_unchanged_at_end_row)
16903 {
16904 row = row_containing_pos (w, PT - delta,
16905 first_unchanged_at_end_row, NULL, 0);
16906 if (row)
16907 set_cursor_from_row (w, row, w->current_matrix, delta,
16908 delta_bytes, dy, dvpos);
16909 }
16910
16911 /* Give up if cursor was not found. */
16912 if (w->cursor.vpos < 0)
16913 {
16914 clear_glyph_matrix (w->desired_matrix);
16915 return -1;
16916 }
16917 }
16918
16919 /* Don't let the cursor end in the scroll margins. */
16920 {
16921 int this_scroll_margin, cursor_height;
16922
16923 this_scroll_margin =
16924 max (0, min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4));
16925 this_scroll_margin *= FRAME_LINE_HEIGHT (it.f);
16926 cursor_height = MATRIX_ROW (w->desired_matrix, w->cursor.vpos)->height;
16927
16928 if ((w->cursor.y < this_scroll_margin
16929 && CHARPOS (start) > BEGV)
16930 /* Old redisplay didn't take scroll margin into account at the bottom,
16931 but then global-hl-line-mode doesn't scroll. KFS 2004-06-14 */
16932 || (w->cursor.y + (make_cursor_line_fully_visible_p
16933 ? cursor_height + this_scroll_margin
16934 : 1)) > it.last_visible_y)
16935 {
16936 w->cursor.vpos = -1;
16937 clear_glyph_matrix (w->desired_matrix);
16938 return -1;
16939 }
16940 }
16941
16942 /* Scroll the display. Do it before changing the current matrix so
16943 that xterm.c doesn't get confused about where the cursor glyph is
16944 found. */
16945 if (dy && run.height)
16946 {
16947 update_begin (f);
16948
16949 if (FRAME_WINDOW_P (f))
16950 {
16951 FRAME_RIF (f)->update_window_begin_hook (w);
16952 FRAME_RIF (f)->clear_window_mouse_face (w);
16953 FRAME_RIF (f)->scroll_run_hook (w, &run);
16954 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
16955 }
16956 else
16957 {
16958 /* Terminal frame. In this case, dvpos gives the number of
16959 lines to scroll by; dvpos < 0 means scroll up. */
16960 int from_vpos
16961 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, w->current_matrix);
16962 int from = WINDOW_TOP_EDGE_LINE (w) + from_vpos;
16963 int end = (WINDOW_TOP_EDGE_LINE (w)
16964 + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0)
16965 + window_internal_height (w));
16966
16967 #if defined (HAVE_GPM) || defined (MSDOS)
16968 x_clear_window_mouse_face (w);
16969 #endif
16970 /* Perform the operation on the screen. */
16971 if (dvpos > 0)
16972 {
16973 /* Scroll last_unchanged_at_beg_row to the end of the
16974 window down dvpos lines. */
16975 set_terminal_window (f, end);
16976
16977 /* On dumb terminals delete dvpos lines at the end
16978 before inserting dvpos empty lines. */
16979 if (!FRAME_SCROLL_REGION_OK (f))
16980 ins_del_lines (f, end - dvpos, -dvpos);
16981
16982 /* Insert dvpos empty lines in front of
16983 last_unchanged_at_beg_row. */
16984 ins_del_lines (f, from, dvpos);
16985 }
16986 else if (dvpos < 0)
16987 {
16988 /* Scroll up last_unchanged_at_beg_vpos to the end of
16989 the window to last_unchanged_at_beg_vpos - |dvpos|. */
16990 set_terminal_window (f, end);
16991
16992 /* Delete dvpos lines in front of
16993 last_unchanged_at_beg_vpos. ins_del_lines will set
16994 the cursor to the given vpos and emit |dvpos| delete
16995 line sequences. */
16996 ins_del_lines (f, from + dvpos, dvpos);
16997
16998 /* On a dumb terminal insert dvpos empty lines at the
16999 end. */
17000 if (!FRAME_SCROLL_REGION_OK (f))
17001 ins_del_lines (f, end + dvpos, -dvpos);
17002 }
17003
17004 set_terminal_window (f, 0);
17005 }
17006
17007 update_end (f);
17008 }
17009
17010 /* Shift reused rows of the current matrix to the right position.
17011 BOTTOM_ROW is the last + 1 row in the current matrix reserved for
17012 text. */
17013 bottom_row = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
17014 bottom_vpos = MATRIX_ROW_VPOS (bottom_row, current_matrix);
17015 if (dvpos < 0)
17016 {
17017 rotate_matrix (current_matrix, first_unchanged_at_end_vpos + dvpos,
17018 bottom_vpos, dvpos);
17019 enable_glyph_matrix_rows (current_matrix, bottom_vpos + dvpos,
17020 bottom_vpos, 0);
17021 }
17022 else if (dvpos > 0)
17023 {
17024 rotate_matrix (current_matrix, first_unchanged_at_end_vpos,
17025 bottom_vpos, dvpos);
17026 enable_glyph_matrix_rows (current_matrix, first_unchanged_at_end_vpos,
17027 first_unchanged_at_end_vpos + dvpos, 0);
17028 }
17029
17030 /* For frame-based redisplay, make sure that current frame and window
17031 matrix are in sync with respect to glyph memory. */
17032 if (!FRAME_WINDOW_P (f))
17033 sync_frame_with_window_matrix_rows (w);
17034
17035 /* Adjust buffer positions in reused rows. */
17036 if (delta || delta_bytes)
17037 increment_matrix_positions (current_matrix,
17038 first_unchanged_at_end_vpos + dvpos,
17039 bottom_vpos, delta, delta_bytes);
17040
17041 /* Adjust Y positions. */
17042 if (dy)
17043 shift_glyph_matrix (w, current_matrix,
17044 first_unchanged_at_end_vpos + dvpos,
17045 bottom_vpos, dy);
17046
17047 if (first_unchanged_at_end_row)
17048 {
17049 first_unchanged_at_end_row += dvpos;
17050 if (first_unchanged_at_end_row->y >= it.last_visible_y
17051 || !MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row))
17052 first_unchanged_at_end_row = NULL;
17053 }
17054
17055 /* If scrolling up, there may be some lines to display at the end of
17056 the window. */
17057 last_text_row_at_end = NULL;
17058 if (dy < 0)
17059 {
17060 /* Scrolling up can leave for example a partially visible line
17061 at the end of the window to be redisplayed. */
17062 /* Set last_row to the glyph row in the current matrix where the
17063 window end line is found. It has been moved up or down in
17064 the matrix by dvpos. */
17065 int last_vpos = XFASTINT (w->window_end_vpos) + dvpos;
17066 struct glyph_row *last_row = MATRIX_ROW (current_matrix, last_vpos);
17067
17068 /* If last_row is the window end line, it should display text. */
17069 xassert (last_row->displays_text_p);
17070
17071 /* If window end line was partially visible before, begin
17072 displaying at that line. Otherwise begin displaying with the
17073 line following it. */
17074 if (MATRIX_ROW_BOTTOM_Y (last_row) - dy >= it.last_visible_y)
17075 {
17076 init_to_row_start (&it, w, last_row);
17077 it.vpos = last_vpos;
17078 it.current_y = last_row->y;
17079 }
17080 else
17081 {
17082 init_to_row_end (&it, w, last_row);
17083 it.vpos = 1 + last_vpos;
17084 it.current_y = MATRIX_ROW_BOTTOM_Y (last_row);
17085 ++last_row;
17086 }
17087
17088 /* We may start in a continuation line. If so, we have to
17089 get the right continuation_lines_width and current_x. */
17090 it.continuation_lines_width = last_row->continuation_lines_width;
17091 it.hpos = it.current_x = 0;
17092
17093 /* Display the rest of the lines at the window end. */
17094 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
17095 while (it.current_y < it.last_visible_y
17096 && !fonts_changed_p)
17097 {
17098 /* Is it always sure that the display agrees with lines in
17099 the current matrix? I don't think so, so we mark rows
17100 displayed invalid in the current matrix by setting their
17101 enabled_p flag to zero. */
17102 MATRIX_ROW (w->current_matrix, it.vpos)->enabled_p = 0;
17103 if (display_line (&it))
17104 last_text_row_at_end = it.glyph_row - 1;
17105 }
17106 }
17107
17108 /* Update window_end_pos and window_end_vpos. */
17109 if (first_unchanged_at_end_row
17110 && !last_text_row_at_end)
17111 {
17112 /* Window end line if one of the preserved rows from the current
17113 matrix. Set row to the last row displaying text in current
17114 matrix starting at first_unchanged_at_end_row, after
17115 scrolling. */
17116 xassert (first_unchanged_at_end_row->displays_text_p);
17117 row = find_last_row_displaying_text (w->current_matrix, &it,
17118 first_unchanged_at_end_row);
17119 xassert (row && MATRIX_ROW_DISPLAYS_TEXT_P (row));
17120
17121 w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
17122 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
17123 w->window_end_vpos
17124 = make_number (MATRIX_ROW_VPOS (row, w->current_matrix));
17125 xassert (w->window_end_bytepos >= 0);
17126 IF_DEBUG (debug_method_add (w, "A"));
17127 }
17128 else if (last_text_row_at_end)
17129 {
17130 w->window_end_pos
17131 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row_at_end));
17132 w->window_end_bytepos
17133 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row_at_end);
17134 w->window_end_vpos
17135 = make_number (MATRIX_ROW_VPOS (last_text_row_at_end, desired_matrix));
17136 xassert (w->window_end_bytepos >= 0);
17137 IF_DEBUG (debug_method_add (w, "B"));
17138 }
17139 else if (last_text_row)
17140 {
17141 /* We have displayed either to the end of the window or at the
17142 end of the window, i.e. the last row with text is to be found
17143 in the desired matrix. */
17144 w->window_end_pos
17145 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
17146 w->window_end_bytepos
17147 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
17148 w->window_end_vpos
17149 = make_number (MATRIX_ROW_VPOS (last_text_row, desired_matrix));
17150 xassert (w->window_end_bytepos >= 0);
17151 }
17152 else if (first_unchanged_at_end_row == NULL
17153 && last_text_row == NULL
17154 && last_text_row_at_end == NULL)
17155 {
17156 /* Displayed to end of window, but no line containing text was
17157 displayed. Lines were deleted at the end of the window. */
17158 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
17159 int vpos = XFASTINT (w->window_end_vpos);
17160 struct glyph_row *current_row = current_matrix->rows + vpos;
17161 struct glyph_row *desired_row = desired_matrix->rows + vpos;
17162
17163 for (row = NULL;
17164 row == NULL && vpos >= first_vpos;
17165 --vpos, --current_row, --desired_row)
17166 {
17167 if (desired_row->enabled_p)
17168 {
17169 if (desired_row->displays_text_p)
17170 row = desired_row;
17171 }
17172 else if (current_row->displays_text_p)
17173 row = current_row;
17174 }
17175
17176 xassert (row != NULL);
17177 w->window_end_vpos = make_number (vpos + 1);
17178 w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
17179 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
17180 xassert (w->window_end_bytepos >= 0);
17181 IF_DEBUG (debug_method_add (w, "C"));
17182 }
17183 else
17184 abort ();
17185
17186 IF_DEBUG (debug_end_pos = XFASTINT (w->window_end_pos);
17187 debug_end_vpos = XFASTINT (w->window_end_vpos));
17188
17189 /* Record that display has not been completed. */
17190 w->window_end_valid = Qnil;
17191 w->desired_matrix->no_scrolling_p = 1;
17192 return 3;
17193
17194 #undef GIVE_UP
17195 }
17196
17197
17198 \f
17199 /***********************************************************************
17200 More debugging support
17201 ***********************************************************************/
17202
17203 #if GLYPH_DEBUG
17204
17205 void dump_glyph_row (struct glyph_row *, int, int) EXTERNALLY_VISIBLE;
17206 void dump_glyph_matrix (struct glyph_matrix *, int) EXTERNALLY_VISIBLE;
17207 void dump_glyph (struct glyph_row *, struct glyph *, int) EXTERNALLY_VISIBLE;
17208
17209
17210 /* Dump the contents of glyph matrix MATRIX on stderr.
17211
17212 GLYPHS 0 means don't show glyph contents.
17213 GLYPHS 1 means show glyphs in short form
17214 GLYPHS > 1 means show glyphs in long form. */
17215
17216 void
17217 dump_glyph_matrix (struct glyph_matrix *matrix, int glyphs)
17218 {
17219 int i;
17220 for (i = 0; i < matrix->nrows; ++i)
17221 dump_glyph_row (MATRIX_ROW (matrix, i), i, glyphs);
17222 }
17223
17224
17225 /* Dump contents of glyph GLYPH to stderr. ROW and AREA are
17226 the glyph row and area where the glyph comes from. */
17227
17228 void
17229 dump_glyph (struct glyph_row *row, struct glyph *glyph, int area)
17230 {
17231 if (glyph->type == CHAR_GLYPH)
17232 {
17233 fprintf (stderr,
17234 " %5td %4c %6"pI"d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
17235 glyph - row->glyphs[TEXT_AREA],
17236 'C',
17237 glyph->charpos,
17238 (BUFFERP (glyph->object)
17239 ? 'B'
17240 : (STRINGP (glyph->object)
17241 ? 'S'
17242 : '-')),
17243 glyph->pixel_width,
17244 glyph->u.ch,
17245 (glyph->u.ch < 0x80 && glyph->u.ch >= ' '
17246 ? glyph->u.ch
17247 : '.'),
17248 glyph->face_id,
17249 glyph->left_box_line_p,
17250 glyph->right_box_line_p);
17251 }
17252 else if (glyph->type == STRETCH_GLYPH)
17253 {
17254 fprintf (stderr,
17255 " %5td %4c %6"pI"d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
17256 glyph - row->glyphs[TEXT_AREA],
17257 'S',
17258 glyph->charpos,
17259 (BUFFERP (glyph->object)
17260 ? 'B'
17261 : (STRINGP (glyph->object)
17262 ? 'S'
17263 : '-')),
17264 glyph->pixel_width,
17265 0,
17266 '.',
17267 glyph->face_id,
17268 glyph->left_box_line_p,
17269 glyph->right_box_line_p);
17270 }
17271 else if (glyph->type == IMAGE_GLYPH)
17272 {
17273 fprintf (stderr,
17274 " %5td %4c %6"pI"d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
17275 glyph - row->glyphs[TEXT_AREA],
17276 'I',
17277 glyph->charpos,
17278 (BUFFERP (glyph->object)
17279 ? 'B'
17280 : (STRINGP (glyph->object)
17281 ? 'S'
17282 : '-')),
17283 glyph->pixel_width,
17284 glyph->u.img_id,
17285 '.',
17286 glyph->face_id,
17287 glyph->left_box_line_p,
17288 glyph->right_box_line_p);
17289 }
17290 else if (glyph->type == COMPOSITE_GLYPH)
17291 {
17292 fprintf (stderr,
17293 " %5td %4c %6"pI"d %c %3d 0x%05x",
17294 glyph - row->glyphs[TEXT_AREA],
17295 '+',
17296 glyph->charpos,
17297 (BUFFERP (glyph->object)
17298 ? 'B'
17299 : (STRINGP (glyph->object)
17300 ? 'S'
17301 : '-')),
17302 glyph->pixel_width,
17303 glyph->u.cmp.id);
17304 if (glyph->u.cmp.automatic)
17305 fprintf (stderr,
17306 "[%d-%d]",
17307 glyph->slice.cmp.from, glyph->slice.cmp.to);
17308 fprintf (stderr, " . %4d %1.1d%1.1d\n",
17309 glyph->face_id,
17310 glyph->left_box_line_p,
17311 glyph->right_box_line_p);
17312 }
17313 }
17314
17315
17316 /* Dump the contents of glyph row at VPOS in MATRIX to stderr.
17317 GLYPHS 0 means don't show glyph contents.
17318 GLYPHS 1 means show glyphs in short form
17319 GLYPHS > 1 means show glyphs in long form. */
17320
17321 void
17322 dump_glyph_row (struct glyph_row *row, int vpos, int glyphs)
17323 {
17324 if (glyphs != 1)
17325 {
17326 fprintf (stderr, "Row Start End Used oE><\\CTZFesm X Y W H V A P\n");
17327 fprintf (stderr, "======================================================================\n");
17328
17329 fprintf (stderr, "%3d %5"pI"d %5"pI"d %4d %1.1d%1.1d%1.1d%1.1d\
17330 %1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d %4d %4d %4d %4d %4d %4d %4d\n",
17331 vpos,
17332 MATRIX_ROW_START_CHARPOS (row),
17333 MATRIX_ROW_END_CHARPOS (row),
17334 row->used[TEXT_AREA],
17335 row->contains_overlapping_glyphs_p,
17336 row->enabled_p,
17337 row->truncated_on_left_p,
17338 row->truncated_on_right_p,
17339 row->continued_p,
17340 MATRIX_ROW_CONTINUATION_LINE_P (row),
17341 row->displays_text_p,
17342 row->ends_at_zv_p,
17343 row->fill_line_p,
17344 row->ends_in_middle_of_char_p,
17345 row->starts_in_middle_of_char_p,
17346 row->mouse_face_p,
17347 row->x,
17348 row->y,
17349 row->pixel_width,
17350 row->height,
17351 row->visible_height,
17352 row->ascent,
17353 row->phys_ascent);
17354 fprintf (stderr, "%9d %5d\t%5d\n", row->start.overlay_string_index,
17355 row->end.overlay_string_index,
17356 row->continuation_lines_width);
17357 fprintf (stderr, "%9"pI"d %5"pI"d\n",
17358 CHARPOS (row->start.string_pos),
17359 CHARPOS (row->end.string_pos));
17360 fprintf (stderr, "%9d %5d\n", row->start.dpvec_index,
17361 row->end.dpvec_index);
17362 }
17363
17364 if (glyphs > 1)
17365 {
17366 int area;
17367
17368 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
17369 {
17370 struct glyph *glyph = row->glyphs[area];
17371 struct glyph *glyph_end = glyph + row->used[area];
17372
17373 /* Glyph for a line end in text. */
17374 if (area == TEXT_AREA && glyph == glyph_end && glyph->charpos > 0)
17375 ++glyph_end;
17376
17377 if (glyph < glyph_end)
17378 fprintf (stderr, " Glyph Type Pos O W Code C Face LR\n");
17379
17380 for (; glyph < glyph_end; ++glyph)
17381 dump_glyph (row, glyph, area);
17382 }
17383 }
17384 else if (glyphs == 1)
17385 {
17386 int area;
17387
17388 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
17389 {
17390 char *s = (char *) alloca (row->used[area] + 1);
17391 int i;
17392
17393 for (i = 0; i < row->used[area]; ++i)
17394 {
17395 struct glyph *glyph = row->glyphs[area] + i;
17396 if (glyph->type == CHAR_GLYPH
17397 && glyph->u.ch < 0x80
17398 && glyph->u.ch >= ' ')
17399 s[i] = glyph->u.ch;
17400 else
17401 s[i] = '.';
17402 }
17403
17404 s[i] = '\0';
17405 fprintf (stderr, "%3d: (%d) '%s'\n", vpos, row->enabled_p, s);
17406 }
17407 }
17408 }
17409
17410
17411 DEFUN ("dump-glyph-matrix", Fdump_glyph_matrix,
17412 Sdump_glyph_matrix, 0, 1, "p",
17413 doc: /* Dump the current matrix of the selected window to stderr.
17414 Shows contents of glyph row structures. With non-nil
17415 parameter GLYPHS, dump glyphs as well. If GLYPHS is 1 show
17416 glyphs in short form, otherwise show glyphs in long form. */)
17417 (Lisp_Object glyphs)
17418 {
17419 struct window *w = XWINDOW (selected_window);
17420 struct buffer *buffer = XBUFFER (w->buffer);
17421
17422 fprintf (stderr, "PT = %"pI"d, BEGV = %"pI"d. ZV = %"pI"d\n",
17423 BUF_PT (buffer), BUF_BEGV (buffer), BUF_ZV (buffer));
17424 fprintf (stderr, "Cursor x = %d, y = %d, hpos = %d, vpos = %d\n",
17425 w->cursor.x, w->cursor.y, w->cursor.hpos, w->cursor.vpos);
17426 fprintf (stderr, "=============================================\n");
17427 dump_glyph_matrix (w->current_matrix,
17428 NILP (glyphs) ? 0 : XINT (glyphs));
17429 return Qnil;
17430 }
17431
17432
17433 DEFUN ("dump-frame-glyph-matrix", Fdump_frame_glyph_matrix,
17434 Sdump_frame_glyph_matrix, 0, 0, "", doc: /* */)
17435 (void)
17436 {
17437 struct frame *f = XFRAME (selected_frame);
17438 dump_glyph_matrix (f->current_matrix, 1);
17439 return Qnil;
17440 }
17441
17442
17443 DEFUN ("dump-glyph-row", Fdump_glyph_row, Sdump_glyph_row, 1, 2, "",
17444 doc: /* Dump glyph row ROW to stderr.
17445 GLYPH 0 means don't dump glyphs.
17446 GLYPH 1 means dump glyphs in short form.
17447 GLYPH > 1 or omitted means dump glyphs in long form. */)
17448 (Lisp_Object row, Lisp_Object glyphs)
17449 {
17450 struct glyph_matrix *matrix;
17451 int vpos;
17452
17453 CHECK_NUMBER (row);
17454 matrix = XWINDOW (selected_window)->current_matrix;
17455 vpos = XINT (row);
17456 if (vpos >= 0 && vpos < matrix->nrows)
17457 dump_glyph_row (MATRIX_ROW (matrix, vpos),
17458 vpos,
17459 INTEGERP (glyphs) ? XINT (glyphs) : 2);
17460 return Qnil;
17461 }
17462
17463
17464 DEFUN ("dump-tool-bar-row", Fdump_tool_bar_row, Sdump_tool_bar_row, 1, 2, "",
17465 doc: /* Dump glyph row ROW of the tool-bar of the current frame to stderr.
17466 GLYPH 0 means don't dump glyphs.
17467 GLYPH 1 means dump glyphs in short form.
17468 GLYPH > 1 or omitted means dump glyphs in long form. */)
17469 (Lisp_Object row, Lisp_Object glyphs)
17470 {
17471 struct frame *sf = SELECTED_FRAME ();
17472 struct glyph_matrix *m = XWINDOW (sf->tool_bar_window)->current_matrix;
17473 int vpos;
17474
17475 CHECK_NUMBER (row);
17476 vpos = XINT (row);
17477 if (vpos >= 0 && vpos < m->nrows)
17478 dump_glyph_row (MATRIX_ROW (m, vpos), vpos,
17479 INTEGERP (glyphs) ? XINT (glyphs) : 2);
17480 return Qnil;
17481 }
17482
17483
17484 DEFUN ("trace-redisplay", Ftrace_redisplay, Strace_redisplay, 0, 1, "P",
17485 doc: /* Toggle tracing of redisplay.
17486 With ARG, turn tracing on if and only if ARG is positive. */)
17487 (Lisp_Object arg)
17488 {
17489 if (NILP (arg))
17490 trace_redisplay_p = !trace_redisplay_p;
17491 else
17492 {
17493 arg = Fprefix_numeric_value (arg);
17494 trace_redisplay_p = XINT (arg) > 0;
17495 }
17496
17497 return Qnil;
17498 }
17499
17500
17501 DEFUN ("trace-to-stderr", Ftrace_to_stderr, Strace_to_stderr, 1, MANY, "",
17502 doc: /* Like `format', but print result to stderr.
17503 usage: (trace-to-stderr STRING &rest OBJECTS) */)
17504 (ptrdiff_t nargs, Lisp_Object *args)
17505 {
17506 Lisp_Object s = Fformat (nargs, args);
17507 fprintf (stderr, "%s", SDATA (s));
17508 return Qnil;
17509 }
17510
17511 #endif /* GLYPH_DEBUG */
17512
17513
17514 \f
17515 /***********************************************************************
17516 Building Desired Matrix Rows
17517 ***********************************************************************/
17518
17519 /* Return a temporary glyph row holding the glyphs of an overlay arrow.
17520 Used for non-window-redisplay windows, and for windows w/o left fringe. */
17521
17522 static struct glyph_row *
17523 get_overlay_arrow_glyph_row (struct window *w, Lisp_Object overlay_arrow_string)
17524 {
17525 struct frame *f = XFRAME (WINDOW_FRAME (w));
17526 struct buffer *buffer = XBUFFER (w->buffer);
17527 struct buffer *old = current_buffer;
17528 const unsigned char *arrow_string = SDATA (overlay_arrow_string);
17529 int arrow_len = SCHARS (overlay_arrow_string);
17530 const unsigned char *arrow_end = arrow_string + arrow_len;
17531 const unsigned char *p;
17532 struct it it;
17533 int multibyte_p;
17534 int n_glyphs_before;
17535
17536 set_buffer_temp (buffer);
17537 init_iterator (&it, w, -1, -1, &scratch_glyph_row, DEFAULT_FACE_ID);
17538 it.glyph_row->used[TEXT_AREA] = 0;
17539 SET_TEXT_POS (it.position, 0, 0);
17540
17541 multibyte_p = !NILP (BVAR (buffer, enable_multibyte_characters));
17542 p = arrow_string;
17543 while (p < arrow_end)
17544 {
17545 Lisp_Object face, ilisp;
17546
17547 /* Get the next character. */
17548 if (multibyte_p)
17549 it.c = it.char_to_display = string_char_and_length (p, &it.len);
17550 else
17551 {
17552 it.c = it.char_to_display = *p, it.len = 1;
17553 if (! ASCII_CHAR_P (it.c))
17554 it.char_to_display = BYTE8_TO_CHAR (it.c);
17555 }
17556 p += it.len;
17557
17558 /* Get its face. */
17559 ilisp = make_number (p - arrow_string);
17560 face = Fget_text_property (ilisp, Qface, overlay_arrow_string);
17561 it.face_id = compute_char_face (f, it.char_to_display, face);
17562
17563 /* Compute its width, get its glyphs. */
17564 n_glyphs_before = it.glyph_row->used[TEXT_AREA];
17565 SET_TEXT_POS (it.position, -1, -1);
17566 PRODUCE_GLYPHS (&it);
17567
17568 /* If this character doesn't fit any more in the line, we have
17569 to remove some glyphs. */
17570 if (it.current_x > it.last_visible_x)
17571 {
17572 it.glyph_row->used[TEXT_AREA] = n_glyphs_before;
17573 break;
17574 }
17575 }
17576
17577 set_buffer_temp (old);
17578 return it.glyph_row;
17579 }
17580
17581
17582 /* Insert truncation glyphs at the start of IT->glyph_row. Truncation
17583 glyphs are only inserted for terminal frames since we can't really
17584 win with truncation glyphs when partially visible glyphs are
17585 involved. Which glyphs to insert is determined by
17586 produce_special_glyphs. */
17587
17588 static void
17589 insert_left_trunc_glyphs (struct it *it)
17590 {
17591 struct it truncate_it;
17592 struct glyph *from, *end, *to, *toend;
17593
17594 xassert (!FRAME_WINDOW_P (it->f));
17595
17596 /* Get the truncation glyphs. */
17597 truncate_it = *it;
17598 truncate_it.current_x = 0;
17599 truncate_it.face_id = DEFAULT_FACE_ID;
17600 truncate_it.glyph_row = &scratch_glyph_row;
17601 truncate_it.glyph_row->used[TEXT_AREA] = 0;
17602 CHARPOS (truncate_it.position) = BYTEPOS (truncate_it.position) = -1;
17603 truncate_it.object = make_number (0);
17604 produce_special_glyphs (&truncate_it, IT_TRUNCATION);
17605
17606 /* Overwrite glyphs from IT with truncation glyphs. */
17607 if (!it->glyph_row->reversed_p)
17608 {
17609 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
17610 end = from + truncate_it.glyph_row->used[TEXT_AREA];
17611 to = it->glyph_row->glyphs[TEXT_AREA];
17612 toend = to + it->glyph_row->used[TEXT_AREA];
17613
17614 while (from < end)
17615 *to++ = *from++;
17616
17617 /* There may be padding glyphs left over. Overwrite them too. */
17618 while (to < toend && CHAR_GLYPH_PADDING_P (*to))
17619 {
17620 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
17621 while (from < end)
17622 *to++ = *from++;
17623 }
17624
17625 if (to > toend)
17626 it->glyph_row->used[TEXT_AREA] = to - it->glyph_row->glyphs[TEXT_AREA];
17627 }
17628 else
17629 {
17630 /* In R2L rows, overwrite the last (rightmost) glyphs, and do
17631 that back to front. */
17632 end = truncate_it.glyph_row->glyphs[TEXT_AREA];
17633 from = end + truncate_it.glyph_row->used[TEXT_AREA] - 1;
17634 toend = it->glyph_row->glyphs[TEXT_AREA];
17635 to = toend + it->glyph_row->used[TEXT_AREA] - 1;
17636
17637 while (from >= end && to >= toend)
17638 *to-- = *from--;
17639 while (to >= toend && CHAR_GLYPH_PADDING_P (*to))
17640 {
17641 from =
17642 truncate_it.glyph_row->glyphs[TEXT_AREA]
17643 + truncate_it.glyph_row->used[TEXT_AREA] - 1;
17644 while (from >= end && to >= toend)
17645 *to-- = *from--;
17646 }
17647 if (from >= end)
17648 {
17649 /* Need to free some room before prepending additional
17650 glyphs. */
17651 int move_by = from - end + 1;
17652 struct glyph *g0 = it->glyph_row->glyphs[TEXT_AREA];
17653 struct glyph *g = g0 + it->glyph_row->used[TEXT_AREA] - 1;
17654
17655 for ( ; g >= g0; g--)
17656 g[move_by] = *g;
17657 while (from >= end)
17658 *to-- = *from--;
17659 it->glyph_row->used[TEXT_AREA] += move_by;
17660 }
17661 }
17662 }
17663
17664
17665 /* Compute the pixel height and width of IT->glyph_row.
17666
17667 Most of the time, ascent and height of a display line will be equal
17668 to the max_ascent and max_height values of the display iterator
17669 structure. This is not the case if
17670
17671 1. We hit ZV without displaying anything. In this case, max_ascent
17672 and max_height will be zero.
17673
17674 2. We have some glyphs that don't contribute to the line height.
17675 (The glyph row flag contributes_to_line_height_p is for future
17676 pixmap extensions).
17677
17678 The first case is easily covered by using default values because in
17679 these cases, the line height does not really matter, except that it
17680 must not be zero. */
17681
17682 static void
17683 compute_line_metrics (struct it *it)
17684 {
17685 struct glyph_row *row = it->glyph_row;
17686
17687 if (FRAME_WINDOW_P (it->f))
17688 {
17689 int i, min_y, max_y;
17690
17691 /* The line may consist of one space only, that was added to
17692 place the cursor on it. If so, the row's height hasn't been
17693 computed yet. */
17694 if (row->height == 0)
17695 {
17696 if (it->max_ascent + it->max_descent == 0)
17697 it->max_descent = it->max_phys_descent = FRAME_LINE_HEIGHT (it->f);
17698 row->ascent = it->max_ascent;
17699 row->height = it->max_ascent + it->max_descent;
17700 row->phys_ascent = it->max_phys_ascent;
17701 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
17702 row->extra_line_spacing = it->max_extra_line_spacing;
17703 }
17704
17705 /* Compute the width of this line. */
17706 row->pixel_width = row->x;
17707 for (i = 0; i < row->used[TEXT_AREA]; ++i)
17708 row->pixel_width += row->glyphs[TEXT_AREA][i].pixel_width;
17709
17710 xassert (row->pixel_width >= 0);
17711 xassert (row->ascent >= 0 && row->height > 0);
17712
17713 row->overlapping_p = (MATRIX_ROW_OVERLAPS_SUCC_P (row)
17714 || MATRIX_ROW_OVERLAPS_PRED_P (row));
17715
17716 /* If first line's physical ascent is larger than its logical
17717 ascent, use the physical ascent, and make the row taller.
17718 This makes accented characters fully visible. */
17719 if (row == MATRIX_FIRST_TEXT_ROW (it->w->desired_matrix)
17720 && row->phys_ascent > row->ascent)
17721 {
17722 row->height += row->phys_ascent - row->ascent;
17723 row->ascent = row->phys_ascent;
17724 }
17725
17726 /* Compute how much of the line is visible. */
17727 row->visible_height = row->height;
17728
17729 min_y = WINDOW_HEADER_LINE_HEIGHT (it->w);
17730 max_y = WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w);
17731
17732 if (row->y < min_y)
17733 row->visible_height -= min_y - row->y;
17734 if (row->y + row->height > max_y)
17735 row->visible_height -= row->y + row->height - max_y;
17736 }
17737 else
17738 {
17739 row->pixel_width = row->used[TEXT_AREA];
17740 if (row->continued_p)
17741 row->pixel_width -= it->continuation_pixel_width;
17742 else if (row->truncated_on_right_p)
17743 row->pixel_width -= it->truncation_pixel_width;
17744 row->ascent = row->phys_ascent = 0;
17745 row->height = row->phys_height = row->visible_height = 1;
17746 row->extra_line_spacing = 0;
17747 }
17748
17749 /* Compute a hash code for this row. */
17750 {
17751 int area, i;
17752 row->hash = 0;
17753 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
17754 for (i = 0; i < row->used[area]; ++i)
17755 row->hash = ((((row->hash << 4) + (row->hash >> 24)) & 0x0fffffff)
17756 + row->glyphs[area][i].u.val
17757 + row->glyphs[area][i].face_id
17758 + row->glyphs[area][i].padding_p
17759 + (row->glyphs[area][i].type << 2));
17760 }
17761
17762 it->max_ascent = it->max_descent = 0;
17763 it->max_phys_ascent = it->max_phys_descent = 0;
17764 }
17765
17766
17767 /* Append one space to the glyph row of iterator IT if doing a
17768 window-based redisplay. The space has the same face as
17769 IT->face_id. Value is non-zero if a space was added.
17770
17771 This function is called to make sure that there is always one glyph
17772 at the end of a glyph row that the cursor can be set on under
17773 window-systems. (If there weren't such a glyph we would not know
17774 how wide and tall a box cursor should be displayed).
17775
17776 At the same time this space let's a nicely handle clearing to the
17777 end of the line if the row ends in italic text. */
17778
17779 static int
17780 append_space_for_newline (struct it *it, int default_face_p)
17781 {
17782 if (FRAME_WINDOW_P (it->f))
17783 {
17784 int n = it->glyph_row->used[TEXT_AREA];
17785
17786 if (it->glyph_row->glyphs[TEXT_AREA] + n
17787 < it->glyph_row->glyphs[1 + TEXT_AREA])
17788 {
17789 /* Save some values that must not be changed.
17790 Must save IT->c and IT->len because otherwise
17791 ITERATOR_AT_END_P wouldn't work anymore after
17792 append_space_for_newline has been called. */
17793 enum display_element_type saved_what = it->what;
17794 int saved_c = it->c, saved_len = it->len;
17795 int saved_char_to_display = it->char_to_display;
17796 int saved_x = it->current_x;
17797 int saved_face_id = it->face_id;
17798 struct text_pos saved_pos;
17799 Lisp_Object saved_object;
17800 struct face *face;
17801
17802 saved_object = it->object;
17803 saved_pos = it->position;
17804
17805 it->what = IT_CHARACTER;
17806 memset (&it->position, 0, sizeof it->position);
17807 it->object = make_number (0);
17808 it->c = it->char_to_display = ' ';
17809 it->len = 1;
17810
17811 if (default_face_p)
17812 it->face_id = DEFAULT_FACE_ID;
17813 else if (it->face_before_selective_p)
17814 it->face_id = it->saved_face_id;
17815 face = FACE_FROM_ID (it->f, it->face_id);
17816 it->face_id = FACE_FOR_CHAR (it->f, face, 0, -1, Qnil);
17817
17818 PRODUCE_GLYPHS (it);
17819
17820 it->override_ascent = -1;
17821 it->constrain_row_ascent_descent_p = 0;
17822 it->current_x = saved_x;
17823 it->object = saved_object;
17824 it->position = saved_pos;
17825 it->what = saved_what;
17826 it->face_id = saved_face_id;
17827 it->len = saved_len;
17828 it->c = saved_c;
17829 it->char_to_display = saved_char_to_display;
17830 return 1;
17831 }
17832 }
17833
17834 return 0;
17835 }
17836
17837
17838 /* Extend the face of the last glyph in the text area of IT->glyph_row
17839 to the end of the display line. Called from display_line. If the
17840 glyph row is empty, add a space glyph to it so that we know the
17841 face to draw. Set the glyph row flag fill_line_p. If the glyph
17842 row is R2L, prepend a stretch glyph to cover the empty space to the
17843 left of the leftmost glyph. */
17844
17845 static void
17846 extend_face_to_end_of_line (struct it *it)
17847 {
17848 struct face *face;
17849 struct frame *f = it->f;
17850
17851 /* If line is already filled, do nothing. Non window-system frames
17852 get a grace of one more ``pixel'' because their characters are
17853 1-``pixel'' wide, so they hit the equality too early. This grace
17854 is needed only for R2L rows that are not continued, to produce
17855 one extra blank where we could display the cursor. */
17856 if (it->current_x >= it->last_visible_x
17857 + (!FRAME_WINDOW_P (f)
17858 && it->glyph_row->reversed_p
17859 && !it->glyph_row->continued_p))
17860 return;
17861
17862 /* Face extension extends the background and box of IT->face_id
17863 to the end of the line. If the background equals the background
17864 of the frame, we don't have to do anything. */
17865 if (it->face_before_selective_p)
17866 face = FACE_FROM_ID (f, it->saved_face_id);
17867 else
17868 face = FACE_FROM_ID (f, it->face_id);
17869
17870 if (FRAME_WINDOW_P (f)
17871 && it->glyph_row->displays_text_p
17872 && face->box == FACE_NO_BOX
17873 && face->background == FRAME_BACKGROUND_PIXEL (f)
17874 && !face->stipple
17875 && !it->glyph_row->reversed_p)
17876 return;
17877
17878 /* Set the glyph row flag indicating that the face of the last glyph
17879 in the text area has to be drawn to the end of the text area. */
17880 it->glyph_row->fill_line_p = 1;
17881
17882 /* If current character of IT is not ASCII, make sure we have the
17883 ASCII face. This will be automatically undone the next time
17884 get_next_display_element returns a multibyte character. Note
17885 that the character will always be single byte in unibyte
17886 text. */
17887 if (!ASCII_CHAR_P (it->c))
17888 {
17889 it->face_id = FACE_FOR_CHAR (f, face, 0, -1, Qnil);
17890 }
17891
17892 if (FRAME_WINDOW_P (f))
17893 {
17894 /* If the row is empty, add a space with the current face of IT,
17895 so that we know which face to draw. */
17896 if (it->glyph_row->used[TEXT_AREA] == 0)
17897 {
17898 it->glyph_row->glyphs[TEXT_AREA][0] = space_glyph;
17899 it->glyph_row->glyphs[TEXT_AREA][0].face_id = it->face_id;
17900 it->glyph_row->used[TEXT_AREA] = 1;
17901 }
17902 #ifdef HAVE_WINDOW_SYSTEM
17903 if (it->glyph_row->reversed_p)
17904 {
17905 /* Prepend a stretch glyph to the row, such that the
17906 rightmost glyph will be drawn flushed all the way to the
17907 right margin of the window. The stretch glyph that will
17908 occupy the empty space, if any, to the left of the
17909 glyphs. */
17910 struct font *font = face->font ? face->font : FRAME_FONT (f);
17911 struct glyph *row_start = it->glyph_row->glyphs[TEXT_AREA];
17912 struct glyph *row_end = row_start + it->glyph_row->used[TEXT_AREA];
17913 struct glyph *g;
17914 int row_width, stretch_ascent, stretch_width;
17915 struct text_pos saved_pos;
17916 int saved_face_id, saved_avoid_cursor;
17917
17918 for (row_width = 0, g = row_start; g < row_end; g++)
17919 row_width += g->pixel_width;
17920 stretch_width = window_box_width (it->w, TEXT_AREA) - row_width;
17921 if (stretch_width > 0)
17922 {
17923 stretch_ascent =
17924 (((it->ascent + it->descent)
17925 * FONT_BASE (font)) / FONT_HEIGHT (font));
17926 saved_pos = it->position;
17927 memset (&it->position, 0, sizeof it->position);
17928 saved_avoid_cursor = it->avoid_cursor_p;
17929 it->avoid_cursor_p = 1;
17930 saved_face_id = it->face_id;
17931 /* The last row's stretch glyph should get the default
17932 face, to avoid painting the rest of the window with
17933 the region face, if the region ends at ZV. */
17934 if (it->glyph_row->ends_at_zv_p)
17935 it->face_id = DEFAULT_FACE_ID;
17936 else
17937 it->face_id = face->id;
17938 append_stretch_glyph (it, make_number (0), stretch_width,
17939 it->ascent + it->descent, stretch_ascent);
17940 it->position = saved_pos;
17941 it->avoid_cursor_p = saved_avoid_cursor;
17942 it->face_id = saved_face_id;
17943 }
17944 }
17945 #endif /* HAVE_WINDOW_SYSTEM */
17946 }
17947 else
17948 {
17949 /* Save some values that must not be changed. */
17950 int saved_x = it->current_x;
17951 struct text_pos saved_pos;
17952 Lisp_Object saved_object;
17953 enum display_element_type saved_what = it->what;
17954 int saved_face_id = it->face_id;
17955
17956 saved_object = it->object;
17957 saved_pos = it->position;
17958
17959 it->what = IT_CHARACTER;
17960 memset (&it->position, 0, sizeof it->position);
17961 it->object = make_number (0);
17962 it->c = it->char_to_display = ' ';
17963 it->len = 1;
17964 /* The last row's blank glyphs should get the default face, to
17965 avoid painting the rest of the window with the region face,
17966 if the region ends at ZV. */
17967 if (it->glyph_row->ends_at_zv_p)
17968 it->face_id = DEFAULT_FACE_ID;
17969 else
17970 it->face_id = face->id;
17971
17972 PRODUCE_GLYPHS (it);
17973
17974 while (it->current_x <= it->last_visible_x)
17975 PRODUCE_GLYPHS (it);
17976
17977 /* Don't count these blanks really. It would let us insert a left
17978 truncation glyph below and make us set the cursor on them, maybe. */
17979 it->current_x = saved_x;
17980 it->object = saved_object;
17981 it->position = saved_pos;
17982 it->what = saved_what;
17983 it->face_id = saved_face_id;
17984 }
17985 }
17986
17987
17988 /* Value is non-zero if text starting at CHARPOS in current_buffer is
17989 trailing whitespace. */
17990
17991 static int
17992 trailing_whitespace_p (EMACS_INT charpos)
17993 {
17994 EMACS_INT bytepos = CHAR_TO_BYTE (charpos);
17995 int c = 0;
17996
17997 while (bytepos < ZV_BYTE
17998 && (c = FETCH_CHAR (bytepos),
17999 c == ' ' || c == '\t'))
18000 ++bytepos;
18001
18002 if (bytepos >= ZV_BYTE || c == '\n' || c == '\r')
18003 {
18004 if (bytepos != PT_BYTE)
18005 return 1;
18006 }
18007 return 0;
18008 }
18009
18010
18011 /* Highlight trailing whitespace, if any, in ROW. */
18012
18013 static void
18014 highlight_trailing_whitespace (struct frame *f, struct glyph_row *row)
18015 {
18016 int used = row->used[TEXT_AREA];
18017
18018 if (used)
18019 {
18020 struct glyph *start = row->glyphs[TEXT_AREA];
18021 struct glyph *glyph = start + used - 1;
18022
18023 if (row->reversed_p)
18024 {
18025 /* Right-to-left rows need to be processed in the opposite
18026 direction, so swap the edge pointers. */
18027 glyph = start;
18028 start = row->glyphs[TEXT_AREA] + used - 1;
18029 }
18030
18031 /* Skip over glyphs inserted to display the cursor at the
18032 end of a line, for extending the face of the last glyph
18033 to the end of the line on terminals, and for truncation
18034 and continuation glyphs. */
18035 if (!row->reversed_p)
18036 {
18037 while (glyph >= start
18038 && glyph->type == CHAR_GLYPH
18039 && INTEGERP (glyph->object))
18040 --glyph;
18041 }
18042 else
18043 {
18044 while (glyph <= start
18045 && glyph->type == CHAR_GLYPH
18046 && INTEGERP (glyph->object))
18047 ++glyph;
18048 }
18049
18050 /* If last glyph is a space or stretch, and it's trailing
18051 whitespace, set the face of all trailing whitespace glyphs in
18052 IT->glyph_row to `trailing-whitespace'. */
18053 if ((row->reversed_p ? glyph <= start : glyph >= start)
18054 && BUFFERP (glyph->object)
18055 && (glyph->type == STRETCH_GLYPH
18056 || (glyph->type == CHAR_GLYPH
18057 && glyph->u.ch == ' '))
18058 && trailing_whitespace_p (glyph->charpos))
18059 {
18060 int face_id = lookup_named_face (f, Qtrailing_whitespace, 0);
18061 if (face_id < 0)
18062 return;
18063
18064 if (!row->reversed_p)
18065 {
18066 while (glyph >= start
18067 && BUFFERP (glyph->object)
18068 && (glyph->type == STRETCH_GLYPH
18069 || (glyph->type == CHAR_GLYPH
18070 && glyph->u.ch == ' ')))
18071 (glyph--)->face_id = face_id;
18072 }
18073 else
18074 {
18075 while (glyph <= start
18076 && BUFFERP (glyph->object)
18077 && (glyph->type == STRETCH_GLYPH
18078 || (glyph->type == CHAR_GLYPH
18079 && glyph->u.ch == ' ')))
18080 (glyph++)->face_id = face_id;
18081 }
18082 }
18083 }
18084 }
18085
18086
18087 /* Value is non-zero if glyph row ROW should be
18088 used to hold the cursor. */
18089
18090 static int
18091 cursor_row_p (struct glyph_row *row)
18092 {
18093 int result = 1;
18094
18095 if (PT == CHARPOS (row->end.pos)
18096 || PT == MATRIX_ROW_END_CHARPOS (row))
18097 {
18098 /* Suppose the row ends on a string.
18099 Unless the row is continued, that means it ends on a newline
18100 in the string. If it's anything other than a display string
18101 (e.g. a before-string from an overlay), we don't want the
18102 cursor there. (This heuristic seems to give the optimal
18103 behavior for the various types of multi-line strings.) */
18104 if (CHARPOS (row->end.string_pos) >= 0)
18105 {
18106 if (row->continued_p)
18107 result = 1;
18108 else
18109 {
18110 /* Check for `display' property. */
18111 struct glyph *beg = row->glyphs[TEXT_AREA];
18112 struct glyph *end = beg + row->used[TEXT_AREA] - 1;
18113 struct glyph *glyph;
18114
18115 result = 0;
18116 for (glyph = end; glyph >= beg; --glyph)
18117 if (STRINGP (glyph->object))
18118 {
18119 Lisp_Object prop
18120 = Fget_char_property (make_number (PT),
18121 Qdisplay, Qnil);
18122 result =
18123 (!NILP (prop)
18124 && display_prop_string_p (prop, glyph->object));
18125 break;
18126 }
18127 }
18128 }
18129 else if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
18130 {
18131 /* If the row ends in middle of a real character,
18132 and the line is continued, we want the cursor here.
18133 That's because CHARPOS (ROW->end.pos) would equal
18134 PT if PT is before the character. */
18135 if (!row->ends_in_ellipsis_p)
18136 result = row->continued_p;
18137 else
18138 /* If the row ends in an ellipsis, then
18139 CHARPOS (ROW->end.pos) will equal point after the
18140 invisible text. We want that position to be displayed
18141 after the ellipsis. */
18142 result = 0;
18143 }
18144 /* If the row ends at ZV, display the cursor at the end of that
18145 row instead of at the start of the row below. */
18146 else if (row->ends_at_zv_p)
18147 result = 1;
18148 else
18149 result = 0;
18150 }
18151
18152 return result;
18153 }
18154
18155 \f
18156
18157 /* Push the property PROP so that it will be rendered at the current
18158 position in IT. Return 1 if PROP was successfully pushed, 0
18159 otherwise. Called from handle_line_prefix to handle the
18160 `line-prefix' and `wrap-prefix' properties. */
18161
18162 static int
18163 push_display_prop (struct it *it, Lisp_Object prop)
18164 {
18165 struct text_pos pos =
18166 (it->method == GET_FROM_STRING) ? it->current.string_pos : it->current.pos;
18167
18168 xassert (it->method == GET_FROM_BUFFER
18169 || it->method == GET_FROM_STRING);
18170
18171 /* We need to save the current buffer/string position, so it will be
18172 restored by pop_it, because iterate_out_of_display_property
18173 depends on that being set correctly, but some situations leave
18174 it->position not yet set when this function is called. */
18175 push_it (it, &pos);
18176
18177 if (STRINGP (prop))
18178 {
18179 if (SCHARS (prop) == 0)
18180 {
18181 pop_it (it);
18182 return 0;
18183 }
18184
18185 it->string = prop;
18186 it->multibyte_p = STRING_MULTIBYTE (it->string);
18187 it->current.overlay_string_index = -1;
18188 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
18189 it->end_charpos = it->string_nchars = SCHARS (it->string);
18190 it->method = GET_FROM_STRING;
18191 it->stop_charpos = 0;
18192 it->prev_stop = 0;
18193 it->base_level_stop = 0;
18194
18195 /* Force paragraph direction to be that of the parent
18196 buffer/string. */
18197 if (it->bidi_p && it->bidi_it.paragraph_dir == R2L)
18198 it->paragraph_embedding = it->bidi_it.paragraph_dir;
18199 else
18200 it->paragraph_embedding = L2R;
18201
18202 /* Set up the bidi iterator for this display string. */
18203 if (it->bidi_p)
18204 {
18205 it->bidi_it.string.lstring = it->string;
18206 it->bidi_it.string.s = NULL;
18207 it->bidi_it.string.schars = it->end_charpos;
18208 it->bidi_it.string.bufpos = IT_CHARPOS (*it);
18209 it->bidi_it.string.from_disp_str = it->string_from_display_prop_p;
18210 it->bidi_it.string.unibyte = !it->multibyte_p;
18211 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
18212 }
18213 }
18214 else if (CONSP (prop) && EQ (XCAR (prop), Qspace))
18215 {
18216 it->method = GET_FROM_STRETCH;
18217 it->object = prop;
18218 }
18219 #ifdef HAVE_WINDOW_SYSTEM
18220 else if (IMAGEP (prop))
18221 {
18222 it->what = IT_IMAGE;
18223 it->image_id = lookup_image (it->f, prop);
18224 it->method = GET_FROM_IMAGE;
18225 }
18226 #endif /* HAVE_WINDOW_SYSTEM */
18227 else
18228 {
18229 pop_it (it); /* bogus display property, give up */
18230 return 0;
18231 }
18232
18233 return 1;
18234 }
18235
18236 /* Return the character-property PROP at the current position in IT. */
18237
18238 static Lisp_Object
18239 get_it_property (struct it *it, Lisp_Object prop)
18240 {
18241 Lisp_Object position;
18242
18243 if (STRINGP (it->object))
18244 position = make_number (IT_STRING_CHARPOS (*it));
18245 else if (BUFFERP (it->object))
18246 position = make_number (IT_CHARPOS (*it));
18247 else
18248 return Qnil;
18249
18250 return Fget_char_property (position, prop, it->object);
18251 }
18252
18253 /* See if there's a line- or wrap-prefix, and if so, push it on IT. */
18254
18255 static void
18256 handle_line_prefix (struct it *it)
18257 {
18258 Lisp_Object prefix;
18259
18260 if (it->continuation_lines_width > 0)
18261 {
18262 prefix = get_it_property (it, Qwrap_prefix);
18263 if (NILP (prefix))
18264 prefix = Vwrap_prefix;
18265 }
18266 else
18267 {
18268 prefix = get_it_property (it, Qline_prefix);
18269 if (NILP (prefix))
18270 prefix = Vline_prefix;
18271 }
18272 if (! NILP (prefix) && push_display_prop (it, prefix))
18273 {
18274 /* If the prefix is wider than the window, and we try to wrap
18275 it, it would acquire its own wrap prefix, and so on till the
18276 iterator stack overflows. So, don't wrap the prefix. */
18277 it->line_wrap = TRUNCATE;
18278 it->avoid_cursor_p = 1;
18279 }
18280 }
18281
18282 \f
18283
18284 /* Remove N glyphs at the start of a reversed IT->glyph_row. Called
18285 only for R2L lines from display_line and display_string, when they
18286 decide that too many glyphs were produced by PRODUCE_GLYPHS, and
18287 the line/string needs to be continued on the next glyph row. */
18288 static void
18289 unproduce_glyphs (struct it *it, int n)
18290 {
18291 struct glyph *glyph, *end;
18292
18293 xassert (it->glyph_row);
18294 xassert (it->glyph_row->reversed_p);
18295 xassert (it->area == TEXT_AREA);
18296 xassert (n <= it->glyph_row->used[TEXT_AREA]);
18297
18298 if (n > it->glyph_row->used[TEXT_AREA])
18299 n = it->glyph_row->used[TEXT_AREA];
18300 glyph = it->glyph_row->glyphs[TEXT_AREA] + n;
18301 end = it->glyph_row->glyphs[TEXT_AREA] + it->glyph_row->used[TEXT_AREA];
18302 for ( ; glyph < end; glyph++)
18303 glyph[-n] = *glyph;
18304 }
18305
18306 /* Find the positions in a bidi-reordered ROW to serve as ROW->minpos
18307 and ROW->maxpos. */
18308 static void
18309 find_row_edges (struct it *it, struct glyph_row *row,
18310 EMACS_INT min_pos, EMACS_INT min_bpos,
18311 EMACS_INT max_pos, EMACS_INT max_bpos)
18312 {
18313 /* FIXME: Revisit this when glyph ``spilling'' in continuation
18314 lines' rows is implemented for bidi-reordered rows. */
18315
18316 /* ROW->minpos is the value of min_pos, the minimal buffer position
18317 we have in ROW, or ROW->start.pos if that is smaller. */
18318 if (min_pos <= ZV && min_pos < row->start.pos.charpos)
18319 SET_TEXT_POS (row->minpos, min_pos, min_bpos);
18320 else
18321 /* We didn't find buffer positions smaller than ROW->start, or
18322 didn't find _any_ valid buffer positions in any of the glyphs,
18323 so we must trust the iterator's computed positions. */
18324 row->minpos = row->start.pos;
18325 if (max_pos <= 0)
18326 {
18327 max_pos = CHARPOS (it->current.pos);
18328 max_bpos = BYTEPOS (it->current.pos);
18329 }
18330
18331 /* Here are the various use-cases for ending the row, and the
18332 corresponding values for ROW->maxpos:
18333
18334 Line ends in a newline from buffer eol_pos + 1
18335 Line is continued from buffer max_pos + 1
18336 Line is truncated on right it->current.pos
18337 Line ends in a newline from string max_pos
18338 Line is continued from string max_pos
18339 Line is continued from display vector max_pos
18340 Line is entirely from a string min_pos == max_pos
18341 Line is entirely from a display vector min_pos == max_pos
18342 Line that ends at ZV ZV
18343
18344 If you discover other use-cases, please add them here as
18345 appropriate. */
18346 if (row->ends_at_zv_p)
18347 row->maxpos = it->current.pos;
18348 else if (row->used[TEXT_AREA])
18349 {
18350 if (row->ends_in_newline_from_string_p)
18351 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
18352 else if (CHARPOS (it->eol_pos) > 0)
18353 SET_TEXT_POS (row->maxpos,
18354 CHARPOS (it->eol_pos) + 1, BYTEPOS (it->eol_pos) + 1);
18355 else if (row->continued_p)
18356 {
18357 /* If max_pos is different from IT's current position, it
18358 means IT->method does not belong to the display element
18359 at max_pos. However, it also means that the display
18360 element at max_pos was displayed in its entirety on this
18361 line, which is equivalent to saying that the next line
18362 starts at the next buffer position. */
18363 if (IT_CHARPOS (*it) == max_pos && it->method != GET_FROM_BUFFER)
18364 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
18365 else
18366 {
18367 INC_BOTH (max_pos, max_bpos);
18368 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
18369 }
18370 }
18371 else if (row->truncated_on_right_p)
18372 /* display_line already called reseat_at_next_visible_line_start,
18373 which puts the iterator at the beginning of the next line, in
18374 the logical order. */
18375 row->maxpos = it->current.pos;
18376 else if (max_pos == min_pos && it->method != GET_FROM_BUFFER)
18377 /* A line that is entirely from a string/image/stretch... */
18378 row->maxpos = row->minpos;
18379 else
18380 abort ();
18381 }
18382 else
18383 row->maxpos = it->current.pos;
18384 }
18385
18386 /* Construct the glyph row IT->glyph_row in the desired matrix of
18387 IT->w from text at the current position of IT. See dispextern.h
18388 for an overview of struct it. Value is non-zero if
18389 IT->glyph_row displays text, as opposed to a line displaying ZV
18390 only. */
18391
18392 static int
18393 display_line (struct it *it)
18394 {
18395 struct glyph_row *row = it->glyph_row;
18396 Lisp_Object overlay_arrow_string;
18397 struct it wrap_it;
18398 void *wrap_data = NULL;
18399 int may_wrap = 0, wrap_x IF_LINT (= 0);
18400 int wrap_row_used = -1;
18401 int wrap_row_ascent IF_LINT (= 0), wrap_row_height IF_LINT (= 0);
18402 int wrap_row_phys_ascent IF_LINT (= 0), wrap_row_phys_height IF_LINT (= 0);
18403 int wrap_row_extra_line_spacing IF_LINT (= 0);
18404 EMACS_INT wrap_row_min_pos IF_LINT (= 0), wrap_row_min_bpos IF_LINT (= 0);
18405 EMACS_INT wrap_row_max_pos IF_LINT (= 0), wrap_row_max_bpos IF_LINT (= 0);
18406 int cvpos;
18407 EMACS_INT min_pos = ZV + 1, max_pos = 0;
18408 EMACS_INT min_bpos IF_LINT (= 0), max_bpos IF_LINT (= 0);
18409
18410 /* We always start displaying at hpos zero even if hscrolled. */
18411 xassert (it->hpos == 0 && it->current_x == 0);
18412
18413 if (MATRIX_ROW_VPOS (row, it->w->desired_matrix)
18414 >= it->w->desired_matrix->nrows)
18415 {
18416 it->w->nrows_scale_factor++;
18417 fonts_changed_p = 1;
18418 return 0;
18419 }
18420
18421 /* Is IT->w showing the region? */
18422 it->w->region_showing = it->region_beg_charpos > 0 ? Qt : Qnil;
18423
18424 /* Clear the result glyph row and enable it. */
18425 prepare_desired_row (row);
18426
18427 row->y = it->current_y;
18428 row->start = it->start;
18429 row->continuation_lines_width = it->continuation_lines_width;
18430 row->displays_text_p = 1;
18431 row->starts_in_middle_of_char_p = it->starts_in_middle_of_char_p;
18432 it->starts_in_middle_of_char_p = 0;
18433
18434 /* Arrange the overlays nicely for our purposes. Usually, we call
18435 display_line on only one line at a time, in which case this
18436 can't really hurt too much, or we call it on lines which appear
18437 one after another in the buffer, in which case all calls to
18438 recenter_overlay_lists but the first will be pretty cheap. */
18439 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
18440
18441 /* Move over display elements that are not visible because we are
18442 hscrolled. This may stop at an x-position < IT->first_visible_x
18443 if the first glyph is partially visible or if we hit a line end. */
18444 if (it->current_x < it->first_visible_x)
18445 {
18446 this_line_min_pos = row->start.pos;
18447 move_it_in_display_line_to (it, ZV, it->first_visible_x,
18448 MOVE_TO_POS | MOVE_TO_X);
18449 /* Record the smallest positions seen while we moved over
18450 display elements that are not visible. This is needed by
18451 redisplay_internal for optimizing the case where the cursor
18452 stays inside the same line. The rest of this function only
18453 considers positions that are actually displayed, so
18454 RECORD_MAX_MIN_POS will not otherwise record positions that
18455 are hscrolled to the left of the left edge of the window. */
18456 min_pos = CHARPOS (this_line_min_pos);
18457 min_bpos = BYTEPOS (this_line_min_pos);
18458 }
18459 else
18460 {
18461 /* We only do this when not calling `move_it_in_display_line_to'
18462 above, because move_it_in_display_line_to calls
18463 handle_line_prefix itself. */
18464 handle_line_prefix (it);
18465 }
18466
18467 /* Get the initial row height. This is either the height of the
18468 text hscrolled, if there is any, or zero. */
18469 row->ascent = it->max_ascent;
18470 row->height = it->max_ascent + it->max_descent;
18471 row->phys_ascent = it->max_phys_ascent;
18472 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
18473 row->extra_line_spacing = it->max_extra_line_spacing;
18474
18475 /* Utility macro to record max and min buffer positions seen until now. */
18476 #define RECORD_MAX_MIN_POS(IT) \
18477 do \
18478 { \
18479 int composition_p = (IT)->what == IT_COMPOSITION; \
18480 EMACS_INT current_pos = \
18481 composition_p ? (IT)->cmp_it.charpos \
18482 : IT_CHARPOS (*(IT)); \
18483 EMACS_INT current_bpos = \
18484 composition_p ? CHAR_TO_BYTE (current_pos) \
18485 : IT_BYTEPOS (*(IT)); \
18486 if (current_pos < min_pos) \
18487 { \
18488 min_pos = current_pos; \
18489 min_bpos = current_bpos; \
18490 } \
18491 if (IT_CHARPOS (*it) > max_pos) \
18492 { \
18493 max_pos = IT_CHARPOS (*it); \
18494 max_bpos = IT_BYTEPOS (*it); \
18495 } \
18496 } \
18497 while (0)
18498
18499 /* Loop generating characters. The loop is left with IT on the next
18500 character to display. */
18501 while (1)
18502 {
18503 int n_glyphs_before, hpos_before, x_before;
18504 int x, nglyphs;
18505 int ascent = 0, descent = 0, phys_ascent = 0, phys_descent = 0;
18506
18507 /* Retrieve the next thing to display. Value is zero if end of
18508 buffer reached. */
18509 if (!get_next_display_element (it))
18510 {
18511 /* Maybe add a space at the end of this line that is used to
18512 display the cursor there under X. Set the charpos of the
18513 first glyph of blank lines not corresponding to any text
18514 to -1. */
18515 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
18516 row->exact_window_width_line_p = 1;
18517 else if ((append_space_for_newline (it, 1) && row->used[TEXT_AREA] == 1)
18518 || row->used[TEXT_AREA] == 0)
18519 {
18520 row->glyphs[TEXT_AREA]->charpos = -1;
18521 row->displays_text_p = 0;
18522
18523 if (!NILP (BVAR (XBUFFER (it->w->buffer), indicate_empty_lines))
18524 && (!MINI_WINDOW_P (it->w)
18525 || (minibuf_level && EQ (it->window, minibuf_window))))
18526 row->indicate_empty_line_p = 1;
18527 }
18528
18529 it->continuation_lines_width = 0;
18530 row->ends_at_zv_p = 1;
18531 /* A row that displays right-to-left text must always have
18532 its last face extended all the way to the end of line,
18533 even if this row ends in ZV, because we still write to
18534 the screen left to right. */
18535 if (row->reversed_p)
18536 extend_face_to_end_of_line (it);
18537 break;
18538 }
18539
18540 /* Now, get the metrics of what we want to display. This also
18541 generates glyphs in `row' (which is IT->glyph_row). */
18542 n_glyphs_before = row->used[TEXT_AREA];
18543 x = it->current_x;
18544
18545 /* Remember the line height so far in case the next element doesn't
18546 fit on the line. */
18547 if (it->line_wrap != TRUNCATE)
18548 {
18549 ascent = it->max_ascent;
18550 descent = it->max_descent;
18551 phys_ascent = it->max_phys_ascent;
18552 phys_descent = it->max_phys_descent;
18553
18554 if (it->line_wrap == WORD_WRAP && it->area == TEXT_AREA)
18555 {
18556 if (IT_DISPLAYING_WHITESPACE (it))
18557 may_wrap = 1;
18558 else if (may_wrap)
18559 {
18560 SAVE_IT (wrap_it, *it, wrap_data);
18561 wrap_x = x;
18562 wrap_row_used = row->used[TEXT_AREA];
18563 wrap_row_ascent = row->ascent;
18564 wrap_row_height = row->height;
18565 wrap_row_phys_ascent = row->phys_ascent;
18566 wrap_row_phys_height = row->phys_height;
18567 wrap_row_extra_line_spacing = row->extra_line_spacing;
18568 wrap_row_min_pos = min_pos;
18569 wrap_row_min_bpos = min_bpos;
18570 wrap_row_max_pos = max_pos;
18571 wrap_row_max_bpos = max_bpos;
18572 may_wrap = 0;
18573 }
18574 }
18575 }
18576
18577 PRODUCE_GLYPHS (it);
18578
18579 /* If this display element was in marginal areas, continue with
18580 the next one. */
18581 if (it->area != TEXT_AREA)
18582 {
18583 row->ascent = max (row->ascent, it->max_ascent);
18584 row->height = max (row->height, it->max_ascent + it->max_descent);
18585 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
18586 row->phys_height = max (row->phys_height,
18587 it->max_phys_ascent + it->max_phys_descent);
18588 row->extra_line_spacing = max (row->extra_line_spacing,
18589 it->max_extra_line_spacing);
18590 set_iterator_to_next (it, 1);
18591 continue;
18592 }
18593
18594 /* Does the display element fit on the line? If we truncate
18595 lines, we should draw past the right edge of the window. If
18596 we don't truncate, we want to stop so that we can display the
18597 continuation glyph before the right margin. If lines are
18598 continued, there are two possible strategies for characters
18599 resulting in more than 1 glyph (e.g. tabs): Display as many
18600 glyphs as possible in this line and leave the rest for the
18601 continuation line, or display the whole element in the next
18602 line. Original redisplay did the former, so we do it also. */
18603 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
18604 hpos_before = it->hpos;
18605 x_before = x;
18606
18607 if (/* Not a newline. */
18608 nglyphs > 0
18609 /* Glyphs produced fit entirely in the line. */
18610 && it->current_x < it->last_visible_x)
18611 {
18612 it->hpos += nglyphs;
18613 row->ascent = max (row->ascent, it->max_ascent);
18614 row->height = max (row->height, it->max_ascent + it->max_descent);
18615 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
18616 row->phys_height = max (row->phys_height,
18617 it->max_phys_ascent + it->max_phys_descent);
18618 row->extra_line_spacing = max (row->extra_line_spacing,
18619 it->max_extra_line_spacing);
18620 if (it->current_x - it->pixel_width < it->first_visible_x)
18621 row->x = x - it->first_visible_x;
18622 /* Record the maximum and minimum buffer positions seen so
18623 far in glyphs that will be displayed by this row. */
18624 if (it->bidi_p)
18625 RECORD_MAX_MIN_POS (it);
18626 }
18627 else
18628 {
18629 int i, new_x;
18630 struct glyph *glyph;
18631
18632 for (i = 0; i < nglyphs; ++i, x = new_x)
18633 {
18634 glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
18635 new_x = x + glyph->pixel_width;
18636
18637 if (/* Lines are continued. */
18638 it->line_wrap != TRUNCATE
18639 && (/* Glyph doesn't fit on the line. */
18640 new_x > it->last_visible_x
18641 /* Or it fits exactly on a window system frame. */
18642 || (new_x == it->last_visible_x
18643 && FRAME_WINDOW_P (it->f))))
18644 {
18645 /* End of a continued line. */
18646
18647 if (it->hpos == 0
18648 || (new_x == it->last_visible_x
18649 && FRAME_WINDOW_P (it->f)))
18650 {
18651 /* Current glyph is the only one on the line or
18652 fits exactly on the line. We must continue
18653 the line because we can't draw the cursor
18654 after the glyph. */
18655 row->continued_p = 1;
18656 it->current_x = new_x;
18657 it->continuation_lines_width += new_x;
18658 ++it->hpos;
18659 /* Record the maximum and minimum buffer
18660 positions seen so far in glyphs that will be
18661 displayed by this row. */
18662 if (it->bidi_p)
18663 RECORD_MAX_MIN_POS (it);
18664 if (i == nglyphs - 1)
18665 {
18666 /* If line-wrap is on, check if a previous
18667 wrap point was found. */
18668 if (wrap_row_used > 0
18669 /* Even if there is a previous wrap
18670 point, continue the line here as
18671 usual, if (i) the previous character
18672 was a space or tab AND (ii) the
18673 current character is not. */
18674 && (!may_wrap
18675 || IT_DISPLAYING_WHITESPACE (it)))
18676 goto back_to_wrap;
18677
18678 set_iterator_to_next (it, 1);
18679 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
18680 {
18681 if (!get_next_display_element (it))
18682 {
18683 row->exact_window_width_line_p = 1;
18684 it->continuation_lines_width = 0;
18685 row->continued_p = 0;
18686 row->ends_at_zv_p = 1;
18687 }
18688 else if (ITERATOR_AT_END_OF_LINE_P (it))
18689 {
18690 row->continued_p = 0;
18691 row->exact_window_width_line_p = 1;
18692 }
18693 }
18694 }
18695 }
18696 else if (CHAR_GLYPH_PADDING_P (*glyph)
18697 && !FRAME_WINDOW_P (it->f))
18698 {
18699 /* A padding glyph that doesn't fit on this line.
18700 This means the whole character doesn't fit
18701 on the line. */
18702 if (row->reversed_p)
18703 unproduce_glyphs (it, row->used[TEXT_AREA]
18704 - n_glyphs_before);
18705 row->used[TEXT_AREA] = n_glyphs_before;
18706
18707 /* Fill the rest of the row with continuation
18708 glyphs like in 20.x. */
18709 while (row->glyphs[TEXT_AREA] + row->used[TEXT_AREA]
18710 < row->glyphs[1 + TEXT_AREA])
18711 produce_special_glyphs (it, IT_CONTINUATION);
18712
18713 row->continued_p = 1;
18714 it->current_x = x_before;
18715 it->continuation_lines_width += x_before;
18716
18717 /* Restore the height to what it was before the
18718 element not fitting on the line. */
18719 it->max_ascent = ascent;
18720 it->max_descent = descent;
18721 it->max_phys_ascent = phys_ascent;
18722 it->max_phys_descent = phys_descent;
18723 }
18724 else if (wrap_row_used > 0)
18725 {
18726 back_to_wrap:
18727 if (row->reversed_p)
18728 unproduce_glyphs (it,
18729 row->used[TEXT_AREA] - wrap_row_used);
18730 RESTORE_IT (it, &wrap_it, wrap_data);
18731 it->continuation_lines_width += wrap_x;
18732 row->used[TEXT_AREA] = wrap_row_used;
18733 row->ascent = wrap_row_ascent;
18734 row->height = wrap_row_height;
18735 row->phys_ascent = wrap_row_phys_ascent;
18736 row->phys_height = wrap_row_phys_height;
18737 row->extra_line_spacing = wrap_row_extra_line_spacing;
18738 min_pos = wrap_row_min_pos;
18739 min_bpos = wrap_row_min_bpos;
18740 max_pos = wrap_row_max_pos;
18741 max_bpos = wrap_row_max_bpos;
18742 row->continued_p = 1;
18743 row->ends_at_zv_p = 0;
18744 row->exact_window_width_line_p = 0;
18745 it->continuation_lines_width += x;
18746
18747 /* Make sure that a non-default face is extended
18748 up to the right margin of the window. */
18749 extend_face_to_end_of_line (it);
18750 }
18751 else if (it->c == '\t' && FRAME_WINDOW_P (it->f))
18752 {
18753 /* A TAB that extends past the right edge of the
18754 window. This produces a single glyph on
18755 window system frames. We leave the glyph in
18756 this row and let it fill the row, but don't
18757 consume the TAB. */
18758 it->continuation_lines_width += it->last_visible_x;
18759 row->ends_in_middle_of_char_p = 1;
18760 row->continued_p = 1;
18761 glyph->pixel_width = it->last_visible_x - x;
18762 it->starts_in_middle_of_char_p = 1;
18763 }
18764 else
18765 {
18766 /* Something other than a TAB that draws past
18767 the right edge of the window. Restore
18768 positions to values before the element. */
18769 if (row->reversed_p)
18770 unproduce_glyphs (it, row->used[TEXT_AREA]
18771 - (n_glyphs_before + i));
18772 row->used[TEXT_AREA] = n_glyphs_before + i;
18773
18774 /* Display continuation glyphs. */
18775 if (!FRAME_WINDOW_P (it->f))
18776 produce_special_glyphs (it, IT_CONTINUATION);
18777 row->continued_p = 1;
18778
18779 it->current_x = x_before;
18780 it->continuation_lines_width += x;
18781 extend_face_to_end_of_line (it);
18782
18783 if (nglyphs > 1 && i > 0)
18784 {
18785 row->ends_in_middle_of_char_p = 1;
18786 it->starts_in_middle_of_char_p = 1;
18787 }
18788
18789 /* Restore the height to what it was before the
18790 element not fitting on the line. */
18791 it->max_ascent = ascent;
18792 it->max_descent = descent;
18793 it->max_phys_ascent = phys_ascent;
18794 it->max_phys_descent = phys_descent;
18795 }
18796
18797 break;
18798 }
18799 else if (new_x > it->first_visible_x)
18800 {
18801 /* Increment number of glyphs actually displayed. */
18802 ++it->hpos;
18803
18804 /* Record the maximum and minimum buffer positions
18805 seen so far in glyphs that will be displayed by
18806 this row. */
18807 if (it->bidi_p)
18808 RECORD_MAX_MIN_POS (it);
18809
18810 if (x < it->first_visible_x)
18811 /* Glyph is partially visible, i.e. row starts at
18812 negative X position. */
18813 row->x = x - it->first_visible_x;
18814 }
18815 else
18816 {
18817 /* Glyph is completely off the left margin of the
18818 window. This should not happen because of the
18819 move_it_in_display_line at the start of this
18820 function, unless the text display area of the
18821 window is empty. */
18822 xassert (it->first_visible_x <= it->last_visible_x);
18823 }
18824 }
18825
18826 row->ascent = max (row->ascent, it->max_ascent);
18827 row->height = max (row->height, it->max_ascent + it->max_descent);
18828 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
18829 row->phys_height = max (row->phys_height,
18830 it->max_phys_ascent + it->max_phys_descent);
18831 row->extra_line_spacing = max (row->extra_line_spacing,
18832 it->max_extra_line_spacing);
18833
18834 /* End of this display line if row is continued. */
18835 if (row->continued_p || row->ends_at_zv_p)
18836 break;
18837 }
18838
18839 at_end_of_line:
18840 /* Is this a line end? If yes, we're also done, after making
18841 sure that a non-default face is extended up to the right
18842 margin of the window. */
18843 if (ITERATOR_AT_END_OF_LINE_P (it))
18844 {
18845 int used_before = row->used[TEXT_AREA];
18846
18847 row->ends_in_newline_from_string_p = STRINGP (it->object);
18848
18849 /* Add a space at the end of the line that is used to
18850 display the cursor there. */
18851 if (!IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
18852 append_space_for_newline (it, 0);
18853
18854 /* Extend the face to the end of the line. */
18855 extend_face_to_end_of_line (it);
18856
18857 /* Make sure we have the position. */
18858 if (used_before == 0)
18859 row->glyphs[TEXT_AREA]->charpos = CHARPOS (it->position);
18860
18861 /* Record the position of the newline, for use in
18862 find_row_edges. */
18863 it->eol_pos = it->current.pos;
18864
18865 /* Consume the line end. This skips over invisible lines. */
18866 set_iterator_to_next (it, 1);
18867 it->continuation_lines_width = 0;
18868 break;
18869 }
18870
18871 /* Proceed with next display element. Note that this skips
18872 over lines invisible because of selective display. */
18873 set_iterator_to_next (it, 1);
18874
18875 /* If we truncate lines, we are done when the last displayed
18876 glyphs reach past the right margin of the window. */
18877 if (it->line_wrap == TRUNCATE
18878 && (FRAME_WINDOW_P (it->f)
18879 ? (it->current_x >= it->last_visible_x)
18880 : (it->current_x > it->last_visible_x)))
18881 {
18882 /* Maybe add truncation glyphs. */
18883 if (!FRAME_WINDOW_P (it->f))
18884 {
18885 int i, n;
18886
18887 if (!row->reversed_p)
18888 {
18889 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
18890 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
18891 break;
18892 }
18893 else
18894 {
18895 for (i = 0; i < row->used[TEXT_AREA]; i++)
18896 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
18897 break;
18898 /* Remove any padding glyphs at the front of ROW, to
18899 make room for the truncation glyphs we will be
18900 adding below. The loop below always inserts at
18901 least one truncation glyph, so also remove the
18902 last glyph added to ROW. */
18903 unproduce_glyphs (it, i + 1);
18904 /* Adjust i for the loop below. */
18905 i = row->used[TEXT_AREA] - (i + 1);
18906 }
18907
18908 for (n = row->used[TEXT_AREA]; i < n; ++i)
18909 {
18910 row->used[TEXT_AREA] = i;
18911 produce_special_glyphs (it, IT_TRUNCATION);
18912 }
18913 }
18914 else if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
18915 {
18916 /* Don't truncate if we can overflow newline into fringe. */
18917 if (!get_next_display_element (it))
18918 {
18919 it->continuation_lines_width = 0;
18920 row->ends_at_zv_p = 1;
18921 row->exact_window_width_line_p = 1;
18922 break;
18923 }
18924 if (ITERATOR_AT_END_OF_LINE_P (it))
18925 {
18926 row->exact_window_width_line_p = 1;
18927 goto at_end_of_line;
18928 }
18929 }
18930
18931 row->truncated_on_right_p = 1;
18932 it->continuation_lines_width = 0;
18933 reseat_at_next_visible_line_start (it, 0);
18934 row->ends_at_zv_p = FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n';
18935 it->hpos = hpos_before;
18936 it->current_x = x_before;
18937 break;
18938 }
18939 }
18940
18941 if (wrap_data)
18942 bidi_unshelve_cache (wrap_data, 1);
18943
18944 /* If line is not empty and hscrolled, maybe insert truncation glyphs
18945 at the left window margin. */
18946 if (it->first_visible_x
18947 && IT_CHARPOS (*it) != CHARPOS (row->start.pos))
18948 {
18949 if (!FRAME_WINDOW_P (it->f))
18950 insert_left_trunc_glyphs (it);
18951 row->truncated_on_left_p = 1;
18952 }
18953
18954 /* Remember the position at which this line ends.
18955
18956 BIDI Note: any code that needs MATRIX_ROW_START/END_CHARPOS
18957 cannot be before the call to find_row_edges below, since that is
18958 where these positions are determined. */
18959 row->end = it->current;
18960 if (!it->bidi_p)
18961 {
18962 row->minpos = row->start.pos;
18963 row->maxpos = row->end.pos;
18964 }
18965 else
18966 {
18967 /* ROW->minpos and ROW->maxpos must be the smallest and
18968 `1 + the largest' buffer positions in ROW. But if ROW was
18969 bidi-reordered, these two positions can be anywhere in the
18970 row, so we must determine them now. */
18971 find_row_edges (it, row, min_pos, min_bpos, max_pos, max_bpos);
18972 }
18973
18974 /* If the start of this line is the overlay arrow-position, then
18975 mark this glyph row as the one containing the overlay arrow.
18976 This is clearly a mess with variable size fonts. It would be
18977 better to let it be displayed like cursors under X. */
18978 if ((row->displays_text_p || !overlay_arrow_seen)
18979 && (overlay_arrow_string = overlay_arrow_at_row (it, row),
18980 !NILP (overlay_arrow_string)))
18981 {
18982 /* Overlay arrow in window redisplay is a fringe bitmap. */
18983 if (STRINGP (overlay_arrow_string))
18984 {
18985 struct glyph_row *arrow_row
18986 = get_overlay_arrow_glyph_row (it->w, overlay_arrow_string);
18987 struct glyph *glyph = arrow_row->glyphs[TEXT_AREA];
18988 struct glyph *arrow_end = glyph + arrow_row->used[TEXT_AREA];
18989 struct glyph *p = row->glyphs[TEXT_AREA];
18990 struct glyph *p2, *end;
18991
18992 /* Copy the arrow glyphs. */
18993 while (glyph < arrow_end)
18994 *p++ = *glyph++;
18995
18996 /* Throw away padding glyphs. */
18997 p2 = p;
18998 end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
18999 while (p2 < end && CHAR_GLYPH_PADDING_P (*p2))
19000 ++p2;
19001 if (p2 > p)
19002 {
19003 while (p2 < end)
19004 *p++ = *p2++;
19005 row->used[TEXT_AREA] = p2 - row->glyphs[TEXT_AREA];
19006 }
19007 }
19008 else
19009 {
19010 xassert (INTEGERP (overlay_arrow_string));
19011 row->overlay_arrow_bitmap = XINT (overlay_arrow_string);
19012 }
19013 overlay_arrow_seen = 1;
19014 }
19015
19016 /* Compute pixel dimensions of this line. */
19017 compute_line_metrics (it);
19018
19019 /* Record whether this row ends inside an ellipsis. */
19020 row->ends_in_ellipsis_p
19021 = (it->method == GET_FROM_DISPLAY_VECTOR
19022 && it->ellipsis_p);
19023
19024 /* Save fringe bitmaps in this row. */
19025 row->left_user_fringe_bitmap = it->left_user_fringe_bitmap;
19026 row->left_user_fringe_face_id = it->left_user_fringe_face_id;
19027 row->right_user_fringe_bitmap = it->right_user_fringe_bitmap;
19028 row->right_user_fringe_face_id = it->right_user_fringe_face_id;
19029
19030 it->left_user_fringe_bitmap = 0;
19031 it->left_user_fringe_face_id = 0;
19032 it->right_user_fringe_bitmap = 0;
19033 it->right_user_fringe_face_id = 0;
19034
19035 /* Maybe set the cursor. */
19036 cvpos = it->w->cursor.vpos;
19037 if ((cvpos < 0
19038 /* In bidi-reordered rows, keep checking for proper cursor
19039 position even if one has been found already, because buffer
19040 positions in such rows change non-linearly with ROW->VPOS,
19041 when a line is continued. One exception: when we are at ZV,
19042 display cursor on the first suitable glyph row, since all
19043 the empty rows after that also have their position set to ZV. */
19044 /* FIXME: Revisit this when glyph ``spilling'' in continuation
19045 lines' rows is implemented for bidi-reordered rows. */
19046 || (it->bidi_p
19047 && !MATRIX_ROW (it->w->desired_matrix, cvpos)->ends_at_zv_p))
19048 && PT >= MATRIX_ROW_START_CHARPOS (row)
19049 && PT <= MATRIX_ROW_END_CHARPOS (row)
19050 && cursor_row_p (row))
19051 set_cursor_from_row (it->w, row, it->w->desired_matrix, 0, 0, 0, 0);
19052
19053 /* Highlight trailing whitespace. */
19054 if (!NILP (Vshow_trailing_whitespace))
19055 highlight_trailing_whitespace (it->f, it->glyph_row);
19056
19057 /* Prepare for the next line. This line starts horizontally at (X
19058 HPOS) = (0 0). Vertical positions are incremented. As a
19059 convenience for the caller, IT->glyph_row is set to the next
19060 row to be used. */
19061 it->current_x = it->hpos = 0;
19062 it->current_y += row->height;
19063 SET_TEXT_POS (it->eol_pos, 0, 0);
19064 ++it->vpos;
19065 ++it->glyph_row;
19066 /* The next row should by default use the same value of the
19067 reversed_p flag as this one. set_iterator_to_next decides when
19068 it's a new paragraph, and PRODUCE_GLYPHS recomputes the value of
19069 the flag accordingly. */
19070 if (it->glyph_row < MATRIX_BOTTOM_TEXT_ROW (it->w->desired_matrix, it->w))
19071 it->glyph_row->reversed_p = row->reversed_p;
19072 it->start = row->end;
19073 return row->displays_text_p;
19074
19075 #undef RECORD_MAX_MIN_POS
19076 }
19077
19078 DEFUN ("current-bidi-paragraph-direction", Fcurrent_bidi_paragraph_direction,
19079 Scurrent_bidi_paragraph_direction, 0, 1, 0,
19080 doc: /* Return paragraph direction at point in BUFFER.
19081 Value is either `left-to-right' or `right-to-left'.
19082 If BUFFER is omitted or nil, it defaults to the current buffer.
19083
19084 Paragraph direction determines how the text in the paragraph is displayed.
19085 In left-to-right paragraphs, text begins at the left margin of the window
19086 and the reading direction is generally left to right. In right-to-left
19087 paragraphs, text begins at the right margin and is read from right to left.
19088
19089 See also `bidi-paragraph-direction'. */)
19090 (Lisp_Object buffer)
19091 {
19092 struct buffer *buf = current_buffer;
19093 struct buffer *old = buf;
19094
19095 if (! NILP (buffer))
19096 {
19097 CHECK_BUFFER (buffer);
19098 buf = XBUFFER (buffer);
19099 }
19100
19101 if (NILP (BVAR (buf, bidi_display_reordering))
19102 || NILP (BVAR (buf, enable_multibyte_characters)))
19103 return Qleft_to_right;
19104 else if (!NILP (BVAR (buf, bidi_paragraph_direction)))
19105 return BVAR (buf, bidi_paragraph_direction);
19106 else
19107 {
19108 /* Determine the direction from buffer text. We could try to
19109 use current_matrix if it is up to date, but this seems fast
19110 enough as it is. */
19111 struct bidi_it itb;
19112 EMACS_INT pos = BUF_PT (buf);
19113 EMACS_INT bytepos = BUF_PT_BYTE (buf);
19114 int c;
19115
19116 set_buffer_temp (buf);
19117 /* bidi_paragraph_init finds the base direction of the paragraph
19118 by searching forward from paragraph start. We need the base
19119 direction of the current or _previous_ paragraph, so we need
19120 to make sure we are within that paragraph. To that end, find
19121 the previous non-empty line. */
19122 if (pos >= ZV && pos > BEGV)
19123 {
19124 pos--;
19125 bytepos = CHAR_TO_BYTE (pos);
19126 }
19127 while ((c = FETCH_BYTE (bytepos)) == '\n'
19128 || c == ' ' || c == '\t' || c == '\f')
19129 {
19130 if (bytepos <= BEGV_BYTE)
19131 break;
19132 bytepos--;
19133 pos--;
19134 }
19135 while (!CHAR_HEAD_P (FETCH_BYTE (bytepos)))
19136 bytepos--;
19137 itb.charpos = pos;
19138 itb.bytepos = bytepos;
19139 itb.nchars = -1;
19140 itb.string.s = NULL;
19141 itb.string.lstring = Qnil;
19142 itb.frame_window_p = FRAME_WINDOW_P (SELECTED_FRAME ()); /* guesswork */
19143 itb.first_elt = 1;
19144 itb.separator_limit = -1;
19145 itb.paragraph_dir = NEUTRAL_DIR;
19146
19147 bidi_paragraph_init (NEUTRAL_DIR, &itb, 1);
19148 set_buffer_temp (old);
19149 switch (itb.paragraph_dir)
19150 {
19151 case L2R:
19152 return Qleft_to_right;
19153 break;
19154 case R2L:
19155 return Qright_to_left;
19156 break;
19157 default:
19158 abort ();
19159 }
19160 }
19161 }
19162
19163
19164 \f
19165 /***********************************************************************
19166 Menu Bar
19167 ***********************************************************************/
19168
19169 /* Redisplay the menu bar in the frame for window W.
19170
19171 The menu bar of X frames that don't have X toolkit support is
19172 displayed in a special window W->frame->menu_bar_window.
19173
19174 The menu bar of terminal frames is treated specially as far as
19175 glyph matrices are concerned. Menu bar lines are not part of
19176 windows, so the update is done directly on the frame matrix rows
19177 for the menu bar. */
19178
19179 static void
19180 display_menu_bar (struct window *w)
19181 {
19182 struct frame *f = XFRAME (WINDOW_FRAME (w));
19183 struct it it;
19184 Lisp_Object items;
19185 int i;
19186
19187 /* Don't do all this for graphical frames. */
19188 #ifdef HAVE_NTGUI
19189 if (FRAME_W32_P (f))
19190 return;
19191 #endif
19192 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
19193 if (FRAME_X_P (f))
19194 return;
19195 #endif
19196
19197 #ifdef HAVE_NS
19198 if (FRAME_NS_P (f))
19199 return;
19200 #endif /* HAVE_NS */
19201
19202 #ifdef USE_X_TOOLKIT
19203 xassert (!FRAME_WINDOW_P (f));
19204 init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MENU_FACE_ID);
19205 it.first_visible_x = 0;
19206 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
19207 #else /* not USE_X_TOOLKIT */
19208 if (FRAME_WINDOW_P (f))
19209 {
19210 /* Menu bar lines are displayed in the desired matrix of the
19211 dummy window menu_bar_window. */
19212 struct window *menu_w;
19213 xassert (WINDOWP (f->menu_bar_window));
19214 menu_w = XWINDOW (f->menu_bar_window);
19215 init_iterator (&it, menu_w, -1, -1, menu_w->desired_matrix->rows,
19216 MENU_FACE_ID);
19217 it.first_visible_x = 0;
19218 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
19219 }
19220 else
19221 {
19222 /* This is a TTY frame, i.e. character hpos/vpos are used as
19223 pixel x/y. */
19224 init_iterator (&it, w, -1, -1, f->desired_matrix->rows,
19225 MENU_FACE_ID);
19226 it.first_visible_x = 0;
19227 it.last_visible_x = FRAME_COLS (f);
19228 }
19229 #endif /* not USE_X_TOOLKIT */
19230
19231 /* FIXME: This should be controlled by a user option. See the
19232 comments in redisplay_tool_bar and display_mode_line about
19233 this. */
19234 it.paragraph_embedding = L2R;
19235
19236 if (! mode_line_inverse_video)
19237 /* Force the menu-bar to be displayed in the default face. */
19238 it.base_face_id = it.face_id = DEFAULT_FACE_ID;
19239
19240 /* Clear all rows of the menu bar. */
19241 for (i = 0; i < FRAME_MENU_BAR_LINES (f); ++i)
19242 {
19243 struct glyph_row *row = it.glyph_row + i;
19244 clear_glyph_row (row);
19245 row->enabled_p = 1;
19246 row->full_width_p = 1;
19247 }
19248
19249 /* Display all items of the menu bar. */
19250 items = FRAME_MENU_BAR_ITEMS (it.f);
19251 for (i = 0; i < ASIZE (items); i += 4)
19252 {
19253 Lisp_Object string;
19254
19255 /* Stop at nil string. */
19256 string = AREF (items, i + 1);
19257 if (NILP (string))
19258 break;
19259
19260 /* Remember where item was displayed. */
19261 ASET (items, i + 3, make_number (it.hpos));
19262
19263 /* Display the item, pad with one space. */
19264 if (it.current_x < it.last_visible_x)
19265 display_string (NULL, string, Qnil, 0, 0, &it,
19266 SCHARS (string) + 1, 0, 0, -1);
19267 }
19268
19269 /* Fill out the line with spaces. */
19270 if (it.current_x < it.last_visible_x)
19271 display_string ("", Qnil, Qnil, 0, 0, &it, -1, 0, 0, -1);
19272
19273 /* Compute the total height of the lines. */
19274 compute_line_metrics (&it);
19275 }
19276
19277
19278 \f
19279 /***********************************************************************
19280 Mode Line
19281 ***********************************************************************/
19282
19283 /* Redisplay mode lines in the window tree whose root is WINDOW. If
19284 FORCE is non-zero, redisplay mode lines unconditionally.
19285 Otherwise, redisplay only mode lines that are garbaged. Value is
19286 the number of windows whose mode lines were redisplayed. */
19287
19288 static int
19289 redisplay_mode_lines (Lisp_Object window, int force)
19290 {
19291 int nwindows = 0;
19292
19293 while (!NILP (window))
19294 {
19295 struct window *w = XWINDOW (window);
19296
19297 if (WINDOWP (w->hchild))
19298 nwindows += redisplay_mode_lines (w->hchild, force);
19299 else if (WINDOWP (w->vchild))
19300 nwindows += redisplay_mode_lines (w->vchild, force);
19301 else if (force
19302 || FRAME_GARBAGED_P (XFRAME (w->frame))
19303 || !MATRIX_MODE_LINE_ROW (w->current_matrix)->enabled_p)
19304 {
19305 struct text_pos lpoint;
19306 struct buffer *old = current_buffer;
19307
19308 /* Set the window's buffer for the mode line display. */
19309 SET_TEXT_POS (lpoint, PT, PT_BYTE);
19310 set_buffer_internal_1 (XBUFFER (w->buffer));
19311
19312 /* Point refers normally to the selected window. For any
19313 other window, set up appropriate value. */
19314 if (!EQ (window, selected_window))
19315 {
19316 struct text_pos pt;
19317
19318 SET_TEXT_POS_FROM_MARKER (pt, w->pointm);
19319 if (CHARPOS (pt) < BEGV)
19320 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
19321 else if (CHARPOS (pt) > (ZV - 1))
19322 TEMP_SET_PT_BOTH (ZV, ZV_BYTE);
19323 else
19324 TEMP_SET_PT_BOTH (CHARPOS (pt), BYTEPOS (pt));
19325 }
19326
19327 /* Display mode lines. */
19328 clear_glyph_matrix (w->desired_matrix);
19329 if (display_mode_lines (w))
19330 {
19331 ++nwindows;
19332 w->must_be_updated_p = 1;
19333 }
19334
19335 /* Restore old settings. */
19336 set_buffer_internal_1 (old);
19337 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
19338 }
19339
19340 window = w->next;
19341 }
19342
19343 return nwindows;
19344 }
19345
19346
19347 /* Display the mode and/or header line of window W. Value is the
19348 sum number of mode lines and header lines displayed. */
19349
19350 static int
19351 display_mode_lines (struct window *w)
19352 {
19353 Lisp_Object old_selected_window, old_selected_frame;
19354 int n = 0;
19355
19356 old_selected_frame = selected_frame;
19357 selected_frame = w->frame;
19358 old_selected_window = selected_window;
19359 XSETWINDOW (selected_window, w);
19360
19361 /* These will be set while the mode line specs are processed. */
19362 line_number_displayed = 0;
19363 w->column_number_displayed = Qnil;
19364
19365 if (WINDOW_WANTS_MODELINE_P (w))
19366 {
19367 struct window *sel_w = XWINDOW (old_selected_window);
19368
19369 /* Select mode line face based on the real selected window. */
19370 display_mode_line (w, CURRENT_MODE_LINE_FACE_ID_3 (sel_w, sel_w, w),
19371 BVAR (current_buffer, mode_line_format));
19372 ++n;
19373 }
19374
19375 if (WINDOW_WANTS_HEADER_LINE_P (w))
19376 {
19377 display_mode_line (w, HEADER_LINE_FACE_ID,
19378 BVAR (current_buffer, header_line_format));
19379 ++n;
19380 }
19381
19382 selected_frame = old_selected_frame;
19383 selected_window = old_selected_window;
19384 return n;
19385 }
19386
19387
19388 /* Display mode or header line of window W. FACE_ID specifies which
19389 line to display; it is either MODE_LINE_FACE_ID or
19390 HEADER_LINE_FACE_ID. FORMAT is the mode/header line format to
19391 display. Value is the pixel height of the mode/header line
19392 displayed. */
19393
19394 static int
19395 display_mode_line (struct window *w, enum face_id face_id, Lisp_Object format)
19396 {
19397 struct it it;
19398 struct face *face;
19399 int count = SPECPDL_INDEX ();
19400
19401 init_iterator (&it, w, -1, -1, NULL, face_id);
19402 /* Don't extend on a previously drawn mode-line.
19403 This may happen if called from pos_visible_p. */
19404 it.glyph_row->enabled_p = 0;
19405 prepare_desired_row (it.glyph_row);
19406
19407 it.glyph_row->mode_line_p = 1;
19408
19409 if (! mode_line_inverse_video)
19410 /* Force the mode-line to be displayed in the default face. */
19411 it.base_face_id = it.face_id = DEFAULT_FACE_ID;
19412
19413 /* FIXME: This should be controlled by a user option. But
19414 supporting such an option is not trivial, since the mode line is
19415 made up of many separate strings. */
19416 it.paragraph_embedding = L2R;
19417
19418 record_unwind_protect (unwind_format_mode_line,
19419 format_mode_line_unwind_data (NULL, Qnil, 0));
19420
19421 mode_line_target = MODE_LINE_DISPLAY;
19422
19423 /* Temporarily make frame's keyboard the current kboard so that
19424 kboard-local variables in the mode_line_format will get the right
19425 values. */
19426 push_kboard (FRAME_KBOARD (it.f));
19427 record_unwind_save_match_data ();
19428 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
19429 pop_kboard ();
19430
19431 unbind_to (count, Qnil);
19432
19433 /* Fill up with spaces. */
19434 display_string (" ", Qnil, Qnil, 0, 0, &it, 10000, -1, -1, 0);
19435
19436 compute_line_metrics (&it);
19437 it.glyph_row->full_width_p = 1;
19438 it.glyph_row->continued_p = 0;
19439 it.glyph_row->truncated_on_left_p = 0;
19440 it.glyph_row->truncated_on_right_p = 0;
19441
19442 /* Make a 3D mode-line have a shadow at its right end. */
19443 face = FACE_FROM_ID (it.f, face_id);
19444 extend_face_to_end_of_line (&it);
19445 if (face->box != FACE_NO_BOX)
19446 {
19447 struct glyph *last = (it.glyph_row->glyphs[TEXT_AREA]
19448 + it.glyph_row->used[TEXT_AREA] - 1);
19449 last->right_box_line_p = 1;
19450 }
19451
19452 return it.glyph_row->height;
19453 }
19454
19455 /* Move element ELT in LIST to the front of LIST.
19456 Return the updated list. */
19457
19458 static Lisp_Object
19459 move_elt_to_front (Lisp_Object elt, Lisp_Object list)
19460 {
19461 register Lisp_Object tail, prev;
19462 register Lisp_Object tem;
19463
19464 tail = list;
19465 prev = Qnil;
19466 while (CONSP (tail))
19467 {
19468 tem = XCAR (tail);
19469
19470 if (EQ (elt, tem))
19471 {
19472 /* Splice out the link TAIL. */
19473 if (NILP (prev))
19474 list = XCDR (tail);
19475 else
19476 Fsetcdr (prev, XCDR (tail));
19477
19478 /* Now make it the first. */
19479 Fsetcdr (tail, list);
19480 return tail;
19481 }
19482 else
19483 prev = tail;
19484 tail = XCDR (tail);
19485 QUIT;
19486 }
19487
19488 /* Not found--return unchanged LIST. */
19489 return list;
19490 }
19491
19492 /* Contribute ELT to the mode line for window IT->w. How it
19493 translates into text depends on its data type.
19494
19495 IT describes the display environment in which we display, as usual.
19496
19497 DEPTH is the depth in recursion. It is used to prevent
19498 infinite recursion here.
19499
19500 FIELD_WIDTH is the number of characters the display of ELT should
19501 occupy in the mode line, and PRECISION is the maximum number of
19502 characters to display from ELT's representation. See
19503 display_string for details.
19504
19505 Returns the hpos of the end of the text generated by ELT.
19506
19507 PROPS is a property list to add to any string we encounter.
19508
19509 If RISKY is nonzero, remove (disregard) any properties in any string
19510 we encounter, and ignore :eval and :propertize.
19511
19512 The global variable `mode_line_target' determines whether the
19513 output is passed to `store_mode_line_noprop',
19514 `store_mode_line_string', or `display_string'. */
19515
19516 static int
19517 display_mode_element (struct it *it, int depth, int field_width, int precision,
19518 Lisp_Object elt, Lisp_Object props, int risky)
19519 {
19520 int n = 0, field, prec;
19521 int literal = 0;
19522
19523 tail_recurse:
19524 if (depth > 100)
19525 elt = build_string ("*too-deep*");
19526
19527 depth++;
19528
19529 switch (SWITCH_ENUM_CAST (XTYPE (elt)))
19530 {
19531 case Lisp_String:
19532 {
19533 /* A string: output it and check for %-constructs within it. */
19534 unsigned char c;
19535 EMACS_INT offset = 0;
19536
19537 if (SCHARS (elt) > 0
19538 && (!NILP (props) || risky))
19539 {
19540 Lisp_Object oprops, aelt;
19541 oprops = Ftext_properties_at (make_number (0), elt);
19542
19543 /* If the starting string's properties are not what
19544 we want, translate the string. Also, if the string
19545 is risky, do that anyway. */
19546
19547 if (NILP (Fequal (props, oprops)) || risky)
19548 {
19549 /* If the starting string has properties,
19550 merge the specified ones onto the existing ones. */
19551 if (! NILP (oprops) && !risky)
19552 {
19553 Lisp_Object tem;
19554
19555 oprops = Fcopy_sequence (oprops);
19556 tem = props;
19557 while (CONSP (tem))
19558 {
19559 oprops = Fplist_put (oprops, XCAR (tem),
19560 XCAR (XCDR (tem)));
19561 tem = XCDR (XCDR (tem));
19562 }
19563 props = oprops;
19564 }
19565
19566 aelt = Fassoc (elt, mode_line_proptrans_alist);
19567 if (! NILP (aelt) && !NILP (Fequal (props, XCDR (aelt))))
19568 {
19569 /* AELT is what we want. Move it to the front
19570 without consing. */
19571 elt = XCAR (aelt);
19572 mode_line_proptrans_alist
19573 = move_elt_to_front (aelt, mode_line_proptrans_alist);
19574 }
19575 else
19576 {
19577 Lisp_Object tem;
19578
19579 /* If AELT has the wrong props, it is useless.
19580 so get rid of it. */
19581 if (! NILP (aelt))
19582 mode_line_proptrans_alist
19583 = Fdelq (aelt, mode_line_proptrans_alist);
19584
19585 elt = Fcopy_sequence (elt);
19586 Fset_text_properties (make_number (0), Flength (elt),
19587 props, elt);
19588 /* Add this item to mode_line_proptrans_alist. */
19589 mode_line_proptrans_alist
19590 = Fcons (Fcons (elt, props),
19591 mode_line_proptrans_alist);
19592 /* Truncate mode_line_proptrans_alist
19593 to at most 50 elements. */
19594 tem = Fnthcdr (make_number (50),
19595 mode_line_proptrans_alist);
19596 if (! NILP (tem))
19597 XSETCDR (tem, Qnil);
19598 }
19599 }
19600 }
19601
19602 offset = 0;
19603
19604 if (literal)
19605 {
19606 prec = precision - n;
19607 switch (mode_line_target)
19608 {
19609 case MODE_LINE_NOPROP:
19610 case MODE_LINE_TITLE:
19611 n += store_mode_line_noprop (SSDATA (elt), -1, prec);
19612 break;
19613 case MODE_LINE_STRING:
19614 n += store_mode_line_string (NULL, elt, 1, 0, prec, Qnil);
19615 break;
19616 case MODE_LINE_DISPLAY:
19617 n += display_string (NULL, elt, Qnil, 0, 0, it,
19618 0, prec, 0, STRING_MULTIBYTE (elt));
19619 break;
19620 }
19621
19622 break;
19623 }
19624
19625 /* Handle the non-literal case. */
19626
19627 while ((precision <= 0 || n < precision)
19628 && SREF (elt, offset) != 0
19629 && (mode_line_target != MODE_LINE_DISPLAY
19630 || it->current_x < it->last_visible_x))
19631 {
19632 EMACS_INT last_offset = offset;
19633
19634 /* Advance to end of string or next format specifier. */
19635 while ((c = SREF (elt, offset++)) != '\0' && c != '%')
19636 ;
19637
19638 if (offset - 1 != last_offset)
19639 {
19640 EMACS_INT nchars, nbytes;
19641
19642 /* Output to end of string or up to '%'. Field width
19643 is length of string. Don't output more than
19644 PRECISION allows us. */
19645 offset--;
19646
19647 prec = c_string_width (SDATA (elt) + last_offset,
19648 offset - last_offset, precision - n,
19649 &nchars, &nbytes);
19650
19651 switch (mode_line_target)
19652 {
19653 case MODE_LINE_NOPROP:
19654 case MODE_LINE_TITLE:
19655 n += store_mode_line_noprop (SSDATA (elt) + last_offset, 0, prec);
19656 break;
19657 case MODE_LINE_STRING:
19658 {
19659 EMACS_INT bytepos = last_offset;
19660 EMACS_INT charpos = string_byte_to_char (elt, bytepos);
19661 EMACS_INT endpos = (precision <= 0
19662 ? string_byte_to_char (elt, offset)
19663 : charpos + nchars);
19664
19665 n += store_mode_line_string (NULL,
19666 Fsubstring (elt, make_number (charpos),
19667 make_number (endpos)),
19668 0, 0, 0, Qnil);
19669 }
19670 break;
19671 case MODE_LINE_DISPLAY:
19672 {
19673 EMACS_INT bytepos = last_offset;
19674 EMACS_INT charpos = string_byte_to_char (elt, bytepos);
19675
19676 if (precision <= 0)
19677 nchars = string_byte_to_char (elt, offset) - charpos;
19678 n += display_string (NULL, elt, Qnil, 0, charpos,
19679 it, 0, nchars, 0,
19680 STRING_MULTIBYTE (elt));
19681 }
19682 break;
19683 }
19684 }
19685 else /* c == '%' */
19686 {
19687 EMACS_INT percent_position = offset;
19688
19689 /* Get the specified minimum width. Zero means
19690 don't pad. */
19691 field = 0;
19692 while ((c = SREF (elt, offset++)) >= '0' && c <= '9')
19693 field = field * 10 + c - '0';
19694
19695 /* Don't pad beyond the total padding allowed. */
19696 if (field_width - n > 0 && field > field_width - n)
19697 field = field_width - n;
19698
19699 /* Note that either PRECISION <= 0 or N < PRECISION. */
19700 prec = precision - n;
19701
19702 if (c == 'M')
19703 n += display_mode_element (it, depth, field, prec,
19704 Vglobal_mode_string, props,
19705 risky);
19706 else if (c != 0)
19707 {
19708 int multibyte;
19709 EMACS_INT bytepos, charpos;
19710 const char *spec;
19711 Lisp_Object string;
19712
19713 bytepos = percent_position;
19714 charpos = (STRING_MULTIBYTE (elt)
19715 ? string_byte_to_char (elt, bytepos)
19716 : bytepos);
19717 spec = decode_mode_spec (it->w, c, field, &string);
19718 multibyte = STRINGP (string) && STRING_MULTIBYTE (string);
19719
19720 switch (mode_line_target)
19721 {
19722 case MODE_LINE_NOPROP:
19723 case MODE_LINE_TITLE:
19724 n += store_mode_line_noprop (spec, field, prec);
19725 break;
19726 case MODE_LINE_STRING:
19727 {
19728 Lisp_Object tem = build_string (spec);
19729 props = Ftext_properties_at (make_number (charpos), elt);
19730 /* Should only keep face property in props */
19731 n += store_mode_line_string (NULL, tem, 0, field, prec, props);
19732 }
19733 break;
19734 case MODE_LINE_DISPLAY:
19735 {
19736 int nglyphs_before, nwritten;
19737
19738 nglyphs_before = it->glyph_row->used[TEXT_AREA];
19739 nwritten = display_string (spec, string, elt,
19740 charpos, 0, it,
19741 field, prec, 0,
19742 multibyte);
19743
19744 /* Assign to the glyphs written above the
19745 string where the `%x' came from, position
19746 of the `%'. */
19747 if (nwritten > 0)
19748 {
19749 struct glyph *glyph
19750 = (it->glyph_row->glyphs[TEXT_AREA]
19751 + nglyphs_before);
19752 int i;
19753
19754 for (i = 0; i < nwritten; ++i)
19755 {
19756 glyph[i].object = elt;
19757 glyph[i].charpos = charpos;
19758 }
19759
19760 n += nwritten;
19761 }
19762 }
19763 break;
19764 }
19765 }
19766 else /* c == 0 */
19767 break;
19768 }
19769 }
19770 }
19771 break;
19772
19773 case Lisp_Symbol:
19774 /* A symbol: process the value of the symbol recursively
19775 as if it appeared here directly. Avoid error if symbol void.
19776 Special case: if value of symbol is a string, output the string
19777 literally. */
19778 {
19779 register Lisp_Object tem;
19780
19781 /* If the variable is not marked as risky to set
19782 then its contents are risky to use. */
19783 if (NILP (Fget (elt, Qrisky_local_variable)))
19784 risky = 1;
19785
19786 tem = Fboundp (elt);
19787 if (!NILP (tem))
19788 {
19789 tem = Fsymbol_value (elt);
19790 /* If value is a string, output that string literally:
19791 don't check for % within it. */
19792 if (STRINGP (tem))
19793 literal = 1;
19794
19795 if (!EQ (tem, elt))
19796 {
19797 /* Give up right away for nil or t. */
19798 elt = tem;
19799 goto tail_recurse;
19800 }
19801 }
19802 }
19803 break;
19804
19805 case Lisp_Cons:
19806 {
19807 register Lisp_Object car, tem;
19808
19809 /* A cons cell: five distinct cases.
19810 If first element is :eval or :propertize, do something special.
19811 If first element is a string or a cons, process all the elements
19812 and effectively concatenate them.
19813 If first element is a negative number, truncate displaying cdr to
19814 at most that many characters. If positive, pad (with spaces)
19815 to at least that many characters.
19816 If first element is a symbol, process the cadr or caddr recursively
19817 according to whether the symbol's value is non-nil or nil. */
19818 car = XCAR (elt);
19819 if (EQ (car, QCeval))
19820 {
19821 /* An element of the form (:eval FORM) means evaluate FORM
19822 and use the result as mode line elements. */
19823
19824 if (risky)
19825 break;
19826
19827 if (CONSP (XCDR (elt)))
19828 {
19829 Lisp_Object spec;
19830 spec = safe_eval (XCAR (XCDR (elt)));
19831 n += display_mode_element (it, depth, field_width - n,
19832 precision - n, spec, props,
19833 risky);
19834 }
19835 }
19836 else if (EQ (car, QCpropertize))
19837 {
19838 /* An element of the form (:propertize ELT PROPS...)
19839 means display ELT but applying properties PROPS. */
19840
19841 if (risky)
19842 break;
19843
19844 if (CONSP (XCDR (elt)))
19845 n += display_mode_element (it, depth, field_width - n,
19846 precision - n, XCAR (XCDR (elt)),
19847 XCDR (XCDR (elt)), risky);
19848 }
19849 else if (SYMBOLP (car))
19850 {
19851 tem = Fboundp (car);
19852 elt = XCDR (elt);
19853 if (!CONSP (elt))
19854 goto invalid;
19855 /* elt is now the cdr, and we know it is a cons cell.
19856 Use its car if CAR has a non-nil value. */
19857 if (!NILP (tem))
19858 {
19859 tem = Fsymbol_value (car);
19860 if (!NILP (tem))
19861 {
19862 elt = XCAR (elt);
19863 goto tail_recurse;
19864 }
19865 }
19866 /* Symbol's value is nil (or symbol is unbound)
19867 Get the cddr of the original list
19868 and if possible find the caddr and use that. */
19869 elt = XCDR (elt);
19870 if (NILP (elt))
19871 break;
19872 else if (!CONSP (elt))
19873 goto invalid;
19874 elt = XCAR (elt);
19875 goto tail_recurse;
19876 }
19877 else if (INTEGERP (car))
19878 {
19879 register int lim = XINT (car);
19880 elt = XCDR (elt);
19881 if (lim < 0)
19882 {
19883 /* Negative int means reduce maximum width. */
19884 if (precision <= 0)
19885 precision = -lim;
19886 else
19887 precision = min (precision, -lim);
19888 }
19889 else if (lim > 0)
19890 {
19891 /* Padding specified. Don't let it be more than
19892 current maximum. */
19893 if (precision > 0)
19894 lim = min (precision, lim);
19895
19896 /* If that's more padding than already wanted, queue it.
19897 But don't reduce padding already specified even if
19898 that is beyond the current truncation point. */
19899 field_width = max (lim, field_width);
19900 }
19901 goto tail_recurse;
19902 }
19903 else if (STRINGP (car) || CONSP (car))
19904 {
19905 Lisp_Object halftail = elt;
19906 int len = 0;
19907
19908 while (CONSP (elt)
19909 && (precision <= 0 || n < precision))
19910 {
19911 n += display_mode_element (it, depth,
19912 /* Do padding only after the last
19913 element in the list. */
19914 (! CONSP (XCDR (elt))
19915 ? field_width - n
19916 : 0),
19917 precision - n, XCAR (elt),
19918 props, risky);
19919 elt = XCDR (elt);
19920 len++;
19921 if ((len & 1) == 0)
19922 halftail = XCDR (halftail);
19923 /* Check for cycle. */
19924 if (EQ (halftail, elt))
19925 break;
19926 }
19927 }
19928 }
19929 break;
19930
19931 default:
19932 invalid:
19933 elt = build_string ("*invalid*");
19934 goto tail_recurse;
19935 }
19936
19937 /* Pad to FIELD_WIDTH. */
19938 if (field_width > 0 && n < field_width)
19939 {
19940 switch (mode_line_target)
19941 {
19942 case MODE_LINE_NOPROP:
19943 case MODE_LINE_TITLE:
19944 n += store_mode_line_noprop ("", field_width - n, 0);
19945 break;
19946 case MODE_LINE_STRING:
19947 n += store_mode_line_string ("", Qnil, 0, field_width - n, 0, Qnil);
19948 break;
19949 case MODE_LINE_DISPLAY:
19950 n += display_string ("", Qnil, Qnil, 0, 0, it, field_width - n,
19951 0, 0, 0);
19952 break;
19953 }
19954 }
19955
19956 return n;
19957 }
19958
19959 /* Store a mode-line string element in mode_line_string_list.
19960
19961 If STRING is non-null, display that C string. Otherwise, the Lisp
19962 string LISP_STRING is displayed.
19963
19964 FIELD_WIDTH is the minimum number of output glyphs to produce.
19965 If STRING has fewer characters than FIELD_WIDTH, pad to the right
19966 with spaces. FIELD_WIDTH <= 0 means don't pad.
19967
19968 PRECISION is the maximum number of characters to output from
19969 STRING. PRECISION <= 0 means don't truncate the string.
19970
19971 If COPY_STRING is non-zero, make a copy of LISP_STRING before adding
19972 properties to the string.
19973
19974 PROPS are the properties to add to the string.
19975 The mode_line_string_face face property is always added to the string.
19976 */
19977
19978 static int
19979 store_mode_line_string (const char *string, Lisp_Object lisp_string, int copy_string,
19980 int field_width, int precision, Lisp_Object props)
19981 {
19982 EMACS_INT len;
19983 int n = 0;
19984
19985 if (string != NULL)
19986 {
19987 len = strlen (string);
19988 if (precision > 0 && len > precision)
19989 len = precision;
19990 lisp_string = make_string (string, len);
19991 if (NILP (props))
19992 props = mode_line_string_face_prop;
19993 else if (!NILP (mode_line_string_face))
19994 {
19995 Lisp_Object face = Fplist_get (props, Qface);
19996 props = Fcopy_sequence (props);
19997 if (NILP (face))
19998 face = mode_line_string_face;
19999 else
20000 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
20001 props = Fplist_put (props, Qface, face);
20002 }
20003 Fadd_text_properties (make_number (0), make_number (len),
20004 props, lisp_string);
20005 }
20006 else
20007 {
20008 len = XFASTINT (Flength (lisp_string));
20009 if (precision > 0 && len > precision)
20010 {
20011 len = precision;
20012 lisp_string = Fsubstring (lisp_string, make_number (0), make_number (len));
20013 precision = -1;
20014 }
20015 if (!NILP (mode_line_string_face))
20016 {
20017 Lisp_Object face;
20018 if (NILP (props))
20019 props = Ftext_properties_at (make_number (0), lisp_string);
20020 face = Fplist_get (props, Qface);
20021 if (NILP (face))
20022 face = mode_line_string_face;
20023 else
20024 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
20025 props = Fcons (Qface, Fcons (face, Qnil));
20026 if (copy_string)
20027 lisp_string = Fcopy_sequence (lisp_string);
20028 }
20029 if (!NILP (props))
20030 Fadd_text_properties (make_number (0), make_number (len),
20031 props, lisp_string);
20032 }
20033
20034 if (len > 0)
20035 {
20036 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
20037 n += len;
20038 }
20039
20040 if (field_width > len)
20041 {
20042 field_width -= len;
20043 lisp_string = Fmake_string (make_number (field_width), make_number (' '));
20044 if (!NILP (props))
20045 Fadd_text_properties (make_number (0), make_number (field_width),
20046 props, lisp_string);
20047 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
20048 n += field_width;
20049 }
20050
20051 return n;
20052 }
20053
20054
20055 DEFUN ("format-mode-line", Fformat_mode_line, Sformat_mode_line,
20056 1, 4, 0,
20057 doc: /* Format a string out of a mode line format specification.
20058 First arg FORMAT specifies the mode line format (see `mode-line-format'
20059 for details) to use.
20060
20061 By default, the format is evaluated for the currently selected window.
20062
20063 Optional second arg FACE specifies the face property to put on all
20064 characters for which no face is specified. The value nil means the
20065 default face. The value t means whatever face the window's mode line
20066 currently uses (either `mode-line' or `mode-line-inactive',
20067 depending on whether the window is the selected window or not).
20068 An integer value means the value string has no text
20069 properties.
20070
20071 Optional third and fourth args WINDOW and BUFFER specify the window
20072 and buffer to use as the context for the formatting (defaults
20073 are the selected window and the WINDOW's buffer). */)
20074 (Lisp_Object format, Lisp_Object face,
20075 Lisp_Object window, Lisp_Object buffer)
20076 {
20077 struct it it;
20078 int len;
20079 struct window *w;
20080 struct buffer *old_buffer = NULL;
20081 int face_id;
20082 int no_props = INTEGERP (face);
20083 int count = SPECPDL_INDEX ();
20084 Lisp_Object str;
20085 int string_start = 0;
20086
20087 if (NILP (window))
20088 window = selected_window;
20089 CHECK_WINDOW (window);
20090 w = XWINDOW (window);
20091
20092 if (NILP (buffer))
20093 buffer = w->buffer;
20094 CHECK_BUFFER (buffer);
20095
20096 /* Make formatting the modeline a non-op when noninteractive, otherwise
20097 there will be problems later caused by a partially initialized frame. */
20098 if (NILP (format) || noninteractive)
20099 return empty_unibyte_string;
20100
20101 if (no_props)
20102 face = Qnil;
20103
20104 face_id = (NILP (face) || EQ (face, Qdefault)) ? DEFAULT_FACE_ID
20105 : EQ (face, Qt) ? (EQ (window, selected_window)
20106 ? MODE_LINE_FACE_ID : MODE_LINE_INACTIVE_FACE_ID)
20107 : EQ (face, Qmode_line) ? MODE_LINE_FACE_ID
20108 : EQ (face, Qmode_line_inactive) ? MODE_LINE_INACTIVE_FACE_ID
20109 : EQ (face, Qheader_line) ? HEADER_LINE_FACE_ID
20110 : EQ (face, Qtool_bar) ? TOOL_BAR_FACE_ID
20111 : DEFAULT_FACE_ID;
20112
20113 if (XBUFFER (buffer) != current_buffer)
20114 old_buffer = current_buffer;
20115
20116 /* Save things including mode_line_proptrans_alist,
20117 and set that to nil so that we don't alter the outer value. */
20118 record_unwind_protect (unwind_format_mode_line,
20119 format_mode_line_unwind_data
20120 (old_buffer, selected_window, 1));
20121 mode_line_proptrans_alist = Qnil;
20122
20123 Fselect_window (window, Qt);
20124 if (old_buffer)
20125 set_buffer_internal_1 (XBUFFER (buffer));
20126
20127 init_iterator (&it, w, -1, -1, NULL, face_id);
20128
20129 if (no_props)
20130 {
20131 mode_line_target = MODE_LINE_NOPROP;
20132 mode_line_string_face_prop = Qnil;
20133 mode_line_string_list = Qnil;
20134 string_start = MODE_LINE_NOPROP_LEN (0);
20135 }
20136 else
20137 {
20138 mode_line_target = MODE_LINE_STRING;
20139 mode_line_string_list = Qnil;
20140 mode_line_string_face = face;
20141 mode_line_string_face_prop
20142 = (NILP (face) ? Qnil : Fcons (Qface, Fcons (face, Qnil)));
20143 }
20144
20145 push_kboard (FRAME_KBOARD (it.f));
20146 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
20147 pop_kboard ();
20148
20149 if (no_props)
20150 {
20151 len = MODE_LINE_NOPROP_LEN (string_start);
20152 str = make_string (mode_line_noprop_buf + string_start, len);
20153 }
20154 else
20155 {
20156 mode_line_string_list = Fnreverse (mode_line_string_list);
20157 str = Fmapconcat (intern ("identity"), mode_line_string_list,
20158 empty_unibyte_string);
20159 }
20160
20161 unbind_to (count, Qnil);
20162 return str;
20163 }
20164
20165 /* Write a null-terminated, right justified decimal representation of
20166 the positive integer D to BUF using a minimal field width WIDTH. */
20167
20168 static void
20169 pint2str (register char *buf, register int width, register EMACS_INT d)
20170 {
20171 register char *p = buf;
20172
20173 if (d <= 0)
20174 *p++ = '0';
20175 else
20176 {
20177 while (d > 0)
20178 {
20179 *p++ = d % 10 + '0';
20180 d /= 10;
20181 }
20182 }
20183
20184 for (width -= (int) (p - buf); width > 0; --width)
20185 *p++ = ' ';
20186 *p-- = '\0';
20187 while (p > buf)
20188 {
20189 d = *buf;
20190 *buf++ = *p;
20191 *p-- = d;
20192 }
20193 }
20194
20195 /* Write a null-terminated, right justified decimal and "human
20196 readable" representation of the nonnegative integer D to BUF using
20197 a minimal field width WIDTH. D should be smaller than 999.5e24. */
20198
20199 static const char power_letter[] =
20200 {
20201 0, /* no letter */
20202 'k', /* kilo */
20203 'M', /* mega */
20204 'G', /* giga */
20205 'T', /* tera */
20206 'P', /* peta */
20207 'E', /* exa */
20208 'Z', /* zetta */
20209 'Y' /* yotta */
20210 };
20211
20212 static void
20213 pint2hrstr (char *buf, int width, EMACS_INT d)
20214 {
20215 /* We aim to represent the nonnegative integer D as
20216 QUOTIENT.TENTHS * 10 ^ (3 * EXPONENT). */
20217 EMACS_INT quotient = d;
20218 int remainder = 0;
20219 /* -1 means: do not use TENTHS. */
20220 int tenths = -1;
20221 int exponent = 0;
20222
20223 /* Length of QUOTIENT.TENTHS as a string. */
20224 int length;
20225
20226 char * psuffix;
20227 char * p;
20228
20229 if (1000 <= quotient)
20230 {
20231 /* Scale to the appropriate EXPONENT. */
20232 do
20233 {
20234 remainder = quotient % 1000;
20235 quotient /= 1000;
20236 exponent++;
20237 }
20238 while (1000 <= quotient);
20239
20240 /* Round to nearest and decide whether to use TENTHS or not. */
20241 if (quotient <= 9)
20242 {
20243 tenths = remainder / 100;
20244 if (50 <= remainder % 100)
20245 {
20246 if (tenths < 9)
20247 tenths++;
20248 else
20249 {
20250 quotient++;
20251 if (quotient == 10)
20252 tenths = -1;
20253 else
20254 tenths = 0;
20255 }
20256 }
20257 }
20258 else
20259 if (500 <= remainder)
20260 {
20261 if (quotient < 999)
20262 quotient++;
20263 else
20264 {
20265 quotient = 1;
20266 exponent++;
20267 tenths = 0;
20268 }
20269 }
20270 }
20271
20272 /* Calculate the LENGTH of QUOTIENT.TENTHS as a string. */
20273 if (tenths == -1 && quotient <= 99)
20274 if (quotient <= 9)
20275 length = 1;
20276 else
20277 length = 2;
20278 else
20279 length = 3;
20280 p = psuffix = buf + max (width, length);
20281
20282 /* Print EXPONENT. */
20283 *psuffix++ = power_letter[exponent];
20284 *psuffix = '\0';
20285
20286 /* Print TENTHS. */
20287 if (tenths >= 0)
20288 {
20289 *--p = '0' + tenths;
20290 *--p = '.';
20291 }
20292
20293 /* Print QUOTIENT. */
20294 do
20295 {
20296 int digit = quotient % 10;
20297 *--p = '0' + digit;
20298 }
20299 while ((quotient /= 10) != 0);
20300
20301 /* Print leading spaces. */
20302 while (buf < p)
20303 *--p = ' ';
20304 }
20305
20306 /* Set a mnemonic character for coding_system (Lisp symbol) in BUF.
20307 If EOL_FLAG is 1, set also a mnemonic character for end-of-line
20308 type of CODING_SYSTEM. Return updated pointer into BUF. */
20309
20310 static unsigned char invalid_eol_type[] = "(*invalid*)";
20311
20312 static char *
20313 decode_mode_spec_coding (Lisp_Object coding_system, register char *buf, int eol_flag)
20314 {
20315 Lisp_Object val;
20316 int multibyte = !NILP (BVAR (current_buffer, enable_multibyte_characters));
20317 const unsigned char *eol_str;
20318 int eol_str_len;
20319 /* The EOL conversion we are using. */
20320 Lisp_Object eoltype;
20321
20322 val = CODING_SYSTEM_SPEC (coding_system);
20323 eoltype = Qnil;
20324
20325 if (!VECTORP (val)) /* Not yet decided. */
20326 {
20327 if (multibyte)
20328 *buf++ = '-';
20329 if (eol_flag)
20330 eoltype = eol_mnemonic_undecided;
20331 /* Don't mention EOL conversion if it isn't decided. */
20332 }
20333 else
20334 {
20335 Lisp_Object attrs;
20336 Lisp_Object eolvalue;
20337
20338 attrs = AREF (val, 0);
20339 eolvalue = AREF (val, 2);
20340
20341 if (multibyte)
20342 *buf++ = XFASTINT (CODING_ATTR_MNEMONIC (attrs));
20343
20344 if (eol_flag)
20345 {
20346 /* The EOL conversion that is normal on this system. */
20347
20348 if (NILP (eolvalue)) /* Not yet decided. */
20349 eoltype = eol_mnemonic_undecided;
20350 else if (VECTORP (eolvalue)) /* Not yet decided. */
20351 eoltype = eol_mnemonic_undecided;
20352 else /* eolvalue is Qunix, Qdos, or Qmac. */
20353 eoltype = (EQ (eolvalue, Qunix)
20354 ? eol_mnemonic_unix
20355 : (EQ (eolvalue, Qdos) == 1
20356 ? eol_mnemonic_dos : eol_mnemonic_mac));
20357 }
20358 }
20359
20360 if (eol_flag)
20361 {
20362 /* Mention the EOL conversion if it is not the usual one. */
20363 if (STRINGP (eoltype))
20364 {
20365 eol_str = SDATA (eoltype);
20366 eol_str_len = SBYTES (eoltype);
20367 }
20368 else if (CHARACTERP (eoltype))
20369 {
20370 unsigned char *tmp = (unsigned char *) alloca (MAX_MULTIBYTE_LENGTH);
20371 int c = XFASTINT (eoltype);
20372 eol_str_len = CHAR_STRING (c, tmp);
20373 eol_str = tmp;
20374 }
20375 else
20376 {
20377 eol_str = invalid_eol_type;
20378 eol_str_len = sizeof (invalid_eol_type) - 1;
20379 }
20380 memcpy (buf, eol_str, eol_str_len);
20381 buf += eol_str_len;
20382 }
20383
20384 return buf;
20385 }
20386
20387 /* Return a string for the output of a mode line %-spec for window W,
20388 generated by character C. FIELD_WIDTH > 0 means pad the string
20389 returned with spaces to that value. Return a Lisp string in
20390 *STRING if the resulting string is taken from that Lisp string.
20391
20392 Note we operate on the current buffer for most purposes,
20393 the exception being w->base_line_pos. */
20394
20395 static char lots_of_dashes[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
20396
20397 static const char *
20398 decode_mode_spec (struct window *w, register int c, int field_width,
20399 Lisp_Object *string)
20400 {
20401 Lisp_Object obj;
20402 struct frame *f = XFRAME (WINDOW_FRAME (w));
20403 char *decode_mode_spec_buf = f->decode_mode_spec_buffer;
20404 struct buffer *b = current_buffer;
20405
20406 obj = Qnil;
20407 *string = Qnil;
20408
20409 switch (c)
20410 {
20411 case '*':
20412 if (!NILP (BVAR (b, read_only)))
20413 return "%";
20414 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
20415 return "*";
20416 return "-";
20417
20418 case '+':
20419 /* This differs from %* only for a modified read-only buffer. */
20420 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
20421 return "*";
20422 if (!NILP (BVAR (b, read_only)))
20423 return "%";
20424 return "-";
20425
20426 case '&':
20427 /* This differs from %* in ignoring read-only-ness. */
20428 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
20429 return "*";
20430 return "-";
20431
20432 case '%':
20433 return "%";
20434
20435 case '[':
20436 {
20437 int i;
20438 char *p;
20439
20440 if (command_loop_level > 5)
20441 return "[[[... ";
20442 p = decode_mode_spec_buf;
20443 for (i = 0; i < command_loop_level; i++)
20444 *p++ = '[';
20445 *p = 0;
20446 return decode_mode_spec_buf;
20447 }
20448
20449 case ']':
20450 {
20451 int i;
20452 char *p;
20453
20454 if (command_loop_level > 5)
20455 return " ...]]]";
20456 p = decode_mode_spec_buf;
20457 for (i = 0; i < command_loop_level; i++)
20458 *p++ = ']';
20459 *p = 0;
20460 return decode_mode_spec_buf;
20461 }
20462
20463 case '-':
20464 {
20465 register int i;
20466
20467 /* Let lots_of_dashes be a string of infinite length. */
20468 if (mode_line_target == MODE_LINE_NOPROP ||
20469 mode_line_target == MODE_LINE_STRING)
20470 return "--";
20471 if (field_width <= 0
20472 || field_width > sizeof (lots_of_dashes))
20473 {
20474 for (i = 0; i < FRAME_MESSAGE_BUF_SIZE (f) - 1; ++i)
20475 decode_mode_spec_buf[i] = '-';
20476 decode_mode_spec_buf[i] = '\0';
20477 return decode_mode_spec_buf;
20478 }
20479 else
20480 return lots_of_dashes;
20481 }
20482
20483 case 'b':
20484 obj = BVAR (b, name);
20485 break;
20486
20487 case 'c':
20488 /* %c and %l are ignored in `frame-title-format'.
20489 (In redisplay_internal, the frame title is drawn _before_ the
20490 windows are updated, so the stuff which depends on actual
20491 window contents (such as %l) may fail to render properly, or
20492 even crash emacs.) */
20493 if (mode_line_target == MODE_LINE_TITLE)
20494 return "";
20495 else
20496 {
20497 EMACS_INT col = current_column ();
20498 w->column_number_displayed = make_number (col);
20499 pint2str (decode_mode_spec_buf, field_width, col);
20500 return decode_mode_spec_buf;
20501 }
20502
20503 case 'e':
20504 #ifndef SYSTEM_MALLOC
20505 {
20506 if (NILP (Vmemory_full))
20507 return "";
20508 else
20509 return "!MEM FULL! ";
20510 }
20511 #else
20512 return "";
20513 #endif
20514
20515 case 'F':
20516 /* %F displays the frame name. */
20517 if (!NILP (f->title))
20518 return SSDATA (f->title);
20519 if (f->explicit_name || ! FRAME_WINDOW_P (f))
20520 return SSDATA (f->name);
20521 return "Emacs";
20522
20523 case 'f':
20524 obj = BVAR (b, filename);
20525 break;
20526
20527 case 'i':
20528 {
20529 EMACS_INT size = ZV - BEGV;
20530 pint2str (decode_mode_spec_buf, field_width, size);
20531 return decode_mode_spec_buf;
20532 }
20533
20534 case 'I':
20535 {
20536 EMACS_INT size = ZV - BEGV;
20537 pint2hrstr (decode_mode_spec_buf, field_width, size);
20538 return decode_mode_spec_buf;
20539 }
20540
20541 case 'l':
20542 {
20543 EMACS_INT startpos, startpos_byte, line, linepos, linepos_byte;
20544 EMACS_INT topline, nlines, height;
20545 EMACS_INT junk;
20546
20547 /* %c and %l are ignored in `frame-title-format'. */
20548 if (mode_line_target == MODE_LINE_TITLE)
20549 return "";
20550
20551 startpos = XMARKER (w->start)->charpos;
20552 startpos_byte = marker_byte_position (w->start);
20553 height = WINDOW_TOTAL_LINES (w);
20554
20555 /* If we decided that this buffer isn't suitable for line numbers,
20556 don't forget that too fast. */
20557 if (EQ (w->base_line_pos, w->buffer))
20558 goto no_value;
20559 /* But do forget it, if the window shows a different buffer now. */
20560 else if (BUFFERP (w->base_line_pos))
20561 w->base_line_pos = Qnil;
20562
20563 /* If the buffer is very big, don't waste time. */
20564 if (INTEGERP (Vline_number_display_limit)
20565 && BUF_ZV (b) - BUF_BEGV (b) > XINT (Vline_number_display_limit))
20566 {
20567 w->base_line_pos = Qnil;
20568 w->base_line_number = Qnil;
20569 goto no_value;
20570 }
20571
20572 if (INTEGERP (w->base_line_number)
20573 && INTEGERP (w->base_line_pos)
20574 && XFASTINT (w->base_line_pos) <= startpos)
20575 {
20576 line = XFASTINT (w->base_line_number);
20577 linepos = XFASTINT (w->base_line_pos);
20578 linepos_byte = buf_charpos_to_bytepos (b, linepos);
20579 }
20580 else
20581 {
20582 line = 1;
20583 linepos = BUF_BEGV (b);
20584 linepos_byte = BUF_BEGV_BYTE (b);
20585 }
20586
20587 /* Count lines from base line to window start position. */
20588 nlines = display_count_lines (linepos_byte,
20589 startpos_byte,
20590 startpos, &junk);
20591
20592 topline = nlines + line;
20593
20594 /* Determine a new base line, if the old one is too close
20595 or too far away, or if we did not have one.
20596 "Too close" means it's plausible a scroll-down would
20597 go back past it. */
20598 if (startpos == BUF_BEGV (b))
20599 {
20600 w->base_line_number = make_number (topline);
20601 w->base_line_pos = make_number (BUF_BEGV (b));
20602 }
20603 else if (nlines < height + 25 || nlines > height * 3 + 50
20604 || linepos == BUF_BEGV (b))
20605 {
20606 EMACS_INT limit = BUF_BEGV (b);
20607 EMACS_INT limit_byte = BUF_BEGV_BYTE (b);
20608 EMACS_INT position;
20609 EMACS_INT distance =
20610 (height * 2 + 30) * line_number_display_limit_width;
20611
20612 if (startpos - distance > limit)
20613 {
20614 limit = startpos - distance;
20615 limit_byte = CHAR_TO_BYTE (limit);
20616 }
20617
20618 nlines = display_count_lines (startpos_byte,
20619 limit_byte,
20620 - (height * 2 + 30),
20621 &position);
20622 /* If we couldn't find the lines we wanted within
20623 line_number_display_limit_width chars per line,
20624 give up on line numbers for this window. */
20625 if (position == limit_byte && limit == startpos - distance)
20626 {
20627 w->base_line_pos = w->buffer;
20628 w->base_line_number = Qnil;
20629 goto no_value;
20630 }
20631
20632 w->base_line_number = make_number (topline - nlines);
20633 w->base_line_pos = make_number (BYTE_TO_CHAR (position));
20634 }
20635
20636 /* Now count lines from the start pos to point. */
20637 nlines = display_count_lines (startpos_byte,
20638 PT_BYTE, PT, &junk);
20639
20640 /* Record that we did display the line number. */
20641 line_number_displayed = 1;
20642
20643 /* Make the string to show. */
20644 pint2str (decode_mode_spec_buf, field_width, topline + nlines);
20645 return decode_mode_spec_buf;
20646 no_value:
20647 {
20648 char* p = decode_mode_spec_buf;
20649 int pad = field_width - 2;
20650 while (pad-- > 0)
20651 *p++ = ' ';
20652 *p++ = '?';
20653 *p++ = '?';
20654 *p = '\0';
20655 return decode_mode_spec_buf;
20656 }
20657 }
20658 break;
20659
20660 case 'm':
20661 obj = BVAR (b, mode_name);
20662 break;
20663
20664 case 'n':
20665 if (BUF_BEGV (b) > BUF_BEG (b) || BUF_ZV (b) < BUF_Z (b))
20666 return " Narrow";
20667 break;
20668
20669 case 'p':
20670 {
20671 EMACS_INT pos = marker_position (w->start);
20672 EMACS_INT total = BUF_ZV (b) - BUF_BEGV (b);
20673
20674 if (XFASTINT (w->window_end_pos) <= BUF_Z (b) - BUF_ZV (b))
20675 {
20676 if (pos <= BUF_BEGV (b))
20677 return "All";
20678 else
20679 return "Bottom";
20680 }
20681 else if (pos <= BUF_BEGV (b))
20682 return "Top";
20683 else
20684 {
20685 if (total > 1000000)
20686 /* Do it differently for a large value, to avoid overflow. */
20687 total = ((pos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
20688 else
20689 total = ((pos - BUF_BEGV (b)) * 100 + total - 1) / total;
20690 /* We can't normally display a 3-digit number,
20691 so get us a 2-digit number that is close. */
20692 if (total == 100)
20693 total = 99;
20694 sprintf (decode_mode_spec_buf, "%2"pI"d%%", total);
20695 return decode_mode_spec_buf;
20696 }
20697 }
20698
20699 /* Display percentage of size above the bottom of the screen. */
20700 case 'P':
20701 {
20702 EMACS_INT toppos = marker_position (w->start);
20703 EMACS_INT botpos = BUF_Z (b) - XFASTINT (w->window_end_pos);
20704 EMACS_INT total = BUF_ZV (b) - BUF_BEGV (b);
20705
20706 if (botpos >= BUF_ZV (b))
20707 {
20708 if (toppos <= BUF_BEGV (b))
20709 return "All";
20710 else
20711 return "Bottom";
20712 }
20713 else
20714 {
20715 if (total > 1000000)
20716 /* Do it differently for a large value, to avoid overflow. */
20717 total = ((botpos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
20718 else
20719 total = ((botpos - BUF_BEGV (b)) * 100 + total - 1) / total;
20720 /* We can't normally display a 3-digit number,
20721 so get us a 2-digit number that is close. */
20722 if (total == 100)
20723 total = 99;
20724 if (toppos <= BUF_BEGV (b))
20725 sprintf (decode_mode_spec_buf, "Top%2"pI"d%%", total);
20726 else
20727 sprintf (decode_mode_spec_buf, "%2"pI"d%%", total);
20728 return decode_mode_spec_buf;
20729 }
20730 }
20731
20732 case 's':
20733 /* status of process */
20734 obj = Fget_buffer_process (Fcurrent_buffer ());
20735 if (NILP (obj))
20736 return "no process";
20737 #ifndef MSDOS
20738 obj = Fsymbol_name (Fprocess_status (obj));
20739 #endif
20740 break;
20741
20742 case '@':
20743 {
20744 int count = inhibit_garbage_collection ();
20745 Lisp_Object val = call1 (intern ("file-remote-p"),
20746 BVAR (current_buffer, directory));
20747 unbind_to (count, Qnil);
20748
20749 if (NILP (val))
20750 return "-";
20751 else
20752 return "@";
20753 }
20754
20755 case 't': /* indicate TEXT or BINARY */
20756 return "T";
20757
20758 case 'z':
20759 /* coding-system (not including end-of-line format) */
20760 case 'Z':
20761 /* coding-system (including end-of-line type) */
20762 {
20763 int eol_flag = (c == 'Z');
20764 char *p = decode_mode_spec_buf;
20765
20766 if (! FRAME_WINDOW_P (f))
20767 {
20768 /* No need to mention EOL here--the terminal never needs
20769 to do EOL conversion. */
20770 p = decode_mode_spec_coding (CODING_ID_NAME
20771 (FRAME_KEYBOARD_CODING (f)->id),
20772 p, 0);
20773 p = decode_mode_spec_coding (CODING_ID_NAME
20774 (FRAME_TERMINAL_CODING (f)->id),
20775 p, 0);
20776 }
20777 p = decode_mode_spec_coding (BVAR (b, buffer_file_coding_system),
20778 p, eol_flag);
20779
20780 #if 0 /* This proves to be annoying; I think we can do without. -- rms. */
20781 #ifdef subprocesses
20782 obj = Fget_buffer_process (Fcurrent_buffer ());
20783 if (PROCESSP (obj))
20784 {
20785 p = decode_mode_spec_coding (XPROCESS (obj)->decode_coding_system,
20786 p, eol_flag);
20787 p = decode_mode_spec_coding (XPROCESS (obj)->encode_coding_system,
20788 p, eol_flag);
20789 }
20790 #endif /* subprocesses */
20791 #endif /* 0 */
20792 *p = 0;
20793 return decode_mode_spec_buf;
20794 }
20795 }
20796
20797 if (STRINGP (obj))
20798 {
20799 *string = obj;
20800 return SSDATA (obj);
20801 }
20802 else
20803 return "";
20804 }
20805
20806
20807 /* Count up to COUNT lines starting from START_BYTE.
20808 But don't go beyond LIMIT_BYTE.
20809 Return the number of lines thus found (always nonnegative).
20810
20811 Set *BYTE_POS_PTR to 1 if we found COUNT lines, 0 if we hit LIMIT. */
20812
20813 static EMACS_INT
20814 display_count_lines (EMACS_INT start_byte,
20815 EMACS_INT limit_byte, EMACS_INT count,
20816 EMACS_INT *byte_pos_ptr)
20817 {
20818 register unsigned char *cursor;
20819 unsigned char *base;
20820
20821 register EMACS_INT ceiling;
20822 register unsigned char *ceiling_addr;
20823 EMACS_INT orig_count = count;
20824
20825 /* If we are not in selective display mode,
20826 check only for newlines. */
20827 int selective_display = (!NILP (BVAR (current_buffer, selective_display))
20828 && !INTEGERP (BVAR (current_buffer, selective_display)));
20829
20830 if (count > 0)
20831 {
20832 while (start_byte < limit_byte)
20833 {
20834 ceiling = BUFFER_CEILING_OF (start_byte);
20835 ceiling = min (limit_byte - 1, ceiling);
20836 ceiling_addr = BYTE_POS_ADDR (ceiling) + 1;
20837 base = (cursor = BYTE_POS_ADDR (start_byte));
20838 while (1)
20839 {
20840 if (selective_display)
20841 while (*cursor != '\n' && *cursor != 015 && ++cursor != ceiling_addr)
20842 ;
20843 else
20844 while (*cursor != '\n' && ++cursor != ceiling_addr)
20845 ;
20846
20847 if (cursor != ceiling_addr)
20848 {
20849 if (--count == 0)
20850 {
20851 start_byte += cursor - base + 1;
20852 *byte_pos_ptr = start_byte;
20853 return orig_count;
20854 }
20855 else
20856 if (++cursor == ceiling_addr)
20857 break;
20858 }
20859 else
20860 break;
20861 }
20862 start_byte += cursor - base;
20863 }
20864 }
20865 else
20866 {
20867 while (start_byte > limit_byte)
20868 {
20869 ceiling = BUFFER_FLOOR_OF (start_byte - 1);
20870 ceiling = max (limit_byte, ceiling);
20871 ceiling_addr = BYTE_POS_ADDR (ceiling) - 1;
20872 base = (cursor = BYTE_POS_ADDR (start_byte - 1) + 1);
20873 while (1)
20874 {
20875 if (selective_display)
20876 while (--cursor != ceiling_addr
20877 && *cursor != '\n' && *cursor != 015)
20878 ;
20879 else
20880 while (--cursor != ceiling_addr && *cursor != '\n')
20881 ;
20882
20883 if (cursor != ceiling_addr)
20884 {
20885 if (++count == 0)
20886 {
20887 start_byte += cursor - base + 1;
20888 *byte_pos_ptr = start_byte;
20889 /* When scanning backwards, we should
20890 not count the newline posterior to which we stop. */
20891 return - orig_count - 1;
20892 }
20893 }
20894 else
20895 break;
20896 }
20897 /* Here we add 1 to compensate for the last decrement
20898 of CURSOR, which took it past the valid range. */
20899 start_byte += cursor - base + 1;
20900 }
20901 }
20902
20903 *byte_pos_ptr = limit_byte;
20904
20905 if (count < 0)
20906 return - orig_count + count;
20907 return orig_count - count;
20908
20909 }
20910
20911
20912 \f
20913 /***********************************************************************
20914 Displaying strings
20915 ***********************************************************************/
20916
20917 /* Display a NUL-terminated string, starting with index START.
20918
20919 If STRING is non-null, display that C string. Otherwise, the Lisp
20920 string LISP_STRING is displayed. There's a case that STRING is
20921 non-null and LISP_STRING is not nil. It means STRING is a string
20922 data of LISP_STRING. In that case, we display LISP_STRING while
20923 ignoring its text properties.
20924
20925 If FACE_STRING is not nil, FACE_STRING_POS is a position in
20926 FACE_STRING. Display STRING or LISP_STRING with the face at
20927 FACE_STRING_POS in FACE_STRING:
20928
20929 Display the string in the environment given by IT, but use the
20930 standard display table, temporarily.
20931
20932 FIELD_WIDTH is the minimum number of output glyphs to produce.
20933 If STRING has fewer characters than FIELD_WIDTH, pad to the right
20934 with spaces. If STRING has more characters, more than FIELD_WIDTH
20935 glyphs will be produced. FIELD_WIDTH <= 0 means don't pad.
20936
20937 PRECISION is the maximum number of characters to output from
20938 STRING. PRECISION < 0 means don't truncate the string.
20939
20940 This is roughly equivalent to printf format specifiers:
20941
20942 FIELD_WIDTH PRECISION PRINTF
20943 ----------------------------------------
20944 -1 -1 %s
20945 -1 10 %.10s
20946 10 -1 %10s
20947 20 10 %20.10s
20948
20949 MULTIBYTE zero means do not display multibyte chars, > 0 means do
20950 display them, and < 0 means obey the current buffer's value of
20951 enable_multibyte_characters.
20952
20953 Value is the number of columns displayed. */
20954
20955 static int
20956 display_string (const char *string, Lisp_Object lisp_string, Lisp_Object face_string,
20957 EMACS_INT face_string_pos, EMACS_INT start, struct it *it,
20958 int field_width, int precision, int max_x, int multibyte)
20959 {
20960 int hpos_at_start = it->hpos;
20961 int saved_face_id = it->face_id;
20962 struct glyph_row *row = it->glyph_row;
20963 EMACS_INT it_charpos;
20964
20965 /* Initialize the iterator IT for iteration over STRING beginning
20966 with index START. */
20967 reseat_to_string (it, NILP (lisp_string) ? string : NULL, lisp_string, start,
20968 precision, field_width, multibyte);
20969 if (string && STRINGP (lisp_string))
20970 /* LISP_STRING is the one returned by decode_mode_spec. We should
20971 ignore its text properties. */
20972 it->stop_charpos = it->end_charpos;
20973
20974 /* If displaying STRING, set up the face of the iterator from
20975 FACE_STRING, if that's given. */
20976 if (STRINGP (face_string))
20977 {
20978 EMACS_INT endptr;
20979 struct face *face;
20980
20981 it->face_id
20982 = face_at_string_position (it->w, face_string, face_string_pos,
20983 0, it->region_beg_charpos,
20984 it->region_end_charpos,
20985 &endptr, it->base_face_id, 0);
20986 face = FACE_FROM_ID (it->f, it->face_id);
20987 it->face_box_p = face->box != FACE_NO_BOX;
20988 }
20989
20990 /* Set max_x to the maximum allowed X position. Don't let it go
20991 beyond the right edge of the window. */
20992 if (max_x <= 0)
20993 max_x = it->last_visible_x;
20994 else
20995 max_x = min (max_x, it->last_visible_x);
20996
20997 /* Skip over display elements that are not visible. because IT->w is
20998 hscrolled. */
20999 if (it->current_x < it->first_visible_x)
21000 move_it_in_display_line_to (it, 100000, it->first_visible_x,
21001 MOVE_TO_POS | MOVE_TO_X);
21002
21003 row->ascent = it->max_ascent;
21004 row->height = it->max_ascent + it->max_descent;
21005 row->phys_ascent = it->max_phys_ascent;
21006 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
21007 row->extra_line_spacing = it->max_extra_line_spacing;
21008
21009 if (STRINGP (it->string))
21010 it_charpos = IT_STRING_CHARPOS (*it);
21011 else
21012 it_charpos = IT_CHARPOS (*it);
21013
21014 /* This condition is for the case that we are called with current_x
21015 past last_visible_x. */
21016 while (it->current_x < max_x)
21017 {
21018 int x_before, x, n_glyphs_before, i, nglyphs;
21019
21020 /* Get the next display element. */
21021 if (!get_next_display_element (it))
21022 break;
21023
21024 /* Produce glyphs. */
21025 x_before = it->current_x;
21026 n_glyphs_before = row->used[TEXT_AREA];
21027 PRODUCE_GLYPHS (it);
21028
21029 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
21030 i = 0;
21031 x = x_before;
21032 while (i < nglyphs)
21033 {
21034 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
21035
21036 if (it->line_wrap != TRUNCATE
21037 && x + glyph->pixel_width > max_x)
21038 {
21039 /* End of continued line or max_x reached. */
21040 if (CHAR_GLYPH_PADDING_P (*glyph))
21041 {
21042 /* A wide character is unbreakable. */
21043 if (row->reversed_p)
21044 unproduce_glyphs (it, row->used[TEXT_AREA]
21045 - n_glyphs_before);
21046 row->used[TEXT_AREA] = n_glyphs_before;
21047 it->current_x = x_before;
21048 }
21049 else
21050 {
21051 if (row->reversed_p)
21052 unproduce_glyphs (it, row->used[TEXT_AREA]
21053 - (n_glyphs_before + i));
21054 row->used[TEXT_AREA] = n_glyphs_before + i;
21055 it->current_x = x;
21056 }
21057 break;
21058 }
21059 else if (x + glyph->pixel_width >= it->first_visible_x)
21060 {
21061 /* Glyph is at least partially visible. */
21062 ++it->hpos;
21063 if (x < it->first_visible_x)
21064 row->x = x - it->first_visible_x;
21065 }
21066 else
21067 {
21068 /* Glyph is off the left margin of the display area.
21069 Should not happen. */
21070 abort ();
21071 }
21072
21073 row->ascent = max (row->ascent, it->max_ascent);
21074 row->height = max (row->height, it->max_ascent + it->max_descent);
21075 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
21076 row->phys_height = max (row->phys_height,
21077 it->max_phys_ascent + it->max_phys_descent);
21078 row->extra_line_spacing = max (row->extra_line_spacing,
21079 it->max_extra_line_spacing);
21080 x += glyph->pixel_width;
21081 ++i;
21082 }
21083
21084 /* Stop if max_x reached. */
21085 if (i < nglyphs)
21086 break;
21087
21088 /* Stop at line ends. */
21089 if (ITERATOR_AT_END_OF_LINE_P (it))
21090 {
21091 it->continuation_lines_width = 0;
21092 break;
21093 }
21094
21095 set_iterator_to_next (it, 1);
21096 if (STRINGP (it->string))
21097 it_charpos = IT_STRING_CHARPOS (*it);
21098 else
21099 it_charpos = IT_CHARPOS (*it);
21100
21101 /* Stop if truncating at the right edge. */
21102 if (it->line_wrap == TRUNCATE
21103 && it->current_x >= it->last_visible_x)
21104 {
21105 /* Add truncation mark, but don't do it if the line is
21106 truncated at a padding space. */
21107 if (it_charpos < it->string_nchars)
21108 {
21109 if (!FRAME_WINDOW_P (it->f))
21110 {
21111 int ii, n;
21112
21113 if (it->current_x > it->last_visible_x)
21114 {
21115 if (!row->reversed_p)
21116 {
21117 for (ii = row->used[TEXT_AREA] - 1; ii > 0; --ii)
21118 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][ii]))
21119 break;
21120 }
21121 else
21122 {
21123 for (ii = 0; ii < row->used[TEXT_AREA]; ii++)
21124 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][ii]))
21125 break;
21126 unproduce_glyphs (it, ii + 1);
21127 ii = row->used[TEXT_AREA] - (ii + 1);
21128 }
21129 for (n = row->used[TEXT_AREA]; ii < n; ++ii)
21130 {
21131 row->used[TEXT_AREA] = ii;
21132 produce_special_glyphs (it, IT_TRUNCATION);
21133 }
21134 }
21135 produce_special_glyphs (it, IT_TRUNCATION);
21136 }
21137 row->truncated_on_right_p = 1;
21138 }
21139 break;
21140 }
21141 }
21142
21143 /* Maybe insert a truncation at the left. */
21144 if (it->first_visible_x
21145 && it_charpos > 0)
21146 {
21147 if (!FRAME_WINDOW_P (it->f))
21148 insert_left_trunc_glyphs (it);
21149 row->truncated_on_left_p = 1;
21150 }
21151
21152 it->face_id = saved_face_id;
21153
21154 /* Value is number of columns displayed. */
21155 return it->hpos - hpos_at_start;
21156 }
21157
21158
21159 \f
21160 /* This is like a combination of memq and assq. Return 1/2 if PROPVAL
21161 appears as an element of LIST or as the car of an element of LIST.
21162 If PROPVAL is a list, compare each element against LIST in that
21163 way, and return 1/2 if any element of PROPVAL is found in LIST.
21164 Otherwise return 0. This function cannot quit.
21165 The return value is 2 if the text is invisible but with an ellipsis
21166 and 1 if it's invisible and without an ellipsis. */
21167
21168 int
21169 invisible_p (register Lisp_Object propval, Lisp_Object list)
21170 {
21171 register Lisp_Object tail, proptail;
21172
21173 for (tail = list; CONSP (tail); tail = XCDR (tail))
21174 {
21175 register Lisp_Object tem;
21176 tem = XCAR (tail);
21177 if (EQ (propval, tem))
21178 return 1;
21179 if (CONSP (tem) && EQ (propval, XCAR (tem)))
21180 return NILP (XCDR (tem)) ? 1 : 2;
21181 }
21182
21183 if (CONSP (propval))
21184 {
21185 for (proptail = propval; CONSP (proptail); proptail = XCDR (proptail))
21186 {
21187 Lisp_Object propelt;
21188 propelt = XCAR (proptail);
21189 for (tail = list; CONSP (tail); tail = XCDR (tail))
21190 {
21191 register Lisp_Object tem;
21192 tem = XCAR (tail);
21193 if (EQ (propelt, tem))
21194 return 1;
21195 if (CONSP (tem) && EQ (propelt, XCAR (tem)))
21196 return NILP (XCDR (tem)) ? 1 : 2;
21197 }
21198 }
21199 }
21200
21201 return 0;
21202 }
21203
21204 DEFUN ("invisible-p", Finvisible_p, Sinvisible_p, 1, 1, 0,
21205 doc: /* Non-nil if the property makes the text invisible.
21206 POS-OR-PROP can be a marker or number, in which case it is taken to be
21207 a position in the current buffer and the value of the `invisible' property
21208 is checked; or it can be some other value, which is then presumed to be the
21209 value of the `invisible' property of the text of interest.
21210 The non-nil value returned can be t for truly invisible text or something
21211 else if the text is replaced by an ellipsis. */)
21212 (Lisp_Object pos_or_prop)
21213 {
21214 Lisp_Object prop
21215 = (NATNUMP (pos_or_prop) || MARKERP (pos_or_prop)
21216 ? Fget_char_property (pos_or_prop, Qinvisible, Qnil)
21217 : pos_or_prop);
21218 int invis = TEXT_PROP_MEANS_INVISIBLE (prop);
21219 return (invis == 0 ? Qnil
21220 : invis == 1 ? Qt
21221 : make_number (invis));
21222 }
21223
21224 /* Calculate a width or height in pixels from a specification using
21225 the following elements:
21226
21227 SPEC ::=
21228 NUM - a (fractional) multiple of the default font width/height
21229 (NUM) - specifies exactly NUM pixels
21230 UNIT - a fixed number of pixels, see below.
21231 ELEMENT - size of a display element in pixels, see below.
21232 (NUM . SPEC) - equals NUM * SPEC
21233 (+ SPEC SPEC ...) - add pixel values
21234 (- SPEC SPEC ...) - subtract pixel values
21235 (- SPEC) - negate pixel value
21236
21237 NUM ::=
21238 INT or FLOAT - a number constant
21239 SYMBOL - use symbol's (buffer local) variable binding.
21240
21241 UNIT ::=
21242 in - pixels per inch *)
21243 mm - pixels per 1/1000 meter *)
21244 cm - pixels per 1/100 meter *)
21245 width - width of current font in pixels.
21246 height - height of current font in pixels.
21247
21248 *) using the ratio(s) defined in display-pixels-per-inch.
21249
21250 ELEMENT ::=
21251
21252 left-fringe - left fringe width in pixels
21253 right-fringe - right fringe width in pixels
21254
21255 left-margin - left margin width in pixels
21256 right-margin - right margin width in pixels
21257
21258 scroll-bar - scroll-bar area width in pixels
21259
21260 Examples:
21261
21262 Pixels corresponding to 5 inches:
21263 (5 . in)
21264
21265 Total width of non-text areas on left side of window (if scroll-bar is on left):
21266 '(space :width (+ left-fringe left-margin scroll-bar))
21267
21268 Align to first text column (in header line):
21269 '(space :align-to 0)
21270
21271 Align to middle of text area minus half the width of variable `my-image'
21272 containing a loaded image:
21273 '(space :align-to (0.5 . (- text my-image)))
21274
21275 Width of left margin minus width of 1 character in the default font:
21276 '(space :width (- left-margin 1))
21277
21278 Width of left margin minus width of 2 characters in the current font:
21279 '(space :width (- left-margin (2 . width)))
21280
21281 Center 1 character over left-margin (in header line):
21282 '(space :align-to (+ left-margin (0.5 . left-margin) -0.5))
21283
21284 Different ways to express width of left fringe plus left margin minus one pixel:
21285 '(space :width (- (+ left-fringe left-margin) (1)))
21286 '(space :width (+ left-fringe left-margin (- (1))))
21287 '(space :width (+ left-fringe left-margin (-1)))
21288
21289 */
21290
21291 #define NUMVAL(X) \
21292 ((INTEGERP (X) || FLOATP (X)) \
21293 ? XFLOATINT (X) \
21294 : - 1)
21295
21296 static int
21297 calc_pixel_width_or_height (double *res, struct it *it, Lisp_Object prop,
21298 struct font *font, int width_p, int *align_to)
21299 {
21300 double pixels;
21301
21302 #define OK_PIXELS(val) ((*res = (double)(val)), 1)
21303 #define OK_ALIGN_TO(val) ((*align_to = (int)(val)), 1)
21304
21305 if (NILP (prop))
21306 return OK_PIXELS (0);
21307
21308 xassert (FRAME_LIVE_P (it->f));
21309
21310 if (SYMBOLP (prop))
21311 {
21312 if (SCHARS (SYMBOL_NAME (prop)) == 2)
21313 {
21314 char *unit = SSDATA (SYMBOL_NAME (prop));
21315
21316 if (unit[0] == 'i' && unit[1] == 'n')
21317 pixels = 1.0;
21318 else if (unit[0] == 'm' && unit[1] == 'm')
21319 pixels = 25.4;
21320 else if (unit[0] == 'c' && unit[1] == 'm')
21321 pixels = 2.54;
21322 else
21323 pixels = 0;
21324 if (pixels > 0)
21325 {
21326 double ppi;
21327 #ifdef HAVE_WINDOW_SYSTEM
21328 if (FRAME_WINDOW_P (it->f)
21329 && (ppi = (width_p
21330 ? FRAME_X_DISPLAY_INFO (it->f)->resx
21331 : FRAME_X_DISPLAY_INFO (it->f)->resy),
21332 ppi > 0))
21333 return OK_PIXELS (ppi / pixels);
21334 #endif
21335
21336 if ((ppi = NUMVAL (Vdisplay_pixels_per_inch), ppi > 0)
21337 || (CONSP (Vdisplay_pixels_per_inch)
21338 && (ppi = (width_p
21339 ? NUMVAL (XCAR (Vdisplay_pixels_per_inch))
21340 : NUMVAL (XCDR (Vdisplay_pixels_per_inch))),
21341 ppi > 0)))
21342 return OK_PIXELS (ppi / pixels);
21343
21344 return 0;
21345 }
21346 }
21347
21348 #ifdef HAVE_WINDOW_SYSTEM
21349 if (EQ (prop, Qheight))
21350 return OK_PIXELS (font ? FONT_HEIGHT (font) : FRAME_LINE_HEIGHT (it->f));
21351 if (EQ (prop, Qwidth))
21352 return OK_PIXELS (font ? FONT_WIDTH (font) : FRAME_COLUMN_WIDTH (it->f));
21353 #else
21354 if (EQ (prop, Qheight) || EQ (prop, Qwidth))
21355 return OK_PIXELS (1);
21356 #endif
21357
21358 if (EQ (prop, Qtext))
21359 return OK_PIXELS (width_p
21360 ? window_box_width (it->w, TEXT_AREA)
21361 : WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w));
21362
21363 if (align_to && *align_to < 0)
21364 {
21365 *res = 0;
21366 if (EQ (prop, Qleft))
21367 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA));
21368 if (EQ (prop, Qright))
21369 return OK_ALIGN_TO (window_box_right_offset (it->w, TEXT_AREA));
21370 if (EQ (prop, Qcenter))
21371 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA)
21372 + window_box_width (it->w, TEXT_AREA) / 2);
21373 if (EQ (prop, Qleft_fringe))
21374 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
21375 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (it->w)
21376 : window_box_right_offset (it->w, LEFT_MARGIN_AREA));
21377 if (EQ (prop, Qright_fringe))
21378 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
21379 ? window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
21380 : window_box_right_offset (it->w, TEXT_AREA));
21381 if (EQ (prop, Qleft_margin))
21382 return OK_ALIGN_TO (window_box_left_offset (it->w, LEFT_MARGIN_AREA));
21383 if (EQ (prop, Qright_margin))
21384 return OK_ALIGN_TO (window_box_left_offset (it->w, RIGHT_MARGIN_AREA));
21385 if (EQ (prop, Qscroll_bar))
21386 return OK_ALIGN_TO (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (it->w)
21387 ? 0
21388 : (window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
21389 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
21390 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
21391 : 0)));
21392 }
21393 else
21394 {
21395 if (EQ (prop, Qleft_fringe))
21396 return OK_PIXELS (WINDOW_LEFT_FRINGE_WIDTH (it->w));
21397 if (EQ (prop, Qright_fringe))
21398 return OK_PIXELS (WINDOW_RIGHT_FRINGE_WIDTH (it->w));
21399 if (EQ (prop, Qleft_margin))
21400 return OK_PIXELS (WINDOW_LEFT_MARGIN_WIDTH (it->w));
21401 if (EQ (prop, Qright_margin))
21402 return OK_PIXELS (WINDOW_RIGHT_MARGIN_WIDTH (it->w));
21403 if (EQ (prop, Qscroll_bar))
21404 return OK_PIXELS (WINDOW_SCROLL_BAR_AREA_WIDTH (it->w));
21405 }
21406
21407 prop = Fbuffer_local_value (prop, it->w->buffer);
21408 }
21409
21410 if (INTEGERP (prop) || FLOATP (prop))
21411 {
21412 int base_unit = (width_p
21413 ? FRAME_COLUMN_WIDTH (it->f)
21414 : FRAME_LINE_HEIGHT (it->f));
21415 return OK_PIXELS (XFLOATINT (prop) * base_unit);
21416 }
21417
21418 if (CONSP (prop))
21419 {
21420 Lisp_Object car = XCAR (prop);
21421 Lisp_Object cdr = XCDR (prop);
21422
21423 if (SYMBOLP (car))
21424 {
21425 #ifdef HAVE_WINDOW_SYSTEM
21426 if (FRAME_WINDOW_P (it->f)
21427 && valid_image_p (prop))
21428 {
21429 ptrdiff_t id = lookup_image (it->f, prop);
21430 struct image *img = IMAGE_FROM_ID (it->f, id);
21431
21432 return OK_PIXELS (width_p ? img->width : img->height);
21433 }
21434 #endif
21435 if (EQ (car, Qplus) || EQ (car, Qminus))
21436 {
21437 int first = 1;
21438 double px;
21439
21440 pixels = 0;
21441 while (CONSP (cdr))
21442 {
21443 if (!calc_pixel_width_or_height (&px, it, XCAR (cdr),
21444 font, width_p, align_to))
21445 return 0;
21446 if (first)
21447 pixels = (EQ (car, Qplus) ? px : -px), first = 0;
21448 else
21449 pixels += px;
21450 cdr = XCDR (cdr);
21451 }
21452 if (EQ (car, Qminus))
21453 pixels = -pixels;
21454 return OK_PIXELS (pixels);
21455 }
21456
21457 car = Fbuffer_local_value (car, it->w->buffer);
21458 }
21459
21460 if (INTEGERP (car) || FLOATP (car))
21461 {
21462 double fact;
21463 pixels = XFLOATINT (car);
21464 if (NILP (cdr))
21465 return OK_PIXELS (pixels);
21466 if (calc_pixel_width_or_height (&fact, it, cdr,
21467 font, width_p, align_to))
21468 return OK_PIXELS (pixels * fact);
21469 return 0;
21470 }
21471
21472 return 0;
21473 }
21474
21475 return 0;
21476 }
21477
21478 \f
21479 /***********************************************************************
21480 Glyph Display
21481 ***********************************************************************/
21482
21483 #ifdef HAVE_WINDOW_SYSTEM
21484
21485 #if GLYPH_DEBUG
21486
21487 void
21488 dump_glyph_string (struct glyph_string *s)
21489 {
21490 fprintf (stderr, "glyph string\n");
21491 fprintf (stderr, " x, y, w, h = %d, %d, %d, %d\n",
21492 s->x, s->y, s->width, s->height);
21493 fprintf (stderr, " ybase = %d\n", s->ybase);
21494 fprintf (stderr, " hl = %d\n", s->hl);
21495 fprintf (stderr, " left overhang = %d, right = %d\n",
21496 s->left_overhang, s->right_overhang);
21497 fprintf (stderr, " nchars = %d\n", s->nchars);
21498 fprintf (stderr, " extends to end of line = %d\n",
21499 s->extends_to_end_of_line_p);
21500 fprintf (stderr, " font height = %d\n", FONT_HEIGHT (s->font));
21501 fprintf (stderr, " bg width = %d\n", s->background_width);
21502 }
21503
21504 #endif /* GLYPH_DEBUG */
21505
21506 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
21507 of XChar2b structures for S; it can't be allocated in
21508 init_glyph_string because it must be allocated via `alloca'. W
21509 is the window on which S is drawn. ROW and AREA are the glyph row
21510 and area within the row from which S is constructed. START is the
21511 index of the first glyph structure covered by S. HL is a
21512 face-override for drawing S. */
21513
21514 #ifdef HAVE_NTGUI
21515 #define OPTIONAL_HDC(hdc) HDC hdc,
21516 #define DECLARE_HDC(hdc) HDC hdc;
21517 #define ALLOCATE_HDC(hdc, f) hdc = get_frame_dc ((f))
21518 #define RELEASE_HDC(hdc, f) release_frame_dc ((f), (hdc))
21519 #endif
21520
21521 #ifndef OPTIONAL_HDC
21522 #define OPTIONAL_HDC(hdc)
21523 #define DECLARE_HDC(hdc)
21524 #define ALLOCATE_HDC(hdc, f)
21525 #define RELEASE_HDC(hdc, f)
21526 #endif
21527
21528 static void
21529 init_glyph_string (struct glyph_string *s,
21530 OPTIONAL_HDC (hdc)
21531 XChar2b *char2b, struct window *w, struct glyph_row *row,
21532 enum glyph_row_area area, int start, enum draw_glyphs_face hl)
21533 {
21534 memset (s, 0, sizeof *s);
21535 s->w = w;
21536 s->f = XFRAME (w->frame);
21537 #ifdef HAVE_NTGUI
21538 s->hdc = hdc;
21539 #endif
21540 s->display = FRAME_X_DISPLAY (s->f);
21541 s->window = FRAME_X_WINDOW (s->f);
21542 s->char2b = char2b;
21543 s->hl = hl;
21544 s->row = row;
21545 s->area = area;
21546 s->first_glyph = row->glyphs[area] + start;
21547 s->height = row->height;
21548 s->y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
21549 s->ybase = s->y + row->ascent;
21550 }
21551
21552
21553 /* Append the list of glyph strings with head H and tail T to the list
21554 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
21555
21556 static inline void
21557 append_glyph_string_lists (struct glyph_string **head, struct glyph_string **tail,
21558 struct glyph_string *h, struct glyph_string *t)
21559 {
21560 if (h)
21561 {
21562 if (*head)
21563 (*tail)->next = h;
21564 else
21565 *head = h;
21566 h->prev = *tail;
21567 *tail = t;
21568 }
21569 }
21570
21571
21572 /* Prepend the list of glyph strings with head H and tail T to the
21573 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
21574 result. */
21575
21576 static inline void
21577 prepend_glyph_string_lists (struct glyph_string **head, struct glyph_string **tail,
21578 struct glyph_string *h, struct glyph_string *t)
21579 {
21580 if (h)
21581 {
21582 if (*head)
21583 (*head)->prev = t;
21584 else
21585 *tail = t;
21586 t->next = *head;
21587 *head = h;
21588 }
21589 }
21590
21591
21592 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
21593 Set *HEAD and *TAIL to the resulting list. */
21594
21595 static inline void
21596 append_glyph_string (struct glyph_string **head, struct glyph_string **tail,
21597 struct glyph_string *s)
21598 {
21599 s->next = s->prev = NULL;
21600 append_glyph_string_lists (head, tail, s, s);
21601 }
21602
21603
21604 /* Get face and two-byte form of character C in face FACE_ID on frame F.
21605 The encoding of C is returned in *CHAR2B. DISPLAY_P non-zero means
21606 make sure that X resources for the face returned are allocated.
21607 Value is a pointer to a realized face that is ready for display if
21608 DISPLAY_P is non-zero. */
21609
21610 static inline struct face *
21611 get_char_face_and_encoding (struct frame *f, int c, int face_id,
21612 XChar2b *char2b, int display_p)
21613 {
21614 struct face *face = FACE_FROM_ID (f, face_id);
21615
21616 if (face->font)
21617 {
21618 unsigned code = face->font->driver->encode_char (face->font, c);
21619
21620 if (code != FONT_INVALID_CODE)
21621 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
21622 else
21623 STORE_XCHAR2B (char2b, 0, 0);
21624 }
21625
21626 /* Make sure X resources of the face are allocated. */
21627 #ifdef HAVE_X_WINDOWS
21628 if (display_p)
21629 #endif
21630 {
21631 xassert (face != NULL);
21632 PREPARE_FACE_FOR_DISPLAY (f, face);
21633 }
21634
21635 return face;
21636 }
21637
21638
21639 /* Get face and two-byte form of character glyph GLYPH on frame F.
21640 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
21641 a pointer to a realized face that is ready for display. */
21642
21643 static inline struct face *
21644 get_glyph_face_and_encoding (struct frame *f, struct glyph *glyph,
21645 XChar2b *char2b, int *two_byte_p)
21646 {
21647 struct face *face;
21648
21649 xassert (glyph->type == CHAR_GLYPH);
21650 face = FACE_FROM_ID (f, glyph->face_id);
21651
21652 if (two_byte_p)
21653 *two_byte_p = 0;
21654
21655 if (face->font)
21656 {
21657 unsigned code;
21658
21659 if (CHAR_BYTE8_P (glyph->u.ch))
21660 code = CHAR_TO_BYTE8 (glyph->u.ch);
21661 else
21662 code = face->font->driver->encode_char (face->font, glyph->u.ch);
21663
21664 if (code != FONT_INVALID_CODE)
21665 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
21666 else
21667 STORE_XCHAR2B (char2b, 0, 0);
21668 }
21669
21670 /* Make sure X resources of the face are allocated. */
21671 xassert (face != NULL);
21672 PREPARE_FACE_FOR_DISPLAY (f, face);
21673 return face;
21674 }
21675
21676
21677 /* Get glyph code of character C in FONT in the two-byte form CHAR2B.
21678 Retunr 1 if FONT has a glyph for C, otherwise return 0. */
21679
21680 static inline int
21681 get_char_glyph_code (int c, struct font *font, XChar2b *char2b)
21682 {
21683 unsigned code;
21684
21685 if (CHAR_BYTE8_P (c))
21686 code = CHAR_TO_BYTE8 (c);
21687 else
21688 code = font->driver->encode_char (font, c);
21689
21690 if (code == FONT_INVALID_CODE)
21691 return 0;
21692 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
21693 return 1;
21694 }
21695
21696
21697 /* Fill glyph string S with composition components specified by S->cmp.
21698
21699 BASE_FACE is the base face of the composition.
21700 S->cmp_from is the index of the first component for S.
21701
21702 OVERLAPS non-zero means S should draw the foreground only, and use
21703 its physical height for clipping. See also draw_glyphs.
21704
21705 Value is the index of a component not in S. */
21706
21707 static int
21708 fill_composite_glyph_string (struct glyph_string *s, struct face *base_face,
21709 int overlaps)
21710 {
21711 int i;
21712 /* For all glyphs of this composition, starting at the offset
21713 S->cmp_from, until we reach the end of the definition or encounter a
21714 glyph that requires the different face, add it to S. */
21715 struct face *face;
21716
21717 xassert (s);
21718
21719 s->for_overlaps = overlaps;
21720 s->face = NULL;
21721 s->font = NULL;
21722 for (i = s->cmp_from; i < s->cmp->glyph_len; i++)
21723 {
21724 int c = COMPOSITION_GLYPH (s->cmp, i);
21725
21726 if (c != '\t')
21727 {
21728 int face_id = FACE_FOR_CHAR (s->f, base_face->ascii_face, c,
21729 -1, Qnil);
21730
21731 face = get_char_face_and_encoding (s->f, c, face_id,
21732 s->char2b + i, 1);
21733 if (face)
21734 {
21735 if (! s->face)
21736 {
21737 s->face = face;
21738 s->font = s->face->font;
21739 }
21740 else if (s->face != face)
21741 break;
21742 }
21743 }
21744 ++s->nchars;
21745 }
21746 s->cmp_to = i;
21747
21748 /* All glyph strings for the same composition has the same width,
21749 i.e. the width set for the first component of the composition. */
21750 s->width = s->first_glyph->pixel_width;
21751
21752 /* If the specified font could not be loaded, use the frame's
21753 default font, but record the fact that we couldn't load it in
21754 the glyph string so that we can draw rectangles for the
21755 characters of the glyph string. */
21756 if (s->font == NULL)
21757 {
21758 s->font_not_found_p = 1;
21759 s->font = FRAME_FONT (s->f);
21760 }
21761
21762 /* Adjust base line for subscript/superscript text. */
21763 s->ybase += s->first_glyph->voffset;
21764
21765 /* This glyph string must always be drawn with 16-bit functions. */
21766 s->two_byte_p = 1;
21767
21768 return s->cmp_to;
21769 }
21770
21771 static int
21772 fill_gstring_glyph_string (struct glyph_string *s, int face_id,
21773 int start, int end, int overlaps)
21774 {
21775 struct glyph *glyph, *last;
21776 Lisp_Object lgstring;
21777 int i;
21778
21779 s->for_overlaps = overlaps;
21780 glyph = s->row->glyphs[s->area] + start;
21781 last = s->row->glyphs[s->area] + end;
21782 s->cmp_id = glyph->u.cmp.id;
21783 s->cmp_from = glyph->slice.cmp.from;
21784 s->cmp_to = glyph->slice.cmp.to + 1;
21785 s->face = FACE_FROM_ID (s->f, face_id);
21786 lgstring = composition_gstring_from_id (s->cmp_id);
21787 s->font = XFONT_OBJECT (LGSTRING_FONT (lgstring));
21788 glyph++;
21789 while (glyph < last
21790 && glyph->u.cmp.automatic
21791 && glyph->u.cmp.id == s->cmp_id
21792 && s->cmp_to == glyph->slice.cmp.from)
21793 s->cmp_to = (glyph++)->slice.cmp.to + 1;
21794
21795 for (i = s->cmp_from; i < s->cmp_to; i++)
21796 {
21797 Lisp_Object lglyph = LGSTRING_GLYPH (lgstring, i);
21798 unsigned code = LGLYPH_CODE (lglyph);
21799
21800 STORE_XCHAR2B ((s->char2b + i), code >> 8, code & 0xFF);
21801 }
21802 s->width = composition_gstring_width (lgstring, s->cmp_from, s->cmp_to, NULL);
21803 return glyph - s->row->glyphs[s->area];
21804 }
21805
21806
21807 /* Fill glyph string S from a sequence glyphs for glyphless characters.
21808 See the comment of fill_glyph_string for arguments.
21809 Value is the index of the first glyph not in S. */
21810
21811
21812 static int
21813 fill_glyphless_glyph_string (struct glyph_string *s, int face_id,
21814 int start, int end, int overlaps)
21815 {
21816 struct glyph *glyph, *last;
21817 int voffset;
21818
21819 xassert (s->first_glyph->type == GLYPHLESS_GLYPH);
21820 s->for_overlaps = overlaps;
21821 glyph = s->row->glyphs[s->area] + start;
21822 last = s->row->glyphs[s->area] + end;
21823 voffset = glyph->voffset;
21824 s->face = FACE_FROM_ID (s->f, face_id);
21825 s->font = s->face->font;
21826 s->nchars = 1;
21827 s->width = glyph->pixel_width;
21828 glyph++;
21829 while (glyph < last
21830 && glyph->type == GLYPHLESS_GLYPH
21831 && glyph->voffset == voffset
21832 && glyph->face_id == face_id)
21833 {
21834 s->nchars++;
21835 s->width += glyph->pixel_width;
21836 glyph++;
21837 }
21838 s->ybase += voffset;
21839 return glyph - s->row->glyphs[s->area];
21840 }
21841
21842
21843 /* Fill glyph string S from a sequence of character glyphs.
21844
21845 FACE_ID is the face id of the string. START is the index of the
21846 first glyph to consider, END is the index of the last + 1.
21847 OVERLAPS non-zero means S should draw the foreground only, and use
21848 its physical height for clipping. See also draw_glyphs.
21849
21850 Value is the index of the first glyph not in S. */
21851
21852 static int
21853 fill_glyph_string (struct glyph_string *s, int face_id,
21854 int start, int end, int overlaps)
21855 {
21856 struct glyph *glyph, *last;
21857 int voffset;
21858 int glyph_not_available_p;
21859
21860 xassert (s->f == XFRAME (s->w->frame));
21861 xassert (s->nchars == 0);
21862 xassert (start >= 0 && end > start);
21863
21864 s->for_overlaps = overlaps;
21865 glyph = s->row->glyphs[s->area] + start;
21866 last = s->row->glyphs[s->area] + end;
21867 voffset = glyph->voffset;
21868 s->padding_p = glyph->padding_p;
21869 glyph_not_available_p = glyph->glyph_not_available_p;
21870
21871 while (glyph < last
21872 && glyph->type == CHAR_GLYPH
21873 && glyph->voffset == voffset
21874 /* Same face id implies same font, nowadays. */
21875 && glyph->face_id == face_id
21876 && glyph->glyph_not_available_p == glyph_not_available_p)
21877 {
21878 int two_byte_p;
21879
21880 s->face = get_glyph_face_and_encoding (s->f, glyph,
21881 s->char2b + s->nchars,
21882 &two_byte_p);
21883 s->two_byte_p = two_byte_p;
21884 ++s->nchars;
21885 xassert (s->nchars <= end - start);
21886 s->width += glyph->pixel_width;
21887 if (glyph++->padding_p != s->padding_p)
21888 break;
21889 }
21890
21891 s->font = s->face->font;
21892
21893 /* If the specified font could not be loaded, use the frame's font,
21894 but record the fact that we couldn't load it in
21895 S->font_not_found_p so that we can draw rectangles for the
21896 characters of the glyph string. */
21897 if (s->font == NULL || glyph_not_available_p)
21898 {
21899 s->font_not_found_p = 1;
21900 s->font = FRAME_FONT (s->f);
21901 }
21902
21903 /* Adjust base line for subscript/superscript text. */
21904 s->ybase += voffset;
21905
21906 xassert (s->face && s->face->gc);
21907 return glyph - s->row->glyphs[s->area];
21908 }
21909
21910
21911 /* Fill glyph string S from image glyph S->first_glyph. */
21912
21913 static void
21914 fill_image_glyph_string (struct glyph_string *s)
21915 {
21916 xassert (s->first_glyph->type == IMAGE_GLYPH);
21917 s->img = IMAGE_FROM_ID (s->f, s->first_glyph->u.img_id);
21918 xassert (s->img);
21919 s->slice = s->first_glyph->slice.img;
21920 s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
21921 s->font = s->face->font;
21922 s->width = s->first_glyph->pixel_width;
21923
21924 /* Adjust base line for subscript/superscript text. */
21925 s->ybase += s->first_glyph->voffset;
21926 }
21927
21928
21929 /* Fill glyph string S from a sequence of stretch glyphs.
21930
21931 START is the index of the first glyph to consider,
21932 END is the index of the last + 1.
21933
21934 Value is the index of the first glyph not in S. */
21935
21936 static int
21937 fill_stretch_glyph_string (struct glyph_string *s, int start, int end)
21938 {
21939 struct glyph *glyph, *last;
21940 int voffset, face_id;
21941
21942 xassert (s->first_glyph->type == STRETCH_GLYPH);
21943
21944 glyph = s->row->glyphs[s->area] + start;
21945 last = s->row->glyphs[s->area] + end;
21946 face_id = glyph->face_id;
21947 s->face = FACE_FROM_ID (s->f, face_id);
21948 s->font = s->face->font;
21949 s->width = glyph->pixel_width;
21950 s->nchars = 1;
21951 voffset = glyph->voffset;
21952
21953 for (++glyph;
21954 (glyph < last
21955 && glyph->type == STRETCH_GLYPH
21956 && glyph->voffset == voffset
21957 && glyph->face_id == face_id);
21958 ++glyph)
21959 s->width += glyph->pixel_width;
21960
21961 /* Adjust base line for subscript/superscript text. */
21962 s->ybase += voffset;
21963
21964 /* The case that face->gc == 0 is handled when drawing the glyph
21965 string by calling PREPARE_FACE_FOR_DISPLAY. */
21966 xassert (s->face);
21967 return glyph - s->row->glyphs[s->area];
21968 }
21969
21970 static struct font_metrics *
21971 get_per_char_metric (struct font *font, XChar2b *char2b)
21972 {
21973 static struct font_metrics metrics;
21974 unsigned code = (XCHAR2B_BYTE1 (char2b) << 8) | XCHAR2B_BYTE2 (char2b);
21975
21976 if (! font || code == FONT_INVALID_CODE)
21977 return NULL;
21978 font->driver->text_extents (font, &code, 1, &metrics);
21979 return &metrics;
21980 }
21981
21982 /* EXPORT for RIF:
21983 Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
21984 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
21985 assumed to be zero. */
21986
21987 void
21988 x_get_glyph_overhangs (struct glyph *glyph, struct frame *f, int *left, int *right)
21989 {
21990 *left = *right = 0;
21991
21992 if (glyph->type == CHAR_GLYPH)
21993 {
21994 struct face *face;
21995 XChar2b char2b;
21996 struct font_metrics *pcm;
21997
21998 face = get_glyph_face_and_encoding (f, glyph, &char2b, NULL);
21999 if (face->font && (pcm = get_per_char_metric (face->font, &char2b)))
22000 {
22001 if (pcm->rbearing > pcm->width)
22002 *right = pcm->rbearing - pcm->width;
22003 if (pcm->lbearing < 0)
22004 *left = -pcm->lbearing;
22005 }
22006 }
22007 else if (glyph->type == COMPOSITE_GLYPH)
22008 {
22009 if (! glyph->u.cmp.automatic)
22010 {
22011 struct composition *cmp = composition_table[glyph->u.cmp.id];
22012
22013 if (cmp->rbearing > cmp->pixel_width)
22014 *right = cmp->rbearing - cmp->pixel_width;
22015 if (cmp->lbearing < 0)
22016 *left = - cmp->lbearing;
22017 }
22018 else
22019 {
22020 Lisp_Object gstring = composition_gstring_from_id (glyph->u.cmp.id);
22021 struct font_metrics metrics;
22022
22023 composition_gstring_width (gstring, glyph->slice.cmp.from,
22024 glyph->slice.cmp.to + 1, &metrics);
22025 if (metrics.rbearing > metrics.width)
22026 *right = metrics.rbearing - metrics.width;
22027 if (metrics.lbearing < 0)
22028 *left = - metrics.lbearing;
22029 }
22030 }
22031 }
22032
22033
22034 /* Return the index of the first glyph preceding glyph string S that
22035 is overwritten by S because of S's left overhang. Value is -1
22036 if no glyphs are overwritten. */
22037
22038 static int
22039 left_overwritten (struct glyph_string *s)
22040 {
22041 int k;
22042
22043 if (s->left_overhang)
22044 {
22045 int x = 0, i;
22046 struct glyph *glyphs = s->row->glyphs[s->area];
22047 int first = s->first_glyph - glyphs;
22048
22049 for (i = first - 1; i >= 0 && x > -s->left_overhang; --i)
22050 x -= glyphs[i].pixel_width;
22051
22052 k = i + 1;
22053 }
22054 else
22055 k = -1;
22056
22057 return k;
22058 }
22059
22060
22061 /* Return the index of the first glyph preceding glyph string S that
22062 is overwriting S because of its right overhang. Value is -1 if no
22063 glyph in front of S overwrites S. */
22064
22065 static int
22066 left_overwriting (struct glyph_string *s)
22067 {
22068 int i, k, x;
22069 struct glyph *glyphs = s->row->glyphs[s->area];
22070 int first = s->first_glyph - glyphs;
22071
22072 k = -1;
22073 x = 0;
22074 for (i = first - 1; i >= 0; --i)
22075 {
22076 int left, right;
22077 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
22078 if (x + right > 0)
22079 k = i;
22080 x -= glyphs[i].pixel_width;
22081 }
22082
22083 return k;
22084 }
22085
22086
22087 /* Return the index of the last glyph following glyph string S that is
22088 overwritten by S because of S's right overhang. Value is -1 if
22089 no such glyph is found. */
22090
22091 static int
22092 right_overwritten (struct glyph_string *s)
22093 {
22094 int k = -1;
22095
22096 if (s->right_overhang)
22097 {
22098 int x = 0, i;
22099 struct glyph *glyphs = s->row->glyphs[s->area];
22100 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
22101 int end = s->row->used[s->area];
22102
22103 for (i = first; i < end && s->right_overhang > x; ++i)
22104 x += glyphs[i].pixel_width;
22105
22106 k = i;
22107 }
22108
22109 return k;
22110 }
22111
22112
22113 /* Return the index of the last glyph following glyph string S that
22114 overwrites S because of its left overhang. Value is negative
22115 if no such glyph is found. */
22116
22117 static int
22118 right_overwriting (struct glyph_string *s)
22119 {
22120 int i, k, x;
22121 int end = s->row->used[s->area];
22122 struct glyph *glyphs = s->row->glyphs[s->area];
22123 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
22124
22125 k = -1;
22126 x = 0;
22127 for (i = first; i < end; ++i)
22128 {
22129 int left, right;
22130 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
22131 if (x - left < 0)
22132 k = i;
22133 x += glyphs[i].pixel_width;
22134 }
22135
22136 return k;
22137 }
22138
22139
22140 /* Set background width of glyph string S. START is the index of the
22141 first glyph following S. LAST_X is the right-most x-position + 1
22142 in the drawing area. */
22143
22144 static inline void
22145 set_glyph_string_background_width (struct glyph_string *s, int start, int last_x)
22146 {
22147 /* If the face of this glyph string has to be drawn to the end of
22148 the drawing area, set S->extends_to_end_of_line_p. */
22149
22150 if (start == s->row->used[s->area]
22151 && s->area == TEXT_AREA
22152 && ((s->row->fill_line_p
22153 && (s->hl == DRAW_NORMAL_TEXT
22154 || s->hl == DRAW_IMAGE_RAISED
22155 || s->hl == DRAW_IMAGE_SUNKEN))
22156 || s->hl == DRAW_MOUSE_FACE))
22157 s->extends_to_end_of_line_p = 1;
22158
22159 /* If S extends its face to the end of the line, set its
22160 background_width to the distance to the right edge of the drawing
22161 area. */
22162 if (s->extends_to_end_of_line_p)
22163 s->background_width = last_x - s->x + 1;
22164 else
22165 s->background_width = s->width;
22166 }
22167
22168
22169 /* Compute overhangs and x-positions for glyph string S and its
22170 predecessors, or successors. X is the starting x-position for S.
22171 BACKWARD_P non-zero means process predecessors. */
22172
22173 static void
22174 compute_overhangs_and_x (struct glyph_string *s, int x, int backward_p)
22175 {
22176 if (backward_p)
22177 {
22178 while (s)
22179 {
22180 if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
22181 FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
22182 x -= s->width;
22183 s->x = x;
22184 s = s->prev;
22185 }
22186 }
22187 else
22188 {
22189 while (s)
22190 {
22191 if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
22192 FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
22193 s->x = x;
22194 x += s->width;
22195 s = s->next;
22196 }
22197 }
22198 }
22199
22200
22201
22202 /* The following macros are only called from draw_glyphs below.
22203 They reference the following parameters of that function directly:
22204 `w', `row', `area', and `overlap_p'
22205 as well as the following local variables:
22206 `s', `f', and `hdc' (in W32) */
22207
22208 #ifdef HAVE_NTGUI
22209 /* On W32, silently add local `hdc' variable to argument list of
22210 init_glyph_string. */
22211 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
22212 init_glyph_string (s, hdc, char2b, w, row, area, start, hl)
22213 #else
22214 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
22215 init_glyph_string (s, char2b, w, row, area, start, hl)
22216 #endif
22217
22218 /* Add a glyph string for a stretch glyph to the list of strings
22219 between HEAD and TAIL. START is the index of the stretch glyph in
22220 row area AREA of glyph row ROW. END is the index of the last glyph
22221 in that glyph row area. X is the current output position assigned
22222 to the new glyph string constructed. HL overrides that face of the
22223 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
22224 is the right-most x-position of the drawing area. */
22225
22226 /* SunOS 4 bundled cc, barfed on continuations in the arg lists here
22227 and below -- keep them on one line. */
22228 #define BUILD_STRETCH_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
22229 do \
22230 { \
22231 s = (struct glyph_string *) alloca (sizeof *s); \
22232 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
22233 START = fill_stretch_glyph_string (s, START, END); \
22234 append_glyph_string (&HEAD, &TAIL, s); \
22235 s->x = (X); \
22236 } \
22237 while (0)
22238
22239
22240 /* Add a glyph string for an image glyph to the list of strings
22241 between HEAD and TAIL. START is the index of the image glyph in
22242 row area AREA of glyph row ROW. END is the index of the last glyph
22243 in that glyph row area. X is the current output position assigned
22244 to the new glyph string constructed. HL overrides that face of the
22245 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
22246 is the right-most x-position of the drawing area. */
22247
22248 #define BUILD_IMAGE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
22249 do \
22250 { \
22251 s = (struct glyph_string *) alloca (sizeof *s); \
22252 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
22253 fill_image_glyph_string (s); \
22254 append_glyph_string (&HEAD, &TAIL, s); \
22255 ++START; \
22256 s->x = (X); \
22257 } \
22258 while (0)
22259
22260
22261 /* Add a glyph string for a sequence of character glyphs to the list
22262 of strings between HEAD and TAIL. START is the index of the first
22263 glyph in row area AREA of glyph row ROW that is part of the new
22264 glyph string. END is the index of the last glyph in that glyph row
22265 area. X is the current output position assigned to the new glyph
22266 string constructed. HL overrides that face of the glyph; e.g. it
22267 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
22268 right-most x-position of the drawing area. */
22269
22270 #define BUILD_CHAR_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
22271 do \
22272 { \
22273 int face_id; \
22274 XChar2b *char2b; \
22275 \
22276 face_id = (row)->glyphs[area][START].face_id; \
22277 \
22278 s = (struct glyph_string *) alloca (sizeof *s); \
22279 char2b = (XChar2b *) alloca ((END - START) * sizeof *char2b); \
22280 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
22281 append_glyph_string (&HEAD, &TAIL, s); \
22282 s->x = (X); \
22283 START = fill_glyph_string (s, face_id, START, END, overlaps); \
22284 } \
22285 while (0)
22286
22287
22288 /* Add a glyph string for a composite sequence to the list of strings
22289 between HEAD and TAIL. START is the index of the first glyph in
22290 row area AREA of glyph row ROW that is part of the new glyph
22291 string. END is the index of the last glyph in that glyph row area.
22292 X is the current output position assigned to the new glyph string
22293 constructed. HL overrides that face of the glyph; e.g. it is
22294 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
22295 x-position of the drawing area. */
22296
22297 #define BUILD_COMPOSITE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
22298 do { \
22299 int face_id = (row)->glyphs[area][START].face_id; \
22300 struct face *base_face = FACE_FROM_ID (f, face_id); \
22301 ptrdiff_t cmp_id = (row)->glyphs[area][START].u.cmp.id; \
22302 struct composition *cmp = composition_table[cmp_id]; \
22303 XChar2b *char2b; \
22304 struct glyph_string *first_s IF_LINT (= NULL); \
22305 int n; \
22306 \
22307 char2b = (XChar2b *) alloca ((sizeof *char2b) * cmp->glyph_len); \
22308 \
22309 /* Make glyph_strings for each glyph sequence that is drawable by \
22310 the same face, and append them to HEAD/TAIL. */ \
22311 for (n = 0; n < cmp->glyph_len;) \
22312 { \
22313 s = (struct glyph_string *) alloca (sizeof *s); \
22314 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
22315 append_glyph_string (&(HEAD), &(TAIL), s); \
22316 s->cmp = cmp; \
22317 s->cmp_from = n; \
22318 s->x = (X); \
22319 if (n == 0) \
22320 first_s = s; \
22321 n = fill_composite_glyph_string (s, base_face, overlaps); \
22322 } \
22323 \
22324 ++START; \
22325 s = first_s; \
22326 } while (0)
22327
22328
22329 /* Add a glyph string for a glyph-string sequence to the list of strings
22330 between HEAD and TAIL. */
22331
22332 #define BUILD_GSTRING_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
22333 do { \
22334 int face_id; \
22335 XChar2b *char2b; \
22336 Lisp_Object gstring; \
22337 \
22338 face_id = (row)->glyphs[area][START].face_id; \
22339 gstring = (composition_gstring_from_id \
22340 ((row)->glyphs[area][START].u.cmp.id)); \
22341 s = (struct glyph_string *) alloca (sizeof *s); \
22342 char2b = (XChar2b *) alloca ((sizeof *char2b) \
22343 * LGSTRING_GLYPH_LEN (gstring)); \
22344 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
22345 append_glyph_string (&(HEAD), &(TAIL), s); \
22346 s->x = (X); \
22347 START = fill_gstring_glyph_string (s, face_id, START, END, overlaps); \
22348 } while (0)
22349
22350
22351 /* Add a glyph string for a sequence of glyphless character's glyphs
22352 to the list of strings between HEAD and TAIL. The meanings of
22353 arguments are the same as those of BUILD_CHAR_GLYPH_STRINGS. */
22354
22355 #define BUILD_GLYPHLESS_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
22356 do \
22357 { \
22358 int face_id; \
22359 \
22360 face_id = (row)->glyphs[area][START].face_id; \
22361 \
22362 s = (struct glyph_string *) alloca (sizeof *s); \
22363 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
22364 append_glyph_string (&HEAD, &TAIL, s); \
22365 s->x = (X); \
22366 START = fill_glyphless_glyph_string (s, face_id, START, END, \
22367 overlaps); \
22368 } \
22369 while (0)
22370
22371
22372 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
22373 of AREA of glyph row ROW on window W between indices START and END.
22374 HL overrides the face for drawing glyph strings, e.g. it is
22375 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
22376 x-positions of the drawing area.
22377
22378 This is an ugly monster macro construct because we must use alloca
22379 to allocate glyph strings (because draw_glyphs can be called
22380 asynchronously). */
22381
22382 #define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
22383 do \
22384 { \
22385 HEAD = TAIL = NULL; \
22386 while (START < END) \
22387 { \
22388 struct glyph *first_glyph = (row)->glyphs[area] + START; \
22389 switch (first_glyph->type) \
22390 { \
22391 case CHAR_GLYPH: \
22392 BUILD_CHAR_GLYPH_STRINGS (START, END, HEAD, TAIL, \
22393 HL, X, LAST_X); \
22394 break; \
22395 \
22396 case COMPOSITE_GLYPH: \
22397 if (first_glyph->u.cmp.automatic) \
22398 BUILD_GSTRING_GLYPH_STRING (START, END, HEAD, TAIL, \
22399 HL, X, LAST_X); \
22400 else \
22401 BUILD_COMPOSITE_GLYPH_STRING (START, END, HEAD, TAIL, \
22402 HL, X, LAST_X); \
22403 break; \
22404 \
22405 case STRETCH_GLYPH: \
22406 BUILD_STRETCH_GLYPH_STRING (START, END, HEAD, TAIL, \
22407 HL, X, LAST_X); \
22408 break; \
22409 \
22410 case IMAGE_GLYPH: \
22411 BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL, \
22412 HL, X, LAST_X); \
22413 break; \
22414 \
22415 case GLYPHLESS_GLYPH: \
22416 BUILD_GLYPHLESS_GLYPH_STRING (START, END, HEAD, TAIL, \
22417 HL, X, LAST_X); \
22418 break; \
22419 \
22420 default: \
22421 abort (); \
22422 } \
22423 \
22424 if (s) \
22425 { \
22426 set_glyph_string_background_width (s, START, LAST_X); \
22427 (X) += s->width; \
22428 } \
22429 } \
22430 } while (0)
22431
22432
22433 /* Draw glyphs between START and END in AREA of ROW on window W,
22434 starting at x-position X. X is relative to AREA in W. HL is a
22435 face-override with the following meaning:
22436
22437 DRAW_NORMAL_TEXT draw normally
22438 DRAW_CURSOR draw in cursor face
22439 DRAW_MOUSE_FACE draw in mouse face.
22440 DRAW_INVERSE_VIDEO draw in mode line face
22441 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
22442 DRAW_IMAGE_RAISED draw an image with a raised relief around it
22443
22444 If OVERLAPS is non-zero, draw only the foreground of characters and
22445 clip to the physical height of ROW. Non-zero value also defines
22446 the overlapping part to be drawn:
22447
22448 OVERLAPS_PRED overlap with preceding rows
22449 OVERLAPS_SUCC overlap with succeeding rows
22450 OVERLAPS_BOTH overlap with both preceding/succeeding rows
22451 OVERLAPS_ERASED_CURSOR overlap with erased cursor area
22452
22453 Value is the x-position reached, relative to AREA of W. */
22454
22455 static int
22456 draw_glyphs (struct window *w, int x, struct glyph_row *row,
22457 enum glyph_row_area area, EMACS_INT start, EMACS_INT end,
22458 enum draw_glyphs_face hl, int overlaps)
22459 {
22460 struct glyph_string *head, *tail;
22461 struct glyph_string *s;
22462 struct glyph_string *clip_head = NULL, *clip_tail = NULL;
22463 int i, j, x_reached, last_x, area_left = 0;
22464 struct frame *f = XFRAME (WINDOW_FRAME (w));
22465 DECLARE_HDC (hdc);
22466
22467 ALLOCATE_HDC (hdc, f);
22468
22469 /* Let's rather be paranoid than getting a SEGV. */
22470 end = min (end, row->used[area]);
22471 start = max (0, start);
22472 start = min (end, start);
22473
22474 /* Translate X to frame coordinates. Set last_x to the right
22475 end of the drawing area. */
22476 if (row->full_width_p)
22477 {
22478 /* X is relative to the left edge of W, without scroll bars
22479 or fringes. */
22480 area_left = WINDOW_LEFT_EDGE_X (w);
22481 last_x = WINDOW_LEFT_EDGE_X (w) + WINDOW_TOTAL_WIDTH (w);
22482 }
22483 else
22484 {
22485 area_left = window_box_left (w, area);
22486 last_x = area_left + window_box_width (w, area);
22487 }
22488 x += area_left;
22489
22490 /* Build a doubly-linked list of glyph_string structures between
22491 head and tail from what we have to draw. Note that the macro
22492 BUILD_GLYPH_STRINGS will modify its start parameter. That's
22493 the reason we use a separate variable `i'. */
22494 i = start;
22495 BUILD_GLYPH_STRINGS (i, end, head, tail, hl, x, last_x);
22496 if (tail)
22497 x_reached = tail->x + tail->background_width;
22498 else
22499 x_reached = x;
22500
22501 /* If there are any glyphs with lbearing < 0 or rbearing > width in
22502 the row, redraw some glyphs in front or following the glyph
22503 strings built above. */
22504 if (head && !overlaps && row->contains_overlapping_glyphs_p)
22505 {
22506 struct glyph_string *h, *t;
22507 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
22508 int mouse_beg_col IF_LINT (= 0), mouse_end_col IF_LINT (= 0);
22509 int check_mouse_face = 0;
22510 int dummy_x = 0;
22511
22512 /* If mouse highlighting is on, we may need to draw adjacent
22513 glyphs using mouse-face highlighting. */
22514 if (area == TEXT_AREA && row->mouse_face_p)
22515 {
22516 struct glyph_row *mouse_beg_row, *mouse_end_row;
22517
22518 mouse_beg_row = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_beg_row);
22519 mouse_end_row = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_end_row);
22520
22521 if (row >= mouse_beg_row && row <= mouse_end_row)
22522 {
22523 check_mouse_face = 1;
22524 mouse_beg_col = (row == mouse_beg_row)
22525 ? hlinfo->mouse_face_beg_col : 0;
22526 mouse_end_col = (row == mouse_end_row)
22527 ? hlinfo->mouse_face_end_col
22528 : row->used[TEXT_AREA];
22529 }
22530 }
22531
22532 /* Compute overhangs for all glyph strings. */
22533 if (FRAME_RIF (f)->compute_glyph_string_overhangs)
22534 for (s = head; s; s = s->next)
22535 FRAME_RIF (f)->compute_glyph_string_overhangs (s);
22536
22537 /* Prepend glyph strings for glyphs in front of the first glyph
22538 string that are overwritten because of the first glyph
22539 string's left overhang. The background of all strings
22540 prepended must be drawn because the first glyph string
22541 draws over it. */
22542 i = left_overwritten (head);
22543 if (i >= 0)
22544 {
22545 enum draw_glyphs_face overlap_hl;
22546
22547 /* If this row contains mouse highlighting, attempt to draw
22548 the overlapped glyphs with the correct highlight. This
22549 code fails if the overlap encompasses more than one glyph
22550 and mouse-highlight spans only some of these glyphs.
22551 However, making it work perfectly involves a lot more
22552 code, and I don't know if the pathological case occurs in
22553 practice, so we'll stick to this for now. --- cyd */
22554 if (check_mouse_face
22555 && mouse_beg_col < start && mouse_end_col > i)
22556 overlap_hl = DRAW_MOUSE_FACE;
22557 else
22558 overlap_hl = DRAW_NORMAL_TEXT;
22559
22560 j = i;
22561 BUILD_GLYPH_STRINGS (j, start, h, t,
22562 overlap_hl, dummy_x, last_x);
22563 start = i;
22564 compute_overhangs_and_x (t, head->x, 1);
22565 prepend_glyph_string_lists (&head, &tail, h, t);
22566 clip_head = head;
22567 }
22568
22569 /* Prepend glyph strings for glyphs in front of the first glyph
22570 string that overwrite that glyph string because of their
22571 right overhang. For these strings, only the foreground must
22572 be drawn, because it draws over the glyph string at `head'.
22573 The background must not be drawn because this would overwrite
22574 right overhangs of preceding glyphs for which no glyph
22575 strings exist. */
22576 i = left_overwriting (head);
22577 if (i >= 0)
22578 {
22579 enum draw_glyphs_face overlap_hl;
22580
22581 if (check_mouse_face
22582 && mouse_beg_col < start && mouse_end_col > i)
22583 overlap_hl = DRAW_MOUSE_FACE;
22584 else
22585 overlap_hl = DRAW_NORMAL_TEXT;
22586
22587 clip_head = head;
22588 BUILD_GLYPH_STRINGS (i, start, h, t,
22589 overlap_hl, dummy_x, last_x);
22590 for (s = h; s; s = s->next)
22591 s->background_filled_p = 1;
22592 compute_overhangs_and_x (t, head->x, 1);
22593 prepend_glyph_string_lists (&head, &tail, h, t);
22594 }
22595
22596 /* Append glyphs strings for glyphs following the last glyph
22597 string tail that are overwritten by tail. The background of
22598 these strings has to be drawn because tail's foreground draws
22599 over it. */
22600 i = right_overwritten (tail);
22601 if (i >= 0)
22602 {
22603 enum draw_glyphs_face overlap_hl;
22604
22605 if (check_mouse_face
22606 && mouse_beg_col < i && mouse_end_col > end)
22607 overlap_hl = DRAW_MOUSE_FACE;
22608 else
22609 overlap_hl = DRAW_NORMAL_TEXT;
22610
22611 BUILD_GLYPH_STRINGS (end, i, h, t,
22612 overlap_hl, x, last_x);
22613 /* Because BUILD_GLYPH_STRINGS updates the first argument,
22614 we don't have `end = i;' here. */
22615 compute_overhangs_and_x (h, tail->x + tail->width, 0);
22616 append_glyph_string_lists (&head, &tail, h, t);
22617 clip_tail = tail;
22618 }
22619
22620 /* Append glyph strings for glyphs following the last glyph
22621 string tail that overwrite tail. The foreground of such
22622 glyphs has to be drawn because it writes into the background
22623 of tail. The background must not be drawn because it could
22624 paint over the foreground of following glyphs. */
22625 i = right_overwriting (tail);
22626 if (i >= 0)
22627 {
22628 enum draw_glyphs_face overlap_hl;
22629 if (check_mouse_face
22630 && mouse_beg_col < i && mouse_end_col > end)
22631 overlap_hl = DRAW_MOUSE_FACE;
22632 else
22633 overlap_hl = DRAW_NORMAL_TEXT;
22634
22635 clip_tail = tail;
22636 i++; /* We must include the Ith glyph. */
22637 BUILD_GLYPH_STRINGS (end, i, h, t,
22638 overlap_hl, x, last_x);
22639 for (s = h; s; s = s->next)
22640 s->background_filled_p = 1;
22641 compute_overhangs_and_x (h, tail->x + tail->width, 0);
22642 append_glyph_string_lists (&head, &tail, h, t);
22643 }
22644 if (clip_head || clip_tail)
22645 for (s = head; s; s = s->next)
22646 {
22647 s->clip_head = clip_head;
22648 s->clip_tail = clip_tail;
22649 }
22650 }
22651
22652 /* Draw all strings. */
22653 for (s = head; s; s = s->next)
22654 FRAME_RIF (f)->draw_glyph_string (s);
22655
22656 #ifndef HAVE_NS
22657 /* When focus a sole frame and move horizontally, this sets on_p to 0
22658 causing a failure to erase prev cursor position. */
22659 if (area == TEXT_AREA
22660 && !row->full_width_p
22661 /* When drawing overlapping rows, only the glyph strings'
22662 foreground is drawn, which doesn't erase a cursor
22663 completely. */
22664 && !overlaps)
22665 {
22666 int x0 = clip_head ? clip_head->x : (head ? head->x : x);
22667 int x1 = (clip_tail ? clip_tail->x + clip_tail->background_width
22668 : (tail ? tail->x + tail->background_width : x));
22669 x0 -= area_left;
22670 x1 -= area_left;
22671
22672 notice_overwritten_cursor (w, TEXT_AREA, x0, x1,
22673 row->y, MATRIX_ROW_BOTTOM_Y (row));
22674 }
22675 #endif
22676
22677 /* Value is the x-position up to which drawn, relative to AREA of W.
22678 This doesn't include parts drawn because of overhangs. */
22679 if (row->full_width_p)
22680 x_reached = FRAME_TO_WINDOW_PIXEL_X (w, x_reached);
22681 else
22682 x_reached -= area_left;
22683
22684 RELEASE_HDC (hdc, f);
22685
22686 return x_reached;
22687 }
22688
22689 /* Expand row matrix if too narrow. Don't expand if area
22690 is not present. */
22691
22692 #define IT_EXPAND_MATRIX_WIDTH(it, area) \
22693 { \
22694 if (!fonts_changed_p \
22695 && (it->glyph_row->glyphs[area] \
22696 < it->glyph_row->glyphs[area + 1])) \
22697 { \
22698 it->w->ncols_scale_factor++; \
22699 fonts_changed_p = 1; \
22700 } \
22701 }
22702
22703 /* Store one glyph for IT->char_to_display in IT->glyph_row.
22704 Called from x_produce_glyphs when IT->glyph_row is non-null. */
22705
22706 static inline void
22707 append_glyph (struct it *it)
22708 {
22709 struct glyph *glyph;
22710 enum glyph_row_area area = it->area;
22711
22712 xassert (it->glyph_row);
22713 xassert (it->char_to_display != '\n' && it->char_to_display != '\t');
22714
22715 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
22716 if (glyph < it->glyph_row->glyphs[area + 1])
22717 {
22718 /* If the glyph row is reversed, we need to prepend the glyph
22719 rather than append it. */
22720 if (it->glyph_row->reversed_p && area == TEXT_AREA)
22721 {
22722 struct glyph *g;
22723
22724 /* Make room for the additional glyph. */
22725 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
22726 g[1] = *g;
22727 glyph = it->glyph_row->glyphs[area];
22728 }
22729 glyph->charpos = CHARPOS (it->position);
22730 glyph->object = it->object;
22731 if (it->pixel_width > 0)
22732 {
22733 glyph->pixel_width = it->pixel_width;
22734 glyph->padding_p = 0;
22735 }
22736 else
22737 {
22738 /* Assure at least 1-pixel width. Otherwise, cursor can't
22739 be displayed correctly. */
22740 glyph->pixel_width = 1;
22741 glyph->padding_p = 1;
22742 }
22743 glyph->ascent = it->ascent;
22744 glyph->descent = it->descent;
22745 glyph->voffset = it->voffset;
22746 glyph->type = CHAR_GLYPH;
22747 glyph->avoid_cursor_p = it->avoid_cursor_p;
22748 glyph->multibyte_p = it->multibyte_p;
22749 glyph->left_box_line_p = it->start_of_box_run_p;
22750 glyph->right_box_line_p = it->end_of_box_run_p;
22751 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
22752 || it->phys_descent > it->descent);
22753 glyph->glyph_not_available_p = it->glyph_not_available_p;
22754 glyph->face_id = it->face_id;
22755 glyph->u.ch = it->char_to_display;
22756 glyph->slice.img = null_glyph_slice;
22757 glyph->font_type = FONT_TYPE_UNKNOWN;
22758 if (it->bidi_p)
22759 {
22760 glyph->resolved_level = it->bidi_it.resolved_level;
22761 if ((it->bidi_it.type & 7) != it->bidi_it.type)
22762 abort ();
22763 glyph->bidi_type = it->bidi_it.type;
22764 }
22765 else
22766 {
22767 glyph->resolved_level = 0;
22768 glyph->bidi_type = UNKNOWN_BT;
22769 }
22770 ++it->glyph_row->used[area];
22771 }
22772 else
22773 IT_EXPAND_MATRIX_WIDTH (it, area);
22774 }
22775
22776 /* Store one glyph for the composition IT->cmp_it.id in
22777 IT->glyph_row. Called from x_produce_glyphs when IT->glyph_row is
22778 non-null. */
22779
22780 static inline void
22781 append_composite_glyph (struct it *it)
22782 {
22783 struct glyph *glyph;
22784 enum glyph_row_area area = it->area;
22785
22786 xassert (it->glyph_row);
22787
22788 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
22789 if (glyph < it->glyph_row->glyphs[area + 1])
22790 {
22791 /* If the glyph row is reversed, we need to prepend the glyph
22792 rather than append it. */
22793 if (it->glyph_row->reversed_p && it->area == TEXT_AREA)
22794 {
22795 struct glyph *g;
22796
22797 /* Make room for the new glyph. */
22798 for (g = glyph - 1; g >= it->glyph_row->glyphs[it->area]; g--)
22799 g[1] = *g;
22800 glyph = it->glyph_row->glyphs[it->area];
22801 }
22802 glyph->charpos = it->cmp_it.charpos;
22803 glyph->object = it->object;
22804 glyph->pixel_width = it->pixel_width;
22805 glyph->ascent = it->ascent;
22806 glyph->descent = it->descent;
22807 glyph->voffset = it->voffset;
22808 glyph->type = COMPOSITE_GLYPH;
22809 if (it->cmp_it.ch < 0)
22810 {
22811 glyph->u.cmp.automatic = 0;
22812 glyph->u.cmp.id = it->cmp_it.id;
22813 glyph->slice.cmp.from = glyph->slice.cmp.to = 0;
22814 }
22815 else
22816 {
22817 glyph->u.cmp.automatic = 1;
22818 glyph->u.cmp.id = it->cmp_it.id;
22819 glyph->slice.cmp.from = it->cmp_it.from;
22820 glyph->slice.cmp.to = it->cmp_it.to - 1;
22821 }
22822 glyph->avoid_cursor_p = it->avoid_cursor_p;
22823 glyph->multibyte_p = it->multibyte_p;
22824 glyph->left_box_line_p = it->start_of_box_run_p;
22825 glyph->right_box_line_p = it->end_of_box_run_p;
22826 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
22827 || it->phys_descent > it->descent);
22828 glyph->padding_p = 0;
22829 glyph->glyph_not_available_p = 0;
22830 glyph->face_id = it->face_id;
22831 glyph->font_type = FONT_TYPE_UNKNOWN;
22832 if (it->bidi_p)
22833 {
22834 glyph->resolved_level = it->bidi_it.resolved_level;
22835 if ((it->bidi_it.type & 7) != it->bidi_it.type)
22836 abort ();
22837 glyph->bidi_type = it->bidi_it.type;
22838 }
22839 ++it->glyph_row->used[area];
22840 }
22841 else
22842 IT_EXPAND_MATRIX_WIDTH (it, area);
22843 }
22844
22845
22846 /* Change IT->ascent and IT->height according to the setting of
22847 IT->voffset. */
22848
22849 static inline void
22850 take_vertical_position_into_account (struct it *it)
22851 {
22852 if (it->voffset)
22853 {
22854 if (it->voffset < 0)
22855 /* Increase the ascent so that we can display the text higher
22856 in the line. */
22857 it->ascent -= it->voffset;
22858 else
22859 /* Increase the descent so that we can display the text lower
22860 in the line. */
22861 it->descent += it->voffset;
22862 }
22863 }
22864
22865
22866 /* Produce glyphs/get display metrics for the image IT is loaded with.
22867 See the description of struct display_iterator in dispextern.h for
22868 an overview of struct display_iterator. */
22869
22870 static void
22871 produce_image_glyph (struct it *it)
22872 {
22873 struct image *img;
22874 struct face *face;
22875 int glyph_ascent, crop;
22876 struct glyph_slice slice;
22877
22878 xassert (it->what == IT_IMAGE);
22879
22880 face = FACE_FROM_ID (it->f, it->face_id);
22881 xassert (face);
22882 /* Make sure X resources of the face is loaded. */
22883 PREPARE_FACE_FOR_DISPLAY (it->f, face);
22884
22885 if (it->image_id < 0)
22886 {
22887 /* Fringe bitmap. */
22888 it->ascent = it->phys_ascent = 0;
22889 it->descent = it->phys_descent = 0;
22890 it->pixel_width = 0;
22891 it->nglyphs = 0;
22892 return;
22893 }
22894
22895 img = IMAGE_FROM_ID (it->f, it->image_id);
22896 xassert (img);
22897 /* Make sure X resources of the image is loaded. */
22898 prepare_image_for_display (it->f, img);
22899
22900 slice.x = slice.y = 0;
22901 slice.width = img->width;
22902 slice.height = img->height;
22903
22904 if (INTEGERP (it->slice.x))
22905 slice.x = XINT (it->slice.x);
22906 else if (FLOATP (it->slice.x))
22907 slice.x = XFLOAT_DATA (it->slice.x) * img->width;
22908
22909 if (INTEGERP (it->slice.y))
22910 slice.y = XINT (it->slice.y);
22911 else if (FLOATP (it->slice.y))
22912 slice.y = XFLOAT_DATA (it->slice.y) * img->height;
22913
22914 if (INTEGERP (it->slice.width))
22915 slice.width = XINT (it->slice.width);
22916 else if (FLOATP (it->slice.width))
22917 slice.width = XFLOAT_DATA (it->slice.width) * img->width;
22918
22919 if (INTEGERP (it->slice.height))
22920 slice.height = XINT (it->slice.height);
22921 else if (FLOATP (it->slice.height))
22922 slice.height = XFLOAT_DATA (it->slice.height) * img->height;
22923
22924 if (slice.x >= img->width)
22925 slice.x = img->width;
22926 if (slice.y >= img->height)
22927 slice.y = img->height;
22928 if (slice.x + slice.width >= img->width)
22929 slice.width = img->width - slice.x;
22930 if (slice.y + slice.height > img->height)
22931 slice.height = img->height - slice.y;
22932
22933 if (slice.width == 0 || slice.height == 0)
22934 return;
22935
22936 it->ascent = it->phys_ascent = glyph_ascent = image_ascent (img, face, &slice);
22937
22938 it->descent = slice.height - glyph_ascent;
22939 if (slice.y == 0)
22940 it->descent += img->vmargin;
22941 if (slice.y + slice.height == img->height)
22942 it->descent += img->vmargin;
22943 it->phys_descent = it->descent;
22944
22945 it->pixel_width = slice.width;
22946 if (slice.x == 0)
22947 it->pixel_width += img->hmargin;
22948 if (slice.x + slice.width == img->width)
22949 it->pixel_width += img->hmargin;
22950
22951 /* It's quite possible for images to have an ascent greater than
22952 their height, so don't get confused in that case. */
22953 if (it->descent < 0)
22954 it->descent = 0;
22955
22956 it->nglyphs = 1;
22957
22958 if (face->box != FACE_NO_BOX)
22959 {
22960 if (face->box_line_width > 0)
22961 {
22962 if (slice.y == 0)
22963 it->ascent += face->box_line_width;
22964 if (slice.y + slice.height == img->height)
22965 it->descent += face->box_line_width;
22966 }
22967
22968 if (it->start_of_box_run_p && slice.x == 0)
22969 it->pixel_width += eabs (face->box_line_width);
22970 if (it->end_of_box_run_p && slice.x + slice.width == img->width)
22971 it->pixel_width += eabs (face->box_line_width);
22972 }
22973
22974 take_vertical_position_into_account (it);
22975
22976 /* Automatically crop wide image glyphs at right edge so we can
22977 draw the cursor on same display row. */
22978 if ((crop = it->pixel_width - (it->last_visible_x - it->current_x), crop > 0)
22979 && (it->hpos == 0 || it->pixel_width > it->last_visible_x / 4))
22980 {
22981 it->pixel_width -= crop;
22982 slice.width -= crop;
22983 }
22984
22985 if (it->glyph_row)
22986 {
22987 struct glyph *glyph;
22988 enum glyph_row_area area = it->area;
22989
22990 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
22991 if (glyph < it->glyph_row->glyphs[area + 1])
22992 {
22993 glyph->charpos = CHARPOS (it->position);
22994 glyph->object = it->object;
22995 glyph->pixel_width = it->pixel_width;
22996 glyph->ascent = glyph_ascent;
22997 glyph->descent = it->descent;
22998 glyph->voffset = it->voffset;
22999 glyph->type = IMAGE_GLYPH;
23000 glyph->avoid_cursor_p = it->avoid_cursor_p;
23001 glyph->multibyte_p = it->multibyte_p;
23002 glyph->left_box_line_p = it->start_of_box_run_p;
23003 glyph->right_box_line_p = it->end_of_box_run_p;
23004 glyph->overlaps_vertically_p = 0;
23005 glyph->padding_p = 0;
23006 glyph->glyph_not_available_p = 0;
23007 glyph->face_id = it->face_id;
23008 glyph->u.img_id = img->id;
23009 glyph->slice.img = slice;
23010 glyph->font_type = FONT_TYPE_UNKNOWN;
23011 if (it->bidi_p)
23012 {
23013 glyph->resolved_level = it->bidi_it.resolved_level;
23014 if ((it->bidi_it.type & 7) != it->bidi_it.type)
23015 abort ();
23016 glyph->bidi_type = it->bidi_it.type;
23017 }
23018 ++it->glyph_row->used[area];
23019 }
23020 else
23021 IT_EXPAND_MATRIX_WIDTH (it, area);
23022 }
23023 }
23024
23025
23026 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
23027 of the glyph, WIDTH and HEIGHT are the width and height of the
23028 stretch. ASCENT is the ascent of the glyph (0 <= ASCENT <= HEIGHT). */
23029
23030 static void
23031 append_stretch_glyph (struct it *it, Lisp_Object object,
23032 int width, int height, int ascent)
23033 {
23034 struct glyph *glyph;
23035 enum glyph_row_area area = it->area;
23036
23037 xassert (ascent >= 0 && ascent <= height);
23038
23039 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
23040 if (glyph < it->glyph_row->glyphs[area + 1])
23041 {
23042 /* If the glyph row is reversed, we need to prepend the glyph
23043 rather than append it. */
23044 if (it->glyph_row->reversed_p && area == TEXT_AREA)
23045 {
23046 struct glyph *g;
23047
23048 /* Make room for the additional glyph. */
23049 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
23050 g[1] = *g;
23051 glyph = it->glyph_row->glyphs[area];
23052 }
23053 glyph->charpos = CHARPOS (it->position);
23054 glyph->object = object;
23055 glyph->pixel_width = width;
23056 glyph->ascent = ascent;
23057 glyph->descent = height - ascent;
23058 glyph->voffset = it->voffset;
23059 glyph->type = STRETCH_GLYPH;
23060 glyph->avoid_cursor_p = it->avoid_cursor_p;
23061 glyph->multibyte_p = it->multibyte_p;
23062 glyph->left_box_line_p = it->start_of_box_run_p;
23063 glyph->right_box_line_p = it->end_of_box_run_p;
23064 glyph->overlaps_vertically_p = 0;
23065 glyph->padding_p = 0;
23066 glyph->glyph_not_available_p = 0;
23067 glyph->face_id = it->face_id;
23068 glyph->u.stretch.ascent = ascent;
23069 glyph->u.stretch.height = height;
23070 glyph->slice.img = null_glyph_slice;
23071 glyph->font_type = FONT_TYPE_UNKNOWN;
23072 if (it->bidi_p)
23073 {
23074 glyph->resolved_level = it->bidi_it.resolved_level;
23075 if ((it->bidi_it.type & 7) != it->bidi_it.type)
23076 abort ();
23077 glyph->bidi_type = it->bidi_it.type;
23078 }
23079 else
23080 {
23081 glyph->resolved_level = 0;
23082 glyph->bidi_type = UNKNOWN_BT;
23083 }
23084 ++it->glyph_row->used[area];
23085 }
23086 else
23087 IT_EXPAND_MATRIX_WIDTH (it, area);
23088 }
23089
23090 #endif /* HAVE_WINDOW_SYSTEM */
23091
23092 /* Produce a stretch glyph for iterator IT. IT->object is the value
23093 of the glyph property displayed. The value must be a list
23094 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
23095 being recognized:
23096
23097 1. `:width WIDTH' specifies that the space should be WIDTH *
23098 canonical char width wide. WIDTH may be an integer or floating
23099 point number.
23100
23101 2. `:relative-width FACTOR' specifies that the width of the stretch
23102 should be computed from the width of the first character having the
23103 `glyph' property, and should be FACTOR times that width.
23104
23105 3. `:align-to HPOS' specifies that the space should be wide enough
23106 to reach HPOS, a value in canonical character units.
23107
23108 Exactly one of the above pairs must be present.
23109
23110 4. `:height HEIGHT' specifies that the height of the stretch produced
23111 should be HEIGHT, measured in canonical character units.
23112
23113 5. `:relative-height FACTOR' specifies that the height of the
23114 stretch should be FACTOR times the height of the characters having
23115 the glyph property.
23116
23117 Either none or exactly one of 4 or 5 must be present.
23118
23119 6. `:ascent ASCENT' specifies that ASCENT percent of the height
23120 of the stretch should be used for the ascent of the stretch.
23121 ASCENT must be in the range 0 <= ASCENT <= 100. */
23122
23123 void
23124 produce_stretch_glyph (struct it *it)
23125 {
23126 /* (space :width WIDTH :height HEIGHT ...) */
23127 Lisp_Object prop, plist;
23128 int width = 0, height = 0, align_to = -1;
23129 int zero_width_ok_p = 0;
23130 int ascent = 0;
23131 double tem;
23132 struct face *face = NULL;
23133 struct font *font = NULL;
23134
23135 #ifdef HAVE_WINDOW_SYSTEM
23136 int zero_height_ok_p = 0;
23137
23138 if (FRAME_WINDOW_P (it->f))
23139 {
23140 face = FACE_FROM_ID (it->f, it->face_id);
23141 font = face->font ? face->font : FRAME_FONT (it->f);
23142 PREPARE_FACE_FOR_DISPLAY (it->f, face);
23143 }
23144 #endif
23145
23146 /* List should start with `space'. */
23147 xassert (CONSP (it->object) && EQ (XCAR (it->object), Qspace));
23148 plist = XCDR (it->object);
23149
23150 /* Compute the width of the stretch. */
23151 if ((prop = Fplist_get (plist, QCwidth), !NILP (prop))
23152 && calc_pixel_width_or_height (&tem, it, prop, font, 1, 0))
23153 {
23154 /* Absolute width `:width WIDTH' specified and valid. */
23155 zero_width_ok_p = 1;
23156 width = (int)tem;
23157 }
23158 #ifdef HAVE_WINDOW_SYSTEM
23159 else if (FRAME_WINDOW_P (it->f)
23160 && (prop = Fplist_get (plist, QCrelative_width), NUMVAL (prop) > 0))
23161 {
23162 /* Relative width `:relative-width FACTOR' specified and valid.
23163 Compute the width of the characters having the `glyph'
23164 property. */
23165 struct it it2;
23166 unsigned char *p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
23167
23168 it2 = *it;
23169 if (it->multibyte_p)
23170 it2.c = it2.char_to_display = STRING_CHAR_AND_LENGTH (p, it2.len);
23171 else
23172 {
23173 it2.c = it2.char_to_display = *p, it2.len = 1;
23174 if (! ASCII_CHAR_P (it2.c))
23175 it2.char_to_display = BYTE8_TO_CHAR (it2.c);
23176 }
23177
23178 it2.glyph_row = NULL;
23179 it2.what = IT_CHARACTER;
23180 x_produce_glyphs (&it2);
23181 width = NUMVAL (prop) * it2.pixel_width;
23182 }
23183 #endif /* HAVE_WINDOW_SYSTEM */
23184 else if ((prop = Fplist_get (plist, QCalign_to), !NILP (prop))
23185 && calc_pixel_width_or_height (&tem, it, prop, font, 1, &align_to))
23186 {
23187 if (it->glyph_row == NULL || !it->glyph_row->mode_line_p)
23188 align_to = (align_to < 0
23189 ? 0
23190 : align_to - window_box_left_offset (it->w, TEXT_AREA));
23191 else if (align_to < 0)
23192 align_to = window_box_left_offset (it->w, TEXT_AREA);
23193 width = max (0, (int)tem + align_to - it->current_x);
23194 zero_width_ok_p = 1;
23195 }
23196 else
23197 /* Nothing specified -> width defaults to canonical char width. */
23198 width = FRAME_COLUMN_WIDTH (it->f);
23199
23200 if (width <= 0 && (width < 0 || !zero_width_ok_p))
23201 width = 1;
23202
23203 #ifdef HAVE_WINDOW_SYSTEM
23204 /* Compute height. */
23205 if (FRAME_WINDOW_P (it->f))
23206 {
23207 if ((prop = Fplist_get (plist, QCheight), !NILP (prop))
23208 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
23209 {
23210 height = (int)tem;
23211 zero_height_ok_p = 1;
23212 }
23213 else if (prop = Fplist_get (plist, QCrelative_height),
23214 NUMVAL (prop) > 0)
23215 height = FONT_HEIGHT (font) * NUMVAL (prop);
23216 else
23217 height = FONT_HEIGHT (font);
23218
23219 if (height <= 0 && (height < 0 || !zero_height_ok_p))
23220 height = 1;
23221
23222 /* Compute percentage of height used for ascent. If
23223 `:ascent ASCENT' is present and valid, use that. Otherwise,
23224 derive the ascent from the font in use. */
23225 if (prop = Fplist_get (plist, QCascent),
23226 NUMVAL (prop) > 0 && NUMVAL (prop) <= 100)
23227 ascent = height * NUMVAL (prop) / 100.0;
23228 else if (!NILP (prop)
23229 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
23230 ascent = min (max (0, (int)tem), height);
23231 else
23232 ascent = (height * FONT_BASE (font)) / FONT_HEIGHT (font);
23233 }
23234 else
23235 #endif /* HAVE_WINDOW_SYSTEM */
23236 height = 1;
23237
23238 if (width > 0 && it->line_wrap != TRUNCATE
23239 && it->current_x + width > it->last_visible_x)
23240 width = it->last_visible_x - it->current_x - 1;
23241
23242 if (width > 0 && height > 0 && it->glyph_row)
23243 {
23244 Lisp_Object o_object = it->object;
23245 Lisp_Object object = it->stack[it->sp - 1].string;
23246 int n = width;
23247
23248 if (!STRINGP (object))
23249 object = it->w->buffer;
23250 #ifdef HAVE_WINDOW_SYSTEM
23251 if (FRAME_WINDOW_P (it->f))
23252 {
23253 append_stretch_glyph (it, object, width, height, ascent);
23254 it->pixel_width = width;
23255 it->ascent = it->phys_ascent = ascent;
23256 it->descent = it->phys_descent = height - it->ascent;
23257 it->nglyphs = width > 0 && height > 0 ? 1 : 0;
23258 take_vertical_position_into_account (it);
23259 }
23260 else
23261 #endif
23262 {
23263 it->object = object;
23264 it->char_to_display = ' ';
23265 it->pixel_width = it->len = 1;
23266 while (n--)
23267 tty_append_glyph (it);
23268 it->object = o_object;
23269 }
23270 }
23271 }
23272
23273 #ifdef HAVE_WINDOW_SYSTEM
23274
23275 /* Calculate line-height and line-spacing properties.
23276 An integer value specifies explicit pixel value.
23277 A float value specifies relative value to current face height.
23278 A cons (float . face-name) specifies relative value to
23279 height of specified face font.
23280
23281 Returns height in pixels, or nil. */
23282
23283
23284 static Lisp_Object
23285 calc_line_height_property (struct it *it, Lisp_Object val, struct font *font,
23286 int boff, int override)
23287 {
23288 Lisp_Object face_name = Qnil;
23289 int ascent, descent, height;
23290
23291 if (NILP (val) || INTEGERP (val) || (override && EQ (val, Qt)))
23292 return val;
23293
23294 if (CONSP (val))
23295 {
23296 face_name = XCAR (val);
23297 val = XCDR (val);
23298 if (!NUMBERP (val))
23299 val = make_number (1);
23300 if (NILP (face_name))
23301 {
23302 height = it->ascent + it->descent;
23303 goto scale;
23304 }
23305 }
23306
23307 if (NILP (face_name))
23308 {
23309 font = FRAME_FONT (it->f);
23310 boff = FRAME_BASELINE_OFFSET (it->f);
23311 }
23312 else if (EQ (face_name, Qt))
23313 {
23314 override = 0;
23315 }
23316 else
23317 {
23318 int face_id;
23319 struct face *face;
23320
23321 face_id = lookup_named_face (it->f, face_name, 0);
23322 if (face_id < 0)
23323 return make_number (-1);
23324
23325 face = FACE_FROM_ID (it->f, face_id);
23326 font = face->font;
23327 if (font == NULL)
23328 return make_number (-1);
23329 boff = font->baseline_offset;
23330 if (font->vertical_centering)
23331 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
23332 }
23333
23334 ascent = FONT_BASE (font) + boff;
23335 descent = FONT_DESCENT (font) - boff;
23336
23337 if (override)
23338 {
23339 it->override_ascent = ascent;
23340 it->override_descent = descent;
23341 it->override_boff = boff;
23342 }
23343
23344 height = ascent + descent;
23345
23346 scale:
23347 if (FLOATP (val))
23348 height = (int)(XFLOAT_DATA (val) * height);
23349 else if (INTEGERP (val))
23350 height *= XINT (val);
23351
23352 return make_number (height);
23353 }
23354
23355
23356 /* Append a glyph for a glyphless character to IT->glyph_row. FACE_ID
23357 is a face ID to be used for the glyph. FOR_NO_FONT is nonzero if
23358 and only if this is for a character for which no font was found.
23359
23360 If the display method (it->glyphless_method) is
23361 GLYPHLESS_DISPLAY_ACRONYM or GLYPHLESS_DISPLAY_HEX_CODE, LEN is a
23362 length of the acronym or the hexadecimal string, UPPER_XOFF and
23363 UPPER_YOFF are pixel offsets for the upper part of the string,
23364 LOWER_XOFF and LOWER_YOFF are for the lower part.
23365
23366 For the other display methods, LEN through LOWER_YOFF are zero. */
23367
23368 static void
23369 append_glyphless_glyph (struct it *it, int face_id, int for_no_font, int len,
23370 short upper_xoff, short upper_yoff,
23371 short lower_xoff, short lower_yoff)
23372 {
23373 struct glyph *glyph;
23374 enum glyph_row_area area = it->area;
23375
23376 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
23377 if (glyph < it->glyph_row->glyphs[area + 1])
23378 {
23379 /* If the glyph row is reversed, we need to prepend the glyph
23380 rather than append it. */
23381 if (it->glyph_row->reversed_p && area == TEXT_AREA)
23382 {
23383 struct glyph *g;
23384
23385 /* Make room for the additional glyph. */
23386 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
23387 g[1] = *g;
23388 glyph = it->glyph_row->glyphs[area];
23389 }
23390 glyph->charpos = CHARPOS (it->position);
23391 glyph->object = it->object;
23392 glyph->pixel_width = it->pixel_width;
23393 glyph->ascent = it->ascent;
23394 glyph->descent = it->descent;
23395 glyph->voffset = it->voffset;
23396 glyph->type = GLYPHLESS_GLYPH;
23397 glyph->u.glyphless.method = it->glyphless_method;
23398 glyph->u.glyphless.for_no_font = for_no_font;
23399 glyph->u.glyphless.len = len;
23400 glyph->u.glyphless.ch = it->c;
23401 glyph->slice.glyphless.upper_xoff = upper_xoff;
23402 glyph->slice.glyphless.upper_yoff = upper_yoff;
23403 glyph->slice.glyphless.lower_xoff = lower_xoff;
23404 glyph->slice.glyphless.lower_yoff = lower_yoff;
23405 glyph->avoid_cursor_p = it->avoid_cursor_p;
23406 glyph->multibyte_p = it->multibyte_p;
23407 glyph->left_box_line_p = it->start_of_box_run_p;
23408 glyph->right_box_line_p = it->end_of_box_run_p;
23409 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
23410 || it->phys_descent > it->descent);
23411 glyph->padding_p = 0;
23412 glyph->glyph_not_available_p = 0;
23413 glyph->face_id = face_id;
23414 glyph->font_type = FONT_TYPE_UNKNOWN;
23415 if (it->bidi_p)
23416 {
23417 glyph->resolved_level = it->bidi_it.resolved_level;
23418 if ((it->bidi_it.type & 7) != it->bidi_it.type)
23419 abort ();
23420 glyph->bidi_type = it->bidi_it.type;
23421 }
23422 ++it->glyph_row->used[area];
23423 }
23424 else
23425 IT_EXPAND_MATRIX_WIDTH (it, area);
23426 }
23427
23428
23429 /* Produce a glyph for a glyphless character for iterator IT.
23430 IT->glyphless_method specifies which method to use for displaying
23431 the character. See the description of enum
23432 glyphless_display_method in dispextern.h for the detail.
23433
23434 FOR_NO_FONT is nonzero if and only if this is for a character for
23435 which no font was found. ACRONYM, if non-nil, is an acronym string
23436 for the character. */
23437
23438 static void
23439 produce_glyphless_glyph (struct it *it, int for_no_font, Lisp_Object acronym)
23440 {
23441 int face_id;
23442 struct face *face;
23443 struct font *font;
23444 int base_width, base_height, width, height;
23445 short upper_xoff, upper_yoff, lower_xoff, lower_yoff;
23446 int len;
23447
23448 /* Get the metrics of the base font. We always refer to the current
23449 ASCII face. */
23450 face = FACE_FROM_ID (it->f, it->face_id)->ascii_face;
23451 font = face->font ? face->font : FRAME_FONT (it->f);
23452 it->ascent = FONT_BASE (font) + font->baseline_offset;
23453 it->descent = FONT_DESCENT (font) - font->baseline_offset;
23454 base_height = it->ascent + it->descent;
23455 base_width = font->average_width;
23456
23457 /* Get a face ID for the glyph by utilizing a cache (the same way as
23458 done for `escape-glyph' in get_next_display_element). */
23459 if (it->f == last_glyphless_glyph_frame
23460 && it->face_id == last_glyphless_glyph_face_id)
23461 {
23462 face_id = last_glyphless_glyph_merged_face_id;
23463 }
23464 else
23465 {
23466 /* Merge the `glyphless-char' face into the current face. */
23467 face_id = merge_faces (it->f, Qglyphless_char, 0, it->face_id);
23468 last_glyphless_glyph_frame = it->f;
23469 last_glyphless_glyph_face_id = it->face_id;
23470 last_glyphless_glyph_merged_face_id = face_id;
23471 }
23472
23473 if (it->glyphless_method == GLYPHLESS_DISPLAY_THIN_SPACE)
23474 {
23475 it->pixel_width = THIN_SPACE_WIDTH;
23476 len = 0;
23477 upper_xoff = upper_yoff = lower_xoff = lower_yoff = 0;
23478 }
23479 else if (it->glyphless_method == GLYPHLESS_DISPLAY_EMPTY_BOX)
23480 {
23481 width = CHAR_WIDTH (it->c);
23482 if (width == 0)
23483 width = 1;
23484 else if (width > 4)
23485 width = 4;
23486 it->pixel_width = base_width * width;
23487 len = 0;
23488 upper_xoff = upper_yoff = lower_xoff = lower_yoff = 0;
23489 }
23490 else
23491 {
23492 char buf[7];
23493 const char *str;
23494 unsigned int code[6];
23495 int upper_len;
23496 int ascent, descent;
23497 struct font_metrics metrics_upper, metrics_lower;
23498
23499 face = FACE_FROM_ID (it->f, face_id);
23500 font = face->font ? face->font : FRAME_FONT (it->f);
23501 PREPARE_FACE_FOR_DISPLAY (it->f, face);
23502
23503 if (it->glyphless_method == GLYPHLESS_DISPLAY_ACRONYM)
23504 {
23505 if (! STRINGP (acronym) && CHAR_TABLE_P (Vglyphless_char_display))
23506 acronym = CHAR_TABLE_REF (Vglyphless_char_display, it->c);
23507 if (CONSP (acronym))
23508 acronym = XCAR (acronym);
23509 str = STRINGP (acronym) ? SSDATA (acronym) : "";
23510 }
23511 else
23512 {
23513 xassert (it->glyphless_method == GLYPHLESS_DISPLAY_HEX_CODE);
23514 sprintf (buf, "%0*X", it->c < 0x10000 ? 4 : 6, it->c);
23515 str = buf;
23516 }
23517 for (len = 0; str[len] && ASCII_BYTE_P (str[len]); len++)
23518 code[len] = font->driver->encode_char (font, str[len]);
23519 upper_len = (len + 1) / 2;
23520 font->driver->text_extents (font, code, upper_len,
23521 &metrics_upper);
23522 font->driver->text_extents (font, code + upper_len, len - upper_len,
23523 &metrics_lower);
23524
23525
23526
23527 /* +4 is for vertical bars of a box plus 1-pixel spaces at both side. */
23528 width = max (metrics_upper.width, metrics_lower.width) + 4;
23529 upper_xoff = upper_yoff = 2; /* the typical case */
23530 if (base_width >= width)
23531 {
23532 /* Align the upper to the left, the lower to the right. */
23533 it->pixel_width = base_width;
23534 lower_xoff = base_width - 2 - metrics_lower.width;
23535 }
23536 else
23537 {
23538 /* Center the shorter one. */
23539 it->pixel_width = width;
23540 if (metrics_upper.width >= metrics_lower.width)
23541 lower_xoff = (width - metrics_lower.width) / 2;
23542 else
23543 {
23544 /* FIXME: This code doesn't look right. It formerly was
23545 missing the "lower_xoff = 0;", which couldn't have
23546 been right since it left lower_xoff uninitialized. */
23547 lower_xoff = 0;
23548 upper_xoff = (width - metrics_upper.width) / 2;
23549 }
23550 }
23551
23552 /* +5 is for horizontal bars of a box plus 1-pixel spaces at
23553 top, bottom, and between upper and lower strings. */
23554 height = (metrics_upper.ascent + metrics_upper.descent
23555 + metrics_lower.ascent + metrics_lower.descent) + 5;
23556 /* Center vertically.
23557 H:base_height, D:base_descent
23558 h:height, ld:lower_descent, la:lower_ascent, ud:upper_descent
23559
23560 ascent = - (D - H/2 - h/2 + 1); "+ 1" for rounding up
23561 descent = D - H/2 + h/2;
23562 lower_yoff = descent - 2 - ld;
23563 upper_yoff = lower_yoff - la - 1 - ud; */
23564 ascent = - (it->descent - (base_height + height + 1) / 2);
23565 descent = it->descent - (base_height - height) / 2;
23566 lower_yoff = descent - 2 - metrics_lower.descent;
23567 upper_yoff = (lower_yoff - metrics_lower.ascent - 1
23568 - metrics_upper.descent);
23569 /* Don't make the height shorter than the base height. */
23570 if (height > base_height)
23571 {
23572 it->ascent = ascent;
23573 it->descent = descent;
23574 }
23575 }
23576
23577 it->phys_ascent = it->ascent;
23578 it->phys_descent = it->descent;
23579 if (it->glyph_row)
23580 append_glyphless_glyph (it, face_id, for_no_font, len,
23581 upper_xoff, upper_yoff,
23582 lower_xoff, lower_yoff);
23583 it->nglyphs = 1;
23584 take_vertical_position_into_account (it);
23585 }
23586
23587
23588 /* RIF:
23589 Produce glyphs/get display metrics for the display element IT is
23590 loaded with. See the description of struct it in dispextern.h
23591 for an overview of struct it. */
23592
23593 void
23594 x_produce_glyphs (struct it *it)
23595 {
23596 int extra_line_spacing = it->extra_line_spacing;
23597
23598 it->glyph_not_available_p = 0;
23599
23600 if (it->what == IT_CHARACTER)
23601 {
23602 XChar2b char2b;
23603 struct face *face = FACE_FROM_ID (it->f, it->face_id);
23604 struct font *font = face->font;
23605 struct font_metrics *pcm = NULL;
23606 int boff; /* baseline offset */
23607
23608 if (font == NULL)
23609 {
23610 /* When no suitable font is found, display this character by
23611 the method specified in the first extra slot of
23612 Vglyphless_char_display. */
23613 Lisp_Object acronym = lookup_glyphless_char_display (-1, it);
23614
23615 xassert (it->what == IT_GLYPHLESS);
23616 produce_glyphless_glyph (it, 1, STRINGP (acronym) ? acronym : Qnil);
23617 goto done;
23618 }
23619
23620 boff = font->baseline_offset;
23621 if (font->vertical_centering)
23622 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
23623
23624 if (it->char_to_display != '\n' && it->char_to_display != '\t')
23625 {
23626 int stretched_p;
23627
23628 it->nglyphs = 1;
23629
23630 if (it->override_ascent >= 0)
23631 {
23632 it->ascent = it->override_ascent;
23633 it->descent = it->override_descent;
23634 boff = it->override_boff;
23635 }
23636 else
23637 {
23638 it->ascent = FONT_BASE (font) + boff;
23639 it->descent = FONT_DESCENT (font) - boff;
23640 }
23641
23642 if (get_char_glyph_code (it->char_to_display, font, &char2b))
23643 {
23644 pcm = get_per_char_metric (font, &char2b);
23645 if (pcm->width == 0
23646 && pcm->rbearing == 0 && pcm->lbearing == 0)
23647 pcm = NULL;
23648 }
23649
23650 if (pcm)
23651 {
23652 it->phys_ascent = pcm->ascent + boff;
23653 it->phys_descent = pcm->descent - boff;
23654 it->pixel_width = pcm->width;
23655 }
23656 else
23657 {
23658 it->glyph_not_available_p = 1;
23659 it->phys_ascent = it->ascent;
23660 it->phys_descent = it->descent;
23661 it->pixel_width = font->space_width;
23662 }
23663
23664 if (it->constrain_row_ascent_descent_p)
23665 {
23666 if (it->descent > it->max_descent)
23667 {
23668 it->ascent += it->descent - it->max_descent;
23669 it->descent = it->max_descent;
23670 }
23671 if (it->ascent > it->max_ascent)
23672 {
23673 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
23674 it->ascent = it->max_ascent;
23675 }
23676 it->phys_ascent = min (it->phys_ascent, it->ascent);
23677 it->phys_descent = min (it->phys_descent, it->descent);
23678 extra_line_spacing = 0;
23679 }
23680
23681 /* If this is a space inside a region of text with
23682 `space-width' property, change its width. */
23683 stretched_p = it->char_to_display == ' ' && !NILP (it->space_width);
23684 if (stretched_p)
23685 it->pixel_width *= XFLOATINT (it->space_width);
23686
23687 /* If face has a box, add the box thickness to the character
23688 height. If character has a box line to the left and/or
23689 right, add the box line width to the character's width. */
23690 if (face->box != FACE_NO_BOX)
23691 {
23692 int thick = face->box_line_width;
23693
23694 if (thick > 0)
23695 {
23696 it->ascent += thick;
23697 it->descent += thick;
23698 }
23699 else
23700 thick = -thick;
23701
23702 if (it->start_of_box_run_p)
23703 it->pixel_width += thick;
23704 if (it->end_of_box_run_p)
23705 it->pixel_width += thick;
23706 }
23707
23708 /* If face has an overline, add the height of the overline
23709 (1 pixel) and a 1 pixel margin to the character height. */
23710 if (face->overline_p)
23711 it->ascent += overline_margin;
23712
23713 if (it->constrain_row_ascent_descent_p)
23714 {
23715 if (it->ascent > it->max_ascent)
23716 it->ascent = it->max_ascent;
23717 if (it->descent > it->max_descent)
23718 it->descent = it->max_descent;
23719 }
23720
23721 take_vertical_position_into_account (it);
23722
23723 /* If we have to actually produce glyphs, do it. */
23724 if (it->glyph_row)
23725 {
23726 if (stretched_p)
23727 {
23728 /* Translate a space with a `space-width' property
23729 into a stretch glyph. */
23730 int ascent = (((it->ascent + it->descent) * FONT_BASE (font))
23731 / FONT_HEIGHT (font));
23732 append_stretch_glyph (it, it->object, it->pixel_width,
23733 it->ascent + it->descent, ascent);
23734 }
23735 else
23736 append_glyph (it);
23737
23738 /* If characters with lbearing or rbearing are displayed
23739 in this line, record that fact in a flag of the
23740 glyph row. This is used to optimize X output code. */
23741 if (pcm && (pcm->lbearing < 0 || pcm->rbearing > pcm->width))
23742 it->glyph_row->contains_overlapping_glyphs_p = 1;
23743 }
23744 if (! stretched_p && it->pixel_width == 0)
23745 /* We assure that all visible glyphs have at least 1-pixel
23746 width. */
23747 it->pixel_width = 1;
23748 }
23749 else if (it->char_to_display == '\n')
23750 {
23751 /* A newline has no width, but we need the height of the
23752 line. But if previous part of the line sets a height,
23753 don't increase that height */
23754
23755 Lisp_Object height;
23756 Lisp_Object total_height = Qnil;
23757
23758 it->override_ascent = -1;
23759 it->pixel_width = 0;
23760 it->nglyphs = 0;
23761
23762 height = get_it_property (it, Qline_height);
23763 /* Split (line-height total-height) list */
23764 if (CONSP (height)
23765 && CONSP (XCDR (height))
23766 && NILP (XCDR (XCDR (height))))
23767 {
23768 total_height = XCAR (XCDR (height));
23769 height = XCAR (height);
23770 }
23771 height = calc_line_height_property (it, height, font, boff, 1);
23772
23773 if (it->override_ascent >= 0)
23774 {
23775 it->ascent = it->override_ascent;
23776 it->descent = it->override_descent;
23777 boff = it->override_boff;
23778 }
23779 else
23780 {
23781 it->ascent = FONT_BASE (font) + boff;
23782 it->descent = FONT_DESCENT (font) - boff;
23783 }
23784
23785 if (EQ (height, Qt))
23786 {
23787 if (it->descent > it->max_descent)
23788 {
23789 it->ascent += it->descent - it->max_descent;
23790 it->descent = it->max_descent;
23791 }
23792 if (it->ascent > it->max_ascent)
23793 {
23794 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
23795 it->ascent = it->max_ascent;
23796 }
23797 it->phys_ascent = min (it->phys_ascent, it->ascent);
23798 it->phys_descent = min (it->phys_descent, it->descent);
23799 it->constrain_row_ascent_descent_p = 1;
23800 extra_line_spacing = 0;
23801 }
23802 else
23803 {
23804 Lisp_Object spacing;
23805
23806 it->phys_ascent = it->ascent;
23807 it->phys_descent = it->descent;
23808
23809 if ((it->max_ascent > 0 || it->max_descent > 0)
23810 && face->box != FACE_NO_BOX
23811 && face->box_line_width > 0)
23812 {
23813 it->ascent += face->box_line_width;
23814 it->descent += face->box_line_width;
23815 }
23816 if (!NILP (height)
23817 && XINT (height) > it->ascent + it->descent)
23818 it->ascent = XINT (height) - it->descent;
23819
23820 if (!NILP (total_height))
23821 spacing = calc_line_height_property (it, total_height, font, boff, 0);
23822 else
23823 {
23824 spacing = get_it_property (it, Qline_spacing);
23825 spacing = calc_line_height_property (it, spacing, font, boff, 0);
23826 }
23827 if (INTEGERP (spacing))
23828 {
23829 extra_line_spacing = XINT (spacing);
23830 if (!NILP (total_height))
23831 extra_line_spacing -= (it->phys_ascent + it->phys_descent);
23832 }
23833 }
23834 }
23835 else /* i.e. (it->char_to_display == '\t') */
23836 {
23837 if (font->space_width > 0)
23838 {
23839 int tab_width = it->tab_width * font->space_width;
23840 int x = it->current_x + it->continuation_lines_width;
23841 int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width;
23842
23843 /* If the distance from the current position to the next tab
23844 stop is less than a space character width, use the
23845 tab stop after that. */
23846 if (next_tab_x - x < font->space_width)
23847 next_tab_x += tab_width;
23848
23849 it->pixel_width = next_tab_x - x;
23850 it->nglyphs = 1;
23851 it->ascent = it->phys_ascent = FONT_BASE (font) + boff;
23852 it->descent = it->phys_descent = FONT_DESCENT (font) - boff;
23853
23854 if (it->glyph_row)
23855 {
23856 append_stretch_glyph (it, it->object, it->pixel_width,
23857 it->ascent + it->descent, it->ascent);
23858 }
23859 }
23860 else
23861 {
23862 it->pixel_width = 0;
23863 it->nglyphs = 1;
23864 }
23865 }
23866 }
23867 else if (it->what == IT_COMPOSITION && it->cmp_it.ch < 0)
23868 {
23869 /* A static composition.
23870
23871 Note: A composition is represented as one glyph in the
23872 glyph matrix. There are no padding glyphs.
23873
23874 Important note: pixel_width, ascent, and descent are the
23875 values of what is drawn by draw_glyphs (i.e. the values of
23876 the overall glyphs composed). */
23877 struct face *face = FACE_FROM_ID (it->f, it->face_id);
23878 int boff; /* baseline offset */
23879 struct composition *cmp = composition_table[it->cmp_it.id];
23880 int glyph_len = cmp->glyph_len;
23881 struct font *font = face->font;
23882
23883 it->nglyphs = 1;
23884
23885 /* If we have not yet calculated pixel size data of glyphs of
23886 the composition for the current face font, calculate them
23887 now. Theoretically, we have to check all fonts for the
23888 glyphs, but that requires much time and memory space. So,
23889 here we check only the font of the first glyph. This may
23890 lead to incorrect display, but it's very rare, and C-l
23891 (recenter-top-bottom) can correct the display anyway. */
23892 if (! cmp->font || cmp->font != font)
23893 {
23894 /* Ascent and descent of the font of the first character
23895 of this composition (adjusted by baseline offset).
23896 Ascent and descent of overall glyphs should not be less
23897 than these, respectively. */
23898 int font_ascent, font_descent, font_height;
23899 /* Bounding box of the overall glyphs. */
23900 int leftmost, rightmost, lowest, highest;
23901 int lbearing, rbearing;
23902 int i, width, ascent, descent;
23903 int left_padded = 0, right_padded = 0;
23904 int c IF_LINT (= 0); /* cmp->glyph_len can't be zero; see Bug#8512 */
23905 XChar2b char2b;
23906 struct font_metrics *pcm;
23907 int font_not_found_p;
23908 EMACS_INT pos;
23909
23910 for (glyph_len = cmp->glyph_len; glyph_len > 0; glyph_len--)
23911 if ((c = COMPOSITION_GLYPH (cmp, glyph_len - 1)) != '\t')
23912 break;
23913 if (glyph_len < cmp->glyph_len)
23914 right_padded = 1;
23915 for (i = 0; i < glyph_len; i++)
23916 {
23917 if ((c = COMPOSITION_GLYPH (cmp, i)) != '\t')
23918 break;
23919 cmp->offsets[i * 2] = cmp->offsets[i * 2 + 1] = 0;
23920 }
23921 if (i > 0)
23922 left_padded = 1;
23923
23924 pos = (STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
23925 : IT_CHARPOS (*it));
23926 /* If no suitable font is found, use the default font. */
23927 font_not_found_p = font == NULL;
23928 if (font_not_found_p)
23929 {
23930 face = face->ascii_face;
23931 font = face->font;
23932 }
23933 boff = font->baseline_offset;
23934 if (font->vertical_centering)
23935 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
23936 font_ascent = FONT_BASE (font) + boff;
23937 font_descent = FONT_DESCENT (font) - boff;
23938 font_height = FONT_HEIGHT (font);
23939
23940 cmp->font = (void *) font;
23941
23942 pcm = NULL;
23943 if (! font_not_found_p)
23944 {
23945 get_char_face_and_encoding (it->f, c, it->face_id,
23946 &char2b, 0);
23947 pcm = get_per_char_metric (font, &char2b);
23948 }
23949
23950 /* Initialize the bounding box. */
23951 if (pcm)
23952 {
23953 width = pcm->width;
23954 ascent = pcm->ascent;
23955 descent = pcm->descent;
23956 lbearing = pcm->lbearing;
23957 rbearing = pcm->rbearing;
23958 }
23959 else
23960 {
23961 width = font->space_width;
23962 ascent = FONT_BASE (font);
23963 descent = FONT_DESCENT (font);
23964 lbearing = 0;
23965 rbearing = width;
23966 }
23967
23968 rightmost = width;
23969 leftmost = 0;
23970 lowest = - descent + boff;
23971 highest = ascent + boff;
23972
23973 if (! font_not_found_p
23974 && font->default_ascent
23975 && CHAR_TABLE_P (Vuse_default_ascent)
23976 && !NILP (Faref (Vuse_default_ascent,
23977 make_number (it->char_to_display))))
23978 highest = font->default_ascent + boff;
23979
23980 /* Draw the first glyph at the normal position. It may be
23981 shifted to right later if some other glyphs are drawn
23982 at the left. */
23983 cmp->offsets[i * 2] = 0;
23984 cmp->offsets[i * 2 + 1] = boff;
23985 cmp->lbearing = lbearing;
23986 cmp->rbearing = rbearing;
23987
23988 /* Set cmp->offsets for the remaining glyphs. */
23989 for (i++; i < glyph_len; i++)
23990 {
23991 int left, right, btm, top;
23992 int ch = COMPOSITION_GLYPH (cmp, i);
23993 int face_id;
23994 struct face *this_face;
23995
23996 if (ch == '\t')
23997 ch = ' ';
23998 face_id = FACE_FOR_CHAR (it->f, face, ch, pos, it->string);
23999 this_face = FACE_FROM_ID (it->f, face_id);
24000 font = this_face->font;
24001
24002 if (font == NULL)
24003 pcm = NULL;
24004 else
24005 {
24006 get_char_face_and_encoding (it->f, ch, face_id,
24007 &char2b, 0);
24008 pcm = get_per_char_metric (font, &char2b);
24009 }
24010 if (! pcm)
24011 cmp->offsets[i * 2] = cmp->offsets[i * 2 + 1] = 0;
24012 else
24013 {
24014 width = pcm->width;
24015 ascent = pcm->ascent;
24016 descent = pcm->descent;
24017 lbearing = pcm->lbearing;
24018 rbearing = pcm->rbearing;
24019 if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS)
24020 {
24021 /* Relative composition with or without
24022 alternate chars. */
24023 left = (leftmost + rightmost - width) / 2;
24024 btm = - descent + boff;
24025 if (font->relative_compose
24026 && (! CHAR_TABLE_P (Vignore_relative_composition)
24027 || NILP (Faref (Vignore_relative_composition,
24028 make_number (ch)))))
24029 {
24030
24031 if (- descent >= font->relative_compose)
24032 /* One extra pixel between two glyphs. */
24033 btm = highest + 1;
24034 else if (ascent <= 0)
24035 /* One extra pixel between two glyphs. */
24036 btm = lowest - 1 - ascent - descent;
24037 }
24038 }
24039 else
24040 {
24041 /* A composition rule is specified by an integer
24042 value that encodes global and new reference
24043 points (GREF and NREF). GREF and NREF are
24044 specified by numbers as below:
24045
24046 0---1---2 -- ascent
24047 | |
24048 | |
24049 | |
24050 9--10--11 -- center
24051 | |
24052 ---3---4---5--- baseline
24053 | |
24054 6---7---8 -- descent
24055 */
24056 int rule = COMPOSITION_RULE (cmp, i);
24057 int gref, nref, grefx, grefy, nrefx, nrefy, xoff, yoff;
24058
24059 COMPOSITION_DECODE_RULE (rule, gref, nref, xoff, yoff);
24060 grefx = gref % 3, nrefx = nref % 3;
24061 grefy = gref / 3, nrefy = nref / 3;
24062 if (xoff)
24063 xoff = font_height * (xoff - 128) / 256;
24064 if (yoff)
24065 yoff = font_height * (yoff - 128) / 256;
24066
24067 left = (leftmost
24068 + grefx * (rightmost - leftmost) / 2
24069 - nrefx * width / 2
24070 + xoff);
24071
24072 btm = ((grefy == 0 ? highest
24073 : grefy == 1 ? 0
24074 : grefy == 2 ? lowest
24075 : (highest + lowest) / 2)
24076 - (nrefy == 0 ? ascent + descent
24077 : nrefy == 1 ? descent - boff
24078 : nrefy == 2 ? 0
24079 : (ascent + descent) / 2)
24080 + yoff);
24081 }
24082
24083 cmp->offsets[i * 2] = left;
24084 cmp->offsets[i * 2 + 1] = btm + descent;
24085
24086 /* Update the bounding box of the overall glyphs. */
24087 if (width > 0)
24088 {
24089 right = left + width;
24090 if (left < leftmost)
24091 leftmost = left;
24092 if (right > rightmost)
24093 rightmost = right;
24094 }
24095 top = btm + descent + ascent;
24096 if (top > highest)
24097 highest = top;
24098 if (btm < lowest)
24099 lowest = btm;
24100
24101 if (cmp->lbearing > left + lbearing)
24102 cmp->lbearing = left + lbearing;
24103 if (cmp->rbearing < left + rbearing)
24104 cmp->rbearing = left + rbearing;
24105 }
24106 }
24107
24108 /* If there are glyphs whose x-offsets are negative,
24109 shift all glyphs to the right and make all x-offsets
24110 non-negative. */
24111 if (leftmost < 0)
24112 {
24113 for (i = 0; i < cmp->glyph_len; i++)
24114 cmp->offsets[i * 2] -= leftmost;
24115 rightmost -= leftmost;
24116 cmp->lbearing -= leftmost;
24117 cmp->rbearing -= leftmost;
24118 }
24119
24120 if (left_padded && cmp->lbearing < 0)
24121 {
24122 for (i = 0; i < cmp->glyph_len; i++)
24123 cmp->offsets[i * 2] -= cmp->lbearing;
24124 rightmost -= cmp->lbearing;
24125 cmp->rbearing -= cmp->lbearing;
24126 cmp->lbearing = 0;
24127 }
24128 if (right_padded && rightmost < cmp->rbearing)
24129 {
24130 rightmost = cmp->rbearing;
24131 }
24132
24133 cmp->pixel_width = rightmost;
24134 cmp->ascent = highest;
24135 cmp->descent = - lowest;
24136 if (cmp->ascent < font_ascent)
24137 cmp->ascent = font_ascent;
24138 if (cmp->descent < font_descent)
24139 cmp->descent = font_descent;
24140 }
24141
24142 if (it->glyph_row
24143 && (cmp->lbearing < 0
24144 || cmp->rbearing > cmp->pixel_width))
24145 it->glyph_row->contains_overlapping_glyphs_p = 1;
24146
24147 it->pixel_width = cmp->pixel_width;
24148 it->ascent = it->phys_ascent = cmp->ascent;
24149 it->descent = it->phys_descent = cmp->descent;
24150 if (face->box != FACE_NO_BOX)
24151 {
24152 int thick = face->box_line_width;
24153
24154 if (thick > 0)
24155 {
24156 it->ascent += thick;
24157 it->descent += thick;
24158 }
24159 else
24160 thick = - thick;
24161
24162 if (it->start_of_box_run_p)
24163 it->pixel_width += thick;
24164 if (it->end_of_box_run_p)
24165 it->pixel_width += thick;
24166 }
24167
24168 /* If face has an overline, add the height of the overline
24169 (1 pixel) and a 1 pixel margin to the character height. */
24170 if (face->overline_p)
24171 it->ascent += overline_margin;
24172
24173 take_vertical_position_into_account (it);
24174 if (it->ascent < 0)
24175 it->ascent = 0;
24176 if (it->descent < 0)
24177 it->descent = 0;
24178
24179 if (it->glyph_row)
24180 append_composite_glyph (it);
24181 }
24182 else if (it->what == IT_COMPOSITION)
24183 {
24184 /* A dynamic (automatic) composition. */
24185 struct face *face = FACE_FROM_ID (it->f, it->face_id);
24186 Lisp_Object gstring;
24187 struct font_metrics metrics;
24188
24189 it->nglyphs = 1;
24190
24191 gstring = composition_gstring_from_id (it->cmp_it.id);
24192 it->pixel_width
24193 = composition_gstring_width (gstring, it->cmp_it.from, it->cmp_it.to,
24194 &metrics);
24195 if (it->glyph_row
24196 && (metrics.lbearing < 0 || metrics.rbearing > metrics.width))
24197 it->glyph_row->contains_overlapping_glyphs_p = 1;
24198 it->ascent = it->phys_ascent = metrics.ascent;
24199 it->descent = it->phys_descent = metrics.descent;
24200 if (face->box != FACE_NO_BOX)
24201 {
24202 int thick = face->box_line_width;
24203
24204 if (thick > 0)
24205 {
24206 it->ascent += thick;
24207 it->descent += thick;
24208 }
24209 else
24210 thick = - thick;
24211
24212 if (it->start_of_box_run_p)
24213 it->pixel_width += thick;
24214 if (it->end_of_box_run_p)
24215 it->pixel_width += thick;
24216 }
24217 /* If face has an overline, add the height of the overline
24218 (1 pixel) and a 1 pixel margin to the character height. */
24219 if (face->overline_p)
24220 it->ascent += overline_margin;
24221 take_vertical_position_into_account (it);
24222 if (it->ascent < 0)
24223 it->ascent = 0;
24224 if (it->descent < 0)
24225 it->descent = 0;
24226
24227 if (it->glyph_row)
24228 append_composite_glyph (it);
24229 }
24230 else if (it->what == IT_GLYPHLESS)
24231 produce_glyphless_glyph (it, 0, Qnil);
24232 else if (it->what == IT_IMAGE)
24233 produce_image_glyph (it);
24234 else if (it->what == IT_STRETCH)
24235 produce_stretch_glyph (it);
24236
24237 done:
24238 /* Accumulate dimensions. Note: can't assume that it->descent > 0
24239 because this isn't true for images with `:ascent 100'. */
24240 xassert (it->ascent >= 0 && it->descent >= 0);
24241 if (it->area == TEXT_AREA)
24242 it->current_x += it->pixel_width;
24243
24244 if (extra_line_spacing > 0)
24245 {
24246 it->descent += extra_line_spacing;
24247 if (extra_line_spacing > it->max_extra_line_spacing)
24248 it->max_extra_line_spacing = extra_line_spacing;
24249 }
24250
24251 it->max_ascent = max (it->max_ascent, it->ascent);
24252 it->max_descent = max (it->max_descent, it->descent);
24253 it->max_phys_ascent = max (it->max_phys_ascent, it->phys_ascent);
24254 it->max_phys_descent = max (it->max_phys_descent, it->phys_descent);
24255 }
24256
24257 /* EXPORT for RIF:
24258 Output LEN glyphs starting at START at the nominal cursor position.
24259 Advance the nominal cursor over the text. The global variable
24260 updated_window contains the window being updated, updated_row is
24261 the glyph row being updated, and updated_area is the area of that
24262 row being updated. */
24263
24264 void
24265 x_write_glyphs (struct glyph *start, int len)
24266 {
24267 int x, hpos;
24268
24269 xassert (updated_window && updated_row);
24270 BLOCK_INPUT;
24271
24272 /* Write glyphs. */
24273
24274 hpos = start - updated_row->glyphs[updated_area];
24275 x = draw_glyphs (updated_window, output_cursor.x,
24276 updated_row, updated_area,
24277 hpos, hpos + len,
24278 DRAW_NORMAL_TEXT, 0);
24279
24280 /* Invalidate old phys cursor if the glyph at its hpos is redrawn. */
24281 if (updated_area == TEXT_AREA
24282 && updated_window->phys_cursor_on_p
24283 && updated_window->phys_cursor.vpos == output_cursor.vpos
24284 && updated_window->phys_cursor.hpos >= hpos
24285 && updated_window->phys_cursor.hpos < hpos + len)
24286 updated_window->phys_cursor_on_p = 0;
24287
24288 UNBLOCK_INPUT;
24289
24290 /* Advance the output cursor. */
24291 output_cursor.hpos += len;
24292 output_cursor.x = x;
24293 }
24294
24295
24296 /* EXPORT for RIF:
24297 Insert LEN glyphs from START at the nominal cursor position. */
24298
24299 void
24300 x_insert_glyphs (struct glyph *start, int len)
24301 {
24302 struct frame *f;
24303 struct window *w;
24304 int line_height, shift_by_width, shifted_region_width;
24305 struct glyph_row *row;
24306 struct glyph *glyph;
24307 int frame_x, frame_y;
24308 EMACS_INT hpos;
24309
24310 xassert (updated_window && updated_row);
24311 BLOCK_INPUT;
24312 w = updated_window;
24313 f = XFRAME (WINDOW_FRAME (w));
24314
24315 /* Get the height of the line we are in. */
24316 row = updated_row;
24317 line_height = row->height;
24318
24319 /* Get the width of the glyphs to insert. */
24320 shift_by_width = 0;
24321 for (glyph = start; glyph < start + len; ++glyph)
24322 shift_by_width += glyph->pixel_width;
24323
24324 /* Get the width of the region to shift right. */
24325 shifted_region_width = (window_box_width (w, updated_area)
24326 - output_cursor.x
24327 - shift_by_width);
24328
24329 /* Shift right. */
24330 frame_x = window_box_left (w, updated_area) + output_cursor.x;
24331 frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, output_cursor.y);
24332
24333 FRAME_RIF (f)->shift_glyphs_for_insert (f, frame_x, frame_y, shifted_region_width,
24334 line_height, shift_by_width);
24335
24336 /* Write the glyphs. */
24337 hpos = start - row->glyphs[updated_area];
24338 draw_glyphs (w, output_cursor.x, row, updated_area,
24339 hpos, hpos + len,
24340 DRAW_NORMAL_TEXT, 0);
24341
24342 /* Advance the output cursor. */
24343 output_cursor.hpos += len;
24344 output_cursor.x += shift_by_width;
24345 UNBLOCK_INPUT;
24346 }
24347
24348
24349 /* EXPORT for RIF:
24350 Erase the current text line from the nominal cursor position
24351 (inclusive) to pixel column TO_X (exclusive). The idea is that
24352 everything from TO_X onward is already erased.
24353
24354 TO_X is a pixel position relative to updated_area of
24355 updated_window. TO_X == -1 means clear to the end of this area. */
24356
24357 void
24358 x_clear_end_of_line (int to_x)
24359 {
24360 struct frame *f;
24361 struct window *w = updated_window;
24362 int max_x, min_y, max_y;
24363 int from_x, from_y, to_y;
24364
24365 xassert (updated_window && updated_row);
24366 f = XFRAME (w->frame);
24367
24368 if (updated_row->full_width_p)
24369 max_x = WINDOW_TOTAL_WIDTH (w);
24370 else
24371 max_x = window_box_width (w, updated_area);
24372 max_y = window_text_bottom_y (w);
24373
24374 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
24375 of window. For TO_X > 0, truncate to end of drawing area. */
24376 if (to_x == 0)
24377 return;
24378 else if (to_x < 0)
24379 to_x = max_x;
24380 else
24381 to_x = min (to_x, max_x);
24382
24383 to_y = min (max_y, output_cursor.y + updated_row->height);
24384
24385 /* Notice if the cursor will be cleared by this operation. */
24386 if (!updated_row->full_width_p)
24387 notice_overwritten_cursor (w, updated_area,
24388 output_cursor.x, -1,
24389 updated_row->y,
24390 MATRIX_ROW_BOTTOM_Y (updated_row));
24391
24392 from_x = output_cursor.x;
24393
24394 /* Translate to frame coordinates. */
24395 if (updated_row->full_width_p)
24396 {
24397 from_x = WINDOW_TO_FRAME_PIXEL_X (w, from_x);
24398 to_x = WINDOW_TO_FRAME_PIXEL_X (w, to_x);
24399 }
24400 else
24401 {
24402 int area_left = window_box_left (w, updated_area);
24403 from_x += area_left;
24404 to_x += area_left;
24405 }
24406
24407 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
24408 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, max (min_y, output_cursor.y));
24409 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, to_y);
24410
24411 /* Prevent inadvertently clearing to end of the X window. */
24412 if (to_x > from_x && to_y > from_y)
24413 {
24414 BLOCK_INPUT;
24415 FRAME_RIF (f)->clear_frame_area (f, from_x, from_y,
24416 to_x - from_x, to_y - from_y);
24417 UNBLOCK_INPUT;
24418 }
24419 }
24420
24421 #endif /* HAVE_WINDOW_SYSTEM */
24422
24423
24424 \f
24425 /***********************************************************************
24426 Cursor types
24427 ***********************************************************************/
24428
24429 /* Value is the internal representation of the specified cursor type
24430 ARG. If type is BAR_CURSOR, return in *WIDTH the specified width
24431 of the bar cursor. */
24432
24433 static enum text_cursor_kinds
24434 get_specified_cursor_type (Lisp_Object arg, int *width)
24435 {
24436 enum text_cursor_kinds type;
24437
24438 if (NILP (arg))
24439 return NO_CURSOR;
24440
24441 if (EQ (arg, Qbox))
24442 return FILLED_BOX_CURSOR;
24443
24444 if (EQ (arg, Qhollow))
24445 return HOLLOW_BOX_CURSOR;
24446
24447 if (EQ (arg, Qbar))
24448 {
24449 *width = 2;
24450 return BAR_CURSOR;
24451 }
24452
24453 if (CONSP (arg)
24454 && EQ (XCAR (arg), Qbar)
24455 && INTEGERP (XCDR (arg))
24456 && XINT (XCDR (arg)) >= 0)
24457 {
24458 *width = XINT (XCDR (arg));
24459 return BAR_CURSOR;
24460 }
24461
24462 if (EQ (arg, Qhbar))
24463 {
24464 *width = 2;
24465 return HBAR_CURSOR;
24466 }
24467
24468 if (CONSP (arg)
24469 && EQ (XCAR (arg), Qhbar)
24470 && INTEGERP (XCDR (arg))
24471 && XINT (XCDR (arg)) >= 0)
24472 {
24473 *width = XINT (XCDR (arg));
24474 return HBAR_CURSOR;
24475 }
24476
24477 /* Treat anything unknown as "hollow box cursor".
24478 It was bad to signal an error; people have trouble fixing
24479 .Xdefaults with Emacs, when it has something bad in it. */
24480 type = HOLLOW_BOX_CURSOR;
24481
24482 return type;
24483 }
24484
24485 /* Set the default cursor types for specified frame. */
24486 void
24487 set_frame_cursor_types (struct frame *f, Lisp_Object arg)
24488 {
24489 int width = 1;
24490 Lisp_Object tem;
24491
24492 FRAME_DESIRED_CURSOR (f) = get_specified_cursor_type (arg, &width);
24493 FRAME_CURSOR_WIDTH (f) = width;
24494
24495 /* By default, set up the blink-off state depending on the on-state. */
24496
24497 tem = Fassoc (arg, Vblink_cursor_alist);
24498 if (!NILP (tem))
24499 {
24500 FRAME_BLINK_OFF_CURSOR (f)
24501 = get_specified_cursor_type (XCDR (tem), &width);
24502 FRAME_BLINK_OFF_CURSOR_WIDTH (f) = width;
24503 }
24504 else
24505 FRAME_BLINK_OFF_CURSOR (f) = DEFAULT_CURSOR;
24506 }
24507
24508
24509 #ifdef HAVE_WINDOW_SYSTEM
24510
24511 /* Return the cursor we want to be displayed in window W. Return
24512 width of bar/hbar cursor through WIDTH arg. Return with
24513 ACTIVE_CURSOR arg set to 1 if cursor in window W is `active'
24514 (i.e. if the `system caret' should track this cursor).
24515
24516 In a mini-buffer window, we want the cursor only to appear if we
24517 are reading input from this window. For the selected window, we
24518 want the cursor type given by the frame parameter or buffer local
24519 setting of cursor-type. If explicitly marked off, draw no cursor.
24520 In all other cases, we want a hollow box cursor. */
24521
24522 static enum text_cursor_kinds
24523 get_window_cursor_type (struct window *w, struct glyph *glyph, int *width,
24524 int *active_cursor)
24525 {
24526 struct frame *f = XFRAME (w->frame);
24527 struct buffer *b = XBUFFER (w->buffer);
24528 int cursor_type = DEFAULT_CURSOR;
24529 Lisp_Object alt_cursor;
24530 int non_selected = 0;
24531
24532 *active_cursor = 1;
24533
24534 /* Echo area */
24535 if (cursor_in_echo_area
24536 && FRAME_HAS_MINIBUF_P (f)
24537 && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
24538 {
24539 if (w == XWINDOW (echo_area_window))
24540 {
24541 if (EQ (BVAR (b, cursor_type), Qt) || NILP (BVAR (b, cursor_type)))
24542 {
24543 *width = FRAME_CURSOR_WIDTH (f);
24544 return FRAME_DESIRED_CURSOR (f);
24545 }
24546 else
24547 return get_specified_cursor_type (BVAR (b, cursor_type), width);
24548 }
24549
24550 *active_cursor = 0;
24551 non_selected = 1;
24552 }
24553
24554 /* Detect a nonselected window or nonselected frame. */
24555 else if (w != XWINDOW (f->selected_window)
24556 || f != FRAME_X_DISPLAY_INFO (f)->x_highlight_frame)
24557 {
24558 *active_cursor = 0;
24559
24560 if (MINI_WINDOW_P (w) && minibuf_level == 0)
24561 return NO_CURSOR;
24562
24563 non_selected = 1;
24564 }
24565
24566 /* Never display a cursor in a window in which cursor-type is nil. */
24567 if (NILP (BVAR (b, cursor_type)))
24568 return NO_CURSOR;
24569
24570 /* Get the normal cursor type for this window. */
24571 if (EQ (BVAR (b, cursor_type), Qt))
24572 {
24573 cursor_type = FRAME_DESIRED_CURSOR (f);
24574 *width = FRAME_CURSOR_WIDTH (f);
24575 }
24576 else
24577 cursor_type = get_specified_cursor_type (BVAR (b, cursor_type), width);
24578
24579 /* Use cursor-in-non-selected-windows instead
24580 for non-selected window or frame. */
24581 if (non_selected)
24582 {
24583 alt_cursor = BVAR (b, cursor_in_non_selected_windows);
24584 if (!EQ (Qt, alt_cursor))
24585 return get_specified_cursor_type (alt_cursor, width);
24586 /* t means modify the normal cursor type. */
24587 if (cursor_type == FILLED_BOX_CURSOR)
24588 cursor_type = HOLLOW_BOX_CURSOR;
24589 else if (cursor_type == BAR_CURSOR && *width > 1)
24590 --*width;
24591 return cursor_type;
24592 }
24593
24594 /* Use normal cursor if not blinked off. */
24595 if (!w->cursor_off_p)
24596 {
24597 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
24598 {
24599 if (cursor_type == FILLED_BOX_CURSOR)
24600 {
24601 /* Using a block cursor on large images can be very annoying.
24602 So use a hollow cursor for "large" images.
24603 If image is not transparent (no mask), also use hollow cursor. */
24604 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
24605 if (img != NULL && IMAGEP (img->spec))
24606 {
24607 /* Arbitrarily, interpret "Large" as >32x32 and >NxN
24608 where N = size of default frame font size.
24609 This should cover most of the "tiny" icons people may use. */
24610 if (!img->mask
24611 || img->width > max (32, WINDOW_FRAME_COLUMN_WIDTH (w))
24612 || img->height > max (32, WINDOW_FRAME_LINE_HEIGHT (w)))
24613 cursor_type = HOLLOW_BOX_CURSOR;
24614 }
24615 }
24616 else if (cursor_type != NO_CURSOR)
24617 {
24618 /* Display current only supports BOX and HOLLOW cursors for images.
24619 So for now, unconditionally use a HOLLOW cursor when cursor is
24620 not a solid box cursor. */
24621 cursor_type = HOLLOW_BOX_CURSOR;
24622 }
24623 }
24624 return cursor_type;
24625 }
24626
24627 /* Cursor is blinked off, so determine how to "toggle" it. */
24628
24629 /* First look for an entry matching the buffer's cursor-type in blink-cursor-alist. */
24630 if ((alt_cursor = Fassoc (BVAR (b, cursor_type), Vblink_cursor_alist), !NILP (alt_cursor)))
24631 return get_specified_cursor_type (XCDR (alt_cursor), width);
24632
24633 /* Then see if frame has specified a specific blink off cursor type. */
24634 if (FRAME_BLINK_OFF_CURSOR (f) != DEFAULT_CURSOR)
24635 {
24636 *width = FRAME_BLINK_OFF_CURSOR_WIDTH (f);
24637 return FRAME_BLINK_OFF_CURSOR (f);
24638 }
24639
24640 #if 0
24641 /* Some people liked having a permanently visible blinking cursor,
24642 while others had very strong opinions against it. So it was
24643 decided to remove it. KFS 2003-09-03 */
24644
24645 /* Finally perform built-in cursor blinking:
24646 filled box <-> hollow box
24647 wide [h]bar <-> narrow [h]bar
24648 narrow [h]bar <-> no cursor
24649 other type <-> no cursor */
24650
24651 if (cursor_type == FILLED_BOX_CURSOR)
24652 return HOLLOW_BOX_CURSOR;
24653
24654 if ((cursor_type == BAR_CURSOR || cursor_type == HBAR_CURSOR) && *width > 1)
24655 {
24656 *width = 1;
24657 return cursor_type;
24658 }
24659 #endif
24660
24661 return NO_CURSOR;
24662 }
24663
24664
24665 /* Notice when the text cursor of window W has been completely
24666 overwritten by a drawing operation that outputs glyphs in AREA
24667 starting at X0 and ending at X1 in the line starting at Y0 and
24668 ending at Y1. X coordinates are area-relative. X1 < 0 means all
24669 the rest of the line after X0 has been written. Y coordinates
24670 are window-relative. */
24671
24672 static void
24673 notice_overwritten_cursor (struct window *w, enum glyph_row_area area,
24674 int x0, int x1, int y0, int y1)
24675 {
24676 int cx0, cx1, cy0, cy1;
24677 struct glyph_row *row;
24678
24679 if (!w->phys_cursor_on_p)
24680 return;
24681 if (area != TEXT_AREA)
24682 return;
24683
24684 if (w->phys_cursor.vpos < 0
24685 || w->phys_cursor.vpos >= w->current_matrix->nrows
24686 || (row = w->current_matrix->rows + w->phys_cursor.vpos,
24687 !(row->enabled_p && row->displays_text_p)))
24688 return;
24689
24690 if (row->cursor_in_fringe_p)
24691 {
24692 row->cursor_in_fringe_p = 0;
24693 draw_fringe_bitmap (w, row, row->reversed_p);
24694 w->phys_cursor_on_p = 0;
24695 return;
24696 }
24697
24698 cx0 = w->phys_cursor.x;
24699 cx1 = cx0 + w->phys_cursor_width;
24700 if (x0 > cx0 || (x1 >= 0 && x1 < cx1))
24701 return;
24702
24703 /* The cursor image will be completely removed from the
24704 screen if the output area intersects the cursor area in
24705 y-direction. When we draw in [y0 y1[, and some part of
24706 the cursor is at y < y0, that part must have been drawn
24707 before. When scrolling, the cursor is erased before
24708 actually scrolling, so we don't come here. When not
24709 scrolling, the rows above the old cursor row must have
24710 changed, and in this case these rows must have written
24711 over the cursor image.
24712
24713 Likewise if part of the cursor is below y1, with the
24714 exception of the cursor being in the first blank row at
24715 the buffer and window end because update_text_area
24716 doesn't draw that row. (Except when it does, but
24717 that's handled in update_text_area.) */
24718
24719 cy0 = w->phys_cursor.y;
24720 cy1 = cy0 + w->phys_cursor_height;
24721 if ((y0 < cy0 || y0 >= cy1) && (y1 <= cy0 || y1 >= cy1))
24722 return;
24723
24724 w->phys_cursor_on_p = 0;
24725 }
24726
24727 #endif /* HAVE_WINDOW_SYSTEM */
24728
24729 \f
24730 /************************************************************************
24731 Mouse Face
24732 ************************************************************************/
24733
24734 #ifdef HAVE_WINDOW_SYSTEM
24735
24736 /* EXPORT for RIF:
24737 Fix the display of area AREA of overlapping row ROW in window W
24738 with respect to the overlapping part OVERLAPS. */
24739
24740 void
24741 x_fix_overlapping_area (struct window *w, struct glyph_row *row,
24742 enum glyph_row_area area, int overlaps)
24743 {
24744 int i, x;
24745
24746 BLOCK_INPUT;
24747
24748 x = 0;
24749 for (i = 0; i < row->used[area];)
24750 {
24751 if (row->glyphs[area][i].overlaps_vertically_p)
24752 {
24753 int start = i, start_x = x;
24754
24755 do
24756 {
24757 x += row->glyphs[area][i].pixel_width;
24758 ++i;
24759 }
24760 while (i < row->used[area]
24761 && row->glyphs[area][i].overlaps_vertically_p);
24762
24763 draw_glyphs (w, start_x, row, area,
24764 start, i,
24765 DRAW_NORMAL_TEXT, overlaps);
24766 }
24767 else
24768 {
24769 x += row->glyphs[area][i].pixel_width;
24770 ++i;
24771 }
24772 }
24773
24774 UNBLOCK_INPUT;
24775 }
24776
24777
24778 /* EXPORT:
24779 Draw the cursor glyph of window W in glyph row ROW. See the
24780 comment of draw_glyphs for the meaning of HL. */
24781
24782 void
24783 draw_phys_cursor_glyph (struct window *w, struct glyph_row *row,
24784 enum draw_glyphs_face hl)
24785 {
24786 /* If cursor hpos is out of bounds, don't draw garbage. This can
24787 happen in mini-buffer windows when switching between echo area
24788 glyphs and mini-buffer. */
24789 if ((row->reversed_p
24790 ? (w->phys_cursor.hpos >= 0)
24791 : (w->phys_cursor.hpos < row->used[TEXT_AREA])))
24792 {
24793 int on_p = w->phys_cursor_on_p;
24794 int x1;
24795 x1 = draw_glyphs (w, w->phys_cursor.x, row, TEXT_AREA,
24796 w->phys_cursor.hpos, w->phys_cursor.hpos + 1,
24797 hl, 0);
24798 w->phys_cursor_on_p = on_p;
24799
24800 if (hl == DRAW_CURSOR)
24801 w->phys_cursor_width = x1 - w->phys_cursor.x;
24802 /* When we erase the cursor, and ROW is overlapped by other
24803 rows, make sure that these overlapping parts of other rows
24804 are redrawn. */
24805 else if (hl == DRAW_NORMAL_TEXT && row->overlapped_p)
24806 {
24807 w->phys_cursor_width = x1 - w->phys_cursor.x;
24808
24809 if (row > w->current_matrix->rows
24810 && MATRIX_ROW_OVERLAPS_SUCC_P (row - 1))
24811 x_fix_overlapping_area (w, row - 1, TEXT_AREA,
24812 OVERLAPS_ERASED_CURSOR);
24813
24814 if (MATRIX_ROW_BOTTOM_Y (row) < window_text_bottom_y (w)
24815 && MATRIX_ROW_OVERLAPS_PRED_P (row + 1))
24816 x_fix_overlapping_area (w, row + 1, TEXT_AREA,
24817 OVERLAPS_ERASED_CURSOR);
24818 }
24819 }
24820 }
24821
24822
24823 /* EXPORT:
24824 Erase the image of a cursor of window W from the screen. */
24825
24826 void
24827 erase_phys_cursor (struct window *w)
24828 {
24829 struct frame *f = XFRAME (w->frame);
24830 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
24831 int hpos = w->phys_cursor.hpos;
24832 int vpos = w->phys_cursor.vpos;
24833 int mouse_face_here_p = 0;
24834 struct glyph_matrix *active_glyphs = w->current_matrix;
24835 struct glyph_row *cursor_row;
24836 struct glyph *cursor_glyph;
24837 enum draw_glyphs_face hl;
24838
24839 /* No cursor displayed or row invalidated => nothing to do on the
24840 screen. */
24841 if (w->phys_cursor_type == NO_CURSOR)
24842 goto mark_cursor_off;
24843
24844 /* VPOS >= active_glyphs->nrows means that window has been resized.
24845 Don't bother to erase the cursor. */
24846 if (vpos >= active_glyphs->nrows)
24847 goto mark_cursor_off;
24848
24849 /* If row containing cursor is marked invalid, there is nothing we
24850 can do. */
24851 cursor_row = MATRIX_ROW (active_glyphs, vpos);
24852 if (!cursor_row->enabled_p)
24853 goto mark_cursor_off;
24854
24855 /* If line spacing is > 0, old cursor may only be partially visible in
24856 window after split-window. So adjust visible height. */
24857 cursor_row->visible_height = min (cursor_row->visible_height,
24858 window_text_bottom_y (w) - cursor_row->y);
24859
24860 /* If row is completely invisible, don't attempt to delete a cursor which
24861 isn't there. This can happen if cursor is at top of a window, and
24862 we switch to a buffer with a header line in that window. */
24863 if (cursor_row->visible_height <= 0)
24864 goto mark_cursor_off;
24865
24866 /* If cursor is in the fringe, erase by drawing actual bitmap there. */
24867 if (cursor_row->cursor_in_fringe_p)
24868 {
24869 cursor_row->cursor_in_fringe_p = 0;
24870 draw_fringe_bitmap (w, cursor_row, cursor_row->reversed_p);
24871 goto mark_cursor_off;
24872 }
24873
24874 /* This can happen when the new row is shorter than the old one.
24875 In this case, either draw_glyphs or clear_end_of_line
24876 should have cleared the cursor. Note that we wouldn't be
24877 able to erase the cursor in this case because we don't have a
24878 cursor glyph at hand. */
24879 if ((cursor_row->reversed_p
24880 ? (w->phys_cursor.hpos < 0)
24881 : (w->phys_cursor.hpos >= cursor_row->used[TEXT_AREA])))
24882 goto mark_cursor_off;
24883
24884 /* If the cursor is in the mouse face area, redisplay that when
24885 we clear the cursor. */
24886 if (! NILP (hlinfo->mouse_face_window)
24887 && coords_in_mouse_face_p (w, hpos, vpos)
24888 /* Don't redraw the cursor's spot in mouse face if it is at the
24889 end of a line (on a newline). The cursor appears there, but
24890 mouse highlighting does not. */
24891 && cursor_row->used[TEXT_AREA] > hpos && hpos >= 0)
24892 mouse_face_here_p = 1;
24893
24894 /* Maybe clear the display under the cursor. */
24895 if (w->phys_cursor_type == HOLLOW_BOX_CURSOR)
24896 {
24897 int x, y, left_x;
24898 int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
24899 int width;
24900
24901 cursor_glyph = get_phys_cursor_glyph (w);
24902 if (cursor_glyph == NULL)
24903 goto mark_cursor_off;
24904
24905 width = cursor_glyph->pixel_width;
24906 left_x = window_box_left_offset (w, TEXT_AREA);
24907 x = w->phys_cursor.x;
24908 if (x < left_x)
24909 width -= left_x - x;
24910 width = min (width, window_box_width (w, TEXT_AREA) - x);
24911 y = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, cursor_row->y));
24912 x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, max (x, left_x));
24913
24914 if (width > 0)
24915 FRAME_RIF (f)->clear_frame_area (f, x, y, width, cursor_row->visible_height);
24916 }
24917
24918 /* Erase the cursor by redrawing the character underneath it. */
24919 if (mouse_face_here_p)
24920 hl = DRAW_MOUSE_FACE;
24921 else
24922 hl = DRAW_NORMAL_TEXT;
24923 draw_phys_cursor_glyph (w, cursor_row, hl);
24924
24925 mark_cursor_off:
24926 w->phys_cursor_on_p = 0;
24927 w->phys_cursor_type = NO_CURSOR;
24928 }
24929
24930
24931 /* EXPORT:
24932 Display or clear cursor of window W. If ON is zero, clear the
24933 cursor. If it is non-zero, display the cursor. If ON is nonzero,
24934 where to put the cursor is specified by HPOS, VPOS, X and Y. */
24935
24936 void
24937 display_and_set_cursor (struct window *w, int on,
24938 int hpos, int vpos, int x, int y)
24939 {
24940 struct frame *f = XFRAME (w->frame);
24941 int new_cursor_type;
24942 int new_cursor_width;
24943 int active_cursor;
24944 struct glyph_row *glyph_row;
24945 struct glyph *glyph;
24946
24947 /* This is pointless on invisible frames, and dangerous on garbaged
24948 windows and frames; in the latter case, the frame or window may
24949 be in the midst of changing its size, and x and y may be off the
24950 window. */
24951 if (! FRAME_VISIBLE_P (f)
24952 || FRAME_GARBAGED_P (f)
24953 || vpos >= w->current_matrix->nrows
24954 || hpos >= w->current_matrix->matrix_w)
24955 return;
24956
24957 /* If cursor is off and we want it off, return quickly. */
24958 if (!on && !w->phys_cursor_on_p)
24959 return;
24960
24961 glyph_row = MATRIX_ROW (w->current_matrix, vpos);
24962 /* If cursor row is not enabled, we don't really know where to
24963 display the cursor. */
24964 if (!glyph_row->enabled_p)
24965 {
24966 w->phys_cursor_on_p = 0;
24967 return;
24968 }
24969
24970 glyph = NULL;
24971 if (!glyph_row->exact_window_width_line_p
24972 || (0 <= hpos && hpos < glyph_row->used[TEXT_AREA]))
24973 glyph = glyph_row->glyphs[TEXT_AREA] + hpos;
24974
24975 xassert (interrupt_input_blocked);
24976
24977 /* Set new_cursor_type to the cursor we want to be displayed. */
24978 new_cursor_type = get_window_cursor_type (w, glyph,
24979 &new_cursor_width, &active_cursor);
24980
24981 /* If cursor is currently being shown and we don't want it to be or
24982 it is in the wrong place, or the cursor type is not what we want,
24983 erase it. */
24984 if (w->phys_cursor_on_p
24985 && (!on
24986 || w->phys_cursor.x != x
24987 || w->phys_cursor.y != y
24988 || new_cursor_type != w->phys_cursor_type
24989 || ((new_cursor_type == BAR_CURSOR || new_cursor_type == HBAR_CURSOR)
24990 && new_cursor_width != w->phys_cursor_width)))
24991 erase_phys_cursor (w);
24992
24993 /* Don't check phys_cursor_on_p here because that flag is only set
24994 to zero in some cases where we know that the cursor has been
24995 completely erased, to avoid the extra work of erasing the cursor
24996 twice. In other words, phys_cursor_on_p can be 1 and the cursor
24997 still not be visible, or it has only been partly erased. */
24998 if (on)
24999 {
25000 w->phys_cursor_ascent = glyph_row->ascent;
25001 w->phys_cursor_height = glyph_row->height;
25002
25003 /* Set phys_cursor_.* before x_draw_.* is called because some
25004 of them may need the information. */
25005 w->phys_cursor.x = x;
25006 w->phys_cursor.y = glyph_row->y;
25007 w->phys_cursor.hpos = hpos;
25008 w->phys_cursor.vpos = vpos;
25009 }
25010
25011 FRAME_RIF (f)->draw_window_cursor (w, glyph_row, x, y,
25012 new_cursor_type, new_cursor_width,
25013 on, active_cursor);
25014 }
25015
25016
25017 /* Switch the display of W's cursor on or off, according to the value
25018 of ON. */
25019
25020 static void
25021 update_window_cursor (struct window *w, int on)
25022 {
25023 /* Don't update cursor in windows whose frame is in the process
25024 of being deleted. */
25025 if (w->current_matrix)
25026 {
25027 BLOCK_INPUT;
25028 display_and_set_cursor (w, on, w->phys_cursor.hpos, w->phys_cursor.vpos,
25029 w->phys_cursor.x, w->phys_cursor.y);
25030 UNBLOCK_INPUT;
25031 }
25032 }
25033
25034
25035 /* Call update_window_cursor with parameter ON_P on all leaf windows
25036 in the window tree rooted at W. */
25037
25038 static void
25039 update_cursor_in_window_tree (struct window *w, int on_p)
25040 {
25041 while (w)
25042 {
25043 if (!NILP (w->hchild))
25044 update_cursor_in_window_tree (XWINDOW (w->hchild), on_p);
25045 else if (!NILP (w->vchild))
25046 update_cursor_in_window_tree (XWINDOW (w->vchild), on_p);
25047 else
25048 update_window_cursor (w, on_p);
25049
25050 w = NILP (w->next) ? 0 : XWINDOW (w->next);
25051 }
25052 }
25053
25054
25055 /* EXPORT:
25056 Display the cursor on window W, or clear it, according to ON_P.
25057 Don't change the cursor's position. */
25058
25059 void
25060 x_update_cursor (struct frame *f, int on_p)
25061 {
25062 update_cursor_in_window_tree (XWINDOW (f->root_window), on_p);
25063 }
25064
25065
25066 /* EXPORT:
25067 Clear the cursor of window W to background color, and mark the
25068 cursor as not shown. This is used when the text where the cursor
25069 is about to be rewritten. */
25070
25071 void
25072 x_clear_cursor (struct window *w)
25073 {
25074 if (FRAME_VISIBLE_P (XFRAME (w->frame)) && w->phys_cursor_on_p)
25075 update_window_cursor (w, 0);
25076 }
25077
25078 #endif /* HAVE_WINDOW_SYSTEM */
25079
25080 /* Implementation of draw_row_with_mouse_face for GUI sessions, GPM,
25081 and MSDOS. */
25082 static void
25083 draw_row_with_mouse_face (struct window *w, int start_x, struct glyph_row *row,
25084 int start_hpos, int end_hpos,
25085 enum draw_glyphs_face draw)
25086 {
25087 #ifdef HAVE_WINDOW_SYSTEM
25088 if (FRAME_WINDOW_P (XFRAME (w->frame)))
25089 {
25090 draw_glyphs (w, start_x, row, TEXT_AREA, start_hpos, end_hpos, draw, 0);
25091 return;
25092 }
25093 #endif
25094 #if defined (HAVE_GPM) || defined (MSDOS)
25095 tty_draw_row_with_mouse_face (w, row, start_hpos, end_hpos, draw);
25096 #endif
25097 }
25098
25099 /* Display the active region described by mouse_face_* according to DRAW. */
25100
25101 static void
25102 show_mouse_face (Mouse_HLInfo *hlinfo, enum draw_glyphs_face draw)
25103 {
25104 struct window *w = XWINDOW (hlinfo->mouse_face_window);
25105 struct frame *f = XFRAME (WINDOW_FRAME (w));
25106
25107 if (/* If window is in the process of being destroyed, don't bother
25108 to do anything. */
25109 w->current_matrix != NULL
25110 /* Don't update mouse highlight if hidden */
25111 && (draw != DRAW_MOUSE_FACE || !hlinfo->mouse_face_hidden)
25112 /* Recognize when we are called to operate on rows that don't exist
25113 anymore. This can happen when a window is split. */
25114 && hlinfo->mouse_face_end_row < w->current_matrix->nrows)
25115 {
25116 int phys_cursor_on_p = w->phys_cursor_on_p;
25117 struct glyph_row *row, *first, *last;
25118
25119 first = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_beg_row);
25120 last = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_end_row);
25121
25122 for (row = first; row <= last && row->enabled_p; ++row)
25123 {
25124 int start_hpos, end_hpos, start_x;
25125
25126 /* For all but the first row, the highlight starts at column 0. */
25127 if (row == first)
25128 {
25129 /* R2L rows have BEG and END in reversed order, but the
25130 screen drawing geometry is always left to right. So
25131 we need to mirror the beginning and end of the
25132 highlighted area in R2L rows. */
25133 if (!row->reversed_p)
25134 {
25135 start_hpos = hlinfo->mouse_face_beg_col;
25136 start_x = hlinfo->mouse_face_beg_x;
25137 }
25138 else if (row == last)
25139 {
25140 start_hpos = hlinfo->mouse_face_end_col;
25141 start_x = hlinfo->mouse_face_end_x;
25142 }
25143 else
25144 {
25145 start_hpos = 0;
25146 start_x = 0;
25147 }
25148 }
25149 else if (row->reversed_p && row == last)
25150 {
25151 start_hpos = hlinfo->mouse_face_end_col;
25152 start_x = hlinfo->mouse_face_end_x;
25153 }
25154 else
25155 {
25156 start_hpos = 0;
25157 start_x = 0;
25158 }
25159
25160 if (row == last)
25161 {
25162 if (!row->reversed_p)
25163 end_hpos = hlinfo->mouse_face_end_col;
25164 else if (row == first)
25165 end_hpos = hlinfo->mouse_face_beg_col;
25166 else
25167 {
25168 end_hpos = row->used[TEXT_AREA];
25169 if (draw == DRAW_NORMAL_TEXT)
25170 row->fill_line_p = 1; /* Clear to end of line */
25171 }
25172 }
25173 else if (row->reversed_p && row == first)
25174 end_hpos = hlinfo->mouse_face_beg_col;
25175 else
25176 {
25177 end_hpos = row->used[TEXT_AREA];
25178 if (draw == DRAW_NORMAL_TEXT)
25179 row->fill_line_p = 1; /* Clear to end of line */
25180 }
25181
25182 if (end_hpos > start_hpos)
25183 {
25184 draw_row_with_mouse_face (w, start_x, row,
25185 start_hpos, end_hpos, draw);
25186
25187 row->mouse_face_p
25188 = draw == DRAW_MOUSE_FACE || draw == DRAW_IMAGE_RAISED;
25189 }
25190 }
25191
25192 #ifdef HAVE_WINDOW_SYSTEM
25193 /* When we've written over the cursor, arrange for it to
25194 be displayed again. */
25195 if (FRAME_WINDOW_P (f)
25196 && phys_cursor_on_p && !w->phys_cursor_on_p)
25197 {
25198 BLOCK_INPUT;
25199 display_and_set_cursor (w, 1,
25200 w->phys_cursor.hpos, w->phys_cursor.vpos,
25201 w->phys_cursor.x, w->phys_cursor.y);
25202 UNBLOCK_INPUT;
25203 }
25204 #endif /* HAVE_WINDOW_SYSTEM */
25205 }
25206
25207 #ifdef HAVE_WINDOW_SYSTEM
25208 /* Change the mouse cursor. */
25209 if (FRAME_WINDOW_P (f))
25210 {
25211 if (draw == DRAW_NORMAL_TEXT
25212 && !EQ (hlinfo->mouse_face_window, f->tool_bar_window))
25213 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->text_cursor);
25214 else if (draw == DRAW_MOUSE_FACE)
25215 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->hand_cursor);
25216 else
25217 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->nontext_cursor);
25218 }
25219 #endif /* HAVE_WINDOW_SYSTEM */
25220 }
25221
25222 /* EXPORT:
25223 Clear out the mouse-highlighted active region.
25224 Redraw it un-highlighted first. Value is non-zero if mouse
25225 face was actually drawn unhighlighted. */
25226
25227 int
25228 clear_mouse_face (Mouse_HLInfo *hlinfo)
25229 {
25230 int cleared = 0;
25231
25232 if (!hlinfo->mouse_face_hidden && !NILP (hlinfo->mouse_face_window))
25233 {
25234 show_mouse_face (hlinfo, DRAW_NORMAL_TEXT);
25235 cleared = 1;
25236 }
25237
25238 hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
25239 hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
25240 hlinfo->mouse_face_window = Qnil;
25241 hlinfo->mouse_face_overlay = Qnil;
25242 return cleared;
25243 }
25244
25245 /* Return non-zero if the coordinates HPOS and VPOS on windows W are
25246 within the mouse face on that window. */
25247 static int
25248 coords_in_mouse_face_p (struct window *w, int hpos, int vpos)
25249 {
25250 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame));
25251
25252 /* Quickly resolve the easy cases. */
25253 if (!(WINDOWP (hlinfo->mouse_face_window)
25254 && XWINDOW (hlinfo->mouse_face_window) == w))
25255 return 0;
25256 if (vpos < hlinfo->mouse_face_beg_row
25257 || vpos > hlinfo->mouse_face_end_row)
25258 return 0;
25259 if (vpos > hlinfo->mouse_face_beg_row
25260 && vpos < hlinfo->mouse_face_end_row)
25261 return 1;
25262
25263 if (!MATRIX_ROW (w->current_matrix, vpos)->reversed_p)
25264 {
25265 if (hlinfo->mouse_face_beg_row == hlinfo->mouse_face_end_row)
25266 {
25267 if (hlinfo->mouse_face_beg_col <= hpos && hpos < hlinfo->mouse_face_end_col)
25268 return 1;
25269 }
25270 else if ((vpos == hlinfo->mouse_face_beg_row
25271 && hpos >= hlinfo->mouse_face_beg_col)
25272 || (vpos == hlinfo->mouse_face_end_row
25273 && hpos < hlinfo->mouse_face_end_col))
25274 return 1;
25275 }
25276 else
25277 {
25278 if (hlinfo->mouse_face_beg_row == hlinfo->mouse_face_end_row)
25279 {
25280 if (hlinfo->mouse_face_end_col < hpos && hpos <= hlinfo->mouse_face_beg_col)
25281 return 1;
25282 }
25283 else if ((vpos == hlinfo->mouse_face_beg_row
25284 && hpos <= hlinfo->mouse_face_beg_col)
25285 || (vpos == hlinfo->mouse_face_end_row
25286 && hpos > hlinfo->mouse_face_end_col))
25287 return 1;
25288 }
25289 return 0;
25290 }
25291
25292
25293 /* EXPORT:
25294 Non-zero if physical cursor of window W is within mouse face. */
25295
25296 int
25297 cursor_in_mouse_face_p (struct window *w)
25298 {
25299 return coords_in_mouse_face_p (w, w->phys_cursor.hpos, w->phys_cursor.vpos);
25300 }
25301
25302
25303 \f
25304 /* Find the glyph rows START_ROW and END_ROW of window W that display
25305 characters between buffer positions START_CHARPOS and END_CHARPOS
25306 (excluding END_CHARPOS). This is similar to row_containing_pos,
25307 but is more accurate when bidi reordering makes buffer positions
25308 change non-linearly with glyph rows. */
25309 static void
25310 rows_from_pos_range (struct window *w,
25311 EMACS_INT start_charpos, EMACS_INT end_charpos,
25312 struct glyph_row **start, struct glyph_row **end)
25313 {
25314 struct glyph_row *first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
25315 int last_y = window_text_bottom_y (w);
25316 struct glyph_row *row;
25317
25318 *start = NULL;
25319 *end = NULL;
25320
25321 while (!first->enabled_p
25322 && first < MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w))
25323 first++;
25324
25325 /* Find the START row. */
25326 for (row = first;
25327 row->enabled_p && MATRIX_ROW_BOTTOM_Y (row) <= last_y;
25328 row++)
25329 {
25330 /* A row can potentially be the START row if the range of the
25331 characters it displays intersects the range
25332 [START_CHARPOS..END_CHARPOS). */
25333 if (! ((start_charpos < MATRIX_ROW_START_CHARPOS (row)
25334 && end_charpos < MATRIX_ROW_START_CHARPOS (row))
25335 /* See the commentary in row_containing_pos, for the
25336 explanation of the complicated way to check whether
25337 some position is beyond the end of the characters
25338 displayed by a row. */
25339 || ((start_charpos > MATRIX_ROW_END_CHARPOS (row)
25340 || (start_charpos == MATRIX_ROW_END_CHARPOS (row)
25341 && !row->ends_at_zv_p
25342 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
25343 && (end_charpos > MATRIX_ROW_END_CHARPOS (row)
25344 || (end_charpos == MATRIX_ROW_END_CHARPOS (row)
25345 && !row->ends_at_zv_p
25346 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))))))
25347 {
25348 /* Found a candidate row. Now make sure at least one of the
25349 glyphs it displays has a charpos from the range
25350 [START_CHARPOS..END_CHARPOS).
25351
25352 This is not obvious because bidi reordering could make
25353 buffer positions of a row be 1,2,3,102,101,100, and if we
25354 want to highlight characters in [50..60), we don't want
25355 this row, even though [50..60) does intersect [1..103),
25356 the range of character positions given by the row's start
25357 and end positions. */
25358 struct glyph *g = row->glyphs[TEXT_AREA];
25359 struct glyph *e = g + row->used[TEXT_AREA];
25360
25361 while (g < e)
25362 {
25363 if ((BUFFERP (g->object) || INTEGERP (g->object))
25364 && start_charpos <= g->charpos && g->charpos < end_charpos)
25365 *start = row;
25366 g++;
25367 }
25368 if (*start)
25369 break;
25370 }
25371 }
25372
25373 /* Find the END row. */
25374 if (!*start
25375 /* If the last row is partially visible, start looking for END
25376 from that row, instead of starting from FIRST. */
25377 && !(row->enabled_p
25378 && row->y < last_y && MATRIX_ROW_BOTTOM_Y (row) > last_y))
25379 row = first;
25380 for ( ; row->enabled_p && MATRIX_ROW_BOTTOM_Y (row) <= last_y; row++)
25381 {
25382 struct glyph_row *next = row + 1;
25383
25384 if (!next->enabled_p
25385 || next >= MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w)
25386 /* The first row >= START whose range of displayed characters
25387 does NOT intersect the range [START_CHARPOS..END_CHARPOS]
25388 is the row END + 1. */
25389 || (start_charpos < MATRIX_ROW_START_CHARPOS (next)
25390 && end_charpos < MATRIX_ROW_START_CHARPOS (next))
25391 || ((start_charpos > MATRIX_ROW_END_CHARPOS (next)
25392 || (start_charpos == MATRIX_ROW_END_CHARPOS (next)
25393 && !next->ends_at_zv_p
25394 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (next)))
25395 && (end_charpos > MATRIX_ROW_END_CHARPOS (next)
25396 || (end_charpos == MATRIX_ROW_END_CHARPOS (next)
25397 && !next->ends_at_zv_p
25398 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (next)))))
25399 {
25400 *end = row;
25401 break;
25402 }
25403 else
25404 {
25405 /* If the next row's edges intersect [START_CHARPOS..END_CHARPOS],
25406 but none of the characters it displays are in the range, it is
25407 also END + 1. */
25408 struct glyph *g = next->glyphs[TEXT_AREA];
25409 struct glyph *e = g + next->used[TEXT_AREA];
25410
25411 while (g < e)
25412 {
25413 if ((BUFFERP (g->object) || INTEGERP (g->object))
25414 && start_charpos <= g->charpos && g->charpos < end_charpos)
25415 break;
25416 g++;
25417 }
25418 if (g == e)
25419 {
25420 *end = row;
25421 break;
25422 }
25423 }
25424 }
25425 }
25426
25427 /* This function sets the mouse_face_* elements of HLINFO, assuming
25428 the mouse cursor is on a glyph with buffer charpos MOUSE_CHARPOS in
25429 window WINDOW. START_CHARPOS and END_CHARPOS are buffer positions
25430 for the overlay or run of text properties specifying the mouse
25431 face. BEFORE_STRING and AFTER_STRING, if non-nil, are a
25432 before-string and after-string that must also be highlighted.
25433 COVER_STRING, if non-nil, is a display string that may cover some
25434 or all of the highlighted text. */
25435
25436 static void
25437 mouse_face_from_buffer_pos (Lisp_Object window,
25438 Mouse_HLInfo *hlinfo,
25439 EMACS_INT mouse_charpos,
25440 EMACS_INT start_charpos,
25441 EMACS_INT end_charpos,
25442 Lisp_Object before_string,
25443 Lisp_Object after_string,
25444 Lisp_Object cover_string)
25445 {
25446 struct window *w = XWINDOW (window);
25447 struct glyph_row *first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
25448 struct glyph_row *r1, *r2;
25449 struct glyph *glyph, *end;
25450 EMACS_INT ignore, pos;
25451 int x;
25452
25453 xassert (NILP (cover_string) || STRINGP (cover_string));
25454 xassert (NILP (before_string) || STRINGP (before_string));
25455 xassert (NILP (after_string) || STRINGP (after_string));
25456
25457 /* Find the rows corresponding to START_CHARPOS and END_CHARPOS. */
25458 rows_from_pos_range (w, start_charpos, end_charpos, &r1, &r2);
25459 if (r1 == NULL)
25460 r1 = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
25461 /* If the before-string or display-string contains newlines,
25462 rows_from_pos_range skips to its last row. Move back. */
25463 if (!NILP (before_string) || !NILP (cover_string))
25464 {
25465 struct glyph_row *prev;
25466 while ((prev = r1 - 1, prev >= first)
25467 && MATRIX_ROW_END_CHARPOS (prev) == start_charpos
25468 && prev->used[TEXT_AREA] > 0)
25469 {
25470 struct glyph *beg = prev->glyphs[TEXT_AREA];
25471 glyph = beg + prev->used[TEXT_AREA];
25472 while (--glyph >= beg && INTEGERP (glyph->object));
25473 if (glyph < beg
25474 || !(EQ (glyph->object, before_string)
25475 || EQ (glyph->object, cover_string)))
25476 break;
25477 r1 = prev;
25478 }
25479 }
25480 if (r2 == NULL)
25481 {
25482 r2 = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
25483 hlinfo->mouse_face_past_end = 1;
25484 }
25485 else if (!NILP (after_string))
25486 {
25487 /* If the after-string has newlines, advance to its last row. */
25488 struct glyph_row *next;
25489 struct glyph_row *last
25490 = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
25491
25492 for (next = r2 + 1;
25493 next <= last
25494 && next->used[TEXT_AREA] > 0
25495 && EQ (next->glyphs[TEXT_AREA]->object, after_string);
25496 ++next)
25497 r2 = next;
25498 }
25499 /* The rest of the display engine assumes that mouse_face_beg_row is
25500 either above below mouse_face_end_row or identical to it. But
25501 with bidi-reordered continued lines, the row for START_CHARPOS
25502 could be below the row for END_CHARPOS. If so, swap the rows and
25503 store them in correct order. */
25504 if (r1->y > r2->y)
25505 {
25506 struct glyph_row *tem = r2;
25507
25508 r2 = r1;
25509 r1 = tem;
25510 }
25511
25512 hlinfo->mouse_face_beg_y = r1->y;
25513 hlinfo->mouse_face_beg_row = MATRIX_ROW_VPOS (r1, w->current_matrix);
25514 hlinfo->mouse_face_end_y = r2->y;
25515 hlinfo->mouse_face_end_row = MATRIX_ROW_VPOS (r2, w->current_matrix);
25516
25517 /* For a bidi-reordered row, the positions of BEFORE_STRING,
25518 AFTER_STRING, COVER_STRING, START_CHARPOS, and END_CHARPOS
25519 could be anywhere in the row and in any order. The strategy
25520 below is to find the leftmost and the rightmost glyph that
25521 belongs to either of these 3 strings, or whose position is
25522 between START_CHARPOS and END_CHARPOS, and highlight all the
25523 glyphs between those two. This may cover more than just the text
25524 between START_CHARPOS and END_CHARPOS if the range of characters
25525 strides the bidi level boundary, e.g. if the beginning is in R2L
25526 text while the end is in L2R text or vice versa. */
25527 if (!r1->reversed_p)
25528 {
25529 /* This row is in a left to right paragraph. Scan it left to
25530 right. */
25531 glyph = r1->glyphs[TEXT_AREA];
25532 end = glyph + r1->used[TEXT_AREA];
25533 x = r1->x;
25534
25535 /* Skip truncation glyphs at the start of the glyph row. */
25536 if (r1->displays_text_p)
25537 for (; glyph < end
25538 && INTEGERP (glyph->object)
25539 && glyph->charpos < 0;
25540 ++glyph)
25541 x += glyph->pixel_width;
25542
25543 /* Scan the glyph row, looking for BEFORE_STRING, AFTER_STRING,
25544 or COVER_STRING, and the first glyph from buffer whose
25545 position is between START_CHARPOS and END_CHARPOS. */
25546 for (; glyph < end
25547 && !INTEGERP (glyph->object)
25548 && !EQ (glyph->object, cover_string)
25549 && !(BUFFERP (glyph->object)
25550 && (glyph->charpos >= start_charpos
25551 && glyph->charpos < end_charpos));
25552 ++glyph)
25553 {
25554 /* BEFORE_STRING or AFTER_STRING are only relevant if they
25555 are present at buffer positions between START_CHARPOS and
25556 END_CHARPOS, or if they come from an overlay. */
25557 if (EQ (glyph->object, before_string))
25558 {
25559 pos = string_buffer_position (before_string,
25560 start_charpos);
25561 /* If pos == 0, it means before_string came from an
25562 overlay, not from a buffer position. */
25563 if (!pos || (pos >= start_charpos && pos < end_charpos))
25564 break;
25565 }
25566 else if (EQ (glyph->object, after_string))
25567 {
25568 pos = string_buffer_position (after_string, end_charpos);
25569 if (!pos || (pos >= start_charpos && pos < end_charpos))
25570 break;
25571 }
25572 x += glyph->pixel_width;
25573 }
25574 hlinfo->mouse_face_beg_x = x;
25575 hlinfo->mouse_face_beg_col = glyph - r1->glyphs[TEXT_AREA];
25576 }
25577 else
25578 {
25579 /* This row is in a right to left paragraph. Scan it right to
25580 left. */
25581 struct glyph *g;
25582
25583 end = r1->glyphs[TEXT_AREA] - 1;
25584 glyph = end + r1->used[TEXT_AREA];
25585
25586 /* Skip truncation glyphs at the start of the glyph row. */
25587 if (r1->displays_text_p)
25588 for (; glyph > end
25589 && INTEGERP (glyph->object)
25590 && glyph->charpos < 0;
25591 --glyph)
25592 ;
25593
25594 /* Scan the glyph row, looking for BEFORE_STRING, AFTER_STRING,
25595 or COVER_STRING, and the first glyph from buffer whose
25596 position is between START_CHARPOS and END_CHARPOS. */
25597 for (; glyph > end
25598 && !INTEGERP (glyph->object)
25599 && !EQ (glyph->object, cover_string)
25600 && !(BUFFERP (glyph->object)
25601 && (glyph->charpos >= start_charpos
25602 && glyph->charpos < end_charpos));
25603 --glyph)
25604 {
25605 /* BEFORE_STRING or AFTER_STRING are only relevant if they
25606 are present at buffer positions between START_CHARPOS and
25607 END_CHARPOS, or if they come from an overlay. */
25608 if (EQ (glyph->object, before_string))
25609 {
25610 pos = string_buffer_position (before_string, start_charpos);
25611 /* If pos == 0, it means before_string came from an
25612 overlay, not from a buffer position. */
25613 if (!pos || (pos >= start_charpos && pos < end_charpos))
25614 break;
25615 }
25616 else if (EQ (glyph->object, after_string))
25617 {
25618 pos = string_buffer_position (after_string, end_charpos);
25619 if (!pos || (pos >= start_charpos && pos < end_charpos))
25620 break;
25621 }
25622 }
25623
25624 glyph++; /* first glyph to the right of the highlighted area */
25625 for (g = r1->glyphs[TEXT_AREA], x = r1->x; g < glyph; g++)
25626 x += g->pixel_width;
25627 hlinfo->mouse_face_beg_x = x;
25628 hlinfo->mouse_face_beg_col = glyph - r1->glyphs[TEXT_AREA];
25629 }
25630
25631 /* If the highlight ends in a different row, compute GLYPH and END
25632 for the end row. Otherwise, reuse the values computed above for
25633 the row where the highlight begins. */
25634 if (r2 != r1)
25635 {
25636 if (!r2->reversed_p)
25637 {
25638 glyph = r2->glyphs[TEXT_AREA];
25639 end = glyph + r2->used[TEXT_AREA];
25640 x = r2->x;
25641 }
25642 else
25643 {
25644 end = r2->glyphs[TEXT_AREA] - 1;
25645 glyph = end + r2->used[TEXT_AREA];
25646 }
25647 }
25648
25649 if (!r2->reversed_p)
25650 {
25651 /* Skip truncation and continuation glyphs near the end of the
25652 row, and also blanks and stretch glyphs inserted by
25653 extend_face_to_end_of_line. */
25654 while (end > glyph
25655 && INTEGERP ((end - 1)->object)
25656 && (end - 1)->charpos <= 0)
25657 --end;
25658 /* Scan the rest of the glyph row from the end, looking for the
25659 first glyph that comes from BEFORE_STRING, AFTER_STRING, or
25660 COVER_STRING, or whose position is between START_CHARPOS
25661 and END_CHARPOS */
25662 for (--end;
25663 end > glyph
25664 && !INTEGERP (end->object)
25665 && !EQ (end->object, cover_string)
25666 && !(BUFFERP (end->object)
25667 && (end->charpos >= start_charpos
25668 && end->charpos < end_charpos));
25669 --end)
25670 {
25671 /* BEFORE_STRING or AFTER_STRING are only relevant if they
25672 are present at buffer positions between START_CHARPOS and
25673 END_CHARPOS, or if they come from an overlay. */
25674 if (EQ (end->object, before_string))
25675 {
25676 pos = string_buffer_position (before_string, start_charpos);
25677 if (!pos || (pos >= start_charpos && pos < end_charpos))
25678 break;
25679 }
25680 else if (EQ (end->object, after_string))
25681 {
25682 pos = string_buffer_position (after_string, end_charpos);
25683 if (!pos || (pos >= start_charpos && pos < end_charpos))
25684 break;
25685 }
25686 }
25687 /* Find the X coordinate of the last glyph to be highlighted. */
25688 for (; glyph <= end; ++glyph)
25689 x += glyph->pixel_width;
25690
25691 hlinfo->mouse_face_end_x = x;
25692 hlinfo->mouse_face_end_col = glyph - r2->glyphs[TEXT_AREA];
25693 }
25694 else
25695 {
25696 /* Skip truncation and continuation glyphs near the end of the
25697 row, and also blanks and stretch glyphs inserted by
25698 extend_face_to_end_of_line. */
25699 x = r2->x;
25700 end++;
25701 while (end < glyph
25702 && INTEGERP (end->object)
25703 && end->charpos <= 0)
25704 {
25705 x += end->pixel_width;
25706 ++end;
25707 }
25708 /* Scan the rest of the glyph row from the end, looking for the
25709 first glyph that comes from BEFORE_STRING, AFTER_STRING, or
25710 COVER_STRING, or whose position is between START_CHARPOS
25711 and END_CHARPOS */
25712 for ( ;
25713 end < glyph
25714 && !INTEGERP (end->object)
25715 && !EQ (end->object, cover_string)
25716 && !(BUFFERP (end->object)
25717 && (end->charpos >= start_charpos
25718 && end->charpos < end_charpos));
25719 ++end)
25720 {
25721 /* BEFORE_STRING or AFTER_STRING are only relevant if they
25722 are present at buffer positions between START_CHARPOS and
25723 END_CHARPOS, or if they come from an overlay. */
25724 if (EQ (end->object, before_string))
25725 {
25726 pos = string_buffer_position (before_string, start_charpos);
25727 if (!pos || (pos >= start_charpos && pos < end_charpos))
25728 break;
25729 }
25730 else if (EQ (end->object, after_string))
25731 {
25732 pos = string_buffer_position (after_string, end_charpos);
25733 if (!pos || (pos >= start_charpos && pos < end_charpos))
25734 break;
25735 }
25736 x += end->pixel_width;
25737 }
25738 hlinfo->mouse_face_end_x = x;
25739 hlinfo->mouse_face_end_col = end - r2->glyphs[TEXT_AREA];
25740 }
25741
25742 hlinfo->mouse_face_window = window;
25743 hlinfo->mouse_face_face_id
25744 = face_at_buffer_position (w, mouse_charpos, 0, 0, &ignore,
25745 mouse_charpos + 1,
25746 !hlinfo->mouse_face_hidden, -1);
25747 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
25748 }
25749
25750 /* The following function is not used anymore (replaced with
25751 mouse_face_from_string_pos), but I leave it here for the time
25752 being, in case someone would. */
25753
25754 #if 0 /* not used */
25755
25756 /* Find the position of the glyph for position POS in OBJECT in
25757 window W's current matrix, and return in *X, *Y the pixel
25758 coordinates, and return in *HPOS, *VPOS the column/row of the glyph.
25759
25760 RIGHT_P non-zero means return the position of the right edge of the
25761 glyph, RIGHT_P zero means return the left edge position.
25762
25763 If no glyph for POS exists in the matrix, return the position of
25764 the glyph with the next smaller position that is in the matrix, if
25765 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS
25766 exists in the matrix, return the position of the glyph with the
25767 next larger position in OBJECT.
25768
25769 Value is non-zero if a glyph was found. */
25770
25771 static int
25772 fast_find_string_pos (struct window *w, EMACS_INT pos, Lisp_Object object,
25773 int *hpos, int *vpos, int *x, int *y, int right_p)
25774 {
25775 int yb = window_text_bottom_y (w);
25776 struct glyph_row *r;
25777 struct glyph *best_glyph = NULL;
25778 struct glyph_row *best_row = NULL;
25779 int best_x = 0;
25780
25781 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
25782 r->enabled_p && r->y < yb;
25783 ++r)
25784 {
25785 struct glyph *g = r->glyphs[TEXT_AREA];
25786 struct glyph *e = g + r->used[TEXT_AREA];
25787 int gx;
25788
25789 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
25790 if (EQ (g->object, object))
25791 {
25792 if (g->charpos == pos)
25793 {
25794 best_glyph = g;
25795 best_x = gx;
25796 best_row = r;
25797 goto found;
25798 }
25799 else if (best_glyph == NULL
25800 || ((eabs (g->charpos - pos)
25801 < eabs (best_glyph->charpos - pos))
25802 && (right_p
25803 ? g->charpos < pos
25804 : g->charpos > pos)))
25805 {
25806 best_glyph = g;
25807 best_x = gx;
25808 best_row = r;
25809 }
25810 }
25811 }
25812
25813 found:
25814
25815 if (best_glyph)
25816 {
25817 *x = best_x;
25818 *hpos = best_glyph - best_row->glyphs[TEXT_AREA];
25819
25820 if (right_p)
25821 {
25822 *x += best_glyph->pixel_width;
25823 ++*hpos;
25824 }
25825
25826 *y = best_row->y;
25827 *vpos = best_row - w->current_matrix->rows;
25828 }
25829
25830 return best_glyph != NULL;
25831 }
25832 #endif /* not used */
25833
25834 /* Find the positions of the first and the last glyphs in window W's
25835 current matrix that occlude positions [STARTPOS..ENDPOS] in OBJECT
25836 (assumed to be a string), and return in HLINFO's mouse_face_*
25837 members the pixel and column/row coordinates of those glyphs. */
25838
25839 static void
25840 mouse_face_from_string_pos (struct window *w, Mouse_HLInfo *hlinfo,
25841 Lisp_Object object,
25842 EMACS_INT startpos, EMACS_INT endpos)
25843 {
25844 int yb = window_text_bottom_y (w);
25845 struct glyph_row *r;
25846 struct glyph *g, *e;
25847 int gx;
25848 int found = 0;
25849
25850 /* Find the glyph row with at least one position in the range
25851 [STARTPOS..ENDPOS], and the first glyph in that row whose
25852 position belongs to that range. */
25853 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
25854 r->enabled_p && r->y < yb;
25855 ++r)
25856 {
25857 if (!r->reversed_p)
25858 {
25859 g = r->glyphs[TEXT_AREA];
25860 e = g + r->used[TEXT_AREA];
25861 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
25862 if (EQ (g->object, object)
25863 && startpos <= g->charpos && g->charpos <= endpos)
25864 {
25865 hlinfo->mouse_face_beg_row = r - w->current_matrix->rows;
25866 hlinfo->mouse_face_beg_y = r->y;
25867 hlinfo->mouse_face_beg_col = g - r->glyphs[TEXT_AREA];
25868 hlinfo->mouse_face_beg_x = gx;
25869 found = 1;
25870 break;
25871 }
25872 }
25873 else
25874 {
25875 struct glyph *g1;
25876
25877 e = r->glyphs[TEXT_AREA];
25878 g = e + r->used[TEXT_AREA];
25879 for ( ; g > e; --g)
25880 if (EQ ((g-1)->object, object)
25881 && startpos <= (g-1)->charpos && (g-1)->charpos <= endpos)
25882 {
25883 hlinfo->mouse_face_beg_row = r - w->current_matrix->rows;
25884 hlinfo->mouse_face_beg_y = r->y;
25885 hlinfo->mouse_face_beg_col = g - r->glyphs[TEXT_AREA];
25886 for (gx = r->x, g1 = r->glyphs[TEXT_AREA]; g1 < g; ++g1)
25887 gx += g1->pixel_width;
25888 hlinfo->mouse_face_beg_x = gx;
25889 found = 1;
25890 break;
25891 }
25892 }
25893 if (found)
25894 break;
25895 }
25896
25897 if (!found)
25898 return;
25899
25900 /* Starting with the next row, look for the first row which does NOT
25901 include any glyphs whose positions are in the range. */
25902 for (++r; r->enabled_p && r->y < yb; ++r)
25903 {
25904 g = r->glyphs[TEXT_AREA];
25905 e = g + r->used[TEXT_AREA];
25906 found = 0;
25907 for ( ; g < e; ++g)
25908 if (EQ (g->object, object)
25909 && startpos <= g->charpos && g->charpos <= endpos)
25910 {
25911 found = 1;
25912 break;
25913 }
25914 if (!found)
25915 break;
25916 }
25917
25918 /* The highlighted region ends on the previous row. */
25919 r--;
25920
25921 /* Set the end row and its vertical pixel coordinate. */
25922 hlinfo->mouse_face_end_row = r - w->current_matrix->rows;
25923 hlinfo->mouse_face_end_y = r->y;
25924
25925 /* Compute and set the end column and the end column's horizontal
25926 pixel coordinate. */
25927 if (!r->reversed_p)
25928 {
25929 g = r->glyphs[TEXT_AREA];
25930 e = g + r->used[TEXT_AREA];
25931 for ( ; e > g; --e)
25932 if (EQ ((e-1)->object, object)
25933 && startpos <= (e-1)->charpos && (e-1)->charpos <= endpos)
25934 break;
25935 hlinfo->mouse_face_end_col = e - g;
25936
25937 for (gx = r->x; g < e; ++g)
25938 gx += g->pixel_width;
25939 hlinfo->mouse_face_end_x = gx;
25940 }
25941 else
25942 {
25943 e = r->glyphs[TEXT_AREA];
25944 g = e + r->used[TEXT_AREA];
25945 for (gx = r->x ; e < g; ++e)
25946 {
25947 if (EQ (e->object, object)
25948 && startpos <= e->charpos && e->charpos <= endpos)
25949 break;
25950 gx += e->pixel_width;
25951 }
25952 hlinfo->mouse_face_end_col = e - r->glyphs[TEXT_AREA];
25953 hlinfo->mouse_face_end_x = gx;
25954 }
25955 }
25956
25957 #ifdef HAVE_WINDOW_SYSTEM
25958
25959 /* See if position X, Y is within a hot-spot of an image. */
25960
25961 static int
25962 on_hot_spot_p (Lisp_Object hot_spot, int x, int y)
25963 {
25964 if (!CONSP (hot_spot))
25965 return 0;
25966
25967 if (EQ (XCAR (hot_spot), Qrect))
25968 {
25969 /* CDR is (Top-Left . Bottom-Right) = ((x0 . y0) . (x1 . y1)) */
25970 Lisp_Object rect = XCDR (hot_spot);
25971 Lisp_Object tem;
25972 if (!CONSP (rect))
25973 return 0;
25974 if (!CONSP (XCAR (rect)))
25975 return 0;
25976 if (!CONSP (XCDR (rect)))
25977 return 0;
25978 if (!(tem = XCAR (XCAR (rect)), INTEGERP (tem) && x >= XINT (tem)))
25979 return 0;
25980 if (!(tem = XCDR (XCAR (rect)), INTEGERP (tem) && y >= XINT (tem)))
25981 return 0;
25982 if (!(tem = XCAR (XCDR (rect)), INTEGERP (tem) && x <= XINT (tem)))
25983 return 0;
25984 if (!(tem = XCDR (XCDR (rect)), INTEGERP (tem) && y <= XINT (tem)))
25985 return 0;
25986 return 1;
25987 }
25988 else if (EQ (XCAR (hot_spot), Qcircle))
25989 {
25990 /* CDR is (Center . Radius) = ((x0 . y0) . r) */
25991 Lisp_Object circ = XCDR (hot_spot);
25992 Lisp_Object lr, lx0, ly0;
25993 if (CONSP (circ)
25994 && CONSP (XCAR (circ))
25995 && (lr = XCDR (circ), INTEGERP (lr) || FLOATP (lr))
25996 && (lx0 = XCAR (XCAR (circ)), INTEGERP (lx0))
25997 && (ly0 = XCDR (XCAR (circ)), INTEGERP (ly0)))
25998 {
25999 double r = XFLOATINT (lr);
26000 double dx = XINT (lx0) - x;
26001 double dy = XINT (ly0) - y;
26002 return (dx * dx + dy * dy <= r * r);
26003 }
26004 }
26005 else if (EQ (XCAR (hot_spot), Qpoly))
26006 {
26007 /* CDR is [x0 y0 x1 y1 x2 y2 ...x(n-1) y(n-1)] */
26008 if (VECTORP (XCDR (hot_spot)))
26009 {
26010 struct Lisp_Vector *v = XVECTOR (XCDR (hot_spot));
26011 Lisp_Object *poly = v->contents;
26012 int n = v->header.size;
26013 int i;
26014 int inside = 0;
26015 Lisp_Object lx, ly;
26016 int x0, y0;
26017
26018 /* Need an even number of coordinates, and at least 3 edges. */
26019 if (n < 6 || n & 1)
26020 return 0;
26021
26022 /* Count edge segments intersecting line from (X,Y) to (X,infinity).
26023 If count is odd, we are inside polygon. Pixels on edges
26024 may or may not be included depending on actual geometry of the
26025 polygon. */
26026 if ((lx = poly[n-2], !INTEGERP (lx))
26027 || (ly = poly[n-1], !INTEGERP (lx)))
26028 return 0;
26029 x0 = XINT (lx), y0 = XINT (ly);
26030 for (i = 0; i < n; i += 2)
26031 {
26032 int x1 = x0, y1 = y0;
26033 if ((lx = poly[i], !INTEGERP (lx))
26034 || (ly = poly[i+1], !INTEGERP (ly)))
26035 return 0;
26036 x0 = XINT (lx), y0 = XINT (ly);
26037
26038 /* Does this segment cross the X line? */
26039 if (x0 >= x)
26040 {
26041 if (x1 >= x)
26042 continue;
26043 }
26044 else if (x1 < x)
26045 continue;
26046 if (y > y0 && y > y1)
26047 continue;
26048 if (y < y0 + ((y1 - y0) * (x - x0)) / (x1 - x0))
26049 inside = !inside;
26050 }
26051 return inside;
26052 }
26053 }
26054 return 0;
26055 }
26056
26057 Lisp_Object
26058 find_hot_spot (Lisp_Object map, int x, int y)
26059 {
26060 while (CONSP (map))
26061 {
26062 if (CONSP (XCAR (map))
26063 && on_hot_spot_p (XCAR (XCAR (map)), x, y))
26064 return XCAR (map);
26065 map = XCDR (map);
26066 }
26067
26068 return Qnil;
26069 }
26070
26071 DEFUN ("lookup-image-map", Flookup_image_map, Slookup_image_map,
26072 3, 3, 0,
26073 doc: /* Lookup in image map MAP coordinates X and Y.
26074 An image map is an alist where each element has the format (AREA ID PLIST).
26075 An AREA is specified as either a rectangle, a circle, or a polygon:
26076 A rectangle is a cons (rect . ((x0 . y0) . (x1 . y1))) specifying the
26077 pixel coordinates of the upper left and bottom right corners.
26078 A circle is a cons (circle . ((x0 . y0) . r)) specifying the center
26079 and the radius of the circle; r may be a float or integer.
26080 A polygon is a cons (poly . [x0 y0 x1 y1 ...]) where each pair in the
26081 vector describes one corner in the polygon.
26082 Returns the alist element for the first matching AREA in MAP. */)
26083 (Lisp_Object map, Lisp_Object x, Lisp_Object y)
26084 {
26085 if (NILP (map))
26086 return Qnil;
26087
26088 CHECK_NUMBER (x);
26089 CHECK_NUMBER (y);
26090
26091 return find_hot_spot (map, XINT (x), XINT (y));
26092 }
26093
26094
26095 /* Display frame CURSOR, optionally using shape defined by POINTER. */
26096 static void
26097 define_frame_cursor1 (struct frame *f, Cursor cursor, Lisp_Object pointer)
26098 {
26099 /* Do not change cursor shape while dragging mouse. */
26100 if (!NILP (do_mouse_tracking))
26101 return;
26102
26103 if (!NILP (pointer))
26104 {
26105 if (EQ (pointer, Qarrow))
26106 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
26107 else if (EQ (pointer, Qhand))
26108 cursor = FRAME_X_OUTPUT (f)->hand_cursor;
26109 else if (EQ (pointer, Qtext))
26110 cursor = FRAME_X_OUTPUT (f)->text_cursor;
26111 else if (EQ (pointer, intern ("hdrag")))
26112 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
26113 #ifdef HAVE_X_WINDOWS
26114 else if (EQ (pointer, intern ("vdrag")))
26115 cursor = FRAME_X_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
26116 #endif
26117 else if (EQ (pointer, intern ("hourglass")))
26118 cursor = FRAME_X_OUTPUT (f)->hourglass_cursor;
26119 else if (EQ (pointer, Qmodeline))
26120 cursor = FRAME_X_OUTPUT (f)->modeline_cursor;
26121 else
26122 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
26123 }
26124
26125 if (cursor != No_Cursor)
26126 FRAME_RIF (f)->define_frame_cursor (f, cursor);
26127 }
26128
26129 #endif /* HAVE_WINDOW_SYSTEM */
26130
26131 /* Take proper action when mouse has moved to the mode or header line
26132 or marginal area AREA of window W, x-position X and y-position Y.
26133 X is relative to the start of the text display area of W, so the
26134 width of bitmap areas and scroll bars must be subtracted to get a
26135 position relative to the start of the mode line. */
26136
26137 static void
26138 note_mode_line_or_margin_highlight (Lisp_Object window, int x, int y,
26139 enum window_part area)
26140 {
26141 struct window *w = XWINDOW (window);
26142 struct frame *f = XFRAME (w->frame);
26143 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
26144 #ifdef HAVE_WINDOW_SYSTEM
26145 Display_Info *dpyinfo;
26146 #endif
26147 Cursor cursor = No_Cursor;
26148 Lisp_Object pointer = Qnil;
26149 int dx, dy, width, height;
26150 EMACS_INT charpos;
26151 Lisp_Object string, object = Qnil;
26152 Lisp_Object pos, help;
26153
26154 Lisp_Object mouse_face;
26155 int original_x_pixel = x;
26156 struct glyph * glyph = NULL, * row_start_glyph = NULL;
26157 struct glyph_row *row;
26158
26159 if (area == ON_MODE_LINE || area == ON_HEADER_LINE)
26160 {
26161 int x0;
26162 struct glyph *end;
26163
26164 /* Kludge alert: mode_line_string takes X/Y in pixels, but
26165 returns them in row/column units! */
26166 string = mode_line_string (w, area, &x, &y, &charpos,
26167 &object, &dx, &dy, &width, &height);
26168
26169 row = (area == ON_MODE_LINE
26170 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
26171 : MATRIX_HEADER_LINE_ROW (w->current_matrix));
26172
26173 /* Find the glyph under the mouse pointer. */
26174 if (row->mode_line_p && row->enabled_p)
26175 {
26176 glyph = row_start_glyph = row->glyphs[TEXT_AREA];
26177 end = glyph + row->used[TEXT_AREA];
26178
26179 for (x0 = original_x_pixel;
26180 glyph < end && x0 >= glyph->pixel_width;
26181 ++glyph)
26182 x0 -= glyph->pixel_width;
26183
26184 if (glyph >= end)
26185 glyph = NULL;
26186 }
26187 }
26188 else
26189 {
26190 x -= WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
26191 /* Kludge alert: marginal_area_string takes X/Y in pixels, but
26192 returns them in row/column units! */
26193 string = marginal_area_string (w, area, &x, &y, &charpos,
26194 &object, &dx, &dy, &width, &height);
26195 }
26196
26197 help = Qnil;
26198
26199 #ifdef HAVE_WINDOW_SYSTEM
26200 if (IMAGEP (object))
26201 {
26202 Lisp_Object image_map, hotspot;
26203 if ((image_map = Fplist_get (XCDR (object), QCmap),
26204 !NILP (image_map))
26205 && (hotspot = find_hot_spot (image_map, dx, dy),
26206 CONSP (hotspot))
26207 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
26208 {
26209 Lisp_Object plist;
26210
26211 /* Could check XCAR (hotspot) to see if we enter/leave this hot-spot.
26212 If so, we could look for mouse-enter, mouse-leave
26213 properties in PLIST (and do something...). */
26214 hotspot = XCDR (hotspot);
26215 if (CONSP (hotspot)
26216 && (plist = XCAR (hotspot), CONSP (plist)))
26217 {
26218 pointer = Fplist_get (plist, Qpointer);
26219 if (NILP (pointer))
26220 pointer = Qhand;
26221 help = Fplist_get (plist, Qhelp_echo);
26222 if (!NILP (help))
26223 {
26224 help_echo_string = help;
26225 /* Is this correct? ++kfs */
26226 XSETWINDOW (help_echo_window, w);
26227 help_echo_object = w->buffer;
26228 help_echo_pos = charpos;
26229 }
26230 }
26231 }
26232 if (NILP (pointer))
26233 pointer = Fplist_get (XCDR (object), QCpointer);
26234 }
26235 #endif /* HAVE_WINDOW_SYSTEM */
26236
26237 if (STRINGP (string))
26238 {
26239 pos = make_number (charpos);
26240 /* If we're on a string with `help-echo' text property, arrange
26241 for the help to be displayed. This is done by setting the
26242 global variable help_echo_string to the help string. */
26243 if (NILP (help))
26244 {
26245 help = Fget_text_property (pos, Qhelp_echo, string);
26246 if (!NILP (help))
26247 {
26248 help_echo_string = help;
26249 XSETWINDOW (help_echo_window, w);
26250 help_echo_object = string;
26251 help_echo_pos = charpos;
26252 }
26253 }
26254
26255 #ifdef HAVE_WINDOW_SYSTEM
26256 if (FRAME_WINDOW_P (f))
26257 {
26258 dpyinfo = FRAME_X_DISPLAY_INFO (f);
26259 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
26260 if (NILP (pointer))
26261 pointer = Fget_text_property (pos, Qpointer, string);
26262
26263 /* Change the mouse pointer according to what is under X/Y. */
26264 if (NILP (pointer)
26265 && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE)))
26266 {
26267 Lisp_Object map;
26268 map = Fget_text_property (pos, Qlocal_map, string);
26269 if (!KEYMAPP (map))
26270 map = Fget_text_property (pos, Qkeymap, string);
26271 if (!KEYMAPP (map))
26272 cursor = dpyinfo->vertical_scroll_bar_cursor;
26273 }
26274 }
26275 #endif
26276
26277 /* Change the mouse face according to what is under X/Y. */
26278 mouse_face = Fget_text_property (pos, Qmouse_face, string);
26279 if (!NILP (mouse_face)
26280 && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE))
26281 && glyph)
26282 {
26283 Lisp_Object b, e;
26284
26285 struct glyph * tmp_glyph;
26286
26287 int gpos;
26288 int gseq_length;
26289 int total_pixel_width;
26290 EMACS_INT begpos, endpos, ignore;
26291
26292 int vpos, hpos;
26293
26294 b = Fprevious_single_property_change (make_number (charpos + 1),
26295 Qmouse_face, string, Qnil);
26296 if (NILP (b))
26297 begpos = 0;
26298 else
26299 begpos = XINT (b);
26300
26301 e = Fnext_single_property_change (pos, Qmouse_face, string, Qnil);
26302 if (NILP (e))
26303 endpos = SCHARS (string);
26304 else
26305 endpos = XINT (e);
26306
26307 /* Calculate the glyph position GPOS of GLYPH in the
26308 displayed string, relative to the beginning of the
26309 highlighted part of the string.
26310
26311 Note: GPOS is different from CHARPOS. CHARPOS is the
26312 position of GLYPH in the internal string object. A mode
26313 line string format has structures which are converted to
26314 a flattened string by the Emacs Lisp interpreter. The
26315 internal string is an element of those structures. The
26316 displayed string is the flattened string. */
26317 tmp_glyph = row_start_glyph;
26318 while (tmp_glyph < glyph
26319 && (!(EQ (tmp_glyph->object, glyph->object)
26320 && begpos <= tmp_glyph->charpos
26321 && tmp_glyph->charpos < endpos)))
26322 tmp_glyph++;
26323 gpos = glyph - tmp_glyph;
26324
26325 /* Calculate the length GSEQ_LENGTH of the glyph sequence of
26326 the highlighted part of the displayed string to which
26327 GLYPH belongs. Note: GSEQ_LENGTH is different from
26328 SCHARS (STRING), because the latter returns the length of
26329 the internal string. */
26330 for (tmp_glyph = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
26331 tmp_glyph > glyph
26332 && (!(EQ (tmp_glyph->object, glyph->object)
26333 && begpos <= tmp_glyph->charpos
26334 && tmp_glyph->charpos < endpos));
26335 tmp_glyph--)
26336 ;
26337 gseq_length = gpos + (tmp_glyph - glyph) + 1;
26338
26339 /* Calculate the total pixel width of all the glyphs between
26340 the beginning of the highlighted area and GLYPH. */
26341 total_pixel_width = 0;
26342 for (tmp_glyph = glyph - gpos; tmp_glyph != glyph; tmp_glyph++)
26343 total_pixel_width += tmp_glyph->pixel_width;
26344
26345 /* Pre calculation of re-rendering position. Note: X is in
26346 column units here, after the call to mode_line_string or
26347 marginal_area_string. */
26348 hpos = x - gpos;
26349 vpos = (area == ON_MODE_LINE
26350 ? (w->current_matrix)->nrows - 1
26351 : 0);
26352
26353 /* If GLYPH's position is included in the region that is
26354 already drawn in mouse face, we have nothing to do. */
26355 if ( EQ (window, hlinfo->mouse_face_window)
26356 && (!row->reversed_p
26357 ? (hlinfo->mouse_face_beg_col <= hpos
26358 && hpos < hlinfo->mouse_face_end_col)
26359 /* In R2L rows we swap BEG and END, see below. */
26360 : (hlinfo->mouse_face_end_col <= hpos
26361 && hpos < hlinfo->mouse_face_beg_col))
26362 && hlinfo->mouse_face_beg_row == vpos )
26363 return;
26364
26365 if (clear_mouse_face (hlinfo))
26366 cursor = No_Cursor;
26367
26368 if (!row->reversed_p)
26369 {
26370 hlinfo->mouse_face_beg_col = hpos;
26371 hlinfo->mouse_face_beg_x = original_x_pixel
26372 - (total_pixel_width + dx);
26373 hlinfo->mouse_face_end_col = hpos + gseq_length;
26374 hlinfo->mouse_face_end_x = 0;
26375 }
26376 else
26377 {
26378 /* In R2L rows, show_mouse_face expects BEG and END
26379 coordinates to be swapped. */
26380 hlinfo->mouse_face_end_col = hpos;
26381 hlinfo->mouse_face_end_x = original_x_pixel
26382 - (total_pixel_width + dx);
26383 hlinfo->mouse_face_beg_col = hpos + gseq_length;
26384 hlinfo->mouse_face_beg_x = 0;
26385 }
26386
26387 hlinfo->mouse_face_beg_row = vpos;
26388 hlinfo->mouse_face_end_row = hlinfo->mouse_face_beg_row;
26389 hlinfo->mouse_face_beg_y = 0;
26390 hlinfo->mouse_face_end_y = 0;
26391 hlinfo->mouse_face_past_end = 0;
26392 hlinfo->mouse_face_window = window;
26393
26394 hlinfo->mouse_face_face_id = face_at_string_position (w, string,
26395 charpos,
26396 0, 0, 0,
26397 &ignore,
26398 glyph->face_id,
26399 1);
26400 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
26401
26402 if (NILP (pointer))
26403 pointer = Qhand;
26404 }
26405 else if ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE))
26406 clear_mouse_face (hlinfo);
26407 }
26408 #ifdef HAVE_WINDOW_SYSTEM
26409 if (FRAME_WINDOW_P (f))
26410 define_frame_cursor1 (f, cursor, pointer);
26411 #endif
26412 }
26413
26414
26415 /* EXPORT:
26416 Take proper action when the mouse has moved to position X, Y on
26417 frame F as regards highlighting characters that have mouse-face
26418 properties. Also de-highlighting chars where the mouse was before.
26419 X and Y can be negative or out of range. */
26420
26421 void
26422 note_mouse_highlight (struct frame *f, int x, int y)
26423 {
26424 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
26425 enum window_part part;
26426 Lisp_Object window;
26427 struct window *w;
26428 Cursor cursor = No_Cursor;
26429 Lisp_Object pointer = Qnil; /* Takes precedence over cursor! */
26430 struct buffer *b;
26431
26432 /* When a menu is active, don't highlight because this looks odd. */
26433 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS) || defined (MSDOS)
26434 if (popup_activated ())
26435 return;
26436 #endif
26437
26438 if (NILP (Vmouse_highlight)
26439 || !f->glyphs_initialized_p
26440 || f->pointer_invisible)
26441 return;
26442
26443 hlinfo->mouse_face_mouse_x = x;
26444 hlinfo->mouse_face_mouse_y = y;
26445 hlinfo->mouse_face_mouse_frame = f;
26446
26447 if (hlinfo->mouse_face_defer)
26448 return;
26449
26450 if (gc_in_progress)
26451 {
26452 hlinfo->mouse_face_deferred_gc = 1;
26453 return;
26454 }
26455
26456 /* Which window is that in? */
26457 window = window_from_coordinates (f, x, y, &part, 1);
26458
26459 /* If we were displaying active text in another window, clear that.
26460 Also clear if we move out of text area in same window. */
26461 if (! EQ (window, hlinfo->mouse_face_window)
26462 || (part != ON_TEXT && part != ON_MODE_LINE && part != ON_HEADER_LINE
26463 && !NILP (hlinfo->mouse_face_window)))
26464 clear_mouse_face (hlinfo);
26465
26466 /* Not on a window -> return. */
26467 if (!WINDOWP (window))
26468 return;
26469
26470 /* Reset help_echo_string. It will get recomputed below. */
26471 help_echo_string = Qnil;
26472
26473 /* Convert to window-relative pixel coordinates. */
26474 w = XWINDOW (window);
26475 frame_to_window_pixel_xy (w, &x, &y);
26476
26477 #ifdef HAVE_WINDOW_SYSTEM
26478 /* Handle tool-bar window differently since it doesn't display a
26479 buffer. */
26480 if (EQ (window, f->tool_bar_window))
26481 {
26482 note_tool_bar_highlight (f, x, y);
26483 return;
26484 }
26485 #endif
26486
26487 /* Mouse is on the mode, header line or margin? */
26488 if (part == ON_MODE_LINE || part == ON_HEADER_LINE
26489 || part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
26490 {
26491 note_mode_line_or_margin_highlight (window, x, y, part);
26492 return;
26493 }
26494
26495 #ifdef HAVE_WINDOW_SYSTEM
26496 if (part == ON_VERTICAL_BORDER)
26497 {
26498 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
26499 help_echo_string = build_string ("drag-mouse-1: resize");
26500 }
26501 else if (part == ON_LEFT_FRINGE || part == ON_RIGHT_FRINGE
26502 || part == ON_SCROLL_BAR)
26503 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
26504 else
26505 cursor = FRAME_X_OUTPUT (f)->text_cursor;
26506 #endif
26507
26508 /* Are we in a window whose display is up to date?
26509 And verify the buffer's text has not changed. */
26510 b = XBUFFER (w->buffer);
26511 if (part == ON_TEXT
26512 && EQ (w->window_end_valid, w->buffer)
26513 && XFASTINT (w->last_modified) == BUF_MODIFF (b)
26514 && XFASTINT (w->last_overlay_modified) == BUF_OVERLAY_MODIFF (b))
26515 {
26516 int hpos, vpos, dx, dy, area;
26517 EMACS_INT pos;
26518 struct glyph *glyph;
26519 Lisp_Object object;
26520 Lisp_Object mouse_face = Qnil, position;
26521 Lisp_Object *overlay_vec = NULL;
26522 ptrdiff_t i, noverlays;
26523 struct buffer *obuf;
26524 EMACS_INT obegv, ozv;
26525 int same_region;
26526
26527 /* Find the glyph under X/Y. */
26528 glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, &dx, &dy, &area);
26529
26530 #ifdef HAVE_WINDOW_SYSTEM
26531 /* Look for :pointer property on image. */
26532 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
26533 {
26534 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
26535 if (img != NULL && IMAGEP (img->spec))
26536 {
26537 Lisp_Object image_map, hotspot;
26538 if ((image_map = Fplist_get (XCDR (img->spec), QCmap),
26539 !NILP (image_map))
26540 && (hotspot = find_hot_spot (image_map,
26541 glyph->slice.img.x + dx,
26542 glyph->slice.img.y + dy),
26543 CONSP (hotspot))
26544 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
26545 {
26546 Lisp_Object plist;
26547
26548 /* Could check XCAR (hotspot) to see if we enter/leave
26549 this hot-spot.
26550 If so, we could look for mouse-enter, mouse-leave
26551 properties in PLIST (and do something...). */
26552 hotspot = XCDR (hotspot);
26553 if (CONSP (hotspot)
26554 && (plist = XCAR (hotspot), CONSP (plist)))
26555 {
26556 pointer = Fplist_get (plist, Qpointer);
26557 if (NILP (pointer))
26558 pointer = Qhand;
26559 help_echo_string = Fplist_get (plist, Qhelp_echo);
26560 if (!NILP (help_echo_string))
26561 {
26562 help_echo_window = window;
26563 help_echo_object = glyph->object;
26564 help_echo_pos = glyph->charpos;
26565 }
26566 }
26567 }
26568 if (NILP (pointer))
26569 pointer = Fplist_get (XCDR (img->spec), QCpointer);
26570 }
26571 }
26572 #endif /* HAVE_WINDOW_SYSTEM */
26573
26574 /* Clear mouse face if X/Y not over text. */
26575 if (glyph == NULL
26576 || area != TEXT_AREA
26577 || !MATRIX_ROW (w->current_matrix, vpos)->displays_text_p
26578 /* Glyph's OBJECT is an integer for glyphs inserted by the
26579 display engine for its internal purposes, like truncation
26580 and continuation glyphs and blanks beyond the end of
26581 line's text on text terminals. If we are over such a
26582 glyph, we are not over any text. */
26583 || INTEGERP (glyph->object)
26584 /* R2L rows have a stretch glyph at their front, which
26585 stands for no text, whereas L2R rows have no glyphs at
26586 all beyond the end of text. Treat such stretch glyphs
26587 like we do with NULL glyphs in L2R rows. */
26588 || (MATRIX_ROW (w->current_matrix, vpos)->reversed_p
26589 && glyph == MATRIX_ROW (w->current_matrix, vpos)->glyphs[TEXT_AREA]
26590 && glyph->type == STRETCH_GLYPH
26591 && glyph->avoid_cursor_p))
26592 {
26593 if (clear_mouse_face (hlinfo))
26594 cursor = No_Cursor;
26595 #ifdef HAVE_WINDOW_SYSTEM
26596 if (FRAME_WINDOW_P (f) && NILP (pointer))
26597 {
26598 if (area != TEXT_AREA)
26599 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
26600 else
26601 pointer = Vvoid_text_area_pointer;
26602 }
26603 #endif
26604 goto set_cursor;
26605 }
26606
26607 pos = glyph->charpos;
26608 object = glyph->object;
26609 if (!STRINGP (object) && !BUFFERP (object))
26610 goto set_cursor;
26611
26612 /* If we get an out-of-range value, return now; avoid an error. */
26613 if (BUFFERP (object) && pos > BUF_Z (b))
26614 goto set_cursor;
26615
26616 /* Make the window's buffer temporarily current for
26617 overlays_at and compute_char_face. */
26618 obuf = current_buffer;
26619 current_buffer = b;
26620 obegv = BEGV;
26621 ozv = ZV;
26622 BEGV = BEG;
26623 ZV = Z;
26624
26625 /* Is this char mouse-active or does it have help-echo? */
26626 position = make_number (pos);
26627
26628 if (BUFFERP (object))
26629 {
26630 /* Put all the overlays we want in a vector in overlay_vec. */
26631 GET_OVERLAYS_AT (pos, overlay_vec, noverlays, NULL, 0);
26632 /* Sort overlays into increasing priority order. */
26633 noverlays = sort_overlays (overlay_vec, noverlays, w);
26634 }
26635 else
26636 noverlays = 0;
26637
26638 same_region = coords_in_mouse_face_p (w, hpos, vpos);
26639
26640 if (same_region)
26641 cursor = No_Cursor;
26642
26643 /* Check mouse-face highlighting. */
26644 if (! same_region
26645 /* If there exists an overlay with mouse-face overlapping
26646 the one we are currently highlighting, we have to
26647 check if we enter the overlapping overlay, and then
26648 highlight only that. */
26649 || (OVERLAYP (hlinfo->mouse_face_overlay)
26650 && mouse_face_overlay_overlaps (hlinfo->mouse_face_overlay)))
26651 {
26652 /* Find the highest priority overlay with a mouse-face. */
26653 Lisp_Object overlay = Qnil;
26654 for (i = noverlays - 1; i >= 0 && NILP (overlay); --i)
26655 {
26656 mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face);
26657 if (!NILP (mouse_face))
26658 overlay = overlay_vec[i];
26659 }
26660
26661 /* If we're highlighting the same overlay as before, there's
26662 no need to do that again. */
26663 if (!NILP (overlay) && EQ (overlay, hlinfo->mouse_face_overlay))
26664 goto check_help_echo;
26665 hlinfo->mouse_face_overlay = overlay;
26666
26667 /* Clear the display of the old active region, if any. */
26668 if (clear_mouse_face (hlinfo))
26669 cursor = No_Cursor;
26670
26671 /* If no overlay applies, get a text property. */
26672 if (NILP (overlay))
26673 mouse_face = Fget_text_property (position, Qmouse_face, object);
26674
26675 /* Next, compute the bounds of the mouse highlighting and
26676 display it. */
26677 if (!NILP (mouse_face) && STRINGP (object))
26678 {
26679 /* The mouse-highlighting comes from a display string
26680 with a mouse-face. */
26681 Lisp_Object s, e;
26682 EMACS_INT ignore;
26683
26684 s = Fprevious_single_property_change
26685 (make_number (pos + 1), Qmouse_face, object, Qnil);
26686 e = Fnext_single_property_change
26687 (position, Qmouse_face, object, Qnil);
26688 if (NILP (s))
26689 s = make_number (0);
26690 if (NILP (e))
26691 e = make_number (SCHARS (object) - 1);
26692 mouse_face_from_string_pos (w, hlinfo, object,
26693 XINT (s), XINT (e));
26694 hlinfo->mouse_face_past_end = 0;
26695 hlinfo->mouse_face_window = window;
26696 hlinfo->mouse_face_face_id
26697 = face_at_string_position (w, object, pos, 0, 0, 0, &ignore,
26698 glyph->face_id, 1);
26699 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
26700 cursor = No_Cursor;
26701 }
26702 else
26703 {
26704 /* The mouse-highlighting, if any, comes from an overlay
26705 or text property in the buffer. */
26706 Lisp_Object buffer IF_LINT (= Qnil);
26707 Lisp_Object cover_string IF_LINT (= Qnil);
26708
26709 if (STRINGP (object))
26710 {
26711 /* If we are on a display string with no mouse-face,
26712 check if the text under it has one. */
26713 struct glyph_row *r = MATRIX_ROW (w->current_matrix, vpos);
26714 EMACS_INT start = MATRIX_ROW_START_CHARPOS (r);
26715 pos = string_buffer_position (object, start);
26716 if (pos > 0)
26717 {
26718 mouse_face = get_char_property_and_overlay
26719 (make_number (pos), Qmouse_face, w->buffer, &overlay);
26720 buffer = w->buffer;
26721 cover_string = object;
26722 }
26723 }
26724 else
26725 {
26726 buffer = object;
26727 cover_string = Qnil;
26728 }
26729
26730 if (!NILP (mouse_face))
26731 {
26732 Lisp_Object before, after;
26733 Lisp_Object before_string, after_string;
26734 /* To correctly find the limits of mouse highlight
26735 in a bidi-reordered buffer, we must not use the
26736 optimization of limiting the search in
26737 previous-single-property-change and
26738 next-single-property-change, because
26739 rows_from_pos_range needs the real start and end
26740 positions to DTRT in this case. That's because
26741 the first row visible in a window does not
26742 necessarily display the character whose position
26743 is the smallest. */
26744 Lisp_Object lim1 =
26745 NILP (BVAR (XBUFFER (buffer), bidi_display_reordering))
26746 ? Fmarker_position (w->start)
26747 : Qnil;
26748 Lisp_Object lim2 =
26749 NILP (BVAR (XBUFFER (buffer), bidi_display_reordering))
26750 ? make_number (BUF_Z (XBUFFER (buffer))
26751 - XFASTINT (w->window_end_pos))
26752 : Qnil;
26753
26754 if (NILP (overlay))
26755 {
26756 /* Handle the text property case. */
26757 before = Fprevious_single_property_change
26758 (make_number (pos + 1), Qmouse_face, buffer, lim1);
26759 after = Fnext_single_property_change
26760 (make_number (pos), Qmouse_face, buffer, lim2);
26761 before_string = after_string = Qnil;
26762 }
26763 else
26764 {
26765 /* Handle the overlay case. */
26766 before = Foverlay_start (overlay);
26767 after = Foverlay_end (overlay);
26768 before_string = Foverlay_get (overlay, Qbefore_string);
26769 after_string = Foverlay_get (overlay, Qafter_string);
26770
26771 if (!STRINGP (before_string)) before_string = Qnil;
26772 if (!STRINGP (after_string)) after_string = Qnil;
26773 }
26774
26775 mouse_face_from_buffer_pos (window, hlinfo, pos,
26776 XFASTINT (before),
26777 XFASTINT (after),
26778 before_string, after_string,
26779 cover_string);
26780 cursor = No_Cursor;
26781 }
26782 }
26783 }
26784
26785 check_help_echo:
26786
26787 /* Look for a `help-echo' property. */
26788 if (NILP (help_echo_string)) {
26789 Lisp_Object help, overlay;
26790
26791 /* Check overlays first. */
26792 help = overlay = Qnil;
26793 for (i = noverlays - 1; i >= 0 && NILP (help); --i)
26794 {
26795 overlay = overlay_vec[i];
26796 help = Foverlay_get (overlay, Qhelp_echo);
26797 }
26798
26799 if (!NILP (help))
26800 {
26801 help_echo_string = help;
26802 help_echo_window = window;
26803 help_echo_object = overlay;
26804 help_echo_pos = pos;
26805 }
26806 else
26807 {
26808 Lisp_Object obj = glyph->object;
26809 EMACS_INT charpos = glyph->charpos;
26810
26811 /* Try text properties. */
26812 if (STRINGP (obj)
26813 && charpos >= 0
26814 && charpos < SCHARS (obj))
26815 {
26816 help = Fget_text_property (make_number (charpos),
26817 Qhelp_echo, obj);
26818 if (NILP (help))
26819 {
26820 /* If the string itself doesn't specify a help-echo,
26821 see if the buffer text ``under'' it does. */
26822 struct glyph_row *r
26823 = MATRIX_ROW (w->current_matrix, vpos);
26824 EMACS_INT start = MATRIX_ROW_START_CHARPOS (r);
26825 EMACS_INT p = string_buffer_position (obj, start);
26826 if (p > 0)
26827 {
26828 help = Fget_char_property (make_number (p),
26829 Qhelp_echo, w->buffer);
26830 if (!NILP (help))
26831 {
26832 charpos = p;
26833 obj = w->buffer;
26834 }
26835 }
26836 }
26837 }
26838 else if (BUFFERP (obj)
26839 && charpos >= BEGV
26840 && charpos < ZV)
26841 help = Fget_text_property (make_number (charpos), Qhelp_echo,
26842 obj);
26843
26844 if (!NILP (help))
26845 {
26846 help_echo_string = help;
26847 help_echo_window = window;
26848 help_echo_object = obj;
26849 help_echo_pos = charpos;
26850 }
26851 }
26852 }
26853
26854 #ifdef HAVE_WINDOW_SYSTEM
26855 /* Look for a `pointer' property. */
26856 if (FRAME_WINDOW_P (f) && NILP (pointer))
26857 {
26858 /* Check overlays first. */
26859 for (i = noverlays - 1; i >= 0 && NILP (pointer); --i)
26860 pointer = Foverlay_get (overlay_vec[i], Qpointer);
26861
26862 if (NILP (pointer))
26863 {
26864 Lisp_Object obj = glyph->object;
26865 EMACS_INT charpos = glyph->charpos;
26866
26867 /* Try text properties. */
26868 if (STRINGP (obj)
26869 && charpos >= 0
26870 && charpos < SCHARS (obj))
26871 {
26872 pointer = Fget_text_property (make_number (charpos),
26873 Qpointer, obj);
26874 if (NILP (pointer))
26875 {
26876 /* If the string itself doesn't specify a pointer,
26877 see if the buffer text ``under'' it does. */
26878 struct glyph_row *r
26879 = MATRIX_ROW (w->current_matrix, vpos);
26880 EMACS_INT start = MATRIX_ROW_START_CHARPOS (r);
26881 EMACS_INT p = string_buffer_position (obj, start);
26882 if (p > 0)
26883 pointer = Fget_char_property (make_number (p),
26884 Qpointer, w->buffer);
26885 }
26886 }
26887 else if (BUFFERP (obj)
26888 && charpos >= BEGV
26889 && charpos < ZV)
26890 pointer = Fget_text_property (make_number (charpos),
26891 Qpointer, obj);
26892 }
26893 }
26894 #endif /* HAVE_WINDOW_SYSTEM */
26895
26896 BEGV = obegv;
26897 ZV = ozv;
26898 current_buffer = obuf;
26899 }
26900
26901 set_cursor:
26902
26903 #ifdef HAVE_WINDOW_SYSTEM
26904 if (FRAME_WINDOW_P (f))
26905 define_frame_cursor1 (f, cursor, pointer);
26906 #else
26907 /* This is here to prevent a compiler error, about "label at end of
26908 compound statement". */
26909 return;
26910 #endif
26911 }
26912
26913
26914 /* EXPORT for RIF:
26915 Clear any mouse-face on window W. This function is part of the
26916 redisplay interface, and is called from try_window_id and similar
26917 functions to ensure the mouse-highlight is off. */
26918
26919 void
26920 x_clear_window_mouse_face (struct window *w)
26921 {
26922 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame));
26923 Lisp_Object window;
26924
26925 BLOCK_INPUT;
26926 XSETWINDOW (window, w);
26927 if (EQ (window, hlinfo->mouse_face_window))
26928 clear_mouse_face (hlinfo);
26929 UNBLOCK_INPUT;
26930 }
26931
26932
26933 /* EXPORT:
26934 Just discard the mouse face information for frame F, if any.
26935 This is used when the size of F is changed. */
26936
26937 void
26938 cancel_mouse_face (struct frame *f)
26939 {
26940 Lisp_Object window;
26941 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
26942
26943 window = hlinfo->mouse_face_window;
26944 if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f)
26945 {
26946 hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
26947 hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
26948 hlinfo->mouse_face_window = Qnil;
26949 }
26950 }
26951
26952
26953 \f
26954 /***********************************************************************
26955 Exposure Events
26956 ***********************************************************************/
26957
26958 #ifdef HAVE_WINDOW_SYSTEM
26959
26960 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
26961 which intersects rectangle R. R is in window-relative coordinates. */
26962
26963 static void
26964 expose_area (struct window *w, struct glyph_row *row, XRectangle *r,
26965 enum glyph_row_area area)
26966 {
26967 struct glyph *first = row->glyphs[area];
26968 struct glyph *end = row->glyphs[area] + row->used[area];
26969 struct glyph *last;
26970 int first_x, start_x, x;
26971
26972 if (area == TEXT_AREA && row->fill_line_p)
26973 /* If row extends face to end of line write the whole line. */
26974 draw_glyphs (w, 0, row, area,
26975 0, row->used[area],
26976 DRAW_NORMAL_TEXT, 0);
26977 else
26978 {
26979 /* Set START_X to the window-relative start position for drawing glyphs of
26980 AREA. The first glyph of the text area can be partially visible.
26981 The first glyphs of other areas cannot. */
26982 start_x = window_box_left_offset (w, area);
26983 x = start_x;
26984 if (area == TEXT_AREA)
26985 x += row->x;
26986
26987 /* Find the first glyph that must be redrawn. */
26988 while (first < end
26989 && x + first->pixel_width < r->x)
26990 {
26991 x += first->pixel_width;
26992 ++first;
26993 }
26994
26995 /* Find the last one. */
26996 last = first;
26997 first_x = x;
26998 while (last < end
26999 && x < r->x + r->width)
27000 {
27001 x += last->pixel_width;
27002 ++last;
27003 }
27004
27005 /* Repaint. */
27006 if (last > first)
27007 draw_glyphs (w, first_x - start_x, row, area,
27008 first - row->glyphs[area], last - row->glyphs[area],
27009 DRAW_NORMAL_TEXT, 0);
27010 }
27011 }
27012
27013
27014 /* Redraw the parts of the glyph row ROW on window W intersecting
27015 rectangle R. R is in window-relative coordinates. Value is
27016 non-zero if mouse-face was overwritten. */
27017
27018 static int
27019 expose_line (struct window *w, struct glyph_row *row, XRectangle *r)
27020 {
27021 xassert (row->enabled_p);
27022
27023 if (row->mode_line_p || w->pseudo_window_p)
27024 draw_glyphs (w, 0, row, TEXT_AREA,
27025 0, row->used[TEXT_AREA],
27026 DRAW_NORMAL_TEXT, 0);
27027 else
27028 {
27029 if (row->used[LEFT_MARGIN_AREA])
27030 expose_area (w, row, r, LEFT_MARGIN_AREA);
27031 if (row->used[TEXT_AREA])
27032 expose_area (w, row, r, TEXT_AREA);
27033 if (row->used[RIGHT_MARGIN_AREA])
27034 expose_area (w, row, r, RIGHT_MARGIN_AREA);
27035 draw_row_fringe_bitmaps (w, row);
27036 }
27037
27038 return row->mouse_face_p;
27039 }
27040
27041
27042 /* Redraw those parts of glyphs rows during expose event handling that
27043 overlap other rows. Redrawing of an exposed line writes over parts
27044 of lines overlapping that exposed line; this function fixes that.
27045
27046 W is the window being exposed. FIRST_OVERLAPPING_ROW is the first
27047 row in W's current matrix that is exposed and overlaps other rows.
27048 LAST_OVERLAPPING_ROW is the last such row. */
27049
27050 static void
27051 expose_overlaps (struct window *w,
27052 struct glyph_row *first_overlapping_row,
27053 struct glyph_row *last_overlapping_row,
27054 XRectangle *r)
27055 {
27056 struct glyph_row *row;
27057
27058 for (row = first_overlapping_row; row <= last_overlapping_row; ++row)
27059 if (row->overlapping_p)
27060 {
27061 xassert (row->enabled_p && !row->mode_line_p);
27062
27063 row->clip = r;
27064 if (row->used[LEFT_MARGIN_AREA])
27065 x_fix_overlapping_area (w, row, LEFT_MARGIN_AREA, OVERLAPS_BOTH);
27066
27067 if (row->used[TEXT_AREA])
27068 x_fix_overlapping_area (w, row, TEXT_AREA, OVERLAPS_BOTH);
27069
27070 if (row->used[RIGHT_MARGIN_AREA])
27071 x_fix_overlapping_area (w, row, RIGHT_MARGIN_AREA, OVERLAPS_BOTH);
27072 row->clip = NULL;
27073 }
27074 }
27075
27076
27077 /* Return non-zero if W's cursor intersects rectangle R. */
27078
27079 static int
27080 phys_cursor_in_rect_p (struct window *w, XRectangle *r)
27081 {
27082 XRectangle cr, result;
27083 struct glyph *cursor_glyph;
27084 struct glyph_row *row;
27085
27086 if (w->phys_cursor.vpos >= 0
27087 && w->phys_cursor.vpos < w->current_matrix->nrows
27088 && (row = MATRIX_ROW (w->current_matrix, w->phys_cursor.vpos),
27089 row->enabled_p)
27090 && row->cursor_in_fringe_p)
27091 {
27092 /* Cursor is in the fringe. */
27093 cr.x = window_box_right_offset (w,
27094 (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
27095 ? RIGHT_MARGIN_AREA
27096 : TEXT_AREA));
27097 cr.y = row->y;
27098 cr.width = WINDOW_RIGHT_FRINGE_WIDTH (w);
27099 cr.height = row->height;
27100 return x_intersect_rectangles (&cr, r, &result);
27101 }
27102
27103 cursor_glyph = get_phys_cursor_glyph (w);
27104 if (cursor_glyph)
27105 {
27106 /* r is relative to W's box, but w->phys_cursor.x is relative
27107 to left edge of W's TEXT area. Adjust it. */
27108 cr.x = window_box_left_offset (w, TEXT_AREA) + w->phys_cursor.x;
27109 cr.y = w->phys_cursor.y;
27110 cr.width = cursor_glyph->pixel_width;
27111 cr.height = w->phys_cursor_height;
27112 /* ++KFS: W32 version used W32-specific IntersectRect here, but
27113 I assume the effect is the same -- and this is portable. */
27114 return x_intersect_rectangles (&cr, r, &result);
27115 }
27116 /* If we don't understand the format, pretend we're not in the hot-spot. */
27117 return 0;
27118 }
27119
27120
27121 /* EXPORT:
27122 Draw a vertical window border to the right of window W if W doesn't
27123 have vertical scroll bars. */
27124
27125 void
27126 x_draw_vertical_border (struct window *w)
27127 {
27128 struct frame *f = XFRAME (WINDOW_FRAME (w));
27129
27130 /* We could do better, if we knew what type of scroll-bar the adjacent
27131 windows (on either side) have... But we don't :-(
27132 However, I think this works ok. ++KFS 2003-04-25 */
27133
27134 /* Redraw borders between horizontally adjacent windows. Don't
27135 do it for frames with vertical scroll bars because either the
27136 right scroll bar of a window, or the left scroll bar of its
27137 neighbor will suffice as a border. */
27138 if (FRAME_HAS_VERTICAL_SCROLL_BARS (XFRAME (w->frame)))
27139 return;
27140
27141 if (!WINDOW_RIGHTMOST_P (w)
27142 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w))
27143 {
27144 int x0, x1, y0, y1;
27145
27146 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
27147 y1 -= 1;
27148
27149 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
27150 x1 -= 1;
27151
27152 FRAME_RIF (f)->draw_vertical_window_border (w, x1, y0, y1);
27153 }
27154 else if (!WINDOW_LEFTMOST_P (w)
27155 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
27156 {
27157 int x0, x1, y0, y1;
27158
27159 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
27160 y1 -= 1;
27161
27162 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
27163 x0 -= 1;
27164
27165 FRAME_RIF (f)->draw_vertical_window_border (w, x0, y0, y1);
27166 }
27167 }
27168
27169
27170 /* Redraw the part of window W intersection rectangle FR. Pixel
27171 coordinates in FR are frame-relative. Call this function with
27172 input blocked. Value is non-zero if the exposure overwrites
27173 mouse-face. */
27174
27175 static int
27176 expose_window (struct window *w, XRectangle *fr)
27177 {
27178 struct frame *f = XFRAME (w->frame);
27179 XRectangle wr, r;
27180 int mouse_face_overwritten_p = 0;
27181
27182 /* If window is not yet fully initialized, do nothing. This can
27183 happen when toolkit scroll bars are used and a window is split.
27184 Reconfiguring the scroll bar will generate an expose for a newly
27185 created window. */
27186 if (w->current_matrix == NULL)
27187 return 0;
27188
27189 /* When we're currently updating the window, display and current
27190 matrix usually don't agree. Arrange for a thorough display
27191 later. */
27192 if (w == updated_window)
27193 {
27194 SET_FRAME_GARBAGED (f);
27195 return 0;
27196 }
27197
27198 /* Frame-relative pixel rectangle of W. */
27199 wr.x = WINDOW_LEFT_EDGE_X (w);
27200 wr.y = WINDOW_TOP_EDGE_Y (w);
27201 wr.width = WINDOW_TOTAL_WIDTH (w);
27202 wr.height = WINDOW_TOTAL_HEIGHT (w);
27203
27204 if (x_intersect_rectangles (fr, &wr, &r))
27205 {
27206 int yb = window_text_bottom_y (w);
27207 struct glyph_row *row;
27208 int cursor_cleared_p;
27209 struct glyph_row *first_overlapping_row, *last_overlapping_row;
27210
27211 TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n",
27212 r.x, r.y, r.width, r.height));
27213
27214 /* Convert to window coordinates. */
27215 r.x -= WINDOW_LEFT_EDGE_X (w);
27216 r.y -= WINDOW_TOP_EDGE_Y (w);
27217
27218 /* Turn off the cursor. */
27219 if (!w->pseudo_window_p
27220 && phys_cursor_in_rect_p (w, &r))
27221 {
27222 x_clear_cursor (w);
27223 cursor_cleared_p = 1;
27224 }
27225 else
27226 cursor_cleared_p = 0;
27227
27228 /* Update lines intersecting rectangle R. */
27229 first_overlapping_row = last_overlapping_row = NULL;
27230 for (row = w->current_matrix->rows;
27231 row->enabled_p;
27232 ++row)
27233 {
27234 int y0 = row->y;
27235 int y1 = MATRIX_ROW_BOTTOM_Y (row);
27236
27237 if ((y0 >= r.y && y0 < r.y + r.height)
27238 || (y1 > r.y && y1 < r.y + r.height)
27239 || (r.y >= y0 && r.y < y1)
27240 || (r.y + r.height > y0 && r.y + r.height < y1))
27241 {
27242 /* A header line may be overlapping, but there is no need
27243 to fix overlapping areas for them. KFS 2005-02-12 */
27244 if (row->overlapping_p && !row->mode_line_p)
27245 {
27246 if (first_overlapping_row == NULL)
27247 first_overlapping_row = row;
27248 last_overlapping_row = row;
27249 }
27250
27251 row->clip = fr;
27252 if (expose_line (w, row, &r))
27253 mouse_face_overwritten_p = 1;
27254 row->clip = NULL;
27255 }
27256 else if (row->overlapping_p)
27257 {
27258 /* We must redraw a row overlapping the exposed area. */
27259 if (y0 < r.y
27260 ? y0 + row->phys_height > r.y
27261 : y0 + row->ascent - row->phys_ascent < r.y +r.height)
27262 {
27263 if (first_overlapping_row == NULL)
27264 first_overlapping_row = row;
27265 last_overlapping_row = row;
27266 }
27267 }
27268
27269 if (y1 >= yb)
27270 break;
27271 }
27272
27273 /* Display the mode line if there is one. */
27274 if (WINDOW_WANTS_MODELINE_P (w)
27275 && (row = MATRIX_MODE_LINE_ROW (w->current_matrix),
27276 row->enabled_p)
27277 && row->y < r.y + r.height)
27278 {
27279 if (expose_line (w, row, &r))
27280 mouse_face_overwritten_p = 1;
27281 }
27282
27283 if (!w->pseudo_window_p)
27284 {
27285 /* Fix the display of overlapping rows. */
27286 if (first_overlapping_row)
27287 expose_overlaps (w, first_overlapping_row, last_overlapping_row,
27288 fr);
27289
27290 /* Draw border between windows. */
27291 x_draw_vertical_border (w);
27292
27293 /* Turn the cursor on again. */
27294 if (cursor_cleared_p)
27295 update_window_cursor (w, 1);
27296 }
27297 }
27298
27299 return mouse_face_overwritten_p;
27300 }
27301
27302
27303
27304 /* Redraw (parts) of all windows in the window tree rooted at W that
27305 intersect R. R contains frame pixel coordinates. Value is
27306 non-zero if the exposure overwrites mouse-face. */
27307
27308 static int
27309 expose_window_tree (struct window *w, XRectangle *r)
27310 {
27311 struct frame *f = XFRAME (w->frame);
27312 int mouse_face_overwritten_p = 0;
27313
27314 while (w && !FRAME_GARBAGED_P (f))
27315 {
27316 if (!NILP (w->hchild))
27317 mouse_face_overwritten_p
27318 |= expose_window_tree (XWINDOW (w->hchild), r);
27319 else if (!NILP (w->vchild))
27320 mouse_face_overwritten_p
27321 |= expose_window_tree (XWINDOW (w->vchild), r);
27322 else
27323 mouse_face_overwritten_p |= expose_window (w, r);
27324
27325 w = NILP (w->next) ? NULL : XWINDOW (w->next);
27326 }
27327
27328 return mouse_face_overwritten_p;
27329 }
27330
27331
27332 /* EXPORT:
27333 Redisplay an exposed area of frame F. X and Y are the upper-left
27334 corner of the exposed rectangle. W and H are width and height of
27335 the exposed area. All are pixel values. W or H zero means redraw
27336 the entire frame. */
27337
27338 void
27339 expose_frame (struct frame *f, int x, int y, int w, int h)
27340 {
27341 XRectangle r;
27342 int mouse_face_overwritten_p = 0;
27343
27344 TRACE ((stderr, "expose_frame "));
27345
27346 /* No need to redraw if frame will be redrawn soon. */
27347 if (FRAME_GARBAGED_P (f))
27348 {
27349 TRACE ((stderr, " garbaged\n"));
27350 return;
27351 }
27352
27353 /* If basic faces haven't been realized yet, there is no point in
27354 trying to redraw anything. This can happen when we get an expose
27355 event while Emacs is starting, e.g. by moving another window. */
27356 if (FRAME_FACE_CACHE (f) == NULL
27357 || FRAME_FACE_CACHE (f)->used < BASIC_FACE_ID_SENTINEL)
27358 {
27359 TRACE ((stderr, " no faces\n"));
27360 return;
27361 }
27362
27363 if (w == 0 || h == 0)
27364 {
27365 r.x = r.y = 0;
27366 r.width = FRAME_COLUMN_WIDTH (f) * FRAME_COLS (f);
27367 r.height = FRAME_LINE_HEIGHT (f) * FRAME_LINES (f);
27368 }
27369 else
27370 {
27371 r.x = x;
27372 r.y = y;
27373 r.width = w;
27374 r.height = h;
27375 }
27376
27377 TRACE ((stderr, "(%d, %d, %d, %d)\n", r.x, r.y, r.width, r.height));
27378 mouse_face_overwritten_p = expose_window_tree (XWINDOW (f->root_window), &r);
27379
27380 if (WINDOWP (f->tool_bar_window))
27381 mouse_face_overwritten_p
27382 |= expose_window (XWINDOW (f->tool_bar_window), &r);
27383
27384 #ifdef HAVE_X_WINDOWS
27385 #ifndef MSDOS
27386 #ifndef USE_X_TOOLKIT
27387 if (WINDOWP (f->menu_bar_window))
27388 mouse_face_overwritten_p
27389 |= expose_window (XWINDOW (f->menu_bar_window), &r);
27390 #endif /* not USE_X_TOOLKIT */
27391 #endif
27392 #endif
27393
27394 /* Some window managers support a focus-follows-mouse style with
27395 delayed raising of frames. Imagine a partially obscured frame,
27396 and moving the mouse into partially obscured mouse-face on that
27397 frame. The visible part of the mouse-face will be highlighted,
27398 then the WM raises the obscured frame. With at least one WM, KDE
27399 2.1, Emacs is not getting any event for the raising of the frame
27400 (even tried with SubstructureRedirectMask), only Expose events.
27401 These expose events will draw text normally, i.e. not
27402 highlighted. Which means we must redo the highlight here.
27403 Subsume it under ``we love X''. --gerd 2001-08-15 */
27404 /* Included in Windows version because Windows most likely does not
27405 do the right thing if any third party tool offers
27406 focus-follows-mouse with delayed raise. --jason 2001-10-12 */
27407 if (mouse_face_overwritten_p && !FRAME_GARBAGED_P (f))
27408 {
27409 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
27410 if (f == hlinfo->mouse_face_mouse_frame)
27411 {
27412 int mouse_x = hlinfo->mouse_face_mouse_x;
27413 int mouse_y = hlinfo->mouse_face_mouse_y;
27414 clear_mouse_face (hlinfo);
27415 note_mouse_highlight (f, mouse_x, mouse_y);
27416 }
27417 }
27418 }
27419
27420
27421 /* EXPORT:
27422 Determine the intersection of two rectangles R1 and R2. Return
27423 the intersection in *RESULT. Value is non-zero if RESULT is not
27424 empty. */
27425
27426 int
27427 x_intersect_rectangles (XRectangle *r1, XRectangle *r2, XRectangle *result)
27428 {
27429 XRectangle *left, *right;
27430 XRectangle *upper, *lower;
27431 int intersection_p = 0;
27432
27433 /* Rearrange so that R1 is the left-most rectangle. */
27434 if (r1->x < r2->x)
27435 left = r1, right = r2;
27436 else
27437 left = r2, right = r1;
27438
27439 /* X0 of the intersection is right.x0, if this is inside R1,
27440 otherwise there is no intersection. */
27441 if (right->x <= left->x + left->width)
27442 {
27443 result->x = right->x;
27444
27445 /* The right end of the intersection is the minimum of
27446 the right ends of left and right. */
27447 result->width = (min (left->x + left->width, right->x + right->width)
27448 - result->x);
27449
27450 /* Same game for Y. */
27451 if (r1->y < r2->y)
27452 upper = r1, lower = r2;
27453 else
27454 upper = r2, lower = r1;
27455
27456 /* The upper end of the intersection is lower.y0, if this is inside
27457 of upper. Otherwise, there is no intersection. */
27458 if (lower->y <= upper->y + upper->height)
27459 {
27460 result->y = lower->y;
27461
27462 /* The lower end of the intersection is the minimum of the lower
27463 ends of upper and lower. */
27464 result->height = (min (lower->y + lower->height,
27465 upper->y + upper->height)
27466 - result->y);
27467 intersection_p = 1;
27468 }
27469 }
27470
27471 return intersection_p;
27472 }
27473
27474 #endif /* HAVE_WINDOW_SYSTEM */
27475
27476 \f
27477 /***********************************************************************
27478 Initialization
27479 ***********************************************************************/
27480
27481 void
27482 syms_of_xdisp (void)
27483 {
27484 Vwith_echo_area_save_vector = Qnil;
27485 staticpro (&Vwith_echo_area_save_vector);
27486
27487 Vmessage_stack = Qnil;
27488 staticpro (&Vmessage_stack);
27489
27490 DEFSYM (Qinhibit_redisplay, "inhibit-redisplay");
27491
27492 message_dolog_marker1 = Fmake_marker ();
27493 staticpro (&message_dolog_marker1);
27494 message_dolog_marker2 = Fmake_marker ();
27495 staticpro (&message_dolog_marker2);
27496 message_dolog_marker3 = Fmake_marker ();
27497 staticpro (&message_dolog_marker3);
27498
27499 #if GLYPH_DEBUG
27500 defsubr (&Sdump_frame_glyph_matrix);
27501 defsubr (&Sdump_glyph_matrix);
27502 defsubr (&Sdump_glyph_row);
27503 defsubr (&Sdump_tool_bar_row);
27504 defsubr (&Strace_redisplay);
27505 defsubr (&Strace_to_stderr);
27506 #endif
27507 #ifdef HAVE_WINDOW_SYSTEM
27508 defsubr (&Stool_bar_lines_needed);
27509 defsubr (&Slookup_image_map);
27510 #endif
27511 defsubr (&Sformat_mode_line);
27512 defsubr (&Sinvisible_p);
27513 defsubr (&Scurrent_bidi_paragraph_direction);
27514
27515 DEFSYM (Qmenu_bar_update_hook, "menu-bar-update-hook");
27516 DEFSYM (Qoverriding_terminal_local_map, "overriding-terminal-local-map");
27517 DEFSYM (Qoverriding_local_map, "overriding-local-map");
27518 DEFSYM (Qwindow_scroll_functions, "window-scroll-functions");
27519 DEFSYM (Qwindow_text_change_functions, "window-text-change-functions");
27520 DEFSYM (Qredisplay_end_trigger_functions, "redisplay-end-trigger-functions");
27521 DEFSYM (Qinhibit_point_motion_hooks, "inhibit-point-motion-hooks");
27522 DEFSYM (Qeval, "eval");
27523 DEFSYM (QCdata, ":data");
27524 DEFSYM (Qdisplay, "display");
27525 DEFSYM (Qspace_width, "space-width");
27526 DEFSYM (Qraise, "raise");
27527 DEFSYM (Qslice, "slice");
27528 DEFSYM (Qspace, "space");
27529 DEFSYM (Qmargin, "margin");
27530 DEFSYM (Qpointer, "pointer");
27531 DEFSYM (Qleft_margin, "left-margin");
27532 DEFSYM (Qright_margin, "right-margin");
27533 DEFSYM (Qcenter, "center");
27534 DEFSYM (Qline_height, "line-height");
27535 DEFSYM (QCalign_to, ":align-to");
27536 DEFSYM (QCrelative_width, ":relative-width");
27537 DEFSYM (QCrelative_height, ":relative-height");
27538 DEFSYM (QCeval, ":eval");
27539 DEFSYM (QCpropertize, ":propertize");
27540 DEFSYM (QCfile, ":file");
27541 DEFSYM (Qfontified, "fontified");
27542 DEFSYM (Qfontification_functions, "fontification-functions");
27543 DEFSYM (Qtrailing_whitespace, "trailing-whitespace");
27544 DEFSYM (Qescape_glyph, "escape-glyph");
27545 DEFSYM (Qnobreak_space, "nobreak-space");
27546 DEFSYM (Qimage, "image");
27547 DEFSYM (Qtext, "text");
27548 DEFSYM (Qboth, "both");
27549 DEFSYM (Qboth_horiz, "both-horiz");
27550 DEFSYM (Qtext_image_horiz, "text-image-horiz");
27551 DEFSYM (QCmap, ":map");
27552 DEFSYM (QCpointer, ":pointer");
27553 DEFSYM (Qrect, "rect");
27554 DEFSYM (Qcircle, "circle");
27555 DEFSYM (Qpoly, "poly");
27556 DEFSYM (Qmessage_truncate_lines, "message-truncate-lines");
27557 DEFSYM (Qgrow_only, "grow-only");
27558 DEFSYM (Qinhibit_menubar_update, "inhibit-menubar-update");
27559 DEFSYM (Qinhibit_eval_during_redisplay, "inhibit-eval-during-redisplay");
27560 DEFSYM (Qposition, "position");
27561 DEFSYM (Qbuffer_position, "buffer-position");
27562 DEFSYM (Qobject, "object");
27563 DEFSYM (Qbar, "bar");
27564 DEFSYM (Qhbar, "hbar");
27565 DEFSYM (Qbox, "box");
27566 DEFSYM (Qhollow, "hollow");
27567 DEFSYM (Qhand, "hand");
27568 DEFSYM (Qarrow, "arrow");
27569 DEFSYM (Qtext, "text");
27570 DEFSYM (Qinhibit_free_realized_faces, "inhibit-free-realized-faces");
27571
27572 list_of_error = Fcons (Fcons (intern_c_string ("error"),
27573 Fcons (intern_c_string ("void-variable"), Qnil)),
27574 Qnil);
27575 staticpro (&list_of_error);
27576
27577 DEFSYM (Qlast_arrow_position, "last-arrow-position");
27578 DEFSYM (Qlast_arrow_string, "last-arrow-string");
27579 DEFSYM (Qoverlay_arrow_string, "overlay-arrow-string");
27580 DEFSYM (Qoverlay_arrow_bitmap, "overlay-arrow-bitmap");
27581
27582 echo_buffer[0] = echo_buffer[1] = Qnil;
27583 staticpro (&echo_buffer[0]);
27584 staticpro (&echo_buffer[1]);
27585
27586 echo_area_buffer[0] = echo_area_buffer[1] = Qnil;
27587 staticpro (&echo_area_buffer[0]);
27588 staticpro (&echo_area_buffer[1]);
27589
27590 Vmessages_buffer_name = make_pure_c_string ("*Messages*");
27591 staticpro (&Vmessages_buffer_name);
27592
27593 mode_line_proptrans_alist = Qnil;
27594 staticpro (&mode_line_proptrans_alist);
27595 mode_line_string_list = Qnil;
27596 staticpro (&mode_line_string_list);
27597 mode_line_string_face = Qnil;
27598 staticpro (&mode_line_string_face);
27599 mode_line_string_face_prop = Qnil;
27600 staticpro (&mode_line_string_face_prop);
27601 Vmode_line_unwind_vector = Qnil;
27602 staticpro (&Vmode_line_unwind_vector);
27603
27604 help_echo_string = Qnil;
27605 staticpro (&help_echo_string);
27606 help_echo_object = Qnil;
27607 staticpro (&help_echo_object);
27608 help_echo_window = Qnil;
27609 staticpro (&help_echo_window);
27610 previous_help_echo_string = Qnil;
27611 staticpro (&previous_help_echo_string);
27612 help_echo_pos = -1;
27613
27614 DEFSYM (Qright_to_left, "right-to-left");
27615 DEFSYM (Qleft_to_right, "left-to-right");
27616
27617 #ifdef HAVE_WINDOW_SYSTEM
27618 DEFVAR_BOOL ("x-stretch-cursor", x_stretch_cursor_p,
27619 doc: /* *Non-nil means draw block cursor as wide as the glyph under it.
27620 For example, if a block cursor is over a tab, it will be drawn as
27621 wide as that tab on the display. */);
27622 x_stretch_cursor_p = 0;
27623 #endif
27624
27625 DEFVAR_LISP ("show-trailing-whitespace", Vshow_trailing_whitespace,
27626 doc: /* *Non-nil means highlight trailing whitespace.
27627 The face used for trailing whitespace is `trailing-whitespace'. */);
27628 Vshow_trailing_whitespace = Qnil;
27629
27630 DEFVAR_LISP ("nobreak-char-display", Vnobreak_char_display,
27631 doc: /* *Control highlighting of nobreak space and soft hyphen.
27632 A value of t means highlight the character itself (for nobreak space,
27633 use face `nobreak-space').
27634 A value of nil means no highlighting.
27635 Other values mean display the escape glyph followed by an ordinary
27636 space or ordinary hyphen. */);
27637 Vnobreak_char_display = Qt;
27638
27639 DEFVAR_LISP ("void-text-area-pointer", Vvoid_text_area_pointer,
27640 doc: /* *The pointer shape to show in void text areas.
27641 A value of nil means to show the text pointer. Other options are `arrow',
27642 `text', `hand', `vdrag', `hdrag', `modeline', and `hourglass'. */);
27643 Vvoid_text_area_pointer = Qarrow;
27644
27645 DEFVAR_LISP ("inhibit-redisplay", Vinhibit_redisplay,
27646 doc: /* Non-nil means don't actually do any redisplay.
27647 This is used for internal purposes. */);
27648 Vinhibit_redisplay = Qnil;
27649
27650 DEFVAR_LISP ("global-mode-string", Vglobal_mode_string,
27651 doc: /* String (or mode line construct) included (normally) in `mode-line-format'. */);
27652 Vglobal_mode_string = Qnil;
27653
27654 DEFVAR_LISP ("overlay-arrow-position", Voverlay_arrow_position,
27655 doc: /* Marker for where to display an arrow on top of the buffer text.
27656 This must be the beginning of a line in order to work.
27657 See also `overlay-arrow-string'. */);
27658 Voverlay_arrow_position = Qnil;
27659
27660 DEFVAR_LISP ("overlay-arrow-string", Voverlay_arrow_string,
27661 doc: /* String to display as an arrow in non-window frames.
27662 See also `overlay-arrow-position'. */);
27663 Voverlay_arrow_string = make_pure_c_string ("=>");
27664
27665 DEFVAR_LISP ("overlay-arrow-variable-list", Voverlay_arrow_variable_list,
27666 doc: /* List of variables (symbols) which hold markers for overlay arrows.
27667 The symbols on this list are examined during redisplay to determine
27668 where to display overlay arrows. */);
27669 Voverlay_arrow_variable_list
27670 = Fcons (intern_c_string ("overlay-arrow-position"), Qnil);
27671
27672 DEFVAR_INT ("scroll-step", emacs_scroll_step,
27673 doc: /* *The number of lines to try scrolling a window by when point moves out.
27674 If that fails to bring point back on frame, point is centered instead.
27675 If this is zero, point is always centered after it moves off frame.
27676 If you want scrolling to always be a line at a time, you should set
27677 `scroll-conservatively' to a large value rather than set this to 1. */);
27678
27679 DEFVAR_INT ("scroll-conservatively", scroll_conservatively,
27680 doc: /* *Scroll up to this many lines, to bring point back on screen.
27681 If point moves off-screen, redisplay will scroll by up to
27682 `scroll-conservatively' lines in order to bring point just barely
27683 onto the screen again. If that cannot be done, then redisplay
27684 recenters point as usual.
27685
27686 If the value is greater than 100, redisplay will never recenter point,
27687 but will always scroll just enough text to bring point into view, even
27688 if you move far away.
27689
27690 A value of zero means always recenter point if it moves off screen. */);
27691 scroll_conservatively = 0;
27692
27693 DEFVAR_INT ("scroll-margin", scroll_margin,
27694 doc: /* *Number of lines of margin at the top and bottom of a window.
27695 Recenter the window whenever point gets within this many lines
27696 of the top or bottom of the window. */);
27697 scroll_margin = 0;
27698
27699 DEFVAR_LISP ("display-pixels-per-inch", Vdisplay_pixels_per_inch,
27700 doc: /* Pixels per inch value for non-window system displays.
27701 Value is a number or a cons (WIDTH-DPI . HEIGHT-DPI). */);
27702 Vdisplay_pixels_per_inch = make_float (72.0);
27703
27704 #if GLYPH_DEBUG
27705 DEFVAR_INT ("debug-end-pos", debug_end_pos, doc: /* Don't ask. */);
27706 #endif
27707
27708 DEFVAR_LISP ("truncate-partial-width-windows",
27709 Vtruncate_partial_width_windows,
27710 doc: /* Non-nil means truncate lines in windows narrower than the frame.
27711 For an integer value, truncate lines in each window narrower than the
27712 full frame width, provided the window width is less than that integer;
27713 otherwise, respect the value of `truncate-lines'.
27714
27715 For any other non-nil value, truncate lines in all windows that do
27716 not span the full frame width.
27717
27718 A value of nil means to respect the value of `truncate-lines'.
27719
27720 If `word-wrap' is enabled, you might want to reduce this. */);
27721 Vtruncate_partial_width_windows = make_number (50);
27722
27723 DEFVAR_BOOL ("mode-line-inverse-video", mode_line_inverse_video,
27724 doc: /* When nil, display the mode-line/header-line/menu-bar in the default face.
27725 Any other value means to use the appropriate face, `mode-line',
27726 `header-line', or `menu' respectively. */);
27727 mode_line_inverse_video = 1;
27728
27729 DEFVAR_LISP ("line-number-display-limit", Vline_number_display_limit,
27730 doc: /* *Maximum buffer size for which line number should be displayed.
27731 If the buffer is bigger than this, the line number does not appear
27732 in the mode line. A value of nil means no limit. */);
27733 Vline_number_display_limit = Qnil;
27734
27735 DEFVAR_INT ("line-number-display-limit-width",
27736 line_number_display_limit_width,
27737 doc: /* *Maximum line width (in characters) for line number display.
27738 If the average length of the lines near point is bigger than this, then the
27739 line number may be omitted from the mode line. */);
27740 line_number_display_limit_width = 200;
27741
27742 DEFVAR_BOOL ("highlight-nonselected-windows", highlight_nonselected_windows,
27743 doc: /* *Non-nil means highlight region even in nonselected windows. */);
27744 highlight_nonselected_windows = 0;
27745
27746 DEFVAR_BOOL ("multiple-frames", multiple_frames,
27747 doc: /* Non-nil if more than one frame is visible on this display.
27748 Minibuffer-only frames don't count, but iconified frames do.
27749 This variable is not guaranteed to be accurate except while processing
27750 `frame-title-format' and `icon-title-format'. */);
27751
27752 DEFVAR_LISP ("frame-title-format", Vframe_title_format,
27753 doc: /* Template for displaying the title bar of visible frames.
27754 \(Assuming the window manager supports this feature.)
27755
27756 This variable has the same structure as `mode-line-format', except that
27757 the %c and %l constructs are ignored. It is used only on frames for
27758 which no explicit name has been set \(see `modify-frame-parameters'). */);
27759
27760 DEFVAR_LISP ("icon-title-format", Vicon_title_format,
27761 doc: /* Template for displaying the title bar of an iconified frame.
27762 \(Assuming the window manager supports this feature.)
27763 This variable has the same structure as `mode-line-format' (which see),
27764 and is used only on frames for which no explicit name has been set
27765 \(see `modify-frame-parameters'). */);
27766 Vicon_title_format
27767 = Vframe_title_format
27768 = pure_cons (intern_c_string ("multiple-frames"),
27769 pure_cons (make_pure_c_string ("%b"),
27770 pure_cons (pure_cons (empty_unibyte_string,
27771 pure_cons (intern_c_string ("invocation-name"),
27772 pure_cons (make_pure_c_string ("@"),
27773 pure_cons (intern_c_string ("system-name"),
27774 Qnil)))),
27775 Qnil)));
27776
27777 DEFVAR_LISP ("message-log-max", Vmessage_log_max,
27778 doc: /* Maximum number of lines to keep in the message log buffer.
27779 If nil, disable message logging. If t, log messages but don't truncate
27780 the buffer when it becomes large. */);
27781 Vmessage_log_max = make_number (100);
27782
27783 DEFVAR_LISP ("window-size-change-functions", Vwindow_size_change_functions,
27784 doc: /* Functions called before redisplay, if window sizes have changed.
27785 The value should be a list of functions that take one argument.
27786 Just before redisplay, for each frame, if any of its windows have changed
27787 size since the last redisplay, or have been split or deleted,
27788 all the functions in the list are called, with the frame as argument. */);
27789 Vwindow_size_change_functions = Qnil;
27790
27791 DEFVAR_LISP ("window-scroll-functions", Vwindow_scroll_functions,
27792 doc: /* List of functions to call before redisplaying a window with scrolling.
27793 Each function is called with two arguments, the window and its new
27794 display-start position. Note that these functions are also called by
27795 `set-window-buffer'. Also note that the value of `window-end' is not
27796 valid when these functions are called. */);
27797 Vwindow_scroll_functions = Qnil;
27798
27799 DEFVAR_LISP ("window-text-change-functions",
27800 Vwindow_text_change_functions,
27801 doc: /* Functions to call in redisplay when text in the window might change. */);
27802 Vwindow_text_change_functions = Qnil;
27803
27804 DEFVAR_LISP ("redisplay-end-trigger-functions", Vredisplay_end_trigger_functions,
27805 doc: /* Functions called when redisplay of a window reaches the end trigger.
27806 Each function is called with two arguments, the window and the end trigger value.
27807 See `set-window-redisplay-end-trigger'. */);
27808 Vredisplay_end_trigger_functions = Qnil;
27809
27810 DEFVAR_LISP ("mouse-autoselect-window", Vmouse_autoselect_window,
27811 doc: /* *Non-nil means autoselect window with mouse pointer.
27812 If nil, do not autoselect windows.
27813 A positive number means delay autoselection by that many seconds: a
27814 window is autoselected only after the mouse has remained in that
27815 window for the duration of the delay.
27816 A negative number has a similar effect, but causes windows to be
27817 autoselected only after the mouse has stopped moving. \(Because of
27818 the way Emacs compares mouse events, you will occasionally wait twice
27819 that time before the window gets selected.\)
27820 Any other value means to autoselect window instantaneously when the
27821 mouse pointer enters it.
27822
27823 Autoselection selects the minibuffer only if it is active, and never
27824 unselects the minibuffer if it is active.
27825
27826 When customizing this variable make sure that the actual value of
27827 `focus-follows-mouse' matches the behavior of your window manager. */);
27828 Vmouse_autoselect_window = Qnil;
27829
27830 DEFVAR_LISP ("auto-resize-tool-bars", Vauto_resize_tool_bars,
27831 doc: /* *Non-nil means automatically resize tool-bars.
27832 This dynamically changes the tool-bar's height to the minimum height
27833 that is needed to make all tool-bar items visible.
27834 If value is `grow-only', the tool-bar's height is only increased
27835 automatically; to decrease the tool-bar height, use \\[recenter]. */);
27836 Vauto_resize_tool_bars = Qt;
27837
27838 DEFVAR_BOOL ("auto-raise-tool-bar-buttons", auto_raise_tool_bar_buttons_p,
27839 doc: /* *Non-nil means raise tool-bar buttons when the mouse moves over them. */);
27840 auto_raise_tool_bar_buttons_p = 1;
27841
27842 DEFVAR_BOOL ("make-cursor-line-fully-visible", make_cursor_line_fully_visible_p,
27843 doc: /* *Non-nil means to scroll (recenter) cursor line if it is not fully visible. */);
27844 make_cursor_line_fully_visible_p = 1;
27845
27846 DEFVAR_LISP ("tool-bar-border", Vtool_bar_border,
27847 doc: /* *Border below tool-bar in pixels.
27848 If an integer, use it as the height of the border.
27849 If it is one of `internal-border-width' or `border-width', use the
27850 value of the corresponding frame parameter.
27851 Otherwise, no border is added below the tool-bar. */);
27852 Vtool_bar_border = Qinternal_border_width;
27853
27854 DEFVAR_LISP ("tool-bar-button-margin", Vtool_bar_button_margin,
27855 doc: /* *Margin around tool-bar buttons in pixels.
27856 If an integer, use that for both horizontal and vertical margins.
27857 Otherwise, value should be a pair of integers `(HORZ . VERT)' with
27858 HORZ specifying the horizontal margin, and VERT specifying the
27859 vertical margin. */);
27860 Vtool_bar_button_margin = make_number (DEFAULT_TOOL_BAR_BUTTON_MARGIN);
27861
27862 DEFVAR_INT ("tool-bar-button-relief", tool_bar_button_relief,
27863 doc: /* *Relief thickness of tool-bar buttons. */);
27864 tool_bar_button_relief = DEFAULT_TOOL_BAR_BUTTON_RELIEF;
27865
27866 DEFVAR_LISP ("tool-bar-style", Vtool_bar_style,
27867 doc: /* Tool bar style to use.
27868 It can be one of
27869 image - show images only
27870 text - show text only
27871 both - show both, text below image
27872 both-horiz - show text to the right of the image
27873 text-image-horiz - show text to the left of the image
27874 any other - use system default or image if no system default. */);
27875 Vtool_bar_style = Qnil;
27876
27877 DEFVAR_INT ("tool-bar-max-label-size", tool_bar_max_label_size,
27878 doc: /* *Maximum number of characters a label can have to be shown.
27879 The tool bar style must also show labels for this to have any effect, see
27880 `tool-bar-style'. */);
27881 tool_bar_max_label_size = DEFAULT_TOOL_BAR_LABEL_SIZE;
27882
27883 DEFVAR_LISP ("fontification-functions", Vfontification_functions,
27884 doc: /* List of functions to call to fontify regions of text.
27885 Each function is called with one argument POS. Functions must
27886 fontify a region starting at POS in the current buffer, and give
27887 fontified regions the property `fontified'. */);
27888 Vfontification_functions = Qnil;
27889 Fmake_variable_buffer_local (Qfontification_functions);
27890
27891 DEFVAR_BOOL ("unibyte-display-via-language-environment",
27892 unibyte_display_via_language_environment,
27893 doc: /* *Non-nil means display unibyte text according to language environment.
27894 Specifically, this means that raw bytes in the range 160-255 decimal
27895 are displayed by converting them to the equivalent multibyte characters
27896 according to the current language environment. As a result, they are
27897 displayed according to the current fontset.
27898
27899 Note that this variable affects only how these bytes are displayed,
27900 but does not change the fact they are interpreted as raw bytes. */);
27901 unibyte_display_via_language_environment = 0;
27902
27903 DEFVAR_LISP ("max-mini-window-height", Vmax_mini_window_height,
27904 doc: /* *Maximum height for resizing mini-windows (the minibuffer and the echo area).
27905 If a float, it specifies a fraction of the mini-window frame's height.
27906 If an integer, it specifies a number of lines. */);
27907 Vmax_mini_window_height = make_float (0.25);
27908
27909 DEFVAR_LISP ("resize-mini-windows", Vresize_mini_windows,
27910 doc: /* How to resize mini-windows (the minibuffer and the echo area).
27911 A value of nil means don't automatically resize mini-windows.
27912 A value of t means resize them to fit the text displayed in them.
27913 A value of `grow-only', the default, means let mini-windows grow only;
27914 they return to their normal size when the minibuffer is closed, or the
27915 echo area becomes empty. */);
27916 Vresize_mini_windows = Qgrow_only;
27917
27918 DEFVAR_LISP ("blink-cursor-alist", Vblink_cursor_alist,
27919 doc: /* Alist specifying how to blink the cursor off.
27920 Each element has the form (ON-STATE . OFF-STATE). Whenever the
27921 `cursor-type' frame-parameter or variable equals ON-STATE,
27922 comparing using `equal', Emacs uses OFF-STATE to specify
27923 how to blink it off. ON-STATE and OFF-STATE are values for
27924 the `cursor-type' frame parameter.
27925
27926 If a frame's ON-STATE has no entry in this list,
27927 the frame's other specifications determine how to blink the cursor off. */);
27928 Vblink_cursor_alist = Qnil;
27929
27930 DEFVAR_BOOL ("auto-hscroll-mode", automatic_hscrolling_p,
27931 doc: /* Allow or disallow automatic horizontal scrolling of windows.
27932 If non-nil, windows are automatically scrolled horizontally to make
27933 point visible. */);
27934 automatic_hscrolling_p = 1;
27935 DEFSYM (Qauto_hscroll_mode, "auto-hscroll-mode");
27936
27937 DEFVAR_INT ("hscroll-margin", hscroll_margin,
27938 doc: /* *How many columns away from the window edge point is allowed to get
27939 before automatic hscrolling will horizontally scroll the window. */);
27940 hscroll_margin = 5;
27941
27942 DEFVAR_LISP ("hscroll-step", Vhscroll_step,
27943 doc: /* *How many columns to scroll the window when point gets too close to the edge.
27944 When point is less than `hscroll-margin' columns from the window
27945 edge, automatic hscrolling will scroll the window by the amount of columns
27946 determined by this variable. If its value is a positive integer, scroll that
27947 many columns. If it's a positive floating-point number, it specifies the
27948 fraction of the window's width to scroll. If it's nil or zero, point will be
27949 centered horizontally after the scroll. Any other value, including negative
27950 numbers, are treated as if the value were zero.
27951
27952 Automatic hscrolling always moves point outside the scroll margin, so if
27953 point was more than scroll step columns inside the margin, the window will
27954 scroll more than the value given by the scroll step.
27955
27956 Note that the lower bound for automatic hscrolling specified by `scroll-left'
27957 and `scroll-right' overrides this variable's effect. */);
27958 Vhscroll_step = make_number (0);
27959
27960 DEFVAR_BOOL ("message-truncate-lines", message_truncate_lines,
27961 doc: /* If non-nil, messages are truncated instead of resizing the echo area.
27962 Bind this around calls to `message' to let it take effect. */);
27963 message_truncate_lines = 0;
27964
27965 DEFVAR_LISP ("menu-bar-update-hook", Vmenu_bar_update_hook,
27966 doc: /* Normal hook run to update the menu bar definitions.
27967 Redisplay runs this hook before it redisplays the menu bar.
27968 This is used to update submenus such as Buffers,
27969 whose contents depend on various data. */);
27970 Vmenu_bar_update_hook = Qnil;
27971
27972 DEFVAR_LISP ("menu-updating-frame", Vmenu_updating_frame,
27973 doc: /* Frame for which we are updating a menu.
27974 The enable predicate for a menu binding should check this variable. */);
27975 Vmenu_updating_frame = Qnil;
27976
27977 DEFVAR_BOOL ("inhibit-menubar-update", inhibit_menubar_update,
27978 doc: /* Non-nil means don't update menu bars. Internal use only. */);
27979 inhibit_menubar_update = 0;
27980
27981 DEFVAR_LISP ("wrap-prefix", Vwrap_prefix,
27982 doc: /* Prefix prepended to all continuation lines at display time.
27983 The value may be a string, an image, or a stretch-glyph; it is
27984 interpreted in the same way as the value of a `display' text property.
27985
27986 This variable is overridden by any `wrap-prefix' text or overlay
27987 property.
27988
27989 To add a prefix to non-continuation lines, use `line-prefix'. */);
27990 Vwrap_prefix = Qnil;
27991 DEFSYM (Qwrap_prefix, "wrap-prefix");
27992 Fmake_variable_buffer_local (Qwrap_prefix);
27993
27994 DEFVAR_LISP ("line-prefix", Vline_prefix,
27995 doc: /* Prefix prepended to all non-continuation lines at display time.
27996 The value may be a string, an image, or a stretch-glyph; it is
27997 interpreted in the same way as the value of a `display' text property.
27998
27999 This variable is overridden by any `line-prefix' text or overlay
28000 property.
28001
28002 To add a prefix to continuation lines, use `wrap-prefix'. */);
28003 Vline_prefix = Qnil;
28004 DEFSYM (Qline_prefix, "line-prefix");
28005 Fmake_variable_buffer_local (Qline_prefix);
28006
28007 DEFVAR_BOOL ("inhibit-eval-during-redisplay", inhibit_eval_during_redisplay,
28008 doc: /* Non-nil means don't eval Lisp during redisplay. */);
28009 inhibit_eval_during_redisplay = 0;
28010
28011 DEFVAR_BOOL ("inhibit-free-realized-faces", inhibit_free_realized_faces,
28012 doc: /* Non-nil means don't free realized faces. Internal use only. */);
28013 inhibit_free_realized_faces = 0;
28014
28015 #if GLYPH_DEBUG
28016 DEFVAR_BOOL ("inhibit-try-window-id", inhibit_try_window_id,
28017 doc: /* Inhibit try_window_id display optimization. */);
28018 inhibit_try_window_id = 0;
28019
28020 DEFVAR_BOOL ("inhibit-try-window-reusing", inhibit_try_window_reusing,
28021 doc: /* Inhibit try_window_reusing display optimization. */);
28022 inhibit_try_window_reusing = 0;
28023
28024 DEFVAR_BOOL ("inhibit-try-cursor-movement", inhibit_try_cursor_movement,
28025 doc: /* Inhibit try_cursor_movement display optimization. */);
28026 inhibit_try_cursor_movement = 0;
28027 #endif /* GLYPH_DEBUG */
28028
28029 DEFVAR_INT ("overline-margin", overline_margin,
28030 doc: /* *Space between overline and text, in pixels.
28031 The default value is 2: the height of the overline (1 pixel) plus 1 pixel
28032 margin to the caracter height. */);
28033 overline_margin = 2;
28034
28035 DEFVAR_INT ("underline-minimum-offset",
28036 underline_minimum_offset,
28037 doc: /* Minimum distance between baseline and underline.
28038 This can improve legibility of underlined text at small font sizes,
28039 particularly when using variable `x-use-underline-position-properties'
28040 with fonts that specify an UNDERLINE_POSITION relatively close to the
28041 baseline. The default value is 1. */);
28042 underline_minimum_offset = 1;
28043
28044 DEFVAR_BOOL ("display-hourglass", display_hourglass_p,
28045 doc: /* Non-nil means show an hourglass pointer, when Emacs is busy.
28046 This feature only works when on a window system that can change
28047 cursor shapes. */);
28048 display_hourglass_p = 1;
28049
28050 DEFVAR_LISP ("hourglass-delay", Vhourglass_delay,
28051 doc: /* *Seconds to wait before displaying an hourglass pointer when Emacs is busy. */);
28052 Vhourglass_delay = make_number (DEFAULT_HOURGLASS_DELAY);
28053
28054 hourglass_atimer = NULL;
28055 hourglass_shown_p = 0;
28056
28057 DEFSYM (Qglyphless_char, "glyphless-char");
28058 DEFSYM (Qhex_code, "hex-code");
28059 DEFSYM (Qempty_box, "empty-box");
28060 DEFSYM (Qthin_space, "thin-space");
28061 DEFSYM (Qzero_width, "zero-width");
28062
28063 DEFSYM (Qglyphless_char_display, "glyphless-char-display");
28064 /* Intern this now in case it isn't already done.
28065 Setting this variable twice is harmless.
28066 But don't staticpro it here--that is done in alloc.c. */
28067 Qchar_table_extra_slots = intern_c_string ("char-table-extra-slots");
28068 Fput (Qglyphless_char_display, Qchar_table_extra_slots, make_number (1));
28069
28070 DEFVAR_LISP ("glyphless-char-display", Vglyphless_char_display,
28071 doc: /* Char-table defining glyphless characters.
28072 Each element, if non-nil, should be one of the following:
28073 an ASCII acronym string: display this string in a box
28074 `hex-code': display the hexadecimal code of a character in a box
28075 `empty-box': display as an empty box
28076 `thin-space': display as 1-pixel width space
28077 `zero-width': don't display
28078 An element may also be a cons cell (GRAPHICAL . TEXT), which specifies the
28079 display method for graphical terminals and text terminals respectively.
28080 GRAPHICAL and TEXT should each have one of the values listed above.
28081
28082 The char-table has one extra slot to control the display of a character for
28083 which no font is found. This slot only takes effect on graphical terminals.
28084 Its value should be an ASCII acronym string, `hex-code', `empty-box', or
28085 `thin-space'. The default is `empty-box'. */);
28086 Vglyphless_char_display = Fmake_char_table (Qglyphless_char_display, Qnil);
28087 Fset_char_table_extra_slot (Vglyphless_char_display, make_number (0),
28088 Qempty_box);
28089 }
28090
28091
28092 /* Initialize this module when Emacs starts. */
28093
28094 void
28095 init_xdisp (void)
28096 {
28097 current_header_line_height = current_mode_line_height = -1;
28098
28099 CHARPOS (this_line_start_pos) = 0;
28100
28101 if (!noninteractive)
28102 {
28103 struct window *m = XWINDOW (minibuf_window);
28104 Lisp_Object frame = m->frame;
28105 struct frame *f = XFRAME (frame);
28106 Lisp_Object root = FRAME_ROOT_WINDOW (f);
28107 struct window *r = XWINDOW (root);
28108 int i;
28109
28110 echo_area_window = minibuf_window;
28111
28112 XSETFASTINT (r->top_line, FRAME_TOP_MARGIN (f));
28113 XSETFASTINT (r->total_lines, FRAME_LINES (f) - 1 - FRAME_TOP_MARGIN (f));
28114 XSETFASTINT (r->total_cols, FRAME_COLS (f));
28115 XSETFASTINT (m->top_line, FRAME_LINES (f) - 1);
28116 XSETFASTINT (m->total_lines, 1);
28117 XSETFASTINT (m->total_cols, FRAME_COLS (f));
28118
28119 scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs;
28120 scratch_glyph_row.glyphs[TEXT_AREA + 1]
28121 = scratch_glyphs + MAX_SCRATCH_GLYPHS;
28122
28123 /* The default ellipsis glyphs `...'. */
28124 for (i = 0; i < 3; ++i)
28125 default_invis_vector[i] = make_number ('.');
28126 }
28127
28128 {
28129 /* Allocate the buffer for frame titles.
28130 Also used for `format-mode-line'. */
28131 int size = 100;
28132 mode_line_noprop_buf = (char *) xmalloc (size);
28133 mode_line_noprop_buf_end = mode_line_noprop_buf + size;
28134 mode_line_noprop_ptr = mode_line_noprop_buf;
28135 mode_line_target = MODE_LINE_DISPLAY;
28136 }
28137
28138 help_echo_showing_p = 0;
28139 }
28140
28141 /* Since w32 does not support atimers, it defines its own implementation of
28142 the following three functions in w32fns.c. */
28143 #ifndef WINDOWSNT
28144
28145 /* Platform-independent portion of hourglass implementation. */
28146
28147 /* Return non-zero if houglass timer has been started or hourglass is shown. */
28148 int
28149 hourglass_started (void)
28150 {
28151 return hourglass_shown_p || hourglass_atimer != NULL;
28152 }
28153
28154 /* Cancel a currently active hourglass timer, and start a new one. */
28155 void
28156 start_hourglass (void)
28157 {
28158 #if defined (HAVE_WINDOW_SYSTEM)
28159 EMACS_TIME delay;
28160 int secs, usecs = 0;
28161
28162 cancel_hourglass ();
28163
28164 if (INTEGERP (Vhourglass_delay)
28165 && XINT (Vhourglass_delay) > 0)
28166 secs = XFASTINT (Vhourglass_delay);
28167 else if (FLOATP (Vhourglass_delay)
28168 && XFLOAT_DATA (Vhourglass_delay) > 0)
28169 {
28170 Lisp_Object tem;
28171 tem = Ftruncate (Vhourglass_delay, Qnil);
28172 secs = XFASTINT (tem);
28173 usecs = (XFLOAT_DATA (Vhourglass_delay) - secs) * 1000000;
28174 }
28175 else
28176 secs = DEFAULT_HOURGLASS_DELAY;
28177
28178 EMACS_SET_SECS_USECS (delay, secs, usecs);
28179 hourglass_atimer = start_atimer (ATIMER_RELATIVE, delay,
28180 show_hourglass, NULL);
28181 #endif
28182 }
28183
28184
28185 /* Cancel the hourglass cursor timer if active, hide a busy cursor if
28186 shown. */
28187 void
28188 cancel_hourglass (void)
28189 {
28190 #if defined (HAVE_WINDOW_SYSTEM)
28191 if (hourglass_atimer)
28192 {
28193 cancel_atimer (hourglass_atimer);
28194 hourglass_atimer = NULL;
28195 }
28196
28197 if (hourglass_shown_p)
28198 hide_hourglass ();
28199 #endif
28200 }
28201 #endif /* ! WINDOWSNT */