]> code.delx.au - gnu-emacs/blob - src/xdisp.c
upstream
[gnu-emacs] / src / xdisp.c
1 /* Display generation from window structure and buffer text.
2
3 Copyright (C) 1985-1988, 1993-1995, 1997-2012 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 "character.h"
285 #include "buffer.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 #ifdef HAVE_XWIDGETS
317 #include "xwidget.h"
318 #endif
319 #ifndef FRAME_X_OUTPUT
320 #define FRAME_X_OUTPUT(f) ((f)->output_data.x)
321 #endif
322
323 #define INFINITY 10000000
324
325 Lisp_Object Qoverriding_local_map, Qoverriding_terminal_local_map;
326 Lisp_Object Qwindow_scroll_functions;
327 static Lisp_Object Qwindow_text_change_functions;
328 static Lisp_Object Qredisplay_end_trigger_functions;
329 Lisp_Object Qinhibit_point_motion_hooks;
330 static Lisp_Object QCeval, QCpropertize;
331 Lisp_Object QCfile, QCdata;
332 static Lisp_Object Qfontified;
333 static Lisp_Object Qgrow_only;
334 static Lisp_Object Qinhibit_eval_during_redisplay;
335 static Lisp_Object Qbuffer_position, Qposition, Qobject;
336 static Lisp_Object Qright_to_left, Qleft_to_right;
337
338 /* Cursor shapes */
339 Lisp_Object Qbar, Qhbar, Qbox, Qhollow;
340
341 /* Pointer shapes */
342 static Lisp_Object Qarrow, Qhand;
343 Lisp_Object Qtext;
344
345 /* Holds the list (error). */
346 static Lisp_Object list_of_error;
347
348 static Lisp_Object Qfontification_functions;
349
350 static Lisp_Object Qwrap_prefix;
351 static Lisp_Object Qline_prefix;
352
353 /* Non-nil means don't actually do any redisplay. */
354
355 Lisp_Object Qinhibit_redisplay;
356
357 /* Names of text properties relevant for redisplay. */
358
359 Lisp_Object Qdisplay;
360
361 Lisp_Object Qspace, QCalign_to;
362 static Lisp_Object QCrelative_width, QCrelative_height;
363 Lisp_Object Qleft_margin, Qright_margin;
364 static Lisp_Object Qspace_width, Qraise;
365 static Lisp_Object Qslice;
366 Lisp_Object Qcenter;
367 static Lisp_Object Qmargin, Qpointer;
368 static Lisp_Object Qline_height;
369
370 /* These setters are used only in this file, so they can be private. */
371 static inline void
372 wset_base_line_number (struct window *w, Lisp_Object val)
373 {
374 w->base_line_number = val;
375 }
376 static inline void
377 wset_base_line_pos (struct window *w, Lisp_Object val)
378 {
379 w->base_line_pos = val;
380 }
381 static inline void
382 wset_column_number_displayed (struct window *w, Lisp_Object val)
383 {
384 w->column_number_displayed = val;
385 }
386 static inline void
387 wset_region_showing (struct window *w, Lisp_Object val)
388 {
389 w->region_showing = val;
390 }
391
392 #ifdef HAVE_WINDOW_SYSTEM
393
394 /* Test if overflow newline into fringe. Called with iterator IT
395 at or past right window margin, and with IT->current_x set. */
396
397 #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(IT) \
398 (!NILP (Voverflow_newline_into_fringe) \
399 && FRAME_WINDOW_P ((IT)->f) \
400 && ((IT)->bidi_it.paragraph_dir == R2L \
401 ? (WINDOW_LEFT_FRINGE_WIDTH ((IT)->w) > 0) \
402 : (WINDOW_RIGHT_FRINGE_WIDTH ((IT)->w) > 0)) \
403 && (IT)->current_x == (IT)->last_visible_x \
404 && (IT)->line_wrap != WORD_WRAP)
405
406 #else /* !HAVE_WINDOW_SYSTEM */
407 #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(it) 0
408 #endif /* HAVE_WINDOW_SYSTEM */
409
410 /* Test if the display element loaded in IT, or the underlying buffer
411 or string character, is a space or a TAB character. This is used
412 to determine where word wrapping can occur. */
413
414 #define IT_DISPLAYING_WHITESPACE(it) \
415 ((it->what == IT_CHARACTER && (it->c == ' ' || it->c == '\t')) \
416 || ((STRINGP (it->string) \
417 && (SREF (it->string, IT_STRING_BYTEPOS (*it)) == ' ' \
418 || SREF (it->string, IT_STRING_BYTEPOS (*it)) == '\t')) \
419 || (it->s \
420 && (it->s[IT_BYTEPOS (*it)] == ' ' \
421 || it->s[IT_BYTEPOS (*it)] == '\t')) \
422 || (IT_BYTEPOS (*it) < ZV_BYTE \
423 && (*BYTE_POS_ADDR (IT_BYTEPOS (*it)) == ' ' \
424 || *BYTE_POS_ADDR (IT_BYTEPOS (*it)) == '\t')))) \
425
426 /* Name of the face used to highlight trailing whitespace. */
427
428 static Lisp_Object Qtrailing_whitespace;
429
430 /* Name and number of the face used to highlight escape glyphs. */
431
432 static Lisp_Object Qescape_glyph;
433
434 /* Name and number of the face used to highlight non-breaking spaces. */
435
436 static Lisp_Object Qnobreak_space;
437
438 /* The symbol `image' which is the car of the lists used to represent
439 images in Lisp. Also a tool bar style. */
440
441 Lisp_Object Qimage;
442
443 /* The image map types. */
444 Lisp_Object QCmap;
445 static Lisp_Object QCpointer;
446 static Lisp_Object Qrect, Qcircle, Qpoly;
447
448 /* Tool bar styles */
449 Lisp_Object Qboth, Qboth_horiz, Qtext_image_horiz;
450
451 /* Non-zero means print newline to stdout before next mini-buffer
452 message. */
453
454 int noninteractive_need_newline;
455
456 /* Non-zero means print newline to message log before next message. */
457
458 static int message_log_need_newline;
459
460 /* Three markers that message_dolog uses.
461 It could allocate them itself, but that causes trouble
462 in handling memory-full errors. */
463 static Lisp_Object message_dolog_marker1;
464 static Lisp_Object message_dolog_marker2;
465 static Lisp_Object message_dolog_marker3;
466 \f
467 /* The buffer position of the first character appearing entirely or
468 partially on the line of the selected window which contains the
469 cursor; <= 0 if not known. Set by set_cursor_from_row, used for
470 redisplay optimization in redisplay_internal. */
471
472 static struct text_pos this_line_start_pos;
473
474 /* Number of characters past the end of the line above, including the
475 terminating newline. */
476
477 static struct text_pos this_line_end_pos;
478
479 /* The vertical positions and the height of this line. */
480
481 static int this_line_vpos;
482 static int this_line_y;
483 static int this_line_pixel_height;
484
485 /* X position at which this display line starts. Usually zero;
486 negative if first character is partially visible. */
487
488 static int this_line_start_x;
489
490 /* The smallest character position seen by move_it_* functions as they
491 move across display lines. Used to set MATRIX_ROW_START_CHARPOS of
492 hscrolled lines, see display_line. */
493
494 static struct text_pos this_line_min_pos;
495
496 /* Buffer that this_line_.* variables are referring to. */
497
498 static struct buffer *this_line_buffer;
499
500
501 /* Values of those variables at last redisplay are stored as
502 properties on `overlay-arrow-position' symbol. However, if
503 Voverlay_arrow_position is a marker, last-arrow-position is its
504 numerical position. */
505
506 static Lisp_Object Qlast_arrow_position, Qlast_arrow_string;
507
508 /* Alternative overlay-arrow-string and overlay-arrow-bitmap
509 properties on a symbol in overlay-arrow-variable-list. */
510
511 static Lisp_Object Qoverlay_arrow_string, Qoverlay_arrow_bitmap;
512
513 Lisp_Object Qmenu_bar_update_hook;
514
515 /* Nonzero if an overlay arrow has been displayed in this window. */
516
517 static int overlay_arrow_seen;
518
519 /* Number of windows showing the buffer of the selected window (or
520 another buffer with the same base buffer). keyboard.c refers to
521 this. */
522
523 int buffer_shared;
524
525 /* Vector containing glyphs for an ellipsis `...'. */
526
527 static Lisp_Object default_invis_vector[3];
528
529 /* This is the window where the echo area message was displayed. It
530 is always a mini-buffer window, but it may not be the same window
531 currently active as a mini-buffer. */
532
533 Lisp_Object echo_area_window;
534
535 /* List of pairs (MESSAGE . MULTIBYTE). The function save_message
536 pushes the current message and the value of
537 message_enable_multibyte on the stack, the function restore_message
538 pops the stack and displays MESSAGE again. */
539
540 static Lisp_Object Vmessage_stack;
541
542 /* Nonzero means multibyte characters were enabled when the echo area
543 message was specified. */
544
545 static int message_enable_multibyte;
546
547 /* Nonzero if we should redraw the mode lines on the next redisplay. */
548
549 int update_mode_lines;
550
551 /* Nonzero if window sizes or contents have changed since last
552 redisplay that finished. */
553
554 int windows_or_buffers_changed;
555
556 /* Nonzero means a frame's cursor type has been changed. */
557
558 int cursor_type_changed;
559
560 /* Nonzero after display_mode_line if %l was used and it displayed a
561 line number. */
562
563 static int line_number_displayed;
564
565 /* The name of the *Messages* buffer, a string. */
566
567 static Lisp_Object Vmessages_buffer_name;
568
569 /* Current, index 0, and last displayed echo area message. Either
570 buffers from echo_buffers, or nil to indicate no message. */
571
572 Lisp_Object echo_area_buffer[2];
573
574 /* The buffers referenced from echo_area_buffer. */
575
576 static Lisp_Object echo_buffer[2];
577
578 /* A vector saved used in with_area_buffer to reduce consing. */
579
580 static Lisp_Object Vwith_echo_area_save_vector;
581
582 /* Non-zero means display_echo_area should display the last echo area
583 message again. Set by redisplay_preserve_echo_area. */
584
585 static int display_last_displayed_message_p;
586
587 /* Nonzero if echo area is being used by print; zero if being used by
588 message. */
589
590 static int message_buf_print;
591
592 /* The symbol `inhibit-menubar-update' and its DEFVAR_BOOL variable. */
593
594 static Lisp_Object Qinhibit_menubar_update;
595 static Lisp_Object Qmessage_truncate_lines;
596
597 /* Set to 1 in clear_message to make redisplay_internal aware
598 of an emptied echo area. */
599
600 static int message_cleared_p;
601
602 /* A scratch glyph row with contents used for generating truncation
603 glyphs. Also used in direct_output_for_insert. */
604
605 #define MAX_SCRATCH_GLYPHS 100
606 static struct glyph_row scratch_glyph_row;
607 static struct glyph scratch_glyphs[MAX_SCRATCH_GLYPHS];
608
609 /* Ascent and height of the last line processed by move_it_to. */
610
611 static int last_max_ascent, last_height;
612
613 /* Non-zero if there's a help-echo in the echo area. */
614
615 int help_echo_showing_p;
616
617 /* If >= 0, computed, exact values of mode-line and header-line height
618 to use in the macros CURRENT_MODE_LINE_HEIGHT and
619 CURRENT_HEADER_LINE_HEIGHT. */
620
621 int current_mode_line_height, current_header_line_height;
622
623 /* The maximum distance to look ahead for text properties. Values
624 that are too small let us call compute_char_face and similar
625 functions too often which is expensive. Values that are too large
626 let us call compute_char_face and alike too often because we
627 might not be interested in text properties that far away. */
628
629 #define TEXT_PROP_DISTANCE_LIMIT 100
630
631 /* SAVE_IT and RESTORE_IT are called when we save a snapshot of the
632 iterator state and later restore it. This is needed because the
633 bidi iterator on bidi.c keeps a stacked cache of its states, which
634 is really a singleton. When we use scratch iterator objects to
635 move around the buffer, we can cause the bidi cache to be pushed or
636 popped, and therefore we need to restore the cache state when we
637 return to the original iterator. */
638 #define SAVE_IT(ITCOPY,ITORIG,CACHE) \
639 do { \
640 if (CACHE) \
641 bidi_unshelve_cache (CACHE, 1); \
642 ITCOPY = ITORIG; \
643 CACHE = bidi_shelve_cache (); \
644 } while (0)
645
646 #define RESTORE_IT(pITORIG,pITCOPY,CACHE) \
647 do { \
648 if (pITORIG != pITCOPY) \
649 *(pITORIG) = *(pITCOPY); \
650 bidi_unshelve_cache (CACHE, 0); \
651 CACHE = NULL; \
652 } while (0)
653
654 #ifdef GLYPH_DEBUG
655
656 /* Non-zero means print traces of redisplay if compiled with
657 GLYPH_DEBUG defined. */
658
659 int trace_redisplay_p;
660
661 #endif /* GLYPH_DEBUG */
662
663 #ifdef DEBUG_TRACE_MOVE
664 /* Non-zero means trace with TRACE_MOVE to stderr. */
665 int trace_move;
666
667 #define TRACE_MOVE(x) if (trace_move) fprintf x; else (void) 0
668 #else
669 #define TRACE_MOVE(x) (void) 0
670 #endif
671
672 static Lisp_Object Qauto_hscroll_mode;
673
674 /* Buffer being redisplayed -- for redisplay_window_error. */
675
676 static struct buffer *displayed_buffer;
677
678 /* Value returned from text property handlers (see below). */
679
680 enum prop_handled
681 {
682 HANDLED_NORMALLY,
683 HANDLED_RECOMPUTE_PROPS,
684 HANDLED_OVERLAY_STRING_CONSUMED,
685 HANDLED_RETURN
686 };
687
688 /* A description of text properties that redisplay is interested
689 in. */
690
691 struct props
692 {
693 /* The name of the property. */
694 Lisp_Object *name;
695
696 /* A unique index for the property. */
697 enum prop_idx idx;
698
699 /* A handler function called to set up iterator IT from the property
700 at IT's current position. Value is used to steer handle_stop. */
701 enum prop_handled (*handler) (struct it *it);
702 };
703
704 static enum prop_handled handle_face_prop (struct it *);
705 static enum prop_handled handle_invisible_prop (struct it *);
706 static enum prop_handled handle_display_prop (struct it *);
707 static enum prop_handled handle_composition_prop (struct it *);
708 static enum prop_handled handle_overlay_change (struct it *);
709 static enum prop_handled handle_fontified_prop (struct it *);
710
711 /* Properties handled by iterators. */
712
713 static struct props it_props[] =
714 {
715 {&Qfontified, FONTIFIED_PROP_IDX, handle_fontified_prop},
716 /* Handle `face' before `display' because some sub-properties of
717 `display' need to know the face. */
718 {&Qface, FACE_PROP_IDX, handle_face_prop},
719 {&Qdisplay, DISPLAY_PROP_IDX, handle_display_prop},
720 {&Qinvisible, INVISIBLE_PROP_IDX, handle_invisible_prop},
721 {&Qcomposition, COMPOSITION_PROP_IDX, handle_composition_prop},
722 {NULL, 0, NULL}
723 };
724
725 /* Value is the position described by X. If X is a marker, value is
726 the marker_position of X. Otherwise, value is X. */
727
728 #define COERCE_MARKER(X) (MARKERP ((X)) ? Fmarker_position (X) : (X))
729
730 /* Enumeration returned by some move_it_.* functions internally. */
731
732 enum move_it_result
733 {
734 /* Not used. Undefined value. */
735 MOVE_UNDEFINED,
736
737 /* Move ended at the requested buffer position or ZV. */
738 MOVE_POS_MATCH_OR_ZV,
739
740 /* Move ended at the requested X pixel position. */
741 MOVE_X_REACHED,
742
743 /* Move within a line ended at the end of a line that must be
744 continued. */
745 MOVE_LINE_CONTINUED,
746
747 /* Move within a line ended at the end of a line that would
748 be displayed truncated. */
749 MOVE_LINE_TRUNCATED,
750
751 /* Move within a line ended at a line end. */
752 MOVE_NEWLINE_OR_CR
753 };
754
755 /* This counter is used to clear the face cache every once in a while
756 in redisplay_internal. It is incremented for each redisplay.
757 Every CLEAR_FACE_CACHE_COUNT full redisplays, the face cache is
758 cleared. */
759
760 #define CLEAR_FACE_CACHE_COUNT 500
761 static int clear_face_cache_count;
762
763 /* Similarly for the image cache. */
764
765 #ifdef HAVE_WINDOW_SYSTEM
766 #define CLEAR_IMAGE_CACHE_COUNT 101
767 static int clear_image_cache_count;
768
769 /* Null glyph slice */
770 static struct glyph_slice null_glyph_slice = { 0, 0, 0, 0 };
771 #endif
772
773 /* True while redisplay_internal is in progress. */
774
775 bool redisplaying_p;
776
777 static Lisp_Object Qinhibit_free_realized_faces;
778 static Lisp_Object Qmode_line_default_help_echo;
779
780 /* If a string, XTread_socket generates an event to display that string.
781 (The display is done in read_char.) */
782
783 Lisp_Object help_echo_string;
784 Lisp_Object help_echo_window;
785 Lisp_Object help_echo_object;
786 ptrdiff_t help_echo_pos;
787
788 /* Temporary variable for XTread_socket. */
789
790 Lisp_Object previous_help_echo_string;
791
792 /* Platform-independent portion of hourglass implementation. */
793
794 /* Non-zero means an hourglass cursor is currently shown. */
795 int hourglass_shown_p;
796
797 /* If non-null, an asynchronous timer that, when it expires, displays
798 an hourglass cursor on all frames. */
799 struct atimer *hourglass_atimer;
800
801 /* Name of the face used to display glyphless characters. */
802 Lisp_Object Qglyphless_char;
803
804 /* Symbol for the purpose of Vglyphless_char_display. */
805 static Lisp_Object Qglyphless_char_display;
806
807 /* Method symbols for Vglyphless_char_display. */
808 static Lisp_Object Qhex_code, Qempty_box, Qthin_space, Qzero_width;
809
810 /* Default pixel width of `thin-space' display method. */
811 #define THIN_SPACE_WIDTH 1
812
813 /* Default number of seconds to wait before displaying an hourglass
814 cursor. */
815 #define DEFAULT_HOURGLASS_DELAY 1
816
817 \f
818 /* Function prototypes. */
819
820 static void setup_for_ellipsis (struct it *, int);
821 static void set_iterator_to_next (struct it *, int);
822 static void mark_window_display_accurate_1 (struct window *, int);
823 static int single_display_spec_string_p (Lisp_Object, Lisp_Object);
824 static int display_prop_string_p (Lisp_Object, Lisp_Object);
825 static int cursor_row_p (struct glyph_row *);
826 static int redisplay_mode_lines (Lisp_Object, int);
827 static char *decode_mode_spec_coding (Lisp_Object, char *, int);
828
829 static Lisp_Object get_it_property (struct it *it, Lisp_Object prop);
830
831 static void handle_line_prefix (struct it *);
832
833 static void pint2str (char *, int, ptrdiff_t);
834 static void pint2hrstr (char *, int, ptrdiff_t);
835 static struct text_pos run_window_scroll_functions (Lisp_Object,
836 struct text_pos);
837 static void reconsider_clip_changes (struct window *, struct buffer *);
838 static int text_outside_line_unchanged_p (struct window *,
839 ptrdiff_t, ptrdiff_t);
840 static void store_mode_line_noprop_char (char);
841 static int store_mode_line_noprop (const char *, int, int);
842 static void handle_stop (struct it *);
843 static void handle_stop_backwards (struct it *, ptrdiff_t);
844 static void vmessage (const char *, va_list) ATTRIBUTE_FORMAT_PRINTF (1, 0);
845 static void ensure_echo_area_buffers (void);
846 static Lisp_Object unwind_with_echo_area_buffer (Lisp_Object);
847 static Lisp_Object with_echo_area_buffer_unwind_data (struct window *);
848 static int with_echo_area_buffer (struct window *, int,
849 int (*) (ptrdiff_t, Lisp_Object, ptrdiff_t, ptrdiff_t),
850 ptrdiff_t, Lisp_Object, ptrdiff_t, ptrdiff_t);
851 static void clear_garbaged_frames (void);
852 static int current_message_1 (ptrdiff_t, Lisp_Object, ptrdiff_t, ptrdiff_t);
853 static void pop_message (void);
854 static int truncate_message_1 (ptrdiff_t, Lisp_Object, ptrdiff_t, ptrdiff_t);
855 static void set_message (const char *, Lisp_Object, ptrdiff_t, int);
856 static int set_message_1 (ptrdiff_t, Lisp_Object, ptrdiff_t, ptrdiff_t);
857 static int display_echo_area (struct window *);
858 static int display_echo_area_1 (ptrdiff_t, Lisp_Object, ptrdiff_t, ptrdiff_t);
859 static int resize_mini_window_1 (ptrdiff_t, Lisp_Object, ptrdiff_t, ptrdiff_t);
860 static Lisp_Object unwind_redisplay (Lisp_Object);
861 static int string_char_and_length (const unsigned char *, int *);
862 static struct text_pos display_prop_end (struct it *, Lisp_Object,
863 struct text_pos);
864 static int compute_window_start_on_continuation_line (struct window *);
865 static void insert_left_trunc_glyphs (struct it *);
866 static struct glyph_row *get_overlay_arrow_glyph_row (struct window *,
867 Lisp_Object);
868 static void extend_face_to_end_of_line (struct it *);
869 static int append_space_for_newline (struct it *, int);
870 static int cursor_row_fully_visible_p (struct window *, int, int);
871 static int try_scrolling (Lisp_Object, int, ptrdiff_t, ptrdiff_t, int, int);
872 static int try_cursor_movement (Lisp_Object, struct text_pos, int *);
873 static int trailing_whitespace_p (ptrdiff_t);
874 static intmax_t message_log_check_duplicate (ptrdiff_t, ptrdiff_t);
875 static void push_it (struct it *, struct text_pos *);
876 static void iterate_out_of_display_property (struct it *);
877 static void pop_it (struct it *);
878 static void sync_frame_with_window_matrix_rows (struct window *);
879 static void select_frame_for_redisplay (Lisp_Object);
880 static void redisplay_internal (void);
881 static int echo_area_display (int);
882 static void redisplay_windows (Lisp_Object);
883 static void redisplay_window (Lisp_Object, int);
884 static Lisp_Object redisplay_window_error (Lisp_Object);
885 static Lisp_Object redisplay_window_0 (Lisp_Object);
886 static Lisp_Object redisplay_window_1 (Lisp_Object);
887 static int set_cursor_from_row (struct window *, struct glyph_row *,
888 struct glyph_matrix *, ptrdiff_t, ptrdiff_t,
889 int, int);
890 static int update_menu_bar (struct frame *, int, int);
891 static int try_window_reusing_current_matrix (struct window *);
892 static int try_window_id (struct window *);
893 static int display_line (struct it *);
894 static int display_mode_lines (struct window *);
895 static int display_mode_line (struct window *, enum face_id, Lisp_Object);
896 static int display_mode_element (struct it *, int, int, int, Lisp_Object, Lisp_Object, int);
897 static int store_mode_line_string (const char *, Lisp_Object, int, int, int, Lisp_Object);
898 static const char *decode_mode_spec (struct window *, int, int, Lisp_Object *);
899 static void display_menu_bar (struct window *);
900 static ptrdiff_t display_count_lines (ptrdiff_t, ptrdiff_t, ptrdiff_t,
901 ptrdiff_t *);
902 static int display_string (const char *, Lisp_Object, Lisp_Object,
903 ptrdiff_t, ptrdiff_t, struct it *, int, int, int, int);
904 static void compute_line_metrics (struct it *);
905 static void run_redisplay_end_trigger_hook (struct it *);
906 static int get_overlay_strings (struct it *, ptrdiff_t);
907 static int get_overlay_strings_1 (struct it *, ptrdiff_t, int);
908 static void next_overlay_string (struct it *);
909 static void reseat (struct it *, struct text_pos, int);
910 static void reseat_1 (struct it *, struct text_pos, int);
911 static void back_to_previous_visible_line_start (struct it *);
912 void reseat_at_previous_visible_line_start (struct it *);
913 static void reseat_at_next_visible_line_start (struct it *, int);
914 static int next_element_from_ellipsis (struct it *);
915 static int next_element_from_display_vector (struct it *);
916 static int next_element_from_string (struct it *);
917 static int next_element_from_c_string (struct it *);
918 static int next_element_from_buffer (struct it *);
919 static int next_element_from_composition (struct it *);
920 static int next_element_from_image (struct it *);
921 #ifdef HAVE_XWIDGETS
922 static int next_element_from_xwidget(struct it *);
923 #endif
924 static int next_element_from_stretch (struct it *);
925 static void load_overlay_strings (struct it *, ptrdiff_t);
926 static int init_from_display_pos (struct it *, struct window *,
927 struct display_pos *);
928 static void reseat_to_string (struct it *, const char *,
929 Lisp_Object, ptrdiff_t, ptrdiff_t, int, int);
930 static int get_next_display_element (struct it *);
931 static enum move_it_result
932 move_it_in_display_line_to (struct it *, ptrdiff_t, int,
933 enum move_operation_enum);
934 void move_it_vertically_backward (struct it *, int);
935 static void init_to_row_start (struct it *, struct window *,
936 struct glyph_row *);
937 static int init_to_row_end (struct it *, struct window *,
938 struct glyph_row *);
939 static void back_to_previous_line_start (struct it *);
940 static int forward_to_next_line_start (struct it *, int *, struct bidi_it *);
941 static struct text_pos string_pos_nchars_ahead (struct text_pos,
942 Lisp_Object, ptrdiff_t);
943 static struct text_pos string_pos (ptrdiff_t, Lisp_Object);
944 static struct text_pos c_string_pos (ptrdiff_t, const char *, int);
945 static ptrdiff_t number_of_chars (const char *, int);
946 static void compute_stop_pos (struct it *);
947 static void compute_string_pos (struct text_pos *, struct text_pos,
948 Lisp_Object);
949 static int face_before_or_after_it_pos (struct it *, int);
950 static ptrdiff_t next_overlay_change (ptrdiff_t);
951 static int handle_display_spec (struct it *, Lisp_Object, Lisp_Object,
952 Lisp_Object, struct text_pos *, ptrdiff_t, int);
953 static int handle_single_display_spec (struct it *, Lisp_Object,
954 Lisp_Object, Lisp_Object,
955 struct text_pos *, ptrdiff_t, int, int);
956 static int underlying_face_id (struct it *);
957 static int in_ellipses_for_invisible_text_p (struct display_pos *,
958 struct window *);
959
960 #define face_before_it_pos(IT) face_before_or_after_it_pos ((IT), 1)
961 #define face_after_it_pos(IT) face_before_or_after_it_pos ((IT), 0)
962
963 #ifdef HAVE_WINDOW_SYSTEM
964
965 static void x_consider_frame_title (Lisp_Object);
966 static int tool_bar_lines_needed (struct frame *, int *);
967 static void update_tool_bar (struct frame *, int);
968 static void build_desired_tool_bar_string (struct frame *f);
969 static int redisplay_tool_bar (struct frame *);
970 static void display_tool_bar_line (struct it *, int);
971 static void notice_overwritten_cursor (struct window *,
972 enum glyph_row_area,
973 int, int, int, int);
974 static void append_stretch_glyph (struct it *, Lisp_Object,
975 int, int, int);
976
977
978 #endif /* HAVE_WINDOW_SYSTEM */
979
980 static void produce_special_glyphs (struct it *, enum display_element_type);
981 static void show_mouse_face (Mouse_HLInfo *, enum draw_glyphs_face);
982 static int coords_in_mouse_face_p (struct window *, int, int);
983
984
985 \f
986 /***********************************************************************
987 Window display dimensions
988 ***********************************************************************/
989
990 /* Return the bottom boundary y-position for text lines in window W.
991 This is the first y position at which a line cannot start.
992 It is relative to the top of the window.
993
994 This is the height of W minus the height of a mode line, if any. */
995
996 int
997 window_text_bottom_y (struct window *w)
998 {
999 int height = WINDOW_TOTAL_HEIGHT (w);
1000
1001 if (WINDOW_WANTS_MODELINE_P (w))
1002 height -= CURRENT_MODE_LINE_HEIGHT (w);
1003 return height;
1004 }
1005
1006 /* Return the pixel width of display area AREA of window W. AREA < 0
1007 means return the total width of W, not including fringes to
1008 the left and right of the window. */
1009
1010 int
1011 window_box_width (struct window *w, int area)
1012 {
1013 int cols = XFASTINT (w->total_cols);
1014 int pixels = 0;
1015
1016 if (!w->pseudo_window_p)
1017 {
1018 cols -= WINDOW_SCROLL_BAR_COLS (w);
1019
1020 if (area == TEXT_AREA)
1021 {
1022 if (INTEGERP (w->left_margin_cols))
1023 cols -= XFASTINT (w->left_margin_cols);
1024 if (INTEGERP (w->right_margin_cols))
1025 cols -= XFASTINT (w->right_margin_cols);
1026 pixels = -WINDOW_TOTAL_FRINGE_WIDTH (w);
1027 }
1028 else if (area == LEFT_MARGIN_AREA)
1029 {
1030 cols = (INTEGERP (w->left_margin_cols)
1031 ? XFASTINT (w->left_margin_cols) : 0);
1032 pixels = 0;
1033 }
1034 else if (area == RIGHT_MARGIN_AREA)
1035 {
1036 cols = (INTEGERP (w->right_margin_cols)
1037 ? XFASTINT (w->right_margin_cols) : 0);
1038 pixels = 0;
1039 }
1040 }
1041
1042 return cols * WINDOW_FRAME_COLUMN_WIDTH (w) + pixels;
1043 }
1044
1045
1046 /* Return the pixel height of the display area of window W, not
1047 including mode lines of W, if any. */
1048
1049 int
1050 window_box_height (struct window *w)
1051 {
1052 struct frame *f = XFRAME (w->frame);
1053 int height = WINDOW_TOTAL_HEIGHT (w);
1054
1055 eassert (height >= 0);
1056
1057 /* Note: the code below that determines the mode-line/header-line
1058 height is essentially the same as that contained in the macro
1059 CURRENT_{MODE,HEADER}_LINE_HEIGHT, except that it checks whether
1060 the appropriate glyph row has its `mode_line_p' flag set,
1061 and if it doesn't, uses estimate_mode_line_height instead. */
1062
1063 if (WINDOW_WANTS_MODELINE_P (w))
1064 {
1065 struct glyph_row *ml_row
1066 = (w->current_matrix && w->current_matrix->rows
1067 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
1068 : 0);
1069 if (ml_row && ml_row->mode_line_p)
1070 height -= ml_row->height;
1071 else
1072 height -= estimate_mode_line_height (f, CURRENT_MODE_LINE_FACE_ID (w));
1073 }
1074
1075 if (WINDOW_WANTS_HEADER_LINE_P (w))
1076 {
1077 struct glyph_row *hl_row
1078 = (w->current_matrix && w->current_matrix->rows
1079 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
1080 : 0);
1081 if (hl_row && hl_row->mode_line_p)
1082 height -= hl_row->height;
1083 else
1084 height -= estimate_mode_line_height (f, HEADER_LINE_FACE_ID);
1085 }
1086
1087 /* With a very small font and a mode-line that's taller than
1088 default, we might end up with a negative height. */
1089 return max (0, height);
1090 }
1091
1092 /* Return the window-relative coordinate of the left edge of display
1093 area AREA of window W. AREA < 0 means return the left edge of the
1094 whole window, to the right of the left fringe of W. */
1095
1096 int
1097 window_box_left_offset (struct window *w, int area)
1098 {
1099 int x;
1100
1101 if (w->pseudo_window_p)
1102 return 0;
1103
1104 x = WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
1105
1106 if (area == TEXT_AREA)
1107 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1108 + window_box_width (w, LEFT_MARGIN_AREA));
1109 else if (area == RIGHT_MARGIN_AREA)
1110 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1111 + window_box_width (w, LEFT_MARGIN_AREA)
1112 + window_box_width (w, TEXT_AREA)
1113 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
1114 ? 0
1115 : WINDOW_RIGHT_FRINGE_WIDTH (w)));
1116 else if (area == LEFT_MARGIN_AREA
1117 && WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w))
1118 x += WINDOW_LEFT_FRINGE_WIDTH (w);
1119
1120 return x;
1121 }
1122
1123
1124 /* Return the window-relative coordinate of the right edge of display
1125 area AREA of window W. AREA < 0 means return the right edge of the
1126 whole window, to the left of the right fringe of W. */
1127
1128 int
1129 window_box_right_offset (struct window *w, int area)
1130 {
1131 return window_box_left_offset (w, area) + window_box_width (w, area);
1132 }
1133
1134 /* Return the frame-relative coordinate of the left edge of display
1135 area AREA of window W. AREA < 0 means return the left edge of the
1136 whole window, to the right of the left fringe of W. */
1137
1138 int
1139 window_box_left (struct window *w, int area)
1140 {
1141 struct frame *f = XFRAME (w->frame);
1142 int x;
1143
1144 if (w->pseudo_window_p)
1145 return FRAME_INTERNAL_BORDER_WIDTH (f);
1146
1147 x = (WINDOW_LEFT_EDGE_X (w)
1148 + window_box_left_offset (w, area));
1149
1150 return x;
1151 }
1152
1153
1154 /* Return the frame-relative coordinate of the right edge of display
1155 area AREA of window W. AREA < 0 means return the right edge of the
1156 whole window, to the left of the right fringe of W. */
1157
1158 int
1159 window_box_right (struct window *w, int area)
1160 {
1161 return window_box_left (w, area) + window_box_width (w, area);
1162 }
1163
1164 /* Get the bounding box of the display area AREA of window W, without
1165 mode lines, in frame-relative coordinates. AREA < 0 means the
1166 whole window, not including the left and right fringes of
1167 the window. Return in *BOX_X and *BOX_Y the frame-relative pixel
1168 coordinates of the upper-left corner of the box. Return in
1169 *BOX_WIDTH, and *BOX_HEIGHT the pixel width and height of the box. */
1170
1171 void
1172 window_box (struct window *w, int area, int *box_x, int *box_y,
1173 int *box_width, int *box_height)
1174 {
1175 if (box_width)
1176 *box_width = window_box_width (w, area);
1177 if (box_height)
1178 *box_height = window_box_height (w);
1179 if (box_x)
1180 *box_x = window_box_left (w, area);
1181 if (box_y)
1182 {
1183 *box_y = WINDOW_TOP_EDGE_Y (w);
1184 if (WINDOW_WANTS_HEADER_LINE_P (w))
1185 *box_y += CURRENT_HEADER_LINE_HEIGHT (w);
1186 }
1187 }
1188
1189
1190 /* Get the bounding box of the display area AREA of window W, without
1191 mode lines. AREA < 0 means the whole window, not including the
1192 left and right fringe of the window. Return in *TOP_LEFT_X
1193 and TOP_LEFT_Y the frame-relative pixel coordinates of the
1194 upper-left corner of the box. Return in *BOTTOM_RIGHT_X, and
1195 *BOTTOM_RIGHT_Y the coordinates of the bottom-right corner of the
1196 box. */
1197
1198 static inline void
1199 window_box_edges (struct window *w, int area, int *top_left_x, int *top_left_y,
1200 int *bottom_right_x, int *bottom_right_y)
1201 {
1202 window_box (w, area, top_left_x, top_left_y, bottom_right_x,
1203 bottom_right_y);
1204 *bottom_right_x += *top_left_x;
1205 *bottom_right_y += *top_left_y;
1206 }
1207
1208
1209 \f
1210 /***********************************************************************
1211 Utilities
1212 ***********************************************************************/
1213
1214 /* Return the bottom y-position of the line the iterator IT is in.
1215 This can modify IT's settings. */
1216
1217 int
1218 line_bottom_y (struct it *it)
1219 {
1220 int line_height = it->max_ascent + it->max_descent;
1221 int line_top_y = it->current_y;
1222
1223 if (line_height == 0)
1224 {
1225 if (last_height)
1226 line_height = last_height;
1227 else if (IT_CHARPOS (*it) < ZV)
1228 {
1229 move_it_by_lines (it, 1);
1230 line_height = (it->max_ascent || it->max_descent
1231 ? it->max_ascent + it->max_descent
1232 : last_height);
1233 }
1234 else
1235 {
1236 struct glyph_row *row = it->glyph_row;
1237
1238 /* Use the default character height. */
1239 it->glyph_row = NULL;
1240 it->what = IT_CHARACTER;
1241 it->c = ' ';
1242 it->len = 1;
1243 PRODUCE_GLYPHS (it);
1244 line_height = it->ascent + it->descent;
1245 it->glyph_row = row;
1246 }
1247 }
1248
1249 return line_top_y + line_height;
1250 }
1251
1252 /* Subroutine of pos_visible_p below. Extracts a display string, if
1253 any, from the display spec given as its argument. */
1254 static Lisp_Object
1255 string_from_display_spec (Lisp_Object spec)
1256 {
1257 if (CONSP (spec))
1258 {
1259 while (CONSP (spec))
1260 {
1261 if (STRINGP (XCAR (spec)))
1262 return XCAR (spec);
1263 spec = XCDR (spec);
1264 }
1265 }
1266 else if (VECTORP (spec))
1267 {
1268 ptrdiff_t i;
1269
1270 for (i = 0; i < ASIZE (spec); i++)
1271 {
1272 if (STRINGP (AREF (spec, i)))
1273 return AREF (spec, i);
1274 }
1275 return Qnil;
1276 }
1277
1278 return spec;
1279 }
1280
1281
1282 /* Limit insanely large values of W->hscroll on frame F to the largest
1283 value that will still prevent first_visible_x and last_visible_x of
1284 'struct it' from overflowing an int. */
1285 static inline int
1286 window_hscroll_limited (struct window *w, struct frame *f)
1287 {
1288 ptrdiff_t window_hscroll = w->hscroll;
1289 int window_text_width = window_box_width (w, TEXT_AREA);
1290 int colwidth = FRAME_COLUMN_WIDTH (f);
1291
1292 if (window_hscroll > (INT_MAX - window_text_width) / colwidth - 1)
1293 window_hscroll = (INT_MAX - window_text_width) / colwidth - 1;
1294
1295 return window_hscroll;
1296 }
1297
1298 /* Return 1 if position CHARPOS is visible in window W.
1299 CHARPOS < 0 means return info about WINDOW_END position.
1300 If visible, set *X and *Y to pixel coordinates of top left corner.
1301 Set *RTOP and *RBOT to pixel height of an invisible area of glyph at POS.
1302 Set *ROWH and *VPOS to row's visible height and VPOS (row number). */
1303
1304 int
1305 pos_visible_p (struct window *w, ptrdiff_t charpos, int *x, int *y,
1306 int *rtop, int *rbot, int *rowh, int *vpos)
1307 {
1308 struct it it;
1309 void *itdata = bidi_shelve_cache ();
1310 struct text_pos top;
1311 int visible_p = 0;
1312 struct buffer *old_buffer = NULL;
1313
1314 if (FRAME_INITIAL_P (XFRAME (WINDOW_FRAME (w))))
1315 return visible_p;
1316
1317 if (XBUFFER (w->buffer) != current_buffer)
1318 {
1319 old_buffer = current_buffer;
1320 set_buffer_internal_1 (XBUFFER (w->buffer));
1321 }
1322
1323 SET_TEXT_POS_FROM_MARKER (top, w->start);
1324 /* Scrolling a minibuffer window via scroll bar when the echo area
1325 shows long text sometimes resets the minibuffer contents behind
1326 our backs. */
1327 if (CHARPOS (top) > ZV)
1328 SET_TEXT_POS (top, BEGV, BEGV_BYTE);
1329
1330 /* Compute exact mode line heights. */
1331 if (WINDOW_WANTS_MODELINE_P (w))
1332 current_mode_line_height
1333 = display_mode_line (w, CURRENT_MODE_LINE_FACE_ID (w),
1334 BVAR (current_buffer, mode_line_format));
1335
1336 if (WINDOW_WANTS_HEADER_LINE_P (w))
1337 current_header_line_height
1338 = display_mode_line (w, HEADER_LINE_FACE_ID,
1339 BVAR (current_buffer, header_line_format));
1340
1341 start_display (&it, w, top);
1342 move_it_to (&it, charpos, -1, it.last_visible_y-1, -1,
1343 (charpos >= 0 ? MOVE_TO_POS : 0) | MOVE_TO_Y);
1344
1345 if (charpos >= 0
1346 && (((!it.bidi_p || it.bidi_it.scan_dir == 1)
1347 && IT_CHARPOS (it) >= charpos)
1348 /* When scanning backwards under bidi iteration, move_it_to
1349 stops at or _before_ CHARPOS, because it stops at or to
1350 the _right_ of the character at CHARPOS. */
1351 || (it.bidi_p && it.bidi_it.scan_dir == -1
1352 && IT_CHARPOS (it) <= charpos)))
1353 {
1354 /* We have reached CHARPOS, or passed it. How the call to
1355 move_it_to can overshoot: (i) If CHARPOS is on invisible text
1356 or covered by a display property, move_it_to stops at the end
1357 of the invisible text, to the right of CHARPOS. (ii) If
1358 CHARPOS is in a display vector, move_it_to stops on its last
1359 glyph. */
1360 int top_x = it.current_x;
1361 int top_y = it.current_y;
1362 /* Calling line_bottom_y may change it.method, it.position, etc. */
1363 enum it_method it_method = it.method;
1364 int bottom_y = (last_height = 0, line_bottom_y (&it));
1365 int window_top_y = WINDOW_HEADER_LINE_HEIGHT (w);
1366
1367 if (top_y < window_top_y)
1368 visible_p = bottom_y > window_top_y;
1369 else if (top_y < it.last_visible_y)
1370 visible_p = 1;
1371 if (bottom_y >= it.last_visible_y
1372 && it.bidi_p && it.bidi_it.scan_dir == -1
1373 && IT_CHARPOS (it) < charpos)
1374 {
1375 /* When the last line of the window is scanned backwards
1376 under bidi iteration, we could be duped into thinking
1377 that we have passed CHARPOS, when in fact move_it_to
1378 simply stopped short of CHARPOS because it reached
1379 last_visible_y. To see if that's what happened, we call
1380 move_it_to again with a slightly larger vertical limit,
1381 and see if it actually moved vertically; if it did, we
1382 didn't really reach CHARPOS, which is beyond window end. */
1383 struct it save_it = it;
1384 /* Why 10? because we don't know how many canonical lines
1385 will the height of the next line(s) be. So we guess. */
1386 int ten_more_lines =
1387 10 * FRAME_LINE_HEIGHT (XFRAME (WINDOW_FRAME (w)));
1388
1389 move_it_to (&it, charpos, -1, bottom_y + ten_more_lines, -1,
1390 MOVE_TO_POS | MOVE_TO_Y);
1391 if (it.current_y > top_y)
1392 visible_p = 0;
1393
1394 it = save_it;
1395 }
1396 if (visible_p)
1397 {
1398 if (it_method == GET_FROM_DISPLAY_VECTOR)
1399 {
1400 /* We stopped on the last glyph of a display vector.
1401 Try and recompute. Hack alert! */
1402 if (charpos < 2 || top.charpos >= charpos)
1403 top_x = it.glyph_row->x;
1404 else
1405 {
1406 struct it it2;
1407 start_display (&it2, w, top);
1408 move_it_to (&it2, charpos - 1, -1, -1, -1, MOVE_TO_POS);
1409 get_next_display_element (&it2);
1410 PRODUCE_GLYPHS (&it2);
1411 if (ITERATOR_AT_END_OF_LINE_P (&it2)
1412 || it2.current_x > it2.last_visible_x)
1413 top_x = it.glyph_row->x;
1414 else
1415 {
1416 top_x = it2.current_x;
1417 top_y = it2.current_y;
1418 }
1419 }
1420 }
1421 else if (IT_CHARPOS (it) != charpos)
1422 {
1423 Lisp_Object cpos = make_number (charpos);
1424 Lisp_Object spec = Fget_char_property (cpos, Qdisplay, Qnil);
1425 Lisp_Object string = string_from_display_spec (spec);
1426 int newline_in_string = 0;
1427
1428 if (STRINGP (string))
1429 {
1430 const char *s = SSDATA (string);
1431 const char *e = s + SBYTES (string);
1432 while (s < e)
1433 {
1434 if (*s++ == '\n')
1435 {
1436 newline_in_string = 1;
1437 break;
1438 }
1439 }
1440 }
1441 /* The tricky code below is needed because there's a
1442 discrepancy between move_it_to and how we set cursor
1443 when the display line ends in a newline from a
1444 display string. move_it_to will stop _after_ such
1445 display strings, whereas set_cursor_from_row
1446 conspires with cursor_row_p to place the cursor on
1447 the first glyph produced from the display string. */
1448
1449 /* We have overshoot PT because it is covered by a
1450 display property whose value is a string. If the
1451 string includes embedded newlines, we are also in the
1452 wrong display line. Backtrack to the correct line,
1453 where the display string begins. */
1454 if (newline_in_string)
1455 {
1456 Lisp_Object startpos, endpos;
1457 EMACS_INT start, end;
1458 struct it it3;
1459 int it3_moved;
1460
1461 /* Find the first and the last buffer positions
1462 covered by the display string. */
1463 endpos =
1464 Fnext_single_char_property_change (cpos, Qdisplay,
1465 Qnil, Qnil);
1466 startpos =
1467 Fprevious_single_char_property_change (endpos, Qdisplay,
1468 Qnil, Qnil);
1469 start = XFASTINT (startpos);
1470 end = XFASTINT (endpos);
1471 /* Move to the last buffer position before the
1472 display property. */
1473 start_display (&it3, w, top);
1474 move_it_to (&it3, start - 1, -1, -1, -1, MOVE_TO_POS);
1475 /* Move forward one more line if the position before
1476 the display string is a newline or if it is the
1477 rightmost character on a line that is
1478 continued or word-wrapped. */
1479 if (it3.method == GET_FROM_BUFFER
1480 && it3.c == '\n')
1481 move_it_by_lines (&it3, 1);
1482 else if (move_it_in_display_line_to (&it3, -1,
1483 it3.current_x
1484 + it3.pixel_width,
1485 MOVE_TO_X)
1486 == MOVE_LINE_CONTINUED)
1487 {
1488 move_it_by_lines (&it3, 1);
1489 /* When we are under word-wrap, the #$@%!
1490 move_it_by_lines moves 2 lines, so we need to
1491 fix that up. */
1492 if (it3.line_wrap == WORD_WRAP)
1493 move_it_by_lines (&it3, -1);
1494 }
1495
1496 /* Record the vertical coordinate of the display
1497 line where we wound up. */
1498 top_y = it3.current_y;
1499 if (it3.bidi_p)
1500 {
1501 /* When characters are reordered for display,
1502 the character displayed to the left of the
1503 display string could be _after_ the display
1504 property in the logical order. Use the
1505 smallest vertical position of these two. */
1506 start_display (&it3, w, top);
1507 move_it_to (&it3, end + 1, -1, -1, -1, MOVE_TO_POS);
1508 if (it3.current_y < top_y)
1509 top_y = it3.current_y;
1510 }
1511 /* Move from the top of the window to the beginning
1512 of the display line where the display string
1513 begins. */
1514 start_display (&it3, w, top);
1515 move_it_to (&it3, -1, 0, top_y, -1, MOVE_TO_X | MOVE_TO_Y);
1516 /* If it3_moved stays zero after the 'while' loop
1517 below, that means we already were at a newline
1518 before the loop (e.g., the display string begins
1519 with a newline), so we don't need to (and cannot)
1520 inspect the glyphs of it3.glyph_row, because
1521 PRODUCE_GLYPHS will not produce anything for a
1522 newline, and thus it3.glyph_row stays at its
1523 stale content it got at top of the window. */
1524 it3_moved = 0;
1525 /* Finally, advance the iterator until we hit the
1526 first display element whose character position is
1527 CHARPOS, or until the first newline from the
1528 display string, which signals the end of the
1529 display line. */
1530 while (get_next_display_element (&it3))
1531 {
1532 PRODUCE_GLYPHS (&it3);
1533 if (IT_CHARPOS (it3) == charpos
1534 || ITERATOR_AT_END_OF_LINE_P (&it3))
1535 break;
1536 it3_moved = 1;
1537 set_iterator_to_next (&it3, 0);
1538 }
1539 top_x = it3.current_x - it3.pixel_width;
1540 /* Normally, we would exit the above loop because we
1541 found the display element whose character
1542 position is CHARPOS. For the contingency that we
1543 didn't, and stopped at the first newline from the
1544 display string, move back over the glyphs
1545 produced from the string, until we find the
1546 rightmost glyph not from the string. */
1547 if (it3_moved
1548 && IT_CHARPOS (it3) != charpos && EQ (it3.object, string))
1549 {
1550 struct glyph *g = it3.glyph_row->glyphs[TEXT_AREA]
1551 + it3.glyph_row->used[TEXT_AREA];
1552
1553 while (EQ ((g - 1)->object, string))
1554 {
1555 --g;
1556 top_x -= g->pixel_width;
1557 }
1558 eassert (g < it3.glyph_row->glyphs[TEXT_AREA]
1559 + it3.glyph_row->used[TEXT_AREA]);
1560 }
1561 }
1562 }
1563
1564 *x = top_x;
1565 *y = max (top_y + max (0, it.max_ascent - it.ascent), window_top_y);
1566 *rtop = max (0, window_top_y - top_y);
1567 *rbot = max (0, bottom_y - it.last_visible_y);
1568 *rowh = max (0, (min (bottom_y, it.last_visible_y)
1569 - max (top_y, window_top_y)));
1570 *vpos = it.vpos;
1571 }
1572 }
1573 else
1574 {
1575 /* We were asked to provide info about WINDOW_END. */
1576 struct it it2;
1577 void *it2data = NULL;
1578
1579 SAVE_IT (it2, it, it2data);
1580 if (IT_CHARPOS (it) < ZV && FETCH_BYTE (IT_BYTEPOS (it)) != '\n')
1581 move_it_by_lines (&it, 1);
1582 if (charpos < IT_CHARPOS (it)
1583 || (it.what == IT_EOB && charpos == IT_CHARPOS (it)))
1584 {
1585 visible_p = 1;
1586 RESTORE_IT (&it2, &it2, it2data);
1587 move_it_to (&it2, charpos, -1, -1, -1, MOVE_TO_POS);
1588 *x = it2.current_x;
1589 *y = it2.current_y + it2.max_ascent - it2.ascent;
1590 *rtop = max (0, -it2.current_y);
1591 *rbot = max (0, ((it2.current_y + it2.max_ascent + it2.max_descent)
1592 - it.last_visible_y));
1593 *rowh = max (0, (min (it2.current_y + it2.max_ascent + it2.max_descent,
1594 it.last_visible_y)
1595 - max (it2.current_y,
1596 WINDOW_HEADER_LINE_HEIGHT (w))));
1597 *vpos = it2.vpos;
1598 }
1599 else
1600 bidi_unshelve_cache (it2data, 1);
1601 }
1602 bidi_unshelve_cache (itdata, 0);
1603
1604 if (old_buffer)
1605 set_buffer_internal_1 (old_buffer);
1606
1607 current_header_line_height = current_mode_line_height = -1;
1608
1609 if (visible_p && w->hscroll > 0)
1610 *x -=
1611 window_hscroll_limited (w, WINDOW_XFRAME (w))
1612 * WINDOW_FRAME_COLUMN_WIDTH (w);
1613
1614 #if 0
1615 /* Debugging code. */
1616 if (visible_p)
1617 fprintf (stderr, "+pv pt=%d vs=%d --> x=%d y=%d rt=%d rb=%d rh=%d vp=%d\n",
1618 charpos, w->vscroll, *x, *y, *rtop, *rbot, *rowh, *vpos);
1619 else
1620 fprintf (stderr, "-pv pt=%d vs=%d\n", charpos, w->vscroll);
1621 #endif
1622
1623 return visible_p;
1624 }
1625
1626
1627 /* Return the next character from STR. Return in *LEN the length of
1628 the character. This is like STRING_CHAR_AND_LENGTH but never
1629 returns an invalid character. If we find one, we return a `?', but
1630 with the length of the invalid character. */
1631
1632 static inline int
1633 string_char_and_length (const unsigned char *str, int *len)
1634 {
1635 int c;
1636
1637 c = STRING_CHAR_AND_LENGTH (str, *len);
1638 if (!CHAR_VALID_P (c))
1639 /* We may not change the length here because other places in Emacs
1640 don't use this function, i.e. they silently accept invalid
1641 characters. */
1642 c = '?';
1643
1644 return c;
1645 }
1646
1647
1648
1649 /* Given a position POS containing a valid character and byte position
1650 in STRING, return the position NCHARS ahead (NCHARS >= 0). */
1651
1652 static struct text_pos
1653 string_pos_nchars_ahead (struct text_pos pos, Lisp_Object string, ptrdiff_t nchars)
1654 {
1655 eassert (STRINGP (string) && nchars >= 0);
1656
1657 if (STRING_MULTIBYTE (string))
1658 {
1659 const unsigned char *p = SDATA (string) + BYTEPOS (pos);
1660 int len;
1661
1662 while (nchars--)
1663 {
1664 string_char_and_length (p, &len);
1665 p += len;
1666 CHARPOS (pos) += 1;
1667 BYTEPOS (pos) += len;
1668 }
1669 }
1670 else
1671 SET_TEXT_POS (pos, CHARPOS (pos) + nchars, BYTEPOS (pos) + nchars);
1672
1673 return pos;
1674 }
1675
1676
1677 /* Value is the text position, i.e. character and byte position,
1678 for character position CHARPOS in STRING. */
1679
1680 static inline struct text_pos
1681 string_pos (ptrdiff_t charpos, Lisp_Object string)
1682 {
1683 struct text_pos pos;
1684 eassert (STRINGP (string));
1685 eassert (charpos >= 0);
1686 SET_TEXT_POS (pos, charpos, string_char_to_byte (string, charpos));
1687 return pos;
1688 }
1689
1690
1691 /* Value is a text position, i.e. character and byte position, for
1692 character position CHARPOS in C string S. MULTIBYTE_P non-zero
1693 means recognize multibyte characters. */
1694
1695 static struct text_pos
1696 c_string_pos (ptrdiff_t charpos, const char *s, int multibyte_p)
1697 {
1698 struct text_pos pos;
1699
1700 eassert (s != NULL);
1701 eassert (charpos >= 0);
1702
1703 if (multibyte_p)
1704 {
1705 int len;
1706
1707 SET_TEXT_POS (pos, 0, 0);
1708 while (charpos--)
1709 {
1710 string_char_and_length ((const unsigned char *) s, &len);
1711 s += len;
1712 CHARPOS (pos) += 1;
1713 BYTEPOS (pos) += len;
1714 }
1715 }
1716 else
1717 SET_TEXT_POS (pos, charpos, charpos);
1718
1719 return pos;
1720 }
1721
1722
1723 /* Value is the number of characters in C string S. MULTIBYTE_P
1724 non-zero means recognize multibyte characters. */
1725
1726 static ptrdiff_t
1727 number_of_chars (const char *s, int multibyte_p)
1728 {
1729 ptrdiff_t nchars;
1730
1731 if (multibyte_p)
1732 {
1733 ptrdiff_t rest = strlen (s);
1734 int len;
1735 const unsigned char *p = (const unsigned char *) s;
1736
1737 for (nchars = 0; rest > 0; ++nchars)
1738 {
1739 string_char_and_length (p, &len);
1740 rest -= len, p += len;
1741 }
1742 }
1743 else
1744 nchars = strlen (s);
1745
1746 return nchars;
1747 }
1748
1749
1750 /* Compute byte position NEWPOS->bytepos corresponding to
1751 NEWPOS->charpos. POS is a known position in string STRING.
1752 NEWPOS->charpos must be >= POS.charpos. */
1753
1754 static void
1755 compute_string_pos (struct text_pos *newpos, struct text_pos pos, Lisp_Object string)
1756 {
1757 eassert (STRINGP (string));
1758 eassert (CHARPOS (*newpos) >= CHARPOS (pos));
1759
1760 if (STRING_MULTIBYTE (string))
1761 *newpos = string_pos_nchars_ahead (pos, string,
1762 CHARPOS (*newpos) - CHARPOS (pos));
1763 else
1764 BYTEPOS (*newpos) = CHARPOS (*newpos);
1765 }
1766
1767 /* EXPORT:
1768 Return an estimation of the pixel height of mode or header lines on
1769 frame F. FACE_ID specifies what line's height to estimate. */
1770
1771 int
1772 estimate_mode_line_height (struct frame *f, enum face_id face_id)
1773 {
1774 #ifdef HAVE_WINDOW_SYSTEM
1775 if (FRAME_WINDOW_P (f))
1776 {
1777 int height = FONT_HEIGHT (FRAME_FONT (f));
1778
1779 /* This function is called so early when Emacs starts that the face
1780 cache and mode line face are not yet initialized. */
1781 if (FRAME_FACE_CACHE (f))
1782 {
1783 struct face *face = FACE_FROM_ID (f, face_id);
1784 if (face)
1785 {
1786 if (face->font)
1787 height = FONT_HEIGHT (face->font);
1788 if (face->box_line_width > 0)
1789 height += 2 * face->box_line_width;
1790 }
1791 }
1792
1793 return height;
1794 }
1795 #endif
1796
1797 return 1;
1798 }
1799
1800 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
1801 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
1802 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
1803 not force the value into range. */
1804
1805 void
1806 pixel_to_glyph_coords (FRAME_PTR f, register int pix_x, register int pix_y,
1807 int *x, int *y, NativeRectangle *bounds, int noclip)
1808 {
1809
1810 #ifdef HAVE_WINDOW_SYSTEM
1811 if (FRAME_WINDOW_P (f))
1812 {
1813 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to round down
1814 even for negative values. */
1815 if (pix_x < 0)
1816 pix_x -= FRAME_COLUMN_WIDTH (f) - 1;
1817 if (pix_y < 0)
1818 pix_y -= FRAME_LINE_HEIGHT (f) - 1;
1819
1820 pix_x = FRAME_PIXEL_X_TO_COL (f, pix_x);
1821 pix_y = FRAME_PIXEL_Y_TO_LINE (f, pix_y);
1822
1823 if (bounds)
1824 STORE_NATIVE_RECT (*bounds,
1825 FRAME_COL_TO_PIXEL_X (f, pix_x),
1826 FRAME_LINE_TO_PIXEL_Y (f, pix_y),
1827 FRAME_COLUMN_WIDTH (f) - 1,
1828 FRAME_LINE_HEIGHT (f) - 1);
1829
1830 if (!noclip)
1831 {
1832 if (pix_x < 0)
1833 pix_x = 0;
1834 else if (pix_x > FRAME_TOTAL_COLS (f))
1835 pix_x = FRAME_TOTAL_COLS (f);
1836
1837 if (pix_y < 0)
1838 pix_y = 0;
1839 else if (pix_y > FRAME_LINES (f))
1840 pix_y = FRAME_LINES (f);
1841 }
1842 }
1843 #endif
1844
1845 *x = pix_x;
1846 *y = pix_y;
1847 }
1848
1849
1850 /* Find the glyph under window-relative coordinates X/Y in window W.
1851 Consider only glyphs from buffer text, i.e. no glyphs from overlay
1852 strings. Return in *HPOS and *VPOS the row and column number of
1853 the glyph found. Return in *AREA the glyph area containing X.
1854 Value is a pointer to the glyph found or null if X/Y is not on
1855 text, or we can't tell because W's current matrix is not up to
1856 date. */
1857
1858 static
1859 struct glyph *
1860 x_y_to_hpos_vpos (struct window *w, int x, int y, int *hpos, int *vpos,
1861 int *dx, int *dy, int *area)
1862 {
1863 struct glyph *glyph, *end;
1864 struct glyph_row *row = NULL;
1865 int x0, i;
1866
1867 /* Find row containing Y. Give up if some row is not enabled. */
1868 for (i = 0; i < w->current_matrix->nrows; ++i)
1869 {
1870 row = MATRIX_ROW (w->current_matrix, i);
1871 if (!row->enabled_p)
1872 return NULL;
1873 if (y >= row->y && y < MATRIX_ROW_BOTTOM_Y (row))
1874 break;
1875 }
1876
1877 *vpos = i;
1878 *hpos = 0;
1879
1880 /* Give up if Y is not in the window. */
1881 if (i == w->current_matrix->nrows)
1882 return NULL;
1883
1884 /* Get the glyph area containing X. */
1885 if (w->pseudo_window_p)
1886 {
1887 *area = TEXT_AREA;
1888 x0 = 0;
1889 }
1890 else
1891 {
1892 if (x < window_box_left_offset (w, TEXT_AREA))
1893 {
1894 *area = LEFT_MARGIN_AREA;
1895 x0 = window_box_left_offset (w, LEFT_MARGIN_AREA);
1896 }
1897 else if (x < window_box_right_offset (w, TEXT_AREA))
1898 {
1899 *area = TEXT_AREA;
1900 x0 = window_box_left_offset (w, TEXT_AREA) + min (row->x, 0);
1901 }
1902 else
1903 {
1904 *area = RIGHT_MARGIN_AREA;
1905 x0 = window_box_left_offset (w, RIGHT_MARGIN_AREA);
1906 }
1907 }
1908
1909 /* Find glyph containing X. */
1910 glyph = row->glyphs[*area];
1911 end = glyph + row->used[*area];
1912 x -= x0;
1913 while (glyph < end && x >= glyph->pixel_width)
1914 {
1915 x -= glyph->pixel_width;
1916 ++glyph;
1917 }
1918
1919 if (glyph == end)
1920 return NULL;
1921
1922 if (dx)
1923 {
1924 *dx = x;
1925 *dy = y - (row->y + row->ascent - glyph->ascent);
1926 }
1927
1928 *hpos = glyph - row->glyphs[*area];
1929 return glyph;
1930 }
1931
1932 /* Convert frame-relative x/y to coordinates relative to window W.
1933 Takes pseudo-windows into account. */
1934
1935 static void
1936 frame_to_window_pixel_xy (struct window *w, int *x, int *y)
1937 {
1938 if (w->pseudo_window_p)
1939 {
1940 /* A pseudo-window is always full-width, and starts at the
1941 left edge of the frame, plus a frame border. */
1942 struct frame *f = XFRAME (w->frame);
1943 *x -= FRAME_INTERNAL_BORDER_WIDTH (f);
1944 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1945 }
1946 else
1947 {
1948 *x -= WINDOW_LEFT_EDGE_X (w);
1949 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1950 }
1951 }
1952
1953 #ifdef HAVE_WINDOW_SYSTEM
1954
1955 /* EXPORT:
1956 Return in RECTS[] at most N clipping rectangles for glyph string S.
1957 Return the number of stored rectangles. */
1958
1959 int
1960 get_glyph_string_clip_rects (struct glyph_string *s, NativeRectangle *rects, int n)
1961 {
1962 XRectangle r;
1963
1964 if (n <= 0)
1965 return 0;
1966
1967 if (s->row->full_width_p)
1968 {
1969 /* Draw full-width. X coordinates are relative to S->w->left_col. */
1970 r.x = WINDOW_LEFT_EDGE_X (s->w);
1971 r.width = WINDOW_TOTAL_WIDTH (s->w);
1972
1973 /* Unless displaying a mode or menu bar line, which are always
1974 fully visible, clip to the visible part of the row. */
1975 if (s->w->pseudo_window_p)
1976 r.height = s->row->visible_height;
1977 else
1978 r.height = s->height;
1979 }
1980 else
1981 {
1982 /* This is a text line that may be partially visible. */
1983 r.x = window_box_left (s->w, s->area);
1984 r.width = window_box_width (s->w, s->area);
1985 r.height = s->row->visible_height;
1986 }
1987
1988 if (s->clip_head)
1989 if (r.x < s->clip_head->x)
1990 {
1991 if (r.width >= s->clip_head->x - r.x)
1992 r.width -= s->clip_head->x - r.x;
1993 else
1994 r.width = 0;
1995 r.x = s->clip_head->x;
1996 }
1997 if (s->clip_tail)
1998 if (r.x + r.width > s->clip_tail->x + s->clip_tail->background_width)
1999 {
2000 if (s->clip_tail->x + s->clip_tail->background_width >= r.x)
2001 r.width = s->clip_tail->x + s->clip_tail->background_width - r.x;
2002 else
2003 r.width = 0;
2004 }
2005
2006 /* If S draws overlapping rows, it's sufficient to use the top and
2007 bottom of the window for clipping because this glyph string
2008 intentionally draws over other lines. */
2009 if (s->for_overlaps)
2010 {
2011 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
2012 r.height = window_text_bottom_y (s->w) - r.y;
2013
2014 /* Alas, the above simple strategy does not work for the
2015 environments with anti-aliased text: if the same text is
2016 drawn onto the same place multiple times, it gets thicker.
2017 If the overlap we are processing is for the erased cursor, we
2018 take the intersection with the rectangle of the cursor. */
2019 if (s->for_overlaps & OVERLAPS_ERASED_CURSOR)
2020 {
2021 XRectangle rc, r_save = r;
2022
2023 rc.x = WINDOW_TEXT_TO_FRAME_PIXEL_X (s->w, s->w->phys_cursor.x);
2024 rc.y = s->w->phys_cursor.y;
2025 rc.width = s->w->phys_cursor_width;
2026 rc.height = s->w->phys_cursor_height;
2027
2028 x_intersect_rectangles (&r_save, &rc, &r);
2029 }
2030 }
2031 else
2032 {
2033 /* Don't use S->y for clipping because it doesn't take partially
2034 visible lines into account. For example, it can be negative for
2035 partially visible lines at the top of a window. */
2036 if (!s->row->full_width_p
2037 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s->w, s->row))
2038 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
2039 else
2040 r.y = max (0, s->row->y);
2041 }
2042
2043 r.y = WINDOW_TO_FRAME_PIXEL_Y (s->w, r.y);
2044
2045 /* If drawing the cursor, don't let glyph draw outside its
2046 advertised boundaries. Cleartype does this under some circumstances. */
2047 if (s->hl == DRAW_CURSOR)
2048 {
2049 struct glyph *glyph = s->first_glyph;
2050 int height, max_y;
2051
2052 if (s->x > r.x)
2053 {
2054 r.width -= s->x - r.x;
2055 r.x = s->x;
2056 }
2057 r.width = min (r.width, glyph->pixel_width);
2058
2059 /* If r.y is below window bottom, ensure that we still see a cursor. */
2060 height = min (glyph->ascent + glyph->descent,
2061 min (FRAME_LINE_HEIGHT (s->f), s->row->visible_height));
2062 max_y = window_text_bottom_y (s->w) - height;
2063 max_y = WINDOW_TO_FRAME_PIXEL_Y (s->w, max_y);
2064 if (s->ybase - glyph->ascent > max_y)
2065 {
2066 r.y = max_y;
2067 r.height = height;
2068 }
2069 else
2070 {
2071 /* Don't draw cursor glyph taller than our actual glyph. */
2072 height = max (FRAME_LINE_HEIGHT (s->f), glyph->ascent + glyph->descent);
2073 if (height < r.height)
2074 {
2075 max_y = r.y + r.height;
2076 r.y = min (max_y, max (r.y, s->ybase + glyph->descent - height));
2077 r.height = min (max_y - r.y, height);
2078 }
2079 }
2080 }
2081
2082 if (s->row->clip)
2083 {
2084 XRectangle r_save = r;
2085
2086 if (! x_intersect_rectangles (&r_save, s->row->clip, &r))
2087 r.width = 0;
2088 }
2089
2090 if ((s->for_overlaps & OVERLAPS_BOTH) == 0
2091 || ((s->for_overlaps & OVERLAPS_BOTH) == OVERLAPS_BOTH && n == 1))
2092 {
2093 #ifdef CONVERT_FROM_XRECT
2094 CONVERT_FROM_XRECT (r, *rects);
2095 #else
2096 *rects = r;
2097 #endif
2098 return 1;
2099 }
2100 else
2101 {
2102 /* If we are processing overlapping and allowed to return
2103 multiple clipping rectangles, we exclude the row of the glyph
2104 string from the clipping rectangle. This is to avoid drawing
2105 the same text on the environment with anti-aliasing. */
2106 #ifdef CONVERT_FROM_XRECT
2107 XRectangle rs[2];
2108 #else
2109 XRectangle *rs = rects;
2110 #endif
2111 int i = 0, row_y = WINDOW_TO_FRAME_PIXEL_Y (s->w, s->row->y);
2112
2113 if (s->for_overlaps & OVERLAPS_PRED)
2114 {
2115 rs[i] = r;
2116 if (r.y + r.height > row_y)
2117 {
2118 if (r.y < row_y)
2119 rs[i].height = row_y - r.y;
2120 else
2121 rs[i].height = 0;
2122 }
2123 i++;
2124 }
2125 if (s->for_overlaps & OVERLAPS_SUCC)
2126 {
2127 rs[i] = r;
2128 if (r.y < row_y + s->row->visible_height)
2129 {
2130 if (r.y + r.height > row_y + s->row->visible_height)
2131 {
2132 rs[i].y = row_y + s->row->visible_height;
2133 rs[i].height = r.y + r.height - rs[i].y;
2134 }
2135 else
2136 rs[i].height = 0;
2137 }
2138 i++;
2139 }
2140
2141 n = i;
2142 #ifdef CONVERT_FROM_XRECT
2143 for (i = 0; i < n; i++)
2144 CONVERT_FROM_XRECT (rs[i], rects[i]);
2145 #endif
2146 return n;
2147 }
2148 }
2149
2150 /* EXPORT:
2151 Return in *NR the clipping rectangle for glyph string S. */
2152
2153 void
2154 get_glyph_string_clip_rect (struct glyph_string *s, NativeRectangle *nr)
2155 {
2156 get_glyph_string_clip_rects (s, nr, 1);
2157 }
2158
2159
2160 /* EXPORT:
2161 Return the position and height of the phys cursor in window W.
2162 Set w->phys_cursor_width to width of phys cursor.
2163 */
2164
2165 void
2166 get_phys_cursor_geometry (struct window *w, struct glyph_row *row,
2167 struct glyph *glyph, int *xp, int *yp, int *heightp)
2168 {
2169 struct frame *f = XFRAME (WINDOW_FRAME (w));
2170 int x, y, wd, h, h0, y0;
2171
2172 /* Compute the width of the rectangle to draw. If on a stretch
2173 glyph, and `x-stretch-block-cursor' is nil, don't draw a
2174 rectangle as wide as the glyph, but use a canonical character
2175 width instead. */
2176 wd = glyph->pixel_width - 1;
2177 #if defined (HAVE_NTGUI) || defined (HAVE_NS)
2178 wd++; /* Why? */
2179 #endif
2180
2181 x = w->phys_cursor.x;
2182 if (x < 0)
2183 {
2184 wd += x;
2185 x = 0;
2186 }
2187
2188 if (glyph->type == STRETCH_GLYPH
2189 && !x_stretch_cursor_p)
2190 wd = min (FRAME_COLUMN_WIDTH (f), wd);
2191 w->phys_cursor_width = wd;
2192
2193 y = w->phys_cursor.y + row->ascent - glyph->ascent;
2194
2195 /* If y is below window bottom, ensure that we still see a cursor. */
2196 h0 = min (FRAME_LINE_HEIGHT (f), row->visible_height);
2197
2198 h = max (h0, glyph->ascent + glyph->descent);
2199 h0 = min (h0, glyph->ascent + glyph->descent);
2200
2201 y0 = WINDOW_HEADER_LINE_HEIGHT (w);
2202 if (y < y0)
2203 {
2204 h = max (h - (y0 - y) + 1, h0);
2205 y = y0 - 1;
2206 }
2207 else
2208 {
2209 y0 = window_text_bottom_y (w) - h0;
2210 if (y > y0)
2211 {
2212 h += y - y0;
2213 y = y0;
2214 }
2215 }
2216
2217 *xp = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, x);
2218 *yp = WINDOW_TO_FRAME_PIXEL_Y (w, y);
2219 *heightp = h;
2220 }
2221
2222 /*
2223 * Remember which glyph the mouse is over.
2224 */
2225
2226 void
2227 remember_mouse_glyph (struct frame *f, int gx, int gy, NativeRectangle *rect)
2228 {
2229 Lisp_Object window;
2230 struct window *w;
2231 struct glyph_row *r, *gr, *end_row;
2232 enum window_part part;
2233 enum glyph_row_area area;
2234 int x, y, width, height;
2235
2236 /* Try to determine frame pixel position and size of the glyph under
2237 frame pixel coordinates X/Y on frame F. */
2238
2239 if (!f->glyphs_initialized_p
2240 || (window = window_from_coordinates (f, gx, gy, &part, 0),
2241 NILP (window)))
2242 {
2243 width = FRAME_SMALLEST_CHAR_WIDTH (f);
2244 height = FRAME_SMALLEST_FONT_HEIGHT (f);
2245 goto virtual_glyph;
2246 }
2247
2248 w = XWINDOW (window);
2249 width = WINDOW_FRAME_COLUMN_WIDTH (w);
2250 height = WINDOW_FRAME_LINE_HEIGHT (w);
2251
2252 x = window_relative_x_coord (w, part, gx);
2253 y = gy - WINDOW_TOP_EDGE_Y (w);
2254
2255 r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
2256 end_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
2257
2258 if (w->pseudo_window_p)
2259 {
2260 area = TEXT_AREA;
2261 part = ON_MODE_LINE; /* Don't adjust margin. */
2262 goto text_glyph;
2263 }
2264
2265 switch (part)
2266 {
2267 case ON_LEFT_MARGIN:
2268 area = LEFT_MARGIN_AREA;
2269 goto text_glyph;
2270
2271 case ON_RIGHT_MARGIN:
2272 area = RIGHT_MARGIN_AREA;
2273 goto text_glyph;
2274
2275 case ON_HEADER_LINE:
2276 case ON_MODE_LINE:
2277 gr = (part == ON_HEADER_LINE
2278 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
2279 : MATRIX_MODE_LINE_ROW (w->current_matrix));
2280 gy = gr->y;
2281 area = TEXT_AREA;
2282 goto text_glyph_row_found;
2283
2284 case ON_TEXT:
2285 area = TEXT_AREA;
2286
2287 text_glyph:
2288 gr = 0; gy = 0;
2289 for (; r <= end_row && r->enabled_p; ++r)
2290 if (r->y + r->height > y)
2291 {
2292 gr = r; gy = r->y;
2293 break;
2294 }
2295
2296 text_glyph_row_found:
2297 if (gr && gy <= y)
2298 {
2299 struct glyph *g = gr->glyphs[area];
2300 struct glyph *end = g + gr->used[area];
2301
2302 height = gr->height;
2303 for (gx = gr->x; g < end; gx += g->pixel_width, ++g)
2304 if (gx + g->pixel_width > x)
2305 break;
2306
2307 if (g < end)
2308 {
2309 if (g->type == IMAGE_GLYPH)
2310 {
2311 /* Don't remember when mouse is over image, as
2312 image may have hot-spots. */
2313 STORE_NATIVE_RECT (*rect, 0, 0, 0, 0);
2314 return;
2315 }
2316 width = g->pixel_width;
2317 }
2318 else
2319 {
2320 /* Use nominal char spacing at end of line. */
2321 x -= gx;
2322 gx += (x / width) * width;
2323 }
2324
2325 if (part != ON_MODE_LINE && part != ON_HEADER_LINE)
2326 gx += window_box_left_offset (w, area);
2327 }
2328 else
2329 {
2330 /* Use nominal line height at end of window. */
2331 gx = (x / width) * width;
2332 y -= gy;
2333 gy += (y / height) * height;
2334 }
2335 break;
2336
2337 case ON_LEFT_FRINGE:
2338 gx = (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2339 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w)
2340 : window_box_right_offset (w, LEFT_MARGIN_AREA));
2341 width = WINDOW_LEFT_FRINGE_WIDTH (w);
2342 goto row_glyph;
2343
2344 case ON_RIGHT_FRINGE:
2345 gx = (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2346 ? window_box_right_offset (w, RIGHT_MARGIN_AREA)
2347 : window_box_right_offset (w, TEXT_AREA));
2348 width = WINDOW_RIGHT_FRINGE_WIDTH (w);
2349 goto row_glyph;
2350
2351 case ON_SCROLL_BAR:
2352 gx = (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w)
2353 ? 0
2354 : (window_box_right_offset (w, RIGHT_MARGIN_AREA)
2355 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2356 ? WINDOW_RIGHT_FRINGE_WIDTH (w)
2357 : 0)));
2358 width = WINDOW_SCROLL_BAR_AREA_WIDTH (w);
2359
2360 row_glyph:
2361 gr = 0, gy = 0;
2362 for (; r <= end_row && r->enabled_p; ++r)
2363 if (r->y + r->height > y)
2364 {
2365 gr = r; gy = r->y;
2366 break;
2367 }
2368
2369 if (gr && gy <= y)
2370 height = gr->height;
2371 else
2372 {
2373 /* Use nominal line height at end of window. */
2374 y -= gy;
2375 gy += (y / height) * height;
2376 }
2377 break;
2378
2379 default:
2380 ;
2381 virtual_glyph:
2382 /* If there is no glyph under the mouse, then we divide the screen
2383 into a grid of the smallest glyph in the frame, and use that
2384 as our "glyph". */
2385
2386 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to
2387 round down even for negative values. */
2388 if (gx < 0)
2389 gx -= width - 1;
2390 if (gy < 0)
2391 gy -= height - 1;
2392
2393 gx = (gx / width) * width;
2394 gy = (gy / height) * height;
2395
2396 goto store_rect;
2397 }
2398
2399 gx += WINDOW_LEFT_EDGE_X (w);
2400 gy += WINDOW_TOP_EDGE_Y (w);
2401
2402 store_rect:
2403 STORE_NATIVE_RECT (*rect, gx, gy, width, height);
2404
2405 /* Visible feedback for debugging. */
2406 #if 0
2407 #if HAVE_X_WINDOWS
2408 XDrawRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2409 f->output_data.x->normal_gc,
2410 gx, gy, width, height);
2411 #endif
2412 #endif
2413 }
2414
2415
2416 #endif /* HAVE_WINDOW_SYSTEM */
2417
2418 \f
2419 /***********************************************************************
2420 Lisp form evaluation
2421 ***********************************************************************/
2422
2423 /* Error handler for safe_eval and safe_call. */
2424
2425 static Lisp_Object
2426 safe_eval_handler (Lisp_Object arg, ptrdiff_t nargs, Lisp_Object *args)
2427 {
2428 add_to_log ("Error during redisplay: %S signaled %S",
2429 Flist (nargs, args), arg);
2430 return Qnil;
2431 }
2432
2433 /* Call function FUNC with the rest of NARGS - 1 arguments
2434 following. Return the result, or nil if something went
2435 wrong. Prevent redisplay during the evaluation. */
2436
2437 Lisp_Object
2438 safe_call (ptrdiff_t nargs, Lisp_Object func, ...)
2439 {
2440 Lisp_Object val;
2441
2442 if (inhibit_eval_during_redisplay)
2443 val = Qnil;
2444 else
2445 {
2446 va_list ap;
2447 ptrdiff_t i;
2448 ptrdiff_t count = SPECPDL_INDEX ();
2449 struct gcpro gcpro1;
2450 Lisp_Object *args = alloca (nargs * word_size);
2451
2452 args[0] = func;
2453 va_start (ap, func);
2454 for (i = 1; i < nargs; i++)
2455 args[i] = va_arg (ap, Lisp_Object);
2456 va_end (ap);
2457
2458 GCPRO1 (args[0]);
2459 gcpro1.nvars = nargs;
2460 specbind (Qinhibit_redisplay, Qt);
2461 /* Use Qt to ensure debugger does not run,
2462 so there is no possibility of wanting to redisplay. */
2463 val = internal_condition_case_n (Ffuncall, nargs, args, Qt,
2464 safe_eval_handler);
2465 UNGCPRO;
2466 val = unbind_to (count, val);
2467 }
2468
2469 return val;
2470 }
2471
2472
2473 /* Call function FN with one argument ARG.
2474 Return the result, or nil if something went wrong. */
2475
2476 Lisp_Object
2477 safe_call1 (Lisp_Object fn, Lisp_Object arg)
2478 {
2479 return safe_call (2, fn, arg);
2480 }
2481
2482 static Lisp_Object Qeval;
2483
2484 Lisp_Object
2485 safe_eval (Lisp_Object sexpr)
2486 {
2487 return safe_call1 (Qeval, sexpr);
2488 }
2489
2490 /* Call function FN with two arguments ARG1 and ARG2.
2491 Return the result, or nil if something went wrong. */
2492
2493 Lisp_Object
2494 safe_call2 (Lisp_Object fn, Lisp_Object arg1, Lisp_Object arg2)
2495 {
2496 return safe_call (3, fn, arg1, arg2);
2497 }
2498
2499
2500 \f
2501 /***********************************************************************
2502 Debugging
2503 ***********************************************************************/
2504
2505 #if 0
2506
2507 /* Define CHECK_IT to perform sanity checks on iterators.
2508 This is for debugging. It is too slow to do unconditionally. */
2509
2510 static void
2511 check_it (struct it *it)
2512 {
2513 if (it->method == GET_FROM_STRING)
2514 {
2515 eassert (STRINGP (it->string));
2516 eassert (IT_STRING_CHARPOS (*it) >= 0);
2517 }
2518 else
2519 {
2520 eassert (IT_STRING_CHARPOS (*it) < 0);
2521 if (it->method == GET_FROM_BUFFER)
2522 {
2523 /* Check that character and byte positions agree. */
2524 eassert (IT_CHARPOS (*it) == BYTE_TO_CHAR (IT_BYTEPOS (*it)));
2525 }
2526 }
2527
2528 if (it->dpvec)
2529 eassert (it->current.dpvec_index >= 0);
2530 else
2531 eassert (it->current.dpvec_index < 0);
2532 }
2533
2534 #define CHECK_IT(IT) check_it ((IT))
2535
2536 #else /* not 0 */
2537
2538 #define CHECK_IT(IT) (void) 0
2539
2540 #endif /* not 0 */
2541
2542
2543 #if defined GLYPH_DEBUG && defined ENABLE_CHECKING
2544
2545 /* Check that the window end of window W is what we expect it
2546 to be---the last row in the current matrix displaying text. */
2547
2548 static void
2549 check_window_end (struct window *w)
2550 {
2551 if (!MINI_WINDOW_P (w)
2552 && !NILP (w->window_end_valid))
2553 {
2554 struct glyph_row *row;
2555 eassert ((row = MATRIX_ROW (w->current_matrix,
2556 XFASTINT (w->window_end_vpos)),
2557 !row->enabled_p
2558 || MATRIX_ROW_DISPLAYS_TEXT_P (row)
2559 || MATRIX_ROW_VPOS (row, w->current_matrix) == 0));
2560 }
2561 }
2562
2563 #define CHECK_WINDOW_END(W) check_window_end ((W))
2564
2565 #else
2566
2567 #define CHECK_WINDOW_END(W) (void) 0
2568
2569 #endif /* GLYPH_DEBUG and ENABLE_CHECKING */
2570
2571
2572 \f
2573 /***********************************************************************
2574 Iterator initialization
2575 ***********************************************************************/
2576
2577 /* Initialize IT for displaying current_buffer in window W, starting
2578 at character position CHARPOS. CHARPOS < 0 means that no buffer
2579 position is specified which is useful when the iterator is assigned
2580 a position later. BYTEPOS is the byte position corresponding to
2581 CHARPOS. BYTEPOS < 0 means compute it from CHARPOS.
2582
2583 If ROW is not null, calls to produce_glyphs with IT as parameter
2584 will produce glyphs in that row.
2585
2586 BASE_FACE_ID is the id of a base face to use. It must be one of
2587 DEFAULT_FACE_ID for normal text, MODE_LINE_FACE_ID,
2588 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID for displaying
2589 mode lines, or TOOL_BAR_FACE_ID for displaying the tool-bar.
2590
2591 If ROW is null and BASE_FACE_ID is equal to MODE_LINE_FACE_ID,
2592 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID, the iterator
2593 will be initialized to use the corresponding mode line glyph row of
2594 the desired matrix of W. */
2595
2596 void
2597 init_iterator (struct it *it, struct window *w,
2598 ptrdiff_t charpos, ptrdiff_t bytepos,
2599 struct glyph_row *row, enum face_id base_face_id)
2600 {
2601 int highlight_region_p;
2602 enum face_id remapped_base_face_id = base_face_id;
2603
2604 /* Some precondition checks. */
2605 eassert (w != NULL && it != NULL);
2606 eassert (charpos < 0 || (charpos >= BUF_BEG (current_buffer)
2607 && charpos <= ZV));
2608
2609 /* If face attributes have been changed since the last redisplay,
2610 free realized faces now because they depend on face definitions
2611 that might have changed. Don't free faces while there might be
2612 desired matrices pending which reference these faces. */
2613 if (face_change_count && !inhibit_free_realized_faces)
2614 {
2615 face_change_count = 0;
2616 free_all_realized_faces (Qnil);
2617 }
2618
2619 /* Perhaps remap BASE_FACE_ID to a user-specified alternative. */
2620 if (! NILP (Vface_remapping_alist))
2621 remapped_base_face_id
2622 = lookup_basic_face (XFRAME (w->frame), base_face_id);
2623
2624 /* Use one of the mode line rows of W's desired matrix if
2625 appropriate. */
2626 if (row == NULL)
2627 {
2628 if (base_face_id == MODE_LINE_FACE_ID
2629 || base_face_id == MODE_LINE_INACTIVE_FACE_ID)
2630 row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
2631 else if (base_face_id == HEADER_LINE_FACE_ID)
2632 row = MATRIX_HEADER_LINE_ROW (w->desired_matrix);
2633 }
2634
2635 /* Clear IT. */
2636 memset (it, 0, sizeof *it);
2637 it->current.overlay_string_index = -1;
2638 it->current.dpvec_index = -1;
2639 it->base_face_id = remapped_base_face_id;
2640 it->string = Qnil;
2641 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
2642 it->paragraph_embedding = L2R;
2643 it->bidi_it.string.lstring = Qnil;
2644 it->bidi_it.string.s = NULL;
2645 it->bidi_it.string.bufpos = 0;
2646
2647 /* The window in which we iterate over current_buffer: */
2648 XSETWINDOW (it->window, w);
2649 it->w = w;
2650 it->f = XFRAME (w->frame);
2651
2652 it->cmp_it.id = -1;
2653
2654 /* Extra space between lines (on window systems only). */
2655 if (base_face_id == DEFAULT_FACE_ID
2656 && FRAME_WINDOW_P (it->f))
2657 {
2658 if (NATNUMP (BVAR (current_buffer, extra_line_spacing)))
2659 it->extra_line_spacing = XFASTINT (BVAR (current_buffer, extra_line_spacing));
2660 else if (FLOATP (BVAR (current_buffer, extra_line_spacing)))
2661 it->extra_line_spacing = (XFLOAT_DATA (BVAR (current_buffer, extra_line_spacing))
2662 * FRAME_LINE_HEIGHT (it->f));
2663 else if (it->f->extra_line_spacing > 0)
2664 it->extra_line_spacing = it->f->extra_line_spacing;
2665 it->max_extra_line_spacing = 0;
2666 }
2667
2668 /* If realized faces have been removed, e.g. because of face
2669 attribute changes of named faces, recompute them. When running
2670 in batch mode, the face cache of the initial frame is null. If
2671 we happen to get called, make a dummy face cache. */
2672 if (FRAME_FACE_CACHE (it->f) == NULL)
2673 init_frame_faces (it->f);
2674 if (FRAME_FACE_CACHE (it->f)->used == 0)
2675 recompute_basic_faces (it->f);
2676
2677 /* Current value of the `slice', `space-width', and 'height' properties. */
2678 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
2679 it->space_width = Qnil;
2680 it->font_height = Qnil;
2681 it->override_ascent = -1;
2682
2683 /* Are control characters displayed as `^C'? */
2684 it->ctl_arrow_p = !NILP (BVAR (current_buffer, ctl_arrow));
2685
2686 /* -1 means everything between a CR and the following line end
2687 is invisible. >0 means lines indented more than this value are
2688 invisible. */
2689 it->selective = (INTEGERP (BVAR (current_buffer, selective_display))
2690 ? (clip_to_bounds
2691 (-1, XINT (BVAR (current_buffer, selective_display)),
2692 PTRDIFF_MAX))
2693 : (!NILP (BVAR (current_buffer, selective_display))
2694 ? -1 : 0));
2695 it->selective_display_ellipsis_p
2696 = !NILP (BVAR (current_buffer, selective_display_ellipses));
2697
2698 /* Display table to use. */
2699 it->dp = window_display_table (w);
2700
2701 /* Are multibyte characters enabled in current_buffer? */
2702 it->multibyte_p = !NILP (BVAR (current_buffer, enable_multibyte_characters));
2703
2704 /* Non-zero if we should highlight the region. */
2705 highlight_region_p
2706 = (!NILP (Vtransient_mark_mode)
2707 && !NILP (BVAR (current_buffer, mark_active))
2708 && XMARKER (BVAR (current_buffer, mark))->buffer != 0);
2709
2710 /* Set IT->region_beg_charpos and IT->region_end_charpos to the
2711 start and end of a visible region in window IT->w. Set both to
2712 -1 to indicate no region. */
2713 if (highlight_region_p
2714 /* Maybe highlight only in selected window. */
2715 && (/* Either show region everywhere. */
2716 highlight_nonselected_windows
2717 /* Or show region in the selected window. */
2718 || w == XWINDOW (selected_window)
2719 /* Or show the region if we are in the mini-buffer and W is
2720 the window the mini-buffer refers to. */
2721 || (MINI_WINDOW_P (XWINDOW (selected_window))
2722 && WINDOWP (minibuf_selected_window)
2723 && w == XWINDOW (minibuf_selected_window))))
2724 {
2725 ptrdiff_t markpos = marker_position (BVAR (current_buffer, mark));
2726 it->region_beg_charpos = min (PT, markpos);
2727 it->region_end_charpos = max (PT, markpos);
2728 }
2729 else
2730 it->region_beg_charpos = it->region_end_charpos = -1;
2731
2732 /* Get the position at which the redisplay_end_trigger hook should
2733 be run, if it is to be run at all. */
2734 if (MARKERP (w->redisplay_end_trigger)
2735 && XMARKER (w->redisplay_end_trigger)->buffer != 0)
2736 it->redisplay_end_trigger_charpos
2737 = marker_position (w->redisplay_end_trigger);
2738 else if (INTEGERP (w->redisplay_end_trigger))
2739 it->redisplay_end_trigger_charpos =
2740 clip_to_bounds (PTRDIFF_MIN, XINT (w->redisplay_end_trigger), PTRDIFF_MAX);
2741
2742 it->tab_width = SANE_TAB_WIDTH (current_buffer);
2743
2744 /* Are lines in the display truncated? */
2745 if (base_face_id != DEFAULT_FACE_ID
2746 || it->w->hscroll
2747 || (! WINDOW_FULL_WIDTH_P (it->w)
2748 && ((!NILP (Vtruncate_partial_width_windows)
2749 && !INTEGERP (Vtruncate_partial_width_windows))
2750 || (INTEGERP (Vtruncate_partial_width_windows)
2751 && (WINDOW_TOTAL_COLS (it->w)
2752 < XINT (Vtruncate_partial_width_windows))))))
2753 it->line_wrap = TRUNCATE;
2754 else if (NILP (BVAR (current_buffer, truncate_lines)))
2755 it->line_wrap = NILP (BVAR (current_buffer, word_wrap))
2756 ? WINDOW_WRAP : WORD_WRAP;
2757 else
2758 it->line_wrap = TRUNCATE;
2759
2760 /* Get dimensions of truncation and continuation glyphs. These are
2761 displayed as fringe bitmaps under X, but we need them for such
2762 frames when the fringes are turned off. But leave the dimensions
2763 zero for tooltip frames, as these glyphs look ugly there and also
2764 sabotage calculations of tooltip dimensions in x-show-tip. */
2765 #ifdef HAVE_WINDOW_SYSTEM
2766 if (!(FRAME_WINDOW_P (it->f)
2767 && FRAMEP (tip_frame)
2768 && it->f == XFRAME (tip_frame)))
2769 #endif
2770 {
2771 if (it->line_wrap == TRUNCATE)
2772 {
2773 /* We will need the truncation glyph. */
2774 eassert (it->glyph_row == NULL);
2775 produce_special_glyphs (it, IT_TRUNCATION);
2776 it->truncation_pixel_width = it->pixel_width;
2777 }
2778 else
2779 {
2780 /* We will need the continuation glyph. */
2781 eassert (it->glyph_row == NULL);
2782 produce_special_glyphs (it, IT_CONTINUATION);
2783 it->continuation_pixel_width = it->pixel_width;
2784 }
2785 }
2786
2787 /* Reset these values to zero because the produce_special_glyphs
2788 above has changed them. */
2789 it->pixel_width = it->ascent = it->descent = 0;
2790 it->phys_ascent = it->phys_descent = 0;
2791
2792 /* Set this after getting the dimensions of truncation and
2793 continuation glyphs, so that we don't produce glyphs when calling
2794 produce_special_glyphs, above. */
2795 it->glyph_row = row;
2796 it->area = TEXT_AREA;
2797
2798 /* Forget any previous info about this row being reversed. */
2799 if (it->glyph_row)
2800 it->glyph_row->reversed_p = 0;
2801
2802 /* Get the dimensions of the display area. The display area
2803 consists of the visible window area plus a horizontally scrolled
2804 part to the left of the window. All x-values are relative to the
2805 start of this total display area. */
2806 if (base_face_id != DEFAULT_FACE_ID)
2807 {
2808 /* Mode lines, menu bar in terminal frames. */
2809 it->first_visible_x = 0;
2810 it->last_visible_x = WINDOW_TOTAL_WIDTH (w);
2811 }
2812 else
2813 {
2814 it->first_visible_x =
2815 window_hscroll_limited (it->w, it->f) * FRAME_COLUMN_WIDTH (it->f);
2816 it->last_visible_x = (it->first_visible_x
2817 + window_box_width (w, TEXT_AREA));
2818
2819 /* If we truncate lines, leave room for the truncation glyph(s) at
2820 the right margin. Otherwise, leave room for the continuation
2821 glyph(s). Done only if the window has no fringes. Since we
2822 don't know at this point whether there will be any R2L lines in
2823 the window, we reserve space for truncation/continuation glyphs
2824 even if only one of the fringes is absent. */
2825 if (WINDOW_RIGHT_FRINGE_WIDTH (it->w) == 0
2826 || (it->bidi_p && WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0))
2827 {
2828 if (it->line_wrap == TRUNCATE)
2829 it->last_visible_x -= it->truncation_pixel_width;
2830 else
2831 it->last_visible_x -= it->continuation_pixel_width;
2832 }
2833
2834 it->header_line_p = WINDOW_WANTS_HEADER_LINE_P (w);
2835 it->current_y = WINDOW_HEADER_LINE_HEIGHT (w) + w->vscroll;
2836 }
2837
2838 /* Leave room for a border glyph. */
2839 if (!FRAME_WINDOW_P (it->f)
2840 && !WINDOW_RIGHTMOST_P (it->w))
2841 it->last_visible_x -= 1;
2842
2843 it->last_visible_y = window_text_bottom_y (w);
2844
2845 /* For mode lines and alike, arrange for the first glyph having a
2846 left box line if the face specifies a box. */
2847 if (base_face_id != DEFAULT_FACE_ID)
2848 {
2849 struct face *face;
2850
2851 it->face_id = remapped_base_face_id;
2852
2853 /* If we have a boxed mode line, make the first character appear
2854 with a left box line. */
2855 face = FACE_FROM_ID (it->f, remapped_base_face_id);
2856 if (face->box != FACE_NO_BOX)
2857 it->start_of_box_run_p = 1;
2858 }
2859
2860 /* If a buffer position was specified, set the iterator there,
2861 getting overlays and face properties from that position. */
2862 if (charpos >= BUF_BEG (current_buffer))
2863 {
2864 it->end_charpos = ZV;
2865 IT_CHARPOS (*it) = charpos;
2866
2867 /* We will rely on `reseat' to set this up properly, via
2868 handle_face_prop. */
2869 it->face_id = it->base_face_id;
2870
2871 /* Compute byte position if not specified. */
2872 if (bytepos < charpos)
2873 IT_BYTEPOS (*it) = CHAR_TO_BYTE (charpos);
2874 else
2875 IT_BYTEPOS (*it) = bytepos;
2876
2877 it->start = it->current;
2878 /* Do we need to reorder bidirectional text? Not if this is a
2879 unibyte buffer: by definition, none of the single-byte
2880 characters are strong R2L, so no reordering is needed. And
2881 bidi.c doesn't support unibyte buffers anyway. Also, don't
2882 reorder while we are loading loadup.el, since the tables of
2883 character properties needed for reordering are not yet
2884 available. */
2885 it->bidi_p =
2886 NILP (Vpurify_flag)
2887 && !NILP (BVAR (current_buffer, bidi_display_reordering))
2888 && it->multibyte_p;
2889
2890 /* If we are to reorder bidirectional text, init the bidi
2891 iterator. */
2892 if (it->bidi_p)
2893 {
2894 /* Note the paragraph direction that this buffer wants to
2895 use. */
2896 if (EQ (BVAR (current_buffer, bidi_paragraph_direction),
2897 Qleft_to_right))
2898 it->paragraph_embedding = L2R;
2899 else if (EQ (BVAR (current_buffer, bidi_paragraph_direction),
2900 Qright_to_left))
2901 it->paragraph_embedding = R2L;
2902 else
2903 it->paragraph_embedding = NEUTRAL_DIR;
2904 bidi_unshelve_cache (NULL, 0);
2905 bidi_init_it (charpos, IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f),
2906 &it->bidi_it);
2907 }
2908
2909 /* Compute faces etc. */
2910 reseat (it, it->current.pos, 1);
2911 }
2912
2913 CHECK_IT (it);
2914 }
2915
2916
2917 /* Initialize IT for the display of window W with window start POS. */
2918
2919 void
2920 start_display (struct it *it, struct window *w, struct text_pos pos)
2921 {
2922 struct glyph_row *row;
2923 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
2924
2925 row = w->desired_matrix->rows + first_vpos;
2926 init_iterator (it, w, CHARPOS (pos), BYTEPOS (pos), row, DEFAULT_FACE_ID);
2927 it->first_vpos = first_vpos;
2928
2929 /* Don't reseat to previous visible line start if current start
2930 position is in a string or image. */
2931 if (it->method == GET_FROM_BUFFER && it->line_wrap != TRUNCATE)
2932 {
2933 int start_at_line_beg_p;
2934 int first_y = it->current_y;
2935
2936 /* If window start is not at a line start, skip forward to POS to
2937 get the correct continuation lines width. */
2938 start_at_line_beg_p = (CHARPOS (pos) == BEGV
2939 || FETCH_BYTE (BYTEPOS (pos) - 1) == '\n');
2940 if (!start_at_line_beg_p)
2941 {
2942 int new_x;
2943
2944 reseat_at_previous_visible_line_start (it);
2945 move_it_to (it, CHARPOS (pos), -1, -1, -1, MOVE_TO_POS);
2946
2947 new_x = it->current_x + it->pixel_width;
2948
2949 /* If lines are continued, this line may end in the middle
2950 of a multi-glyph character (e.g. a control character
2951 displayed as \003, or in the middle of an overlay
2952 string). In this case move_it_to above will not have
2953 taken us to the start of the continuation line but to the
2954 end of the continued line. */
2955 if (it->current_x > 0
2956 && it->line_wrap != TRUNCATE /* Lines are continued. */
2957 && (/* And glyph doesn't fit on the line. */
2958 new_x > it->last_visible_x
2959 /* Or it fits exactly and we're on a window
2960 system frame. */
2961 || (new_x == it->last_visible_x
2962 && FRAME_WINDOW_P (it->f)
2963 && ((it->bidi_p && it->bidi_it.paragraph_dir == R2L)
2964 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
2965 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)))))
2966 {
2967 if ((it->current.dpvec_index >= 0
2968 || it->current.overlay_string_index >= 0)
2969 /* If we are on a newline from a display vector or
2970 overlay string, then we are already at the end of
2971 a screen line; no need to go to the next line in
2972 that case, as this line is not really continued.
2973 (If we do go to the next line, C-e will not DTRT.) */
2974 && it->c != '\n')
2975 {
2976 set_iterator_to_next (it, 1);
2977 move_it_in_display_line_to (it, -1, -1, 0);
2978 }
2979
2980 it->continuation_lines_width += it->current_x;
2981 }
2982 /* If the character at POS is displayed via a display
2983 vector, move_it_to above stops at the final glyph of
2984 IT->dpvec. To make the caller redisplay that character
2985 again (a.k.a. start at POS), we need to reset the
2986 dpvec_index to the beginning of IT->dpvec. */
2987 else if (it->current.dpvec_index >= 0)
2988 it->current.dpvec_index = 0;
2989
2990 /* We're starting a new display line, not affected by the
2991 height of the continued line, so clear the appropriate
2992 fields in the iterator structure. */
2993 it->max_ascent = it->max_descent = 0;
2994 it->max_phys_ascent = it->max_phys_descent = 0;
2995
2996 it->current_y = first_y;
2997 it->vpos = 0;
2998 it->current_x = it->hpos = 0;
2999 }
3000 }
3001 }
3002
3003
3004 /* Return 1 if POS is a position in ellipses displayed for invisible
3005 text. W is the window we display, for text property lookup. */
3006
3007 static int
3008 in_ellipses_for_invisible_text_p (struct display_pos *pos, struct window *w)
3009 {
3010 Lisp_Object prop, window;
3011 int ellipses_p = 0;
3012 ptrdiff_t charpos = CHARPOS (pos->pos);
3013
3014 /* If POS specifies a position in a display vector, this might
3015 be for an ellipsis displayed for invisible text. We won't
3016 get the iterator set up for delivering that ellipsis unless
3017 we make sure that it gets aware of the invisible text. */
3018 if (pos->dpvec_index >= 0
3019 && pos->overlay_string_index < 0
3020 && CHARPOS (pos->string_pos) < 0
3021 && charpos > BEGV
3022 && (XSETWINDOW (window, w),
3023 prop = Fget_char_property (make_number (charpos),
3024 Qinvisible, window),
3025 !TEXT_PROP_MEANS_INVISIBLE (prop)))
3026 {
3027 prop = Fget_char_property (make_number (charpos - 1), Qinvisible,
3028 window);
3029 ellipses_p = 2 == TEXT_PROP_MEANS_INVISIBLE (prop);
3030 }
3031
3032 return ellipses_p;
3033 }
3034
3035
3036 /* Initialize IT for stepping through current_buffer in window W,
3037 starting at position POS that includes overlay string and display
3038 vector/ control character translation position information. Value
3039 is zero if there are overlay strings with newlines at POS. */
3040
3041 static int
3042 init_from_display_pos (struct it *it, struct window *w, struct display_pos *pos)
3043 {
3044 ptrdiff_t charpos = CHARPOS (pos->pos), bytepos = BYTEPOS (pos->pos);
3045 int i, overlay_strings_with_newlines = 0;
3046
3047 /* If POS specifies a position in a display vector, this might
3048 be for an ellipsis displayed for invisible text. We won't
3049 get the iterator set up for delivering that ellipsis unless
3050 we make sure that it gets aware of the invisible text. */
3051 if (in_ellipses_for_invisible_text_p (pos, w))
3052 {
3053 --charpos;
3054 bytepos = 0;
3055 }
3056
3057 /* Keep in mind: the call to reseat in init_iterator skips invisible
3058 text, so we might end up at a position different from POS. This
3059 is only a problem when POS is a row start after a newline and an
3060 overlay starts there with an after-string, and the overlay has an
3061 invisible property. Since we don't skip invisible text in
3062 display_line and elsewhere immediately after consuming the
3063 newline before the row start, such a POS will not be in a string,
3064 but the call to init_iterator below will move us to the
3065 after-string. */
3066 init_iterator (it, w, charpos, bytepos, NULL, DEFAULT_FACE_ID);
3067
3068 /* This only scans the current chunk -- it should scan all chunks.
3069 However, OVERLAY_STRING_CHUNK_SIZE has been increased from 3 in 21.1
3070 to 16 in 22.1 to make this a lesser problem. */
3071 for (i = 0; i < it->n_overlay_strings && i < OVERLAY_STRING_CHUNK_SIZE; ++i)
3072 {
3073 const char *s = SSDATA (it->overlay_strings[i]);
3074 const char *e = s + SBYTES (it->overlay_strings[i]);
3075
3076 while (s < e && *s != '\n')
3077 ++s;
3078
3079 if (s < e)
3080 {
3081 overlay_strings_with_newlines = 1;
3082 break;
3083 }
3084 }
3085
3086 /* If position is within an overlay string, set up IT to the right
3087 overlay string. */
3088 if (pos->overlay_string_index >= 0)
3089 {
3090 int relative_index;
3091
3092 /* If the first overlay string happens to have a `display'
3093 property for an image, the iterator will be set up for that
3094 image, and we have to undo that setup first before we can
3095 correct the overlay string index. */
3096 if (it->method == GET_FROM_IMAGE)
3097 pop_it (it);
3098
3099 /* We already have the first chunk of overlay strings in
3100 IT->overlay_strings. Load more until the one for
3101 pos->overlay_string_index is in IT->overlay_strings. */
3102 if (pos->overlay_string_index >= OVERLAY_STRING_CHUNK_SIZE)
3103 {
3104 ptrdiff_t n = pos->overlay_string_index / OVERLAY_STRING_CHUNK_SIZE;
3105 it->current.overlay_string_index = 0;
3106 while (n--)
3107 {
3108 load_overlay_strings (it, 0);
3109 it->current.overlay_string_index += OVERLAY_STRING_CHUNK_SIZE;
3110 }
3111 }
3112
3113 it->current.overlay_string_index = pos->overlay_string_index;
3114 relative_index = (it->current.overlay_string_index
3115 % OVERLAY_STRING_CHUNK_SIZE);
3116 it->string = it->overlay_strings[relative_index];
3117 eassert (STRINGP (it->string));
3118 it->current.string_pos = pos->string_pos;
3119 it->method = GET_FROM_STRING;
3120 }
3121
3122 if (CHARPOS (pos->string_pos) >= 0)
3123 {
3124 /* Recorded position is not in an overlay string, but in another
3125 string. This can only be a string from a `display' property.
3126 IT should already be filled with that string. */
3127 it->current.string_pos = pos->string_pos;
3128 eassert (STRINGP (it->string));
3129 }
3130
3131 /* Restore position in display vector translations, control
3132 character translations or ellipses. */
3133 if (pos->dpvec_index >= 0)
3134 {
3135 if (it->dpvec == NULL)
3136 get_next_display_element (it);
3137 eassert (it->dpvec && it->current.dpvec_index == 0);
3138 it->current.dpvec_index = pos->dpvec_index;
3139 }
3140
3141 CHECK_IT (it);
3142 return !overlay_strings_with_newlines;
3143 }
3144
3145
3146 /* Initialize IT for stepping through current_buffer in window W
3147 starting at ROW->start. */
3148
3149 static void
3150 init_to_row_start (struct it *it, struct window *w, struct glyph_row *row)
3151 {
3152 init_from_display_pos (it, w, &row->start);
3153 it->start = row->start;
3154 it->continuation_lines_width = row->continuation_lines_width;
3155 CHECK_IT (it);
3156 }
3157
3158
3159 /* Initialize IT for stepping through current_buffer in window W
3160 starting in the line following ROW, i.e. starting at ROW->end.
3161 Value is zero if there are overlay strings with newlines at ROW's
3162 end position. */
3163
3164 static int
3165 init_to_row_end (struct it *it, struct window *w, struct glyph_row *row)
3166 {
3167 int success = 0;
3168
3169 if (init_from_display_pos (it, w, &row->end))
3170 {
3171 if (row->continued_p)
3172 it->continuation_lines_width
3173 = row->continuation_lines_width + row->pixel_width;
3174 CHECK_IT (it);
3175 success = 1;
3176 }
3177
3178 return success;
3179 }
3180
3181
3182
3183 \f
3184 /***********************************************************************
3185 Text properties
3186 ***********************************************************************/
3187
3188 /* Called when IT reaches IT->stop_charpos. Handle text property and
3189 overlay changes. Set IT->stop_charpos to the next position where
3190 to stop. */
3191
3192 static void
3193 handle_stop (struct it *it)
3194 {
3195 enum prop_handled handled;
3196 int handle_overlay_change_p;
3197 struct props *p;
3198
3199 it->dpvec = NULL;
3200 it->current.dpvec_index = -1;
3201 handle_overlay_change_p = !it->ignore_overlay_strings_at_pos_p;
3202 it->ignore_overlay_strings_at_pos_p = 0;
3203 it->ellipsis_p = 0;
3204
3205 /* Use face of preceding text for ellipsis (if invisible) */
3206 if (it->selective_display_ellipsis_p)
3207 it->saved_face_id = it->face_id;
3208
3209 do
3210 {
3211 handled = HANDLED_NORMALLY;
3212
3213 /* Call text property handlers. */
3214 for (p = it_props; p->handler; ++p)
3215 {
3216 handled = p->handler (it);
3217
3218 if (handled == HANDLED_RECOMPUTE_PROPS)
3219 break;
3220 else if (handled == HANDLED_RETURN)
3221 {
3222 /* We still want to show before and after strings from
3223 overlays even if the actual buffer text is replaced. */
3224 if (!handle_overlay_change_p
3225 || it->sp > 1
3226 /* Don't call get_overlay_strings_1 if we already
3227 have overlay strings loaded, because doing so
3228 will load them again and push the iterator state
3229 onto the stack one more time, which is not
3230 expected by the rest of the code that processes
3231 overlay strings. */
3232 || (it->current.overlay_string_index < 0
3233 ? !get_overlay_strings_1 (it, 0, 0)
3234 : 0))
3235 {
3236 if (it->ellipsis_p)
3237 setup_for_ellipsis (it, 0);
3238 /* When handling a display spec, we might load an
3239 empty string. In that case, discard it here. We
3240 used to discard it in handle_single_display_spec,
3241 but that causes get_overlay_strings_1, above, to
3242 ignore overlay strings that we must check. */
3243 if (STRINGP (it->string) && !SCHARS (it->string))
3244 pop_it (it);
3245 return;
3246 }
3247 else if (STRINGP (it->string) && !SCHARS (it->string))
3248 pop_it (it);
3249 else
3250 {
3251 it->ignore_overlay_strings_at_pos_p = 1;
3252 it->string_from_display_prop_p = 0;
3253 it->from_disp_prop_p = 0;
3254 handle_overlay_change_p = 0;
3255 }
3256 handled = HANDLED_RECOMPUTE_PROPS;
3257 break;
3258 }
3259 else if (handled == HANDLED_OVERLAY_STRING_CONSUMED)
3260 handle_overlay_change_p = 0;
3261 }
3262
3263 if (handled != HANDLED_RECOMPUTE_PROPS)
3264 {
3265 /* Don't check for overlay strings below when set to deliver
3266 characters from a display vector. */
3267 if (it->method == GET_FROM_DISPLAY_VECTOR)
3268 handle_overlay_change_p = 0;
3269
3270 /* Handle overlay changes.
3271 This sets HANDLED to HANDLED_RECOMPUTE_PROPS
3272 if it finds overlays. */
3273 if (handle_overlay_change_p)
3274 handled = handle_overlay_change (it);
3275 }
3276
3277 if (it->ellipsis_p)
3278 {
3279 setup_for_ellipsis (it, 0);
3280 break;
3281 }
3282 }
3283 while (handled == HANDLED_RECOMPUTE_PROPS);
3284
3285 /* Determine where to stop next. */
3286 if (handled == HANDLED_NORMALLY)
3287 compute_stop_pos (it);
3288 }
3289
3290
3291 /* Compute IT->stop_charpos from text property and overlay change
3292 information for IT's current position. */
3293
3294 static void
3295 compute_stop_pos (struct it *it)
3296 {
3297 register INTERVAL iv, next_iv;
3298 Lisp_Object object, limit, position;
3299 ptrdiff_t charpos, bytepos;
3300
3301 if (STRINGP (it->string))
3302 {
3303 /* Strings are usually short, so don't limit the search for
3304 properties. */
3305 it->stop_charpos = it->end_charpos;
3306 object = it->string;
3307 limit = Qnil;
3308 charpos = IT_STRING_CHARPOS (*it);
3309 bytepos = IT_STRING_BYTEPOS (*it);
3310 }
3311 else
3312 {
3313 ptrdiff_t pos;
3314
3315 /* If end_charpos is out of range for some reason, such as a
3316 misbehaving display function, rationalize it (Bug#5984). */
3317 if (it->end_charpos > ZV)
3318 it->end_charpos = ZV;
3319 it->stop_charpos = it->end_charpos;
3320
3321 /* If next overlay change is in front of the current stop pos
3322 (which is IT->end_charpos), stop there. Note: value of
3323 next_overlay_change is point-max if no overlay change
3324 follows. */
3325 charpos = IT_CHARPOS (*it);
3326 bytepos = IT_BYTEPOS (*it);
3327 pos = next_overlay_change (charpos);
3328 if (pos < it->stop_charpos)
3329 it->stop_charpos = pos;
3330
3331 /* If showing the region, we have to stop at the region
3332 start or end because the face might change there. */
3333 if (it->region_beg_charpos > 0)
3334 {
3335 if (IT_CHARPOS (*it) < it->region_beg_charpos)
3336 it->stop_charpos = min (it->stop_charpos, it->region_beg_charpos);
3337 else if (IT_CHARPOS (*it) < it->region_end_charpos)
3338 it->stop_charpos = min (it->stop_charpos, it->region_end_charpos);
3339 }
3340
3341 /* Set up variables for computing the stop position from text
3342 property changes. */
3343 XSETBUFFER (object, current_buffer);
3344 limit = make_number (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT);
3345 }
3346
3347 /* Get the interval containing IT's position. Value is a null
3348 interval if there isn't such an interval. */
3349 position = make_number (charpos);
3350 iv = validate_interval_range (object, &position, &position, 0);
3351 if (iv)
3352 {
3353 Lisp_Object values_here[LAST_PROP_IDX];
3354 struct props *p;
3355
3356 /* Get properties here. */
3357 for (p = it_props; p->handler; ++p)
3358 values_here[p->idx] = textget (iv->plist, *p->name);
3359
3360 /* Look for an interval following iv that has different
3361 properties. */
3362 for (next_iv = next_interval (iv);
3363 (next_iv
3364 && (NILP (limit)
3365 || XFASTINT (limit) > next_iv->position));
3366 next_iv = next_interval (next_iv))
3367 {
3368 for (p = it_props; p->handler; ++p)
3369 {
3370 Lisp_Object new_value;
3371
3372 new_value = textget (next_iv->plist, *p->name);
3373 if (!EQ (values_here[p->idx], new_value))
3374 break;
3375 }
3376
3377 if (p->handler)
3378 break;
3379 }
3380
3381 if (next_iv)
3382 {
3383 if (INTEGERP (limit)
3384 && next_iv->position >= XFASTINT (limit))
3385 /* No text property change up to limit. */
3386 it->stop_charpos = min (XFASTINT (limit), it->stop_charpos);
3387 else
3388 /* Text properties change in next_iv. */
3389 it->stop_charpos = min (it->stop_charpos, next_iv->position);
3390 }
3391 }
3392
3393 if (it->cmp_it.id < 0)
3394 {
3395 ptrdiff_t stoppos = it->end_charpos;
3396
3397 if (it->bidi_p && it->bidi_it.scan_dir < 0)
3398 stoppos = -1;
3399 composition_compute_stop_pos (&it->cmp_it, charpos, bytepos,
3400 stoppos, it->string);
3401 }
3402
3403 eassert (STRINGP (it->string)
3404 || (it->stop_charpos >= BEGV
3405 && it->stop_charpos >= IT_CHARPOS (*it)));
3406 }
3407
3408
3409 /* Return the position of the next overlay change after POS in
3410 current_buffer. Value is point-max if no overlay change
3411 follows. This is like `next-overlay-change' but doesn't use
3412 xmalloc. */
3413
3414 static ptrdiff_t
3415 next_overlay_change (ptrdiff_t pos)
3416 {
3417 ptrdiff_t i, noverlays;
3418 ptrdiff_t endpos;
3419 Lisp_Object *overlays;
3420
3421 /* Get all overlays at the given position. */
3422 GET_OVERLAYS_AT (pos, overlays, noverlays, &endpos, 1);
3423
3424 /* If any of these overlays ends before endpos,
3425 use its ending point instead. */
3426 for (i = 0; i < noverlays; ++i)
3427 {
3428 Lisp_Object oend;
3429 ptrdiff_t oendpos;
3430
3431 oend = OVERLAY_END (overlays[i]);
3432 oendpos = OVERLAY_POSITION (oend);
3433 endpos = min (endpos, oendpos);
3434 }
3435
3436 return endpos;
3437 }
3438
3439 /* How many characters forward to search for a display property or
3440 display string. Searching too far forward makes the bidi display
3441 sluggish, especially in small windows. */
3442 #define MAX_DISP_SCAN 250
3443
3444 /* Return the character position of a display string at or after
3445 position specified by POSITION. If no display string exists at or
3446 after POSITION, return ZV. A display string is either an overlay
3447 with `display' property whose value is a string, or a `display'
3448 text property whose value is a string. STRING is data about the
3449 string to iterate; if STRING->lstring is nil, we are iterating a
3450 buffer. FRAME_WINDOW_P is non-zero when we are displaying a window
3451 on a GUI frame. DISP_PROP is set to zero if we searched
3452 MAX_DISP_SCAN characters forward without finding any display
3453 strings, non-zero otherwise. It is set to 2 if the display string
3454 uses any kind of `(space ...)' spec that will produce a stretch of
3455 white space in the text area. */
3456 ptrdiff_t
3457 compute_display_string_pos (struct text_pos *position,
3458 struct bidi_string_data *string,
3459 int frame_window_p, int *disp_prop)
3460 {
3461 /* OBJECT = nil means current buffer. */
3462 Lisp_Object object =
3463 (string && STRINGP (string->lstring)) ? string->lstring : Qnil;
3464 Lisp_Object pos, spec, limpos;
3465 int string_p = (string && (STRINGP (string->lstring) || string->s));
3466 ptrdiff_t eob = string_p ? string->schars : ZV;
3467 ptrdiff_t begb = string_p ? 0 : BEGV;
3468 ptrdiff_t bufpos, charpos = CHARPOS (*position);
3469 ptrdiff_t lim =
3470 (charpos < eob - MAX_DISP_SCAN) ? charpos + MAX_DISP_SCAN : eob;
3471 struct text_pos tpos;
3472 int rv = 0;
3473
3474 *disp_prop = 1;
3475
3476 if (charpos >= eob
3477 /* We don't support display properties whose values are strings
3478 that have display string properties. */
3479 || string->from_disp_str
3480 /* C strings cannot have display properties. */
3481 || (string->s && !STRINGP (object)))
3482 {
3483 *disp_prop = 0;
3484 return eob;
3485 }
3486
3487 /* If the character at CHARPOS is where the display string begins,
3488 return CHARPOS. */
3489 pos = make_number (charpos);
3490 if (STRINGP (object))
3491 bufpos = string->bufpos;
3492 else
3493 bufpos = charpos;
3494 tpos = *position;
3495 if (!NILP (spec = Fget_char_property (pos, Qdisplay, object))
3496 && (charpos <= begb
3497 || !EQ (Fget_char_property (make_number (charpos - 1), Qdisplay,
3498 object),
3499 spec))
3500 && (rv = handle_display_spec (NULL, spec, object, Qnil, &tpos, bufpos,
3501 frame_window_p)))
3502 {
3503 if (rv == 2)
3504 *disp_prop = 2;
3505 return charpos;
3506 }
3507
3508 /* Look forward for the first character with a `display' property
3509 that will replace the underlying text when displayed. */
3510 limpos = make_number (lim);
3511 do {
3512 pos = Fnext_single_char_property_change (pos, Qdisplay, object, limpos);
3513 CHARPOS (tpos) = XFASTINT (pos);
3514 if (CHARPOS (tpos) >= lim)
3515 {
3516 *disp_prop = 0;
3517 break;
3518 }
3519 if (STRINGP (object))
3520 BYTEPOS (tpos) = string_char_to_byte (object, CHARPOS (tpos));
3521 else
3522 BYTEPOS (tpos) = CHAR_TO_BYTE (CHARPOS (tpos));
3523 spec = Fget_char_property (pos, Qdisplay, object);
3524 if (!STRINGP (object))
3525 bufpos = CHARPOS (tpos);
3526 } while (NILP (spec)
3527 || !(rv = handle_display_spec (NULL, spec, object, Qnil, &tpos,
3528 bufpos, frame_window_p)));
3529 if (rv == 2)
3530 *disp_prop = 2;
3531
3532 return CHARPOS (tpos);
3533 }
3534
3535 /* Return the character position of the end of the display string that
3536 started at CHARPOS. If there's no display string at CHARPOS,
3537 return -1. A display string is either an overlay with `display'
3538 property whose value is a string or a `display' text property whose
3539 value is a string. */
3540 ptrdiff_t
3541 compute_display_string_end (ptrdiff_t charpos, struct bidi_string_data *string)
3542 {
3543 /* OBJECT = nil means current buffer. */
3544 Lisp_Object object =
3545 (string && STRINGP (string->lstring)) ? string->lstring : Qnil;
3546 Lisp_Object pos = make_number (charpos);
3547 ptrdiff_t eob =
3548 (STRINGP (object) || (string && string->s)) ? string->schars : ZV;
3549
3550 if (charpos >= eob || (string->s && !STRINGP (object)))
3551 return eob;
3552
3553 /* It could happen that the display property or overlay was removed
3554 since we found it in compute_display_string_pos above. One way
3555 this can happen is if JIT font-lock was called (through
3556 handle_fontified_prop), and jit-lock-functions remove text
3557 properties or overlays from the portion of buffer that includes
3558 CHARPOS. Muse mode is known to do that, for example. In this
3559 case, we return -1 to the caller, to signal that no display
3560 string is actually present at CHARPOS. See bidi_fetch_char for
3561 how this is handled.
3562
3563 An alternative would be to never look for display properties past
3564 it->stop_charpos. But neither compute_display_string_pos nor
3565 bidi_fetch_char that calls it know or care where the next
3566 stop_charpos is. */
3567 if (NILP (Fget_char_property (pos, Qdisplay, object)))
3568 return -1;
3569
3570 /* Look forward for the first character where the `display' property
3571 changes. */
3572 pos = Fnext_single_char_property_change (pos, Qdisplay, object, Qnil);
3573
3574 return XFASTINT (pos);
3575 }
3576
3577
3578 \f
3579 /***********************************************************************
3580 Fontification
3581 ***********************************************************************/
3582
3583 /* Handle changes in the `fontified' property of the current buffer by
3584 calling hook functions from Qfontification_functions to fontify
3585 regions of text. */
3586
3587 static enum prop_handled
3588 handle_fontified_prop (struct it *it)
3589 {
3590 Lisp_Object prop, pos;
3591 enum prop_handled handled = HANDLED_NORMALLY;
3592
3593 if (!NILP (Vmemory_full))
3594 return handled;
3595
3596 /* Get the value of the `fontified' property at IT's current buffer
3597 position. (The `fontified' property doesn't have a special
3598 meaning in strings.) If the value is nil, call functions from
3599 Qfontification_functions. */
3600 if (!STRINGP (it->string)
3601 && it->s == NULL
3602 && !NILP (Vfontification_functions)
3603 && !NILP (Vrun_hooks)
3604 && (pos = make_number (IT_CHARPOS (*it)),
3605 prop = Fget_char_property (pos, Qfontified, Qnil),
3606 /* Ignore the special cased nil value always present at EOB since
3607 no amount of fontifying will be able to change it. */
3608 NILP (prop) && IT_CHARPOS (*it) < Z))
3609 {
3610 ptrdiff_t count = SPECPDL_INDEX ();
3611 Lisp_Object val;
3612 struct buffer *obuf = current_buffer;
3613 int begv = BEGV, zv = ZV;
3614 int old_clip_changed = current_buffer->clip_changed;
3615
3616 val = Vfontification_functions;
3617 specbind (Qfontification_functions, Qnil);
3618
3619 eassert (it->end_charpos == ZV);
3620
3621 if (!CONSP (val) || EQ (XCAR (val), Qlambda))
3622 safe_call1 (val, pos);
3623 else
3624 {
3625 Lisp_Object fns, fn;
3626 struct gcpro gcpro1, gcpro2;
3627
3628 fns = Qnil;
3629 GCPRO2 (val, fns);
3630
3631 for (; CONSP (val); val = XCDR (val))
3632 {
3633 fn = XCAR (val);
3634
3635 if (EQ (fn, Qt))
3636 {
3637 /* A value of t indicates this hook has a local
3638 binding; it means to run the global binding too.
3639 In a global value, t should not occur. If it
3640 does, we must ignore it to avoid an endless
3641 loop. */
3642 for (fns = Fdefault_value (Qfontification_functions);
3643 CONSP (fns);
3644 fns = XCDR (fns))
3645 {
3646 fn = XCAR (fns);
3647 if (!EQ (fn, Qt))
3648 safe_call1 (fn, pos);
3649 }
3650 }
3651 else
3652 safe_call1 (fn, pos);
3653 }
3654
3655 UNGCPRO;
3656 }
3657
3658 unbind_to (count, Qnil);
3659
3660 /* Fontification functions routinely call `save-restriction'.
3661 Normally, this tags clip_changed, which can confuse redisplay
3662 (see discussion in Bug#6671). Since we don't perform any
3663 special handling of fontification changes in the case where
3664 `save-restriction' isn't called, there's no point doing so in
3665 this case either. So, if the buffer's restrictions are
3666 actually left unchanged, reset clip_changed. */
3667 if (obuf == current_buffer)
3668 {
3669 if (begv == BEGV && zv == ZV)
3670 current_buffer->clip_changed = old_clip_changed;
3671 }
3672 /* There isn't much we can reasonably do to protect against
3673 misbehaving fontification, but here's a fig leaf. */
3674 else if (!NILP (BVAR (obuf, name)))
3675 set_buffer_internal_1 (obuf);
3676
3677 /* The fontification code may have added/removed text.
3678 It could do even a lot worse, but let's at least protect against
3679 the most obvious case where only the text past `pos' gets changed',
3680 as is/was done in grep.el where some escapes sequences are turned
3681 into face properties (bug#7876). */
3682 it->end_charpos = ZV;
3683
3684 /* Return HANDLED_RECOMPUTE_PROPS only if function fontified
3685 something. This avoids an endless loop if they failed to
3686 fontify the text for which reason ever. */
3687 if (!NILP (Fget_char_property (pos, Qfontified, Qnil)))
3688 handled = HANDLED_RECOMPUTE_PROPS;
3689 }
3690
3691 return handled;
3692 }
3693
3694
3695 \f
3696 /***********************************************************************
3697 Faces
3698 ***********************************************************************/
3699
3700 /* Set up iterator IT from face properties at its current position.
3701 Called from handle_stop. */
3702
3703 static enum prop_handled
3704 handle_face_prop (struct it *it)
3705 {
3706 int new_face_id;
3707 ptrdiff_t next_stop;
3708
3709 if (!STRINGP (it->string))
3710 {
3711 new_face_id
3712 = face_at_buffer_position (it->w,
3713 IT_CHARPOS (*it),
3714 it->region_beg_charpos,
3715 it->region_end_charpos,
3716 &next_stop,
3717 (IT_CHARPOS (*it)
3718 + TEXT_PROP_DISTANCE_LIMIT),
3719 0, it->base_face_id);
3720
3721 /* Is this a start of a run of characters with box face?
3722 Caveat: this can be called for a freshly initialized
3723 iterator; face_id is -1 in this case. We know that the new
3724 face will not change until limit, i.e. if the new face has a
3725 box, all characters up to limit will have one. But, as
3726 usual, we don't know whether limit is really the end. */
3727 if (new_face_id != it->face_id)
3728 {
3729 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
3730
3731 /* If new face has a box but old face has not, this is
3732 the start of a run of characters with box, i.e. it has
3733 a shadow on the left side. The value of face_id of the
3734 iterator will be -1 if this is the initial call that gets
3735 the face. In this case, we have to look in front of IT's
3736 position and see whether there is a face != new_face_id. */
3737 it->start_of_box_run_p
3738 = (new_face->box != FACE_NO_BOX
3739 && (it->face_id >= 0
3740 || IT_CHARPOS (*it) == BEG
3741 || new_face_id != face_before_it_pos (it)));
3742 it->face_box_p = new_face->box != FACE_NO_BOX;
3743 }
3744 }
3745 else
3746 {
3747 int base_face_id;
3748 ptrdiff_t bufpos;
3749 int i;
3750 Lisp_Object from_overlay
3751 = (it->current.overlay_string_index >= 0
3752 ? it->string_overlays[it->current.overlay_string_index
3753 % OVERLAY_STRING_CHUNK_SIZE]
3754 : Qnil);
3755
3756 /* See if we got to this string directly or indirectly from
3757 an overlay property. That includes the before-string or
3758 after-string of an overlay, strings in display properties
3759 provided by an overlay, their text properties, etc.
3760
3761 FROM_OVERLAY is the overlay that brought us here, or nil if none. */
3762 if (! NILP (from_overlay))
3763 for (i = it->sp - 1; i >= 0; i--)
3764 {
3765 if (it->stack[i].current.overlay_string_index >= 0)
3766 from_overlay
3767 = it->string_overlays[it->stack[i].current.overlay_string_index
3768 % OVERLAY_STRING_CHUNK_SIZE];
3769 else if (! NILP (it->stack[i].from_overlay))
3770 from_overlay = it->stack[i].from_overlay;
3771
3772 if (!NILP (from_overlay))
3773 break;
3774 }
3775
3776 if (! NILP (from_overlay))
3777 {
3778 bufpos = IT_CHARPOS (*it);
3779 /* For a string from an overlay, the base face depends
3780 only on text properties and ignores overlays. */
3781 base_face_id
3782 = face_for_overlay_string (it->w,
3783 IT_CHARPOS (*it),
3784 it->region_beg_charpos,
3785 it->region_end_charpos,
3786 &next_stop,
3787 (IT_CHARPOS (*it)
3788 + TEXT_PROP_DISTANCE_LIMIT),
3789 0,
3790 from_overlay);
3791 }
3792 else
3793 {
3794 bufpos = 0;
3795
3796 /* For strings from a `display' property, use the face at
3797 IT's current buffer position as the base face to merge
3798 with, so that overlay strings appear in the same face as
3799 surrounding text, unless they specify their own
3800 faces. */
3801 base_face_id = it->string_from_prefix_prop_p
3802 ? DEFAULT_FACE_ID
3803 : underlying_face_id (it);
3804 }
3805
3806 new_face_id = face_at_string_position (it->w,
3807 it->string,
3808 IT_STRING_CHARPOS (*it),
3809 bufpos,
3810 it->region_beg_charpos,
3811 it->region_end_charpos,
3812 &next_stop,
3813 base_face_id, 0);
3814
3815 /* Is this a start of a run of characters with box? Caveat:
3816 this can be called for a freshly allocated iterator; face_id
3817 is -1 is this case. We know that the new face will not
3818 change until the next check pos, i.e. if the new face has a
3819 box, all characters up to that position will have a
3820 box. But, as usual, we don't know whether that position
3821 is really the end. */
3822 if (new_face_id != it->face_id)
3823 {
3824 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
3825 struct face *old_face = FACE_FROM_ID (it->f, it->face_id);
3826
3827 /* If new face has a box but old face hasn't, this is the
3828 start of a run of characters with box, i.e. it has a
3829 shadow on the left side. */
3830 it->start_of_box_run_p
3831 = new_face->box && (old_face == NULL || !old_face->box);
3832 it->face_box_p = new_face->box != FACE_NO_BOX;
3833 }
3834 }
3835
3836 it->face_id = new_face_id;
3837 return HANDLED_NORMALLY;
3838 }
3839
3840
3841 /* Return the ID of the face ``underlying'' IT's current position,
3842 which is in a string. If the iterator is associated with a
3843 buffer, return the face at IT's current buffer position.
3844 Otherwise, use the iterator's base_face_id. */
3845
3846 static int
3847 underlying_face_id (struct it *it)
3848 {
3849 int face_id = it->base_face_id, i;
3850
3851 eassert (STRINGP (it->string));
3852
3853 for (i = it->sp - 1; i >= 0; --i)
3854 if (NILP (it->stack[i].string))
3855 face_id = it->stack[i].face_id;
3856
3857 return face_id;
3858 }
3859
3860
3861 /* Compute the face one character before or after the current position
3862 of IT, in the visual order. BEFORE_P non-zero means get the face
3863 in front (to the left in L2R paragraphs, to the right in R2L
3864 paragraphs) of IT's screen position. Value is the ID of the face. */
3865
3866 static int
3867 face_before_or_after_it_pos (struct it *it, int before_p)
3868 {
3869 int face_id, limit;
3870 ptrdiff_t next_check_charpos;
3871 struct it it_copy;
3872 void *it_copy_data = NULL;
3873
3874 eassert (it->s == NULL);
3875
3876 if (STRINGP (it->string))
3877 {
3878 ptrdiff_t bufpos, charpos;
3879 int base_face_id;
3880
3881 /* No face change past the end of the string (for the case
3882 we are padding with spaces). No face change before the
3883 string start. */
3884 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string)
3885 || (IT_STRING_CHARPOS (*it) == 0 && before_p))
3886 return it->face_id;
3887
3888 if (!it->bidi_p)
3889 {
3890 /* Set charpos to the position before or after IT's current
3891 position, in the logical order, which in the non-bidi
3892 case is the same as the visual order. */
3893 if (before_p)
3894 charpos = IT_STRING_CHARPOS (*it) - 1;
3895 else if (it->what == IT_COMPOSITION)
3896 /* For composition, we must check the character after the
3897 composition. */
3898 charpos = IT_STRING_CHARPOS (*it) + it->cmp_it.nchars;
3899 else
3900 charpos = IT_STRING_CHARPOS (*it) + 1;
3901 }
3902 else
3903 {
3904 if (before_p)
3905 {
3906 /* With bidi iteration, the character before the current
3907 in the visual order cannot be found by simple
3908 iteration, because "reverse" reordering is not
3909 supported. Instead, we need to use the move_it_*
3910 family of functions. */
3911 /* Ignore face changes before the first visible
3912 character on this display line. */
3913 if (it->current_x <= it->first_visible_x)
3914 return it->face_id;
3915 SAVE_IT (it_copy, *it, it_copy_data);
3916 /* Implementation note: Since move_it_in_display_line
3917 works in the iterator geometry, and thinks the first
3918 character is always the leftmost, even in R2L lines,
3919 we don't need to distinguish between the R2L and L2R
3920 cases here. */
3921 move_it_in_display_line (&it_copy, SCHARS (it_copy.string),
3922 it_copy.current_x - 1, MOVE_TO_X);
3923 charpos = IT_STRING_CHARPOS (it_copy);
3924 RESTORE_IT (it, it, it_copy_data);
3925 }
3926 else
3927 {
3928 /* Set charpos to the string position of the character
3929 that comes after IT's current position in the visual
3930 order. */
3931 int n = (it->what == IT_COMPOSITION ? it->cmp_it.nchars : 1);
3932
3933 it_copy = *it;
3934 while (n--)
3935 bidi_move_to_visually_next (&it_copy.bidi_it);
3936
3937 charpos = it_copy.bidi_it.charpos;
3938 }
3939 }
3940 eassert (0 <= charpos && charpos <= SCHARS (it->string));
3941
3942 if (it->current.overlay_string_index >= 0)
3943 bufpos = IT_CHARPOS (*it);
3944 else
3945 bufpos = 0;
3946
3947 base_face_id = underlying_face_id (it);
3948
3949 /* Get the face for ASCII, or unibyte. */
3950 face_id = face_at_string_position (it->w,
3951 it->string,
3952 charpos,
3953 bufpos,
3954 it->region_beg_charpos,
3955 it->region_end_charpos,
3956 &next_check_charpos,
3957 base_face_id, 0);
3958
3959 /* Correct the face for charsets different from ASCII. Do it
3960 for the multibyte case only. The face returned above is
3961 suitable for unibyte text if IT->string is unibyte. */
3962 if (STRING_MULTIBYTE (it->string))
3963 {
3964 struct text_pos pos1 = string_pos (charpos, it->string);
3965 const unsigned char *p = SDATA (it->string) + BYTEPOS (pos1);
3966 int c, len;
3967 struct face *face = FACE_FROM_ID (it->f, face_id);
3968
3969 c = string_char_and_length (p, &len);
3970 face_id = FACE_FOR_CHAR (it->f, face, c, charpos, it->string);
3971 }
3972 }
3973 else
3974 {
3975 struct text_pos pos;
3976
3977 if ((IT_CHARPOS (*it) >= ZV && !before_p)
3978 || (IT_CHARPOS (*it) <= BEGV && before_p))
3979 return it->face_id;
3980
3981 limit = IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT;
3982 pos = it->current.pos;
3983
3984 if (!it->bidi_p)
3985 {
3986 if (before_p)
3987 DEC_TEXT_POS (pos, it->multibyte_p);
3988 else
3989 {
3990 if (it->what == IT_COMPOSITION)
3991 {
3992 /* For composition, we must check the position after
3993 the composition. */
3994 pos.charpos += it->cmp_it.nchars;
3995 pos.bytepos += it->len;
3996 }
3997 else
3998 INC_TEXT_POS (pos, it->multibyte_p);
3999 }
4000 }
4001 else
4002 {
4003 if (before_p)
4004 {
4005 /* With bidi iteration, the character before the current
4006 in the visual order cannot be found by simple
4007 iteration, because "reverse" reordering is not
4008 supported. Instead, we need to use the move_it_*
4009 family of functions. */
4010 /* Ignore face changes before the first visible
4011 character on this display line. */
4012 if (it->current_x <= it->first_visible_x)
4013 return it->face_id;
4014 SAVE_IT (it_copy, *it, it_copy_data);
4015 /* Implementation note: Since move_it_in_display_line
4016 works in the iterator geometry, and thinks the first
4017 character is always the leftmost, even in R2L lines,
4018 we don't need to distinguish between the R2L and L2R
4019 cases here. */
4020 move_it_in_display_line (&it_copy, ZV,
4021 it_copy.current_x - 1, MOVE_TO_X);
4022 pos = it_copy.current.pos;
4023 RESTORE_IT (it, it, it_copy_data);
4024 }
4025 else
4026 {
4027 /* Set charpos to the buffer position of the character
4028 that comes after IT's current position in the visual
4029 order. */
4030 int n = (it->what == IT_COMPOSITION ? it->cmp_it.nchars : 1);
4031
4032 it_copy = *it;
4033 while (n--)
4034 bidi_move_to_visually_next (&it_copy.bidi_it);
4035
4036 SET_TEXT_POS (pos,
4037 it_copy.bidi_it.charpos, it_copy.bidi_it.bytepos);
4038 }
4039 }
4040 eassert (BEGV <= CHARPOS (pos) && CHARPOS (pos) <= ZV);
4041
4042 /* Determine face for CHARSET_ASCII, or unibyte. */
4043 face_id = face_at_buffer_position (it->w,
4044 CHARPOS (pos),
4045 it->region_beg_charpos,
4046 it->region_end_charpos,
4047 &next_check_charpos,
4048 limit, 0, -1);
4049
4050 /* Correct the face for charsets different from ASCII. Do it
4051 for the multibyte case only. The face returned above is
4052 suitable for unibyte text if current_buffer is unibyte. */
4053 if (it->multibyte_p)
4054 {
4055 int c = FETCH_MULTIBYTE_CHAR (BYTEPOS (pos));
4056 struct face *face = FACE_FROM_ID (it->f, face_id);
4057 face_id = FACE_FOR_CHAR (it->f, face, c, CHARPOS (pos), Qnil);
4058 }
4059 }
4060
4061 return face_id;
4062 }
4063
4064
4065 \f
4066 /***********************************************************************
4067 Invisible text
4068 ***********************************************************************/
4069
4070 /* Set up iterator IT from invisible properties at its current
4071 position. Called from handle_stop. */
4072
4073 static enum prop_handled
4074 handle_invisible_prop (struct it *it)
4075 {
4076 enum prop_handled handled = HANDLED_NORMALLY;
4077 int invis_p;
4078 Lisp_Object prop;
4079
4080 if (STRINGP (it->string))
4081 {
4082 Lisp_Object end_charpos, limit, charpos;
4083
4084 /* Get the value of the invisible text property at the
4085 current position. Value will be nil if there is no such
4086 property. */
4087 charpos = make_number (IT_STRING_CHARPOS (*it));
4088 prop = Fget_text_property (charpos, Qinvisible, it->string);
4089 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
4090
4091 if (invis_p && IT_STRING_CHARPOS (*it) < it->end_charpos)
4092 {
4093 /* Record whether we have to display an ellipsis for the
4094 invisible text. */
4095 int display_ellipsis_p = (invis_p == 2);
4096 ptrdiff_t len, endpos;
4097
4098 handled = HANDLED_RECOMPUTE_PROPS;
4099
4100 /* Get the position at which the next visible text can be
4101 found in IT->string, if any. */
4102 endpos = len = SCHARS (it->string);
4103 XSETINT (limit, len);
4104 do
4105 {
4106 end_charpos = Fnext_single_property_change (charpos, Qinvisible,
4107 it->string, limit);
4108 if (INTEGERP (end_charpos))
4109 {
4110 endpos = XFASTINT (end_charpos);
4111 prop = Fget_text_property (end_charpos, Qinvisible, it->string);
4112 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
4113 if (invis_p == 2)
4114 display_ellipsis_p = 1;
4115 }
4116 }
4117 while (invis_p && endpos < len);
4118
4119 if (display_ellipsis_p)
4120 it->ellipsis_p = 1;
4121
4122 if (endpos < len)
4123 {
4124 /* Text at END_CHARPOS is visible. Move IT there. */
4125 struct text_pos old;
4126 ptrdiff_t oldpos;
4127
4128 old = it->current.string_pos;
4129 oldpos = CHARPOS (old);
4130 if (it->bidi_p)
4131 {
4132 if (it->bidi_it.first_elt
4133 && it->bidi_it.charpos < SCHARS (it->string))
4134 bidi_paragraph_init (it->paragraph_embedding,
4135 &it->bidi_it, 1);
4136 /* Bidi-iterate out of the invisible text. */
4137 do
4138 {
4139 bidi_move_to_visually_next (&it->bidi_it);
4140 }
4141 while (oldpos <= it->bidi_it.charpos
4142 && it->bidi_it.charpos < endpos);
4143
4144 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
4145 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
4146 if (IT_CHARPOS (*it) >= endpos)
4147 it->prev_stop = endpos;
4148 }
4149 else
4150 {
4151 IT_STRING_CHARPOS (*it) = XFASTINT (end_charpos);
4152 compute_string_pos (&it->current.string_pos, old, it->string);
4153 }
4154 }
4155 else
4156 {
4157 /* The rest of the string is invisible. If this is an
4158 overlay string, proceed with the next overlay string
4159 or whatever comes and return a character from there. */
4160 if (it->current.overlay_string_index >= 0
4161 && !display_ellipsis_p)
4162 {
4163 next_overlay_string (it);
4164 /* Don't check for overlay strings when we just
4165 finished processing them. */
4166 handled = HANDLED_OVERLAY_STRING_CONSUMED;
4167 }
4168 else
4169 {
4170 IT_STRING_CHARPOS (*it) = SCHARS (it->string);
4171 IT_STRING_BYTEPOS (*it) = SBYTES (it->string);
4172 }
4173 }
4174 }
4175 }
4176 else
4177 {
4178 ptrdiff_t newpos, next_stop, start_charpos, tem;
4179 Lisp_Object pos, overlay;
4180
4181 /* First of all, is there invisible text at this position? */
4182 tem = start_charpos = IT_CHARPOS (*it);
4183 pos = make_number (tem);
4184 prop = get_char_property_and_overlay (pos, Qinvisible, it->window,
4185 &overlay);
4186 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
4187
4188 /* If we are on invisible text, skip over it. */
4189 if (invis_p && start_charpos < it->end_charpos)
4190 {
4191 /* Record whether we have to display an ellipsis for the
4192 invisible text. */
4193 int display_ellipsis_p = invis_p == 2;
4194
4195 handled = HANDLED_RECOMPUTE_PROPS;
4196
4197 /* Loop skipping over invisible text. The loop is left at
4198 ZV or with IT on the first char being visible again. */
4199 do
4200 {
4201 /* Try to skip some invisible text. Return value is the
4202 position reached which can be equal to where we start
4203 if there is nothing invisible there. This skips both
4204 over invisible text properties and overlays with
4205 invisible property. */
4206 newpos = skip_invisible (tem, &next_stop, ZV, it->window);
4207
4208 /* If we skipped nothing at all we weren't at invisible
4209 text in the first place. If everything to the end of
4210 the buffer was skipped, end the loop. */
4211 if (newpos == tem || newpos >= ZV)
4212 invis_p = 0;
4213 else
4214 {
4215 /* We skipped some characters but not necessarily
4216 all there are. Check if we ended up on visible
4217 text. Fget_char_property returns the property of
4218 the char before the given position, i.e. if we
4219 get invis_p = 0, this means that the char at
4220 newpos is visible. */
4221 pos = make_number (newpos);
4222 prop = Fget_char_property (pos, Qinvisible, it->window);
4223 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
4224 }
4225
4226 /* If we ended up on invisible text, proceed to
4227 skip starting with next_stop. */
4228 if (invis_p)
4229 tem = next_stop;
4230
4231 /* If there are adjacent invisible texts, don't lose the
4232 second one's ellipsis. */
4233 if (invis_p == 2)
4234 display_ellipsis_p = 1;
4235 }
4236 while (invis_p);
4237
4238 /* The position newpos is now either ZV or on visible text. */
4239 if (it->bidi_p)
4240 {
4241 ptrdiff_t bpos = CHAR_TO_BYTE (newpos);
4242 int on_newline =
4243 bpos == ZV_BYTE || FETCH_BYTE (bpos) == '\n';
4244 int after_newline =
4245 newpos <= BEGV || FETCH_BYTE (bpos - 1) == '\n';
4246
4247 /* If the invisible text ends on a newline or on a
4248 character after a newline, we can avoid the costly,
4249 character by character, bidi iteration to NEWPOS, and
4250 instead simply reseat the iterator there. That's
4251 because all bidi reordering information is tossed at
4252 the newline. This is a big win for modes that hide
4253 complete lines, like Outline, Org, etc. */
4254 if (on_newline || after_newline)
4255 {
4256 struct text_pos tpos;
4257 bidi_dir_t pdir = it->bidi_it.paragraph_dir;
4258
4259 SET_TEXT_POS (tpos, newpos, bpos);
4260 reseat_1 (it, tpos, 0);
4261 /* If we reseat on a newline/ZV, we need to prep the
4262 bidi iterator for advancing to the next character
4263 after the newline/EOB, keeping the current paragraph
4264 direction (so that PRODUCE_GLYPHS does TRT wrt
4265 prepending/appending glyphs to a glyph row). */
4266 if (on_newline)
4267 {
4268 it->bidi_it.first_elt = 0;
4269 it->bidi_it.paragraph_dir = pdir;
4270 it->bidi_it.ch = (bpos == ZV_BYTE) ? -1 : '\n';
4271 it->bidi_it.nchars = 1;
4272 it->bidi_it.ch_len = 1;
4273 }
4274 }
4275 else /* Must use the slow method. */
4276 {
4277 /* With bidi iteration, the region of invisible text
4278 could start and/or end in the middle of a
4279 non-base embedding level. Therefore, we need to
4280 skip invisible text using the bidi iterator,
4281 starting at IT's current position, until we find
4282 ourselves outside of the invisible text.
4283 Skipping invisible text _after_ bidi iteration
4284 avoids affecting the visual order of the
4285 displayed text when invisible properties are
4286 added or removed. */
4287 if (it->bidi_it.first_elt && it->bidi_it.charpos < ZV)
4288 {
4289 /* If we were `reseat'ed to a new paragraph,
4290 determine the paragraph base direction. We
4291 need to do it now because
4292 next_element_from_buffer may not have a
4293 chance to do it, if we are going to skip any
4294 text at the beginning, which resets the
4295 FIRST_ELT flag. */
4296 bidi_paragraph_init (it->paragraph_embedding,
4297 &it->bidi_it, 1);
4298 }
4299 do
4300 {
4301 bidi_move_to_visually_next (&it->bidi_it);
4302 }
4303 while (it->stop_charpos <= it->bidi_it.charpos
4304 && it->bidi_it.charpos < newpos);
4305 IT_CHARPOS (*it) = it->bidi_it.charpos;
4306 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
4307 /* If we overstepped NEWPOS, record its position in
4308 the iterator, so that we skip invisible text if
4309 later the bidi iteration lands us in the
4310 invisible region again. */
4311 if (IT_CHARPOS (*it) >= newpos)
4312 it->prev_stop = newpos;
4313 }
4314 }
4315 else
4316 {
4317 IT_CHARPOS (*it) = newpos;
4318 IT_BYTEPOS (*it) = CHAR_TO_BYTE (newpos);
4319 }
4320
4321 /* If there are before-strings at the start of invisible
4322 text, and the text is invisible because of a text
4323 property, arrange to show before-strings because 20.x did
4324 it that way. (If the text is invisible because of an
4325 overlay property instead of a text property, this is
4326 already handled in the overlay code.) */
4327 if (NILP (overlay)
4328 && get_overlay_strings (it, it->stop_charpos))
4329 {
4330 handled = HANDLED_RECOMPUTE_PROPS;
4331 it->stack[it->sp - 1].display_ellipsis_p = display_ellipsis_p;
4332 }
4333 else if (display_ellipsis_p)
4334 {
4335 /* Make sure that the glyphs of the ellipsis will get
4336 correct `charpos' values. If we would not update
4337 it->position here, the glyphs would belong to the
4338 last visible character _before_ the invisible
4339 text, which confuses `set_cursor_from_row'.
4340
4341 We use the last invisible position instead of the
4342 first because this way the cursor is always drawn on
4343 the first "." of the ellipsis, whenever PT is inside
4344 the invisible text. Otherwise the cursor would be
4345 placed _after_ the ellipsis when the point is after the
4346 first invisible character. */
4347 if (!STRINGP (it->object))
4348 {
4349 it->position.charpos = newpos - 1;
4350 it->position.bytepos = CHAR_TO_BYTE (it->position.charpos);
4351 }
4352 it->ellipsis_p = 1;
4353 /* Let the ellipsis display before
4354 considering any properties of the following char.
4355 Fixes jasonr@gnu.org 01 Oct 07 bug. */
4356 handled = HANDLED_RETURN;
4357 }
4358 }
4359 }
4360
4361 return handled;
4362 }
4363
4364
4365 /* Make iterator IT return `...' next.
4366 Replaces LEN characters from buffer. */
4367
4368 static void
4369 setup_for_ellipsis (struct it *it, int len)
4370 {
4371 /* Use the display table definition for `...'. Invalid glyphs
4372 will be handled by the method returning elements from dpvec. */
4373 if (it->dp && VECTORP (DISP_INVIS_VECTOR (it->dp)))
4374 {
4375 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
4376 it->dpvec = v->contents;
4377 it->dpend = v->contents + v->header.size;
4378 }
4379 else
4380 {
4381 /* Default `...'. */
4382 it->dpvec = default_invis_vector;
4383 it->dpend = default_invis_vector + 3;
4384 }
4385
4386 it->dpvec_char_len = len;
4387 it->current.dpvec_index = 0;
4388 it->dpvec_face_id = -1;
4389
4390 /* Remember the current face id in case glyphs specify faces.
4391 IT's face is restored in set_iterator_to_next.
4392 saved_face_id was set to preceding char's face in handle_stop. */
4393 if (it->saved_face_id < 0 || it->saved_face_id != it->face_id)
4394 it->saved_face_id = it->face_id = DEFAULT_FACE_ID;
4395
4396 it->method = GET_FROM_DISPLAY_VECTOR;
4397 it->ellipsis_p = 1;
4398 }
4399
4400
4401 \f
4402 /***********************************************************************
4403 'display' property
4404 ***********************************************************************/
4405
4406 /* Set up iterator IT from `display' property at its current position.
4407 Called from handle_stop.
4408 We return HANDLED_RETURN if some part of the display property
4409 overrides the display of the buffer text itself.
4410 Otherwise we return HANDLED_NORMALLY. */
4411
4412 static enum prop_handled
4413 handle_display_prop (struct it *it)
4414 {
4415 Lisp_Object propval, object, overlay;
4416 struct text_pos *position;
4417 ptrdiff_t bufpos;
4418 /* Nonzero if some property replaces the display of the text itself. */
4419 int display_replaced_p = 0;
4420
4421 if (STRINGP (it->string))
4422 {
4423 object = it->string;
4424 position = &it->current.string_pos;
4425 bufpos = CHARPOS (it->current.pos);
4426 }
4427 else
4428 {
4429 XSETWINDOW (object, it->w);
4430 position = &it->current.pos;
4431 bufpos = CHARPOS (*position);
4432 }
4433
4434 /* Reset those iterator values set from display property values. */
4435 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
4436 it->space_width = Qnil;
4437 it->font_height = Qnil;
4438 it->voffset = 0;
4439
4440 /* We don't support recursive `display' properties, i.e. string
4441 values that have a string `display' property, that have a string
4442 `display' property etc. */
4443 if (!it->string_from_display_prop_p)
4444 it->area = TEXT_AREA;
4445
4446 propval = get_char_property_and_overlay (make_number (position->charpos),
4447 Qdisplay, object, &overlay);
4448 if (NILP (propval))
4449 return HANDLED_NORMALLY;
4450 /* Now OVERLAY is the overlay that gave us this property, or nil
4451 if it was a text property. */
4452
4453 if (!STRINGP (it->string))
4454 object = it->w->buffer;
4455
4456 display_replaced_p = handle_display_spec (it, propval, object, overlay,
4457 position, bufpos,
4458 FRAME_WINDOW_P (it->f));
4459
4460 return display_replaced_p ? HANDLED_RETURN : HANDLED_NORMALLY;
4461 }
4462
4463 /* Subroutine of handle_display_prop. Returns non-zero if the display
4464 specification in SPEC is a replacing specification, i.e. it would
4465 replace the text covered by `display' property with something else,
4466 such as an image or a display string. If SPEC includes any kind or
4467 `(space ...) specification, the value is 2; this is used by
4468 compute_display_string_pos, which see.
4469
4470 See handle_single_display_spec for documentation of arguments.
4471 frame_window_p is non-zero if the window being redisplayed is on a
4472 GUI frame; this argument is used only if IT is NULL, see below.
4473
4474 IT can be NULL, if this is called by the bidi reordering code
4475 through compute_display_string_pos, which see. In that case, this
4476 function only examines SPEC, but does not otherwise "handle" it, in
4477 the sense that it doesn't set up members of IT from the display
4478 spec. */
4479 static int
4480 handle_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
4481 Lisp_Object overlay, struct text_pos *position,
4482 ptrdiff_t bufpos, int frame_window_p)
4483 {
4484 int replacing_p = 0;
4485 int rv;
4486
4487 if (CONSP (spec)
4488 /* Simple specifications. */
4489 && !EQ (XCAR (spec), Qimage)
4490 #ifdef HAVE_XWIDGETS
4491 && !EQ (XCAR (spec), Qxwidget)
4492 #endif
4493 && !EQ (XCAR (spec), Qspace)
4494 && !EQ (XCAR (spec), Qwhen)
4495 && !EQ (XCAR (spec), Qslice)
4496 && !EQ (XCAR (spec), Qspace_width)
4497 && !EQ (XCAR (spec), Qheight)
4498 && !EQ (XCAR (spec), Qraise)
4499 /* Marginal area specifications. */
4500 && !(CONSP (XCAR (spec)) && EQ (XCAR (XCAR (spec)), Qmargin))
4501 && !EQ (XCAR (spec), Qleft_fringe)
4502 && !EQ (XCAR (spec), Qright_fringe)
4503 && !NILP (XCAR (spec)))
4504 {
4505 for (; CONSP (spec); spec = XCDR (spec))
4506 {
4507 if ((rv = handle_single_display_spec (it, XCAR (spec), object,
4508 overlay, position, bufpos,
4509 replacing_p, frame_window_p)))
4510 {
4511 replacing_p = rv;
4512 /* If some text in a string is replaced, `position' no
4513 longer points to the position of `object'. */
4514 if (!it || STRINGP (object))
4515 break;
4516 }
4517 }
4518 }
4519 else if (VECTORP (spec))
4520 {
4521 ptrdiff_t i;
4522 for (i = 0; i < ASIZE (spec); ++i)
4523 if ((rv = handle_single_display_spec (it, AREF (spec, i), object,
4524 overlay, position, bufpos,
4525 replacing_p, frame_window_p)))
4526 {
4527 replacing_p = rv;
4528 /* If some text in a string is replaced, `position' no
4529 longer points to the position of `object'. */
4530 if (!it || STRINGP (object))
4531 break;
4532 }
4533 }
4534 else
4535 {
4536 if ((rv = handle_single_display_spec (it, spec, object, overlay,
4537 position, bufpos, 0,
4538 frame_window_p)))
4539 replacing_p = rv;
4540 }
4541
4542 return replacing_p;
4543 }
4544
4545 /* Value is the position of the end of the `display' property starting
4546 at START_POS in OBJECT. */
4547
4548 static struct text_pos
4549 display_prop_end (struct it *it, Lisp_Object object, struct text_pos start_pos)
4550 {
4551 Lisp_Object end;
4552 struct text_pos end_pos;
4553
4554 end = Fnext_single_char_property_change (make_number (CHARPOS (start_pos)),
4555 Qdisplay, object, Qnil);
4556 CHARPOS (end_pos) = XFASTINT (end);
4557 if (STRINGP (object))
4558 compute_string_pos (&end_pos, start_pos, it->string);
4559 else
4560 BYTEPOS (end_pos) = CHAR_TO_BYTE (XFASTINT (end));
4561
4562 return end_pos;
4563 }
4564
4565
4566 /* Set up IT from a single `display' property specification SPEC. OBJECT
4567 is the object in which the `display' property was found. *POSITION
4568 is the position in OBJECT at which the `display' property was found.
4569 BUFPOS is the buffer position of OBJECT (different from POSITION if
4570 OBJECT is not a buffer). DISPLAY_REPLACED_P non-zero means that we
4571 previously saw a display specification which already replaced text
4572 display with something else, for example an image; we ignore such
4573 properties after the first one has been processed.
4574
4575 OVERLAY is the overlay this `display' property came from,
4576 or nil if it was a text property.
4577
4578 If SPEC is a `space' or `image' specification, and in some other
4579 cases too, set *POSITION to the position where the `display'
4580 property ends.
4581
4582 If IT is NULL, only examine the property specification in SPEC, but
4583 don't set up IT. In that case, FRAME_WINDOW_P non-zero means SPEC
4584 is intended to be displayed in a window on a GUI frame.
4585
4586 Value is non-zero if something was found which replaces the display
4587 of buffer or string text. */
4588
4589 static int
4590 handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
4591 Lisp_Object overlay, struct text_pos *position,
4592 ptrdiff_t bufpos, int display_replaced_p,
4593 int frame_window_p)
4594 {
4595 Lisp_Object form;
4596 Lisp_Object location, value;
4597 struct text_pos start_pos = *position;
4598 int valid_p;
4599
4600 /* If SPEC is a list of the form `(when FORM . VALUE)', evaluate FORM.
4601 If the result is non-nil, use VALUE instead of SPEC. */
4602 form = Qt;
4603 if (CONSP (spec) && EQ (XCAR (spec), Qwhen))
4604 {
4605 spec = XCDR (spec);
4606 if (!CONSP (spec))
4607 return 0;
4608 form = XCAR (spec);
4609 spec = XCDR (spec);
4610 }
4611
4612 if (!NILP (form) && !EQ (form, Qt))
4613 {
4614 ptrdiff_t count = SPECPDL_INDEX ();
4615 struct gcpro gcpro1;
4616
4617 /* Bind `object' to the object having the `display' property, a
4618 buffer or string. Bind `position' to the position in the
4619 object where the property was found, and `buffer-position'
4620 to the current position in the buffer. */
4621
4622 if (NILP (object))
4623 XSETBUFFER (object, current_buffer);
4624 specbind (Qobject, object);
4625 specbind (Qposition, make_number (CHARPOS (*position)));
4626 specbind (Qbuffer_position, make_number (bufpos));
4627 GCPRO1 (form);
4628 form = safe_eval (form);
4629 UNGCPRO;
4630 unbind_to (count, Qnil);
4631 }
4632
4633 if (NILP (form))
4634 return 0;
4635
4636 /* Handle `(height HEIGHT)' specifications. */
4637 if (CONSP (spec)
4638 && EQ (XCAR (spec), Qheight)
4639 && CONSP (XCDR (spec)))
4640 {
4641 if (it)
4642 {
4643 if (!FRAME_WINDOW_P (it->f))
4644 return 0;
4645
4646 it->font_height = XCAR (XCDR (spec));
4647 if (!NILP (it->font_height))
4648 {
4649 struct face *face = FACE_FROM_ID (it->f, it->face_id);
4650 int new_height = -1;
4651
4652 if (CONSP (it->font_height)
4653 && (EQ (XCAR (it->font_height), Qplus)
4654 || EQ (XCAR (it->font_height), Qminus))
4655 && CONSP (XCDR (it->font_height))
4656 && RANGED_INTEGERP (0, XCAR (XCDR (it->font_height)), INT_MAX))
4657 {
4658 /* `(+ N)' or `(- N)' where N is an integer. */
4659 int steps = XINT (XCAR (XCDR (it->font_height)));
4660 if (EQ (XCAR (it->font_height), Qplus))
4661 steps = - steps;
4662 it->face_id = smaller_face (it->f, it->face_id, steps);
4663 }
4664 else if (FUNCTIONP (it->font_height))
4665 {
4666 /* Call function with current height as argument.
4667 Value is the new height. */
4668 Lisp_Object height;
4669 height = safe_call1 (it->font_height,
4670 face->lface[LFACE_HEIGHT_INDEX]);
4671 if (NUMBERP (height))
4672 new_height = XFLOATINT (height);
4673 }
4674 else if (NUMBERP (it->font_height))
4675 {
4676 /* Value is a multiple of the canonical char height. */
4677 struct face *f;
4678
4679 f = FACE_FROM_ID (it->f,
4680 lookup_basic_face (it->f, DEFAULT_FACE_ID));
4681 new_height = (XFLOATINT (it->font_height)
4682 * XINT (f->lface[LFACE_HEIGHT_INDEX]));
4683 }
4684 else
4685 {
4686 /* Evaluate IT->font_height with `height' bound to the
4687 current specified height to get the new height. */
4688 ptrdiff_t count = SPECPDL_INDEX ();
4689
4690 specbind (Qheight, face->lface[LFACE_HEIGHT_INDEX]);
4691 value = safe_eval (it->font_height);
4692 unbind_to (count, Qnil);
4693
4694 if (NUMBERP (value))
4695 new_height = XFLOATINT (value);
4696 }
4697
4698 if (new_height > 0)
4699 it->face_id = face_with_height (it->f, it->face_id, new_height);
4700 }
4701 }
4702
4703 return 0;
4704 }
4705
4706 /* Handle `(space-width WIDTH)'. */
4707 if (CONSP (spec)
4708 && EQ (XCAR (spec), Qspace_width)
4709 && CONSP (XCDR (spec)))
4710 {
4711 if (it)
4712 {
4713 if (!FRAME_WINDOW_P (it->f))
4714 return 0;
4715
4716 value = XCAR (XCDR (spec));
4717 if (NUMBERP (value) && XFLOATINT (value) > 0)
4718 it->space_width = value;
4719 }
4720
4721 return 0;
4722 }
4723
4724 /* Handle `(slice X Y WIDTH HEIGHT)'. */
4725 if (CONSP (spec)
4726 && EQ (XCAR (spec), Qslice))
4727 {
4728 Lisp_Object tem;
4729
4730 if (it)
4731 {
4732 if (!FRAME_WINDOW_P (it->f))
4733 return 0;
4734
4735 if (tem = XCDR (spec), CONSP (tem))
4736 {
4737 it->slice.x = XCAR (tem);
4738 if (tem = XCDR (tem), CONSP (tem))
4739 {
4740 it->slice.y = XCAR (tem);
4741 if (tem = XCDR (tem), CONSP (tem))
4742 {
4743 it->slice.width = XCAR (tem);
4744 if (tem = XCDR (tem), CONSP (tem))
4745 it->slice.height = XCAR (tem);
4746 }
4747 }
4748 }
4749 }
4750
4751 return 0;
4752 }
4753
4754 /* Handle `(raise FACTOR)'. */
4755 if (CONSP (spec)
4756 && EQ (XCAR (spec), Qraise)
4757 && CONSP (XCDR (spec)))
4758 {
4759 if (it)
4760 {
4761 if (!FRAME_WINDOW_P (it->f))
4762 return 0;
4763
4764 #ifdef HAVE_WINDOW_SYSTEM
4765 value = XCAR (XCDR (spec));
4766 if (NUMBERP (value))
4767 {
4768 struct face *face = FACE_FROM_ID (it->f, it->face_id);
4769 it->voffset = - (XFLOATINT (value)
4770 * (FONT_HEIGHT (face->font)));
4771 }
4772 #endif /* HAVE_WINDOW_SYSTEM */
4773 }
4774
4775 return 0;
4776 }
4777
4778 /* Don't handle the other kinds of display specifications
4779 inside a string that we got from a `display' property. */
4780 if (it && it->string_from_display_prop_p)
4781 return 0;
4782
4783 /* Characters having this form of property are not displayed, so
4784 we have to find the end of the property. */
4785 if (it)
4786 {
4787 start_pos = *position;
4788 *position = display_prop_end (it, object, start_pos);
4789 }
4790 value = Qnil;
4791
4792 /* Stop the scan at that end position--we assume that all
4793 text properties change there. */
4794 if (it)
4795 it->stop_charpos = position->charpos;
4796
4797 /* Handle `(left-fringe BITMAP [FACE])'
4798 and `(right-fringe BITMAP [FACE])'. */
4799 if (CONSP (spec)
4800 && (EQ (XCAR (spec), Qleft_fringe)
4801 || EQ (XCAR (spec), Qright_fringe))
4802 && CONSP (XCDR (spec)))
4803 {
4804 int fringe_bitmap;
4805
4806 if (it)
4807 {
4808 if (!FRAME_WINDOW_P (it->f))
4809 /* If we return here, POSITION has been advanced
4810 across the text with this property. */
4811 {
4812 /* Synchronize the bidi iterator with POSITION. This is
4813 needed because we are not going to push the iterator
4814 on behalf of this display property, so there will be
4815 no pop_it call to do this synchronization for us. */
4816 if (it->bidi_p)
4817 {
4818 it->position = *position;
4819 iterate_out_of_display_property (it);
4820 *position = it->position;
4821 }
4822 return 1;
4823 }
4824 }
4825 else if (!frame_window_p)
4826 return 1;
4827
4828 #ifdef HAVE_WINDOW_SYSTEM
4829 value = XCAR (XCDR (spec));
4830 if (!SYMBOLP (value)
4831 || !(fringe_bitmap = lookup_fringe_bitmap (value)))
4832 /* If we return here, POSITION has been advanced
4833 across the text with this property. */
4834 {
4835 if (it && it->bidi_p)
4836 {
4837 it->position = *position;
4838 iterate_out_of_display_property (it);
4839 *position = it->position;
4840 }
4841 return 1;
4842 }
4843
4844 if (it)
4845 {
4846 int face_id = lookup_basic_face (it->f, DEFAULT_FACE_ID);;
4847
4848 if (CONSP (XCDR (XCDR (spec))))
4849 {
4850 Lisp_Object face_name = XCAR (XCDR (XCDR (spec)));
4851 int face_id2 = lookup_derived_face (it->f, face_name,
4852 FRINGE_FACE_ID, 0);
4853 if (face_id2 >= 0)
4854 face_id = face_id2;
4855 }
4856
4857 /* Save current settings of IT so that we can restore them
4858 when we are finished with the glyph property value. */
4859 push_it (it, position);
4860
4861 it->area = TEXT_AREA;
4862 it->what = IT_IMAGE;
4863 it->image_id = -1; /* no image */
4864 it->position = start_pos;
4865 it->object = NILP (object) ? it->w->buffer : object;
4866 it->method = GET_FROM_IMAGE;
4867 it->from_overlay = Qnil;
4868 it->face_id = face_id;
4869 it->from_disp_prop_p = 1;
4870
4871 /* Say that we haven't consumed the characters with
4872 `display' property yet. The call to pop_it in
4873 set_iterator_to_next will clean this up. */
4874 *position = start_pos;
4875
4876 if (EQ (XCAR (spec), Qleft_fringe))
4877 {
4878 it->left_user_fringe_bitmap = fringe_bitmap;
4879 it->left_user_fringe_face_id = face_id;
4880 }
4881 else
4882 {
4883 it->right_user_fringe_bitmap = fringe_bitmap;
4884 it->right_user_fringe_face_id = face_id;
4885 }
4886 }
4887 #endif /* HAVE_WINDOW_SYSTEM */
4888 return 1;
4889 }
4890
4891 /* Prepare to handle `((margin left-margin) ...)',
4892 `((margin right-margin) ...)' and `((margin nil) ...)'
4893 prefixes for display specifications. */
4894 location = Qunbound;
4895 if (CONSP (spec) && CONSP (XCAR (spec)))
4896 {
4897 Lisp_Object tem;
4898
4899 value = XCDR (spec);
4900 if (CONSP (value))
4901 value = XCAR (value);
4902
4903 tem = XCAR (spec);
4904 if (EQ (XCAR (tem), Qmargin)
4905 && (tem = XCDR (tem),
4906 tem = CONSP (tem) ? XCAR (tem) : Qnil,
4907 (NILP (tem)
4908 || EQ (tem, Qleft_margin)
4909 || EQ (tem, Qright_margin))))
4910 location = tem;
4911 }
4912
4913 if (EQ (location, Qunbound))
4914 {
4915 location = Qnil;
4916 value = spec;
4917 }
4918
4919 /* After this point, VALUE is the property after any
4920 margin prefix has been stripped. It must be a string,
4921 an image specification, or `(space ...)'.
4922
4923 LOCATION specifies where to display: `left-margin',
4924 `right-margin' or nil. */
4925
4926 valid_p = (STRINGP (value)
4927 #ifdef HAVE_WINDOW_SYSTEM
4928 || ((it ? FRAME_WINDOW_P (it->f) : frame_window_p)
4929 && valid_image_p (value))
4930 #endif /* not HAVE_WINDOW_SYSTEM */
4931 || (CONSP (value) && EQ (XCAR (value), Qspace))
4932 #ifdef HAVE_XWIDGETS
4933 || XWIDGETP(value)
4934 #endif
4935 );
4936
4937 if (valid_p && !display_replaced_p)
4938 {
4939 int retval = 1;
4940
4941 if (!it)
4942 {
4943 /* Callers need to know whether the display spec is any kind
4944 of `(space ...)' spec that is about to affect text-area
4945 display. */
4946 if (CONSP (value) && EQ (XCAR (value), Qspace) && NILP (location))
4947 retval = 2;
4948 return retval;
4949 }
4950
4951 /* Save current settings of IT so that we can restore them
4952 when we are finished with the glyph property value. */
4953 push_it (it, position);
4954 it->from_overlay = overlay;
4955 it->from_disp_prop_p = 1;
4956
4957 if (NILP (location))
4958 it->area = TEXT_AREA;
4959 else if (EQ (location, Qleft_margin))
4960 it->area = LEFT_MARGIN_AREA;
4961 else
4962 it->area = RIGHT_MARGIN_AREA;
4963
4964 if (STRINGP (value))
4965 {
4966 it->string = value;
4967 it->multibyte_p = STRING_MULTIBYTE (it->string);
4968 it->current.overlay_string_index = -1;
4969 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
4970 it->end_charpos = it->string_nchars = SCHARS (it->string);
4971 it->method = GET_FROM_STRING;
4972 it->stop_charpos = 0;
4973 it->prev_stop = 0;
4974 it->base_level_stop = 0;
4975 it->string_from_display_prop_p = 1;
4976 /* Say that we haven't consumed the characters with
4977 `display' property yet. The call to pop_it in
4978 set_iterator_to_next will clean this up. */
4979 if (BUFFERP (object))
4980 *position = start_pos;
4981
4982 /* Force paragraph direction to be that of the parent
4983 object. If the parent object's paragraph direction is
4984 not yet determined, default to L2R. */
4985 if (it->bidi_p && it->bidi_it.paragraph_dir == R2L)
4986 it->paragraph_embedding = it->bidi_it.paragraph_dir;
4987 else
4988 it->paragraph_embedding = L2R;
4989
4990 /* Set up the bidi iterator for this display string. */
4991 if (it->bidi_p)
4992 {
4993 it->bidi_it.string.lstring = it->string;
4994 it->bidi_it.string.s = NULL;
4995 it->bidi_it.string.schars = it->end_charpos;
4996 it->bidi_it.string.bufpos = bufpos;
4997 it->bidi_it.string.from_disp_str = 1;
4998 it->bidi_it.string.unibyte = !it->multibyte_p;
4999 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
5000 }
5001 }
5002 else if (CONSP (value) && EQ (XCAR (value), Qspace))
5003 {
5004 it->method = GET_FROM_STRETCH;
5005 it->object = value;
5006 *position = it->position = start_pos;
5007 retval = 1 + (it->area == TEXT_AREA);
5008 }
5009 #ifdef HAVE_XWIDGETS
5010 else if (XWIDGETP(value))
5011 {
5012 //printf("handle_single_display_spec: im an xwidget!!\n");
5013 it->what = IT_XWIDGET;
5014 it->method = GET_FROM_XWIDGET;
5015 it->position = start_pos;
5016 it->object = NILP (object) ? it->w->buffer : object;
5017 *position = start_pos;
5018
5019 it->xwidget = lookup_xwidget(value);
5020 }
5021 #endif
5022 #ifdef HAVE_WINDOW_SYSTEM
5023 else
5024 {
5025 it->what = IT_IMAGE;
5026 it->image_id = lookup_image (it->f, value);
5027 it->position = start_pos;
5028 it->object = NILP (object) ? it->w->buffer : object;
5029 it->method = GET_FROM_IMAGE;
5030
5031 /* Say that we haven't consumed the characters with
5032 `display' property yet. The call to pop_it in
5033 set_iterator_to_next will clean this up. */
5034 *position = start_pos;
5035 }
5036 #endif /* HAVE_WINDOW_SYSTEM */
5037
5038 return retval;
5039 }
5040
5041 /* Invalid property or property not supported. Restore
5042 POSITION to what it was before. */
5043 *position = start_pos;
5044 return 0;
5045 }
5046
5047 /* Check if PROP is a display property value whose text should be
5048 treated as intangible. OVERLAY is the overlay from which PROP
5049 came, or nil if it came from a text property. CHARPOS and BYTEPOS
5050 specify the buffer position covered by PROP. */
5051
5052 int
5053 display_prop_intangible_p (Lisp_Object prop, Lisp_Object overlay,
5054 ptrdiff_t charpos, ptrdiff_t bytepos)
5055 {
5056 int frame_window_p = FRAME_WINDOW_P (XFRAME (selected_frame));
5057 struct text_pos position;
5058
5059 SET_TEXT_POS (position, charpos, bytepos);
5060 return handle_display_spec (NULL, prop, Qnil, overlay,
5061 &position, charpos, frame_window_p);
5062 }
5063
5064
5065 /* Return 1 if PROP is a display sub-property value containing STRING.
5066
5067 Implementation note: this and the following function are really
5068 special cases of handle_display_spec and
5069 handle_single_display_spec, and should ideally use the same code.
5070 Until they do, these two pairs must be consistent and must be
5071 modified in sync. */
5072
5073 static int
5074 single_display_spec_string_p (Lisp_Object prop, Lisp_Object string)
5075 {
5076 if (EQ (string, prop))
5077 return 1;
5078
5079 /* Skip over `when FORM'. */
5080 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
5081 {
5082 prop = XCDR (prop);
5083 if (!CONSP (prop))
5084 return 0;
5085 /* Actually, the condition following `when' should be eval'ed,
5086 like handle_single_display_spec does, and we should return
5087 zero if it evaluates to nil. However, this function is
5088 called only when the buffer was already displayed and some
5089 glyph in the glyph matrix was found to come from a display
5090 string. Therefore, the condition was already evaluated, and
5091 the result was non-nil, otherwise the display string wouldn't
5092 have been displayed and we would have never been called for
5093 this property. Thus, we can skip the evaluation and assume
5094 its result is non-nil. */
5095 prop = XCDR (prop);
5096 }
5097
5098 if (CONSP (prop))
5099 /* Skip over `margin LOCATION'. */
5100 if (EQ (XCAR (prop), Qmargin))
5101 {
5102 prop = XCDR (prop);
5103 if (!CONSP (prop))
5104 return 0;
5105
5106 prop = XCDR (prop);
5107 if (!CONSP (prop))
5108 return 0;
5109 }
5110
5111 return EQ (prop, string) || (CONSP (prop) && EQ (XCAR (prop), string));
5112 }
5113
5114
5115 /* Return 1 if STRING appears in the `display' property PROP. */
5116
5117 static int
5118 display_prop_string_p (Lisp_Object prop, Lisp_Object string)
5119 {
5120 if (CONSP (prop)
5121 && !EQ (XCAR (prop), Qwhen)
5122 && !(CONSP (XCAR (prop)) && EQ (Qmargin, XCAR (XCAR (prop)))))
5123 {
5124 /* A list of sub-properties. */
5125 while (CONSP (prop))
5126 {
5127 if (single_display_spec_string_p (XCAR (prop), string))
5128 return 1;
5129 prop = XCDR (prop);
5130 }
5131 }
5132 else if (VECTORP (prop))
5133 {
5134 /* A vector of sub-properties. */
5135 ptrdiff_t i;
5136 for (i = 0; i < ASIZE (prop); ++i)
5137 if (single_display_spec_string_p (AREF (prop, i), string))
5138 return 1;
5139 }
5140 else
5141 return single_display_spec_string_p (prop, string);
5142
5143 return 0;
5144 }
5145
5146 /* Look for STRING in overlays and text properties in the current
5147 buffer, between character positions FROM and TO (excluding TO).
5148 BACK_P non-zero means look back (in this case, TO is supposed to be
5149 less than FROM).
5150 Value is the first character position where STRING was found, or
5151 zero if it wasn't found before hitting TO.
5152
5153 This function may only use code that doesn't eval because it is
5154 called asynchronously from note_mouse_highlight. */
5155
5156 static ptrdiff_t
5157 string_buffer_position_lim (Lisp_Object string,
5158 ptrdiff_t from, ptrdiff_t to, int back_p)
5159 {
5160 Lisp_Object limit, prop, pos;
5161 int found = 0;
5162
5163 pos = make_number (max (from, BEGV));
5164
5165 if (!back_p) /* looking forward */
5166 {
5167 limit = make_number (min (to, ZV));
5168 while (!found && !EQ (pos, limit))
5169 {
5170 prop = Fget_char_property (pos, Qdisplay, Qnil);
5171 if (!NILP (prop) && display_prop_string_p (prop, string))
5172 found = 1;
5173 else
5174 pos = Fnext_single_char_property_change (pos, Qdisplay, Qnil,
5175 limit);
5176 }
5177 }
5178 else /* looking back */
5179 {
5180 limit = make_number (max (to, BEGV));
5181 while (!found && !EQ (pos, limit))
5182 {
5183 prop = Fget_char_property (pos, Qdisplay, Qnil);
5184 if (!NILP (prop) && display_prop_string_p (prop, string))
5185 found = 1;
5186 else
5187 pos = Fprevious_single_char_property_change (pos, Qdisplay, Qnil,
5188 limit);
5189 }
5190 }
5191
5192 return found ? XINT (pos) : 0;
5193 }
5194
5195 /* Determine which buffer position in current buffer STRING comes from.
5196 AROUND_CHARPOS is an approximate position where it could come from.
5197 Value is the buffer position or 0 if it couldn't be determined.
5198
5199 This function is necessary because we don't record buffer positions
5200 in glyphs generated from strings (to keep struct glyph small).
5201 This function may only use code that doesn't eval because it is
5202 called asynchronously from note_mouse_highlight. */
5203
5204 static ptrdiff_t
5205 string_buffer_position (Lisp_Object string, ptrdiff_t around_charpos)
5206 {
5207 const int MAX_DISTANCE = 1000;
5208 ptrdiff_t found = string_buffer_position_lim (string, around_charpos,
5209 around_charpos + MAX_DISTANCE,
5210 0);
5211
5212 if (!found)
5213 found = string_buffer_position_lim (string, around_charpos,
5214 around_charpos - MAX_DISTANCE, 1);
5215 return found;
5216 }
5217
5218
5219 \f
5220 /***********************************************************************
5221 `composition' property
5222 ***********************************************************************/
5223
5224 /* Set up iterator IT from `composition' property at its current
5225 position. Called from handle_stop. */
5226
5227 static enum prop_handled
5228 handle_composition_prop (struct it *it)
5229 {
5230 Lisp_Object prop, string;
5231 ptrdiff_t pos, pos_byte, start, end;
5232
5233 if (STRINGP (it->string))
5234 {
5235 unsigned char *s;
5236
5237 pos = IT_STRING_CHARPOS (*it);
5238 pos_byte = IT_STRING_BYTEPOS (*it);
5239 string = it->string;
5240 s = SDATA (string) + pos_byte;
5241 it->c = STRING_CHAR (s);
5242 }
5243 else
5244 {
5245 pos = IT_CHARPOS (*it);
5246 pos_byte = IT_BYTEPOS (*it);
5247 string = Qnil;
5248 it->c = FETCH_CHAR (pos_byte);
5249 }
5250
5251 /* If there's a valid composition and point is not inside of the
5252 composition (in the case that the composition is from the current
5253 buffer), draw a glyph composed from the composition components. */
5254 if (find_composition (pos, -1, &start, &end, &prop, string)
5255 && COMPOSITION_VALID_P (start, end, prop)
5256 && (STRINGP (it->string) || (PT <= start || PT >= end)))
5257 {
5258 if (start < pos)
5259 /* As we can't handle this situation (perhaps font-lock added
5260 a new composition), we just return here hoping that next
5261 redisplay will detect this composition much earlier. */
5262 return HANDLED_NORMALLY;
5263 if (start != pos)
5264 {
5265 if (STRINGP (it->string))
5266 pos_byte = string_char_to_byte (it->string, start);
5267 else
5268 pos_byte = CHAR_TO_BYTE (start);
5269 }
5270 it->cmp_it.id = get_composition_id (start, pos_byte, end - start,
5271 prop, string);
5272
5273 if (it->cmp_it.id >= 0)
5274 {
5275 it->cmp_it.ch = -1;
5276 it->cmp_it.nchars = COMPOSITION_LENGTH (prop);
5277 it->cmp_it.nglyphs = -1;
5278 }
5279 }
5280
5281 return HANDLED_NORMALLY;
5282 }
5283
5284
5285 \f
5286 /***********************************************************************
5287 Overlay strings
5288 ***********************************************************************/
5289
5290 /* The following structure is used to record overlay strings for
5291 later sorting in load_overlay_strings. */
5292
5293 struct overlay_entry
5294 {
5295 Lisp_Object overlay;
5296 Lisp_Object string;
5297 EMACS_INT priority;
5298 int after_string_p;
5299 };
5300
5301
5302 /* Set up iterator IT from overlay strings at its current position.
5303 Called from handle_stop. */
5304
5305 static enum prop_handled
5306 handle_overlay_change (struct it *it)
5307 {
5308 if (!STRINGP (it->string) && get_overlay_strings (it, 0))
5309 return HANDLED_RECOMPUTE_PROPS;
5310 else
5311 return HANDLED_NORMALLY;
5312 }
5313
5314
5315 /* Set up the next overlay string for delivery by IT, if there is an
5316 overlay string to deliver. Called by set_iterator_to_next when the
5317 end of the current overlay string is reached. If there are more
5318 overlay strings to display, IT->string and
5319 IT->current.overlay_string_index are set appropriately here.
5320 Otherwise IT->string is set to nil. */
5321
5322 static void
5323 next_overlay_string (struct it *it)
5324 {
5325 ++it->current.overlay_string_index;
5326 if (it->current.overlay_string_index == it->n_overlay_strings)
5327 {
5328 /* No more overlay strings. Restore IT's settings to what
5329 they were before overlay strings were processed, and
5330 continue to deliver from current_buffer. */
5331
5332 it->ellipsis_p = (it->stack[it->sp - 1].display_ellipsis_p != 0);
5333 pop_it (it);
5334 eassert (it->sp > 0
5335 || (NILP (it->string)
5336 && it->method == GET_FROM_BUFFER
5337 && it->stop_charpos >= BEGV
5338 && it->stop_charpos <= it->end_charpos));
5339 it->current.overlay_string_index = -1;
5340 it->n_overlay_strings = 0;
5341 it->overlay_strings_charpos = -1;
5342 /* If there's an empty display string on the stack, pop the
5343 stack, to resync the bidi iterator with IT's position. Such
5344 empty strings are pushed onto the stack in
5345 get_overlay_strings_1. */
5346 if (it->sp > 0 && STRINGP (it->string) && !SCHARS (it->string))
5347 pop_it (it);
5348
5349 /* If we're at the end of the buffer, record that we have
5350 processed the overlay strings there already, so that
5351 next_element_from_buffer doesn't try it again. */
5352 if (NILP (it->string) && IT_CHARPOS (*it) >= it->end_charpos)
5353 it->overlay_strings_at_end_processed_p = 1;
5354 }
5355 else
5356 {
5357 /* There are more overlay strings to process. If
5358 IT->current.overlay_string_index has advanced to a position
5359 where we must load IT->overlay_strings with more strings, do
5360 it. We must load at the IT->overlay_strings_charpos where
5361 IT->n_overlay_strings was originally computed; when invisible
5362 text is present, this might not be IT_CHARPOS (Bug#7016). */
5363 int i = it->current.overlay_string_index % OVERLAY_STRING_CHUNK_SIZE;
5364
5365 if (it->current.overlay_string_index && i == 0)
5366 load_overlay_strings (it, it->overlay_strings_charpos);
5367
5368 /* Initialize IT to deliver display elements from the overlay
5369 string. */
5370 it->string = it->overlay_strings[i];
5371 it->multibyte_p = STRING_MULTIBYTE (it->string);
5372 SET_TEXT_POS (it->current.string_pos, 0, 0);
5373 it->method = GET_FROM_STRING;
5374 it->stop_charpos = 0;
5375 if (it->cmp_it.stop_pos >= 0)
5376 it->cmp_it.stop_pos = 0;
5377 it->prev_stop = 0;
5378 it->base_level_stop = 0;
5379
5380 /* Set up the bidi iterator for this overlay string. */
5381 if (it->bidi_p)
5382 {
5383 it->bidi_it.string.lstring = it->string;
5384 it->bidi_it.string.s = NULL;
5385 it->bidi_it.string.schars = SCHARS (it->string);
5386 it->bidi_it.string.bufpos = it->overlay_strings_charpos;
5387 it->bidi_it.string.from_disp_str = it->string_from_display_prop_p;
5388 it->bidi_it.string.unibyte = !it->multibyte_p;
5389 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
5390 }
5391 }
5392
5393 CHECK_IT (it);
5394 }
5395
5396
5397 /* Compare two overlay_entry structures E1 and E2. Used as a
5398 comparison function for qsort in load_overlay_strings. Overlay
5399 strings for the same position are sorted so that
5400
5401 1. All after-strings come in front of before-strings, except
5402 when they come from the same overlay.
5403
5404 2. Within after-strings, strings are sorted so that overlay strings
5405 from overlays with higher priorities come first.
5406
5407 2. Within before-strings, strings are sorted so that overlay
5408 strings from overlays with higher priorities come last.
5409
5410 Value is analogous to strcmp. */
5411
5412
5413 static int
5414 compare_overlay_entries (const void *e1, const void *e2)
5415 {
5416 struct overlay_entry *entry1 = (struct overlay_entry *) e1;
5417 struct overlay_entry *entry2 = (struct overlay_entry *) e2;
5418 int result;
5419
5420 if (entry1->after_string_p != entry2->after_string_p)
5421 {
5422 /* Let after-strings appear in front of before-strings if
5423 they come from different overlays. */
5424 if (EQ (entry1->overlay, entry2->overlay))
5425 result = entry1->after_string_p ? 1 : -1;
5426 else
5427 result = entry1->after_string_p ? -1 : 1;
5428 }
5429 else if (entry1->priority != entry2->priority)
5430 {
5431 if (entry1->after_string_p)
5432 /* After-strings sorted in order of decreasing priority. */
5433 result = entry2->priority < entry1->priority ? -1 : 1;
5434 else
5435 /* Before-strings sorted in order of increasing priority. */
5436 result = entry1->priority < entry2->priority ? -1 : 1;
5437 }
5438 else
5439 result = 0;
5440
5441 return result;
5442 }
5443
5444
5445 /* Load the vector IT->overlay_strings with overlay strings from IT's
5446 current buffer position, or from CHARPOS if that is > 0. Set
5447 IT->n_overlays to the total number of overlay strings found.
5448
5449 Overlay strings are processed OVERLAY_STRING_CHUNK_SIZE strings at
5450 a time. On entry into load_overlay_strings,
5451 IT->current.overlay_string_index gives the number of overlay
5452 strings that have already been loaded by previous calls to this
5453 function.
5454
5455 IT->add_overlay_start contains an additional overlay start
5456 position to consider for taking overlay strings from, if non-zero.
5457 This position comes into play when the overlay has an `invisible'
5458 property, and both before and after-strings. When we've skipped to
5459 the end of the overlay, because of its `invisible' property, we
5460 nevertheless want its before-string to appear.
5461 IT->add_overlay_start will contain the overlay start position
5462 in this case.
5463
5464 Overlay strings are sorted so that after-string strings come in
5465 front of before-string strings. Within before and after-strings,
5466 strings are sorted by overlay priority. See also function
5467 compare_overlay_entries. */
5468
5469 static void
5470 load_overlay_strings (struct it *it, ptrdiff_t charpos)
5471 {
5472 Lisp_Object overlay, window, str, invisible;
5473 struct Lisp_Overlay *ov;
5474 ptrdiff_t start, end;
5475 ptrdiff_t size = 20;
5476 ptrdiff_t n = 0, i, j;
5477 int invis_p;
5478 struct overlay_entry *entries = alloca (size * sizeof *entries);
5479 USE_SAFE_ALLOCA;
5480
5481 if (charpos <= 0)
5482 charpos = IT_CHARPOS (*it);
5483
5484 /* Append the overlay string STRING of overlay OVERLAY to vector
5485 `entries' which has size `size' and currently contains `n'
5486 elements. AFTER_P non-zero means STRING is an after-string of
5487 OVERLAY. */
5488 #define RECORD_OVERLAY_STRING(OVERLAY, STRING, AFTER_P) \
5489 do \
5490 { \
5491 Lisp_Object priority; \
5492 \
5493 if (n == size) \
5494 { \
5495 struct overlay_entry *old = entries; \
5496 SAFE_NALLOCA (entries, 2, size); \
5497 memcpy (entries, old, size * sizeof *entries); \
5498 size *= 2; \
5499 } \
5500 \
5501 entries[n].string = (STRING); \
5502 entries[n].overlay = (OVERLAY); \
5503 priority = Foverlay_get ((OVERLAY), Qpriority); \
5504 entries[n].priority = INTEGERP (priority) ? XINT (priority) : 0; \
5505 entries[n].after_string_p = (AFTER_P); \
5506 ++n; \
5507 } \
5508 while (0)
5509
5510 /* Process overlay before the overlay center. */
5511 for (ov = current_buffer->overlays_before; ov; ov = ov->next)
5512 {
5513 XSETMISC (overlay, ov);
5514 eassert (OVERLAYP (overlay));
5515 start = OVERLAY_POSITION (OVERLAY_START (overlay));
5516 end = OVERLAY_POSITION (OVERLAY_END (overlay));
5517
5518 if (end < charpos)
5519 break;
5520
5521 /* Skip this overlay if it doesn't start or end at IT's current
5522 position. */
5523 if (end != charpos && start != charpos)
5524 continue;
5525
5526 /* Skip this overlay if it doesn't apply to IT->w. */
5527 window = Foverlay_get (overlay, Qwindow);
5528 if (WINDOWP (window) && XWINDOW (window) != it->w)
5529 continue;
5530
5531 /* If the text ``under'' the overlay is invisible, both before-
5532 and after-strings from this overlay are visible; start and
5533 end position are indistinguishable. */
5534 invisible = Foverlay_get (overlay, Qinvisible);
5535 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
5536
5537 /* If overlay has a non-empty before-string, record it. */
5538 if ((start == charpos || (end == charpos && invis_p))
5539 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
5540 && SCHARS (str))
5541 RECORD_OVERLAY_STRING (overlay, str, 0);
5542
5543 /* If overlay has a non-empty after-string, record it. */
5544 if ((end == charpos || (start == charpos && invis_p))
5545 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
5546 && SCHARS (str))
5547 RECORD_OVERLAY_STRING (overlay, str, 1);
5548 }
5549
5550 /* Process overlays after the overlay center. */
5551 for (ov = current_buffer->overlays_after; ov; ov = ov->next)
5552 {
5553 XSETMISC (overlay, ov);
5554 eassert (OVERLAYP (overlay));
5555 start = OVERLAY_POSITION (OVERLAY_START (overlay));
5556 end = OVERLAY_POSITION (OVERLAY_END (overlay));
5557
5558 if (start > charpos)
5559 break;
5560
5561 /* Skip this overlay if it doesn't start or end at IT's current
5562 position. */
5563 if (end != charpos && start != charpos)
5564 continue;
5565
5566 /* Skip this overlay if it doesn't apply to IT->w. */
5567 window = Foverlay_get (overlay, Qwindow);
5568 if (WINDOWP (window) && XWINDOW (window) != it->w)
5569 continue;
5570
5571 /* If the text ``under'' the overlay is invisible, it has a zero
5572 dimension, and both before- and after-strings apply. */
5573 invisible = Foverlay_get (overlay, Qinvisible);
5574 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
5575
5576 /* If overlay has a non-empty before-string, record it. */
5577 if ((start == charpos || (end == charpos && invis_p))
5578 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
5579 && SCHARS (str))
5580 RECORD_OVERLAY_STRING (overlay, str, 0);
5581
5582 /* If overlay has a non-empty after-string, record it. */
5583 if ((end == charpos || (start == charpos && invis_p))
5584 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
5585 && SCHARS (str))
5586 RECORD_OVERLAY_STRING (overlay, str, 1);
5587 }
5588
5589 #undef RECORD_OVERLAY_STRING
5590
5591 /* Sort entries. */
5592 if (n > 1)
5593 qsort (entries, n, sizeof *entries, compare_overlay_entries);
5594
5595 /* Record number of overlay strings, and where we computed it. */
5596 it->n_overlay_strings = n;
5597 it->overlay_strings_charpos = charpos;
5598
5599 /* IT->current.overlay_string_index is the number of overlay strings
5600 that have already been consumed by IT. Copy some of the
5601 remaining overlay strings to IT->overlay_strings. */
5602 i = 0;
5603 j = it->current.overlay_string_index;
5604 while (i < OVERLAY_STRING_CHUNK_SIZE && j < n)
5605 {
5606 it->overlay_strings[i] = entries[j].string;
5607 it->string_overlays[i++] = entries[j++].overlay;
5608 }
5609
5610 CHECK_IT (it);
5611 SAFE_FREE ();
5612 }
5613
5614
5615 /* Get the first chunk of overlay strings at IT's current buffer
5616 position, or at CHARPOS if that is > 0. Value is non-zero if at
5617 least one overlay string was found. */
5618
5619 static int
5620 get_overlay_strings_1 (struct it *it, ptrdiff_t charpos, int compute_stop_p)
5621 {
5622 /* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to
5623 process. This fills IT->overlay_strings with strings, and sets
5624 IT->n_overlay_strings to the total number of strings to process.
5625 IT->pos.overlay_string_index has to be set temporarily to zero
5626 because load_overlay_strings needs this; it must be set to -1
5627 when no overlay strings are found because a zero value would
5628 indicate a position in the first overlay string. */
5629 it->current.overlay_string_index = 0;
5630 load_overlay_strings (it, charpos);
5631
5632 /* If we found overlay strings, set up IT to deliver display
5633 elements from the first one. Otherwise set up IT to deliver
5634 from current_buffer. */
5635 if (it->n_overlay_strings)
5636 {
5637 /* Make sure we know settings in current_buffer, so that we can
5638 restore meaningful values when we're done with the overlay
5639 strings. */
5640 if (compute_stop_p)
5641 compute_stop_pos (it);
5642 eassert (it->face_id >= 0);
5643
5644 /* Save IT's settings. They are restored after all overlay
5645 strings have been processed. */
5646 eassert (!compute_stop_p || it->sp == 0);
5647
5648 /* When called from handle_stop, there might be an empty display
5649 string loaded. In that case, don't bother saving it. But
5650 don't use this optimization with the bidi iterator, since we
5651 need the corresponding pop_it call to resync the bidi
5652 iterator's position with IT's position, after we are done
5653 with the overlay strings. (The corresponding call to pop_it
5654 in case of an empty display string is in
5655 next_overlay_string.) */
5656 if (!(!it->bidi_p
5657 && STRINGP (it->string) && !SCHARS (it->string)))
5658 push_it (it, NULL);
5659
5660 /* Set up IT to deliver display elements from the first overlay
5661 string. */
5662 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
5663 it->string = it->overlay_strings[0];
5664 it->from_overlay = Qnil;
5665 it->stop_charpos = 0;
5666 eassert (STRINGP (it->string));
5667 it->end_charpos = SCHARS (it->string);
5668 it->prev_stop = 0;
5669 it->base_level_stop = 0;
5670 it->multibyte_p = STRING_MULTIBYTE (it->string);
5671 it->method = GET_FROM_STRING;
5672 it->from_disp_prop_p = 0;
5673
5674 /* Force paragraph direction to be that of the parent
5675 buffer. */
5676 if (it->bidi_p && it->bidi_it.paragraph_dir == R2L)
5677 it->paragraph_embedding = it->bidi_it.paragraph_dir;
5678 else
5679 it->paragraph_embedding = L2R;
5680
5681 /* Set up the bidi iterator for this overlay string. */
5682 if (it->bidi_p)
5683 {
5684 ptrdiff_t pos = (charpos > 0 ? charpos : IT_CHARPOS (*it));
5685
5686 it->bidi_it.string.lstring = it->string;
5687 it->bidi_it.string.s = NULL;
5688 it->bidi_it.string.schars = SCHARS (it->string);
5689 it->bidi_it.string.bufpos = pos;
5690 it->bidi_it.string.from_disp_str = it->string_from_display_prop_p;
5691 it->bidi_it.string.unibyte = !it->multibyte_p;
5692 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
5693 }
5694 return 1;
5695 }
5696
5697 it->current.overlay_string_index = -1;
5698 return 0;
5699 }
5700
5701 static int
5702 get_overlay_strings (struct it *it, ptrdiff_t charpos)
5703 {
5704 it->string = Qnil;
5705 it->method = GET_FROM_BUFFER;
5706
5707 (void) get_overlay_strings_1 (it, charpos, 1);
5708
5709 CHECK_IT (it);
5710
5711 /* Value is non-zero if we found at least one overlay string. */
5712 return STRINGP (it->string);
5713 }
5714
5715
5716 \f
5717 /***********************************************************************
5718 Saving and restoring state
5719 ***********************************************************************/
5720
5721 /* Save current settings of IT on IT->stack. Called, for example,
5722 before setting up IT for an overlay string, to be able to restore
5723 IT's settings to what they were after the overlay string has been
5724 processed. If POSITION is non-NULL, it is the position to save on
5725 the stack instead of IT->position. */
5726
5727 static void
5728 push_it (struct it *it, struct text_pos *position)
5729 {
5730 struct iterator_stack_entry *p;
5731
5732 eassert (it->sp < IT_STACK_SIZE);
5733 p = it->stack + it->sp;
5734
5735 p->stop_charpos = it->stop_charpos;
5736 p->prev_stop = it->prev_stop;
5737 p->base_level_stop = it->base_level_stop;
5738 p->cmp_it = it->cmp_it;
5739 eassert (it->face_id >= 0);
5740 p->face_id = it->face_id;
5741 p->string = it->string;
5742 p->method = it->method;
5743 p->from_overlay = it->from_overlay;
5744 switch (p->method)
5745 {
5746 case GET_FROM_IMAGE:
5747 p->u.image.object = it->object;
5748 p->u.image.image_id = it->image_id;
5749 p->u.image.slice = it->slice;
5750 break;
5751 case GET_FROM_STRETCH:
5752 p->u.stretch.object = it->object;
5753 break;
5754 #ifdef HAVE_XWIDGETS
5755 case GET_FROM_XWIDGET:
5756 p->u.xwidget.object = it->object;
5757 break;
5758 #endif
5759 }
5760 p->position = position ? *position : it->position;
5761 p->current = it->current;
5762 p->end_charpos = it->end_charpos;
5763 p->string_nchars = it->string_nchars;
5764 p->area = it->area;
5765 p->multibyte_p = it->multibyte_p;
5766 p->avoid_cursor_p = it->avoid_cursor_p;
5767 p->space_width = it->space_width;
5768 p->font_height = it->font_height;
5769 p->voffset = it->voffset;
5770 p->string_from_display_prop_p = it->string_from_display_prop_p;
5771 p->string_from_prefix_prop_p = it->string_from_prefix_prop_p;
5772 p->display_ellipsis_p = 0;
5773 p->line_wrap = it->line_wrap;
5774 p->bidi_p = it->bidi_p;
5775 p->paragraph_embedding = it->paragraph_embedding;
5776 p->from_disp_prop_p = it->from_disp_prop_p;
5777 ++it->sp;
5778
5779 /* Save the state of the bidi iterator as well. */
5780 if (it->bidi_p)
5781 bidi_push_it (&it->bidi_it);
5782 }
5783
5784 static void
5785 iterate_out_of_display_property (struct it *it)
5786 {
5787 int buffer_p = !STRINGP (it->string);
5788 ptrdiff_t eob = (buffer_p ? ZV : it->end_charpos);
5789 ptrdiff_t bob = (buffer_p ? BEGV : 0);
5790
5791 eassert (eob >= CHARPOS (it->position) && CHARPOS (it->position) >= bob);
5792
5793 /* Maybe initialize paragraph direction. If we are at the beginning
5794 of a new paragraph, next_element_from_buffer may not have a
5795 chance to do that. */
5796 if (it->bidi_it.first_elt && it->bidi_it.charpos < eob)
5797 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1);
5798 /* prev_stop can be zero, so check against BEGV as well. */
5799 while (it->bidi_it.charpos >= bob
5800 && it->prev_stop <= it->bidi_it.charpos
5801 && it->bidi_it.charpos < CHARPOS (it->position)
5802 && it->bidi_it.charpos < eob)
5803 bidi_move_to_visually_next (&it->bidi_it);
5804 /* Record the stop_pos we just crossed, for when we cross it
5805 back, maybe. */
5806 if (it->bidi_it.charpos > CHARPOS (it->position))
5807 it->prev_stop = CHARPOS (it->position);
5808 /* If we ended up not where pop_it put us, resync IT's
5809 positional members with the bidi iterator. */
5810 if (it->bidi_it.charpos != CHARPOS (it->position))
5811 SET_TEXT_POS (it->position, it->bidi_it.charpos, it->bidi_it.bytepos);
5812 if (buffer_p)
5813 it->current.pos = it->position;
5814 else
5815 it->current.string_pos = it->position;
5816 }
5817
5818 /* Restore IT's settings from IT->stack. Called, for example, when no
5819 more overlay strings must be processed, and we return to delivering
5820 display elements from a buffer, or when the end of a string from a
5821 `display' property is reached and we return to delivering display
5822 elements from an overlay string, or from a buffer. */
5823
5824 static void
5825 pop_it (struct it *it)
5826 {
5827 struct iterator_stack_entry *p;
5828 int from_display_prop = it->from_disp_prop_p;
5829
5830 eassert (it->sp > 0);
5831 --it->sp;
5832 p = it->stack + it->sp;
5833 it->stop_charpos = p->stop_charpos;
5834 it->prev_stop = p->prev_stop;
5835 it->base_level_stop = p->base_level_stop;
5836 it->cmp_it = p->cmp_it;
5837 it->face_id = p->face_id;
5838 it->current = p->current;
5839 it->position = p->position;
5840 it->string = p->string;
5841 it->from_overlay = p->from_overlay;
5842 if (NILP (it->string))
5843 SET_TEXT_POS (it->current.string_pos, -1, -1);
5844 it->method = p->method;
5845 switch (it->method)
5846 {
5847 case GET_FROM_IMAGE:
5848 it->image_id = p->u.image.image_id;
5849 it->object = p->u.image.object;
5850 it->slice = p->u.image.slice;
5851 break;
5852 #ifdef HAVE_XWIDGETS
5853 case GET_FROM_XWIDGET:
5854 it->object = p->u.xwidget.object;
5855 break;
5856 #endif
5857 case GET_FROM_STRETCH:
5858 it->object = p->u.stretch.object;
5859 break;
5860 case GET_FROM_BUFFER:
5861 it->object = it->w->buffer;
5862 break;
5863 case GET_FROM_STRING:
5864 it->object = it->string;
5865 break;
5866 case GET_FROM_DISPLAY_VECTOR:
5867 if (it->s)
5868 it->method = GET_FROM_C_STRING;
5869 else if (STRINGP (it->string))
5870 it->method = GET_FROM_STRING;
5871 else
5872 {
5873 it->method = GET_FROM_BUFFER;
5874 it->object = it->w->buffer;
5875 }
5876 }
5877 it->end_charpos = p->end_charpos;
5878 it->string_nchars = p->string_nchars;
5879 it->area = p->area;
5880 it->multibyte_p = p->multibyte_p;
5881 it->avoid_cursor_p = p->avoid_cursor_p;
5882 it->space_width = p->space_width;
5883 it->font_height = p->font_height;
5884 it->voffset = p->voffset;
5885 it->string_from_display_prop_p = p->string_from_display_prop_p;
5886 it->string_from_prefix_prop_p = p->string_from_prefix_prop_p;
5887 it->line_wrap = p->line_wrap;
5888 it->bidi_p = p->bidi_p;
5889 it->paragraph_embedding = p->paragraph_embedding;
5890 it->from_disp_prop_p = p->from_disp_prop_p;
5891 if (it->bidi_p)
5892 {
5893 bidi_pop_it (&it->bidi_it);
5894 /* Bidi-iterate until we get out of the portion of text, if any,
5895 covered by a `display' text property or by an overlay with
5896 `display' property. (We cannot just jump there, because the
5897 internal coherency of the bidi iterator state can not be
5898 preserved across such jumps.) We also must determine the
5899 paragraph base direction if the overlay we just processed is
5900 at the beginning of a new paragraph. */
5901 if (from_display_prop
5902 && (it->method == GET_FROM_BUFFER || it->method == GET_FROM_STRING))
5903 iterate_out_of_display_property (it);
5904
5905 eassert ((BUFFERP (it->object)
5906 && IT_CHARPOS (*it) == it->bidi_it.charpos
5907 && IT_BYTEPOS (*it) == it->bidi_it.bytepos)
5908 || (STRINGP (it->object)
5909 && IT_STRING_CHARPOS (*it) == it->bidi_it.charpos
5910 && IT_STRING_BYTEPOS (*it) == it->bidi_it.bytepos)
5911 || (CONSP (it->object) && it->method == GET_FROM_STRETCH));
5912 }
5913 }
5914
5915
5916 \f
5917 /***********************************************************************
5918 Moving over lines
5919 ***********************************************************************/
5920
5921 /* Set IT's current position to the previous line start. */
5922
5923 static void
5924 back_to_previous_line_start (struct it *it)
5925 {
5926 IT_CHARPOS (*it) = find_next_newline_no_quit (IT_CHARPOS (*it) - 1, -1);
5927 IT_BYTEPOS (*it) = CHAR_TO_BYTE (IT_CHARPOS (*it));
5928 }
5929
5930
5931 /* Move IT to the next line start.
5932
5933 Value is non-zero if a newline was found. Set *SKIPPED_P to 1 if
5934 we skipped over part of the text (as opposed to moving the iterator
5935 continuously over the text). Otherwise, don't change the value
5936 of *SKIPPED_P.
5937
5938 If BIDI_IT_PREV is non-NULL, store into it the state of the bidi
5939 iterator on the newline, if it was found.
5940
5941 Newlines may come from buffer text, overlay strings, or strings
5942 displayed via the `display' property. That's the reason we can't
5943 simply use find_next_newline_no_quit.
5944
5945 Note that this function may not skip over invisible text that is so
5946 because of text properties and immediately follows a newline. If
5947 it would, function reseat_at_next_visible_line_start, when called
5948 from set_iterator_to_next, would effectively make invisible
5949 characters following a newline part of the wrong glyph row, which
5950 leads to wrong cursor motion. */
5951
5952 static int
5953 forward_to_next_line_start (struct it *it, int *skipped_p,
5954 struct bidi_it *bidi_it_prev)
5955 {
5956 ptrdiff_t old_selective;
5957 int newline_found_p, n;
5958 const int MAX_NEWLINE_DISTANCE = 500;
5959
5960 /* If already on a newline, just consume it to avoid unintended
5961 skipping over invisible text below. */
5962 if (it->what == IT_CHARACTER
5963 && it->c == '\n'
5964 && CHARPOS (it->position) == IT_CHARPOS (*it))
5965 {
5966 if (it->bidi_p && bidi_it_prev)
5967 *bidi_it_prev = it->bidi_it;
5968 set_iterator_to_next (it, 0);
5969 it->c = 0;
5970 return 1;
5971 }
5972
5973 /* Don't handle selective display in the following. It's (a)
5974 unnecessary because it's done by the caller, and (b) leads to an
5975 infinite recursion because next_element_from_ellipsis indirectly
5976 calls this function. */
5977 old_selective = it->selective;
5978 it->selective = 0;
5979
5980 /* Scan for a newline within MAX_NEWLINE_DISTANCE display elements
5981 from buffer text. */
5982 for (n = newline_found_p = 0;
5983 !newline_found_p && n < MAX_NEWLINE_DISTANCE;
5984 n += STRINGP (it->string) ? 0 : 1)
5985 {
5986 if (!get_next_display_element (it))
5987 return 0;
5988 newline_found_p = it->what == IT_CHARACTER && it->c == '\n';
5989 if (newline_found_p && it->bidi_p && bidi_it_prev)
5990 *bidi_it_prev = it->bidi_it;
5991 set_iterator_to_next (it, 0);
5992 }
5993
5994 /* If we didn't find a newline near enough, see if we can use a
5995 short-cut. */
5996 if (!newline_found_p)
5997 {
5998 ptrdiff_t start = IT_CHARPOS (*it);
5999 ptrdiff_t limit = find_next_newline_no_quit (start, 1);
6000 Lisp_Object pos;
6001
6002 eassert (!STRINGP (it->string));
6003
6004 /* If there isn't any `display' property in sight, and no
6005 overlays, we can just use the position of the newline in
6006 buffer text. */
6007 if (it->stop_charpos >= limit
6008 || ((pos = Fnext_single_property_change (make_number (start),
6009 Qdisplay, Qnil,
6010 make_number (limit)),
6011 NILP (pos))
6012 && next_overlay_change (start) == ZV))
6013 {
6014 if (!it->bidi_p)
6015 {
6016 IT_CHARPOS (*it) = limit;
6017 IT_BYTEPOS (*it) = CHAR_TO_BYTE (limit);
6018 }
6019 else
6020 {
6021 struct bidi_it bprev;
6022
6023 /* Help bidi.c avoid expensive searches for display
6024 properties and overlays, by telling it that there are
6025 none up to `limit'. */
6026 if (it->bidi_it.disp_pos < limit)
6027 {
6028 it->bidi_it.disp_pos = limit;
6029 it->bidi_it.disp_prop = 0;
6030 }
6031 do {
6032 bprev = it->bidi_it;
6033 bidi_move_to_visually_next (&it->bidi_it);
6034 } while (it->bidi_it.charpos != limit);
6035 IT_CHARPOS (*it) = limit;
6036 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
6037 if (bidi_it_prev)
6038 *bidi_it_prev = bprev;
6039 }
6040 *skipped_p = newline_found_p = 1;
6041 }
6042 else
6043 {
6044 while (get_next_display_element (it)
6045 && !newline_found_p)
6046 {
6047 newline_found_p = ITERATOR_AT_END_OF_LINE_P (it);
6048 if (newline_found_p && it->bidi_p && bidi_it_prev)
6049 *bidi_it_prev = it->bidi_it;
6050 set_iterator_to_next (it, 0);
6051 }
6052 }
6053 }
6054
6055 it->selective = old_selective;
6056 return newline_found_p;
6057 }
6058
6059
6060 /* Set IT's current position to the previous visible line start. Skip
6061 invisible text that is so either due to text properties or due to
6062 selective display. Caution: this does not change IT->current_x and
6063 IT->hpos. */
6064
6065 static void
6066 back_to_previous_visible_line_start (struct it *it)
6067 {
6068 while (IT_CHARPOS (*it) > BEGV)
6069 {
6070 back_to_previous_line_start (it);
6071
6072 if (IT_CHARPOS (*it) <= BEGV)
6073 break;
6074
6075 /* If selective > 0, then lines indented more than its value are
6076 invisible. */
6077 if (it->selective > 0
6078 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
6079 it->selective))
6080 continue;
6081
6082 /* Check the newline before point for invisibility. */
6083 {
6084 Lisp_Object prop;
6085 prop = Fget_char_property (make_number (IT_CHARPOS (*it) - 1),
6086 Qinvisible, it->window);
6087 if (TEXT_PROP_MEANS_INVISIBLE (prop))
6088 continue;
6089 }
6090
6091 if (IT_CHARPOS (*it) <= BEGV)
6092 break;
6093
6094 {
6095 struct it it2;
6096 void *it2data = NULL;
6097 ptrdiff_t pos;
6098 ptrdiff_t beg, end;
6099 Lisp_Object val, overlay;
6100
6101 SAVE_IT (it2, *it, it2data);
6102
6103 /* If newline is part of a composition, continue from start of composition */
6104 if (find_composition (IT_CHARPOS (*it), -1, &beg, &end, &val, Qnil)
6105 && beg < IT_CHARPOS (*it))
6106 goto replaced;
6107
6108 /* If newline is replaced by a display property, find start of overlay
6109 or interval and continue search from that point. */
6110 pos = --IT_CHARPOS (it2);
6111 --IT_BYTEPOS (it2);
6112 it2.sp = 0;
6113 bidi_unshelve_cache (NULL, 0);
6114 it2.string_from_display_prop_p = 0;
6115 it2.from_disp_prop_p = 0;
6116 if (handle_display_prop (&it2) == HANDLED_RETURN
6117 && !NILP (val = get_char_property_and_overlay
6118 (make_number (pos), Qdisplay, Qnil, &overlay))
6119 && (OVERLAYP (overlay)
6120 ? (beg = OVERLAY_POSITION (OVERLAY_START (overlay)))
6121 : get_property_and_range (pos, Qdisplay, &val, &beg, &end, Qnil)))
6122 {
6123 RESTORE_IT (it, it, it2data);
6124 goto replaced;
6125 }
6126
6127 /* Newline is not replaced by anything -- so we are done. */
6128 RESTORE_IT (it, it, it2data);
6129 break;
6130
6131 replaced:
6132 if (beg < BEGV)
6133 beg = BEGV;
6134 IT_CHARPOS (*it) = beg;
6135 IT_BYTEPOS (*it) = buf_charpos_to_bytepos (current_buffer, beg);
6136 }
6137 }
6138
6139 it->continuation_lines_width = 0;
6140
6141 eassert (IT_CHARPOS (*it) >= BEGV);
6142 eassert (IT_CHARPOS (*it) == BEGV
6143 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
6144 CHECK_IT (it);
6145 }
6146
6147
6148 /* Reseat iterator IT at the previous visible line start. Skip
6149 invisible text that is so either due to text properties or due to
6150 selective display. At the end, update IT's overlay information,
6151 face information etc. */
6152
6153 void
6154 reseat_at_previous_visible_line_start (struct it *it)
6155 {
6156 back_to_previous_visible_line_start (it);
6157 reseat (it, it->current.pos, 1);
6158 CHECK_IT (it);
6159 }
6160
6161
6162 /* Reseat iterator IT on the next visible line start in the current
6163 buffer. ON_NEWLINE_P non-zero means position IT on the newline
6164 preceding the line start. Skip over invisible text that is so
6165 because of selective display. Compute faces, overlays etc at the
6166 new position. Note that this function does not skip over text that
6167 is invisible because of text properties. */
6168
6169 static void
6170 reseat_at_next_visible_line_start (struct it *it, int on_newline_p)
6171 {
6172 int newline_found_p, skipped_p = 0;
6173 struct bidi_it bidi_it_prev;
6174
6175 newline_found_p = forward_to_next_line_start (it, &skipped_p, &bidi_it_prev);
6176
6177 /* Skip over lines that are invisible because they are indented
6178 more than the value of IT->selective. */
6179 if (it->selective > 0)
6180 while (IT_CHARPOS (*it) < ZV
6181 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
6182 it->selective))
6183 {
6184 eassert (IT_BYTEPOS (*it) == BEGV
6185 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
6186 newline_found_p =
6187 forward_to_next_line_start (it, &skipped_p, &bidi_it_prev);
6188 }
6189
6190 /* Position on the newline if that's what's requested. */
6191 if (on_newline_p && newline_found_p)
6192 {
6193 if (STRINGP (it->string))
6194 {
6195 if (IT_STRING_CHARPOS (*it) > 0)
6196 {
6197 if (!it->bidi_p)
6198 {
6199 --IT_STRING_CHARPOS (*it);
6200 --IT_STRING_BYTEPOS (*it);
6201 }
6202 else
6203 {
6204 /* We need to restore the bidi iterator to the state
6205 it had on the newline, and resync the IT's
6206 position with that. */
6207 it->bidi_it = bidi_it_prev;
6208 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
6209 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
6210 }
6211 }
6212 }
6213 else if (IT_CHARPOS (*it) > BEGV)
6214 {
6215 if (!it->bidi_p)
6216 {
6217 --IT_CHARPOS (*it);
6218 --IT_BYTEPOS (*it);
6219 }
6220 else
6221 {
6222 /* We need to restore the bidi iterator to the state it
6223 had on the newline and resync IT with that. */
6224 it->bidi_it = bidi_it_prev;
6225 IT_CHARPOS (*it) = it->bidi_it.charpos;
6226 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
6227 }
6228 reseat (it, it->current.pos, 0);
6229 }
6230 }
6231 else if (skipped_p)
6232 reseat (it, it->current.pos, 0);
6233
6234 CHECK_IT (it);
6235 }
6236
6237
6238 \f
6239 /***********************************************************************
6240 Changing an iterator's position
6241 ***********************************************************************/
6242
6243 /* Change IT's current position to POS in current_buffer. If FORCE_P
6244 is non-zero, always check for text properties at the new position.
6245 Otherwise, text properties are only looked up if POS >=
6246 IT->check_charpos of a property. */
6247
6248 static void
6249 reseat (struct it *it, struct text_pos pos, int force_p)
6250 {
6251 ptrdiff_t original_pos = IT_CHARPOS (*it);
6252
6253 reseat_1 (it, pos, 0);
6254
6255 /* Determine where to check text properties. Avoid doing it
6256 where possible because text property lookup is very expensive. */
6257 if (force_p
6258 || CHARPOS (pos) > it->stop_charpos
6259 || CHARPOS (pos) < original_pos)
6260 {
6261 if (it->bidi_p)
6262 {
6263 /* For bidi iteration, we need to prime prev_stop and
6264 base_level_stop with our best estimations. */
6265 /* Implementation note: Of course, POS is not necessarily a
6266 stop position, so assigning prev_pos to it is a lie; we
6267 should have called compute_stop_backwards. However, if
6268 the current buffer does not include any R2L characters,
6269 that call would be a waste of cycles, because the
6270 iterator will never move back, and thus never cross this
6271 "fake" stop position. So we delay that backward search
6272 until the time we really need it, in next_element_from_buffer. */
6273 if (CHARPOS (pos) != it->prev_stop)
6274 it->prev_stop = CHARPOS (pos);
6275 if (CHARPOS (pos) < it->base_level_stop)
6276 it->base_level_stop = 0; /* meaning it's unknown */
6277 handle_stop (it);
6278 }
6279 else
6280 {
6281 handle_stop (it);
6282 it->prev_stop = it->base_level_stop = 0;
6283 }
6284
6285 }
6286
6287 CHECK_IT (it);
6288 }
6289
6290
6291 /* Change IT's buffer position to POS. SET_STOP_P non-zero means set
6292 IT->stop_pos to POS, also. */
6293
6294 static void
6295 reseat_1 (struct it *it, struct text_pos pos, int set_stop_p)
6296 {
6297 /* Don't call this function when scanning a C string. */
6298 eassert (it->s == NULL);
6299
6300 /* POS must be a reasonable value. */
6301 eassert (CHARPOS (pos) >= BEGV && CHARPOS (pos) <= ZV);
6302
6303 it->current.pos = it->position = pos;
6304 it->end_charpos = ZV;
6305 it->dpvec = NULL;
6306 it->current.dpvec_index = -1;
6307 it->current.overlay_string_index = -1;
6308 IT_STRING_CHARPOS (*it) = -1;
6309 IT_STRING_BYTEPOS (*it) = -1;
6310 it->string = Qnil;
6311 it->method = GET_FROM_BUFFER;
6312 it->object = it->w->buffer;
6313 it->area = TEXT_AREA;
6314 it->multibyte_p = !NILP (BVAR (current_buffer, enable_multibyte_characters));
6315 it->sp = 0;
6316 it->string_from_display_prop_p = 0;
6317 it->string_from_prefix_prop_p = 0;
6318
6319 it->from_disp_prop_p = 0;
6320 it->face_before_selective_p = 0;
6321 if (it->bidi_p)
6322 {
6323 bidi_init_it (IT_CHARPOS (*it), IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f),
6324 &it->bidi_it);
6325 bidi_unshelve_cache (NULL, 0);
6326 it->bidi_it.paragraph_dir = NEUTRAL_DIR;
6327 it->bidi_it.string.s = NULL;
6328 it->bidi_it.string.lstring = Qnil;
6329 it->bidi_it.string.bufpos = 0;
6330 it->bidi_it.string.unibyte = 0;
6331 }
6332
6333 if (set_stop_p)
6334 {
6335 it->stop_charpos = CHARPOS (pos);
6336 it->base_level_stop = CHARPOS (pos);
6337 }
6338 }
6339
6340
6341 /* Set up IT for displaying a string, starting at CHARPOS in window W.
6342 If S is non-null, it is a C string to iterate over. Otherwise,
6343 STRING gives a Lisp string to iterate over.
6344
6345 If PRECISION > 0, don't return more then PRECISION number of
6346 characters from the string.
6347
6348 If FIELD_WIDTH > 0, return padding spaces until FIELD_WIDTH
6349 characters have been returned. FIELD_WIDTH < 0 means an infinite
6350 field width.
6351
6352 MULTIBYTE = 0 means disable processing of multibyte characters,
6353 MULTIBYTE > 0 means enable it,
6354 MULTIBYTE < 0 means use IT->multibyte_p.
6355
6356 IT must be initialized via a prior call to init_iterator before
6357 calling this function. */
6358
6359 static void
6360 reseat_to_string (struct it *it, const char *s, Lisp_Object string,
6361 ptrdiff_t charpos, ptrdiff_t precision, int field_width,
6362 int multibyte)
6363 {
6364 /* No region in strings. */
6365 it->region_beg_charpos = it->region_end_charpos = -1;
6366
6367 /* No text property checks performed by default, but see below. */
6368 it->stop_charpos = -1;
6369
6370 /* Set iterator position and end position. */
6371 memset (&it->current, 0, sizeof it->current);
6372 it->current.overlay_string_index = -1;
6373 it->current.dpvec_index = -1;
6374 eassert (charpos >= 0);
6375
6376 /* If STRING is specified, use its multibyteness, otherwise use the
6377 setting of MULTIBYTE, if specified. */
6378 if (multibyte >= 0)
6379 it->multibyte_p = multibyte > 0;
6380
6381 /* Bidirectional reordering of strings is controlled by the default
6382 value of bidi-display-reordering. Don't try to reorder while
6383 loading loadup.el, as the necessary character property tables are
6384 not yet available. */
6385 it->bidi_p =
6386 NILP (Vpurify_flag)
6387 && !NILP (BVAR (&buffer_defaults, bidi_display_reordering));
6388
6389 if (s == NULL)
6390 {
6391 eassert (STRINGP (string));
6392 it->string = string;
6393 it->s = NULL;
6394 it->end_charpos = it->string_nchars = SCHARS (string);
6395 it->method = GET_FROM_STRING;
6396 it->current.string_pos = string_pos (charpos, string);
6397
6398 if (it->bidi_p)
6399 {
6400 it->bidi_it.string.lstring = string;
6401 it->bidi_it.string.s = NULL;
6402 it->bidi_it.string.schars = it->end_charpos;
6403 it->bidi_it.string.bufpos = 0;
6404 it->bidi_it.string.from_disp_str = 0;
6405 it->bidi_it.string.unibyte = !it->multibyte_p;
6406 bidi_init_it (charpos, IT_STRING_BYTEPOS (*it),
6407 FRAME_WINDOW_P (it->f), &it->bidi_it);
6408 }
6409 }
6410 else
6411 {
6412 it->s = (const unsigned char *) s;
6413 it->string = Qnil;
6414
6415 /* Note that we use IT->current.pos, not it->current.string_pos,
6416 for displaying C strings. */
6417 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
6418 if (it->multibyte_p)
6419 {
6420 it->current.pos = c_string_pos (charpos, s, 1);
6421 it->end_charpos = it->string_nchars = number_of_chars (s, 1);
6422 }
6423 else
6424 {
6425 IT_CHARPOS (*it) = IT_BYTEPOS (*it) = charpos;
6426 it->end_charpos = it->string_nchars = strlen (s);
6427 }
6428
6429 if (it->bidi_p)
6430 {
6431 it->bidi_it.string.lstring = Qnil;
6432 it->bidi_it.string.s = (const unsigned char *) s;
6433 it->bidi_it.string.schars = it->end_charpos;
6434 it->bidi_it.string.bufpos = 0;
6435 it->bidi_it.string.from_disp_str = 0;
6436 it->bidi_it.string.unibyte = !it->multibyte_p;
6437 bidi_init_it (charpos, IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f),
6438 &it->bidi_it);
6439 }
6440 it->method = GET_FROM_C_STRING;
6441 }
6442
6443 /* PRECISION > 0 means don't return more than PRECISION characters
6444 from the string. */
6445 if (precision > 0 && it->end_charpos - charpos > precision)
6446 {
6447 it->end_charpos = it->string_nchars = charpos + precision;
6448 if (it->bidi_p)
6449 it->bidi_it.string.schars = it->end_charpos;
6450 }
6451
6452 /* FIELD_WIDTH > 0 means pad with spaces until FIELD_WIDTH
6453 characters have been returned. FIELD_WIDTH == 0 means don't pad,
6454 FIELD_WIDTH < 0 means infinite field width. This is useful for
6455 padding with `-' at the end of a mode line. */
6456 if (field_width < 0)
6457 field_width = INFINITY;
6458 /* Implementation note: We deliberately don't enlarge
6459 it->bidi_it.string.schars here to fit it->end_charpos, because
6460 the bidi iterator cannot produce characters out of thin air. */
6461 if (field_width > it->end_charpos - charpos)
6462 it->end_charpos = charpos + field_width;
6463
6464 /* Use the standard display table for displaying strings. */
6465 if (DISP_TABLE_P (Vstandard_display_table))
6466 it->dp = XCHAR_TABLE (Vstandard_display_table);
6467
6468 it->stop_charpos = charpos;
6469 it->prev_stop = charpos;
6470 it->base_level_stop = 0;
6471 if (it->bidi_p)
6472 {
6473 it->bidi_it.first_elt = 1;
6474 it->bidi_it.paragraph_dir = NEUTRAL_DIR;
6475 it->bidi_it.disp_pos = -1;
6476 }
6477 if (s == NULL && it->multibyte_p)
6478 {
6479 ptrdiff_t endpos = SCHARS (it->string);
6480 if (endpos > it->end_charpos)
6481 endpos = it->end_charpos;
6482 composition_compute_stop_pos (&it->cmp_it, charpos, -1, endpos,
6483 it->string);
6484 }
6485 CHECK_IT (it);
6486 }
6487
6488
6489 \f
6490 /***********************************************************************
6491 Iteration
6492 ***********************************************************************/
6493
6494 /* Map enum it_method value to corresponding next_element_from_* function. */
6495
6496 static int (* get_next_element[NUM_IT_METHODS]) (struct it *it) =
6497 {
6498 next_element_from_buffer,
6499 next_element_from_display_vector,
6500 next_element_from_string,
6501 next_element_from_c_string,
6502 next_element_from_image,
6503 next_element_from_stretch
6504 #ifdef HAVE_XWIDGETS
6505 ,next_element_from_xwidget
6506 #endif
6507 };
6508
6509 #define GET_NEXT_DISPLAY_ELEMENT(it) (*get_next_element[(it)->method]) (it)
6510
6511
6512 /* Return 1 iff a character at CHARPOS (and BYTEPOS) is composed
6513 (possibly with the following characters). */
6514
6515 #define CHAR_COMPOSED_P(IT,CHARPOS,BYTEPOS,END_CHARPOS) \
6516 ((IT)->cmp_it.id >= 0 \
6517 || ((IT)->cmp_it.stop_pos == (CHARPOS) \
6518 && composition_reseat_it (&(IT)->cmp_it, CHARPOS, BYTEPOS, \
6519 END_CHARPOS, (IT)->w, \
6520 FACE_FROM_ID ((IT)->f, (IT)->face_id), \
6521 (IT)->string)))
6522
6523
6524 /* Lookup the char-table Vglyphless_char_display for character C (-1
6525 if we want information for no-font case), and return the display
6526 method symbol. By side-effect, update it->what and
6527 it->glyphless_method. This function is called from
6528 get_next_display_element for each character element, and from
6529 x_produce_glyphs when no suitable font was found. */
6530
6531 Lisp_Object
6532 lookup_glyphless_char_display (int c, struct it *it)
6533 {
6534 Lisp_Object glyphless_method = Qnil;
6535
6536 if (CHAR_TABLE_P (Vglyphless_char_display)
6537 && CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (Vglyphless_char_display)) >= 1)
6538 {
6539 if (c >= 0)
6540 {
6541 glyphless_method = CHAR_TABLE_REF (Vglyphless_char_display, c);
6542 if (CONSP (glyphless_method))
6543 glyphless_method = FRAME_WINDOW_P (it->f)
6544 ? XCAR (glyphless_method)
6545 : XCDR (glyphless_method);
6546 }
6547 else
6548 glyphless_method = XCHAR_TABLE (Vglyphless_char_display)->extras[0];
6549 }
6550
6551 retry:
6552 if (NILP (glyphless_method))
6553 {
6554 if (c >= 0)
6555 /* The default is to display the character by a proper font. */
6556 return Qnil;
6557 /* The default for the no-font case is to display an empty box. */
6558 glyphless_method = Qempty_box;
6559 }
6560 if (EQ (glyphless_method, Qzero_width))
6561 {
6562 if (c >= 0)
6563 return glyphless_method;
6564 /* This method can't be used for the no-font case. */
6565 glyphless_method = Qempty_box;
6566 }
6567 if (EQ (glyphless_method, Qthin_space))
6568 it->glyphless_method = GLYPHLESS_DISPLAY_THIN_SPACE;
6569 else if (EQ (glyphless_method, Qempty_box))
6570 it->glyphless_method = GLYPHLESS_DISPLAY_EMPTY_BOX;
6571 else if (EQ (glyphless_method, Qhex_code))
6572 it->glyphless_method = GLYPHLESS_DISPLAY_HEX_CODE;
6573 else if (STRINGP (glyphless_method))
6574 it->glyphless_method = GLYPHLESS_DISPLAY_ACRONYM;
6575 else
6576 {
6577 /* Invalid value. We use the default method. */
6578 glyphless_method = Qnil;
6579 goto retry;
6580 }
6581 it->what = IT_GLYPHLESS;
6582 return glyphless_method;
6583 }
6584
6585 /* Load IT's display element fields with information about the next
6586 display element from the current position of IT. Value is zero if
6587 end of buffer (or C string) is reached. */
6588
6589 static struct frame *last_escape_glyph_frame = NULL;
6590 static int last_escape_glyph_face_id = (1 << FACE_ID_BITS);
6591 static int last_escape_glyph_merged_face_id = 0;
6592
6593 struct frame *last_glyphless_glyph_frame = NULL;
6594 int last_glyphless_glyph_face_id = (1 << FACE_ID_BITS);
6595 int last_glyphless_glyph_merged_face_id = 0;
6596
6597 static int
6598 get_next_display_element (struct it *it)
6599 {
6600 /* Non-zero means that we found a display element. Zero means that
6601 we hit the end of what we iterate over. Performance note: the
6602 function pointer `method' used here turns out to be faster than
6603 using a sequence of if-statements. */
6604 int success_p;
6605
6606 get_next:
6607 success_p = GET_NEXT_DISPLAY_ELEMENT (it);
6608
6609 if (it->what == IT_CHARACTER)
6610 {
6611 /* UAX#9, L4: "A character is depicted by a mirrored glyph if
6612 and only if (a) the resolved directionality of that character
6613 is R..." */
6614 /* FIXME: Do we need an exception for characters from display
6615 tables? */
6616 if (it->bidi_p && it->bidi_it.type == STRONG_R)
6617 it->c = bidi_mirror_char (it->c);
6618 /* Map via display table or translate control characters.
6619 IT->c, IT->len etc. have been set to the next character by
6620 the function call above. If we have a display table, and it
6621 contains an entry for IT->c, translate it. Don't do this if
6622 IT->c itself comes from a display table, otherwise we could
6623 end up in an infinite recursion. (An alternative could be to
6624 count the recursion depth of this function and signal an
6625 error when a certain maximum depth is reached.) Is it worth
6626 it? */
6627 if (success_p && it->dpvec == NULL)
6628 {
6629 Lisp_Object dv;
6630 struct charset *unibyte = CHARSET_FROM_ID (charset_unibyte);
6631 int nonascii_space_p = 0;
6632 int nonascii_hyphen_p = 0;
6633 int c = it->c; /* This is the character to display. */
6634
6635 if (! it->multibyte_p && ! ASCII_CHAR_P (c))
6636 {
6637 eassert (SINGLE_BYTE_CHAR_P (c));
6638 if (unibyte_display_via_language_environment)
6639 {
6640 c = DECODE_CHAR (unibyte, c);
6641 if (c < 0)
6642 c = BYTE8_TO_CHAR (it->c);
6643 }
6644 else
6645 c = BYTE8_TO_CHAR (it->c);
6646 }
6647
6648 if (it->dp
6649 && (dv = DISP_CHAR_VECTOR (it->dp, c),
6650 VECTORP (dv)))
6651 {
6652 struct Lisp_Vector *v = XVECTOR (dv);
6653
6654 /* Return the first character from the display table
6655 entry, if not empty. If empty, don't display the
6656 current character. */
6657 if (v->header.size)
6658 {
6659 it->dpvec_char_len = it->len;
6660 it->dpvec = v->contents;
6661 it->dpend = v->contents + v->header.size;
6662 it->current.dpvec_index = 0;
6663 it->dpvec_face_id = -1;
6664 it->saved_face_id = it->face_id;
6665 it->method = GET_FROM_DISPLAY_VECTOR;
6666 it->ellipsis_p = 0;
6667 }
6668 else
6669 {
6670 set_iterator_to_next (it, 0);
6671 }
6672 goto get_next;
6673 }
6674
6675 if (! NILP (lookup_glyphless_char_display (c, it)))
6676 {
6677 if (it->what == IT_GLYPHLESS)
6678 goto done;
6679 /* Don't display this character. */
6680 set_iterator_to_next (it, 0);
6681 goto get_next;
6682 }
6683
6684 /* If `nobreak-char-display' is non-nil, we display
6685 non-ASCII spaces and hyphens specially. */
6686 if (! ASCII_CHAR_P (c) && ! NILP (Vnobreak_char_display))
6687 {
6688 if (c == 0xA0)
6689 nonascii_space_p = 1;
6690 else if (c == 0xAD || c == 0x2010 || c == 0x2011)
6691 nonascii_hyphen_p = 1;
6692 }
6693
6694 /* Translate control characters into `\003' or `^C' form.
6695 Control characters coming from a display table entry are
6696 currently not translated because we use IT->dpvec to hold
6697 the translation. This could easily be changed but I
6698 don't believe that it is worth doing.
6699
6700 The characters handled by `nobreak-char-display' must be
6701 translated too.
6702
6703 Non-printable characters and raw-byte characters are also
6704 translated to octal form. */
6705 if (((c < ' ' || c == 127) /* ASCII control chars */
6706 ? (it->area != TEXT_AREA
6707 /* In mode line, treat \n, \t like other crl chars. */
6708 || (c != '\t'
6709 && it->glyph_row
6710 && (it->glyph_row->mode_line_p || it->avoid_cursor_p))
6711 || (c != '\n' && c != '\t'))
6712 : (nonascii_space_p
6713 || nonascii_hyphen_p
6714 || CHAR_BYTE8_P (c)
6715 || ! CHAR_PRINTABLE_P (c))))
6716 {
6717 /* C is a control character, non-ASCII space/hyphen,
6718 raw-byte, or a non-printable character which must be
6719 displayed either as '\003' or as `^C' where the '\\'
6720 and '^' can be defined in the display table. Fill
6721 IT->ctl_chars with glyphs for what we have to
6722 display. Then, set IT->dpvec to these glyphs. */
6723 Lisp_Object gc;
6724 int ctl_len;
6725 int face_id;
6726 int lface_id = 0;
6727 int escape_glyph;
6728
6729 /* Handle control characters with ^. */
6730
6731 if (ASCII_CHAR_P (c) && it->ctl_arrow_p)
6732 {
6733 int g;
6734
6735 g = '^'; /* default glyph for Control */
6736 /* Set IT->ctl_chars[0] to the glyph for `^'. */
6737 if (it->dp
6738 && (gc = DISP_CTRL_GLYPH (it->dp), GLYPH_CODE_P (gc)))
6739 {
6740 g = GLYPH_CODE_CHAR (gc);
6741 lface_id = GLYPH_CODE_FACE (gc);
6742 }
6743 if (lface_id)
6744 {
6745 face_id = merge_faces (it->f, Qt, lface_id, it->face_id);
6746 }
6747 else if (it->f == last_escape_glyph_frame
6748 && it->face_id == last_escape_glyph_face_id)
6749 {
6750 face_id = last_escape_glyph_merged_face_id;
6751 }
6752 else
6753 {
6754 /* Merge the escape-glyph face into the current face. */
6755 face_id = merge_faces (it->f, Qescape_glyph, 0,
6756 it->face_id);
6757 last_escape_glyph_frame = it->f;
6758 last_escape_glyph_face_id = it->face_id;
6759 last_escape_glyph_merged_face_id = face_id;
6760 }
6761
6762 XSETINT (it->ctl_chars[0], g);
6763 XSETINT (it->ctl_chars[1], c ^ 0100);
6764 ctl_len = 2;
6765 goto display_control;
6766 }
6767
6768 /* Handle non-ascii space in the mode where it only gets
6769 highlighting. */
6770
6771 if (nonascii_space_p && EQ (Vnobreak_char_display, Qt))
6772 {
6773 /* Merge `nobreak-space' into the current face. */
6774 face_id = merge_faces (it->f, Qnobreak_space, 0,
6775 it->face_id);
6776 XSETINT (it->ctl_chars[0], ' ');
6777 ctl_len = 1;
6778 goto display_control;
6779 }
6780
6781 /* Handle sequences that start with the "escape glyph". */
6782
6783 /* the default escape glyph is \. */
6784 escape_glyph = '\\';
6785
6786 if (it->dp
6787 && (gc = DISP_ESCAPE_GLYPH (it->dp), GLYPH_CODE_P (gc)))
6788 {
6789 escape_glyph = GLYPH_CODE_CHAR (gc);
6790 lface_id = GLYPH_CODE_FACE (gc);
6791 }
6792 if (lface_id)
6793 {
6794 /* The display table specified a face.
6795 Merge it into face_id and also into escape_glyph. */
6796 face_id = merge_faces (it->f, Qt, lface_id,
6797 it->face_id);
6798 }
6799 else if (it->f == last_escape_glyph_frame
6800 && it->face_id == last_escape_glyph_face_id)
6801 {
6802 face_id = last_escape_glyph_merged_face_id;
6803 }
6804 else
6805 {
6806 /* Merge the escape-glyph face into the current face. */
6807 face_id = merge_faces (it->f, Qescape_glyph, 0,
6808 it->face_id);
6809 last_escape_glyph_frame = it->f;
6810 last_escape_glyph_face_id = it->face_id;
6811 last_escape_glyph_merged_face_id = face_id;
6812 }
6813
6814 /* Draw non-ASCII hyphen with just highlighting: */
6815
6816 if (nonascii_hyphen_p && EQ (Vnobreak_char_display, Qt))
6817 {
6818 XSETINT (it->ctl_chars[0], '-');
6819 ctl_len = 1;
6820 goto display_control;
6821 }
6822
6823 /* Draw non-ASCII space/hyphen with escape glyph: */
6824
6825 if (nonascii_space_p || nonascii_hyphen_p)
6826 {
6827 XSETINT (it->ctl_chars[0], escape_glyph);
6828 XSETINT (it->ctl_chars[1], nonascii_space_p ? ' ' : '-');
6829 ctl_len = 2;
6830 goto display_control;
6831 }
6832
6833 {
6834 char str[10];
6835 int len, i;
6836
6837 if (CHAR_BYTE8_P (c))
6838 /* Display \200 instead of \17777600. */
6839 c = CHAR_TO_BYTE8 (c);
6840 len = sprintf (str, "%03o", c);
6841
6842 XSETINT (it->ctl_chars[0], escape_glyph);
6843 for (i = 0; i < len; i++)
6844 XSETINT (it->ctl_chars[i + 1], str[i]);
6845 ctl_len = len + 1;
6846 }
6847
6848 display_control:
6849 /* Set up IT->dpvec and return first character from it. */
6850 it->dpvec_char_len = it->len;
6851 it->dpvec = it->ctl_chars;
6852 it->dpend = it->dpvec + ctl_len;
6853 it->current.dpvec_index = 0;
6854 it->dpvec_face_id = face_id;
6855 it->saved_face_id = it->face_id;
6856 it->method = GET_FROM_DISPLAY_VECTOR;
6857 it->ellipsis_p = 0;
6858 goto get_next;
6859 }
6860 it->char_to_display = c;
6861 }
6862 else if (success_p)
6863 {
6864 it->char_to_display = it->c;
6865 }
6866 }
6867
6868 /* Adjust face id for a multibyte character. There are no multibyte
6869 character in unibyte text. */
6870 if ((it->what == IT_CHARACTER || it->what == IT_COMPOSITION)
6871 && it->multibyte_p
6872 && success_p
6873 && FRAME_WINDOW_P (it->f))
6874 {
6875 struct face *face = FACE_FROM_ID (it->f, it->face_id);
6876
6877 if (it->what == IT_COMPOSITION && it->cmp_it.ch >= 0)
6878 {
6879 /* Automatic composition with glyph-string. */
6880 Lisp_Object gstring = composition_gstring_from_id (it->cmp_it.id);
6881
6882 it->face_id = face_for_font (it->f, LGSTRING_FONT (gstring), face);
6883 }
6884 else
6885 {
6886 ptrdiff_t pos = (it->s ? -1
6887 : STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
6888 : IT_CHARPOS (*it));
6889 int c;
6890
6891 if (it->what == IT_CHARACTER)
6892 c = it->char_to_display;
6893 else
6894 {
6895 struct composition *cmp = composition_table[it->cmp_it.id];
6896 int i;
6897
6898 c = ' ';
6899 for (i = 0; i < cmp->glyph_len; i++)
6900 /* TAB in a composition means display glyphs with
6901 padding space on the left or right. */
6902 if ((c = COMPOSITION_GLYPH (cmp, i)) != '\t')
6903 break;
6904 }
6905 it->face_id = FACE_FOR_CHAR (it->f, face, c, pos, it->string);
6906 }
6907 }
6908
6909 done:
6910 /* Is this character the last one of a run of characters with
6911 box? If yes, set IT->end_of_box_run_p to 1. */
6912 if (it->face_box_p
6913 && it->s == NULL)
6914 {
6915 if (it->method == GET_FROM_STRING && it->sp)
6916 {
6917 int face_id = underlying_face_id (it);
6918 struct face *face = FACE_FROM_ID (it->f, face_id);
6919
6920 if (face)
6921 {
6922 if (face->box == FACE_NO_BOX)
6923 {
6924 /* If the box comes from face properties in a
6925 display string, check faces in that string. */
6926 int string_face_id = face_after_it_pos (it);
6927 it->end_of_box_run_p
6928 = (FACE_FROM_ID (it->f, string_face_id)->box
6929 == FACE_NO_BOX);
6930 }
6931 /* Otherwise, the box comes from the underlying face.
6932 If this is the last string character displayed, check
6933 the next buffer location. */
6934 else if ((IT_STRING_CHARPOS (*it) >= SCHARS (it->string) - 1)
6935 && (it->current.overlay_string_index
6936 == it->n_overlay_strings - 1))
6937 {
6938 ptrdiff_t ignore;
6939 int next_face_id;
6940 struct text_pos pos = it->current.pos;
6941 INC_TEXT_POS (pos, it->multibyte_p);
6942
6943 next_face_id = face_at_buffer_position
6944 (it->w, CHARPOS (pos), it->region_beg_charpos,
6945 it->region_end_charpos, &ignore,
6946 (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT), 0,
6947 -1);
6948 it->end_of_box_run_p
6949 = (FACE_FROM_ID (it->f, next_face_id)->box
6950 == FACE_NO_BOX);
6951 }
6952 }
6953 }
6954 else
6955 {
6956 int face_id = face_after_it_pos (it);
6957 it->end_of_box_run_p
6958 = (face_id != it->face_id
6959 && FACE_FROM_ID (it->f, face_id)->box == FACE_NO_BOX);
6960 }
6961 }
6962 /* If we reached the end of the object we've been iterating (e.g., a
6963 display string or an overlay string), and there's something on
6964 IT->stack, proceed with what's on the stack. It doesn't make
6965 sense to return zero if there's unprocessed stuff on the stack,
6966 because otherwise that stuff will never be displayed. */
6967 if (!success_p && it->sp > 0)
6968 {
6969 set_iterator_to_next (it, 0);
6970 success_p = get_next_display_element (it);
6971 }
6972
6973 /* Value is 0 if end of buffer or string reached. */
6974 return success_p;
6975 }
6976
6977
6978 /* Move IT to the next display element.
6979
6980 RESEAT_P non-zero means if called on a newline in buffer text,
6981 skip to the next visible line start.
6982
6983 Functions get_next_display_element and set_iterator_to_next are
6984 separate because I find this arrangement easier to handle than a
6985 get_next_display_element function that also increments IT's
6986 position. The way it is we can first look at an iterator's current
6987 display element, decide whether it fits on a line, and if it does,
6988 increment the iterator position. The other way around we probably
6989 would either need a flag indicating whether the iterator has to be
6990 incremented the next time, or we would have to implement a
6991 decrement position function which would not be easy to write. */
6992
6993 void
6994 set_iterator_to_next (struct it *it, int reseat_p)
6995 {
6996 /* Reset flags indicating start and end of a sequence of characters
6997 with box. Reset them at the start of this function because
6998 moving the iterator to a new position might set them. */
6999 it->start_of_box_run_p = it->end_of_box_run_p = 0;
7000
7001 switch (it->method)
7002 {
7003 case GET_FROM_BUFFER:
7004 /* The current display element of IT is a character from
7005 current_buffer. Advance in the buffer, and maybe skip over
7006 invisible lines that are so because of selective display. */
7007 if (ITERATOR_AT_END_OF_LINE_P (it) && reseat_p)
7008 reseat_at_next_visible_line_start (it, 0);
7009 else if (it->cmp_it.id >= 0)
7010 {
7011 /* We are currently getting glyphs from a composition. */
7012 int i;
7013
7014 if (! it->bidi_p)
7015 {
7016 IT_CHARPOS (*it) += it->cmp_it.nchars;
7017 IT_BYTEPOS (*it) += it->cmp_it.nbytes;
7018 if (it->cmp_it.to < it->cmp_it.nglyphs)
7019 {
7020 it->cmp_it.from = it->cmp_it.to;
7021 }
7022 else
7023 {
7024 it->cmp_it.id = -1;
7025 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
7026 IT_BYTEPOS (*it),
7027 it->end_charpos, Qnil);
7028 }
7029 }
7030 else if (! it->cmp_it.reversed_p)
7031 {
7032 /* Composition created while scanning forward. */
7033 /* Update IT's char/byte positions to point to the first
7034 character of the next grapheme cluster, or to the
7035 character visually after the current composition. */
7036 for (i = 0; i < it->cmp_it.nchars; i++)
7037 bidi_move_to_visually_next (&it->bidi_it);
7038 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
7039 IT_CHARPOS (*it) = it->bidi_it.charpos;
7040
7041 if (it->cmp_it.to < it->cmp_it.nglyphs)
7042 {
7043 /* Proceed to the next grapheme cluster. */
7044 it->cmp_it.from = it->cmp_it.to;
7045 }
7046 else
7047 {
7048 /* No more grapheme clusters in this composition.
7049 Find the next stop position. */
7050 ptrdiff_t stop = it->end_charpos;
7051 if (it->bidi_it.scan_dir < 0)
7052 /* Now we are scanning backward and don't know
7053 where to stop. */
7054 stop = -1;
7055 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
7056 IT_BYTEPOS (*it), stop, Qnil);
7057 }
7058 }
7059 else
7060 {
7061 /* Composition created while scanning backward. */
7062 /* Update IT's char/byte positions to point to the last
7063 character of the previous grapheme cluster, or the
7064 character visually after the current composition. */
7065 for (i = 0; i < it->cmp_it.nchars; i++)
7066 bidi_move_to_visually_next (&it->bidi_it);
7067 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
7068 IT_CHARPOS (*it) = it->bidi_it.charpos;
7069 if (it->cmp_it.from > 0)
7070 {
7071 /* Proceed to the previous grapheme cluster. */
7072 it->cmp_it.to = it->cmp_it.from;
7073 }
7074 else
7075 {
7076 /* No more grapheme clusters in this composition.
7077 Find the next stop position. */
7078 ptrdiff_t stop = it->end_charpos;
7079 if (it->bidi_it.scan_dir < 0)
7080 /* Now we are scanning backward and don't know
7081 where to stop. */
7082 stop = -1;
7083 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
7084 IT_BYTEPOS (*it), stop, Qnil);
7085 }
7086 }
7087 }
7088 else
7089 {
7090 eassert (it->len != 0);
7091
7092 if (!it->bidi_p)
7093 {
7094 IT_BYTEPOS (*it) += it->len;
7095 IT_CHARPOS (*it) += 1;
7096 }
7097 else
7098 {
7099 int prev_scan_dir = it->bidi_it.scan_dir;
7100 /* If this is a new paragraph, determine its base
7101 direction (a.k.a. its base embedding level). */
7102 if (it->bidi_it.new_paragraph)
7103 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 0);
7104 bidi_move_to_visually_next (&it->bidi_it);
7105 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
7106 IT_CHARPOS (*it) = it->bidi_it.charpos;
7107 if (prev_scan_dir != it->bidi_it.scan_dir)
7108 {
7109 /* As the scan direction was changed, we must
7110 re-compute the stop position for composition. */
7111 ptrdiff_t stop = it->end_charpos;
7112 if (it->bidi_it.scan_dir < 0)
7113 stop = -1;
7114 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
7115 IT_BYTEPOS (*it), stop, Qnil);
7116 }
7117 }
7118 eassert (IT_BYTEPOS (*it) == CHAR_TO_BYTE (IT_CHARPOS (*it)));
7119 }
7120 break;
7121
7122 case GET_FROM_C_STRING:
7123 /* Current display element of IT is from a C string. */
7124 if (!it->bidi_p
7125 /* If the string position is beyond string's end, it means
7126 next_element_from_c_string is padding the string with
7127 blanks, in which case we bypass the bidi iterator,
7128 because it cannot deal with such virtual characters. */
7129 || IT_CHARPOS (*it) >= it->bidi_it.string.schars)
7130 {
7131 IT_BYTEPOS (*it) += it->len;
7132 IT_CHARPOS (*it) += 1;
7133 }
7134 else
7135 {
7136 bidi_move_to_visually_next (&it->bidi_it);
7137 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
7138 IT_CHARPOS (*it) = it->bidi_it.charpos;
7139 }
7140 break;
7141
7142 case GET_FROM_DISPLAY_VECTOR:
7143 /* Current display element of IT is from a display table entry.
7144 Advance in the display table definition. Reset it to null if
7145 end reached, and continue with characters from buffers/
7146 strings. */
7147 ++it->current.dpvec_index;
7148
7149 /* Restore face of the iterator to what they were before the
7150 display vector entry (these entries may contain faces). */
7151 it->face_id = it->saved_face_id;
7152
7153 if (it->dpvec + it->current.dpvec_index >= it->dpend)
7154 {
7155 int recheck_faces = it->ellipsis_p;
7156
7157 if (it->s)
7158 it->method = GET_FROM_C_STRING;
7159 else if (STRINGP (it->string))
7160 it->method = GET_FROM_STRING;
7161 else
7162 {
7163 it->method = GET_FROM_BUFFER;
7164 it->object = it->w->buffer;
7165 }
7166
7167 it->dpvec = NULL;
7168 it->current.dpvec_index = -1;
7169
7170 /* Skip over characters which were displayed via IT->dpvec. */
7171 if (it->dpvec_char_len < 0)
7172 reseat_at_next_visible_line_start (it, 1);
7173 else if (it->dpvec_char_len > 0)
7174 {
7175 if (it->method == GET_FROM_STRING
7176 && it->n_overlay_strings > 0)
7177 it->ignore_overlay_strings_at_pos_p = 1;
7178 it->len = it->dpvec_char_len;
7179 set_iterator_to_next (it, reseat_p);
7180 }
7181
7182 /* Maybe recheck faces after display vector */
7183 if (recheck_faces)
7184 it->stop_charpos = IT_CHARPOS (*it);
7185 }
7186 break;
7187
7188 case GET_FROM_STRING:
7189 /* Current display element is a character from a Lisp string. */
7190 eassert (it->s == NULL && STRINGP (it->string));
7191 /* Don't advance past string end. These conditions are true
7192 when set_iterator_to_next is called at the end of
7193 get_next_display_element, in which case the Lisp string is
7194 already exhausted, and all we want is pop the iterator
7195 stack. */
7196 if (it->current.overlay_string_index >= 0)
7197 {
7198 /* This is an overlay string, so there's no padding with
7199 spaces, and the number of characters in the string is
7200 where the string ends. */
7201 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
7202 goto consider_string_end;
7203 }
7204 else
7205 {
7206 /* Not an overlay string. There could be padding, so test
7207 against it->end_charpos . */
7208 if (IT_STRING_CHARPOS (*it) >= it->end_charpos)
7209 goto consider_string_end;
7210 }
7211 if (it->cmp_it.id >= 0)
7212 {
7213 int i;
7214
7215 if (! it->bidi_p)
7216 {
7217 IT_STRING_CHARPOS (*it) += it->cmp_it.nchars;
7218 IT_STRING_BYTEPOS (*it) += it->cmp_it.nbytes;
7219 if (it->cmp_it.to < it->cmp_it.nglyphs)
7220 it->cmp_it.from = it->cmp_it.to;
7221 else
7222 {
7223 it->cmp_it.id = -1;
7224 composition_compute_stop_pos (&it->cmp_it,
7225 IT_STRING_CHARPOS (*it),
7226 IT_STRING_BYTEPOS (*it),
7227 it->end_charpos, it->string);
7228 }
7229 }
7230 else if (! it->cmp_it.reversed_p)
7231 {
7232 for (i = 0; i < it->cmp_it.nchars; i++)
7233 bidi_move_to_visually_next (&it->bidi_it);
7234 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
7235 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
7236
7237 if (it->cmp_it.to < it->cmp_it.nglyphs)
7238 it->cmp_it.from = it->cmp_it.to;
7239 else
7240 {
7241 ptrdiff_t stop = it->end_charpos;
7242 if (it->bidi_it.scan_dir < 0)
7243 stop = -1;
7244 composition_compute_stop_pos (&it->cmp_it,
7245 IT_STRING_CHARPOS (*it),
7246 IT_STRING_BYTEPOS (*it), stop,
7247 it->string);
7248 }
7249 }
7250 else
7251 {
7252 for (i = 0; i < it->cmp_it.nchars; i++)
7253 bidi_move_to_visually_next (&it->bidi_it);
7254 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
7255 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
7256 if (it->cmp_it.from > 0)
7257 it->cmp_it.to = it->cmp_it.from;
7258 else
7259 {
7260 ptrdiff_t stop = it->end_charpos;
7261 if (it->bidi_it.scan_dir < 0)
7262 stop = -1;
7263 composition_compute_stop_pos (&it->cmp_it,
7264 IT_STRING_CHARPOS (*it),
7265 IT_STRING_BYTEPOS (*it), stop,
7266 it->string);
7267 }
7268 }
7269 }
7270 else
7271 {
7272 if (!it->bidi_p
7273 /* If the string position is beyond string's end, it
7274 means next_element_from_string is padding the string
7275 with blanks, in which case we bypass the bidi
7276 iterator, because it cannot deal with such virtual
7277 characters. */
7278 || IT_STRING_CHARPOS (*it) >= it->bidi_it.string.schars)
7279 {
7280 IT_STRING_BYTEPOS (*it) += it->len;
7281 IT_STRING_CHARPOS (*it) += 1;
7282 }
7283 else
7284 {
7285 int prev_scan_dir = it->bidi_it.scan_dir;
7286
7287 bidi_move_to_visually_next (&it->bidi_it);
7288 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
7289 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
7290 if (prev_scan_dir != it->bidi_it.scan_dir)
7291 {
7292 ptrdiff_t stop = it->end_charpos;
7293
7294 if (it->bidi_it.scan_dir < 0)
7295 stop = -1;
7296 composition_compute_stop_pos (&it->cmp_it,
7297 IT_STRING_CHARPOS (*it),
7298 IT_STRING_BYTEPOS (*it), stop,
7299 it->string);
7300 }
7301 }
7302 }
7303
7304 consider_string_end:
7305
7306 if (it->current.overlay_string_index >= 0)
7307 {
7308 /* IT->string is an overlay string. Advance to the
7309 next, if there is one. */
7310 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
7311 {
7312 it->ellipsis_p = 0;
7313 next_overlay_string (it);
7314 if (it->ellipsis_p)
7315 setup_for_ellipsis (it, 0);
7316 }
7317 }
7318 else
7319 {
7320 /* IT->string is not an overlay string. If we reached
7321 its end, and there is something on IT->stack, proceed
7322 with what is on the stack. This can be either another
7323 string, this time an overlay string, or a buffer. */
7324 if (IT_STRING_CHARPOS (*it) == SCHARS (it->string)
7325 && it->sp > 0)
7326 {
7327 pop_it (it);
7328 if (it->method == GET_FROM_STRING)
7329 goto consider_string_end;
7330 }
7331 }
7332 break;
7333
7334 case GET_FROM_IMAGE:
7335 case GET_FROM_STRETCH:
7336 #ifdef HAVE_XWIDGETS
7337 case GET_FROM_XWIDGET:
7338
7339 /* The position etc with which we have to proceed are on
7340 the stack. The position may be at the end of a string,
7341 if the `display' property takes up the whole string. */
7342 eassert (it->sp > 0);
7343 pop_it (it);
7344 if (it->method == GET_FROM_STRING)
7345 goto consider_string_end;
7346 break;
7347 #endif
7348 default:
7349 /* There are no other methods defined, so this should be a bug. */
7350 emacs_abort ();
7351 }
7352
7353 eassert (it->method != GET_FROM_STRING
7354 || (STRINGP (it->string)
7355 && IT_STRING_CHARPOS (*it) >= 0));
7356 }
7357
7358 /* Load IT's display element fields with information about the next
7359 display element which comes from a display table entry or from the
7360 result of translating a control character to one of the forms `^C'
7361 or `\003'.
7362
7363 IT->dpvec holds the glyphs to return as characters.
7364 IT->saved_face_id holds the face id before the display vector--it
7365 is restored into IT->face_id in set_iterator_to_next. */
7366
7367 static int
7368 next_element_from_display_vector (struct it *it)
7369 {
7370 Lisp_Object gc;
7371
7372 /* Precondition. */
7373 eassert (it->dpvec && it->current.dpvec_index >= 0);
7374
7375 it->face_id = it->saved_face_id;
7376
7377 /* KFS: This code used to check ip->dpvec[0] instead of the current element.
7378 That seemed totally bogus - so I changed it... */
7379 gc = it->dpvec[it->current.dpvec_index];
7380
7381 if (GLYPH_CODE_P (gc))
7382 {
7383 it->c = GLYPH_CODE_CHAR (gc);
7384 it->len = CHAR_BYTES (it->c);
7385
7386 /* The entry may contain a face id to use. Such a face id is
7387 the id of a Lisp face, not a realized face. A face id of
7388 zero means no face is specified. */
7389 if (it->dpvec_face_id >= 0)
7390 it->face_id = it->dpvec_face_id;
7391 else
7392 {
7393 int lface_id = GLYPH_CODE_FACE (gc);
7394 if (lface_id > 0)
7395 it->face_id = merge_faces (it->f, Qt, lface_id,
7396 it->saved_face_id);
7397 }
7398 }
7399 else
7400 /* Display table entry is invalid. Return a space. */
7401 it->c = ' ', it->len = 1;
7402
7403 /* Don't change position and object of the iterator here. They are
7404 still the values of the character that had this display table
7405 entry or was translated, and that's what we want. */
7406 it->what = IT_CHARACTER;
7407 return 1;
7408 }
7409
7410 /* Get the first element of string/buffer in the visual order, after
7411 being reseated to a new position in a string or a buffer. */
7412 static void
7413 get_visually_first_element (struct it *it)
7414 {
7415 int string_p = STRINGP (it->string) || it->s;
7416 ptrdiff_t eob = (string_p ? it->bidi_it.string.schars : ZV);
7417 ptrdiff_t bob = (string_p ? 0 : BEGV);
7418
7419 if (STRINGP (it->string))
7420 {
7421 it->bidi_it.charpos = IT_STRING_CHARPOS (*it);
7422 it->bidi_it.bytepos = IT_STRING_BYTEPOS (*it);
7423 }
7424 else
7425 {
7426 it->bidi_it.charpos = IT_CHARPOS (*it);
7427 it->bidi_it.bytepos = IT_BYTEPOS (*it);
7428 }
7429
7430 if (it->bidi_it.charpos == eob)
7431 {
7432 /* Nothing to do, but reset the FIRST_ELT flag, like
7433 bidi_paragraph_init does, because we are not going to
7434 call it. */
7435 it->bidi_it.first_elt = 0;
7436 }
7437 else if (it->bidi_it.charpos == bob
7438 || (!string_p
7439 && (FETCH_CHAR (it->bidi_it.bytepos - 1) == '\n'
7440 || FETCH_CHAR (it->bidi_it.bytepos) == '\n')))
7441 {
7442 /* If we are at the beginning of a line/string, we can produce
7443 the next element right away. */
7444 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1);
7445 bidi_move_to_visually_next (&it->bidi_it);
7446 }
7447 else
7448 {
7449 ptrdiff_t orig_bytepos = it->bidi_it.bytepos;
7450
7451 /* We need to prime the bidi iterator starting at the line's or
7452 string's beginning, before we will be able to produce the
7453 next element. */
7454 if (string_p)
7455 it->bidi_it.charpos = it->bidi_it.bytepos = 0;
7456 else
7457 {
7458 it->bidi_it.charpos = find_next_newline_no_quit (IT_CHARPOS (*it),
7459 -1);
7460 it->bidi_it.bytepos = CHAR_TO_BYTE (it->bidi_it.charpos);
7461 }
7462 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1);
7463 do
7464 {
7465 /* Now return to buffer/string position where we were asked
7466 to get the next display element, and produce that. */
7467 bidi_move_to_visually_next (&it->bidi_it);
7468 }
7469 while (it->bidi_it.bytepos != orig_bytepos
7470 && it->bidi_it.charpos < eob);
7471 }
7472
7473 /* Adjust IT's position information to where we ended up. */
7474 if (STRINGP (it->string))
7475 {
7476 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
7477 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
7478 }
7479 else
7480 {
7481 IT_CHARPOS (*it) = it->bidi_it.charpos;
7482 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
7483 }
7484
7485 if (STRINGP (it->string) || !it->s)
7486 {
7487 ptrdiff_t stop, charpos, bytepos;
7488
7489 if (STRINGP (it->string))
7490 {
7491 eassert (!it->s);
7492 stop = SCHARS (it->string);
7493 if (stop > it->end_charpos)
7494 stop = it->end_charpos;
7495 charpos = IT_STRING_CHARPOS (*it);
7496 bytepos = IT_STRING_BYTEPOS (*it);
7497 }
7498 else
7499 {
7500 stop = it->end_charpos;
7501 charpos = IT_CHARPOS (*it);
7502 bytepos = IT_BYTEPOS (*it);
7503 }
7504 if (it->bidi_it.scan_dir < 0)
7505 stop = -1;
7506 composition_compute_stop_pos (&it->cmp_it, charpos, bytepos, stop,
7507 it->string);
7508 }
7509 }
7510
7511 /* Load IT with the next display element from Lisp string IT->string.
7512 IT->current.string_pos is the current position within the string.
7513 If IT->current.overlay_string_index >= 0, the Lisp string is an
7514 overlay string. */
7515
7516 static int
7517 next_element_from_string (struct it *it)
7518 {
7519 struct text_pos position;
7520
7521 eassert (STRINGP (it->string));
7522 eassert (!it->bidi_p || EQ (it->string, it->bidi_it.string.lstring));
7523 eassert (IT_STRING_CHARPOS (*it) >= 0);
7524 position = it->current.string_pos;
7525
7526 /* With bidi reordering, the character to display might not be the
7527 character at IT_STRING_CHARPOS. BIDI_IT.FIRST_ELT non-zero means
7528 that we were reseat()ed to a new string, whose paragraph
7529 direction is not known. */
7530 if (it->bidi_p && it->bidi_it.first_elt)
7531 {
7532 get_visually_first_element (it);
7533 SET_TEXT_POS (position, IT_STRING_CHARPOS (*it), IT_STRING_BYTEPOS (*it));
7534 }
7535
7536 /* Time to check for invisible text? */
7537 if (IT_STRING_CHARPOS (*it) < it->end_charpos)
7538 {
7539 if (IT_STRING_CHARPOS (*it) >= it->stop_charpos)
7540 {
7541 if (!(!it->bidi_p
7542 || BIDI_AT_BASE_LEVEL (it->bidi_it)
7543 || IT_STRING_CHARPOS (*it) == it->stop_charpos))
7544 {
7545 /* With bidi non-linear iteration, we could find
7546 ourselves far beyond the last computed stop_charpos,
7547 with several other stop positions in between that we
7548 missed. Scan them all now, in buffer's logical
7549 order, until we find and handle the last stop_charpos
7550 that precedes our current position. */
7551 handle_stop_backwards (it, it->stop_charpos);
7552 return GET_NEXT_DISPLAY_ELEMENT (it);
7553 }
7554 else
7555 {
7556 if (it->bidi_p)
7557 {
7558 /* Take note of the stop position we just moved
7559 across, for when we will move back across it. */
7560 it->prev_stop = it->stop_charpos;
7561 /* If we are at base paragraph embedding level, take
7562 note of the last stop position seen at this
7563 level. */
7564 if (BIDI_AT_BASE_LEVEL (it->bidi_it))
7565 it->base_level_stop = it->stop_charpos;
7566 }
7567 handle_stop (it);
7568
7569 /* Since a handler may have changed IT->method, we must
7570 recurse here. */
7571 return GET_NEXT_DISPLAY_ELEMENT (it);
7572 }
7573 }
7574 else if (it->bidi_p
7575 /* If we are before prev_stop, we may have overstepped
7576 on our way backwards a stop_pos, and if so, we need
7577 to handle that stop_pos. */
7578 && IT_STRING_CHARPOS (*it) < it->prev_stop
7579 /* We can sometimes back up for reasons that have nothing
7580 to do with bidi reordering. E.g., compositions. The
7581 code below is only needed when we are above the base
7582 embedding level, so test for that explicitly. */
7583 && !BIDI_AT_BASE_LEVEL (it->bidi_it))
7584 {
7585 /* If we lost track of base_level_stop, we have no better
7586 place for handle_stop_backwards to start from than string
7587 beginning. This happens, e.g., when we were reseated to
7588 the previous screenful of text by vertical-motion. */
7589 if (it->base_level_stop <= 0
7590 || IT_STRING_CHARPOS (*it) < it->base_level_stop)
7591 it->base_level_stop = 0;
7592 handle_stop_backwards (it, it->base_level_stop);
7593 return GET_NEXT_DISPLAY_ELEMENT (it);
7594 }
7595 }
7596
7597 if (it->current.overlay_string_index >= 0)
7598 {
7599 /* Get the next character from an overlay string. In overlay
7600 strings, there is no field width or padding with spaces to
7601 do. */
7602 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
7603 {
7604 it->what = IT_EOB;
7605 return 0;
7606 }
7607 else if (CHAR_COMPOSED_P (it, IT_STRING_CHARPOS (*it),
7608 IT_STRING_BYTEPOS (*it),
7609 it->bidi_it.scan_dir < 0
7610 ? -1
7611 : SCHARS (it->string))
7612 && next_element_from_composition (it))
7613 {
7614 return 1;
7615 }
7616 else if (STRING_MULTIBYTE (it->string))
7617 {
7618 const unsigned char *s = (SDATA (it->string)
7619 + IT_STRING_BYTEPOS (*it));
7620 it->c = string_char_and_length (s, &it->len);
7621 }
7622 else
7623 {
7624 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
7625 it->len = 1;
7626 }
7627 }
7628 else
7629 {
7630 /* Get the next character from a Lisp string that is not an
7631 overlay string. Such strings come from the mode line, for
7632 example. We may have to pad with spaces, or truncate the
7633 string. See also next_element_from_c_string. */
7634 if (IT_STRING_CHARPOS (*it) >= it->end_charpos)
7635 {
7636 it->what = IT_EOB;
7637 return 0;
7638 }
7639 else if (IT_STRING_CHARPOS (*it) >= it->string_nchars)
7640 {
7641 /* Pad with spaces. */
7642 it->c = ' ', it->len = 1;
7643 CHARPOS (position) = BYTEPOS (position) = -1;
7644 }
7645 else if (CHAR_COMPOSED_P (it, IT_STRING_CHARPOS (*it),
7646 IT_STRING_BYTEPOS (*it),
7647 it->bidi_it.scan_dir < 0
7648 ? -1
7649 : it->string_nchars)
7650 && next_element_from_composition (it))
7651 {
7652 return 1;
7653 }
7654 else if (STRING_MULTIBYTE (it->string))
7655 {
7656 const unsigned char *s = (SDATA (it->string)
7657 + IT_STRING_BYTEPOS (*it));
7658 it->c = string_char_and_length (s, &it->len);
7659 }
7660 else
7661 {
7662 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
7663 it->len = 1;
7664 }
7665 }
7666
7667 /* Record what we have and where it came from. */
7668 it->what = IT_CHARACTER;
7669 it->object = it->string;
7670 it->position = position;
7671 return 1;
7672 }
7673
7674
7675 /* Load IT with next display element from C string IT->s.
7676 IT->string_nchars is the maximum number of characters to return
7677 from the string. IT->end_charpos may be greater than
7678 IT->string_nchars when this function is called, in which case we
7679 may have to return padding spaces. Value is zero if end of string
7680 reached, including padding spaces. */
7681
7682 static int
7683 next_element_from_c_string (struct it *it)
7684 {
7685 int success_p = 1;
7686
7687 eassert (it->s);
7688 eassert (!it->bidi_p || it->s == it->bidi_it.string.s);
7689 it->what = IT_CHARACTER;
7690 BYTEPOS (it->position) = CHARPOS (it->position) = 0;
7691 it->object = Qnil;
7692
7693 /* With bidi reordering, the character to display might not be the
7694 character at IT_CHARPOS. BIDI_IT.FIRST_ELT non-zero means that
7695 we were reseated to a new string, whose paragraph direction is
7696 not known. */
7697 if (it->bidi_p && it->bidi_it.first_elt)
7698 get_visually_first_element (it);
7699
7700 /* IT's position can be greater than IT->string_nchars in case a
7701 field width or precision has been specified when the iterator was
7702 initialized. */
7703 if (IT_CHARPOS (*it) >= it->end_charpos)
7704 {
7705 /* End of the game. */
7706 it->what = IT_EOB;
7707 success_p = 0;
7708 }
7709 else if (IT_CHARPOS (*it) >= it->string_nchars)
7710 {
7711 /* Pad with spaces. */
7712 it->c = ' ', it->len = 1;
7713 BYTEPOS (it->position) = CHARPOS (it->position) = -1;
7714 }
7715 else if (it->multibyte_p)
7716 it->c = string_char_and_length (it->s + IT_BYTEPOS (*it), &it->len);
7717 else
7718 it->c = it->s[IT_BYTEPOS (*it)], it->len = 1;
7719
7720 return success_p;
7721 }
7722
7723
7724 /* Set up IT to return characters from an ellipsis, if appropriate.
7725 The definition of the ellipsis glyphs may come from a display table
7726 entry. This function fills IT with the first glyph from the
7727 ellipsis if an ellipsis is to be displayed. */
7728
7729 static int
7730 next_element_from_ellipsis (struct it *it)
7731 {
7732 if (it->selective_display_ellipsis_p)
7733 setup_for_ellipsis (it, it->len);
7734 else
7735 {
7736 /* The face at the current position may be different from the
7737 face we find after the invisible text. Remember what it
7738 was in IT->saved_face_id, and signal that it's there by
7739 setting face_before_selective_p. */
7740 it->saved_face_id = it->face_id;
7741 it->method = GET_FROM_BUFFER;
7742 it->object = it->w->buffer;
7743 reseat_at_next_visible_line_start (it, 1);
7744 it->face_before_selective_p = 1;
7745 }
7746
7747 return GET_NEXT_DISPLAY_ELEMENT (it);
7748 }
7749
7750
7751 /* Deliver an image display element. The iterator IT is already
7752 filled with image information (done in handle_display_prop). Value
7753 is always 1. */
7754
7755
7756 static int
7757 next_element_from_image (struct it *it)
7758 {
7759 it->what = IT_IMAGE;
7760 it->ignore_overlay_strings_at_pos_p = 0;
7761 return 1;
7762 }
7763
7764 #ifdef HAVE_XWIDGETS
7765 /* im not sure about this FIXME JAVE*/
7766 static int
7767 next_element_from_xwidget (struct it *it)
7768 {
7769 it->what = IT_XWIDGET;
7770 //assert_valid_xwidget_id(it->xwidget_id,"next_element_from_xwidget");
7771 //this is shaky because why do we set "what" if we dont set the other parts??
7772 //printf("xwidget_id %d: in next_element_from_xwidget: FIXME \n", it->xwidget_id);
7773 return 1;
7774 }
7775 #endif
7776
7777
7778 /* Fill iterator IT with next display element from a stretch glyph
7779 property. IT->object is the value of the text property. Value is
7780 always 1. */
7781
7782 static int
7783 next_element_from_stretch (struct it *it)
7784 {
7785 it->what = IT_STRETCH;
7786 return 1;
7787 }
7788
7789 /* Scan backwards from IT's current position until we find a stop
7790 position, or until BEGV. This is called when we find ourself
7791 before both the last known prev_stop and base_level_stop while
7792 reordering bidirectional text. */
7793
7794 static void
7795 compute_stop_pos_backwards (struct it *it)
7796 {
7797 const int SCAN_BACK_LIMIT = 1000;
7798 struct text_pos pos;
7799 struct display_pos save_current = it->current;
7800 struct text_pos save_position = it->position;
7801 ptrdiff_t charpos = IT_CHARPOS (*it);
7802 ptrdiff_t where_we_are = charpos;
7803 ptrdiff_t save_stop_pos = it->stop_charpos;
7804 ptrdiff_t save_end_pos = it->end_charpos;
7805
7806 eassert (NILP (it->string) && !it->s);
7807 eassert (it->bidi_p);
7808 it->bidi_p = 0;
7809 do
7810 {
7811 it->end_charpos = min (charpos + 1, ZV);
7812 charpos = max (charpos - SCAN_BACK_LIMIT, BEGV);
7813 SET_TEXT_POS (pos, charpos, BYTE_TO_CHAR (charpos));
7814 reseat_1 (it, pos, 0);
7815 compute_stop_pos (it);
7816 /* We must advance forward, right? */
7817 if (it->stop_charpos <= charpos)
7818 emacs_abort ();
7819 }
7820 while (charpos > BEGV && it->stop_charpos >= it->end_charpos);
7821
7822 if (it->stop_charpos <= where_we_are)
7823 it->prev_stop = it->stop_charpos;
7824 else
7825 it->prev_stop = BEGV;
7826 it->bidi_p = 1;
7827 it->current = save_current;
7828 it->position = save_position;
7829 it->stop_charpos = save_stop_pos;
7830 it->end_charpos = save_end_pos;
7831 }
7832
7833 /* Scan forward from CHARPOS in the current buffer/string, until we
7834 find a stop position > current IT's position. Then handle the stop
7835 position before that. This is called when we bump into a stop
7836 position while reordering bidirectional text. CHARPOS should be
7837 the last previously processed stop_pos (or BEGV/0, if none were
7838 processed yet) whose position is less that IT's current
7839 position. */
7840
7841 static void
7842 handle_stop_backwards (struct it *it, ptrdiff_t charpos)
7843 {
7844 int bufp = !STRINGP (it->string);
7845 ptrdiff_t where_we_are = (bufp ? IT_CHARPOS (*it) : IT_STRING_CHARPOS (*it));
7846 struct display_pos save_current = it->current;
7847 struct text_pos save_position = it->position;
7848 struct text_pos pos1;
7849 ptrdiff_t next_stop;
7850
7851 /* Scan in strict logical order. */
7852 eassert (it->bidi_p);
7853 it->bidi_p = 0;
7854 do
7855 {
7856 it->prev_stop = charpos;
7857 if (bufp)
7858 {
7859 SET_TEXT_POS (pos1, charpos, CHAR_TO_BYTE (charpos));
7860 reseat_1 (it, pos1, 0);
7861 }
7862 else
7863 it->current.string_pos = string_pos (charpos, it->string);
7864 compute_stop_pos (it);
7865 /* We must advance forward, right? */
7866 if (it->stop_charpos <= it->prev_stop)
7867 emacs_abort ();
7868 charpos = it->stop_charpos;
7869 }
7870 while (charpos <= where_we_are);
7871
7872 it->bidi_p = 1;
7873 it->current = save_current;
7874 it->position = save_position;
7875 next_stop = it->stop_charpos;
7876 it->stop_charpos = it->prev_stop;
7877 handle_stop (it);
7878 it->stop_charpos = next_stop;
7879 }
7880
7881 /* Load IT with the next display element from current_buffer. Value
7882 is zero if end of buffer reached. IT->stop_charpos is the next
7883 position at which to stop and check for text properties or buffer
7884 end. */
7885
7886 static int
7887 next_element_from_buffer (struct it *it)
7888 {
7889 int success_p = 1;
7890
7891 eassert (IT_CHARPOS (*it) >= BEGV);
7892 eassert (NILP (it->string) && !it->s);
7893 eassert (!it->bidi_p
7894 || (EQ (it->bidi_it.string.lstring, Qnil)
7895 && it->bidi_it.string.s == NULL));
7896
7897 /* With bidi reordering, the character to display might not be the
7898 character at IT_CHARPOS. BIDI_IT.FIRST_ELT non-zero means that
7899 we were reseat()ed to a new buffer position, which is potentially
7900 a different paragraph. */
7901 if (it->bidi_p && it->bidi_it.first_elt)
7902 {
7903 get_visually_first_element (it);
7904 SET_TEXT_POS (it->position, IT_CHARPOS (*it), IT_BYTEPOS (*it));
7905 }
7906
7907 if (IT_CHARPOS (*it) >= it->stop_charpos)
7908 {
7909 if (IT_CHARPOS (*it) >= it->end_charpos)
7910 {
7911 int overlay_strings_follow_p;
7912
7913 /* End of the game, except when overlay strings follow that
7914 haven't been returned yet. */
7915 if (it->overlay_strings_at_end_processed_p)
7916 overlay_strings_follow_p = 0;
7917 else
7918 {
7919 it->overlay_strings_at_end_processed_p = 1;
7920 overlay_strings_follow_p = get_overlay_strings (it, 0);
7921 }
7922
7923 if (overlay_strings_follow_p)
7924 success_p = GET_NEXT_DISPLAY_ELEMENT (it);
7925 else
7926 {
7927 it->what = IT_EOB;
7928 it->position = it->current.pos;
7929 success_p = 0;
7930 }
7931 }
7932 else if (!(!it->bidi_p
7933 || BIDI_AT_BASE_LEVEL (it->bidi_it)
7934 || IT_CHARPOS (*it) == it->stop_charpos))
7935 {
7936 /* With bidi non-linear iteration, we could find ourselves
7937 far beyond the last computed stop_charpos, with several
7938 other stop positions in between that we missed. Scan
7939 them all now, in buffer's logical order, until we find
7940 and handle the last stop_charpos that precedes our
7941 current position. */
7942 handle_stop_backwards (it, it->stop_charpos);
7943 return GET_NEXT_DISPLAY_ELEMENT (it);
7944 }
7945 else
7946 {
7947 if (it->bidi_p)
7948 {
7949 /* Take note of the stop position we just moved across,
7950 for when we will move back across it. */
7951 it->prev_stop = it->stop_charpos;
7952 /* If we are at base paragraph embedding level, take
7953 note of the last stop position seen at this
7954 level. */
7955 if (BIDI_AT_BASE_LEVEL (it->bidi_it))
7956 it->base_level_stop = it->stop_charpos;
7957 }
7958 handle_stop (it);
7959 return GET_NEXT_DISPLAY_ELEMENT (it);
7960 }
7961 }
7962 else if (it->bidi_p
7963 /* If we are before prev_stop, we may have overstepped on
7964 our way backwards a stop_pos, and if so, we need to
7965 handle that stop_pos. */
7966 && IT_CHARPOS (*it) < it->prev_stop
7967 /* We can sometimes back up for reasons that have nothing
7968 to do with bidi reordering. E.g., compositions. The
7969 code below is only needed when we are above the base
7970 embedding level, so test for that explicitly. */
7971 && !BIDI_AT_BASE_LEVEL (it->bidi_it))
7972 {
7973 if (it->base_level_stop <= 0
7974 || IT_CHARPOS (*it) < it->base_level_stop)
7975 {
7976 /* If we lost track of base_level_stop, we need to find
7977 prev_stop by looking backwards. This happens, e.g., when
7978 we were reseated to the previous screenful of text by
7979 vertical-motion. */
7980 it->base_level_stop = BEGV;
7981 compute_stop_pos_backwards (it);
7982 handle_stop_backwards (it, it->prev_stop);
7983 }
7984 else
7985 handle_stop_backwards (it, it->base_level_stop);
7986 return GET_NEXT_DISPLAY_ELEMENT (it);
7987 }
7988 else
7989 {
7990 /* No face changes, overlays etc. in sight, so just return a
7991 character from current_buffer. */
7992 unsigned char *p;
7993 ptrdiff_t stop;
7994
7995 /* Maybe run the redisplay end trigger hook. Performance note:
7996 This doesn't seem to cost measurable time. */
7997 if (it->redisplay_end_trigger_charpos
7998 && it->glyph_row
7999 && IT_CHARPOS (*it) >= it->redisplay_end_trigger_charpos)
8000 run_redisplay_end_trigger_hook (it);
8001
8002 stop = it->bidi_it.scan_dir < 0 ? -1 : it->end_charpos;
8003 if (CHAR_COMPOSED_P (it, IT_CHARPOS (*it), IT_BYTEPOS (*it),
8004 stop)
8005 && next_element_from_composition (it))
8006 {
8007 return 1;
8008 }
8009
8010 /* Get the next character, maybe multibyte. */
8011 p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
8012 if (it->multibyte_p && !ASCII_BYTE_P (*p))
8013 it->c = STRING_CHAR_AND_LENGTH (p, it->len);
8014 else
8015 it->c = *p, it->len = 1;
8016
8017 /* Record what we have and where it came from. */
8018 it->what = IT_CHARACTER;
8019 it->object = it->w->buffer;
8020 it->position = it->current.pos;
8021
8022 /* Normally we return the character found above, except when we
8023 really want to return an ellipsis for selective display. */
8024 if (it->selective)
8025 {
8026 if (it->c == '\n')
8027 {
8028 /* A value of selective > 0 means hide lines indented more
8029 than that number of columns. */
8030 if (it->selective > 0
8031 && IT_CHARPOS (*it) + 1 < ZV
8032 && indented_beyond_p (IT_CHARPOS (*it) + 1,
8033 IT_BYTEPOS (*it) + 1,
8034 it->selective))
8035 {
8036 success_p = next_element_from_ellipsis (it);
8037 it->dpvec_char_len = -1;
8038 }
8039 }
8040 else if (it->c == '\r' && it->selective == -1)
8041 {
8042 /* A value of selective == -1 means that everything from the
8043 CR to the end of the line is invisible, with maybe an
8044 ellipsis displayed for it. */
8045 success_p = next_element_from_ellipsis (it);
8046 it->dpvec_char_len = -1;
8047 }
8048 }
8049 }
8050
8051 /* Value is zero if end of buffer reached. */
8052 eassert (!success_p || it->what != IT_CHARACTER || it->len > 0);
8053 return success_p;
8054 }
8055
8056
8057 /* Run the redisplay end trigger hook for IT. */
8058
8059 static void
8060 run_redisplay_end_trigger_hook (struct it *it)
8061 {
8062 Lisp_Object args[3];
8063
8064 /* IT->glyph_row should be non-null, i.e. we should be actually
8065 displaying something, or otherwise we should not run the hook. */
8066 eassert (it->glyph_row);
8067
8068 /* Set up hook arguments. */
8069 args[0] = Qredisplay_end_trigger_functions;
8070 args[1] = it->window;
8071 XSETINT (args[2], it->redisplay_end_trigger_charpos);
8072 it->redisplay_end_trigger_charpos = 0;
8073
8074 /* Since we are *trying* to run these functions, don't try to run
8075 them again, even if they get an error. */
8076 wset_redisplay_end_trigger (it->w, Qnil);
8077 Frun_hook_with_args (3, args);
8078
8079 /* Notice if it changed the face of the character we are on. */
8080 handle_face_prop (it);
8081 }
8082
8083
8084 /* Deliver a composition display element. Unlike the other
8085 next_element_from_XXX, this function is not registered in the array
8086 get_next_element[]. It is called from next_element_from_buffer and
8087 next_element_from_string when necessary. */
8088
8089 static int
8090 next_element_from_composition (struct it *it)
8091 {
8092 it->what = IT_COMPOSITION;
8093 it->len = it->cmp_it.nbytes;
8094 if (STRINGP (it->string))
8095 {
8096 if (it->c < 0)
8097 {
8098 IT_STRING_CHARPOS (*it) += it->cmp_it.nchars;
8099 IT_STRING_BYTEPOS (*it) += it->cmp_it.nbytes;
8100 return 0;
8101 }
8102 it->position = it->current.string_pos;
8103 it->object = it->string;
8104 it->c = composition_update_it (&it->cmp_it, IT_STRING_CHARPOS (*it),
8105 IT_STRING_BYTEPOS (*it), it->string);
8106 }
8107 else
8108 {
8109 if (it->c < 0)
8110 {
8111 IT_CHARPOS (*it) += it->cmp_it.nchars;
8112 IT_BYTEPOS (*it) += it->cmp_it.nbytes;
8113 if (it->bidi_p)
8114 {
8115 if (it->bidi_it.new_paragraph)
8116 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 0);
8117 /* Resync the bidi iterator with IT's new position.
8118 FIXME: this doesn't support bidirectional text. */
8119 while (it->bidi_it.charpos < IT_CHARPOS (*it))
8120 bidi_move_to_visually_next (&it->bidi_it);
8121 }
8122 return 0;
8123 }
8124 it->position = it->current.pos;
8125 it->object = it->w->buffer;
8126 it->c = composition_update_it (&it->cmp_it, IT_CHARPOS (*it),
8127 IT_BYTEPOS (*it), Qnil);
8128 }
8129 return 1;
8130 }
8131
8132
8133 \f
8134 /***********************************************************************
8135 Moving an iterator without producing glyphs
8136 ***********************************************************************/
8137
8138 /* Check if iterator is at a position corresponding to a valid buffer
8139 position after some move_it_ call. */
8140
8141 #define IT_POS_VALID_AFTER_MOVE_P(it) \
8142 ((it)->method == GET_FROM_STRING \
8143 ? IT_STRING_CHARPOS (*it) == 0 \
8144 : 1)
8145
8146
8147 /* Move iterator IT to a specified buffer or X position within one
8148 line on the display without producing glyphs.
8149
8150 OP should be a bit mask including some or all of these bits:
8151 MOVE_TO_X: Stop upon reaching x-position TO_X.
8152 MOVE_TO_POS: Stop upon reaching buffer or string position TO_CHARPOS.
8153 Regardless of OP's value, stop upon reaching the end of the display line.
8154
8155 TO_X is normally a value 0 <= TO_X <= IT->last_visible_x.
8156 This means, in particular, that TO_X includes window's horizontal
8157 scroll amount.
8158
8159 The return value has several possible values that
8160 say what condition caused the scan to stop:
8161
8162 MOVE_POS_MATCH_OR_ZV
8163 - when TO_POS or ZV was reached.
8164
8165 MOVE_X_REACHED
8166 -when TO_X was reached before TO_POS or ZV were reached.
8167
8168 MOVE_LINE_CONTINUED
8169 - when we reached the end of the display area and the line must
8170 be continued.
8171
8172 MOVE_LINE_TRUNCATED
8173 - when we reached the end of the display area and the line is
8174 truncated.
8175
8176 MOVE_NEWLINE_OR_CR
8177 - when we stopped at a line end, i.e. a newline or a CR and selective
8178 display is on. */
8179
8180 static enum move_it_result
8181 move_it_in_display_line_to (struct it *it,
8182 ptrdiff_t to_charpos, int to_x,
8183 enum move_operation_enum op)
8184 {
8185 enum move_it_result result = MOVE_UNDEFINED;
8186 struct glyph_row *saved_glyph_row;
8187 struct it wrap_it, atpos_it, atx_it, ppos_it;
8188 void *wrap_data = NULL, *atpos_data = NULL, *atx_data = NULL;
8189 void *ppos_data = NULL;
8190 int may_wrap = 0;
8191 enum it_method prev_method = it->method;
8192 ptrdiff_t prev_pos = IT_CHARPOS (*it);
8193 int saw_smaller_pos = prev_pos < to_charpos;
8194
8195 /* Don't produce glyphs in produce_glyphs. */
8196 saved_glyph_row = it->glyph_row;
8197 it->glyph_row = NULL;
8198
8199 /* Use wrap_it to save a copy of IT wherever a word wrap could
8200 occur. Use atpos_it to save a copy of IT at the desired buffer
8201 position, if found, so that we can scan ahead and check if the
8202 word later overshoots the window edge. Use atx_it similarly, for
8203 pixel positions. */
8204 wrap_it.sp = -1;
8205 atpos_it.sp = -1;
8206 atx_it.sp = -1;
8207
8208 /* Use ppos_it under bidi reordering to save a copy of IT for the
8209 position > CHARPOS that is the closest to CHARPOS. We restore
8210 that position in IT when we have scanned the entire display line
8211 without finding a match for CHARPOS and all the character
8212 positions are greater than CHARPOS. */
8213 if (it->bidi_p)
8214 {
8215 SAVE_IT (ppos_it, *it, ppos_data);
8216 SET_TEXT_POS (ppos_it.current.pos, ZV, ZV_BYTE);
8217 if ((op & MOVE_TO_POS) && IT_CHARPOS (*it) >= to_charpos)
8218 SAVE_IT (ppos_it, *it, ppos_data);
8219 }
8220
8221 #define BUFFER_POS_REACHED_P() \
8222 ((op & MOVE_TO_POS) != 0 \
8223 && BUFFERP (it->object) \
8224 && (IT_CHARPOS (*it) == to_charpos \
8225 || ((!it->bidi_p \
8226 || BIDI_AT_BASE_LEVEL (it->bidi_it)) \
8227 && IT_CHARPOS (*it) > to_charpos) \
8228 || (it->what == IT_COMPOSITION \
8229 && ((IT_CHARPOS (*it) > to_charpos \
8230 && to_charpos >= it->cmp_it.charpos) \
8231 || (IT_CHARPOS (*it) < to_charpos \
8232 && to_charpos <= it->cmp_it.charpos)))) \
8233 && (it->method == GET_FROM_BUFFER \
8234 || (it->method == GET_FROM_DISPLAY_VECTOR \
8235 && it->dpvec + it->current.dpvec_index + 1 >= it->dpend)))
8236
8237 /* If there's a line-/wrap-prefix, handle it. */
8238 if (it->hpos == 0 && it->method == GET_FROM_BUFFER
8239 && it->current_y < it->last_visible_y)
8240 handle_line_prefix (it);
8241
8242 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
8243 SET_TEXT_POS (this_line_min_pos, IT_CHARPOS (*it), IT_BYTEPOS (*it));
8244
8245 while (1)
8246 {
8247 int x, i, ascent = 0, descent = 0;
8248
8249 /* Utility macro to reset an iterator with x, ascent, and descent. */
8250 #define IT_RESET_X_ASCENT_DESCENT(IT) \
8251 ((IT)->current_x = x, (IT)->max_ascent = ascent, \
8252 (IT)->max_descent = descent)
8253
8254 /* Stop if we move beyond TO_CHARPOS (after an image or a
8255 display string or stretch glyph). */
8256 if ((op & MOVE_TO_POS) != 0
8257 && BUFFERP (it->object)
8258 && it->method == GET_FROM_BUFFER
8259 && (((!it->bidi_p
8260 /* When the iterator is at base embedding level, we
8261 are guaranteed that characters are delivered for
8262 display in strictly increasing order of their
8263 buffer positions. */
8264 || BIDI_AT_BASE_LEVEL (it->bidi_it))
8265 && IT_CHARPOS (*it) > to_charpos)
8266 || (it->bidi_p
8267 && (prev_method == GET_FROM_IMAGE
8268 || prev_method == GET_FROM_STRETCH
8269 || prev_method == GET_FROM_STRING)
8270 /* Passed TO_CHARPOS from left to right. */
8271 && ((prev_pos < to_charpos
8272 && IT_CHARPOS (*it) > to_charpos)
8273 /* Passed TO_CHARPOS from right to left. */
8274 || (prev_pos > to_charpos
8275 && IT_CHARPOS (*it) < to_charpos)))))
8276 {
8277 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
8278 {
8279 result = MOVE_POS_MATCH_OR_ZV;
8280 break;
8281 }
8282 else if (it->line_wrap == WORD_WRAP && atpos_it.sp < 0)
8283 /* If wrap_it is valid, the current position might be in a
8284 word that is wrapped. So, save the iterator in
8285 atpos_it and continue to see if wrapping happens. */
8286 SAVE_IT (atpos_it, *it, atpos_data);
8287 }
8288
8289 /* Stop when ZV reached.
8290 We used to stop here when TO_CHARPOS reached as well, but that is
8291 too soon if this glyph does not fit on this line. So we handle it
8292 explicitly below. */
8293 if (!get_next_display_element (it))
8294 {
8295 result = MOVE_POS_MATCH_OR_ZV;
8296 break;
8297 }
8298
8299 if (it->line_wrap == TRUNCATE)
8300 {
8301 if (BUFFER_POS_REACHED_P ())
8302 {
8303 result = MOVE_POS_MATCH_OR_ZV;
8304 break;
8305 }
8306 }
8307 else
8308 {
8309 if (it->line_wrap == WORD_WRAP)
8310 {
8311 if (IT_DISPLAYING_WHITESPACE (it))
8312 may_wrap = 1;
8313 else if (may_wrap)
8314 {
8315 /* We have reached a glyph that follows one or more
8316 whitespace characters. If the position is
8317 already found, we are done. */
8318 if (atpos_it.sp >= 0)
8319 {
8320 RESTORE_IT (it, &atpos_it, atpos_data);
8321 result = MOVE_POS_MATCH_OR_ZV;
8322 goto done;
8323 }
8324 if (atx_it.sp >= 0)
8325 {
8326 RESTORE_IT (it, &atx_it, atx_data);
8327 result = MOVE_X_REACHED;
8328 goto done;
8329 }
8330 /* Otherwise, we can wrap here. */
8331 SAVE_IT (wrap_it, *it, wrap_data);
8332 may_wrap = 0;
8333 }
8334 }
8335 }
8336
8337 /* Remember the line height for the current line, in case
8338 the next element doesn't fit on the line. */
8339 ascent = it->max_ascent;
8340 descent = it->max_descent;
8341
8342 /* The call to produce_glyphs will get the metrics of the
8343 display element IT is loaded with. Record the x-position
8344 before this display element, in case it doesn't fit on the
8345 line. */
8346 x = it->current_x;
8347
8348 PRODUCE_GLYPHS (it);
8349
8350 if (it->area != TEXT_AREA)
8351 {
8352 prev_method = it->method;
8353 if (it->method == GET_FROM_BUFFER)
8354 prev_pos = IT_CHARPOS (*it);
8355 set_iterator_to_next (it, 1);
8356 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
8357 SET_TEXT_POS (this_line_min_pos,
8358 IT_CHARPOS (*it), IT_BYTEPOS (*it));
8359 if (it->bidi_p
8360 && (op & MOVE_TO_POS)
8361 && IT_CHARPOS (*it) > to_charpos
8362 && IT_CHARPOS (*it) < IT_CHARPOS (ppos_it))
8363 SAVE_IT (ppos_it, *it, ppos_data);
8364 continue;
8365 }
8366
8367 /* The number of glyphs we get back in IT->nglyphs will normally
8368 be 1 except when IT->c is (i) a TAB, or (ii) a multi-glyph
8369 character on a terminal frame, or (iii) a line end. For the
8370 second case, IT->nglyphs - 1 padding glyphs will be present.
8371 (On X frames, there is only one glyph produced for a
8372 composite character.)
8373
8374 The behavior implemented below means, for continuation lines,
8375 that as many spaces of a TAB as fit on the current line are
8376 displayed there. For terminal frames, as many glyphs of a
8377 multi-glyph character are displayed in the current line, too.
8378 This is what the old redisplay code did, and we keep it that
8379 way. Under X, the whole shape of a complex character must
8380 fit on the line or it will be completely displayed in the
8381 next line.
8382
8383 Note that both for tabs and padding glyphs, all glyphs have
8384 the same width. */
8385 if (it->nglyphs)
8386 {
8387 /* More than one glyph or glyph doesn't fit on line. All
8388 glyphs have the same width. */
8389 int single_glyph_width = it->pixel_width / it->nglyphs;
8390 int new_x;
8391 int x_before_this_char = x;
8392 int hpos_before_this_char = it->hpos;
8393
8394 for (i = 0; i < it->nglyphs; ++i, x = new_x)
8395 {
8396 new_x = x + single_glyph_width;
8397
8398 /* We want to leave anything reaching TO_X to the caller. */
8399 if ((op & MOVE_TO_X) && new_x > to_x)
8400 {
8401 if (BUFFER_POS_REACHED_P ())
8402 {
8403 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
8404 goto buffer_pos_reached;
8405 if (atpos_it.sp < 0)
8406 {
8407 SAVE_IT (atpos_it, *it, atpos_data);
8408 IT_RESET_X_ASCENT_DESCENT (&atpos_it);
8409 }
8410 }
8411 else
8412 {
8413 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
8414 {
8415 it->current_x = x;
8416 result = MOVE_X_REACHED;
8417 break;
8418 }
8419 if (atx_it.sp < 0)
8420 {
8421 SAVE_IT (atx_it, *it, atx_data);
8422 IT_RESET_X_ASCENT_DESCENT (&atx_it);
8423 }
8424 }
8425 }
8426
8427 if (/* Lines are continued. */
8428 it->line_wrap != TRUNCATE
8429 && (/* And glyph doesn't fit on the line. */
8430 new_x > it->last_visible_x
8431 /* Or it fits exactly and we're on a window
8432 system frame. */
8433 || (new_x == it->last_visible_x
8434 && FRAME_WINDOW_P (it->f)
8435 && ((it->bidi_p && it->bidi_it.paragraph_dir == R2L)
8436 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
8437 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)))))
8438 {
8439 if (/* IT->hpos == 0 means the very first glyph
8440 doesn't fit on the line, e.g. a wide image. */
8441 it->hpos == 0
8442 || (new_x == it->last_visible_x
8443 && FRAME_WINDOW_P (it->f)))
8444 {
8445 ++it->hpos;
8446 it->current_x = new_x;
8447
8448 /* The character's last glyph just barely fits
8449 in this row. */
8450 if (i == it->nglyphs - 1)
8451 {
8452 /* If this is the destination position,
8453 return a position *before* it in this row,
8454 now that we know it fits in this row. */
8455 if (BUFFER_POS_REACHED_P ())
8456 {
8457 if (it->line_wrap != WORD_WRAP
8458 || wrap_it.sp < 0)
8459 {
8460 it->hpos = hpos_before_this_char;
8461 it->current_x = x_before_this_char;
8462 result = MOVE_POS_MATCH_OR_ZV;
8463 break;
8464 }
8465 if (it->line_wrap == WORD_WRAP
8466 && atpos_it.sp < 0)
8467 {
8468 SAVE_IT (atpos_it, *it, atpos_data);
8469 atpos_it.current_x = x_before_this_char;
8470 atpos_it.hpos = hpos_before_this_char;
8471 }
8472 }
8473
8474 prev_method = it->method;
8475 if (it->method == GET_FROM_BUFFER)
8476 prev_pos = IT_CHARPOS (*it);
8477 set_iterator_to_next (it, 1);
8478 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
8479 SET_TEXT_POS (this_line_min_pos,
8480 IT_CHARPOS (*it), IT_BYTEPOS (*it));
8481 /* On graphical terminals, newlines may
8482 "overflow" into the fringe if
8483 overflow-newline-into-fringe is non-nil.
8484 On text terminals, and on graphical
8485 terminals with no right margin, newlines
8486 may overflow into the last glyph on the
8487 display line.*/
8488 if (!FRAME_WINDOW_P (it->f)
8489 || ((it->bidi_p
8490 && it->bidi_it.paragraph_dir == R2L)
8491 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
8492 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0
8493 || IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
8494 {
8495 if (!get_next_display_element (it))
8496 {
8497 result = MOVE_POS_MATCH_OR_ZV;
8498 break;
8499 }
8500 if (BUFFER_POS_REACHED_P ())
8501 {
8502 if (ITERATOR_AT_END_OF_LINE_P (it))
8503 result = MOVE_POS_MATCH_OR_ZV;
8504 else
8505 result = MOVE_LINE_CONTINUED;
8506 break;
8507 }
8508 if (ITERATOR_AT_END_OF_LINE_P (it))
8509 {
8510 result = MOVE_NEWLINE_OR_CR;
8511 break;
8512 }
8513 }
8514 }
8515 }
8516 else
8517 IT_RESET_X_ASCENT_DESCENT (it);
8518
8519 if (wrap_it.sp >= 0)
8520 {
8521 RESTORE_IT (it, &wrap_it, wrap_data);
8522 atpos_it.sp = -1;
8523 atx_it.sp = -1;
8524 }
8525
8526 TRACE_MOVE ((stderr, "move_it_in: continued at %d\n",
8527 IT_CHARPOS (*it)));
8528 result = MOVE_LINE_CONTINUED;
8529 break;
8530 }
8531
8532 if (BUFFER_POS_REACHED_P ())
8533 {
8534 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
8535 goto buffer_pos_reached;
8536 if (it->line_wrap == WORD_WRAP && atpos_it.sp < 0)
8537 {
8538 SAVE_IT (atpos_it, *it, atpos_data);
8539 IT_RESET_X_ASCENT_DESCENT (&atpos_it);
8540 }
8541 }
8542
8543 if (new_x > it->first_visible_x)
8544 {
8545 /* Glyph is visible. Increment number of glyphs that
8546 would be displayed. */
8547 ++it->hpos;
8548 }
8549 }
8550
8551 if (result != MOVE_UNDEFINED)
8552 break;
8553 }
8554 else if (BUFFER_POS_REACHED_P ())
8555 {
8556 buffer_pos_reached:
8557 IT_RESET_X_ASCENT_DESCENT (it);
8558 result = MOVE_POS_MATCH_OR_ZV;
8559 break;
8560 }
8561 else if ((op & MOVE_TO_X) && it->current_x >= to_x)
8562 {
8563 /* Stop when TO_X specified and reached. This check is
8564 necessary here because of lines consisting of a line end,
8565 only. The line end will not produce any glyphs and we
8566 would never get MOVE_X_REACHED. */
8567 eassert (it->nglyphs == 0);
8568 result = MOVE_X_REACHED;
8569 break;
8570 }
8571
8572 /* Is this a line end? If yes, we're done. */
8573 if (ITERATOR_AT_END_OF_LINE_P (it))
8574 {
8575 /* If we are past TO_CHARPOS, but never saw any character
8576 positions smaller than TO_CHARPOS, return
8577 MOVE_POS_MATCH_OR_ZV, like the unidirectional display
8578 did. */
8579 if (it->bidi_p && (op & MOVE_TO_POS) != 0)
8580 {
8581 if (!saw_smaller_pos && IT_CHARPOS (*it) > to_charpos)
8582 {
8583 if (IT_CHARPOS (ppos_it) < ZV)
8584 {
8585 RESTORE_IT (it, &ppos_it, ppos_data);
8586 result = MOVE_POS_MATCH_OR_ZV;
8587 }
8588 else
8589 goto buffer_pos_reached;
8590 }
8591 else if (it->line_wrap == WORD_WRAP && atpos_it.sp >= 0
8592 && IT_CHARPOS (*it) > to_charpos)
8593 goto buffer_pos_reached;
8594 else
8595 result = MOVE_NEWLINE_OR_CR;
8596 }
8597 else
8598 result = MOVE_NEWLINE_OR_CR;
8599 break;
8600 }
8601
8602 prev_method = it->method;
8603 if (it->method == GET_FROM_BUFFER)
8604 prev_pos = IT_CHARPOS (*it);
8605 /* The current display element has been consumed. Advance
8606 to the next. */
8607 set_iterator_to_next (it, 1);
8608 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
8609 SET_TEXT_POS (this_line_min_pos, IT_CHARPOS (*it), IT_BYTEPOS (*it));
8610 if (IT_CHARPOS (*it) < to_charpos)
8611 saw_smaller_pos = 1;
8612 if (it->bidi_p
8613 && (op & MOVE_TO_POS)
8614 && IT_CHARPOS (*it) >= to_charpos
8615 && IT_CHARPOS (*it) < IT_CHARPOS (ppos_it))
8616 SAVE_IT (ppos_it, *it, ppos_data);
8617
8618 /* Stop if lines are truncated and IT's current x-position is
8619 past the right edge of the window now. */
8620 if (it->line_wrap == TRUNCATE
8621 && it->current_x >= it->last_visible_x)
8622 {
8623 if (!FRAME_WINDOW_P (it->f)
8624 || ((it->bidi_p && it->bidi_it.paragraph_dir == R2L)
8625 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
8626 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0
8627 || IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
8628 {
8629 int at_eob_p = 0;
8630
8631 if ((at_eob_p = !get_next_display_element (it))
8632 || BUFFER_POS_REACHED_P ()
8633 /* If we are past TO_CHARPOS, but never saw any
8634 character positions smaller than TO_CHARPOS,
8635 return MOVE_POS_MATCH_OR_ZV, like the
8636 unidirectional display did. */
8637 || (it->bidi_p && (op & MOVE_TO_POS) != 0
8638 && !saw_smaller_pos
8639 && IT_CHARPOS (*it) > to_charpos))
8640 {
8641 if (it->bidi_p
8642 && !at_eob_p && IT_CHARPOS (ppos_it) < ZV)
8643 RESTORE_IT (it, &ppos_it, ppos_data);
8644 result = MOVE_POS_MATCH_OR_ZV;
8645 break;
8646 }
8647 if (ITERATOR_AT_END_OF_LINE_P (it))
8648 {
8649 result = MOVE_NEWLINE_OR_CR;
8650 break;
8651 }
8652 }
8653 else if (it->bidi_p && (op & MOVE_TO_POS) != 0
8654 && !saw_smaller_pos
8655 && IT_CHARPOS (*it) > to_charpos)
8656 {
8657 if (IT_CHARPOS (ppos_it) < ZV)
8658 RESTORE_IT (it, &ppos_it, ppos_data);
8659 result = MOVE_POS_MATCH_OR_ZV;
8660 break;
8661 }
8662 result = MOVE_LINE_TRUNCATED;
8663 break;
8664 }
8665 #undef IT_RESET_X_ASCENT_DESCENT
8666 }
8667
8668 #undef BUFFER_POS_REACHED_P
8669
8670 /* If we scanned beyond to_pos and didn't find a point to wrap at,
8671 restore the saved iterator. */
8672 if (atpos_it.sp >= 0)
8673 RESTORE_IT (it, &atpos_it, atpos_data);
8674 else if (atx_it.sp >= 0)
8675 RESTORE_IT (it, &atx_it, atx_data);
8676
8677 done:
8678
8679 if (atpos_data)
8680 bidi_unshelve_cache (atpos_data, 1);
8681 if (atx_data)
8682 bidi_unshelve_cache (atx_data, 1);
8683 if (wrap_data)
8684 bidi_unshelve_cache (wrap_data, 1);
8685 if (ppos_data)
8686 bidi_unshelve_cache (ppos_data, 1);
8687
8688 /* Restore the iterator settings altered at the beginning of this
8689 function. */
8690 it->glyph_row = saved_glyph_row;
8691 return result;
8692 }
8693
8694 /* For external use. */
8695 void
8696 move_it_in_display_line (struct it *it,
8697 ptrdiff_t to_charpos, int to_x,
8698 enum move_operation_enum op)
8699 {
8700 if (it->line_wrap == WORD_WRAP
8701 && (op & MOVE_TO_X))
8702 {
8703 struct it save_it;
8704 void *save_data = NULL;
8705 int skip;
8706
8707 SAVE_IT (save_it, *it, save_data);
8708 skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
8709 /* When word-wrap is on, TO_X may lie past the end
8710 of a wrapped line. Then it->current is the
8711 character on the next line, so backtrack to the
8712 space before the wrap point. */
8713 if (skip == MOVE_LINE_CONTINUED)
8714 {
8715 int prev_x = max (it->current_x - 1, 0);
8716 RESTORE_IT (it, &save_it, save_data);
8717 move_it_in_display_line_to
8718 (it, -1, prev_x, MOVE_TO_X);
8719 }
8720 else
8721 bidi_unshelve_cache (save_data, 1);
8722 }
8723 else
8724 move_it_in_display_line_to (it, to_charpos, to_x, op);
8725 }
8726
8727
8728 /* Move IT forward until it satisfies one or more of the criteria in
8729 TO_CHARPOS, TO_X, TO_Y, and TO_VPOS.
8730
8731 OP is a bit-mask that specifies where to stop, and in particular,
8732 which of those four position arguments makes a difference. See the
8733 description of enum move_operation_enum.
8734
8735 If TO_CHARPOS is in invisible text, e.g. a truncated part of a
8736 screen line, this function will set IT to the next position that is
8737 displayed to the right of TO_CHARPOS on the screen. */
8738
8739 void
8740 move_it_to (struct it *it, ptrdiff_t to_charpos, int to_x, int to_y, int to_vpos, int op)
8741 {
8742 enum move_it_result skip, skip2 = MOVE_X_REACHED;
8743 int line_height, line_start_x = 0, reached = 0;
8744 void *backup_data = NULL;
8745
8746 for (;;)
8747 {
8748 if (op & MOVE_TO_VPOS)
8749 {
8750 /* If no TO_CHARPOS and no TO_X specified, stop at the
8751 start of the line TO_VPOS. */
8752 if ((op & (MOVE_TO_X | MOVE_TO_POS)) == 0)
8753 {
8754 if (it->vpos == to_vpos)
8755 {
8756 reached = 1;
8757 break;
8758 }
8759 else
8760 skip = move_it_in_display_line_to (it, -1, -1, 0);
8761 }
8762 else
8763 {
8764 /* TO_VPOS >= 0 means stop at TO_X in the line at
8765 TO_VPOS, or at TO_POS, whichever comes first. */
8766 if (it->vpos == to_vpos)
8767 {
8768 reached = 2;
8769 break;
8770 }
8771
8772 skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
8773
8774 if (skip == MOVE_POS_MATCH_OR_ZV || it->vpos == to_vpos)
8775 {
8776 reached = 3;
8777 break;
8778 }
8779 else if (skip == MOVE_X_REACHED && it->vpos != to_vpos)
8780 {
8781 /* We have reached TO_X but not in the line we want. */
8782 skip = move_it_in_display_line_to (it, to_charpos,
8783 -1, MOVE_TO_POS);
8784 if (skip == MOVE_POS_MATCH_OR_ZV)
8785 {
8786 reached = 4;
8787 break;
8788 }
8789 }
8790 }
8791 }
8792 else if (op & MOVE_TO_Y)
8793 {
8794 struct it it_backup;
8795
8796 if (it->line_wrap == WORD_WRAP)
8797 SAVE_IT (it_backup, *it, backup_data);
8798
8799 /* TO_Y specified means stop at TO_X in the line containing
8800 TO_Y---or at TO_CHARPOS if this is reached first. The
8801 problem is that we can't really tell whether the line
8802 contains TO_Y before we have completely scanned it, and
8803 this may skip past TO_X. What we do is to first scan to
8804 TO_X.
8805
8806 If TO_X is not specified, use a TO_X of zero. The reason
8807 is to make the outcome of this function more predictable.
8808 If we didn't use TO_X == 0, we would stop at the end of
8809 the line which is probably not what a caller would expect
8810 to happen. */
8811 skip = move_it_in_display_line_to
8812 (it, to_charpos, ((op & MOVE_TO_X) ? to_x : 0),
8813 (MOVE_TO_X | (op & MOVE_TO_POS)));
8814
8815 /* If TO_CHARPOS is reached or ZV, we don't have to do more. */
8816 if (skip == MOVE_POS_MATCH_OR_ZV)
8817 reached = 5;
8818 else if (skip == MOVE_X_REACHED)
8819 {
8820 /* If TO_X was reached, we want to know whether TO_Y is
8821 in the line. We know this is the case if the already
8822 scanned glyphs make the line tall enough. Otherwise,
8823 we must check by scanning the rest of the line. */
8824 line_height = it->max_ascent + it->max_descent;
8825 if (to_y >= it->current_y
8826 && to_y < it->current_y + line_height)
8827 {
8828 reached = 6;
8829 break;
8830 }
8831 SAVE_IT (it_backup, *it, backup_data);
8832 TRACE_MOVE ((stderr, "move_it: from %d\n", IT_CHARPOS (*it)));
8833 skip2 = move_it_in_display_line_to (it, to_charpos, -1,
8834 op & MOVE_TO_POS);
8835 TRACE_MOVE ((stderr, "move_it: to %d\n", IT_CHARPOS (*it)));
8836 line_height = it->max_ascent + it->max_descent;
8837 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
8838
8839 if (to_y >= it->current_y
8840 && to_y < it->current_y + line_height)
8841 {
8842 /* If TO_Y is in this line and TO_X was reached
8843 above, we scanned too far. We have to restore
8844 IT's settings to the ones before skipping. But
8845 keep the more accurate values of max_ascent and
8846 max_descent we've found while skipping the rest
8847 of the line, for the sake of callers, such as
8848 pos_visible_p, that need to know the line
8849 height. */
8850 int max_ascent = it->max_ascent;
8851 int max_descent = it->max_descent;
8852
8853 RESTORE_IT (it, &it_backup, backup_data);
8854 it->max_ascent = max_ascent;
8855 it->max_descent = max_descent;
8856 reached = 6;
8857 }
8858 else
8859 {
8860 skip = skip2;
8861 if (skip == MOVE_POS_MATCH_OR_ZV)
8862 reached = 7;
8863 }
8864 }
8865 else
8866 {
8867 /* Check whether TO_Y is in this line. */
8868 line_height = it->max_ascent + it->max_descent;
8869 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
8870
8871 if (to_y >= it->current_y
8872 && to_y < it->current_y + line_height)
8873 {
8874 /* When word-wrap is on, TO_X may lie past the end
8875 of a wrapped line. Then it->current is the
8876 character on the next line, so backtrack to the
8877 space before the wrap point. */
8878 if (skip == MOVE_LINE_CONTINUED
8879 && it->line_wrap == WORD_WRAP)
8880 {
8881 int prev_x = max (it->current_x - 1, 0);
8882 RESTORE_IT (it, &it_backup, backup_data);
8883 skip = move_it_in_display_line_to
8884 (it, -1, prev_x, MOVE_TO_X);
8885 }
8886 reached = 6;
8887 }
8888 }
8889
8890 if (reached)
8891 break;
8892 }
8893 else if (BUFFERP (it->object)
8894 && (it->method == GET_FROM_BUFFER
8895 || it->method == GET_FROM_STRETCH)
8896 && IT_CHARPOS (*it) >= to_charpos
8897 /* Under bidi iteration, a call to set_iterator_to_next
8898 can scan far beyond to_charpos if the initial
8899 portion of the next line needs to be reordered. In
8900 that case, give move_it_in_display_line_to another
8901 chance below. */
8902 && !(it->bidi_p
8903 && it->bidi_it.scan_dir == -1))
8904 skip = MOVE_POS_MATCH_OR_ZV;
8905 else
8906 skip = move_it_in_display_line_to (it, to_charpos, -1, MOVE_TO_POS);
8907
8908 switch (skip)
8909 {
8910 case MOVE_POS_MATCH_OR_ZV:
8911 reached = 8;
8912 goto out;
8913
8914 case MOVE_NEWLINE_OR_CR:
8915 set_iterator_to_next (it, 1);
8916 it->continuation_lines_width = 0;
8917 break;
8918
8919 case MOVE_LINE_TRUNCATED:
8920 it->continuation_lines_width = 0;
8921 reseat_at_next_visible_line_start (it, 0);
8922 if ((op & MOVE_TO_POS) != 0
8923 && IT_CHARPOS (*it) > to_charpos)
8924 {
8925 reached = 9;
8926 goto out;
8927 }
8928 break;
8929
8930 case MOVE_LINE_CONTINUED:
8931 /* For continued lines ending in a tab, some of the glyphs
8932 associated with the tab are displayed on the current
8933 line. Since it->current_x does not include these glyphs,
8934 we use it->last_visible_x instead. */
8935 if (it->c == '\t')
8936 {
8937 it->continuation_lines_width += it->last_visible_x;
8938 /* When moving by vpos, ensure that the iterator really
8939 advances to the next line (bug#847, bug#969). Fixme:
8940 do we need to do this in other circumstances? */
8941 if (it->current_x != it->last_visible_x
8942 && (op & MOVE_TO_VPOS)
8943 && !(op & (MOVE_TO_X | MOVE_TO_POS)))
8944 {
8945 line_start_x = it->current_x + it->pixel_width
8946 - it->last_visible_x;
8947 set_iterator_to_next (it, 0);
8948 }
8949 }
8950 else
8951 it->continuation_lines_width += it->current_x;
8952 break;
8953
8954 default:
8955 emacs_abort ();
8956 }
8957
8958 /* Reset/increment for the next run. */
8959 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
8960 it->current_x = line_start_x;
8961 line_start_x = 0;
8962 it->hpos = 0;
8963 it->current_y += it->max_ascent + it->max_descent;
8964 ++it->vpos;
8965 last_height = it->max_ascent + it->max_descent;
8966 last_max_ascent = it->max_ascent;
8967 it->max_ascent = it->max_descent = 0;
8968 }
8969
8970 out:
8971
8972 /* On text terminals, we may stop at the end of a line in the middle
8973 of a multi-character glyph. If the glyph itself is continued,
8974 i.e. it is actually displayed on the next line, don't treat this
8975 stopping point as valid; move to the next line instead (unless
8976 that brings us offscreen). */
8977 if (!FRAME_WINDOW_P (it->f)
8978 && op & MOVE_TO_POS
8979 && IT_CHARPOS (*it) == to_charpos
8980 && it->what == IT_CHARACTER
8981 && it->nglyphs > 1
8982 && it->line_wrap == WINDOW_WRAP
8983 && it->current_x == it->last_visible_x - 1
8984 && it->c != '\n'
8985 && it->c != '\t'
8986 && it->vpos < XFASTINT (it->w->window_end_vpos))
8987 {
8988 it->continuation_lines_width += it->current_x;
8989 it->current_x = it->hpos = it->max_ascent = it->max_descent = 0;
8990 it->current_y += it->max_ascent + it->max_descent;
8991 ++it->vpos;
8992 last_height = it->max_ascent + it->max_descent;
8993 last_max_ascent = it->max_ascent;
8994 }
8995
8996 if (backup_data)
8997 bidi_unshelve_cache (backup_data, 1);
8998
8999 TRACE_MOVE ((stderr, "move_it_to: reached %d\n", reached));
9000 }
9001
9002
9003 /* Move iterator IT backward by a specified y-distance DY, DY >= 0.
9004
9005 If DY > 0, move IT backward at least that many pixels. DY = 0
9006 means move IT backward to the preceding line start or BEGV. This
9007 function may move over more than DY pixels if IT->current_y - DY
9008 ends up in the middle of a line; in this case IT->current_y will be
9009 set to the top of the line moved to. */
9010
9011 void
9012 move_it_vertically_backward (struct it *it, int dy)
9013 {
9014 int nlines, h;
9015 struct it it2, it3;
9016 void *it2data = NULL, *it3data = NULL;
9017 ptrdiff_t start_pos;
9018
9019 move_further_back:
9020 eassert (dy >= 0);
9021
9022 start_pos = IT_CHARPOS (*it);
9023
9024 /* Estimate how many newlines we must move back. */
9025 nlines = max (1, dy / FRAME_LINE_HEIGHT (it->f));
9026
9027 /* Set the iterator's position that many lines back. */
9028 while (nlines-- && IT_CHARPOS (*it) > BEGV)
9029 back_to_previous_visible_line_start (it);
9030
9031 /* Reseat the iterator here. When moving backward, we don't want
9032 reseat to skip forward over invisible text, set up the iterator
9033 to deliver from overlay strings at the new position etc. So,
9034 use reseat_1 here. */
9035 reseat_1 (it, it->current.pos, 1);
9036
9037 /* We are now surely at a line start. */
9038 it->current_x = it->hpos = 0; /* FIXME: this is incorrect when bidi
9039 reordering is in effect. */
9040 it->continuation_lines_width = 0;
9041
9042 /* Move forward and see what y-distance we moved. First move to the
9043 start of the next line so that we get its height. We need this
9044 height to be able to tell whether we reached the specified
9045 y-distance. */
9046 SAVE_IT (it2, *it, it2data);
9047 it2.max_ascent = it2.max_descent = 0;
9048 do
9049 {
9050 move_it_to (&it2, start_pos, -1, -1, it2.vpos + 1,
9051 MOVE_TO_POS | MOVE_TO_VPOS);
9052 }
9053 while (!(IT_POS_VALID_AFTER_MOVE_P (&it2)
9054 /* If we are in a display string which starts at START_POS,
9055 and that display string includes a newline, and we are
9056 right after that newline (i.e. at the beginning of a
9057 display line), exit the loop, because otherwise we will
9058 infloop, since move_it_to will see that it is already at
9059 START_POS and will not move. */
9060 || (it2.method == GET_FROM_STRING
9061 && IT_CHARPOS (it2) == start_pos
9062 && SREF (it2.string, IT_STRING_BYTEPOS (it2) - 1) == '\n')));
9063 eassert (IT_CHARPOS (*it) >= BEGV);
9064 SAVE_IT (it3, it2, it3data);
9065
9066 move_it_to (&it2, start_pos, -1, -1, -1, MOVE_TO_POS);
9067 eassert (IT_CHARPOS (*it) >= BEGV);
9068 /* H is the actual vertical distance from the position in *IT
9069 and the starting position. */
9070 h = it2.current_y - it->current_y;
9071 /* NLINES is the distance in number of lines. */
9072 nlines = it2.vpos - it->vpos;
9073
9074 /* Correct IT's y and vpos position
9075 so that they are relative to the starting point. */
9076 it->vpos -= nlines;
9077 it->current_y -= h;
9078
9079 if (dy == 0)
9080 {
9081 /* DY == 0 means move to the start of the screen line. The
9082 value of nlines is > 0 if continuation lines were involved,
9083 or if the original IT position was at start of a line. */
9084 RESTORE_IT (it, it, it2data);
9085 if (nlines > 0)
9086 move_it_by_lines (it, nlines);
9087 /* The above code moves us to some position NLINES down,
9088 usually to its first glyph (leftmost in an L2R line), but
9089 that's not necessarily the start of the line, under bidi
9090 reordering. We want to get to the character position
9091 that is immediately after the newline of the previous
9092 line. */
9093 if (it->bidi_p
9094 && !it->continuation_lines_width
9095 && !STRINGP (it->string)
9096 && IT_CHARPOS (*it) > BEGV
9097 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
9098 {
9099 ptrdiff_t nl_pos =
9100 find_next_newline_no_quit (IT_CHARPOS (*it) - 1, -1);
9101
9102 move_it_to (it, nl_pos, -1, -1, -1, MOVE_TO_POS);
9103 }
9104 bidi_unshelve_cache (it3data, 1);
9105 }
9106 else
9107 {
9108 /* The y-position we try to reach, relative to *IT.
9109 Note that H has been subtracted in front of the if-statement. */
9110 int target_y = it->current_y + h - dy;
9111 int y0 = it3.current_y;
9112 int y1;
9113 int line_height;
9114
9115 RESTORE_IT (&it3, &it3, it3data);
9116 y1 = line_bottom_y (&it3);
9117 line_height = y1 - y0;
9118 RESTORE_IT (it, it, it2data);
9119 /* If we did not reach target_y, try to move further backward if
9120 we can. If we moved too far backward, try to move forward. */
9121 if (target_y < it->current_y
9122 /* This is heuristic. In a window that's 3 lines high, with
9123 a line height of 13 pixels each, recentering with point
9124 on the bottom line will try to move -39/2 = 19 pixels
9125 backward. Try to avoid moving into the first line. */
9126 && (it->current_y - target_y
9127 > min (window_box_height (it->w), line_height * 2 / 3))
9128 && IT_CHARPOS (*it) > BEGV)
9129 {
9130 TRACE_MOVE ((stderr, " not far enough -> move_vert %d\n",
9131 target_y - it->current_y));
9132 dy = it->current_y - target_y;
9133 goto move_further_back;
9134 }
9135 else if (target_y >= it->current_y + line_height
9136 && IT_CHARPOS (*it) < ZV)
9137 {
9138 /* Should move forward by at least one line, maybe more.
9139
9140 Note: Calling move_it_by_lines can be expensive on
9141 terminal frames, where compute_motion is used (via
9142 vmotion) to do the job, when there are very long lines
9143 and truncate-lines is nil. That's the reason for
9144 treating terminal frames specially here. */
9145
9146 if (!FRAME_WINDOW_P (it->f))
9147 move_it_vertically (it, target_y - (it->current_y + line_height));
9148 else
9149 {
9150 do
9151 {
9152 move_it_by_lines (it, 1);
9153 }
9154 while (target_y >= line_bottom_y (it) && IT_CHARPOS (*it) < ZV);
9155 }
9156 }
9157 }
9158 }
9159
9160
9161 /* Move IT by a specified amount of pixel lines DY. DY negative means
9162 move backwards. DY = 0 means move to start of screen line. At the
9163 end, IT will be on the start of a screen line. */
9164
9165 void
9166 move_it_vertically (struct it *it, int dy)
9167 {
9168 if (dy <= 0)
9169 move_it_vertically_backward (it, -dy);
9170 else
9171 {
9172 TRACE_MOVE ((stderr, "move_it_v: from %d, %d\n", IT_CHARPOS (*it), dy));
9173 move_it_to (it, ZV, -1, it->current_y + dy, -1,
9174 MOVE_TO_POS | MOVE_TO_Y);
9175 TRACE_MOVE ((stderr, "move_it_v: to %d\n", IT_CHARPOS (*it)));
9176
9177 /* If buffer ends in ZV without a newline, move to the start of
9178 the line to satisfy the post-condition. */
9179 if (IT_CHARPOS (*it) == ZV
9180 && ZV > BEGV
9181 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
9182 move_it_by_lines (it, 0);
9183 }
9184 }
9185
9186
9187 /* Move iterator IT past the end of the text line it is in. */
9188
9189 void
9190 move_it_past_eol (struct it *it)
9191 {
9192 enum move_it_result rc;
9193
9194 rc = move_it_in_display_line_to (it, Z, 0, MOVE_TO_POS);
9195 if (rc == MOVE_NEWLINE_OR_CR)
9196 set_iterator_to_next (it, 0);
9197 }
9198
9199
9200 /* Move IT by a specified number DVPOS of screen lines down. DVPOS
9201 negative means move up. DVPOS == 0 means move to the start of the
9202 screen line.
9203
9204 Optimization idea: If we would know that IT->f doesn't use
9205 a face with proportional font, we could be faster for
9206 truncate-lines nil. */
9207
9208 void
9209 move_it_by_lines (struct it *it, ptrdiff_t dvpos)
9210 {
9211
9212 /* The commented-out optimization uses vmotion on terminals. This
9213 gives bad results, because elements like it->what, on which
9214 callers such as pos_visible_p rely, aren't updated. */
9215 /* struct position pos;
9216 if (!FRAME_WINDOW_P (it->f))
9217 {
9218 struct text_pos textpos;
9219
9220 pos = *vmotion (IT_CHARPOS (*it), dvpos, it->w);
9221 SET_TEXT_POS (textpos, pos.bufpos, pos.bytepos);
9222 reseat (it, textpos, 1);
9223 it->vpos += pos.vpos;
9224 it->current_y += pos.vpos;
9225 }
9226 else */
9227
9228 if (dvpos == 0)
9229 {
9230 /* DVPOS == 0 means move to the start of the screen line. */
9231 move_it_vertically_backward (it, 0);
9232 /* Let next call to line_bottom_y calculate real line height */
9233 last_height = 0;
9234 }
9235 else if (dvpos > 0)
9236 {
9237 move_it_to (it, -1, -1, -1, it->vpos + dvpos, MOVE_TO_VPOS);
9238 if (!IT_POS_VALID_AFTER_MOVE_P (it))
9239 {
9240 /* Only move to the next buffer position if we ended up in a
9241 string from display property, not in an overlay string
9242 (before-string or after-string). That is because the
9243 latter don't conceal the underlying buffer position, so
9244 we can ask to move the iterator to the exact position we
9245 are interested in. Note that, even if we are already at
9246 IT_CHARPOS (*it), the call below is not a no-op, as it
9247 will detect that we are at the end of the string, pop the
9248 iterator, and compute it->current_x and it->hpos
9249 correctly. */
9250 move_it_to (it, IT_CHARPOS (*it) + it->string_from_display_prop_p,
9251 -1, -1, -1, MOVE_TO_POS);
9252 }
9253 }
9254 else
9255 {
9256 struct it it2;
9257 void *it2data = NULL;
9258 ptrdiff_t start_charpos, i;
9259
9260 /* Start at the beginning of the screen line containing IT's
9261 position. This may actually move vertically backwards,
9262 in case of overlays, so adjust dvpos accordingly. */
9263 dvpos += it->vpos;
9264 move_it_vertically_backward (it, 0);
9265 dvpos -= it->vpos;
9266
9267 /* Go back -DVPOS visible lines and reseat the iterator there. */
9268 start_charpos = IT_CHARPOS (*it);
9269 for (i = -dvpos; i > 0 && IT_CHARPOS (*it) > BEGV; --i)
9270 back_to_previous_visible_line_start (it);
9271 reseat (it, it->current.pos, 1);
9272
9273 /* Move further back if we end up in a string or an image. */
9274 while (!IT_POS_VALID_AFTER_MOVE_P (it))
9275 {
9276 /* First try to move to start of display line. */
9277 dvpos += it->vpos;
9278 move_it_vertically_backward (it, 0);
9279 dvpos -= it->vpos;
9280 if (IT_POS_VALID_AFTER_MOVE_P (it))
9281 break;
9282 /* If start of line is still in string or image,
9283 move further back. */
9284 back_to_previous_visible_line_start (it);
9285 reseat (it, it->current.pos, 1);
9286 dvpos--;
9287 }
9288
9289 it->current_x = it->hpos = 0;
9290
9291 /* Above call may have moved too far if continuation lines
9292 are involved. Scan forward and see if it did. */
9293 SAVE_IT (it2, *it, it2data);
9294 it2.vpos = it2.current_y = 0;
9295 move_it_to (&it2, start_charpos, -1, -1, -1, MOVE_TO_POS);
9296 it->vpos -= it2.vpos;
9297 it->current_y -= it2.current_y;
9298 it->current_x = it->hpos = 0;
9299
9300 /* If we moved too far back, move IT some lines forward. */
9301 if (it2.vpos > -dvpos)
9302 {
9303 int delta = it2.vpos + dvpos;
9304
9305 RESTORE_IT (&it2, &it2, it2data);
9306 SAVE_IT (it2, *it, it2data);
9307 move_it_to (it, -1, -1, -1, it->vpos + delta, MOVE_TO_VPOS);
9308 /* Move back again if we got too far ahead. */
9309 if (IT_CHARPOS (*it) >= start_charpos)
9310 RESTORE_IT (it, &it2, it2data);
9311 else
9312 bidi_unshelve_cache (it2data, 1);
9313 }
9314 else
9315 RESTORE_IT (it, it, it2data);
9316 }
9317 }
9318
9319 /* Return 1 if IT points into the middle of a display vector. */
9320
9321 int
9322 in_display_vector_p (struct it *it)
9323 {
9324 return (it->method == GET_FROM_DISPLAY_VECTOR
9325 && it->current.dpvec_index > 0
9326 && it->dpvec + it->current.dpvec_index != it->dpend);
9327 }
9328
9329 \f
9330 /***********************************************************************
9331 Messages
9332 ***********************************************************************/
9333
9334
9335 /* Add a message with format string FORMAT and arguments ARG1 and ARG2
9336 to *Messages*. */
9337
9338 void
9339 add_to_log (const char *format, Lisp_Object arg1, Lisp_Object arg2)
9340 {
9341 Lisp_Object args[3];
9342 Lisp_Object msg, fmt;
9343 char *buffer;
9344 ptrdiff_t len;
9345 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
9346 USE_SAFE_ALLOCA;
9347
9348 /* Do nothing if called asynchronously. Inserting text into
9349 a buffer may call after-change-functions and alike and
9350 that would means running Lisp asynchronously. */
9351 if (handling_signal)
9352 return;
9353
9354 fmt = msg = Qnil;
9355 GCPRO4 (fmt, msg, arg1, arg2);
9356
9357 args[0] = fmt = build_string (format);
9358 args[1] = arg1;
9359 args[2] = arg2;
9360 msg = Fformat (3, args);
9361
9362 len = SBYTES (msg) + 1;
9363 buffer = SAFE_ALLOCA (len);
9364 memcpy (buffer, SDATA (msg), len);
9365
9366 message_dolog (buffer, len - 1, 1, 0);
9367 SAFE_FREE ();
9368
9369 UNGCPRO;
9370 }
9371
9372
9373 /* Output a newline in the *Messages* buffer if "needs" one. */
9374
9375 void
9376 message_log_maybe_newline (void)
9377 {
9378 if (message_log_need_newline)
9379 message_dolog ("", 0, 1, 0);
9380 }
9381
9382
9383 /* Add a string M of length NBYTES to the message log, optionally
9384 terminated with a newline when NLFLAG is non-zero. MULTIBYTE, if
9385 nonzero, means interpret the contents of M as multibyte. This
9386 function calls low-level routines in order to bypass text property
9387 hooks, etc. which might not be safe to run.
9388
9389 This may GC (insert may run before/after change hooks),
9390 so the buffer M must NOT point to a Lisp string. */
9391
9392 void
9393 message_dolog (const char *m, ptrdiff_t nbytes, int nlflag, int multibyte)
9394 {
9395 const unsigned char *msg = (const unsigned char *) m;
9396
9397 if (!NILP (Vmemory_full))
9398 return;
9399
9400 if (!NILP (Vmessage_log_max))
9401 {
9402 struct buffer *oldbuf;
9403 Lisp_Object oldpoint, oldbegv, oldzv;
9404 int old_windows_or_buffers_changed = windows_or_buffers_changed;
9405 ptrdiff_t point_at_end = 0;
9406 ptrdiff_t zv_at_end = 0;
9407 Lisp_Object old_deactivate_mark, tem;
9408 struct gcpro gcpro1;
9409
9410 old_deactivate_mark = Vdeactivate_mark;
9411 oldbuf = current_buffer;
9412 Fset_buffer (Fget_buffer_create (Vmessages_buffer_name));
9413 bset_undo_list (current_buffer, Qt);
9414
9415 oldpoint = message_dolog_marker1;
9416 set_marker_restricted (oldpoint, make_number (PT), Qnil);
9417 oldbegv = message_dolog_marker2;
9418 set_marker_restricted (oldbegv, make_number (BEGV), Qnil);
9419 oldzv = message_dolog_marker3;
9420 set_marker_restricted (oldzv, make_number (ZV), Qnil);
9421 GCPRO1 (old_deactivate_mark);
9422
9423 if (PT == Z)
9424 point_at_end = 1;
9425 if (ZV == Z)
9426 zv_at_end = 1;
9427
9428 BEGV = BEG;
9429 BEGV_BYTE = BEG_BYTE;
9430 ZV = Z;
9431 ZV_BYTE = Z_BYTE;
9432 TEMP_SET_PT_BOTH (Z, Z_BYTE);
9433
9434 /* Insert the string--maybe converting multibyte to single byte
9435 or vice versa, so that all the text fits the buffer. */
9436 if (multibyte
9437 && NILP (BVAR (current_buffer, enable_multibyte_characters)))
9438 {
9439 ptrdiff_t i;
9440 int c, char_bytes;
9441 char work[1];
9442
9443 /* Convert a multibyte string to single-byte
9444 for the *Message* buffer. */
9445 for (i = 0; i < nbytes; i += char_bytes)
9446 {
9447 c = string_char_and_length (msg + i, &char_bytes);
9448 work[0] = (ASCII_CHAR_P (c)
9449 ? c
9450 : multibyte_char_to_unibyte (c));
9451 insert_1_both (work, 1, 1, 1, 0, 0);
9452 }
9453 }
9454 else if (! multibyte
9455 && ! NILP (BVAR (current_buffer, enable_multibyte_characters)))
9456 {
9457 ptrdiff_t i;
9458 int c, char_bytes;
9459 unsigned char str[MAX_MULTIBYTE_LENGTH];
9460 /* Convert a single-byte string to multibyte
9461 for the *Message* buffer. */
9462 for (i = 0; i < nbytes; i++)
9463 {
9464 c = msg[i];
9465 MAKE_CHAR_MULTIBYTE (c);
9466 char_bytes = CHAR_STRING (c, str);
9467 insert_1_both ((char *) str, 1, char_bytes, 1, 0, 0);
9468 }
9469 }
9470 else if (nbytes)
9471 insert_1 (m, nbytes, 1, 0, 0);
9472
9473 if (nlflag)
9474 {
9475 ptrdiff_t this_bol, this_bol_byte, prev_bol, prev_bol_byte;
9476 printmax_t dups;
9477 insert_1 ("\n", 1, 1, 0, 0);
9478
9479 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE, -2, 0);
9480 this_bol = PT;
9481 this_bol_byte = PT_BYTE;
9482
9483 /* See if this line duplicates the previous one.
9484 If so, combine duplicates. */
9485 if (this_bol > BEG)
9486 {
9487 scan_newline (PT, PT_BYTE, BEG, BEG_BYTE, -2, 0);
9488 prev_bol = PT;
9489 prev_bol_byte = PT_BYTE;
9490
9491 dups = message_log_check_duplicate (prev_bol_byte,
9492 this_bol_byte);
9493 if (dups)
9494 {
9495 del_range_both (prev_bol, prev_bol_byte,
9496 this_bol, this_bol_byte, 0);
9497 if (dups > 1)
9498 {
9499 char dupstr[sizeof " [ times]"
9500 + INT_STRLEN_BOUND (printmax_t)];
9501
9502 /* If you change this format, don't forget to also
9503 change message_log_check_duplicate. */
9504 int duplen = sprintf (dupstr, " [%"pMd" times]", dups);
9505 TEMP_SET_PT_BOTH (Z - 1, Z_BYTE - 1);
9506 insert_1 (dupstr, duplen, 1, 0, 1);
9507 }
9508 }
9509 }
9510
9511 /* If we have more than the desired maximum number of lines
9512 in the *Messages* buffer now, delete the oldest ones.
9513 This is safe because we don't have undo in this buffer. */
9514
9515 if (NATNUMP (Vmessage_log_max))
9516 {
9517 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE,
9518 -XFASTINT (Vmessage_log_max) - 1, 0);
9519 del_range_both (BEG, BEG_BYTE, PT, PT_BYTE, 0);
9520 }
9521 }
9522 BEGV = XMARKER (oldbegv)->charpos;
9523 BEGV_BYTE = marker_byte_position (oldbegv);
9524
9525 if (zv_at_end)
9526 {
9527 ZV = Z;
9528 ZV_BYTE = Z_BYTE;
9529 }
9530 else
9531 {
9532 ZV = XMARKER (oldzv)->charpos;
9533 ZV_BYTE = marker_byte_position (oldzv);
9534 }
9535
9536 if (point_at_end)
9537 TEMP_SET_PT_BOTH (Z, Z_BYTE);
9538 else
9539 /* We can't do Fgoto_char (oldpoint) because it will run some
9540 Lisp code. */
9541 TEMP_SET_PT_BOTH (XMARKER (oldpoint)->charpos,
9542 XMARKER (oldpoint)->bytepos);
9543
9544 UNGCPRO;
9545 unchain_marker (XMARKER (oldpoint));
9546 unchain_marker (XMARKER (oldbegv));
9547 unchain_marker (XMARKER (oldzv));
9548
9549 tem = Fget_buffer_window (Fcurrent_buffer (), Qt);
9550 set_buffer_internal (oldbuf);
9551 if (NILP (tem))
9552 windows_or_buffers_changed = old_windows_or_buffers_changed;
9553 message_log_need_newline = !nlflag;
9554 Vdeactivate_mark = old_deactivate_mark;
9555 }
9556 }
9557
9558
9559 /* We are at the end of the buffer after just having inserted a newline.
9560 (Note: We depend on the fact we won't be crossing the gap.)
9561 Check to see if the most recent message looks a lot like the previous one.
9562 Return 0 if different, 1 if the new one should just replace it, or a
9563 value N > 1 if we should also append " [N times]". */
9564
9565 static intmax_t
9566 message_log_check_duplicate (ptrdiff_t prev_bol_byte, ptrdiff_t this_bol_byte)
9567 {
9568 ptrdiff_t i;
9569 ptrdiff_t len = Z_BYTE - 1 - this_bol_byte;
9570 int seen_dots = 0;
9571 unsigned char *p1 = BUF_BYTE_ADDRESS (current_buffer, prev_bol_byte);
9572 unsigned char *p2 = BUF_BYTE_ADDRESS (current_buffer, this_bol_byte);
9573
9574 for (i = 0; i < len; i++)
9575 {
9576 if (i >= 3 && p1[i-3] == '.' && p1[i-2] == '.' && p1[i-1] == '.')
9577 seen_dots = 1;
9578 if (p1[i] != p2[i])
9579 return seen_dots;
9580 }
9581 p1 += len;
9582 if (*p1 == '\n')
9583 return 2;
9584 if (*p1++ == ' ' && *p1++ == '[')
9585 {
9586 char *pend;
9587 intmax_t n = strtoimax ((char *) p1, &pend, 10);
9588 if (0 < n && n < INTMAX_MAX && strncmp (pend, " times]\n", 8) == 0)
9589 return n+1;
9590 }
9591 return 0;
9592 }
9593 \f
9594
9595 /* Display an echo area message M with a specified length of NBYTES
9596 bytes. The string may include null characters. If M is 0, clear
9597 out any existing message, and let the mini-buffer text show
9598 through.
9599
9600 This may GC, so the buffer M must NOT point to a Lisp string. */
9601
9602 void
9603 message2 (const char *m, ptrdiff_t nbytes, int multibyte)
9604 {
9605 /* First flush out any partial line written with print. */
9606 message_log_maybe_newline ();
9607 if (m)
9608 message_dolog (m, nbytes, 1, multibyte);
9609 message2_nolog (m, nbytes, multibyte);
9610 }
9611
9612
9613 /* The non-logging counterpart of message2. */
9614
9615 void
9616 message2_nolog (const char *m, ptrdiff_t nbytes, int multibyte)
9617 {
9618 struct frame *sf = SELECTED_FRAME ();
9619 message_enable_multibyte = multibyte;
9620
9621 if (FRAME_INITIAL_P (sf))
9622 {
9623 if (noninteractive_need_newline)
9624 putc ('\n', stderr);
9625 noninteractive_need_newline = 0;
9626 if (m)
9627 fwrite (m, nbytes, 1, stderr);
9628 if (cursor_in_echo_area == 0)
9629 fprintf (stderr, "\n");
9630 fflush (stderr);
9631 }
9632 /* A null message buffer means that the frame hasn't really been
9633 initialized yet. Error messages get reported properly by
9634 cmd_error, so this must be just an informative message; toss it. */
9635 else if (INTERACTIVE
9636 && sf->glyphs_initialized_p
9637 && FRAME_MESSAGE_BUF (sf))
9638 {
9639 Lisp_Object mini_window;
9640 struct frame *f;
9641
9642 /* Get the frame containing the mini-buffer
9643 that the selected frame is using. */
9644 mini_window = FRAME_MINIBUF_WINDOW (sf);
9645 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
9646
9647 FRAME_SAMPLE_VISIBILITY (f);
9648 if (FRAME_VISIBLE_P (sf)
9649 && ! FRAME_VISIBLE_P (f))
9650 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (mini_window)));
9651
9652 if (m)
9653 {
9654 set_message (m, Qnil, nbytes, multibyte);
9655 if (minibuffer_auto_raise)
9656 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
9657 }
9658 else
9659 clear_message (1, 1);
9660
9661 do_pending_window_change (0);
9662 echo_area_display (1);
9663 do_pending_window_change (0);
9664 if (FRAME_TERMINAL (f)->frame_up_to_date_hook != 0 && ! gc_in_progress)
9665 (*FRAME_TERMINAL (f)->frame_up_to_date_hook) (f);
9666 }
9667 }
9668
9669
9670 /* Display an echo area message M with a specified length of NBYTES
9671 bytes. The string may include null characters. If M is not a
9672 string, clear out any existing message, and let the mini-buffer
9673 text show through.
9674
9675 This function cancels echoing. */
9676
9677 void
9678 message3 (Lisp_Object m, ptrdiff_t nbytes, int multibyte)
9679 {
9680 struct gcpro gcpro1;
9681
9682 GCPRO1 (m);
9683 clear_message (1,1);
9684 cancel_echoing ();
9685
9686 /* First flush out any partial line written with print. */
9687 message_log_maybe_newline ();
9688 if (STRINGP (m))
9689 {
9690 USE_SAFE_ALLOCA;
9691 char *buffer = SAFE_ALLOCA (nbytes);
9692 memcpy (buffer, SDATA (m), nbytes);
9693 message_dolog (buffer, nbytes, 1, multibyte);
9694 SAFE_FREE ();
9695 }
9696 message3_nolog (m, nbytes, multibyte);
9697
9698 UNGCPRO;
9699 }
9700
9701
9702 /* The non-logging version of message3.
9703 This does not cancel echoing, because it is used for echoing.
9704 Perhaps we need to make a separate function for echoing
9705 and make this cancel echoing. */
9706
9707 void
9708 message3_nolog (Lisp_Object m, ptrdiff_t nbytes, int multibyte)
9709 {
9710 struct frame *sf = SELECTED_FRAME ();
9711 message_enable_multibyte = multibyte;
9712
9713 if (FRAME_INITIAL_P (sf))
9714 {
9715 if (noninteractive_need_newline)
9716 putc ('\n', stderr);
9717 noninteractive_need_newline = 0;
9718 if (STRINGP (m))
9719 fwrite (SDATA (m), nbytes, 1, stderr);
9720 if (cursor_in_echo_area == 0)
9721 fprintf (stderr, "\n");
9722 fflush (stderr);
9723 }
9724 /* A null message buffer means that the frame hasn't really been
9725 initialized yet. Error messages get reported properly by
9726 cmd_error, so this must be just an informative message; toss it. */
9727 else if (INTERACTIVE
9728 && sf->glyphs_initialized_p
9729 && FRAME_MESSAGE_BUF (sf))
9730 {
9731 Lisp_Object mini_window;
9732 Lisp_Object frame;
9733 struct frame *f;
9734
9735 /* Get the frame containing the mini-buffer
9736 that the selected frame is using. */
9737 mini_window = FRAME_MINIBUF_WINDOW (sf);
9738 frame = XWINDOW (mini_window)->frame;
9739 f = XFRAME (frame);
9740
9741 FRAME_SAMPLE_VISIBILITY (f);
9742 if (FRAME_VISIBLE_P (sf)
9743 && !FRAME_VISIBLE_P (f))
9744 Fmake_frame_visible (frame);
9745
9746 if (STRINGP (m) && SCHARS (m) > 0)
9747 {
9748 set_message (NULL, m, nbytes, multibyte);
9749 if (minibuffer_auto_raise)
9750 Fraise_frame (frame);
9751 /* Assume we are not echoing.
9752 (If we are, echo_now will override this.) */
9753 echo_message_buffer = Qnil;
9754 }
9755 else
9756 clear_message (1, 1);
9757
9758 do_pending_window_change (0);
9759 echo_area_display (1);
9760 do_pending_window_change (0);
9761 if (FRAME_TERMINAL (f)->frame_up_to_date_hook != 0 && ! gc_in_progress)
9762 (*FRAME_TERMINAL (f)->frame_up_to_date_hook) (f);
9763 }
9764 }
9765
9766
9767 /* Display a null-terminated echo area message M. If M is 0, clear
9768 out any existing message, and let the mini-buffer text show through.
9769
9770 The buffer M must continue to exist until after the echo area gets
9771 cleared or some other message gets displayed there. Do not pass
9772 text that is stored in a Lisp string. Do not pass text in a buffer
9773 that was alloca'd. */
9774
9775 void
9776 message1 (const char *m)
9777 {
9778 message2 (m, (m ? strlen (m) : 0), 0);
9779 }
9780
9781
9782 /* The non-logging counterpart of message1. */
9783
9784 void
9785 message1_nolog (const char *m)
9786 {
9787 message2_nolog (m, (m ? strlen (m) : 0), 0);
9788 }
9789
9790 /* Display a message M which contains a single %s
9791 which gets replaced with STRING. */
9792
9793 void
9794 message_with_string (const char *m, Lisp_Object string, int log)
9795 {
9796 CHECK_STRING (string);
9797
9798 if (noninteractive)
9799 {
9800 if (m)
9801 {
9802 if (noninteractive_need_newline)
9803 putc ('\n', stderr);
9804 noninteractive_need_newline = 0;
9805 fprintf (stderr, m, SDATA (string));
9806 if (!cursor_in_echo_area)
9807 fprintf (stderr, "\n");
9808 fflush (stderr);
9809 }
9810 }
9811 else if (INTERACTIVE)
9812 {
9813 /* The frame whose minibuffer we're going to display the message on.
9814 It may be larger than the selected frame, so we need
9815 to use its buffer, not the selected frame's buffer. */
9816 Lisp_Object mini_window;
9817 struct frame *f, *sf = SELECTED_FRAME ();
9818
9819 /* Get the frame containing the minibuffer
9820 that the selected frame is using. */
9821 mini_window = FRAME_MINIBUF_WINDOW (sf);
9822 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
9823
9824 /* A null message buffer means that the frame hasn't really been
9825 initialized yet. Error messages get reported properly by
9826 cmd_error, so this must be just an informative message; toss it. */
9827 if (FRAME_MESSAGE_BUF (f))
9828 {
9829 Lisp_Object args[2], msg;
9830 struct gcpro gcpro1, gcpro2;
9831
9832 args[0] = build_string (m);
9833 args[1] = msg = string;
9834 GCPRO2 (args[0], msg);
9835 gcpro1.nvars = 2;
9836
9837 msg = Fformat (2, args);
9838
9839 if (log)
9840 message3 (msg, SBYTES (msg), STRING_MULTIBYTE (msg));
9841 else
9842 message3_nolog (msg, SBYTES (msg), STRING_MULTIBYTE (msg));
9843
9844 UNGCPRO;
9845
9846 /* Print should start at the beginning of the message
9847 buffer next time. */
9848 message_buf_print = 0;
9849 }
9850 }
9851 }
9852
9853
9854 /* Dump an informative message to the minibuf. If M is 0, clear out
9855 any existing message, and let the mini-buffer text show through. */
9856
9857 static void
9858 vmessage (const char *m, va_list ap)
9859 {
9860 if (noninteractive)
9861 {
9862 if (m)
9863 {
9864 if (noninteractive_need_newline)
9865 putc ('\n', stderr);
9866 noninteractive_need_newline = 0;
9867 vfprintf (stderr, m, ap);
9868 if (cursor_in_echo_area == 0)
9869 fprintf (stderr, "\n");
9870 fflush (stderr);
9871 }
9872 }
9873 else if (INTERACTIVE)
9874 {
9875 /* The frame whose mini-buffer we're going to display the message
9876 on. It may be larger than the selected frame, so we need to
9877 use its buffer, not the selected frame's buffer. */
9878 Lisp_Object mini_window;
9879 struct frame *f, *sf = SELECTED_FRAME ();
9880
9881 /* Get the frame containing the mini-buffer
9882 that the selected frame is using. */
9883 mini_window = FRAME_MINIBUF_WINDOW (sf);
9884 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
9885
9886 /* A null message buffer means that the frame hasn't really been
9887 initialized yet. Error messages get reported properly by
9888 cmd_error, so this must be just an informative message; toss
9889 it. */
9890 if (FRAME_MESSAGE_BUF (f))
9891 {
9892 if (m)
9893 {
9894 ptrdiff_t len;
9895
9896 len = doprnt (FRAME_MESSAGE_BUF (f),
9897 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, ap);
9898
9899 message2 (FRAME_MESSAGE_BUF (f), len, 1);
9900 }
9901 else
9902 message1 (0);
9903
9904 /* Print should start at the beginning of the message
9905 buffer next time. */
9906 message_buf_print = 0;
9907 }
9908 }
9909 }
9910
9911 void
9912 message (const char *m, ...)
9913 {
9914 va_list ap;
9915 va_start (ap, m);
9916 vmessage (m, ap);
9917 va_end (ap);
9918 }
9919
9920
9921 #if 0
9922 /* The non-logging version of message. */
9923
9924 void
9925 message_nolog (const char *m, ...)
9926 {
9927 Lisp_Object old_log_max;
9928 va_list ap;
9929 va_start (ap, m);
9930 old_log_max = Vmessage_log_max;
9931 Vmessage_log_max = Qnil;
9932 vmessage (m, ap);
9933 Vmessage_log_max = old_log_max;
9934 va_end (ap);
9935 }
9936 #endif
9937
9938
9939 /* Display the current message in the current mini-buffer. This is
9940 only called from error handlers in process.c, and is not time
9941 critical. */
9942
9943 void
9944 update_echo_area (void)
9945 {
9946 if (!NILP (echo_area_buffer[0]))
9947 {
9948 Lisp_Object string;
9949 string = Fcurrent_message ();
9950 message3 (string, SBYTES (string),
9951 !NILP (BVAR (current_buffer, enable_multibyte_characters)));
9952 }
9953 }
9954
9955
9956 /* Make sure echo area buffers in `echo_buffers' are live.
9957 If they aren't, make new ones. */
9958
9959 static void
9960 ensure_echo_area_buffers (void)
9961 {
9962 int i;
9963
9964 for (i = 0; i < 2; ++i)
9965 if (!BUFFERP (echo_buffer[i])
9966 || NILP (BVAR (XBUFFER (echo_buffer[i]), name)))
9967 {
9968 char name[30];
9969 Lisp_Object old_buffer;
9970 int j;
9971
9972 old_buffer = echo_buffer[i];
9973 echo_buffer[i] = Fget_buffer_create
9974 (make_formatted_string (name, " *Echo Area %d*", i));
9975 bset_truncate_lines (XBUFFER (echo_buffer[i]), Qnil);
9976 /* to force word wrap in echo area -
9977 it was decided to postpone this*/
9978 /* XBUFFER (echo_buffer[i])->word_wrap = Qt; */
9979
9980 for (j = 0; j < 2; ++j)
9981 if (EQ (old_buffer, echo_area_buffer[j]))
9982 echo_area_buffer[j] = echo_buffer[i];
9983 }
9984 }
9985
9986
9987 /* Call FN with args A1..A4 with either the current or last displayed
9988 echo_area_buffer as current buffer.
9989
9990 WHICH zero means use the current message buffer
9991 echo_area_buffer[0]. If that is nil, choose a suitable buffer
9992 from echo_buffer[] and clear it.
9993
9994 WHICH > 0 means use echo_area_buffer[1]. If that is nil, choose a
9995 suitable buffer from echo_buffer[] and clear it.
9996
9997 If WHICH < 0, set echo_area_buffer[1] to echo_area_buffer[0], so
9998 that the current message becomes the last displayed one, make
9999 choose a suitable buffer for echo_area_buffer[0], and clear it.
10000
10001 Value is what FN returns. */
10002
10003 static int
10004 with_echo_area_buffer (struct window *w, int which,
10005 int (*fn) (ptrdiff_t, Lisp_Object, ptrdiff_t, ptrdiff_t),
10006 ptrdiff_t a1, Lisp_Object a2, ptrdiff_t a3, ptrdiff_t a4)
10007 {
10008 Lisp_Object buffer;
10009 int this_one, the_other, clear_buffer_p, rc;
10010 ptrdiff_t count = SPECPDL_INDEX ();
10011
10012 /* If buffers aren't live, make new ones. */
10013 ensure_echo_area_buffers ();
10014
10015 clear_buffer_p = 0;
10016
10017 if (which == 0)
10018 this_one = 0, the_other = 1;
10019 else if (which > 0)
10020 this_one = 1, the_other = 0;
10021 else
10022 {
10023 this_one = 0, the_other = 1;
10024 clear_buffer_p = 1;
10025
10026 /* We need a fresh one in case the current echo buffer equals
10027 the one containing the last displayed echo area message. */
10028 if (!NILP (echo_area_buffer[this_one])
10029 && EQ (echo_area_buffer[this_one], echo_area_buffer[the_other]))
10030 echo_area_buffer[this_one] = Qnil;
10031 }
10032
10033 /* Choose a suitable buffer from echo_buffer[] is we don't
10034 have one. */
10035 if (NILP (echo_area_buffer[this_one]))
10036 {
10037 echo_area_buffer[this_one]
10038 = (EQ (echo_area_buffer[the_other], echo_buffer[this_one])
10039 ? echo_buffer[the_other]
10040 : echo_buffer[this_one]);
10041 clear_buffer_p = 1;
10042 }
10043
10044 buffer = echo_area_buffer[this_one];
10045
10046 /* Don't get confused by reusing the buffer used for echoing
10047 for a different purpose. */
10048 if (echo_kboard == NULL && EQ (buffer, echo_message_buffer))
10049 cancel_echoing ();
10050
10051 record_unwind_protect (unwind_with_echo_area_buffer,
10052 with_echo_area_buffer_unwind_data (w));
10053
10054 /* Make the echo area buffer current. Note that for display
10055 purposes, it is not necessary that the displayed window's buffer
10056 == current_buffer, except for text property lookup. So, let's
10057 only set that buffer temporarily here without doing a full
10058 Fset_window_buffer. We must also change w->pointm, though,
10059 because otherwise an assertions in unshow_buffer fails, and Emacs
10060 aborts. */
10061 set_buffer_internal_1 (XBUFFER (buffer));
10062 if (w)
10063 {
10064 wset_buffer (w, buffer);
10065 set_marker_both (w->pointm, buffer, BEG, BEG_BYTE);
10066 }
10067
10068 bset_undo_list (current_buffer, Qt);
10069 bset_read_only (current_buffer, Qnil);
10070 specbind (Qinhibit_read_only, Qt);
10071 specbind (Qinhibit_modification_hooks, Qt);
10072
10073 if (clear_buffer_p && Z > BEG)
10074 del_range (BEG, Z);
10075
10076 eassert (BEGV >= BEG);
10077 eassert (ZV <= Z && ZV >= BEGV);
10078
10079 rc = fn (a1, a2, a3, a4);
10080
10081 eassert (BEGV >= BEG);
10082 eassert (ZV <= Z && ZV >= BEGV);
10083
10084 unbind_to (count, Qnil);
10085 return rc;
10086 }
10087
10088
10089 /* Save state that should be preserved around the call to the function
10090 FN called in with_echo_area_buffer. */
10091
10092 static Lisp_Object
10093 with_echo_area_buffer_unwind_data (struct window *w)
10094 {
10095 int i = 0;
10096 Lisp_Object vector, tmp;
10097
10098 /* Reduce consing by keeping one vector in
10099 Vwith_echo_area_save_vector. */
10100 vector = Vwith_echo_area_save_vector;
10101 Vwith_echo_area_save_vector = Qnil;
10102
10103 if (NILP (vector))
10104 vector = Fmake_vector (make_number (7), Qnil);
10105
10106 XSETBUFFER (tmp, current_buffer); ASET (vector, i, tmp); ++i;
10107 ASET (vector, i, Vdeactivate_mark); ++i;
10108 ASET (vector, i, make_number (windows_or_buffers_changed)); ++i;
10109
10110 if (w)
10111 {
10112 XSETWINDOW (tmp, w); ASET (vector, i, tmp); ++i;
10113 ASET (vector, i, w->buffer); ++i;
10114 ASET (vector, i, make_number (XMARKER (w->pointm)->charpos)); ++i;
10115 ASET (vector, i, make_number (XMARKER (w->pointm)->bytepos)); ++i;
10116 }
10117 else
10118 {
10119 int end = i + 4;
10120 for (; i < end; ++i)
10121 ASET (vector, i, Qnil);
10122 }
10123
10124 eassert (i == ASIZE (vector));
10125 return vector;
10126 }
10127
10128
10129 /* Restore global state from VECTOR which was created by
10130 with_echo_area_buffer_unwind_data. */
10131
10132 static Lisp_Object
10133 unwind_with_echo_area_buffer (Lisp_Object vector)
10134 {
10135 set_buffer_internal_1 (XBUFFER (AREF (vector, 0)));
10136 Vdeactivate_mark = AREF (vector, 1);
10137 windows_or_buffers_changed = XFASTINT (AREF (vector, 2));
10138
10139 if (WINDOWP (AREF (vector, 3)))
10140 {
10141 struct window *w;
10142 Lisp_Object buffer, charpos, bytepos;
10143
10144 w = XWINDOW (AREF (vector, 3));
10145 buffer = AREF (vector, 4);
10146 charpos = AREF (vector, 5);
10147 bytepos = AREF (vector, 6);
10148
10149 wset_buffer (w, buffer);
10150 set_marker_both (w->pointm, buffer,
10151 XFASTINT (charpos), XFASTINT (bytepos));
10152 }
10153
10154 Vwith_echo_area_save_vector = vector;
10155 return Qnil;
10156 }
10157
10158
10159 /* Set up the echo area for use by print functions. MULTIBYTE_P
10160 non-zero means we will print multibyte. */
10161
10162 void
10163 setup_echo_area_for_printing (int multibyte_p)
10164 {
10165 /* If we can't find an echo area any more, exit. */
10166 if (! FRAME_LIVE_P (XFRAME (selected_frame)))
10167 Fkill_emacs (Qnil);
10168
10169 ensure_echo_area_buffers ();
10170
10171 if (!message_buf_print)
10172 {
10173 /* A message has been output since the last time we printed.
10174 Choose a fresh echo area buffer. */
10175 if (EQ (echo_area_buffer[1], echo_buffer[0]))
10176 echo_area_buffer[0] = echo_buffer[1];
10177 else
10178 echo_area_buffer[0] = echo_buffer[0];
10179
10180 /* Switch to that buffer and clear it. */
10181 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
10182 bset_truncate_lines (current_buffer, Qnil);
10183
10184 if (Z > BEG)
10185 {
10186 ptrdiff_t count = SPECPDL_INDEX ();
10187 specbind (Qinhibit_read_only, Qt);
10188 /* Note that undo recording is always disabled. */
10189 del_range (BEG, Z);
10190 unbind_to (count, Qnil);
10191 }
10192 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
10193
10194 /* Set up the buffer for the multibyteness we need. */
10195 if (multibyte_p
10196 != !NILP (BVAR (current_buffer, enable_multibyte_characters)))
10197 Fset_buffer_multibyte (multibyte_p ? Qt : Qnil);
10198
10199 /* Raise the frame containing the echo area. */
10200 if (minibuffer_auto_raise)
10201 {
10202 struct frame *sf = SELECTED_FRAME ();
10203 Lisp_Object mini_window;
10204 mini_window = FRAME_MINIBUF_WINDOW (sf);
10205 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
10206 }
10207
10208 message_log_maybe_newline ();
10209 message_buf_print = 1;
10210 }
10211 else
10212 {
10213 if (NILP (echo_area_buffer[0]))
10214 {
10215 if (EQ (echo_area_buffer[1], echo_buffer[0]))
10216 echo_area_buffer[0] = echo_buffer[1];
10217 else
10218 echo_area_buffer[0] = echo_buffer[0];
10219 }
10220
10221 if (current_buffer != XBUFFER (echo_area_buffer[0]))
10222 {
10223 /* Someone switched buffers between print requests. */
10224 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
10225 bset_truncate_lines (current_buffer, Qnil);
10226 }
10227 }
10228 }
10229
10230
10231 /* Display an echo area message in window W. Value is non-zero if W's
10232 height is changed. If display_last_displayed_message_p is
10233 non-zero, display the message that was last displayed, otherwise
10234 display the current message. */
10235
10236 static int
10237 display_echo_area (struct window *w)
10238 {
10239 int i, no_message_p, window_height_changed_p;
10240
10241 /* Temporarily disable garbage collections while displaying the echo
10242 area. This is done because a GC can print a message itself.
10243 That message would modify the echo area buffer's contents while a
10244 redisplay of the buffer is going on, and seriously confuse
10245 redisplay. */
10246 ptrdiff_t count = inhibit_garbage_collection ();
10247
10248 /* If there is no message, we must call display_echo_area_1
10249 nevertheless because it resizes the window. But we will have to
10250 reset the echo_area_buffer in question to nil at the end because
10251 with_echo_area_buffer will sets it to an empty buffer. */
10252 i = display_last_displayed_message_p ? 1 : 0;
10253 no_message_p = NILP (echo_area_buffer[i]);
10254
10255 window_height_changed_p
10256 = with_echo_area_buffer (w, display_last_displayed_message_p,
10257 display_echo_area_1,
10258 (intptr_t) w, Qnil, 0, 0);
10259
10260 if (no_message_p)
10261 echo_area_buffer[i] = Qnil;
10262
10263 unbind_to (count, Qnil);
10264 return window_height_changed_p;
10265 }
10266
10267
10268 /* Helper for display_echo_area. Display the current buffer which
10269 contains the current echo area message in window W, a mini-window,
10270 a pointer to which is passed in A1. A2..A4 are currently not used.
10271 Change the height of W so that all of the message is displayed.
10272 Value is non-zero if height of W was changed. */
10273
10274 static int
10275 display_echo_area_1 (ptrdiff_t a1, Lisp_Object a2, ptrdiff_t a3, ptrdiff_t a4)
10276 {
10277 intptr_t i1 = a1;
10278 struct window *w = (struct window *) i1;
10279 Lisp_Object window;
10280 struct text_pos start;
10281 int window_height_changed_p = 0;
10282
10283 /* Do this before displaying, so that we have a large enough glyph
10284 matrix for the display. If we can't get enough space for the
10285 whole text, display the last N lines. That works by setting w->start. */
10286 window_height_changed_p = resize_mini_window (w, 0);
10287
10288 /* Use the starting position chosen by resize_mini_window. */
10289 SET_TEXT_POS_FROM_MARKER (start, w->start);
10290
10291 /* Display. */
10292 clear_glyph_matrix (w->desired_matrix);
10293 XSETWINDOW (window, w);
10294 try_window (window, start, 0);
10295
10296 return window_height_changed_p;
10297 }
10298
10299
10300 /* Resize the echo area window to exactly the size needed for the
10301 currently displayed message, if there is one. If a mini-buffer
10302 is active, don't shrink it. */
10303
10304 void
10305 resize_echo_area_exactly (void)
10306 {
10307 if (BUFFERP (echo_area_buffer[0])
10308 && WINDOWP (echo_area_window))
10309 {
10310 struct window *w = XWINDOW (echo_area_window);
10311 int resized_p;
10312 Lisp_Object resize_exactly;
10313
10314 if (minibuf_level == 0)
10315 resize_exactly = Qt;
10316 else
10317 resize_exactly = Qnil;
10318
10319 resized_p = with_echo_area_buffer (w, 0, resize_mini_window_1,
10320 (intptr_t) w, resize_exactly,
10321 0, 0);
10322 if (resized_p)
10323 {
10324 ++windows_or_buffers_changed;
10325 ++update_mode_lines;
10326 redisplay_internal ();
10327 }
10328 }
10329 }
10330
10331
10332 /* Callback function for with_echo_area_buffer, when used from
10333 resize_echo_area_exactly. A1 contains a pointer to the window to
10334 resize, EXACTLY non-nil means resize the mini-window exactly to the
10335 size of the text displayed. A3 and A4 are not used. Value is what
10336 resize_mini_window returns. */
10337
10338 static int
10339 resize_mini_window_1 (ptrdiff_t a1, Lisp_Object exactly, ptrdiff_t a3, ptrdiff_t a4)
10340 {
10341 intptr_t i1 = a1;
10342 return resize_mini_window ((struct window *) i1, !NILP (exactly));
10343 }
10344
10345
10346 /* Resize mini-window W to fit the size of its contents. EXACT_P
10347 means size the window exactly to the size needed. Otherwise, it's
10348 only enlarged until W's buffer is empty.
10349
10350 Set W->start to the right place to begin display. If the whole
10351 contents fit, start at the beginning. Otherwise, start so as
10352 to make the end of the contents appear. This is particularly
10353 important for y-or-n-p, but seems desirable generally.
10354
10355 Value is non-zero if the window height has been changed. */
10356
10357 int
10358 resize_mini_window (struct window *w, int exact_p)
10359 {
10360 struct frame *f = XFRAME (w->frame);
10361 int window_height_changed_p = 0;
10362
10363 eassert (MINI_WINDOW_P (w));
10364
10365 /* By default, start display at the beginning. */
10366 set_marker_both (w->start, w->buffer,
10367 BUF_BEGV (XBUFFER (w->buffer)),
10368 BUF_BEGV_BYTE (XBUFFER (w->buffer)));
10369
10370 /* Don't resize windows while redisplaying a window; it would
10371 confuse redisplay functions when the size of the window they are
10372 displaying changes from under them. Such a resizing can happen,
10373 for instance, when which-func prints a long message while
10374 we are running fontification-functions. We're running these
10375 functions with safe_call which binds inhibit-redisplay to t. */
10376 if (!NILP (Vinhibit_redisplay))
10377 return 0;
10378
10379 /* Nil means don't try to resize. */
10380 if (NILP (Vresize_mini_windows)
10381 || (FRAME_X_P (f) && FRAME_X_OUTPUT (f) == NULL))
10382 return 0;
10383
10384 if (!FRAME_MINIBUF_ONLY_P (f))
10385 {
10386 struct it it;
10387 struct window *root = XWINDOW (FRAME_ROOT_WINDOW (f));
10388 int total_height = WINDOW_TOTAL_LINES (root) + WINDOW_TOTAL_LINES (w);
10389 int height;
10390 EMACS_INT max_height;
10391 int unit = FRAME_LINE_HEIGHT (f);
10392 struct text_pos start;
10393 struct buffer *old_current_buffer = NULL;
10394
10395 if (current_buffer != XBUFFER (w->buffer))
10396 {
10397 old_current_buffer = current_buffer;
10398 set_buffer_internal (XBUFFER (w->buffer));
10399 }
10400
10401 init_iterator (&it, w, BEGV, BEGV_BYTE, NULL, DEFAULT_FACE_ID);
10402
10403 /* Compute the max. number of lines specified by the user. */
10404 if (FLOATP (Vmax_mini_window_height))
10405 max_height = XFLOATINT (Vmax_mini_window_height) * FRAME_LINES (f);
10406 else if (INTEGERP (Vmax_mini_window_height))
10407 max_height = XINT (Vmax_mini_window_height);
10408 else
10409 max_height = total_height / 4;
10410
10411 /* Correct that max. height if it's bogus. */
10412 max_height = max (1, max_height);
10413 max_height = min (total_height, max_height);
10414
10415 /* Find out the height of the text in the window. */
10416 if (it.line_wrap == TRUNCATE)
10417 height = 1;
10418 else
10419 {
10420 last_height = 0;
10421 move_it_to (&it, ZV, -1, -1, -1, MOVE_TO_POS);
10422 if (it.max_ascent == 0 && it.max_descent == 0)
10423 height = it.current_y + last_height;
10424 else
10425 height = it.current_y + it.max_ascent + it.max_descent;
10426 height -= min (it.extra_line_spacing, it.max_extra_line_spacing);
10427 height = (height + unit - 1) / unit;
10428 }
10429
10430 /* Compute a suitable window start. */
10431 if (height > max_height)
10432 {
10433 height = max_height;
10434 init_iterator (&it, w, ZV, ZV_BYTE, NULL, DEFAULT_FACE_ID);
10435 move_it_vertically_backward (&it, (height - 1) * unit);
10436 start = it.current.pos;
10437 }
10438 else
10439 SET_TEXT_POS (start, BEGV, BEGV_BYTE);
10440 SET_MARKER_FROM_TEXT_POS (w->start, start);
10441
10442 if (EQ (Vresize_mini_windows, Qgrow_only))
10443 {
10444 /* Let it grow only, until we display an empty message, in which
10445 case the window shrinks again. */
10446 if (height > WINDOW_TOTAL_LINES (w))
10447 {
10448 int old_height = WINDOW_TOTAL_LINES (w);
10449 freeze_window_starts (f, 1);
10450 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
10451 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
10452 }
10453 else if (height < WINDOW_TOTAL_LINES (w)
10454 && (exact_p || BEGV == ZV))
10455 {
10456 int old_height = WINDOW_TOTAL_LINES (w);
10457 freeze_window_starts (f, 0);
10458 shrink_mini_window (w);
10459 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
10460 }
10461 }
10462 else
10463 {
10464 /* Always resize to exact size needed. */
10465 if (height > WINDOW_TOTAL_LINES (w))
10466 {
10467 int old_height = WINDOW_TOTAL_LINES (w);
10468 freeze_window_starts (f, 1);
10469 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
10470 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
10471 }
10472 else if (height < WINDOW_TOTAL_LINES (w))
10473 {
10474 int old_height = WINDOW_TOTAL_LINES (w);
10475 freeze_window_starts (f, 0);
10476 shrink_mini_window (w);
10477
10478 if (height)
10479 {
10480 freeze_window_starts (f, 1);
10481 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
10482 }
10483
10484 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
10485 }
10486 }
10487
10488 if (old_current_buffer)
10489 set_buffer_internal (old_current_buffer);
10490 }
10491
10492 return window_height_changed_p;
10493 }
10494
10495
10496 /* Value is the current message, a string, or nil if there is no
10497 current message. */
10498
10499 Lisp_Object
10500 current_message (void)
10501 {
10502 Lisp_Object msg;
10503
10504 if (!BUFFERP (echo_area_buffer[0]))
10505 msg = Qnil;
10506 else
10507 {
10508 with_echo_area_buffer (0, 0, current_message_1,
10509 (intptr_t) &msg, Qnil, 0, 0);
10510 if (NILP (msg))
10511 echo_area_buffer[0] = Qnil;
10512 }
10513
10514 return msg;
10515 }
10516
10517
10518 static int
10519 current_message_1 (ptrdiff_t a1, Lisp_Object a2, ptrdiff_t a3, ptrdiff_t a4)
10520 {
10521 intptr_t i1 = a1;
10522 Lisp_Object *msg = (Lisp_Object *) i1;
10523
10524 if (Z > BEG)
10525 *msg = make_buffer_string (BEG, Z, 1);
10526 else
10527 *msg = Qnil;
10528 return 0;
10529 }
10530
10531
10532 /* Push the current message on Vmessage_stack for later restoration
10533 by restore_message. Value is non-zero if the current message isn't
10534 empty. This is a relatively infrequent operation, so it's not
10535 worth optimizing. */
10536
10537 bool
10538 push_message (void)
10539 {
10540 Lisp_Object msg = current_message ();
10541 Vmessage_stack = Fcons (msg, Vmessage_stack);
10542 return STRINGP (msg);
10543 }
10544
10545
10546 /* Restore message display from the top of Vmessage_stack. */
10547
10548 void
10549 restore_message (void)
10550 {
10551 Lisp_Object msg;
10552
10553 eassert (CONSP (Vmessage_stack));
10554 msg = XCAR (Vmessage_stack);
10555 if (STRINGP (msg))
10556 message3_nolog (msg, SBYTES (msg), STRING_MULTIBYTE (msg));
10557 else
10558 message3_nolog (msg, 0, 0);
10559 }
10560
10561
10562 /* Handler for record_unwind_protect calling pop_message. */
10563
10564 Lisp_Object
10565 pop_message_unwind (Lisp_Object dummy)
10566 {
10567 pop_message ();
10568 return Qnil;
10569 }
10570
10571 /* Pop the top-most entry off Vmessage_stack. */
10572
10573 static void
10574 pop_message (void)
10575 {
10576 eassert (CONSP (Vmessage_stack));
10577 Vmessage_stack = XCDR (Vmessage_stack);
10578 }
10579
10580
10581 /* Check that Vmessage_stack is nil. Called from emacs.c when Emacs
10582 exits. If the stack is not empty, we have a missing pop_message
10583 somewhere. */
10584
10585 void
10586 check_message_stack (void)
10587 {
10588 if (!NILP (Vmessage_stack))
10589 emacs_abort ();
10590 }
10591
10592
10593 /* Truncate to NCHARS what will be displayed in the echo area the next
10594 time we display it---but don't redisplay it now. */
10595
10596 void
10597 truncate_echo_area (ptrdiff_t nchars)
10598 {
10599 if (nchars == 0)
10600 echo_area_buffer[0] = Qnil;
10601 /* A null message buffer means that the frame hasn't really been
10602 initialized yet. Error messages get reported properly by
10603 cmd_error, so this must be just an informative message; toss it. */
10604 else if (!noninteractive
10605 && INTERACTIVE
10606 && !NILP (echo_area_buffer[0]))
10607 {
10608 struct frame *sf = SELECTED_FRAME ();
10609 if (FRAME_MESSAGE_BUF (sf))
10610 with_echo_area_buffer (0, 0, truncate_message_1, nchars, Qnil, 0, 0);
10611 }
10612 }
10613
10614
10615 /* Helper function for truncate_echo_area. Truncate the current
10616 message to at most NCHARS characters. */
10617
10618 static int
10619 truncate_message_1 (ptrdiff_t nchars, Lisp_Object a2, ptrdiff_t a3, ptrdiff_t a4)
10620 {
10621 if (BEG + nchars < Z)
10622 del_range (BEG + nchars, Z);
10623 if (Z == BEG)
10624 echo_area_buffer[0] = Qnil;
10625 return 0;
10626 }
10627
10628 /* Set the current message to a substring of S or STRING.
10629
10630 If STRING is a Lisp string, set the message to the first NBYTES
10631 bytes from STRING. NBYTES zero means use the whole string. If
10632 STRING is multibyte, the message will be displayed multibyte.
10633
10634 If S is not null, set the message to the first LEN bytes of S. LEN
10635 zero means use the whole string. MULTIBYTE_P non-zero means S is
10636 multibyte. Display the message multibyte in that case.
10637
10638 Doesn't GC, as with_echo_area_buffer binds Qinhibit_modification_hooks
10639 to t before calling set_message_1 (which calls insert).
10640 */
10641
10642 static void
10643 set_message (const char *s, Lisp_Object string,
10644 ptrdiff_t nbytes, int multibyte_p)
10645 {
10646 message_enable_multibyte
10647 = ((s && multibyte_p)
10648 || (STRINGP (string) && STRING_MULTIBYTE (string)));
10649
10650 with_echo_area_buffer (0, -1, set_message_1,
10651 (intptr_t) s, string, nbytes, multibyte_p);
10652 message_buf_print = 0;
10653 help_echo_showing_p = 0;
10654
10655 if (STRINGP (Vdebug_on_message)
10656 && fast_string_match (Vdebug_on_message, string) >= 0)
10657 call_debugger (list2 (Qerror, string));
10658 }
10659
10660
10661 /* Helper function for set_message. Arguments have the same meaning
10662 as there, with A1 corresponding to S and A2 corresponding to STRING
10663 This function is called with the echo area buffer being
10664 current. */
10665
10666 static int
10667 set_message_1 (ptrdiff_t a1, Lisp_Object a2, ptrdiff_t nbytes, ptrdiff_t multibyte_p)
10668 {
10669 intptr_t i1 = a1;
10670 const char *s = (const char *) i1;
10671 const unsigned char *msg = (const unsigned char *) s;
10672 Lisp_Object string = a2;
10673
10674 /* Change multibyteness of the echo buffer appropriately. */
10675 if (message_enable_multibyte
10676 != !NILP (BVAR (current_buffer, enable_multibyte_characters)))
10677 Fset_buffer_multibyte (message_enable_multibyte ? Qt : Qnil);
10678
10679 bset_truncate_lines (current_buffer, message_truncate_lines ? Qt : Qnil);
10680 if (!NILP (BVAR (current_buffer, bidi_display_reordering)))
10681 bset_bidi_paragraph_direction (current_buffer, Qleft_to_right);
10682
10683 /* Insert new message at BEG. */
10684 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
10685
10686 if (STRINGP (string))
10687 {
10688 ptrdiff_t nchars;
10689
10690 if (nbytes == 0)
10691 nbytes = SBYTES (string);
10692 nchars = string_byte_to_char (string, nbytes);
10693
10694 /* This function takes care of single/multibyte conversion. We
10695 just have to ensure that the echo area buffer has the right
10696 setting of enable_multibyte_characters. */
10697 insert_from_string (string, 0, 0, nchars, nbytes, 1);
10698 }
10699 else if (s)
10700 {
10701 if (nbytes == 0)
10702 nbytes = strlen (s);
10703
10704 if (multibyte_p && NILP (BVAR (current_buffer, enable_multibyte_characters)))
10705 {
10706 /* Convert from multi-byte to single-byte. */
10707 ptrdiff_t i;
10708 int c, n;
10709 char work[1];
10710
10711 /* Convert a multibyte string to single-byte. */
10712 for (i = 0; i < nbytes; i += n)
10713 {
10714 c = string_char_and_length (msg + i, &n);
10715 work[0] = (ASCII_CHAR_P (c)
10716 ? c
10717 : multibyte_char_to_unibyte (c));
10718 insert_1_both (work, 1, 1, 1, 0, 0);
10719 }
10720 }
10721 else if (!multibyte_p
10722 && !NILP (BVAR (current_buffer, enable_multibyte_characters)))
10723 {
10724 /* Convert from single-byte to multi-byte. */
10725 ptrdiff_t i;
10726 int c, n;
10727 unsigned char str[MAX_MULTIBYTE_LENGTH];
10728
10729 /* Convert a single-byte string to multibyte. */
10730 for (i = 0; i < nbytes; i++)
10731 {
10732 c = msg[i];
10733 MAKE_CHAR_MULTIBYTE (c);
10734 n = CHAR_STRING (c, str);
10735 insert_1_both ((char *) str, 1, n, 1, 0, 0);
10736 }
10737 }
10738 else
10739 insert_1 (s, nbytes, 1, 0, 0);
10740 }
10741
10742 return 0;
10743 }
10744
10745
10746 /* Clear messages. CURRENT_P non-zero means clear the current
10747 message. LAST_DISPLAYED_P non-zero means clear the message
10748 last displayed. */
10749
10750 void
10751 clear_message (int current_p, int last_displayed_p)
10752 {
10753 if (current_p)
10754 {
10755 echo_area_buffer[0] = Qnil;
10756 message_cleared_p = 1;
10757 }
10758
10759 if (last_displayed_p)
10760 echo_area_buffer[1] = Qnil;
10761
10762 message_buf_print = 0;
10763 }
10764
10765 /* Clear garbaged frames.
10766
10767 This function is used where the old redisplay called
10768 redraw_garbaged_frames which in turn called redraw_frame which in
10769 turn called clear_frame. The call to clear_frame was a source of
10770 flickering. I believe a clear_frame is not necessary. It should
10771 suffice in the new redisplay to invalidate all current matrices,
10772 and ensure a complete redisplay of all windows. */
10773
10774 static void
10775 clear_garbaged_frames (void)
10776 {
10777 if (frame_garbaged)
10778 {
10779 Lisp_Object tail, frame;
10780 int changed_count = 0;
10781
10782 FOR_EACH_FRAME (tail, frame)
10783 {
10784 struct frame *f = XFRAME (frame);
10785
10786 if (FRAME_VISIBLE_P (f) && FRAME_GARBAGED_P (f))
10787 {
10788 if (f->resized_p)
10789 {
10790 Fredraw_frame (frame);
10791 f->force_flush_display_p = 1;
10792 }
10793 clear_current_matrices (f);
10794 changed_count++;
10795 f->garbaged = 0;
10796 f->resized_p = 0;
10797 }
10798 }
10799
10800 frame_garbaged = 0;
10801 if (changed_count)
10802 ++windows_or_buffers_changed;
10803 }
10804 }
10805
10806
10807 /* Redisplay the echo area of the selected frame. If UPDATE_FRAME_P
10808 is non-zero update selected_frame. Value is non-zero if the
10809 mini-windows height has been changed. */
10810
10811 static int
10812 echo_area_display (int update_frame_p)
10813 {
10814 Lisp_Object mini_window;
10815 struct window *w;
10816 struct frame *f;
10817 int window_height_changed_p = 0;
10818 struct frame *sf = SELECTED_FRAME ();
10819
10820 mini_window = FRAME_MINIBUF_WINDOW (sf);
10821 w = XWINDOW (mini_window);
10822 f = XFRAME (WINDOW_FRAME (w));
10823
10824 /* Don't display if frame is invisible or not yet initialized. */
10825 if (!FRAME_VISIBLE_P (f) || !f->glyphs_initialized_p)
10826 return 0;
10827
10828 #ifdef HAVE_WINDOW_SYSTEM
10829 /* When Emacs starts, selected_frame may be the initial terminal
10830 frame. If we let this through, a message would be displayed on
10831 the terminal. */
10832 if (FRAME_INITIAL_P (XFRAME (selected_frame)))
10833 return 0;
10834 #endif /* HAVE_WINDOW_SYSTEM */
10835
10836 /* Redraw garbaged frames. */
10837 if (frame_garbaged)
10838 clear_garbaged_frames ();
10839
10840 if (!NILP (echo_area_buffer[0]) || minibuf_level == 0)
10841 {
10842 echo_area_window = mini_window;
10843 window_height_changed_p = display_echo_area (w);
10844 w->must_be_updated_p = 1;
10845
10846 /* Update the display, unless called from redisplay_internal.
10847 Also don't update the screen during redisplay itself. The
10848 update will happen at the end of redisplay, and an update
10849 here could cause confusion. */
10850 if (update_frame_p && !redisplaying_p)
10851 {
10852 int n = 0;
10853
10854 /* If the display update has been interrupted by pending
10855 input, update mode lines in the frame. Due to the
10856 pending input, it might have been that redisplay hasn't
10857 been called, so that mode lines above the echo area are
10858 garbaged. This looks odd, so we prevent it here. */
10859 if (!display_completed)
10860 n = redisplay_mode_lines (FRAME_ROOT_WINDOW (f), 0);
10861
10862 if (window_height_changed_p
10863 /* Don't do this if Emacs is shutting down. Redisplay
10864 needs to run hooks. */
10865 && !NILP (Vrun_hooks))
10866 {
10867 /* Must update other windows. Likewise as in other
10868 cases, don't let this update be interrupted by
10869 pending input. */
10870 ptrdiff_t count = SPECPDL_INDEX ();
10871 specbind (Qredisplay_dont_pause, Qt);
10872 windows_or_buffers_changed = 1;
10873 redisplay_internal ();
10874 unbind_to (count, Qnil);
10875 }
10876 else if (FRAME_WINDOW_P (f) && n == 0)
10877 {
10878 /* Window configuration is the same as before.
10879 Can do with a display update of the echo area,
10880 unless we displayed some mode lines. */
10881 update_single_window (w, 1);
10882 FRAME_RIF (f)->flush_display (f);
10883 }
10884 else
10885 update_frame (f, 1, 1);
10886
10887 /* If cursor is in the echo area, make sure that the next
10888 redisplay displays the minibuffer, so that the cursor will
10889 be replaced with what the minibuffer wants. */
10890 if (cursor_in_echo_area)
10891 ++windows_or_buffers_changed;
10892 }
10893 }
10894 else if (!EQ (mini_window, selected_window))
10895 windows_or_buffers_changed++;
10896
10897 /* Last displayed message is now the current message. */
10898 echo_area_buffer[1] = echo_area_buffer[0];
10899 /* Inform read_char that we're not echoing. */
10900 echo_message_buffer = Qnil;
10901
10902 /* Prevent redisplay optimization in redisplay_internal by resetting
10903 this_line_start_pos. This is done because the mini-buffer now
10904 displays the message instead of its buffer text. */
10905 if (EQ (mini_window, selected_window))
10906 CHARPOS (this_line_start_pos) = 0;
10907
10908 return window_height_changed_p;
10909 }
10910
10911
10912 \f
10913 /***********************************************************************
10914 Mode Lines and Frame Titles
10915 ***********************************************************************/
10916
10917 /* A buffer for constructing non-propertized mode-line strings and
10918 frame titles in it; allocated from the heap in init_xdisp and
10919 resized as needed in store_mode_line_noprop_char. */
10920
10921 static char *mode_line_noprop_buf;
10922
10923 /* The buffer's end, and a current output position in it. */
10924
10925 static char *mode_line_noprop_buf_end;
10926 static char *mode_line_noprop_ptr;
10927
10928 #define MODE_LINE_NOPROP_LEN(start) \
10929 ((mode_line_noprop_ptr - mode_line_noprop_buf) - start)
10930
10931 static enum {
10932 MODE_LINE_DISPLAY = 0,
10933 MODE_LINE_TITLE,
10934 MODE_LINE_NOPROP,
10935 MODE_LINE_STRING
10936 } mode_line_target;
10937
10938 /* Alist that caches the results of :propertize.
10939 Each element is (PROPERTIZED-STRING . PROPERTY-LIST). */
10940 static Lisp_Object mode_line_proptrans_alist;
10941
10942 /* List of strings making up the mode-line. */
10943 static Lisp_Object mode_line_string_list;
10944
10945 /* Base face property when building propertized mode line string. */
10946 static Lisp_Object mode_line_string_face;
10947 static Lisp_Object mode_line_string_face_prop;
10948
10949
10950 /* Unwind data for mode line strings */
10951
10952 static Lisp_Object Vmode_line_unwind_vector;
10953
10954 static Lisp_Object
10955 format_mode_line_unwind_data (struct frame *target_frame,
10956 struct buffer *obuf,
10957 Lisp_Object owin,
10958 int save_proptrans)
10959 {
10960 Lisp_Object vector, tmp;
10961
10962 /* Reduce consing by keeping one vector in
10963 Vwith_echo_area_save_vector. */
10964 vector = Vmode_line_unwind_vector;
10965 Vmode_line_unwind_vector = Qnil;
10966
10967 if (NILP (vector))
10968 vector = Fmake_vector (make_number (10), Qnil);
10969
10970 ASET (vector, 0, make_number (mode_line_target));
10971 ASET (vector, 1, make_number (MODE_LINE_NOPROP_LEN (0)));
10972 ASET (vector, 2, mode_line_string_list);
10973 ASET (vector, 3, save_proptrans ? mode_line_proptrans_alist : Qt);
10974 ASET (vector, 4, mode_line_string_face);
10975 ASET (vector, 5, mode_line_string_face_prop);
10976
10977 if (obuf)
10978 XSETBUFFER (tmp, obuf);
10979 else
10980 tmp = Qnil;
10981 ASET (vector, 6, tmp);
10982 ASET (vector, 7, owin);
10983 if (target_frame)
10984 {
10985 /* Similarly to `with-selected-window', if the operation selects
10986 a window on another frame, we must restore that frame's
10987 selected window, and (for a tty) the top-frame. */
10988 ASET (vector, 8, target_frame->selected_window);
10989 if (FRAME_TERMCAP_P (target_frame))
10990 ASET (vector, 9, FRAME_TTY (target_frame)->top_frame);
10991 }
10992
10993 return vector;
10994 }
10995
10996 static Lisp_Object
10997 unwind_format_mode_line (Lisp_Object vector)
10998 {
10999 Lisp_Object old_window = AREF (vector, 7);
11000 Lisp_Object target_frame_window = AREF (vector, 8);
11001 Lisp_Object old_top_frame = AREF (vector, 9);
11002
11003 mode_line_target = XINT (AREF (vector, 0));
11004 mode_line_noprop_ptr = mode_line_noprop_buf + XINT (AREF (vector, 1));
11005 mode_line_string_list = AREF (vector, 2);
11006 if (! EQ (AREF (vector, 3), Qt))
11007 mode_line_proptrans_alist = AREF (vector, 3);
11008 mode_line_string_face = AREF (vector, 4);
11009 mode_line_string_face_prop = AREF (vector, 5);
11010
11011 /* Select window before buffer, since it may change the buffer. */
11012 if (!NILP (old_window))
11013 {
11014 /* If the operation that we are unwinding had selected a window
11015 on a different frame, reset its frame-selected-window. For a
11016 text terminal, reset its top-frame if necessary. */
11017 if (!NILP (target_frame_window))
11018 {
11019 Lisp_Object frame
11020 = WINDOW_FRAME (XWINDOW (target_frame_window));
11021
11022 if (!EQ (frame, WINDOW_FRAME (XWINDOW (old_window))))
11023 Fselect_window (target_frame_window, Qt);
11024
11025 if (!NILP (old_top_frame) && !EQ (old_top_frame, frame))
11026 Fselect_frame (old_top_frame, Qt);
11027 }
11028
11029 Fselect_window (old_window, Qt);
11030 }
11031
11032 if (!NILP (AREF (vector, 6)))
11033 {
11034 set_buffer_internal_1 (XBUFFER (AREF (vector, 6)));
11035 ASET (vector, 6, Qnil);
11036 }
11037
11038 Vmode_line_unwind_vector = vector;
11039 return Qnil;
11040 }
11041
11042
11043 /* Store a single character C for the frame title in mode_line_noprop_buf.
11044 Re-allocate mode_line_noprop_buf if necessary. */
11045
11046 static void
11047 store_mode_line_noprop_char (char c)
11048 {
11049 /* If output position has reached the end of the allocated buffer,
11050 increase the buffer's size. */
11051 if (mode_line_noprop_ptr == mode_line_noprop_buf_end)
11052 {
11053 ptrdiff_t len = MODE_LINE_NOPROP_LEN (0);
11054 ptrdiff_t size = len;
11055 mode_line_noprop_buf =
11056 xpalloc (mode_line_noprop_buf, &size, 1, STRING_BYTES_BOUND, 1);
11057 mode_line_noprop_buf_end = mode_line_noprop_buf + size;
11058 mode_line_noprop_ptr = mode_line_noprop_buf + len;
11059 }
11060
11061 *mode_line_noprop_ptr++ = c;
11062 }
11063
11064
11065 /* Store part of a frame title in mode_line_noprop_buf, beginning at
11066 mode_line_noprop_ptr. STRING is the string to store. Do not copy
11067 characters that yield more columns than PRECISION; PRECISION <= 0
11068 means copy the whole string. Pad with spaces until FIELD_WIDTH
11069 number of characters have been copied; FIELD_WIDTH <= 0 means don't
11070 pad. Called from display_mode_element when it is used to build a
11071 frame title. */
11072
11073 static int
11074 store_mode_line_noprop (const char *string, int field_width, int precision)
11075 {
11076 const unsigned char *str = (const unsigned char *) string;
11077 int n = 0;
11078 ptrdiff_t dummy, nbytes;
11079
11080 /* Copy at most PRECISION chars from STR. */
11081 nbytes = strlen (string);
11082 n += c_string_width (str, nbytes, precision, &dummy, &nbytes);
11083 while (nbytes--)
11084 store_mode_line_noprop_char (*str++);
11085
11086 /* Fill up with spaces until FIELD_WIDTH reached. */
11087 while (field_width > 0
11088 && n < field_width)
11089 {
11090 store_mode_line_noprop_char (' ');
11091 ++n;
11092 }
11093
11094 return n;
11095 }
11096
11097 /***********************************************************************
11098 Frame Titles
11099 ***********************************************************************/
11100
11101 #ifdef HAVE_WINDOW_SYSTEM
11102
11103 /* Set the title of FRAME, if it has changed. The title format is
11104 Vicon_title_format if FRAME is iconified, otherwise it is
11105 frame_title_format. */
11106
11107 static void
11108 x_consider_frame_title (Lisp_Object frame)
11109 {
11110 struct frame *f = XFRAME (frame);
11111
11112 if (FRAME_WINDOW_P (f)
11113 || FRAME_MINIBUF_ONLY_P (f)
11114 || f->explicit_name)
11115 {
11116 /* Do we have more than one visible frame on this X display? */
11117 Lisp_Object tail;
11118 Lisp_Object fmt;
11119 ptrdiff_t title_start;
11120 char *title;
11121 ptrdiff_t len;
11122 struct it it;
11123 ptrdiff_t count = SPECPDL_INDEX ();
11124
11125 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
11126 {
11127 Lisp_Object other_frame = XCAR (tail);
11128 struct frame *tf = XFRAME (other_frame);
11129
11130 if (tf != f
11131 && FRAME_KBOARD (tf) == FRAME_KBOARD (f)
11132 && !FRAME_MINIBUF_ONLY_P (tf)
11133 && !EQ (other_frame, tip_frame)
11134 && (FRAME_VISIBLE_P (tf) || FRAME_ICONIFIED_P (tf)))
11135 break;
11136 }
11137
11138 /* Set global variable indicating that multiple frames exist. */
11139 multiple_frames = CONSP (tail);
11140
11141 /* Switch to the buffer of selected window of the frame. Set up
11142 mode_line_target so that display_mode_element will output into
11143 mode_line_noprop_buf; then display the title. */
11144 record_unwind_protect (unwind_format_mode_line,
11145 format_mode_line_unwind_data
11146 (f, current_buffer, selected_window, 0));
11147
11148 Fselect_window (f->selected_window, Qt);
11149 set_buffer_internal_1
11150 (XBUFFER (XWINDOW (f->selected_window)->buffer));
11151 fmt = FRAME_ICONIFIED_P (f) ? Vicon_title_format : Vframe_title_format;
11152
11153 mode_line_target = MODE_LINE_TITLE;
11154 title_start = MODE_LINE_NOPROP_LEN (0);
11155 init_iterator (&it, XWINDOW (f->selected_window), -1, -1,
11156 NULL, DEFAULT_FACE_ID);
11157 display_mode_element (&it, 0, -1, -1, fmt, Qnil, 0);
11158 len = MODE_LINE_NOPROP_LEN (title_start);
11159 title = mode_line_noprop_buf + title_start;
11160 unbind_to (count, Qnil);
11161
11162 /* Set the title only if it's changed. This avoids consing in
11163 the common case where it hasn't. (If it turns out that we've
11164 already wasted too much time by walking through the list with
11165 display_mode_element, then we might need to optimize at a
11166 higher level than this.) */
11167 if (! STRINGP (f->name)
11168 || SBYTES (f->name) != len
11169 || memcmp (title, SDATA (f->name), len) != 0)
11170 x_implicitly_set_name (f, make_string (title, len), Qnil);
11171 }
11172 }
11173
11174 #endif /* not HAVE_WINDOW_SYSTEM */
11175
11176 \f
11177 /***********************************************************************
11178 Menu Bars
11179 ***********************************************************************/
11180
11181
11182 /* Prepare for redisplay by updating menu-bar item lists when
11183 appropriate. This can call eval. */
11184
11185 void
11186 prepare_menu_bars (void)
11187 {
11188 int all_windows;
11189 struct gcpro gcpro1, gcpro2;
11190 struct frame *f;
11191 Lisp_Object tooltip_frame;
11192
11193 #ifdef HAVE_WINDOW_SYSTEM
11194 tooltip_frame = tip_frame;
11195 #else
11196 tooltip_frame = Qnil;
11197 #endif
11198
11199 /* Update all frame titles based on their buffer names, etc. We do
11200 this before the menu bars so that the buffer-menu will show the
11201 up-to-date frame titles. */
11202 #ifdef HAVE_WINDOW_SYSTEM
11203 if (windows_or_buffers_changed || update_mode_lines)
11204 {
11205 Lisp_Object tail, frame;
11206
11207 FOR_EACH_FRAME (tail, frame)
11208 {
11209 f = XFRAME (frame);
11210 if (!EQ (frame, tooltip_frame)
11211 && (FRAME_VISIBLE_P (f) || FRAME_ICONIFIED_P (f)))
11212 x_consider_frame_title (frame);
11213 }
11214 }
11215 #endif /* HAVE_WINDOW_SYSTEM */
11216
11217 /* Update the menu bar item lists, if appropriate. This has to be
11218 done before any actual redisplay or generation of display lines. */
11219 all_windows = (update_mode_lines
11220 || buffer_shared > 1
11221 || windows_or_buffers_changed);
11222 if (all_windows)
11223 {
11224 Lisp_Object tail, frame;
11225 ptrdiff_t count = SPECPDL_INDEX ();
11226 /* 1 means that update_menu_bar has run its hooks
11227 so any further calls to update_menu_bar shouldn't do so again. */
11228 int menu_bar_hooks_run = 0;
11229
11230 record_unwind_save_match_data ();
11231
11232 FOR_EACH_FRAME (tail, frame)
11233 {
11234 f = XFRAME (frame);
11235
11236 /* Ignore tooltip frame. */
11237 if (EQ (frame, tooltip_frame))
11238 continue;
11239
11240 /* If a window on this frame changed size, report that to
11241 the user and clear the size-change flag. */
11242 if (FRAME_WINDOW_SIZES_CHANGED (f))
11243 {
11244 Lisp_Object functions;
11245
11246 /* Clear flag first in case we get an error below. */
11247 FRAME_WINDOW_SIZES_CHANGED (f) = 0;
11248 functions = Vwindow_size_change_functions;
11249 GCPRO2 (tail, functions);
11250
11251 while (CONSP (functions))
11252 {
11253 if (!EQ (XCAR (functions), Qt))
11254 call1 (XCAR (functions), frame);
11255 functions = XCDR (functions);
11256 }
11257 UNGCPRO;
11258 }
11259
11260 GCPRO1 (tail);
11261 menu_bar_hooks_run = update_menu_bar (f, 0, menu_bar_hooks_run);
11262 #ifdef HAVE_WINDOW_SYSTEM
11263 update_tool_bar (f, 0);
11264 #endif
11265 #ifdef HAVE_NS
11266 if (windows_or_buffers_changed
11267 && FRAME_NS_P (f))
11268 ns_set_doc_edited
11269 (f, Fbuffer_modified_p (XWINDOW (f->selected_window)->buffer));
11270 #endif
11271 UNGCPRO;
11272 }
11273
11274 unbind_to (count, Qnil);
11275 }
11276 else
11277 {
11278 struct frame *sf = SELECTED_FRAME ();
11279 update_menu_bar (sf, 1, 0);
11280 #ifdef HAVE_WINDOW_SYSTEM
11281 update_tool_bar (sf, 1);
11282 #endif
11283 }
11284 }
11285
11286
11287 /* Update the menu bar item list for frame F. This has to be done
11288 before we start to fill in any display lines, because it can call
11289 eval.
11290
11291 If SAVE_MATCH_DATA is non-zero, we must save and restore it here.
11292
11293 If HOOKS_RUN is 1, that means a previous call to update_menu_bar
11294 already ran the menu bar hooks for this redisplay, so there
11295 is no need to run them again. The return value is the
11296 updated value of this flag, to pass to the next call. */
11297
11298 static int
11299 update_menu_bar (struct frame *f, int save_match_data, int hooks_run)
11300 {
11301 Lisp_Object window;
11302 register struct window *w;
11303
11304 /* If called recursively during a menu update, do nothing. This can
11305 happen when, for instance, an activate-menubar-hook causes a
11306 redisplay. */
11307 if (inhibit_menubar_update)
11308 return hooks_run;
11309
11310 window = FRAME_SELECTED_WINDOW (f);
11311 w = XWINDOW (window);
11312
11313 if (FRAME_WINDOW_P (f)
11314 ?
11315 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
11316 || defined (HAVE_NS) || defined (USE_GTK)
11317 FRAME_EXTERNAL_MENU_BAR (f)
11318 #else
11319 FRAME_MENU_BAR_LINES (f) > 0
11320 #endif
11321 : FRAME_MENU_BAR_LINES (f) > 0)
11322 {
11323 /* If the user has switched buffers or windows, we need to
11324 recompute to reflect the new bindings. But we'll
11325 recompute when update_mode_lines is set too; that means
11326 that people can use force-mode-line-update to request
11327 that the menu bar be recomputed. The adverse effect on
11328 the rest of the redisplay algorithm is about the same as
11329 windows_or_buffers_changed anyway. */
11330 if (windows_or_buffers_changed
11331 /* This used to test w->update_mode_line, but we believe
11332 there is no need to recompute the menu in that case. */
11333 || update_mode_lines
11334 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
11335 < BUF_MODIFF (XBUFFER (w->buffer)))
11336 != w->last_had_star)
11337 || ((!NILP (Vtransient_mark_mode)
11338 && !NILP (BVAR (XBUFFER (w->buffer), mark_active)))
11339 != !NILP (w->region_showing)))
11340 {
11341 struct buffer *prev = current_buffer;
11342 ptrdiff_t count = SPECPDL_INDEX ();
11343
11344 specbind (Qinhibit_menubar_update, Qt);
11345
11346 set_buffer_internal_1 (XBUFFER (w->buffer));
11347 if (save_match_data)
11348 record_unwind_save_match_data ();
11349 if (NILP (Voverriding_local_map_menu_flag))
11350 {
11351 specbind (Qoverriding_terminal_local_map, Qnil);
11352 specbind (Qoverriding_local_map, Qnil);
11353 }
11354
11355 if (!hooks_run)
11356 {
11357 /* Run the Lucid hook. */
11358 safe_run_hooks (Qactivate_menubar_hook);
11359
11360 /* If it has changed current-menubar from previous value,
11361 really recompute the menu-bar from the value. */
11362 if (! NILP (Vlucid_menu_bar_dirty_flag))
11363 call0 (Qrecompute_lucid_menubar);
11364
11365 safe_run_hooks (Qmenu_bar_update_hook);
11366
11367 hooks_run = 1;
11368 }
11369
11370 XSETFRAME (Vmenu_updating_frame, f);
11371 fset_menu_bar_items (f, menu_bar_items (FRAME_MENU_BAR_ITEMS (f)));
11372
11373 /* Redisplay the menu bar in case we changed it. */
11374 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
11375 || defined (HAVE_NS) || defined (USE_GTK)
11376 if (FRAME_WINDOW_P (f))
11377 {
11378 #if defined (HAVE_NS)
11379 /* All frames on Mac OS share the same menubar. So only
11380 the selected frame should be allowed to set it. */
11381 if (f == SELECTED_FRAME ())
11382 #endif
11383 set_frame_menubar (f, 0, 0);
11384 }
11385 else
11386 /* On a terminal screen, the menu bar is an ordinary screen
11387 line, and this makes it get updated. */
11388 w->update_mode_line = 1;
11389 #else /* ! (USE_X_TOOLKIT || HAVE_NTGUI || HAVE_NS || USE_GTK) */
11390 /* In the non-toolkit version, the menu bar is an ordinary screen
11391 line, and this makes it get updated. */
11392 w->update_mode_line = 1;
11393 #endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI || HAVE_NS || USE_GTK) */
11394
11395 unbind_to (count, Qnil);
11396 set_buffer_internal_1 (prev);
11397 }
11398 }
11399
11400 return hooks_run;
11401 }
11402
11403
11404 \f
11405 /***********************************************************************
11406 Output Cursor
11407 ***********************************************************************/
11408
11409 #ifdef HAVE_WINDOW_SYSTEM
11410
11411 /* EXPORT:
11412 Nominal cursor position -- where to draw output.
11413 HPOS and VPOS are window relative glyph matrix coordinates.
11414 X and Y are window relative pixel coordinates. */
11415
11416 struct cursor_pos output_cursor;
11417
11418
11419 /* EXPORT:
11420 Set the global variable output_cursor to CURSOR. All cursor
11421 positions are relative to updated_window. */
11422
11423 void
11424 set_output_cursor (struct cursor_pos *cursor)
11425 {
11426 output_cursor.hpos = cursor->hpos;
11427 output_cursor.vpos = cursor->vpos;
11428 output_cursor.x = cursor->x;
11429 output_cursor.y = cursor->y;
11430 }
11431
11432
11433 /* EXPORT for RIF:
11434 Set a nominal cursor position.
11435
11436 HPOS and VPOS are column/row positions in a window glyph matrix. X
11437 and Y are window text area relative pixel positions.
11438
11439 If this is done during an update, updated_window will contain the
11440 window that is being updated and the position is the future output
11441 cursor position for that window. If updated_window is null, use
11442 selected_window and display the cursor at the given position. */
11443
11444 void
11445 x_cursor_to (int vpos, int hpos, int y, int x)
11446 {
11447 struct window *w;
11448
11449 /* If updated_window is not set, work on selected_window. */
11450 if (updated_window)
11451 w = updated_window;
11452 else
11453 w = XWINDOW (selected_window);
11454
11455 /* Set the output cursor. */
11456 output_cursor.hpos = hpos;
11457 output_cursor.vpos = vpos;
11458 output_cursor.x = x;
11459 output_cursor.y = y;
11460
11461 /* If not called as part of an update, really display the cursor.
11462 This will also set the cursor position of W. */
11463 if (updated_window == NULL)
11464 {
11465 BLOCK_INPUT;
11466 display_and_set_cursor (w, 1, hpos, vpos, x, y);
11467 if (FRAME_RIF (SELECTED_FRAME ())->flush_display_optional)
11468 FRAME_RIF (SELECTED_FRAME ())->flush_display_optional (SELECTED_FRAME ());
11469 UNBLOCK_INPUT;
11470 }
11471 }
11472
11473 #endif /* HAVE_WINDOW_SYSTEM */
11474
11475 \f
11476 /***********************************************************************
11477 Tool-bars
11478 ***********************************************************************/
11479
11480 #ifdef HAVE_WINDOW_SYSTEM
11481
11482 /* Where the mouse was last time we reported a mouse event. */
11483
11484 FRAME_PTR last_mouse_frame;
11485
11486 /* Tool-bar item index of the item on which a mouse button was pressed
11487 or -1. */
11488
11489 int last_tool_bar_item;
11490
11491
11492 static Lisp_Object
11493 update_tool_bar_unwind (Lisp_Object frame)
11494 {
11495 selected_frame = frame;
11496 return Qnil;
11497 }
11498
11499 /* Update the tool-bar item list for frame F. This has to be done
11500 before we start to fill in any display lines. Called from
11501 prepare_menu_bars. If SAVE_MATCH_DATA is non-zero, we must save
11502 and restore it here. */
11503
11504 static void
11505 update_tool_bar (struct frame *f, int save_match_data)
11506 {
11507 #if defined (USE_GTK) || defined (HAVE_NS)
11508 int do_update = FRAME_EXTERNAL_TOOL_BAR (f);
11509 #else
11510 int do_update = WINDOWP (f->tool_bar_window)
11511 && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)) > 0;
11512 #endif
11513
11514 if (do_update)
11515 {
11516 Lisp_Object window;
11517 struct window *w;
11518
11519 window = FRAME_SELECTED_WINDOW (f);
11520 w = XWINDOW (window);
11521
11522 /* If the user has switched buffers or windows, we need to
11523 recompute to reflect the new bindings. But we'll
11524 recompute when update_mode_lines is set too; that means
11525 that people can use force-mode-line-update to request
11526 that the menu bar be recomputed. The adverse effect on
11527 the rest of the redisplay algorithm is about the same as
11528 windows_or_buffers_changed anyway. */
11529 if (windows_or_buffers_changed
11530 || w->update_mode_line
11531 || update_mode_lines
11532 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
11533 < BUF_MODIFF (XBUFFER (w->buffer)))
11534 != w->last_had_star)
11535 || ((!NILP (Vtransient_mark_mode)
11536 && !NILP (BVAR (XBUFFER (w->buffer), mark_active)))
11537 != !NILP (w->region_showing)))
11538 {
11539 struct buffer *prev = current_buffer;
11540 ptrdiff_t count = SPECPDL_INDEX ();
11541 Lisp_Object frame, new_tool_bar;
11542 int new_n_tool_bar;
11543 struct gcpro gcpro1;
11544
11545 /* Set current_buffer to the buffer of the selected
11546 window of the frame, so that we get the right local
11547 keymaps. */
11548 set_buffer_internal_1 (XBUFFER (w->buffer));
11549
11550 /* Save match data, if we must. */
11551 if (save_match_data)
11552 record_unwind_save_match_data ();
11553
11554 /* Make sure that we don't accidentally use bogus keymaps. */
11555 if (NILP (Voverriding_local_map_menu_flag))
11556 {
11557 specbind (Qoverriding_terminal_local_map, Qnil);
11558 specbind (Qoverriding_local_map, Qnil);
11559 }
11560
11561 GCPRO1 (new_tool_bar);
11562
11563 /* We must temporarily set the selected frame to this frame
11564 before calling tool_bar_items, because the calculation of
11565 the tool-bar keymap uses the selected frame (see
11566 `tool-bar-make-keymap' in tool-bar.el). */
11567 record_unwind_protect (update_tool_bar_unwind, selected_frame);
11568 XSETFRAME (frame, f);
11569 selected_frame = frame;
11570
11571 /* Build desired tool-bar items from keymaps. */
11572 new_tool_bar
11573 = tool_bar_items (Fcopy_sequence (f->tool_bar_items),
11574 &new_n_tool_bar);
11575
11576 /* Redisplay the tool-bar if we changed it. */
11577 if (new_n_tool_bar != f->n_tool_bar_items
11578 || NILP (Fequal (new_tool_bar, f->tool_bar_items)))
11579 {
11580 /* Redisplay that happens asynchronously due to an expose event
11581 may access f->tool_bar_items. Make sure we update both
11582 variables within BLOCK_INPUT so no such event interrupts. */
11583 BLOCK_INPUT;
11584 fset_tool_bar_items (f, new_tool_bar);
11585 f->n_tool_bar_items = new_n_tool_bar;
11586 w->update_mode_line = 1;
11587 UNBLOCK_INPUT;
11588 }
11589
11590 UNGCPRO;
11591
11592 unbind_to (count, Qnil);
11593 set_buffer_internal_1 (prev);
11594 }
11595 }
11596 }
11597
11598
11599 /* Set F->desired_tool_bar_string to a Lisp string representing frame
11600 F's desired tool-bar contents. F->tool_bar_items must have
11601 been set up previously by calling prepare_menu_bars. */
11602
11603 static void
11604 build_desired_tool_bar_string (struct frame *f)
11605 {
11606 int i, size, size_needed;
11607 struct gcpro gcpro1, gcpro2, gcpro3;
11608 Lisp_Object image, plist, props;
11609
11610 image = plist = props = Qnil;
11611 GCPRO3 (image, plist, props);
11612
11613 /* Prepare F->desired_tool_bar_string. If we can reuse it, do so.
11614 Otherwise, make a new string. */
11615
11616 /* The size of the string we might be able to reuse. */
11617 size = (STRINGP (f->desired_tool_bar_string)
11618 ? SCHARS (f->desired_tool_bar_string)
11619 : 0);
11620
11621 /* We need one space in the string for each image. */
11622 size_needed = f->n_tool_bar_items;
11623
11624 /* Reuse f->desired_tool_bar_string, if possible. */
11625 if (size < size_needed || NILP (f->desired_tool_bar_string))
11626 fset_desired_tool_bar_string
11627 (f, Fmake_string (make_number (size_needed), make_number (' ')));
11628 else
11629 {
11630 props = list4 (Qdisplay, Qnil, Qmenu_item, Qnil);
11631 Fremove_text_properties (make_number (0), make_number (size),
11632 props, f->desired_tool_bar_string);
11633 }
11634
11635 /* Put a `display' property on the string for the images to display,
11636 put a `menu_item' property on tool-bar items with a value that
11637 is the index of the item in F's tool-bar item vector. */
11638 for (i = 0; i < f->n_tool_bar_items; ++i)
11639 {
11640 #define PROP(IDX) \
11641 AREF (f->tool_bar_items, i * TOOL_BAR_ITEM_NSLOTS + (IDX))
11642
11643 int enabled_p = !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P));
11644 int selected_p = !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P));
11645 int hmargin, vmargin, relief, idx, end;
11646
11647 /* If image is a vector, choose the image according to the
11648 button state. */
11649 image = PROP (TOOL_BAR_ITEM_IMAGES);
11650 if (VECTORP (image))
11651 {
11652 if (enabled_p)
11653 idx = (selected_p
11654 ? TOOL_BAR_IMAGE_ENABLED_SELECTED
11655 : TOOL_BAR_IMAGE_ENABLED_DESELECTED);
11656 else
11657 idx = (selected_p
11658 ? TOOL_BAR_IMAGE_DISABLED_SELECTED
11659 : TOOL_BAR_IMAGE_DISABLED_DESELECTED);
11660
11661 eassert (ASIZE (image) >= idx);
11662 image = AREF (image, idx);
11663 }
11664 else
11665 idx = -1;
11666
11667 /* Ignore invalid image specifications. */
11668 if (!valid_image_p (image))
11669 continue;
11670
11671 /* Display the tool-bar button pressed, or depressed. */
11672 plist = Fcopy_sequence (XCDR (image));
11673
11674 /* Compute margin and relief to draw. */
11675 relief = (tool_bar_button_relief >= 0
11676 ? tool_bar_button_relief
11677 : DEFAULT_TOOL_BAR_BUTTON_RELIEF);
11678 hmargin = vmargin = relief;
11679
11680 if (RANGED_INTEGERP (1, Vtool_bar_button_margin,
11681 INT_MAX - max (hmargin, vmargin)))
11682 {
11683 hmargin += XFASTINT (Vtool_bar_button_margin);
11684 vmargin += XFASTINT (Vtool_bar_button_margin);
11685 }
11686 else if (CONSP (Vtool_bar_button_margin))
11687 {
11688 if (RANGED_INTEGERP (1, XCAR (Vtool_bar_button_margin),
11689 INT_MAX - hmargin))
11690 hmargin += XFASTINT (XCAR (Vtool_bar_button_margin));
11691
11692 if (RANGED_INTEGERP (1, XCDR (Vtool_bar_button_margin),
11693 INT_MAX - vmargin))
11694 vmargin += XFASTINT (XCDR (Vtool_bar_button_margin));
11695 }
11696
11697 if (auto_raise_tool_bar_buttons_p)
11698 {
11699 /* Add a `:relief' property to the image spec if the item is
11700 selected. */
11701 if (selected_p)
11702 {
11703 plist = Fplist_put (plist, QCrelief, make_number (-relief));
11704 hmargin -= relief;
11705 vmargin -= relief;
11706 }
11707 }
11708 else
11709 {
11710 /* If image is selected, display it pressed, i.e. with a
11711 negative relief. If it's not selected, display it with a
11712 raised relief. */
11713 plist = Fplist_put (plist, QCrelief,
11714 (selected_p
11715 ? make_number (-relief)
11716 : make_number (relief)));
11717 hmargin -= relief;
11718 vmargin -= relief;
11719 }
11720
11721 /* Put a margin around the image. */
11722 if (hmargin || vmargin)
11723 {
11724 if (hmargin == vmargin)
11725 plist = Fplist_put (plist, QCmargin, make_number (hmargin));
11726 else
11727 plist = Fplist_put (plist, QCmargin,
11728 Fcons (make_number (hmargin),
11729 make_number (vmargin)));
11730 }
11731
11732 /* If button is not enabled, and we don't have special images
11733 for the disabled state, make the image appear disabled by
11734 applying an appropriate algorithm to it. */
11735 if (!enabled_p && idx < 0)
11736 plist = Fplist_put (plist, QCconversion, Qdisabled);
11737
11738 /* Put a `display' text property on the string for the image to
11739 display. Put a `menu-item' property on the string that gives
11740 the start of this item's properties in the tool-bar items
11741 vector. */
11742 image = Fcons (Qimage, plist);
11743 props = list4 (Qdisplay, image,
11744 Qmenu_item, make_number (i * TOOL_BAR_ITEM_NSLOTS));
11745
11746 /* Let the last image hide all remaining spaces in the tool bar
11747 string. The string can be longer than needed when we reuse a
11748 previous string. */
11749 if (i + 1 == f->n_tool_bar_items)
11750 end = SCHARS (f->desired_tool_bar_string);
11751 else
11752 end = i + 1;
11753 Fadd_text_properties (make_number (i), make_number (end),
11754 props, f->desired_tool_bar_string);
11755 #undef PROP
11756 }
11757
11758 UNGCPRO;
11759 }
11760
11761
11762 /* Display one line of the tool-bar of frame IT->f.
11763
11764 HEIGHT specifies the desired height of the tool-bar line.
11765 If the actual height of the glyph row is less than HEIGHT, the
11766 row's height is increased to HEIGHT, and the icons are centered
11767 vertically in the new height.
11768
11769 If HEIGHT is -1, we are counting needed tool-bar lines, so don't
11770 count a final empty row in case the tool-bar width exactly matches
11771 the window width.
11772 */
11773
11774 static void
11775 display_tool_bar_line (struct it *it, int height)
11776 {
11777 struct glyph_row *row = it->glyph_row;
11778 int max_x = it->last_visible_x;
11779 struct glyph *last;
11780
11781 prepare_desired_row (row);
11782 row->y = it->current_y;
11783
11784 /* Note that this isn't made use of if the face hasn't a box,
11785 so there's no need to check the face here. */
11786 it->start_of_box_run_p = 1;
11787
11788 while (it->current_x < max_x)
11789 {
11790 int x, n_glyphs_before, i, nglyphs;
11791 struct it it_before;
11792
11793 /* Get the next display element. */
11794 if (!get_next_display_element (it))
11795 {
11796 /* Don't count empty row if we are counting needed tool-bar lines. */
11797 if (height < 0 && !it->hpos)
11798 return;
11799 break;
11800 }
11801
11802 /* Produce glyphs. */
11803 n_glyphs_before = row->used[TEXT_AREA];
11804 it_before = *it;
11805
11806 PRODUCE_GLYPHS (it);
11807
11808 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
11809 i = 0;
11810 x = it_before.current_x;
11811 while (i < nglyphs)
11812 {
11813 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
11814
11815 if (x + glyph->pixel_width > max_x)
11816 {
11817 /* Glyph doesn't fit on line. Backtrack. */
11818 row->used[TEXT_AREA] = n_glyphs_before;
11819 *it = it_before;
11820 /* If this is the only glyph on this line, it will never fit on the
11821 tool-bar, so skip it. But ensure there is at least one glyph,
11822 so we don't accidentally disable the tool-bar. */
11823 if (n_glyphs_before == 0
11824 && (it->vpos > 0 || IT_STRING_CHARPOS (*it) < it->end_charpos-1))
11825 break;
11826 goto out;
11827 }
11828
11829 ++it->hpos;
11830 x += glyph->pixel_width;
11831 ++i;
11832 }
11833
11834 /* Stop at line end. */
11835 if (ITERATOR_AT_END_OF_LINE_P (it))
11836 break;
11837
11838 set_iterator_to_next (it, 1);
11839 }
11840
11841 out:;
11842
11843 row->displays_text_p = row->used[TEXT_AREA] != 0;
11844
11845 /* Use default face for the border below the tool bar.
11846
11847 FIXME: When auto-resize-tool-bars is grow-only, there is
11848 no additional border below the possibly empty tool-bar lines.
11849 So to make the extra empty lines look "normal", we have to
11850 use the tool-bar face for the border too. */
11851 if (!row->displays_text_p && !EQ (Vauto_resize_tool_bars, Qgrow_only))
11852 it->face_id = DEFAULT_FACE_ID;
11853
11854 extend_face_to_end_of_line (it);
11855 last = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
11856 last->right_box_line_p = 1;
11857 if (last == row->glyphs[TEXT_AREA])
11858 last->left_box_line_p = 1;
11859
11860 /* Make line the desired height and center it vertically. */
11861 if ((height -= it->max_ascent + it->max_descent) > 0)
11862 {
11863 /* Don't add more than one line height. */
11864 height %= FRAME_LINE_HEIGHT (it->f);
11865 it->max_ascent += height / 2;
11866 it->max_descent += (height + 1) / 2;
11867 }
11868
11869 compute_line_metrics (it);
11870
11871 /* If line is empty, make it occupy the rest of the tool-bar. */
11872 if (!row->displays_text_p)
11873 {
11874 row->height = row->phys_height = it->last_visible_y - row->y;
11875 row->visible_height = row->height;
11876 row->ascent = row->phys_ascent = 0;
11877 row->extra_line_spacing = 0;
11878 }
11879
11880 row->full_width_p = 1;
11881 row->continued_p = 0;
11882 row->truncated_on_left_p = 0;
11883 row->truncated_on_right_p = 0;
11884
11885 it->current_x = it->hpos = 0;
11886 it->current_y += row->height;
11887 ++it->vpos;
11888 ++it->glyph_row;
11889 }
11890
11891
11892 /* Max tool-bar height. */
11893
11894 #define MAX_FRAME_TOOL_BAR_HEIGHT(f) \
11895 ((FRAME_LINE_HEIGHT (f) * FRAME_LINES (f)))
11896
11897 /* Value is the number of screen lines needed to make all tool-bar
11898 items of frame F visible. The number of actual rows needed is
11899 returned in *N_ROWS if non-NULL. */
11900
11901 static int
11902 tool_bar_lines_needed (struct frame *f, int *n_rows)
11903 {
11904 struct window *w = XWINDOW (f->tool_bar_window);
11905 struct it it;
11906 /* tool_bar_lines_needed is called from redisplay_tool_bar after building
11907 the desired matrix, so use (unused) mode-line row as temporary row to
11908 avoid destroying the first tool-bar row. */
11909 struct glyph_row *temp_row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
11910
11911 /* Initialize an iterator for iteration over
11912 F->desired_tool_bar_string in the tool-bar window of frame F. */
11913 init_iterator (&it, w, -1, -1, temp_row, TOOL_BAR_FACE_ID);
11914 it.first_visible_x = 0;
11915 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
11916 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
11917 it.paragraph_embedding = L2R;
11918
11919 while (!ITERATOR_AT_END_P (&it))
11920 {
11921 clear_glyph_row (temp_row);
11922 it.glyph_row = temp_row;
11923 display_tool_bar_line (&it, -1);
11924 }
11925 clear_glyph_row (temp_row);
11926
11927 /* f->n_tool_bar_rows == 0 means "unknown"; -1 means no tool-bar. */
11928 if (n_rows)
11929 *n_rows = it.vpos > 0 ? it.vpos : -1;
11930
11931 return (it.current_y + FRAME_LINE_HEIGHT (f) - 1) / FRAME_LINE_HEIGHT (f);
11932 }
11933
11934
11935 DEFUN ("tool-bar-lines-needed", Ftool_bar_lines_needed, Stool_bar_lines_needed,
11936 0, 1, 0,
11937 doc: /* Return the number of lines occupied by the tool bar of FRAME. */)
11938 (Lisp_Object frame)
11939 {
11940 struct frame *f;
11941 struct window *w;
11942 int nlines = 0;
11943
11944 if (NILP (frame))
11945 frame = selected_frame;
11946 else
11947 CHECK_FRAME (frame);
11948 f = XFRAME (frame);
11949
11950 if (WINDOWP (f->tool_bar_window)
11951 && (w = XWINDOW (f->tool_bar_window),
11952 WINDOW_TOTAL_LINES (w) > 0))
11953 {
11954 update_tool_bar (f, 1);
11955 if (f->n_tool_bar_items)
11956 {
11957 build_desired_tool_bar_string (f);
11958 nlines = tool_bar_lines_needed (f, NULL);
11959 }
11960 }
11961
11962 return make_number (nlines);
11963 }
11964
11965
11966 /* Display the tool-bar of frame F. Value is non-zero if tool-bar's
11967 height should be changed. */
11968
11969 static int
11970 redisplay_tool_bar (struct frame *f)
11971 {
11972 struct window *w;
11973 struct it it;
11974 struct glyph_row *row;
11975
11976 #if defined (USE_GTK) || defined (HAVE_NS)
11977 if (FRAME_EXTERNAL_TOOL_BAR (f))
11978 update_frame_tool_bar (f);
11979 return 0;
11980 #endif
11981
11982 /* If frame hasn't a tool-bar window or if it is zero-height, don't
11983 do anything. This means you must start with tool-bar-lines
11984 non-zero to get the auto-sizing effect. Or in other words, you
11985 can turn off tool-bars by specifying tool-bar-lines zero. */
11986 if (!WINDOWP (f->tool_bar_window)
11987 || (w = XWINDOW (f->tool_bar_window),
11988 WINDOW_TOTAL_LINES (w) == 0))
11989 return 0;
11990
11991 /* Set up an iterator for the tool-bar window. */
11992 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
11993 it.first_visible_x = 0;
11994 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
11995 row = it.glyph_row;
11996
11997 /* Build a string that represents the contents of the tool-bar. */
11998 build_desired_tool_bar_string (f);
11999 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
12000 /* FIXME: This should be controlled by a user option. But it
12001 doesn't make sense to have an R2L tool bar if the menu bar cannot
12002 be drawn also R2L, and making the menu bar R2L is tricky due
12003 toolkit-specific code that implements it. If an R2L tool bar is
12004 ever supported, display_tool_bar_line should also be augmented to
12005 call unproduce_glyphs like display_line and display_string
12006 do. */
12007 it.paragraph_embedding = L2R;
12008
12009 if (f->n_tool_bar_rows == 0)
12010 {
12011 int nlines;
12012
12013 if ((nlines = tool_bar_lines_needed (f, &f->n_tool_bar_rows),
12014 nlines != WINDOW_TOTAL_LINES (w)))
12015 {
12016 Lisp_Object frame;
12017 int old_height = WINDOW_TOTAL_LINES (w);
12018
12019 XSETFRAME (frame, f);
12020 Fmodify_frame_parameters (frame,
12021 Fcons (Fcons (Qtool_bar_lines,
12022 make_number (nlines)),
12023 Qnil));
12024 if (WINDOW_TOTAL_LINES (w) != old_height)
12025 {
12026 clear_glyph_matrix (w->desired_matrix);
12027 fonts_changed_p = 1;
12028 return 1;
12029 }
12030 }
12031 }
12032
12033 /* Display as many lines as needed to display all tool-bar items. */
12034
12035 if (f->n_tool_bar_rows > 0)
12036 {
12037 int border, rows, height, extra;
12038
12039 if (TYPE_RANGED_INTEGERP (int, Vtool_bar_border))
12040 border = XINT (Vtool_bar_border);
12041 else if (EQ (Vtool_bar_border, Qinternal_border_width))
12042 border = FRAME_INTERNAL_BORDER_WIDTH (f);
12043 else if (EQ (Vtool_bar_border, Qborder_width))
12044 border = f->border_width;
12045 else
12046 border = 0;
12047 if (border < 0)
12048 border = 0;
12049
12050 rows = f->n_tool_bar_rows;
12051 height = max (1, (it.last_visible_y - border) / rows);
12052 extra = it.last_visible_y - border - height * rows;
12053
12054 while (it.current_y < it.last_visible_y)
12055 {
12056 int h = 0;
12057 if (extra > 0 && rows-- > 0)
12058 {
12059 h = (extra + rows - 1) / rows;
12060 extra -= h;
12061 }
12062 display_tool_bar_line (&it, height + h);
12063 }
12064 }
12065 else
12066 {
12067 while (it.current_y < it.last_visible_y)
12068 display_tool_bar_line (&it, 0);
12069 }
12070
12071 /* It doesn't make much sense to try scrolling in the tool-bar
12072 window, so don't do it. */
12073 w->desired_matrix->no_scrolling_p = 1;
12074 w->must_be_updated_p = 1;
12075
12076 if (!NILP (Vauto_resize_tool_bars))
12077 {
12078 int max_tool_bar_height = MAX_FRAME_TOOL_BAR_HEIGHT (f);
12079 int change_height_p = 0;
12080
12081 /* If we couldn't display everything, change the tool-bar's
12082 height if there is room for more. */
12083 if (IT_STRING_CHARPOS (it) < it.end_charpos
12084 && it.current_y < max_tool_bar_height)
12085 change_height_p = 1;
12086
12087 row = it.glyph_row - 1;
12088
12089 /* If there are blank lines at the end, except for a partially
12090 visible blank line at the end that is smaller than
12091 FRAME_LINE_HEIGHT, change the tool-bar's height. */
12092 if (!row->displays_text_p
12093 && row->height >= FRAME_LINE_HEIGHT (f))
12094 change_height_p = 1;
12095
12096 /* If row displays tool-bar items, but is partially visible,
12097 change the tool-bar's height. */
12098 if (row->displays_text_p
12099 && MATRIX_ROW_BOTTOM_Y (row) > it.last_visible_y
12100 && MATRIX_ROW_BOTTOM_Y (row) < max_tool_bar_height)
12101 change_height_p = 1;
12102
12103 /* Resize windows as needed by changing the `tool-bar-lines'
12104 frame parameter. */
12105 if (change_height_p)
12106 {
12107 Lisp_Object frame;
12108 int old_height = WINDOW_TOTAL_LINES (w);
12109 int nrows;
12110 int nlines = tool_bar_lines_needed (f, &nrows);
12111
12112 change_height_p = ((EQ (Vauto_resize_tool_bars, Qgrow_only)
12113 && !f->minimize_tool_bar_window_p)
12114 ? (nlines > old_height)
12115 : (nlines != old_height));
12116 f->minimize_tool_bar_window_p = 0;
12117
12118 if (change_height_p)
12119 {
12120 XSETFRAME (frame, f);
12121 Fmodify_frame_parameters (frame,
12122 Fcons (Fcons (Qtool_bar_lines,
12123 make_number (nlines)),
12124 Qnil));
12125 if (WINDOW_TOTAL_LINES (w) != old_height)
12126 {
12127 clear_glyph_matrix (w->desired_matrix);
12128 f->n_tool_bar_rows = nrows;
12129 fonts_changed_p = 1;
12130 return 1;
12131 }
12132 }
12133 }
12134 }
12135
12136 f->minimize_tool_bar_window_p = 0;
12137 return 0;
12138 }
12139
12140
12141 /* Get information about the tool-bar item which is displayed in GLYPH
12142 on frame F. Return in *PROP_IDX the index where tool-bar item
12143 properties start in F->tool_bar_items. Value is zero if
12144 GLYPH doesn't display a tool-bar item. */
12145
12146 static int
12147 tool_bar_item_info (struct frame *f, struct glyph *glyph, int *prop_idx)
12148 {
12149 Lisp_Object prop;
12150 int success_p;
12151 int charpos;
12152
12153 /* This function can be called asynchronously, which means we must
12154 exclude any possibility that Fget_text_property signals an
12155 error. */
12156 charpos = min (SCHARS (f->current_tool_bar_string), glyph->charpos);
12157 charpos = max (0, charpos);
12158
12159 /* Get the text property `menu-item' at pos. The value of that
12160 property is the start index of this item's properties in
12161 F->tool_bar_items. */
12162 prop = Fget_text_property (make_number (charpos),
12163 Qmenu_item, f->current_tool_bar_string);
12164 if (INTEGERP (prop))
12165 {
12166 *prop_idx = XINT (prop);
12167 success_p = 1;
12168 }
12169 else
12170 success_p = 0;
12171
12172 return success_p;
12173 }
12174
12175 \f
12176 /* Get information about the tool-bar item at position X/Y on frame F.
12177 Return in *GLYPH a pointer to the glyph of the tool-bar item in
12178 the current matrix of the tool-bar window of F, or NULL if not
12179 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
12180 item in F->tool_bar_items. Value is
12181
12182 -1 if X/Y is not on a tool-bar item
12183 0 if X/Y is on the same item that was highlighted before.
12184 1 otherwise. */
12185
12186 static int
12187 get_tool_bar_item (struct frame *f, int x, int y, struct glyph **glyph,
12188 int *hpos, int *vpos, int *prop_idx)
12189 {
12190 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
12191 struct window *w = XWINDOW (f->tool_bar_window);
12192 int area;
12193
12194 /* Find the glyph under X/Y. */
12195 *glyph = x_y_to_hpos_vpos (w, x, y, hpos, vpos, 0, 0, &area);
12196 if (*glyph == NULL)
12197 return -1;
12198
12199 /* Get the start of this tool-bar item's properties in
12200 f->tool_bar_items. */
12201 if (!tool_bar_item_info (f, *glyph, prop_idx))
12202 return -1;
12203
12204 /* Is mouse on the highlighted item? */
12205 if (EQ (f->tool_bar_window, hlinfo->mouse_face_window)
12206 && *vpos >= hlinfo->mouse_face_beg_row
12207 && *vpos <= hlinfo->mouse_face_end_row
12208 && (*vpos > hlinfo->mouse_face_beg_row
12209 || *hpos >= hlinfo->mouse_face_beg_col)
12210 && (*vpos < hlinfo->mouse_face_end_row
12211 || *hpos < hlinfo->mouse_face_end_col
12212 || hlinfo->mouse_face_past_end))
12213 return 0;
12214
12215 return 1;
12216 }
12217
12218
12219 /* EXPORT:
12220 Handle mouse button event on the tool-bar of frame F, at
12221 frame-relative coordinates X/Y. DOWN_P is 1 for a button press,
12222 0 for button release. MODIFIERS is event modifiers for button
12223 release. */
12224
12225 void
12226 handle_tool_bar_click (struct frame *f, int x, int y, int down_p,
12227 int modifiers)
12228 {
12229 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
12230 struct window *w = XWINDOW (f->tool_bar_window);
12231 int hpos, vpos, prop_idx;
12232 struct glyph *glyph;
12233 Lisp_Object enabled_p;
12234
12235 /* If not on the highlighted tool-bar item, return. */
12236 frame_to_window_pixel_xy (w, &x, &y);
12237 if (get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx) != 0)
12238 return;
12239
12240 /* If item is disabled, do nothing. */
12241 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
12242 if (NILP (enabled_p))
12243 return;
12244
12245 if (down_p)
12246 {
12247 /* Show item in pressed state. */
12248 show_mouse_face (hlinfo, DRAW_IMAGE_SUNKEN);
12249 hlinfo->mouse_face_image_state = DRAW_IMAGE_SUNKEN;
12250 last_tool_bar_item = prop_idx;
12251 }
12252 else
12253 {
12254 Lisp_Object key, frame;
12255 struct input_event event;
12256 EVENT_INIT (event);
12257
12258 /* Show item in released state. */
12259 show_mouse_face (hlinfo, DRAW_IMAGE_RAISED);
12260 hlinfo->mouse_face_image_state = DRAW_IMAGE_RAISED;
12261
12262 key = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_KEY);
12263
12264 XSETFRAME (frame, f);
12265 event.kind = TOOL_BAR_EVENT;
12266 event.frame_or_window = frame;
12267 event.arg = frame;
12268 kbd_buffer_store_event (&event);
12269
12270 event.kind = TOOL_BAR_EVENT;
12271 event.frame_or_window = frame;
12272 event.arg = key;
12273 event.modifiers = modifiers;
12274 kbd_buffer_store_event (&event);
12275 last_tool_bar_item = -1;
12276 }
12277 }
12278
12279
12280 /* Possibly highlight a tool-bar item on frame F when mouse moves to
12281 tool-bar window-relative coordinates X/Y. Called from
12282 note_mouse_highlight. */
12283
12284 static void
12285 note_tool_bar_highlight (struct frame *f, int x, int y)
12286 {
12287 Lisp_Object window = f->tool_bar_window;
12288 struct window *w = XWINDOW (window);
12289 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
12290 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
12291 int hpos, vpos;
12292 struct glyph *glyph;
12293 struct glyph_row *row;
12294 int i;
12295 Lisp_Object enabled_p;
12296 int prop_idx;
12297 enum draw_glyphs_face draw = DRAW_IMAGE_RAISED;
12298 int mouse_down_p, rc;
12299
12300 /* Function note_mouse_highlight is called with negative X/Y
12301 values when mouse moves outside of the frame. */
12302 if (x <= 0 || y <= 0)
12303 {
12304 clear_mouse_face (hlinfo);
12305 return;
12306 }
12307
12308 rc = get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx);
12309 if (rc < 0)
12310 {
12311 /* Not on tool-bar item. */
12312 clear_mouse_face (hlinfo);
12313 return;
12314 }
12315 else if (rc == 0)
12316 /* On same tool-bar item as before. */
12317 goto set_help_echo;
12318
12319 clear_mouse_face (hlinfo);
12320
12321 /* Mouse is down, but on different tool-bar item? */
12322 mouse_down_p = (dpyinfo->grabbed
12323 && f == last_mouse_frame
12324 && FRAME_LIVE_P (f));
12325 if (mouse_down_p
12326 && last_tool_bar_item != prop_idx)
12327 return;
12328
12329 hlinfo->mouse_face_image_state = DRAW_NORMAL_TEXT;
12330 draw = mouse_down_p ? DRAW_IMAGE_SUNKEN : DRAW_IMAGE_RAISED;
12331
12332 /* If tool-bar item is not enabled, don't highlight it. */
12333 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
12334 if (!NILP (enabled_p))
12335 {
12336 /* Compute the x-position of the glyph. In front and past the
12337 image is a space. We include this in the highlighted area. */
12338 row = MATRIX_ROW (w->current_matrix, vpos);
12339 for (i = x = 0; i < hpos; ++i)
12340 x += row->glyphs[TEXT_AREA][i].pixel_width;
12341
12342 /* Record this as the current active region. */
12343 hlinfo->mouse_face_beg_col = hpos;
12344 hlinfo->mouse_face_beg_row = vpos;
12345 hlinfo->mouse_face_beg_x = x;
12346 hlinfo->mouse_face_beg_y = row->y;
12347 hlinfo->mouse_face_past_end = 0;
12348
12349 hlinfo->mouse_face_end_col = hpos + 1;
12350 hlinfo->mouse_face_end_row = vpos;
12351 hlinfo->mouse_face_end_x = x + glyph->pixel_width;
12352 hlinfo->mouse_face_end_y = row->y;
12353 hlinfo->mouse_face_window = window;
12354 hlinfo->mouse_face_face_id = TOOL_BAR_FACE_ID;
12355
12356 /* Display it as active. */
12357 show_mouse_face (hlinfo, draw);
12358 hlinfo->mouse_face_image_state = draw;
12359 }
12360
12361 set_help_echo:
12362
12363 /* Set help_echo_string to a help string to display for this tool-bar item.
12364 XTread_socket does the rest. */
12365 help_echo_object = help_echo_window = Qnil;
12366 help_echo_pos = -1;
12367 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_HELP);
12368 if (NILP (help_echo_string))
12369 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_CAPTION);
12370 }
12371
12372 #endif /* HAVE_WINDOW_SYSTEM */
12373
12374
12375 \f
12376 /************************************************************************
12377 Horizontal scrolling
12378 ************************************************************************/
12379
12380 static int hscroll_window_tree (Lisp_Object);
12381 static int hscroll_windows (Lisp_Object);
12382
12383 /* For all leaf windows in the window tree rooted at WINDOW, set their
12384 hscroll value so that PT is (i) visible in the window, and (ii) so
12385 that it is not within a certain margin at the window's left and
12386 right border. Value is non-zero if any window's hscroll has been
12387 changed. */
12388
12389 static int
12390 hscroll_window_tree (Lisp_Object window)
12391 {
12392 int hscrolled_p = 0;
12393 int hscroll_relative_p = FLOATP (Vhscroll_step);
12394 int hscroll_step_abs = 0;
12395 double hscroll_step_rel = 0;
12396
12397 if (hscroll_relative_p)
12398 {
12399 hscroll_step_rel = XFLOAT_DATA (Vhscroll_step);
12400 if (hscroll_step_rel < 0)
12401 {
12402 hscroll_relative_p = 0;
12403 hscroll_step_abs = 0;
12404 }
12405 }
12406 else if (TYPE_RANGED_INTEGERP (int, Vhscroll_step))
12407 {
12408 hscroll_step_abs = XINT (Vhscroll_step);
12409 if (hscroll_step_abs < 0)
12410 hscroll_step_abs = 0;
12411 }
12412 else
12413 hscroll_step_abs = 0;
12414
12415 while (WINDOWP (window))
12416 {
12417 struct window *w = XWINDOW (window);
12418
12419 if (WINDOWP (w->hchild))
12420 hscrolled_p |= hscroll_window_tree (w->hchild);
12421 else if (WINDOWP (w->vchild))
12422 hscrolled_p |= hscroll_window_tree (w->vchild);
12423 else if (w->cursor.vpos >= 0)
12424 {
12425 int h_margin;
12426 int text_area_width;
12427 struct glyph_row *current_cursor_row
12428 = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
12429 struct glyph_row *desired_cursor_row
12430 = MATRIX_ROW (w->desired_matrix, w->cursor.vpos);
12431 struct glyph_row *cursor_row
12432 = (desired_cursor_row->enabled_p
12433 ? desired_cursor_row
12434 : current_cursor_row);
12435 int row_r2l_p = cursor_row->reversed_p;
12436
12437 text_area_width = window_box_width (w, TEXT_AREA);
12438
12439 /* Scroll when cursor is inside this scroll margin. */
12440 h_margin = hscroll_margin * WINDOW_FRAME_COLUMN_WIDTH (w);
12441
12442 if (!NILP (Fbuffer_local_value (Qauto_hscroll_mode, w->buffer))
12443 /* For left-to-right rows, hscroll when cursor is either
12444 (i) inside the right hscroll margin, or (ii) if it is
12445 inside the left margin and the window is already
12446 hscrolled. */
12447 && ((!row_r2l_p
12448 && ((w->hscroll
12449 && w->cursor.x <= h_margin)
12450 || (cursor_row->enabled_p
12451 && cursor_row->truncated_on_right_p
12452 && (w->cursor.x >= text_area_width - h_margin))))
12453 /* For right-to-left rows, the logic is similar,
12454 except that rules for scrolling to left and right
12455 are reversed. E.g., if cursor.x <= h_margin, we
12456 need to hscroll "to the right" unconditionally,
12457 and that will scroll the screen to the left so as
12458 to reveal the next portion of the row. */
12459 || (row_r2l_p
12460 && ((cursor_row->enabled_p
12461 /* FIXME: It is confusing to set the
12462 truncated_on_right_p flag when R2L rows
12463 are actually truncated on the left. */
12464 && cursor_row->truncated_on_right_p
12465 && w->cursor.x <= h_margin)
12466 || (w->hscroll
12467 && (w->cursor.x >= text_area_width - h_margin))))))
12468 {
12469 struct it it;
12470 ptrdiff_t hscroll;
12471 struct buffer *saved_current_buffer;
12472 ptrdiff_t pt;
12473 int wanted_x;
12474
12475 /* Find point in a display of infinite width. */
12476 saved_current_buffer = current_buffer;
12477 current_buffer = XBUFFER (w->buffer);
12478
12479 if (w == XWINDOW (selected_window))
12480 pt = PT;
12481 else
12482 {
12483 pt = marker_position (w->pointm);
12484 pt = max (BEGV, pt);
12485 pt = min (ZV, pt);
12486 }
12487
12488 /* Move iterator to pt starting at cursor_row->start in
12489 a line with infinite width. */
12490 init_to_row_start (&it, w, cursor_row);
12491 it.last_visible_x = INFINITY;
12492 move_it_in_display_line_to (&it, pt, -1, MOVE_TO_POS);
12493 current_buffer = saved_current_buffer;
12494
12495 /* Position cursor in window. */
12496 if (!hscroll_relative_p && hscroll_step_abs == 0)
12497 hscroll = max (0, (it.current_x
12498 - (ITERATOR_AT_END_OF_LINE_P (&it)
12499 ? (text_area_width - 4 * FRAME_COLUMN_WIDTH (it.f))
12500 : (text_area_width / 2))))
12501 / FRAME_COLUMN_WIDTH (it.f);
12502 else if ((!row_r2l_p
12503 && w->cursor.x >= text_area_width - h_margin)
12504 || (row_r2l_p && w->cursor.x <= h_margin))
12505 {
12506 if (hscroll_relative_p)
12507 wanted_x = text_area_width * (1 - hscroll_step_rel)
12508 - h_margin;
12509 else
12510 wanted_x = text_area_width
12511 - hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
12512 - h_margin;
12513 hscroll
12514 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
12515 }
12516 else
12517 {
12518 if (hscroll_relative_p)
12519 wanted_x = text_area_width * hscroll_step_rel
12520 + h_margin;
12521 else
12522 wanted_x = hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
12523 + h_margin;
12524 hscroll
12525 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
12526 }
12527 hscroll = max (hscroll, w->min_hscroll);
12528
12529 /* Don't prevent redisplay optimizations if hscroll
12530 hasn't changed, as it will unnecessarily slow down
12531 redisplay. */
12532 if (w->hscroll != hscroll)
12533 {
12534 XBUFFER (w->buffer)->prevent_redisplay_optimizations_p = 1;
12535 w->hscroll = hscroll;
12536 hscrolled_p = 1;
12537 }
12538 }
12539 }
12540
12541 window = w->next;
12542 }
12543
12544 /* Value is non-zero if hscroll of any leaf window has been changed. */
12545 return hscrolled_p;
12546 }
12547
12548
12549 /* Set hscroll so that cursor is visible and not inside horizontal
12550 scroll margins for all windows in the tree rooted at WINDOW. See
12551 also hscroll_window_tree above. Value is non-zero if any window's
12552 hscroll has been changed. If it has, desired matrices on the frame
12553 of WINDOW are cleared. */
12554
12555 static int
12556 hscroll_windows (Lisp_Object window)
12557 {
12558 int hscrolled_p = hscroll_window_tree (window);
12559 if (hscrolled_p)
12560 clear_desired_matrices (XFRAME (WINDOW_FRAME (XWINDOW (window))));
12561 return hscrolled_p;
12562 }
12563
12564
12565 \f
12566 /************************************************************************
12567 Redisplay
12568 ************************************************************************/
12569
12570 /* Variables holding some state of redisplay if GLYPH_DEBUG is defined
12571 to a non-zero value. This is sometimes handy to have in a debugger
12572 session. */
12573
12574 #ifdef GLYPH_DEBUG
12575
12576 /* First and last unchanged row for try_window_id. */
12577
12578 static int debug_first_unchanged_at_end_vpos;
12579 static int debug_last_unchanged_at_beg_vpos;
12580
12581 /* Delta vpos and y. */
12582
12583 static int debug_dvpos, debug_dy;
12584
12585 /* Delta in characters and bytes for try_window_id. */
12586
12587 static ptrdiff_t debug_delta, debug_delta_bytes;
12588
12589 /* Values of window_end_pos and window_end_vpos at the end of
12590 try_window_id. */
12591
12592 static ptrdiff_t debug_end_vpos;
12593
12594 /* Append a string to W->desired_matrix->method. FMT is a printf
12595 format string. If trace_redisplay_p is non-zero also printf the
12596 resulting string to stderr. */
12597
12598 static void debug_method_add (struct window *, char const *, ...)
12599 ATTRIBUTE_FORMAT_PRINTF (2, 3);
12600
12601 static void
12602 debug_method_add (struct window *w, char const *fmt, ...)
12603 {
12604 char *method = w->desired_matrix->method;
12605 int len = strlen (method);
12606 int size = sizeof w->desired_matrix->method;
12607 int remaining = size - len - 1;
12608 va_list ap;
12609
12610 if (len && remaining)
12611 {
12612 method[len] = '|';
12613 --remaining, ++len;
12614 }
12615
12616 va_start (ap, fmt);
12617 vsnprintf (method + len, remaining + 1, fmt, ap);
12618 va_end (ap);
12619
12620 if (trace_redisplay_p)
12621 fprintf (stderr, "%p (%s): %s\n",
12622 w,
12623 ((BUFFERP (w->buffer)
12624 && STRINGP (BVAR (XBUFFER (w->buffer), name)))
12625 ? SSDATA (BVAR (XBUFFER (w->buffer), name))
12626 : "no buffer"),
12627 method + len);
12628 }
12629
12630 #endif /* GLYPH_DEBUG */
12631
12632
12633 /* Value is non-zero if all changes in window W, which displays
12634 current_buffer, are in the text between START and END. START is a
12635 buffer position, END is given as a distance from Z. Used in
12636 redisplay_internal for display optimization. */
12637
12638 static inline int
12639 text_outside_line_unchanged_p (struct window *w,
12640 ptrdiff_t start, ptrdiff_t end)
12641 {
12642 int unchanged_p = 1;
12643
12644 /* If text or overlays have changed, see where. */
12645 if (w->last_modified < MODIFF
12646 || w->last_overlay_modified < OVERLAY_MODIFF)
12647 {
12648 /* Gap in the line? */
12649 if (GPT < start || Z - GPT < end)
12650 unchanged_p = 0;
12651
12652 /* Changes start in front of the line, or end after it? */
12653 if (unchanged_p
12654 && (BEG_UNCHANGED < start - 1
12655 || END_UNCHANGED < end))
12656 unchanged_p = 0;
12657
12658 /* If selective display, can't optimize if changes start at the
12659 beginning of the line. */
12660 if (unchanged_p
12661 && INTEGERP (BVAR (current_buffer, selective_display))
12662 && XINT (BVAR (current_buffer, selective_display)) > 0
12663 && (BEG_UNCHANGED < start || GPT <= start))
12664 unchanged_p = 0;
12665
12666 /* If there are overlays at the start or end of the line, these
12667 may have overlay strings with newlines in them. A change at
12668 START, for instance, may actually concern the display of such
12669 overlay strings as well, and they are displayed on different
12670 lines. So, quickly rule out this case. (For the future, it
12671 might be desirable to implement something more telling than
12672 just BEG/END_UNCHANGED.) */
12673 if (unchanged_p)
12674 {
12675 if (BEG + BEG_UNCHANGED == start
12676 && overlay_touches_p (start))
12677 unchanged_p = 0;
12678 if (END_UNCHANGED == end
12679 && overlay_touches_p (Z - end))
12680 unchanged_p = 0;
12681 }
12682
12683 /* Under bidi reordering, adding or deleting a character in the
12684 beginning of a paragraph, before the first strong directional
12685 character, can change the base direction of the paragraph (unless
12686 the buffer specifies a fixed paragraph direction), which will
12687 require to redisplay the whole paragraph. It might be worthwhile
12688 to find the paragraph limits and widen the range of redisplayed
12689 lines to that, but for now just give up this optimization. */
12690 if (!NILP (BVAR (XBUFFER (w->buffer), bidi_display_reordering))
12691 && NILP (BVAR (XBUFFER (w->buffer), bidi_paragraph_direction)))
12692 unchanged_p = 0;
12693 }
12694
12695 return unchanged_p;
12696 }
12697
12698
12699 /* Do a frame update, taking possible shortcuts into account. This is
12700 the main external entry point for redisplay.
12701
12702 If the last redisplay displayed an echo area message and that message
12703 is no longer requested, we clear the echo area or bring back the
12704 mini-buffer if that is in use. */
12705
12706 void
12707 redisplay (void)
12708 {
12709 redisplay_internal ();
12710 }
12711
12712
12713 static Lisp_Object
12714 overlay_arrow_string_or_property (Lisp_Object var)
12715 {
12716 Lisp_Object val;
12717
12718 if (val = Fget (var, Qoverlay_arrow_string), STRINGP (val))
12719 return val;
12720
12721 return Voverlay_arrow_string;
12722 }
12723
12724 /* Return 1 if there are any overlay-arrows in current_buffer. */
12725 static int
12726 overlay_arrow_in_current_buffer_p (void)
12727 {
12728 Lisp_Object vlist;
12729
12730 for (vlist = Voverlay_arrow_variable_list;
12731 CONSP (vlist);
12732 vlist = XCDR (vlist))
12733 {
12734 Lisp_Object var = XCAR (vlist);
12735 Lisp_Object val;
12736
12737 if (!SYMBOLP (var))
12738 continue;
12739 val = find_symbol_value (var);
12740 if (MARKERP (val)
12741 && current_buffer == XMARKER (val)->buffer)
12742 return 1;
12743 }
12744 return 0;
12745 }
12746
12747
12748 /* Return 1 if any overlay_arrows have moved or overlay-arrow-string
12749 has changed. */
12750
12751 static int
12752 overlay_arrows_changed_p (void)
12753 {
12754 Lisp_Object vlist;
12755
12756 for (vlist = Voverlay_arrow_variable_list;
12757 CONSP (vlist);
12758 vlist = XCDR (vlist))
12759 {
12760 Lisp_Object var = XCAR (vlist);
12761 Lisp_Object val, pstr;
12762
12763 if (!SYMBOLP (var))
12764 continue;
12765 val = find_symbol_value (var);
12766 if (!MARKERP (val))
12767 continue;
12768 if (! EQ (COERCE_MARKER (val),
12769 Fget (var, Qlast_arrow_position))
12770 || ! (pstr = overlay_arrow_string_or_property (var),
12771 EQ (pstr, Fget (var, Qlast_arrow_string))))
12772 return 1;
12773 }
12774 return 0;
12775 }
12776
12777 /* Mark overlay arrows to be updated on next redisplay. */
12778
12779 static void
12780 update_overlay_arrows (int up_to_date)
12781 {
12782 Lisp_Object vlist;
12783
12784 for (vlist = Voverlay_arrow_variable_list;
12785 CONSP (vlist);
12786 vlist = XCDR (vlist))
12787 {
12788 Lisp_Object var = XCAR (vlist);
12789
12790 if (!SYMBOLP (var))
12791 continue;
12792
12793 if (up_to_date > 0)
12794 {
12795 Lisp_Object val = find_symbol_value (var);
12796 Fput (var, Qlast_arrow_position,
12797 COERCE_MARKER (val));
12798 Fput (var, Qlast_arrow_string,
12799 overlay_arrow_string_or_property (var));
12800 }
12801 else if (up_to_date < 0
12802 || !NILP (Fget (var, Qlast_arrow_position)))
12803 {
12804 Fput (var, Qlast_arrow_position, Qt);
12805 Fput (var, Qlast_arrow_string, Qt);
12806 }
12807 }
12808 }
12809
12810
12811 /* Return overlay arrow string to display at row.
12812 Return integer (bitmap number) for arrow bitmap in left fringe.
12813 Return nil if no overlay arrow. */
12814
12815 static Lisp_Object
12816 overlay_arrow_at_row (struct it *it, struct glyph_row *row)
12817 {
12818 Lisp_Object vlist;
12819
12820 for (vlist = Voverlay_arrow_variable_list;
12821 CONSP (vlist);
12822 vlist = XCDR (vlist))
12823 {
12824 Lisp_Object var = XCAR (vlist);
12825 Lisp_Object val;
12826
12827 if (!SYMBOLP (var))
12828 continue;
12829
12830 val = find_symbol_value (var);
12831
12832 if (MARKERP (val)
12833 && current_buffer == XMARKER (val)->buffer
12834 && (MATRIX_ROW_START_CHARPOS (row) == marker_position (val)))
12835 {
12836 if (FRAME_WINDOW_P (it->f)
12837 /* FIXME: if ROW->reversed_p is set, this should test
12838 the right fringe, not the left one. */
12839 && WINDOW_LEFT_FRINGE_WIDTH (it->w) > 0)
12840 {
12841 #ifdef HAVE_WINDOW_SYSTEM
12842 if (val = Fget (var, Qoverlay_arrow_bitmap), SYMBOLP (val))
12843 {
12844 int fringe_bitmap;
12845 if ((fringe_bitmap = lookup_fringe_bitmap (val)) != 0)
12846 return make_number (fringe_bitmap);
12847 }
12848 #endif
12849 return make_number (-1); /* Use default arrow bitmap. */
12850 }
12851 return overlay_arrow_string_or_property (var);
12852 }
12853 }
12854
12855 return Qnil;
12856 }
12857
12858 /* Return 1 if point moved out of or into a composition. Otherwise
12859 return 0. PREV_BUF and PREV_PT are the last point buffer and
12860 position. BUF and PT are the current point buffer and position. */
12861
12862 static int
12863 check_point_in_composition (struct buffer *prev_buf, ptrdiff_t prev_pt,
12864 struct buffer *buf, ptrdiff_t pt)
12865 {
12866 ptrdiff_t start, end;
12867 Lisp_Object prop;
12868 Lisp_Object buffer;
12869
12870 XSETBUFFER (buffer, buf);
12871 /* Check a composition at the last point if point moved within the
12872 same buffer. */
12873 if (prev_buf == buf)
12874 {
12875 if (prev_pt == pt)
12876 /* Point didn't move. */
12877 return 0;
12878
12879 if (prev_pt > BUF_BEGV (buf) && prev_pt < BUF_ZV (buf)
12880 && find_composition (prev_pt, -1, &start, &end, &prop, buffer)
12881 && COMPOSITION_VALID_P (start, end, prop)
12882 && start < prev_pt && end > prev_pt)
12883 /* The last point was within the composition. Return 1 iff
12884 point moved out of the composition. */
12885 return (pt <= start || pt >= end);
12886 }
12887
12888 /* Check a composition at the current point. */
12889 return (pt > BUF_BEGV (buf) && pt < BUF_ZV (buf)
12890 && find_composition (pt, -1, &start, &end, &prop, buffer)
12891 && COMPOSITION_VALID_P (start, end, prop)
12892 && start < pt && end > pt);
12893 }
12894
12895
12896 /* Reconsider the setting of B->clip_changed which is displayed
12897 in window W. */
12898
12899 static inline void
12900 reconsider_clip_changes (struct window *w, struct buffer *b)
12901 {
12902 if (b->clip_changed
12903 && !NILP (w->window_end_valid)
12904 && w->current_matrix->buffer == b
12905 && w->current_matrix->zv == BUF_ZV (b)
12906 && w->current_matrix->begv == BUF_BEGV (b))
12907 b->clip_changed = 0;
12908
12909 /* If display wasn't paused, and W is not a tool bar window, see if
12910 point has been moved into or out of a composition. In that case,
12911 we set b->clip_changed to 1 to force updating the screen. If
12912 b->clip_changed has already been set to 1, we can skip this
12913 check. */
12914 if (!b->clip_changed
12915 && BUFFERP (w->buffer) && !NILP (w->window_end_valid))
12916 {
12917 ptrdiff_t pt;
12918
12919 if (w == XWINDOW (selected_window))
12920 pt = PT;
12921 else
12922 pt = marker_position (w->pointm);
12923
12924 if ((w->current_matrix->buffer != XBUFFER (w->buffer)
12925 || pt != w->last_point)
12926 && check_point_in_composition (w->current_matrix->buffer,
12927 w->last_point,
12928 XBUFFER (w->buffer), pt))
12929 b->clip_changed = 1;
12930 }
12931 }
12932 \f
12933
12934 /* Select FRAME to forward the values of frame-local variables into C
12935 variables so that the redisplay routines can access those values
12936 directly. */
12937
12938 static void
12939 select_frame_for_redisplay (Lisp_Object frame)
12940 {
12941 Lisp_Object tail, tem;
12942 Lisp_Object old = selected_frame;
12943 struct Lisp_Symbol *sym;
12944
12945 eassert (FRAMEP (frame) && FRAME_LIVE_P (XFRAME (frame)));
12946
12947 selected_frame = frame;
12948
12949 do {
12950 for (tail = XFRAME (frame)->param_alist;
12951 CONSP (tail); tail = XCDR (tail))
12952 if (CONSP (XCAR (tail))
12953 && (tem = XCAR (XCAR (tail)),
12954 SYMBOLP (tem))
12955 && (sym = indirect_variable (XSYMBOL (tem)),
12956 sym->redirect == SYMBOL_LOCALIZED)
12957 && sym->val.blv->frame_local)
12958 /* Use find_symbol_value rather than Fsymbol_value
12959 to avoid an error if it is void. */
12960 find_symbol_value (tem);
12961 } while (!EQ (frame, old) && (frame = old, 1));
12962 }
12963
12964
12965 #define STOP_POLLING \
12966 do { if (! polling_stopped_here) stop_polling (); \
12967 polling_stopped_here = 1; } while (0)
12968
12969 #define RESUME_POLLING \
12970 do { if (polling_stopped_here) start_polling (); \
12971 polling_stopped_here = 0; } while (0)
12972
12973
12974 /* Perhaps in the future avoid recentering windows if it
12975 is not necessary; currently that causes some problems. */
12976
12977 static void
12978 redisplay_internal (void)
12979 {
12980 struct window *w = XWINDOW (selected_window);
12981 struct window *sw;
12982 struct frame *fr;
12983 int pending;
12984 int must_finish = 0;
12985 struct text_pos tlbufpos, tlendpos;
12986 int number_of_visible_frames;
12987 ptrdiff_t count, count1;
12988 struct frame *sf;
12989 int polling_stopped_here = 0;
12990 Lisp_Object old_frame = selected_frame;
12991
12992 /* Non-zero means redisplay has to consider all windows on all
12993 frames. Zero means, only selected_window is considered. */
12994 int consider_all_windows_p;
12995
12996 /* Non-zero means redisplay has to redisplay the miniwindow */
12997 int update_miniwindow_p = 0;
12998
12999 TRACE ((stderr, "redisplay_internal %d\n", redisplaying_p));
13000
13001 /* No redisplay if running in batch mode or frame is not yet fully
13002 initialized, or redisplay is explicitly turned off by setting
13003 Vinhibit_redisplay. */
13004 if (FRAME_INITIAL_P (SELECTED_FRAME ())
13005 || !NILP (Vinhibit_redisplay))
13006 return;
13007
13008 /* Don't examine these until after testing Vinhibit_redisplay.
13009 When Emacs is shutting down, perhaps because its connection to
13010 X has dropped, we should not look at them at all. */
13011 fr = XFRAME (w->frame);
13012 sf = SELECTED_FRAME ();
13013
13014 if (!fr->glyphs_initialized_p)
13015 return;
13016
13017 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS)
13018 if (popup_activated ())
13019 return;
13020 #endif
13021
13022 /* I don't think this happens but let's be paranoid. */
13023 if (redisplaying_p)
13024 return;
13025
13026 /* Record a function that clears redisplaying_p
13027 when we leave this function. */
13028 count = SPECPDL_INDEX ();
13029 record_unwind_protect (unwind_redisplay, selected_frame);
13030 redisplaying_p = 1;
13031 specbind (Qinhibit_free_realized_faces, Qnil);
13032
13033 {
13034 Lisp_Object tail, frame;
13035
13036 FOR_EACH_FRAME (tail, frame)
13037 {
13038 struct frame *f = XFRAME (frame);
13039 f->already_hscrolled_p = 0;
13040 }
13041 }
13042
13043 retry:
13044 /* Remember the currently selected window. */
13045 sw = w;
13046
13047 if (!EQ (old_frame, selected_frame)
13048 && FRAME_LIVE_P (XFRAME (old_frame)))
13049 /* When running redisplay, we play a bit fast-and-loose and allow e.g.
13050 selected_frame and selected_window to be temporarily out-of-sync so
13051 when we come back here via `goto retry', we need to resync because we
13052 may need to run Elisp code (via prepare_menu_bars). */
13053 select_frame_for_redisplay (old_frame);
13054
13055 pending = 0;
13056 reconsider_clip_changes (w, current_buffer);
13057 last_escape_glyph_frame = NULL;
13058 last_escape_glyph_face_id = (1 << FACE_ID_BITS);
13059 last_glyphless_glyph_frame = NULL;
13060 last_glyphless_glyph_face_id = (1 << FACE_ID_BITS);
13061
13062 /* If new fonts have been loaded that make a glyph matrix adjustment
13063 necessary, do it. */
13064 if (fonts_changed_p)
13065 {
13066 adjust_glyphs (NULL);
13067 ++windows_or_buffers_changed;
13068 fonts_changed_p = 0;
13069 }
13070
13071 /* If face_change_count is non-zero, init_iterator will free all
13072 realized faces, which includes the faces referenced from current
13073 matrices. So, we can't reuse current matrices in this case. */
13074 if (face_change_count)
13075 ++windows_or_buffers_changed;
13076
13077 if ((FRAME_TERMCAP_P (sf) || FRAME_MSDOS_P (sf))
13078 && FRAME_TTY (sf)->previous_frame != sf)
13079 {
13080 /* Since frames on a single ASCII terminal share the same
13081 display area, displaying a different frame means redisplay
13082 the whole thing. */
13083 windows_or_buffers_changed++;
13084 SET_FRAME_GARBAGED (sf);
13085 #ifndef DOS_NT
13086 set_tty_color_mode (FRAME_TTY (sf), sf);
13087 #endif
13088 FRAME_TTY (sf)->previous_frame = sf;
13089 }
13090
13091 /* Set the visible flags for all frames. Do this before checking
13092 for resized or garbaged frames; they want to know if their frames
13093 are visible. See the comment in frame.h for
13094 FRAME_SAMPLE_VISIBILITY. */
13095 {
13096 Lisp_Object tail, frame;
13097
13098 number_of_visible_frames = 0;
13099
13100 FOR_EACH_FRAME (tail, frame)
13101 {
13102 struct frame *f = XFRAME (frame);
13103
13104 FRAME_SAMPLE_VISIBILITY (f);
13105 if (FRAME_VISIBLE_P (f))
13106 ++number_of_visible_frames;
13107 clear_desired_matrices (f);
13108 }
13109 }
13110
13111 /* Notice any pending interrupt request to change frame size. */
13112 do_pending_window_change (1);
13113
13114 /* do_pending_window_change could change the selected_window due to
13115 frame resizing which makes the selected window too small. */
13116 if (WINDOWP (selected_window) && (w = XWINDOW (selected_window)) != sw)
13117 {
13118 sw = w;
13119 reconsider_clip_changes (w, current_buffer);
13120 }
13121
13122 /* Clear frames marked as garbaged. */
13123 if (frame_garbaged)
13124 clear_garbaged_frames ();
13125
13126 /* Build menubar and tool-bar items. */
13127 if (NILP (Vmemory_full))
13128 prepare_menu_bars ();
13129
13130 if (windows_or_buffers_changed)
13131 update_mode_lines++;
13132
13133 /* Detect case that we need to write or remove a star in the mode line. */
13134 if ((SAVE_MODIFF < MODIFF) != w->last_had_star)
13135 {
13136 w->update_mode_line = 1;
13137 if (buffer_shared > 1)
13138 update_mode_lines++;
13139 }
13140
13141 /* Avoid invocation of point motion hooks by `current_column' below. */
13142 count1 = SPECPDL_INDEX ();
13143 specbind (Qinhibit_point_motion_hooks, Qt);
13144
13145 /* If %c is in the mode line, update it if needed. */
13146 if (!NILP (w->column_number_displayed)
13147 /* This alternative quickly identifies a common case
13148 where no change is needed. */
13149 && !(PT == w->last_point
13150 && w->last_modified >= MODIFF
13151 && w->last_overlay_modified >= OVERLAY_MODIFF)
13152 && (XFASTINT (w->column_number_displayed) != current_column ()))
13153 w->update_mode_line = 1;
13154
13155 unbind_to (count1, Qnil);
13156
13157 FRAME_SCROLL_BOTTOM_VPOS (XFRAME (w->frame)) = -1;
13158
13159 /* The variable buffer_shared is set in redisplay_window and
13160 indicates that we redisplay a buffer in different windows. See
13161 there. */
13162 consider_all_windows_p = (update_mode_lines || buffer_shared > 1
13163 || cursor_type_changed);
13164
13165 /* If specs for an arrow have changed, do thorough redisplay
13166 to ensure we remove any arrow that should no longer exist. */
13167 if (overlay_arrows_changed_p ())
13168 consider_all_windows_p = windows_or_buffers_changed = 1;
13169
13170 /* Normally the message* functions will have already displayed and
13171 updated the echo area, but the frame may have been trashed, or
13172 the update may have been preempted, so display the echo area
13173 again here. Checking message_cleared_p captures the case that
13174 the echo area should be cleared. */
13175 if ((!NILP (echo_area_buffer[0]) && !display_last_displayed_message_p)
13176 || (!NILP (echo_area_buffer[1]) && display_last_displayed_message_p)
13177 || (message_cleared_p
13178 && minibuf_level == 0
13179 /* If the mini-window is currently selected, this means the
13180 echo-area doesn't show through. */
13181 && !MINI_WINDOW_P (XWINDOW (selected_window))))
13182 {
13183 int window_height_changed_p = echo_area_display (0);
13184
13185 if (message_cleared_p)
13186 update_miniwindow_p = 1;
13187
13188 must_finish = 1;
13189
13190 /* If we don't display the current message, don't clear the
13191 message_cleared_p flag, because, if we did, we wouldn't clear
13192 the echo area in the next redisplay which doesn't preserve
13193 the echo area. */
13194 if (!display_last_displayed_message_p)
13195 message_cleared_p = 0;
13196
13197 if (fonts_changed_p)
13198 goto retry;
13199 else if (window_height_changed_p)
13200 {
13201 consider_all_windows_p = 1;
13202 ++update_mode_lines;
13203 ++windows_or_buffers_changed;
13204
13205 /* If window configuration was changed, frames may have been
13206 marked garbaged. Clear them or we will experience
13207 surprises wrt scrolling. */
13208 if (frame_garbaged)
13209 clear_garbaged_frames ();
13210 }
13211 }
13212 else if (EQ (selected_window, minibuf_window)
13213 && (current_buffer->clip_changed
13214 || w->last_modified < MODIFF
13215 || w->last_overlay_modified < OVERLAY_MODIFF)
13216 && resize_mini_window (w, 0))
13217 {
13218 /* Resized active mini-window to fit the size of what it is
13219 showing if its contents might have changed. */
13220 must_finish = 1;
13221 /* FIXME: this causes all frames to be updated, which seems unnecessary
13222 since only the current frame needs to be considered. This function needs
13223 to be rewritten with two variables, consider_all_windows and
13224 consider_all_frames. */
13225 consider_all_windows_p = 1;
13226 ++windows_or_buffers_changed;
13227 ++update_mode_lines;
13228
13229 /* If window configuration was changed, frames may have been
13230 marked garbaged. Clear them or we will experience
13231 surprises wrt scrolling. */
13232 if (frame_garbaged)
13233 clear_garbaged_frames ();
13234 }
13235
13236
13237 /* If showing the region, and mark has changed, we must redisplay
13238 the whole window. The assignment to this_line_start_pos prevents
13239 the optimization directly below this if-statement. */
13240 if (((!NILP (Vtransient_mark_mode)
13241 && !NILP (BVAR (XBUFFER (w->buffer), mark_active)))
13242 != !NILP (w->region_showing))
13243 || (!NILP (w->region_showing)
13244 && !EQ (w->region_showing,
13245 Fmarker_position (BVAR (XBUFFER (w->buffer), mark)))))
13246 CHARPOS (this_line_start_pos) = 0;
13247
13248 /* Optimize the case that only the line containing the cursor in the
13249 selected window has changed. Variables starting with this_ are
13250 set in display_line and record information about the line
13251 containing the cursor. */
13252 tlbufpos = this_line_start_pos;
13253 tlendpos = this_line_end_pos;
13254 if (!consider_all_windows_p
13255 && CHARPOS (tlbufpos) > 0
13256 && !w->update_mode_line
13257 && !current_buffer->clip_changed
13258 && !current_buffer->prevent_redisplay_optimizations_p
13259 && FRAME_VISIBLE_P (XFRAME (w->frame))
13260 && !FRAME_OBSCURED_P (XFRAME (w->frame))
13261 /* Make sure recorded data applies to current buffer, etc. */
13262 && this_line_buffer == current_buffer
13263 && current_buffer == XBUFFER (w->buffer)
13264 && !w->force_start
13265 && !w->optional_new_start
13266 /* Point must be on the line that we have info recorded about. */
13267 && PT >= CHARPOS (tlbufpos)
13268 && PT <= Z - CHARPOS (tlendpos)
13269 /* All text outside that line, including its final newline,
13270 must be unchanged. */
13271 && text_outside_line_unchanged_p (w, CHARPOS (tlbufpos),
13272 CHARPOS (tlendpos)))
13273 {
13274 if (CHARPOS (tlbufpos) > BEGV
13275 && FETCH_BYTE (BYTEPOS (tlbufpos) - 1) != '\n'
13276 && (CHARPOS (tlbufpos) == ZV
13277 || FETCH_BYTE (BYTEPOS (tlbufpos)) == '\n'))
13278 /* Former continuation line has disappeared by becoming empty. */
13279 goto cancel;
13280 else if (w->last_modified < MODIFF
13281 || w->last_overlay_modified < OVERLAY_MODIFF
13282 || MINI_WINDOW_P (w))
13283 {
13284 /* We have to handle the case of continuation around a
13285 wide-column character (see the comment in indent.c around
13286 line 1340).
13287
13288 For instance, in the following case:
13289
13290 -------- Insert --------
13291 K_A_N_\\ `a' K_A_N_a\ `X_' are wide-column chars.
13292 J_I_ ==> J_I_ `^^' are cursors.
13293 ^^ ^^
13294 -------- --------
13295
13296 As we have to redraw the line above, we cannot use this
13297 optimization. */
13298
13299 struct it it;
13300 int line_height_before = this_line_pixel_height;
13301
13302 /* Note that start_display will handle the case that the
13303 line starting at tlbufpos is a continuation line. */
13304 start_display (&it, w, tlbufpos);
13305
13306 /* Implementation note: It this still necessary? */
13307 if (it.current_x != this_line_start_x)
13308 goto cancel;
13309
13310 TRACE ((stderr, "trying display optimization 1\n"));
13311 w->cursor.vpos = -1;
13312 overlay_arrow_seen = 0;
13313 it.vpos = this_line_vpos;
13314 it.current_y = this_line_y;
13315 it.glyph_row = MATRIX_ROW (w->desired_matrix, this_line_vpos);
13316 display_line (&it);
13317
13318 /* If line contains point, is not continued,
13319 and ends at same distance from eob as before, we win. */
13320 if (w->cursor.vpos >= 0
13321 /* Line is not continued, otherwise this_line_start_pos
13322 would have been set to 0 in display_line. */
13323 && CHARPOS (this_line_start_pos)
13324 /* Line ends as before. */
13325 && CHARPOS (this_line_end_pos) == CHARPOS (tlendpos)
13326 /* Line has same height as before. Otherwise other lines
13327 would have to be shifted up or down. */
13328 && this_line_pixel_height == line_height_before)
13329 {
13330 /* If this is not the window's last line, we must adjust
13331 the charstarts of the lines below. */
13332 if (it.current_y < it.last_visible_y)
13333 {
13334 struct glyph_row *row
13335 = MATRIX_ROW (w->current_matrix, this_line_vpos + 1);
13336 ptrdiff_t delta, delta_bytes;
13337
13338 /* We used to distinguish between two cases here,
13339 conditioned by Z - CHARPOS (tlendpos) == ZV, for
13340 when the line ends in a newline or the end of the
13341 buffer's accessible portion. But both cases did
13342 the same, so they were collapsed. */
13343 delta = (Z
13344 - CHARPOS (tlendpos)
13345 - MATRIX_ROW_START_CHARPOS (row));
13346 delta_bytes = (Z_BYTE
13347 - BYTEPOS (tlendpos)
13348 - MATRIX_ROW_START_BYTEPOS (row));
13349
13350 increment_matrix_positions (w->current_matrix,
13351 this_line_vpos + 1,
13352 w->current_matrix->nrows,
13353 delta, delta_bytes);
13354 }
13355
13356 /* If this row displays text now but previously didn't,
13357 or vice versa, w->window_end_vpos may have to be
13358 adjusted. */
13359 if ((it.glyph_row - 1)->displays_text_p)
13360 {
13361 if (XFASTINT (w->window_end_vpos) < this_line_vpos)
13362 wset_window_end_vpos (w, make_number (this_line_vpos));
13363 }
13364 else if (XFASTINT (w->window_end_vpos) == this_line_vpos
13365 && this_line_vpos > 0)
13366 wset_window_end_vpos (w, make_number (this_line_vpos - 1));
13367 wset_window_end_valid (w, Qnil);
13368
13369 /* Update hint: No need to try to scroll in update_window. */
13370 w->desired_matrix->no_scrolling_p = 1;
13371
13372 #ifdef GLYPH_DEBUG
13373 *w->desired_matrix->method = 0;
13374 debug_method_add (w, "optimization 1");
13375 #endif
13376 #if HAVE_XWIDGETS
13377 //debug optimization movement issue
13378 //w->desired_matrix->no_scrolling_p = 1;
13379 //*w->desired_matrix->method = 0;
13380 //debug_method_add (w, "optimization 1");
13381 #endif
13382
13383 #ifdef HAVE_WINDOW_SYSTEM
13384 update_window_fringes (w, 0);
13385 #endif
13386 goto update;
13387 }
13388 else
13389 goto cancel;
13390 }
13391 else if (/* Cursor position hasn't changed. */
13392 PT == w->last_point
13393 /* Make sure the cursor was last displayed
13394 in this window. Otherwise we have to reposition it. */
13395 && 0 <= w->cursor.vpos
13396 && WINDOW_TOTAL_LINES (w) > w->cursor.vpos)
13397 {
13398 if (!must_finish)
13399 {
13400 do_pending_window_change (1);
13401 /* If selected_window changed, redisplay again. */
13402 if (WINDOWP (selected_window)
13403 && (w = XWINDOW (selected_window)) != sw)
13404 goto retry;
13405
13406 /* We used to always goto end_of_redisplay here, but this
13407 isn't enough if we have a blinking cursor. */
13408 if (w->cursor_off_p == w->last_cursor_off_p)
13409 goto end_of_redisplay;
13410 }
13411 goto update;
13412 }
13413 /* If highlighting the region, or if the cursor is in the echo area,
13414 then we can't just move the cursor. */
13415 else if (! (!NILP (Vtransient_mark_mode)
13416 && !NILP (BVAR (current_buffer, mark_active)))
13417 && (EQ (selected_window,
13418 BVAR (current_buffer, last_selected_window))
13419 || highlight_nonselected_windows)
13420 && NILP (w->region_showing)
13421 && NILP (Vshow_trailing_whitespace)
13422 && !cursor_in_echo_area)
13423 {
13424 struct it it;
13425 struct glyph_row *row;
13426
13427 /* Skip from tlbufpos to PT and see where it is. Note that
13428 PT may be in invisible text. If so, we will end at the
13429 next visible position. */
13430 init_iterator (&it, w, CHARPOS (tlbufpos), BYTEPOS (tlbufpos),
13431 NULL, DEFAULT_FACE_ID);
13432 it.current_x = this_line_start_x;
13433 it.current_y = this_line_y;
13434 it.vpos = this_line_vpos;
13435
13436 /* The call to move_it_to stops in front of PT, but
13437 moves over before-strings. */
13438 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
13439
13440 if (it.vpos == this_line_vpos
13441 && (row = MATRIX_ROW (w->current_matrix, this_line_vpos),
13442 row->enabled_p))
13443 {
13444 eassert (this_line_vpos == it.vpos);
13445 eassert (this_line_y == it.current_y);
13446 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
13447 #ifdef GLYPH_DEBUG
13448 *w->desired_matrix->method = 0;
13449 debug_method_add (w, "optimization 3");
13450 #endif
13451 goto update;
13452 }
13453 else
13454 goto cancel;
13455 }
13456
13457 cancel:
13458 /* Text changed drastically or point moved off of line. */
13459 SET_MATRIX_ROW_ENABLED_P (w->desired_matrix, this_line_vpos, 0);
13460 }
13461
13462 CHARPOS (this_line_start_pos) = 0;
13463 consider_all_windows_p |= buffer_shared > 1;
13464 ++clear_face_cache_count;
13465 #ifdef HAVE_WINDOW_SYSTEM
13466 ++clear_image_cache_count;
13467 #endif
13468
13469 /* Build desired matrices, and update the display. If
13470 consider_all_windows_p is non-zero, do it for all windows on all
13471 frames. Otherwise do it for selected_window, only. */
13472
13473 if (consider_all_windows_p)
13474 {
13475 Lisp_Object tail, frame;
13476
13477 FOR_EACH_FRAME (tail, frame)
13478 XFRAME (frame)->updated_p = 0;
13479
13480 /* Recompute # windows showing selected buffer. This will be
13481 incremented each time such a window is displayed. */
13482 buffer_shared = 0;
13483
13484 FOR_EACH_FRAME (tail, frame)
13485 {
13486 struct frame *f = XFRAME (frame);
13487
13488 /* We don't have to do anything for unselected terminal
13489 frames. */
13490 if ((FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f))
13491 && !EQ (FRAME_TTY (f)->top_frame, frame))
13492 continue;
13493
13494 if (FRAME_WINDOW_P (f) || FRAME_TERMCAP_P (f) || f == sf)
13495 {
13496 if (! EQ (frame, selected_frame))
13497 /* Select the frame, for the sake of frame-local
13498 variables. */
13499 select_frame_for_redisplay (frame);
13500
13501 /* Mark all the scroll bars to be removed; we'll redeem
13502 the ones we want when we redisplay their windows. */
13503 if (FRAME_TERMINAL (f)->condemn_scroll_bars_hook)
13504 FRAME_TERMINAL (f)->condemn_scroll_bars_hook (f);
13505
13506 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
13507 redisplay_windows (FRAME_ROOT_WINDOW (f));
13508
13509 /* The X error handler may have deleted that frame. */
13510 if (!FRAME_LIVE_P (f))
13511 continue;
13512
13513 /* Any scroll bars which redisplay_windows should have
13514 nuked should now go away. */
13515 if (FRAME_TERMINAL (f)->judge_scroll_bars_hook)
13516 FRAME_TERMINAL (f)->judge_scroll_bars_hook (f);
13517
13518 /* If fonts changed, display again. */
13519 /* ??? rms: I suspect it is a mistake to jump all the way
13520 back to retry here. It should just retry this frame. */
13521 if (fonts_changed_p)
13522 goto retry;
13523
13524 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
13525 {
13526 /* See if we have to hscroll. */
13527 if (!f->already_hscrolled_p)
13528 {
13529 f->already_hscrolled_p = 1;
13530 if (hscroll_windows (f->root_window))
13531 goto retry;
13532 }
13533
13534 /* Prevent various kinds of signals during display
13535 update. stdio is not robust about handling
13536 signals, which can cause an apparent I/O
13537 error. */
13538 if (interrupt_input)
13539 unrequest_sigio ();
13540 STOP_POLLING;
13541
13542 /* Update the display. */
13543 set_window_update_flags (XWINDOW (f->root_window), 1);
13544 pending |= update_frame (f, 0, 0);
13545 f->updated_p = 1;
13546 }
13547 }
13548 }
13549
13550 if (!EQ (old_frame, selected_frame)
13551 && FRAME_LIVE_P (XFRAME (old_frame)))
13552 /* We played a bit fast-and-loose above and allowed selected_frame
13553 and selected_window to be temporarily out-of-sync but let's make
13554 sure this stays contained. */
13555 select_frame_for_redisplay (old_frame);
13556 eassert (EQ (XFRAME (selected_frame)->selected_window,
13557 selected_window));
13558
13559 if (!pending)
13560 {
13561 /* Do the mark_window_display_accurate after all windows have
13562 been redisplayed because this call resets flags in buffers
13563 which are needed for proper redisplay. */
13564 FOR_EACH_FRAME (tail, frame)
13565 {
13566 struct frame *f = XFRAME (frame);
13567 if (f->updated_p)
13568 {
13569 mark_window_display_accurate (f->root_window, 1);
13570 if (FRAME_TERMINAL (f)->frame_up_to_date_hook)
13571 FRAME_TERMINAL (f)->frame_up_to_date_hook (f);
13572 }
13573 }
13574 }
13575 }
13576 else if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
13577 {
13578 Lisp_Object mini_window = FRAME_MINIBUF_WINDOW (sf);
13579 struct frame *mini_frame;
13580
13581 displayed_buffer = XBUFFER (XWINDOW (selected_window)->buffer);
13582 /* Use list_of_error, not Qerror, so that
13583 we catch only errors and don't run the debugger. */
13584 internal_condition_case_1 (redisplay_window_1, selected_window,
13585 list_of_error,
13586 redisplay_window_error);
13587 if (update_miniwindow_p)
13588 internal_condition_case_1 (redisplay_window_1, mini_window,
13589 list_of_error,
13590 redisplay_window_error);
13591
13592 /* Compare desired and current matrices, perform output. */
13593
13594 update:
13595 /* If fonts changed, display again. */
13596 if (fonts_changed_p)
13597 goto retry;
13598
13599 /* Prevent various kinds of signals during display update.
13600 stdio is not robust about handling signals,
13601 which can cause an apparent I/O error. */
13602 if (interrupt_input)
13603 unrequest_sigio ();
13604 STOP_POLLING;
13605
13606 if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
13607 {
13608 if (hscroll_windows (selected_window))
13609 goto retry;
13610
13611 XWINDOW (selected_window)->must_be_updated_p = 1;
13612 pending = update_frame (sf, 0, 0);
13613 }
13614
13615 /* We may have called echo_area_display at the top of this
13616 function. If the echo area is on another frame, that may
13617 have put text on a frame other than the selected one, so the
13618 above call to update_frame would not have caught it. Catch
13619 it here. */
13620 mini_window = FRAME_MINIBUF_WINDOW (sf);
13621 mini_frame = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
13622
13623 if (mini_frame != sf && FRAME_WINDOW_P (mini_frame))
13624 {
13625 XWINDOW (mini_window)->must_be_updated_p = 1;
13626 pending |= update_frame (mini_frame, 0, 0);
13627 if (!pending && hscroll_windows (mini_window))
13628 goto retry;
13629 }
13630 }
13631
13632 /* If display was paused because of pending input, make sure we do a
13633 thorough update the next time. */
13634 if (pending)
13635 {
13636 /* Prevent the optimization at the beginning of
13637 redisplay_internal that tries a single-line update of the
13638 line containing the cursor in the selected window. */
13639 CHARPOS (this_line_start_pos) = 0;
13640
13641 /* Let the overlay arrow be updated the next time. */
13642 update_overlay_arrows (0);
13643
13644 /* If we pause after scrolling, some rows in the current
13645 matrices of some windows are not valid. */
13646 if (!WINDOW_FULL_WIDTH_P (w)
13647 && !FRAME_WINDOW_P (XFRAME (w->frame)))
13648 update_mode_lines = 1;
13649 }
13650 else
13651 {
13652 if (!consider_all_windows_p)
13653 {
13654 /* This has already been done above if
13655 consider_all_windows_p is set. */
13656 mark_window_display_accurate_1 (w, 1);
13657
13658 /* Say overlay arrows are up to date. */
13659 update_overlay_arrows (1);
13660
13661 if (FRAME_TERMINAL (sf)->frame_up_to_date_hook != 0)
13662 FRAME_TERMINAL (sf)->frame_up_to_date_hook (sf);
13663 }
13664
13665 update_mode_lines = 0;
13666 windows_or_buffers_changed = 0;
13667 cursor_type_changed = 0;
13668 }
13669
13670 /* Start SIGIO interrupts coming again. Having them off during the
13671 code above makes it less likely one will discard output, but not
13672 impossible, since there might be stuff in the system buffer here.
13673 But it is much hairier to try to do anything about that. */
13674 if (interrupt_input)
13675 request_sigio ();
13676 RESUME_POLLING;
13677
13678 /* If a frame has become visible which was not before, redisplay
13679 again, so that we display it. Expose events for such a frame
13680 (which it gets when becoming visible) don't call the parts of
13681 redisplay constructing glyphs, so simply exposing a frame won't
13682 display anything in this case. So, we have to display these
13683 frames here explicitly. */
13684 if (!pending)
13685 {
13686 Lisp_Object tail, frame;
13687 int new_count = 0;
13688
13689 FOR_EACH_FRAME (tail, frame)
13690 {
13691 int this_is_visible = 0;
13692
13693 if (XFRAME (frame)->visible)
13694 this_is_visible = 1;
13695 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
13696 if (XFRAME (frame)->visible)
13697 this_is_visible = 1;
13698
13699 if (this_is_visible)
13700 new_count++;
13701 }
13702
13703 if (new_count != number_of_visible_frames)
13704 windows_or_buffers_changed++;
13705 }
13706
13707 /* Change frame size now if a change is pending. */
13708 do_pending_window_change (1);
13709
13710 /* If we just did a pending size change, or have additional
13711 visible frames, or selected_window changed, redisplay again. */
13712 if ((windows_or_buffers_changed && !pending)
13713 || (WINDOWP (selected_window) && (w = XWINDOW (selected_window)) != sw))
13714 goto retry;
13715
13716 /* Clear the face and image caches.
13717
13718 We used to do this only if consider_all_windows_p. But the cache
13719 needs to be cleared if a timer creates images in the current
13720 buffer (e.g. the test case in Bug#6230). */
13721
13722 if (clear_face_cache_count > CLEAR_FACE_CACHE_COUNT)
13723 {
13724 clear_face_cache (0);
13725 clear_face_cache_count = 0;
13726 }
13727
13728 #ifdef HAVE_WINDOW_SYSTEM
13729 if (clear_image_cache_count > CLEAR_IMAGE_CACHE_COUNT)
13730 {
13731 clear_image_caches (Qnil);
13732 clear_image_cache_count = 0;
13733 }
13734 #endif /* HAVE_WINDOW_SYSTEM */
13735
13736 end_of_redisplay:
13737 unbind_to (count, Qnil);
13738 RESUME_POLLING;
13739 }
13740
13741
13742 /* Redisplay, but leave alone any recent echo area message unless
13743 another message has been requested in its place.
13744
13745 This is useful in situations where you need to redisplay but no
13746 user action has occurred, making it inappropriate for the message
13747 area to be cleared. See tracking_off and
13748 wait_reading_process_output for examples of these situations.
13749
13750 FROM_WHERE is an integer saying from where this function was
13751 called. This is useful for debugging. */
13752
13753 void
13754 redisplay_preserve_echo_area (int from_where)
13755 {
13756 TRACE ((stderr, "redisplay_preserve_echo_area (%d)\n", from_where));
13757
13758 if (!NILP (echo_area_buffer[1]))
13759 {
13760 /* We have a previously displayed message, but no current
13761 message. Redisplay the previous message. */
13762 display_last_displayed_message_p = 1;
13763 redisplay_internal ();
13764 display_last_displayed_message_p = 0;
13765 }
13766 else
13767 redisplay_internal ();
13768
13769 if (FRAME_RIF (SELECTED_FRAME ()) != NULL
13770 && FRAME_RIF (SELECTED_FRAME ())->flush_display_optional)
13771 FRAME_RIF (SELECTED_FRAME ())->flush_display_optional (NULL);
13772 }
13773
13774
13775 /* Function registered with record_unwind_protect in redisplay_internal.
13776 Clear redisplaying_p. Also, select the previously
13777 selected frame, unless it has been deleted (by an X connection
13778 failure during redisplay, for example). */
13779
13780 static Lisp_Object
13781 unwind_redisplay (Lisp_Object old_frame)
13782 {
13783 redisplaying_p = 0;
13784 if (! EQ (old_frame, selected_frame)
13785 && FRAME_LIVE_P (XFRAME (old_frame)))
13786 select_frame_for_redisplay (old_frame);
13787 return Qnil;
13788 }
13789
13790
13791 /* Mark the display of window W as accurate or inaccurate. If
13792 ACCURATE_P is non-zero mark display of W as accurate. If
13793 ACCURATE_P is zero, arrange for W to be redisplayed the next time
13794 redisplay_internal is called. */
13795
13796 static void
13797 mark_window_display_accurate_1 (struct window *w, int accurate_p)
13798 {
13799 if (BUFFERP (w->buffer))
13800 {
13801 struct buffer *b = XBUFFER (w->buffer);
13802
13803 w->last_modified = accurate_p ? BUF_MODIFF(b) : 0;
13804 w->last_overlay_modified = accurate_p ? BUF_OVERLAY_MODIFF(b) : 0;
13805 w->last_had_star
13806 = BUF_MODIFF (b) > BUF_SAVE_MODIFF (b);
13807
13808 if (accurate_p)
13809 {
13810 b->clip_changed = 0;
13811 b->prevent_redisplay_optimizations_p = 0;
13812
13813 BUF_UNCHANGED_MODIFIED (b) = BUF_MODIFF (b);
13814 BUF_OVERLAY_UNCHANGED_MODIFIED (b) = BUF_OVERLAY_MODIFF (b);
13815 BUF_BEG_UNCHANGED (b) = BUF_GPT (b) - BUF_BEG (b);
13816 BUF_END_UNCHANGED (b) = BUF_Z (b) - BUF_GPT (b);
13817
13818 w->current_matrix->buffer = b;
13819 w->current_matrix->begv = BUF_BEGV (b);
13820 w->current_matrix->zv = BUF_ZV (b);
13821
13822 w->last_cursor = w->cursor;
13823 w->last_cursor_off_p = w->cursor_off_p;
13824
13825 if (w == XWINDOW (selected_window))
13826 w->last_point = BUF_PT (b);
13827 else
13828 w->last_point = XMARKER (w->pointm)->charpos;
13829 }
13830 }
13831
13832 if (accurate_p)
13833 {
13834 wset_window_end_valid (w, w->buffer);
13835 w->update_mode_line = 0;
13836 }
13837 }
13838
13839
13840 /* Mark the display of windows in the window tree rooted at WINDOW as
13841 accurate or inaccurate. If ACCURATE_P is non-zero mark display of
13842 windows as accurate. If ACCURATE_P is zero, arrange for windows to
13843 be redisplayed the next time redisplay_internal is called. */
13844
13845 void
13846 mark_window_display_accurate (Lisp_Object window, int accurate_p)
13847 {
13848 struct window *w;
13849
13850 for (; !NILP (window); window = w->next)
13851 {
13852 w = XWINDOW (window);
13853 mark_window_display_accurate_1 (w, accurate_p);
13854
13855 if (!NILP (w->vchild))
13856 mark_window_display_accurate (w->vchild, accurate_p);
13857 if (!NILP (w->hchild))
13858 mark_window_display_accurate (w->hchild, accurate_p);
13859 }
13860
13861 if (accurate_p)
13862 {
13863 update_overlay_arrows (1);
13864 }
13865 else
13866 {
13867 /* Force a thorough redisplay the next time by setting
13868 last_arrow_position and last_arrow_string to t, which is
13869 unequal to any useful value of Voverlay_arrow_... */
13870 update_overlay_arrows (-1);
13871 }
13872 }
13873
13874
13875 /* Return value in display table DP (Lisp_Char_Table *) for character
13876 C. Since a display table doesn't have any parent, we don't have to
13877 follow parent. Do not call this function directly but use the
13878 macro DISP_CHAR_VECTOR. */
13879
13880 Lisp_Object
13881 disp_char_vector (struct Lisp_Char_Table *dp, int c)
13882 {
13883 Lisp_Object val;
13884
13885 if (ASCII_CHAR_P (c))
13886 {
13887 val = dp->ascii;
13888 if (SUB_CHAR_TABLE_P (val))
13889 val = XSUB_CHAR_TABLE (val)->contents[c];
13890 }
13891 else
13892 {
13893 Lisp_Object table;
13894
13895 XSETCHAR_TABLE (table, dp);
13896 val = char_table_ref (table, c);
13897 }
13898 if (NILP (val))
13899 val = dp->defalt;
13900 return val;
13901 }
13902
13903
13904 \f
13905 /***********************************************************************
13906 Window Redisplay
13907 ***********************************************************************/
13908
13909 /* Redisplay all leaf windows in the window tree rooted at WINDOW. */
13910
13911 static void
13912 redisplay_windows (Lisp_Object window)
13913 {
13914 while (!NILP (window))
13915 {
13916 struct window *w = XWINDOW (window);
13917
13918 if (!NILP (w->hchild))
13919 redisplay_windows (w->hchild);
13920 else if (!NILP (w->vchild))
13921 redisplay_windows (w->vchild);
13922 else if (!NILP (w->buffer))
13923 {
13924 displayed_buffer = XBUFFER (w->buffer);
13925 /* Use list_of_error, not Qerror, so that
13926 we catch only errors and don't run the debugger. */
13927 internal_condition_case_1 (redisplay_window_0, window,
13928 list_of_error,
13929 redisplay_window_error);
13930 }
13931
13932 window = w->next;
13933 }
13934 }
13935
13936 static Lisp_Object
13937 redisplay_window_error (Lisp_Object ignore)
13938 {
13939 displayed_buffer->display_error_modiff = BUF_MODIFF (displayed_buffer);
13940 return Qnil;
13941 }
13942
13943 static Lisp_Object
13944 redisplay_window_0 (Lisp_Object window)
13945 {
13946 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
13947 redisplay_window (window, 0);
13948 return Qnil;
13949 }
13950
13951 static Lisp_Object
13952 redisplay_window_1 (Lisp_Object window)
13953 {
13954 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
13955 redisplay_window (window, 1);
13956 return Qnil;
13957 }
13958 \f
13959
13960 /* Set cursor position of W. PT is assumed to be displayed in ROW.
13961 DELTA and DELTA_BYTES are the numbers of characters and bytes by
13962 which positions recorded in ROW differ from current buffer
13963 positions.
13964
13965 Return 0 if cursor is not on this row, 1 otherwise. */
13966
13967 static int
13968 set_cursor_from_row (struct window *w, struct glyph_row *row,
13969 struct glyph_matrix *matrix,
13970 ptrdiff_t delta, ptrdiff_t delta_bytes,
13971 int dy, int dvpos)
13972 {
13973 struct glyph *glyph = row->glyphs[TEXT_AREA];
13974 struct glyph *end = glyph + row->used[TEXT_AREA];
13975 struct glyph *cursor = NULL;
13976 /* The last known character position in row. */
13977 ptrdiff_t last_pos = MATRIX_ROW_START_CHARPOS (row) + delta;
13978 int x = row->x;
13979 ptrdiff_t pt_old = PT - delta;
13980 ptrdiff_t pos_before = MATRIX_ROW_START_CHARPOS (row) + delta;
13981 ptrdiff_t pos_after = MATRIX_ROW_END_CHARPOS (row) + delta;
13982 struct glyph *glyph_before = glyph - 1, *glyph_after = end;
13983 /* A glyph beyond the edge of TEXT_AREA which we should never
13984 touch. */
13985 struct glyph *glyphs_end = end;
13986 /* Non-zero means we've found a match for cursor position, but that
13987 glyph has the avoid_cursor_p flag set. */
13988 int match_with_avoid_cursor = 0;
13989 /* Non-zero means we've seen at least one glyph that came from a
13990 display string. */
13991 int string_seen = 0;
13992 /* Largest and smallest buffer positions seen so far during scan of
13993 glyph row. */
13994 ptrdiff_t bpos_max = pos_before;
13995 ptrdiff_t bpos_min = pos_after;
13996 /* Last buffer position covered by an overlay string with an integer
13997 `cursor' property. */
13998 ptrdiff_t bpos_covered = 0;
13999 /* Non-zero means the display string on which to display the cursor
14000 comes from a text property, not from an overlay. */
14001 int string_from_text_prop = 0;
14002
14003 /* Don't even try doing anything if called for a mode-line or
14004 header-line row, since the rest of the code isn't prepared to
14005 deal with such calamities. */
14006 eassert (!row->mode_line_p);
14007 if (row->mode_line_p)
14008 return 0;
14009
14010 /* Skip over glyphs not having an object at the start and the end of
14011 the row. These are special glyphs like truncation marks on
14012 terminal frames. */
14013 if (row->displays_text_p)
14014 {
14015 if (!row->reversed_p)
14016 {
14017 while (glyph < end
14018 && INTEGERP (glyph->object)
14019 && glyph->charpos < 0)
14020 {
14021 x += glyph->pixel_width;
14022 ++glyph;
14023 }
14024 while (end > glyph
14025 && INTEGERP ((end - 1)->object)
14026 /* CHARPOS is zero for blanks and stretch glyphs
14027 inserted by extend_face_to_end_of_line. */
14028 && (end - 1)->charpos <= 0)
14029 --end;
14030 glyph_before = glyph - 1;
14031 glyph_after = end;
14032 }
14033 else
14034 {
14035 struct glyph *g;
14036
14037 /* If the glyph row is reversed, we need to process it from back
14038 to front, so swap the edge pointers. */
14039 glyphs_end = end = glyph - 1;
14040 glyph += row->used[TEXT_AREA] - 1;
14041
14042 while (glyph > end + 1
14043 && INTEGERP (glyph->object)
14044 && glyph->charpos < 0)
14045 {
14046 --glyph;
14047 x -= glyph->pixel_width;
14048 }
14049 if (INTEGERP (glyph->object) && glyph->charpos < 0)
14050 --glyph;
14051 /* By default, in reversed rows we put the cursor on the
14052 rightmost (first in the reading order) glyph. */
14053 for (g = end + 1; g < glyph; g++)
14054 x += g->pixel_width;
14055 while (end < glyph
14056 && INTEGERP ((end + 1)->object)
14057 && (end + 1)->charpos <= 0)
14058 ++end;
14059 glyph_before = glyph + 1;
14060 glyph_after = end;
14061 }
14062 }
14063 else if (row->reversed_p)
14064 {
14065 /* In R2L rows that don't display text, put the cursor on the
14066 rightmost glyph. Case in point: an empty last line that is
14067 part of an R2L paragraph. */
14068 cursor = end - 1;
14069 /* Avoid placing the cursor on the last glyph of the row, where
14070 on terminal frames we hold the vertical border between
14071 adjacent windows. */
14072 if (!FRAME_WINDOW_P (WINDOW_XFRAME (w))
14073 && !WINDOW_RIGHTMOST_P (w)
14074 && cursor == row->glyphs[LAST_AREA] - 1)
14075 cursor--;
14076 x = -1; /* will be computed below, at label compute_x */
14077 }
14078
14079 /* Step 1: Try to find the glyph whose character position
14080 corresponds to point. If that's not possible, find 2 glyphs
14081 whose character positions are the closest to point, one before
14082 point, the other after it. */
14083 if (!row->reversed_p)
14084 while (/* not marched to end of glyph row */
14085 glyph < end
14086 /* glyph was not inserted by redisplay for internal purposes */
14087 && !INTEGERP (glyph->object))
14088 {
14089 if (BUFFERP (glyph->object))
14090 {
14091 ptrdiff_t dpos = glyph->charpos - pt_old;
14092
14093 if (glyph->charpos > bpos_max)
14094 bpos_max = glyph->charpos;
14095 if (glyph->charpos < bpos_min)
14096 bpos_min = glyph->charpos;
14097 if (!glyph->avoid_cursor_p)
14098 {
14099 /* If we hit point, we've found the glyph on which to
14100 display the cursor. */
14101 if (dpos == 0)
14102 {
14103 match_with_avoid_cursor = 0;
14104 break;
14105 }
14106 /* See if we've found a better approximation to
14107 POS_BEFORE or to POS_AFTER. */
14108 if (0 > dpos && dpos > pos_before - pt_old)
14109 {
14110 pos_before = glyph->charpos;
14111 glyph_before = glyph;
14112 }
14113 else if (0 < dpos && dpos < pos_after - pt_old)
14114 {
14115 pos_after = glyph->charpos;
14116 glyph_after = glyph;
14117 }
14118 }
14119 else if (dpos == 0)
14120 match_with_avoid_cursor = 1;
14121 }
14122 else if (STRINGP (glyph->object))
14123 {
14124 Lisp_Object chprop;
14125 ptrdiff_t glyph_pos = glyph->charpos;
14126
14127 chprop = Fget_char_property (make_number (glyph_pos), Qcursor,
14128 glyph->object);
14129 if (!NILP (chprop))
14130 {
14131 /* If the string came from a `display' text property,
14132 look up the buffer position of that property and
14133 use that position to update bpos_max, as if we
14134 actually saw such a position in one of the row's
14135 glyphs. This helps with supporting integer values
14136 of `cursor' property on the display string in
14137 situations where most or all of the row's buffer
14138 text is completely covered by display properties,
14139 so that no glyph with valid buffer positions is
14140 ever seen in the row. */
14141 ptrdiff_t prop_pos =
14142 string_buffer_position_lim (glyph->object, pos_before,
14143 pos_after, 0);
14144
14145 if (prop_pos >= pos_before)
14146 bpos_max = prop_pos - 1;
14147 }
14148 if (INTEGERP (chprop))
14149 {
14150 bpos_covered = bpos_max + XINT (chprop);
14151 /* If the `cursor' property covers buffer positions up
14152 to and including point, we should display cursor on
14153 this glyph. Note that, if a `cursor' property on one
14154 of the string's characters has an integer value, we
14155 will break out of the loop below _before_ we get to
14156 the position match above. IOW, integer values of
14157 the `cursor' property override the "exact match for
14158 point" strategy of positioning the cursor. */
14159 /* Implementation note: bpos_max == pt_old when, e.g.,
14160 we are in an empty line, where bpos_max is set to
14161 MATRIX_ROW_START_CHARPOS, see above. */
14162 if (bpos_max <= pt_old && bpos_covered >= pt_old)
14163 {
14164 cursor = glyph;
14165 break;
14166 }
14167 }
14168
14169 string_seen = 1;
14170 }
14171 x += glyph->pixel_width;
14172 ++glyph;
14173 }
14174 else if (glyph > end) /* row is reversed */
14175 while (!INTEGERP (glyph->object))
14176 {
14177 if (BUFFERP (glyph->object))
14178 {
14179 ptrdiff_t dpos = glyph->charpos - pt_old;
14180
14181 if (glyph->charpos > bpos_max)
14182 bpos_max = glyph->charpos;
14183 if (glyph->charpos < bpos_min)
14184 bpos_min = glyph->charpos;
14185 if (!glyph->avoid_cursor_p)
14186 {
14187 if (dpos == 0)
14188 {
14189 match_with_avoid_cursor = 0;
14190 break;
14191 }
14192 if (0 > dpos && dpos > pos_before - pt_old)
14193 {
14194 pos_before = glyph->charpos;
14195 glyph_before = glyph;
14196 }
14197 else if (0 < dpos && dpos < pos_after - pt_old)
14198 {
14199 pos_after = glyph->charpos;
14200 glyph_after = glyph;
14201 }
14202 }
14203 else if (dpos == 0)
14204 match_with_avoid_cursor = 1;
14205 }
14206 else if (STRINGP (glyph->object))
14207 {
14208 Lisp_Object chprop;
14209 ptrdiff_t glyph_pos = glyph->charpos;
14210
14211 chprop = Fget_char_property (make_number (glyph_pos), Qcursor,
14212 glyph->object);
14213 if (!NILP (chprop))
14214 {
14215 ptrdiff_t prop_pos =
14216 string_buffer_position_lim (glyph->object, pos_before,
14217 pos_after, 0);
14218
14219 if (prop_pos >= pos_before)
14220 bpos_max = prop_pos - 1;
14221 }
14222 if (INTEGERP (chprop))
14223 {
14224 bpos_covered = bpos_max + XINT (chprop);
14225 /* If the `cursor' property covers buffer positions up
14226 to and including point, we should display cursor on
14227 this glyph. */
14228 if (bpos_max <= pt_old && bpos_covered >= pt_old)
14229 {
14230 cursor = glyph;
14231 break;
14232 }
14233 }
14234 string_seen = 1;
14235 }
14236 --glyph;
14237 if (glyph == glyphs_end) /* don't dereference outside TEXT_AREA */
14238 {
14239 x--; /* can't use any pixel_width */
14240 break;
14241 }
14242 x -= glyph->pixel_width;
14243 }
14244
14245 /* Step 2: If we didn't find an exact match for point, we need to
14246 look for a proper place to put the cursor among glyphs between
14247 GLYPH_BEFORE and GLYPH_AFTER. */
14248 if (!((row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end)
14249 && BUFFERP (glyph->object) && glyph->charpos == pt_old)
14250 && bpos_covered < pt_old)
14251 {
14252 /* An empty line has a single glyph whose OBJECT is zero and
14253 whose CHARPOS is the position of a newline on that line.
14254 Note that on a TTY, there are more glyphs after that, which
14255 were produced by extend_face_to_end_of_line, but their
14256 CHARPOS is zero or negative. */
14257 int empty_line_p =
14258 (row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end)
14259 && INTEGERP (glyph->object) && glyph->charpos > 0;
14260
14261 if (row->ends_in_ellipsis_p && pos_after == last_pos)
14262 {
14263 ptrdiff_t ellipsis_pos;
14264
14265 /* Scan back over the ellipsis glyphs. */
14266 if (!row->reversed_p)
14267 {
14268 ellipsis_pos = (glyph - 1)->charpos;
14269 while (glyph > row->glyphs[TEXT_AREA]
14270 && (glyph - 1)->charpos == ellipsis_pos)
14271 glyph--, x -= glyph->pixel_width;
14272 /* That loop always goes one position too far, including
14273 the glyph before the ellipsis. So scan forward over
14274 that one. */
14275 x += glyph->pixel_width;
14276 glyph++;
14277 }
14278 else /* row is reversed */
14279 {
14280 ellipsis_pos = (glyph + 1)->charpos;
14281 while (glyph < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1
14282 && (glyph + 1)->charpos == ellipsis_pos)
14283 glyph++, x += glyph->pixel_width;
14284 x -= glyph->pixel_width;
14285 glyph--;
14286 }
14287 }
14288 else if (match_with_avoid_cursor)
14289 {
14290 cursor = glyph_after;
14291 x = -1;
14292 }
14293 else if (string_seen)
14294 {
14295 int incr = row->reversed_p ? -1 : +1;
14296
14297 /* Need to find the glyph that came out of a string which is
14298 present at point. That glyph is somewhere between
14299 GLYPH_BEFORE and GLYPH_AFTER, and it came from a string
14300 positioned between POS_BEFORE and POS_AFTER in the
14301 buffer. */
14302 struct glyph *start, *stop;
14303 ptrdiff_t pos = pos_before;
14304
14305 x = -1;
14306
14307 /* If the row ends in a newline from a display string,
14308 reordering could have moved the glyphs belonging to the
14309 string out of the [GLYPH_BEFORE..GLYPH_AFTER] range. So
14310 in this case we extend the search to the last glyph in
14311 the row that was not inserted by redisplay. */
14312 if (row->ends_in_newline_from_string_p)
14313 {
14314 glyph_after = end;
14315 pos_after = MATRIX_ROW_END_CHARPOS (row) + delta;
14316 }
14317
14318 /* GLYPH_BEFORE and GLYPH_AFTER are the glyphs that
14319 correspond to POS_BEFORE and POS_AFTER, respectively. We
14320 need START and STOP in the order that corresponds to the
14321 row's direction as given by its reversed_p flag. If the
14322 directionality of characters between POS_BEFORE and
14323 POS_AFTER is the opposite of the row's base direction,
14324 these characters will have been reordered for display,
14325 and we need to reverse START and STOP. */
14326 if (!row->reversed_p)
14327 {
14328 start = min (glyph_before, glyph_after);
14329 stop = max (glyph_before, glyph_after);
14330 }
14331 else
14332 {
14333 start = max (glyph_before, glyph_after);
14334 stop = min (glyph_before, glyph_after);
14335 }
14336 for (glyph = start + incr;
14337 row->reversed_p ? glyph > stop : glyph < stop; )
14338 {
14339
14340 /* Any glyphs that come from the buffer are here because
14341 of bidi reordering. Skip them, and only pay
14342 attention to glyphs that came from some string. */
14343 if (STRINGP (glyph->object))
14344 {
14345 Lisp_Object str;
14346 ptrdiff_t tem;
14347 /* If the display property covers the newline, we
14348 need to search for it one position farther. */
14349 ptrdiff_t lim = pos_after
14350 + (pos_after == MATRIX_ROW_END_CHARPOS (row) + delta);
14351
14352 string_from_text_prop = 0;
14353 str = glyph->object;
14354 tem = string_buffer_position_lim (str, pos, lim, 0);
14355 if (tem == 0 /* from overlay */
14356 || pos <= tem)
14357 {
14358 /* If the string from which this glyph came is
14359 found in the buffer at point, or at position
14360 that is closer to point than pos_after, then
14361 we've found the glyph we've been looking for.
14362 If it comes from an overlay (tem == 0), and
14363 it has the `cursor' property on one of its
14364 glyphs, record that glyph as a candidate for
14365 displaying the cursor. (As in the
14366 unidirectional version, we will display the
14367 cursor on the last candidate we find.) */
14368 if (tem == 0
14369 || tem == pt_old
14370 || (tem - pt_old > 0 && tem < pos_after))
14371 {
14372 /* The glyphs from this string could have
14373 been reordered. Find the one with the
14374 smallest string position. Or there could
14375 be a character in the string with the
14376 `cursor' property, which means display
14377 cursor on that character's glyph. */
14378 ptrdiff_t strpos = glyph->charpos;
14379
14380 if (tem)
14381 {
14382 cursor = glyph;
14383 string_from_text_prop = 1;
14384 }
14385 for ( ;
14386 (row->reversed_p ? glyph > stop : glyph < stop)
14387 && EQ (glyph->object, str);
14388 glyph += incr)
14389 {
14390 Lisp_Object cprop;
14391 ptrdiff_t gpos = glyph->charpos;
14392
14393 cprop = Fget_char_property (make_number (gpos),
14394 Qcursor,
14395 glyph->object);
14396 if (!NILP (cprop))
14397 {
14398 cursor = glyph;
14399 break;
14400 }
14401 if (tem && glyph->charpos < strpos)
14402 {
14403 strpos = glyph->charpos;
14404 cursor = glyph;
14405 }
14406 }
14407
14408 if (tem == pt_old
14409 || (tem - pt_old > 0 && tem < pos_after))
14410 goto compute_x;
14411 }
14412 if (tem)
14413 pos = tem + 1; /* don't find previous instances */
14414 }
14415 /* This string is not what we want; skip all of the
14416 glyphs that came from it. */
14417 while ((row->reversed_p ? glyph > stop : glyph < stop)
14418 && EQ (glyph->object, str))
14419 glyph += incr;
14420 }
14421 else
14422 glyph += incr;
14423 }
14424
14425 /* If we reached the end of the line, and END was from a string,
14426 the cursor is not on this line. */
14427 if (cursor == NULL
14428 && (row->reversed_p ? glyph <= end : glyph >= end)
14429 && (row->reversed_p ? end > glyphs_end : end < glyphs_end)
14430 && STRINGP (end->object)
14431 && row->continued_p)
14432 return 0;
14433 }
14434 /* A truncated row may not include PT among its character positions.
14435 Setting the cursor inside the scroll margin will trigger
14436 recalculation of hscroll in hscroll_window_tree. But if a
14437 display string covers point, defer to the string-handling
14438 code below to figure this out. */
14439 else if (row->truncated_on_left_p && pt_old < bpos_min)
14440 {
14441 cursor = glyph_before;
14442 x = -1;
14443 }
14444 else if ((row->truncated_on_right_p && pt_old > bpos_max)
14445 /* Zero-width characters produce no glyphs. */
14446 || (!empty_line_p
14447 && (row->reversed_p
14448 ? glyph_after > glyphs_end
14449 : glyph_after < glyphs_end)))
14450 {
14451 cursor = glyph_after;
14452 x = -1;
14453 }
14454 }
14455
14456 compute_x:
14457 if (cursor != NULL)
14458 glyph = cursor;
14459 else if (glyph == glyphs_end
14460 && pos_before == pos_after
14461 && STRINGP ((row->reversed_p
14462 ? row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1
14463 : row->glyphs[TEXT_AREA])->object))
14464 {
14465 /* If all the glyphs of this row came from strings, put the
14466 cursor on the first glyph of the row. This avoids having the
14467 cursor outside of the text area in this very rare and hard
14468 use case. */
14469 glyph =
14470 row->reversed_p
14471 ? row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1
14472 : row->glyphs[TEXT_AREA];
14473 }
14474 if (x < 0)
14475 {
14476 struct glyph *g;
14477
14478 /* Need to compute x that corresponds to GLYPH. */
14479 for (g = row->glyphs[TEXT_AREA], x = row->x; g < glyph; g++)
14480 {
14481 if (g >= row->glyphs[TEXT_AREA] + row->used[TEXT_AREA])
14482 emacs_abort ();
14483 x += g->pixel_width;
14484 }
14485 }
14486
14487 /* ROW could be part of a continued line, which, under bidi
14488 reordering, might have other rows whose start and end charpos
14489 occlude point. Only set w->cursor if we found a better
14490 approximation to the cursor position than we have from previously
14491 examined candidate rows belonging to the same continued line. */
14492 if (/* we already have a candidate row */
14493 w->cursor.vpos >= 0
14494 /* that candidate is not the row we are processing */
14495 && MATRIX_ROW (matrix, w->cursor.vpos) != row
14496 /* Make sure cursor.vpos specifies a row whose start and end
14497 charpos occlude point, and it is valid candidate for being a
14498 cursor-row. This is because some callers of this function
14499 leave cursor.vpos at the row where the cursor was displayed
14500 during the last redisplay cycle. */
14501 && MATRIX_ROW_START_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos)) <= pt_old
14502 && pt_old <= MATRIX_ROW_END_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))
14503 && cursor_row_p (MATRIX_ROW (matrix, w->cursor.vpos)))
14504 {
14505 struct glyph *g1 =
14506 MATRIX_ROW_GLYPH_START (matrix, w->cursor.vpos) + w->cursor.hpos;
14507
14508 /* Don't consider glyphs that are outside TEXT_AREA. */
14509 if (!(row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end))
14510 return 0;
14511 /* Keep the candidate whose buffer position is the closest to
14512 point or has the `cursor' property. */
14513 if (/* previous candidate is a glyph in TEXT_AREA of that row */
14514 w->cursor.hpos >= 0
14515 && w->cursor.hpos < MATRIX_ROW_USED (matrix, w->cursor.vpos)
14516 && ((BUFFERP (g1->object)
14517 && (g1->charpos == pt_old /* an exact match always wins */
14518 || (BUFFERP (glyph->object)
14519 && eabs (g1->charpos - pt_old)
14520 < eabs (glyph->charpos - pt_old))))
14521 /* previous candidate is a glyph from a string that has
14522 a non-nil `cursor' property */
14523 || (STRINGP (g1->object)
14524 && (!NILP (Fget_char_property (make_number (g1->charpos),
14525 Qcursor, g1->object))
14526 /* previous candidate is from the same display
14527 string as this one, and the display string
14528 came from a text property */
14529 || (EQ (g1->object, glyph->object)
14530 && string_from_text_prop)
14531 /* this candidate is from newline and its
14532 position is not an exact match */
14533 || (INTEGERP (glyph->object)
14534 && glyph->charpos != pt_old)))))
14535 return 0;
14536 /* If this candidate gives an exact match, use that. */
14537 if (!((BUFFERP (glyph->object) && glyph->charpos == pt_old)
14538 /* If this candidate is a glyph created for the
14539 terminating newline of a line, and point is on that
14540 newline, it wins because it's an exact match. */
14541 || (!row->continued_p
14542 && INTEGERP (glyph->object)
14543 && glyph->charpos == 0
14544 && pt_old == MATRIX_ROW_END_CHARPOS (row) - 1))
14545 /* Otherwise, keep the candidate that comes from a row
14546 spanning less buffer positions. This may win when one or
14547 both candidate positions are on glyphs that came from
14548 display strings, for which we cannot compare buffer
14549 positions. */
14550 && MATRIX_ROW_END_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))
14551 - MATRIX_ROW_START_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))
14552 < MATRIX_ROW_END_CHARPOS (row) - MATRIX_ROW_START_CHARPOS (row))
14553 return 0;
14554 }
14555 w->cursor.hpos = glyph - row->glyphs[TEXT_AREA];
14556 w->cursor.x = x;
14557 w->cursor.vpos = MATRIX_ROW_VPOS (row, matrix) + dvpos;
14558 w->cursor.y = row->y + dy;
14559
14560 if (w == XWINDOW (selected_window))
14561 {
14562 if (!row->continued_p
14563 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
14564 && row->x == 0)
14565 {
14566 this_line_buffer = XBUFFER (w->buffer);
14567
14568 CHARPOS (this_line_start_pos)
14569 = MATRIX_ROW_START_CHARPOS (row) + delta;
14570 BYTEPOS (this_line_start_pos)
14571 = MATRIX_ROW_START_BYTEPOS (row) + delta_bytes;
14572
14573 CHARPOS (this_line_end_pos)
14574 = Z - (MATRIX_ROW_END_CHARPOS (row) + delta);
14575 BYTEPOS (this_line_end_pos)
14576 = Z_BYTE - (MATRIX_ROW_END_BYTEPOS (row) + delta_bytes);
14577
14578 this_line_y = w->cursor.y;
14579 this_line_pixel_height = row->height;
14580 this_line_vpos = w->cursor.vpos;
14581 this_line_start_x = row->x;
14582 }
14583 else
14584 CHARPOS (this_line_start_pos) = 0;
14585 }
14586
14587 return 1;
14588 }
14589
14590
14591 /* Run window scroll functions, if any, for WINDOW with new window
14592 start STARTP. Sets the window start of WINDOW to that position.
14593
14594 We assume that the window's buffer is really current. */
14595
14596 static inline struct text_pos
14597 run_window_scroll_functions (Lisp_Object window, struct text_pos startp)
14598 {
14599 struct window *w = XWINDOW (window);
14600 SET_MARKER_FROM_TEXT_POS (w->start, startp);
14601
14602 if (current_buffer != XBUFFER (w->buffer))
14603 emacs_abort ();
14604
14605 if (!NILP (Vwindow_scroll_functions))
14606 {
14607 run_hook_with_args_2 (Qwindow_scroll_functions, window,
14608 make_number (CHARPOS (startp)));
14609 SET_TEXT_POS_FROM_MARKER (startp, w->start);
14610 /* In case the hook functions switch buffers. */
14611 set_buffer_internal (XBUFFER (w->buffer));
14612 }
14613
14614 return startp;
14615 }
14616
14617
14618 /* Make sure the line containing the cursor is fully visible.
14619 A value of 1 means there is nothing to be done.
14620 (Either the line is fully visible, or it cannot be made so,
14621 or we cannot tell.)
14622
14623 If FORCE_P is non-zero, return 0 even if partial visible cursor row
14624 is higher than window.
14625
14626 A value of 0 means the caller should do scrolling
14627 as if point had gone off the screen. */
14628
14629 static int
14630 cursor_row_fully_visible_p (struct window *w, int force_p, int current_matrix_p)
14631 {
14632 struct glyph_matrix *matrix;
14633 struct glyph_row *row;
14634 int window_height;
14635
14636 if (!make_cursor_line_fully_visible_p)
14637 return 1;
14638
14639 /* It's not always possible to find the cursor, e.g, when a window
14640 is full of overlay strings. Don't do anything in that case. */
14641 if (w->cursor.vpos < 0)
14642 return 1;
14643
14644 matrix = current_matrix_p ? w->current_matrix : w->desired_matrix;
14645 row = MATRIX_ROW (matrix, w->cursor.vpos);
14646
14647 /* If the cursor row is not partially visible, there's nothing to do. */
14648 if (!MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row))
14649 return 1;
14650
14651 /* If the row the cursor is in is taller than the window's height,
14652 it's not clear what to do, so do nothing. */
14653 window_height = window_box_height (w);
14654 if (row->height >= window_height)
14655 {
14656 if (!force_p || MINI_WINDOW_P (w)
14657 || w->vscroll || w->cursor.vpos == 0)
14658 return 1;
14659 }
14660 return 0;
14661 }
14662
14663
14664 /* Try scrolling PT into view in window WINDOW. JUST_THIS_ONE_P
14665 non-zero means only WINDOW is redisplayed in redisplay_internal.
14666 TEMP_SCROLL_STEP has the same meaning as emacs_scroll_step, and is used
14667 in redisplay_window to bring a partially visible line into view in
14668 the case that only the cursor has moved.
14669
14670 LAST_LINE_MISFIT should be nonzero if we're scrolling because the
14671 last screen line's vertical height extends past the end of the screen.
14672
14673 Value is
14674
14675 1 if scrolling succeeded
14676
14677 0 if scrolling didn't find point.
14678
14679 -1 if new fonts have been loaded so that we must interrupt
14680 redisplay, adjust glyph matrices, and try again. */
14681
14682 enum
14683 {
14684 SCROLLING_SUCCESS,
14685 SCROLLING_FAILED,
14686 SCROLLING_NEED_LARGER_MATRICES
14687 };
14688
14689 /* If scroll-conservatively is more than this, never recenter.
14690
14691 If you change this, don't forget to update the doc string of
14692 `scroll-conservatively' and the Emacs manual. */
14693 #define SCROLL_LIMIT 100
14694
14695 static int
14696 try_scrolling (Lisp_Object window, int just_this_one_p,
14697 ptrdiff_t arg_scroll_conservatively, ptrdiff_t scroll_step,
14698 int temp_scroll_step, int last_line_misfit)
14699 {
14700 struct window *w = XWINDOW (window);
14701 struct frame *f = XFRAME (w->frame);
14702 struct text_pos pos, startp;
14703 struct it it;
14704 int this_scroll_margin, scroll_max, rc, height;
14705 int dy = 0, amount_to_scroll = 0, scroll_down_p = 0;
14706 int extra_scroll_margin_lines = last_line_misfit ? 1 : 0;
14707 Lisp_Object aggressive;
14708 /* We will never try scrolling more than this number of lines. */
14709 int scroll_limit = SCROLL_LIMIT;
14710
14711 #ifdef GLYPH_DEBUG
14712 debug_method_add (w, "try_scrolling");
14713 #endif
14714
14715 SET_TEXT_POS_FROM_MARKER (startp, w->start);
14716
14717 /* Compute scroll margin height in pixels. We scroll when point is
14718 within this distance from the top or bottom of the window. */
14719 if (scroll_margin > 0)
14720 this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4)
14721 * FRAME_LINE_HEIGHT (f);
14722 else
14723 this_scroll_margin = 0;
14724
14725 /* Force arg_scroll_conservatively to have a reasonable value, to
14726 avoid scrolling too far away with slow move_it_* functions. Note
14727 that the user can supply scroll-conservatively equal to
14728 `most-positive-fixnum', which can be larger than INT_MAX. */
14729 if (arg_scroll_conservatively > scroll_limit)
14730 {
14731 arg_scroll_conservatively = scroll_limit + 1;
14732 scroll_max = scroll_limit * FRAME_LINE_HEIGHT (f);
14733 }
14734 else if (scroll_step || arg_scroll_conservatively || temp_scroll_step)
14735 /* Compute how much we should try to scroll maximally to bring
14736 point into view. */
14737 scroll_max = (max (scroll_step,
14738 max (arg_scroll_conservatively, temp_scroll_step))
14739 * FRAME_LINE_HEIGHT (f));
14740 else if (NUMBERP (BVAR (current_buffer, scroll_down_aggressively))
14741 || NUMBERP (BVAR (current_buffer, scroll_up_aggressively)))
14742 /* We're trying to scroll because of aggressive scrolling but no
14743 scroll_step is set. Choose an arbitrary one. */
14744 scroll_max = 10 * FRAME_LINE_HEIGHT (f);
14745 else
14746 scroll_max = 0;
14747
14748 too_near_end:
14749
14750 /* Decide whether to scroll down. */
14751 if (PT > CHARPOS (startp))
14752 {
14753 int scroll_margin_y;
14754
14755 /* Compute the pixel ypos of the scroll margin, then move IT to
14756 either that ypos or PT, whichever comes first. */
14757 start_display (&it, w, startp);
14758 scroll_margin_y = it.last_visible_y - this_scroll_margin
14759 - FRAME_LINE_HEIGHT (f) * extra_scroll_margin_lines;
14760 move_it_to (&it, PT, -1, scroll_margin_y - 1, -1,
14761 (MOVE_TO_POS | MOVE_TO_Y));
14762
14763 if (PT > CHARPOS (it.current.pos))
14764 {
14765 int y0 = line_bottom_y (&it);
14766 /* Compute how many pixels below window bottom to stop searching
14767 for PT. This avoids costly search for PT that is far away if
14768 the user limited scrolling by a small number of lines, but
14769 always finds PT if scroll_conservatively is set to a large
14770 number, such as most-positive-fixnum. */
14771 int slack = max (scroll_max, 10 * FRAME_LINE_HEIGHT (f));
14772 int y_to_move = it.last_visible_y + slack;
14773
14774 /* Compute the distance from the scroll margin to PT or to
14775 the scroll limit, whichever comes first. This should
14776 include the height of the cursor line, to make that line
14777 fully visible. */
14778 move_it_to (&it, PT, -1, y_to_move,
14779 -1, MOVE_TO_POS | MOVE_TO_Y);
14780 dy = line_bottom_y (&it) - y0;
14781
14782 if (dy > scroll_max)
14783 return SCROLLING_FAILED;
14784
14785 if (dy > 0)
14786 scroll_down_p = 1;
14787 }
14788 }
14789
14790 if (scroll_down_p)
14791 {
14792 /* Point is in or below the bottom scroll margin, so move the
14793 window start down. If scrolling conservatively, move it just
14794 enough down to make point visible. If scroll_step is set,
14795 move it down by scroll_step. */
14796 if (arg_scroll_conservatively)
14797 amount_to_scroll
14798 = min (max (dy, FRAME_LINE_HEIGHT (f)),
14799 FRAME_LINE_HEIGHT (f) * arg_scroll_conservatively);
14800 else if (scroll_step || temp_scroll_step)
14801 amount_to_scroll = scroll_max;
14802 else
14803 {
14804 aggressive = BVAR (current_buffer, scroll_up_aggressively);
14805 height = WINDOW_BOX_TEXT_HEIGHT (w);
14806 if (NUMBERP (aggressive))
14807 {
14808 double float_amount = XFLOATINT (aggressive) * height;
14809 amount_to_scroll = float_amount;
14810 if (amount_to_scroll == 0 && float_amount > 0)
14811 amount_to_scroll = 1;
14812 /* Don't let point enter the scroll margin near top of
14813 the window. */
14814 if (amount_to_scroll > height - 2*this_scroll_margin + dy)
14815 amount_to_scroll = height - 2*this_scroll_margin + dy;
14816 }
14817 }
14818
14819 if (amount_to_scroll <= 0)
14820 return SCROLLING_FAILED;
14821
14822 start_display (&it, w, startp);
14823 if (arg_scroll_conservatively <= scroll_limit)
14824 move_it_vertically (&it, amount_to_scroll);
14825 else
14826 {
14827 /* Extra precision for users who set scroll-conservatively
14828 to a large number: make sure the amount we scroll
14829 the window start is never less than amount_to_scroll,
14830 which was computed as distance from window bottom to
14831 point. This matters when lines at window top and lines
14832 below window bottom have different height. */
14833 struct it it1;
14834 void *it1data = NULL;
14835 /* We use a temporary it1 because line_bottom_y can modify
14836 its argument, if it moves one line down; see there. */
14837 int start_y;
14838
14839 SAVE_IT (it1, it, it1data);
14840 start_y = line_bottom_y (&it1);
14841 do {
14842 RESTORE_IT (&it, &it, it1data);
14843 move_it_by_lines (&it, 1);
14844 SAVE_IT (it1, it, it1data);
14845 } while (line_bottom_y (&it1) - start_y < amount_to_scroll);
14846 }
14847
14848 /* If STARTP is unchanged, move it down another screen line. */
14849 if (CHARPOS (it.current.pos) == CHARPOS (startp))
14850 move_it_by_lines (&it, 1);
14851 startp = it.current.pos;
14852 }
14853 else
14854 {
14855 struct text_pos scroll_margin_pos = startp;
14856
14857 /* See if point is inside the scroll margin at the top of the
14858 window. */
14859 if (this_scroll_margin)
14860 {
14861 start_display (&it, w, startp);
14862 move_it_vertically (&it, this_scroll_margin);
14863 scroll_margin_pos = it.current.pos;
14864 }
14865
14866 if (PT < CHARPOS (scroll_margin_pos))
14867 {
14868 /* Point is in the scroll margin at the top of the window or
14869 above what is displayed in the window. */
14870 int y0, y_to_move;
14871
14872 /* Compute the vertical distance from PT to the scroll
14873 margin position. Move as far as scroll_max allows, or
14874 one screenful, or 10 screen lines, whichever is largest.
14875 Give up if distance is greater than scroll_max. */
14876 SET_TEXT_POS (pos, PT, PT_BYTE);
14877 start_display (&it, w, pos);
14878 y0 = it.current_y;
14879 y_to_move = max (it.last_visible_y,
14880 max (scroll_max, 10 * FRAME_LINE_HEIGHT (f)));
14881 move_it_to (&it, CHARPOS (scroll_margin_pos), 0,
14882 y_to_move, -1,
14883 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
14884 dy = it.current_y - y0;
14885 if (dy > scroll_max)
14886 return SCROLLING_FAILED;
14887
14888 /* Compute new window start. */
14889 start_display (&it, w, startp);
14890
14891 if (arg_scroll_conservatively)
14892 amount_to_scroll = max (dy, FRAME_LINE_HEIGHT (f) *
14893 max (scroll_step, temp_scroll_step));
14894 else if (scroll_step || temp_scroll_step)
14895 amount_to_scroll = scroll_max;
14896 else
14897 {
14898 aggressive = BVAR (current_buffer, scroll_down_aggressively);
14899 height = WINDOW_BOX_TEXT_HEIGHT (w);
14900 if (NUMBERP (aggressive))
14901 {
14902 double float_amount = XFLOATINT (aggressive) * height;
14903 amount_to_scroll = float_amount;
14904 if (amount_to_scroll == 0 && float_amount > 0)
14905 amount_to_scroll = 1;
14906 amount_to_scroll -=
14907 this_scroll_margin - dy - FRAME_LINE_HEIGHT (f);
14908 /* Don't let point enter the scroll margin near
14909 bottom of the window. */
14910 if (amount_to_scroll > height - 2*this_scroll_margin + dy)
14911 amount_to_scroll = height - 2*this_scroll_margin + dy;
14912 }
14913 }
14914
14915 if (amount_to_scroll <= 0)
14916 return SCROLLING_FAILED;
14917
14918 move_it_vertically_backward (&it, amount_to_scroll);
14919 startp = it.current.pos;
14920 }
14921 }
14922
14923 /* Run window scroll functions. */
14924 startp = run_window_scroll_functions (window, startp);
14925
14926 /* Display the window. Give up if new fonts are loaded, or if point
14927 doesn't appear. */
14928 if (!try_window (window, startp, 0))
14929 rc = SCROLLING_NEED_LARGER_MATRICES;
14930 else if (w->cursor.vpos < 0)
14931 {
14932 clear_glyph_matrix (w->desired_matrix);
14933 rc = SCROLLING_FAILED;
14934 }
14935 else
14936 {
14937 /* Maybe forget recorded base line for line number display. */
14938 if (!just_this_one_p
14939 || current_buffer->clip_changed
14940 || BEG_UNCHANGED < CHARPOS (startp))
14941 wset_base_line_number (w, Qnil);
14942
14943 /* If cursor ends up on a partially visible line,
14944 treat that as being off the bottom of the screen. */
14945 if (! cursor_row_fully_visible_p (w, extra_scroll_margin_lines <= 1, 0)
14946 /* It's possible that the cursor is on the first line of the
14947 buffer, which is partially obscured due to a vscroll
14948 (Bug#7537). In that case, avoid looping forever . */
14949 && extra_scroll_margin_lines < w->desired_matrix->nrows - 1)
14950 {
14951 clear_glyph_matrix (w->desired_matrix);
14952 ++extra_scroll_margin_lines;
14953 goto too_near_end;
14954 }
14955 rc = SCROLLING_SUCCESS;
14956 }
14957
14958 return rc;
14959 }
14960
14961
14962 /* Compute a suitable window start for window W if display of W starts
14963 on a continuation line. Value is non-zero if a new window start
14964 was computed.
14965
14966 The new window start will be computed, based on W's width, starting
14967 from the start of the continued line. It is the start of the
14968 screen line with the minimum distance from the old start W->start. */
14969
14970 static int
14971 compute_window_start_on_continuation_line (struct window *w)
14972 {
14973 struct text_pos pos, start_pos;
14974 int window_start_changed_p = 0;
14975
14976 SET_TEXT_POS_FROM_MARKER (start_pos, w->start);
14977
14978 /* If window start is on a continuation line... Window start may be
14979 < BEGV in case there's invisible text at the start of the
14980 buffer (M-x rmail, for example). */
14981 if (CHARPOS (start_pos) > BEGV
14982 && FETCH_BYTE (BYTEPOS (start_pos) - 1) != '\n')
14983 {
14984 struct it it;
14985 struct glyph_row *row;
14986
14987 /* Handle the case that the window start is out of range. */
14988 if (CHARPOS (start_pos) < BEGV)
14989 SET_TEXT_POS (start_pos, BEGV, BEGV_BYTE);
14990 else if (CHARPOS (start_pos) > ZV)
14991 SET_TEXT_POS (start_pos, ZV, ZV_BYTE);
14992
14993 /* Find the start of the continued line. This should be fast
14994 because scan_buffer is fast (newline cache). */
14995 row = w->desired_matrix->rows + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0);
14996 init_iterator (&it, w, CHARPOS (start_pos), BYTEPOS (start_pos),
14997 row, DEFAULT_FACE_ID);
14998 reseat_at_previous_visible_line_start (&it);
14999
15000 /* If the line start is "too far" away from the window start,
15001 say it takes too much time to compute a new window start. */
15002 if (CHARPOS (start_pos) - IT_CHARPOS (it)
15003 < WINDOW_TOTAL_LINES (w) * WINDOW_TOTAL_COLS (w))
15004 {
15005 int min_distance, distance;
15006
15007 /* Move forward by display lines to find the new window
15008 start. If window width was enlarged, the new start can
15009 be expected to be > the old start. If window width was
15010 decreased, the new window start will be < the old start.
15011 So, we're looking for the display line start with the
15012 minimum distance from the old window start. */
15013 pos = it.current.pos;
15014 min_distance = INFINITY;
15015 while ((distance = eabs (CHARPOS (start_pos) - IT_CHARPOS (it))),
15016 distance < min_distance)
15017 {
15018 min_distance = distance;
15019 pos = it.current.pos;
15020 move_it_by_lines (&it, 1);
15021 }
15022
15023 /* Set the window start there. */
15024 SET_MARKER_FROM_TEXT_POS (w->start, pos);
15025 window_start_changed_p = 1;
15026 }
15027 }
15028
15029 return window_start_changed_p;
15030 }
15031
15032
15033 /* Try cursor movement in case text has not changed in window WINDOW,
15034 with window start STARTP. Value is
15035
15036 CURSOR_MOVEMENT_SUCCESS if successful
15037
15038 CURSOR_MOVEMENT_CANNOT_BE_USED if this method cannot be used
15039
15040 CURSOR_MOVEMENT_MUST_SCROLL if we know we have to scroll the
15041 display. *SCROLL_STEP is set to 1, under certain circumstances, if
15042 we want to scroll as if scroll-step were set to 1. See the code.
15043
15044 CURSOR_MOVEMENT_NEED_LARGER_MATRICES if we need larger matrices, in
15045 which case we have to abort this redisplay, and adjust matrices
15046 first. */
15047
15048 enum
15049 {
15050 CURSOR_MOVEMENT_SUCCESS,
15051 CURSOR_MOVEMENT_CANNOT_BE_USED,
15052 CURSOR_MOVEMENT_MUST_SCROLL,
15053 CURSOR_MOVEMENT_NEED_LARGER_MATRICES
15054 };
15055
15056 static int
15057 try_cursor_movement (Lisp_Object window, struct text_pos startp, int *scroll_step)
15058 {
15059 struct window *w = XWINDOW (window);
15060 struct frame *f = XFRAME (w->frame);
15061 int rc = CURSOR_MOVEMENT_CANNOT_BE_USED;
15062
15063 #ifdef GLYPH_DEBUG
15064 if (inhibit_try_cursor_movement)
15065 return rc;
15066 #endif
15067
15068 /* Previously, there was a check for Lisp integer in the
15069 if-statement below. Now, this field is converted to
15070 ptrdiff_t, thus zero means invalid position in a buffer. */
15071 eassert (w->last_point > 0);
15072
15073 /* Handle case where text has not changed, only point, and it has
15074 not moved off the frame. */
15075 if (/* Point may be in this window. */
15076 PT >= CHARPOS (startp)
15077 /* Selective display hasn't changed. */
15078 && !current_buffer->clip_changed
15079 /* Function force-mode-line-update is used to force a thorough
15080 redisplay. It sets either windows_or_buffers_changed or
15081 update_mode_lines. So don't take a shortcut here for these
15082 cases. */
15083 && !update_mode_lines
15084 && !windows_or_buffers_changed
15085 && !cursor_type_changed
15086 /* Can't use this case if highlighting a region. When a
15087 region exists, cursor movement has to do more than just
15088 set the cursor. */
15089 && !(!NILP (Vtransient_mark_mode)
15090 && !NILP (BVAR (current_buffer, mark_active)))
15091 && NILP (w->region_showing)
15092 && NILP (Vshow_trailing_whitespace)
15093 /* This code is not used for mini-buffer for the sake of the case
15094 of redisplaying to replace an echo area message; since in
15095 that case the mini-buffer contents per se are usually
15096 unchanged. This code is of no real use in the mini-buffer
15097 since the handling of this_line_start_pos, etc., in redisplay
15098 handles the same cases. */
15099 && !EQ (window, minibuf_window)
15100 /* When splitting windows or for new windows, it happens that
15101 redisplay is called with a nil window_end_vpos or one being
15102 larger than the window. This should really be fixed in
15103 window.c. I don't have this on my list, now, so we do
15104 approximately the same as the old redisplay code. --gerd. */
15105 && INTEGERP (w->window_end_vpos)
15106 && XFASTINT (w->window_end_vpos) < w->current_matrix->nrows
15107 && (FRAME_WINDOW_P (f)
15108 || !overlay_arrow_in_current_buffer_p ()))
15109 {
15110 int this_scroll_margin, top_scroll_margin;
15111 struct glyph_row *row = NULL;
15112
15113 #ifdef GLYPH_DEBUG
15114 debug_method_add (w, "cursor movement");
15115 #endif
15116
15117 /* Scroll if point within this distance from the top or bottom
15118 of the window. This is a pixel value. */
15119 if (scroll_margin > 0)
15120 {
15121 this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
15122 this_scroll_margin *= FRAME_LINE_HEIGHT (f);
15123 }
15124 else
15125 this_scroll_margin = 0;
15126
15127 top_scroll_margin = this_scroll_margin;
15128 if (WINDOW_WANTS_HEADER_LINE_P (w))
15129 top_scroll_margin += CURRENT_HEADER_LINE_HEIGHT (w);
15130
15131 /* Start with the row the cursor was displayed during the last
15132 not paused redisplay. Give up if that row is not valid. */
15133 if (w->last_cursor.vpos < 0
15134 || w->last_cursor.vpos >= w->current_matrix->nrows)
15135 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15136 else
15137 {
15138 row = MATRIX_ROW (w->current_matrix, w->last_cursor.vpos);
15139 if (row->mode_line_p)
15140 ++row;
15141 if (!row->enabled_p)
15142 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15143 }
15144
15145 if (rc == CURSOR_MOVEMENT_CANNOT_BE_USED)
15146 {
15147 int scroll_p = 0, must_scroll = 0;
15148 int last_y = window_text_bottom_y (w) - this_scroll_margin;
15149
15150 if (PT > w->last_point)
15151 {
15152 /* Point has moved forward. */
15153 while (MATRIX_ROW_END_CHARPOS (row) < PT
15154 && MATRIX_ROW_BOTTOM_Y (row) < last_y)
15155 {
15156 eassert (row->enabled_p);
15157 ++row;
15158 }
15159
15160 /* If the end position of a row equals the start
15161 position of the next row, and PT is at that position,
15162 we would rather display cursor in the next line. */
15163 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
15164 && MATRIX_ROW_END_CHARPOS (row) == PT
15165 && row < w->current_matrix->rows
15166 + w->current_matrix->nrows - 1
15167 && MATRIX_ROW_START_CHARPOS (row+1) == PT
15168 && !cursor_row_p (row))
15169 ++row;
15170
15171 /* If within the scroll margin, scroll. Note that
15172 MATRIX_ROW_BOTTOM_Y gives the pixel position at which
15173 the next line would be drawn, and that
15174 this_scroll_margin can be zero. */
15175 if (MATRIX_ROW_BOTTOM_Y (row) > last_y
15176 || PT > MATRIX_ROW_END_CHARPOS (row)
15177 /* Line is completely visible last line in window
15178 and PT is to be set in the next line. */
15179 || (MATRIX_ROW_BOTTOM_Y (row) == last_y
15180 && PT == MATRIX_ROW_END_CHARPOS (row)
15181 && !row->ends_at_zv_p
15182 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
15183 scroll_p = 1;
15184 }
15185 else if (PT < w->last_point)
15186 {
15187 /* Cursor has to be moved backward. Note that PT >=
15188 CHARPOS (startp) because of the outer if-statement. */
15189 while (!row->mode_line_p
15190 && (MATRIX_ROW_START_CHARPOS (row) > PT
15191 || (MATRIX_ROW_START_CHARPOS (row) == PT
15192 && (MATRIX_ROW_STARTS_IN_MIDDLE_OF_CHAR_P (row)
15193 || (/* STARTS_IN_MIDDLE_OF_STRING_P (row) */
15194 row > w->current_matrix->rows
15195 && (row-1)->ends_in_newline_from_string_p))))
15196 && (row->y > top_scroll_margin
15197 || CHARPOS (startp) == BEGV))
15198 {
15199 eassert (row->enabled_p);
15200 --row;
15201 }
15202
15203 /* Consider the following case: Window starts at BEGV,
15204 there is invisible, intangible text at BEGV, so that
15205 display starts at some point START > BEGV. It can
15206 happen that we are called with PT somewhere between
15207 BEGV and START. Try to handle that case. */
15208 if (row < w->current_matrix->rows
15209 || row->mode_line_p)
15210 {
15211 row = w->current_matrix->rows;
15212 if (row->mode_line_p)
15213 ++row;
15214 }
15215
15216 /* Due to newlines in overlay strings, we may have to
15217 skip forward over overlay strings. */
15218 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
15219 && MATRIX_ROW_END_CHARPOS (row) == PT
15220 && !cursor_row_p (row))
15221 ++row;
15222
15223 /* If within the scroll margin, scroll. */
15224 if (row->y < top_scroll_margin
15225 && CHARPOS (startp) != BEGV)
15226 scroll_p = 1;
15227 }
15228 else
15229 {
15230 /* Cursor did not move. So don't scroll even if cursor line
15231 is partially visible, as it was so before. */
15232 rc = CURSOR_MOVEMENT_SUCCESS;
15233 }
15234
15235 if (PT < MATRIX_ROW_START_CHARPOS (row)
15236 || PT > MATRIX_ROW_END_CHARPOS (row))
15237 {
15238 /* if PT is not in the glyph row, give up. */
15239 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15240 must_scroll = 1;
15241 }
15242 else if (rc != CURSOR_MOVEMENT_SUCCESS
15243 && !NILP (BVAR (XBUFFER (w->buffer), bidi_display_reordering)))
15244 {
15245 struct glyph_row *row1;
15246
15247 /* If rows are bidi-reordered and point moved, back up
15248 until we find a row that does not belong to a
15249 continuation line. This is because we must consider
15250 all rows of a continued line as candidates for the
15251 new cursor positioning, since row start and end
15252 positions change non-linearly with vertical position
15253 in such rows. */
15254 /* FIXME: Revisit this when glyph ``spilling'' in
15255 continuation lines' rows is implemented for
15256 bidi-reordered rows. */
15257 for (row1 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
15258 MATRIX_ROW_CONTINUATION_LINE_P (row);
15259 --row)
15260 {
15261 /* If we hit the beginning of the displayed portion
15262 without finding the first row of a continued
15263 line, give up. */
15264 if (row <= row1)
15265 {
15266 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15267 break;
15268 }
15269 eassert (row->enabled_p);
15270 }
15271 }
15272 if (must_scroll)
15273 ;
15274 else if (rc != CURSOR_MOVEMENT_SUCCESS
15275 && MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row)
15276 /* Make sure this isn't a header line by any chance, since
15277 then MATRIX_ROW_PARTIALLY_VISIBLE_P might yield non-zero. */
15278 && !row->mode_line_p
15279 && make_cursor_line_fully_visible_p)
15280 {
15281 if (PT == MATRIX_ROW_END_CHARPOS (row)
15282 && !row->ends_at_zv_p
15283 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
15284 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15285 else if (row->height > window_box_height (w))
15286 {
15287 /* If we end up in a partially visible line, let's
15288 make it fully visible, except when it's taller
15289 than the window, in which case we can't do much
15290 about it. */
15291 *scroll_step = 1;
15292 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15293 }
15294 else
15295 {
15296 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
15297 if (!cursor_row_fully_visible_p (w, 0, 1))
15298 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15299 else
15300 rc = CURSOR_MOVEMENT_SUCCESS;
15301 }
15302 }
15303 else if (scroll_p)
15304 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15305 else if (rc != CURSOR_MOVEMENT_SUCCESS
15306 && !NILP (BVAR (XBUFFER (w->buffer), bidi_display_reordering)))
15307 {
15308 /* With bidi-reordered rows, there could be more than
15309 one candidate row whose start and end positions
15310 occlude point. We need to let set_cursor_from_row
15311 find the best candidate. */
15312 /* FIXME: Revisit this when glyph ``spilling'' in
15313 continuation lines' rows is implemented for
15314 bidi-reordered rows. */
15315 int rv = 0;
15316
15317 do
15318 {
15319 int at_zv_p = 0, exact_match_p = 0;
15320
15321 if (MATRIX_ROW_START_CHARPOS (row) <= PT
15322 && PT <= MATRIX_ROW_END_CHARPOS (row)
15323 && cursor_row_p (row))
15324 rv |= set_cursor_from_row (w, row, w->current_matrix,
15325 0, 0, 0, 0);
15326 /* As soon as we've found the exact match for point,
15327 or the first suitable row whose ends_at_zv_p flag
15328 is set, we are done. */
15329 at_zv_p =
15330 MATRIX_ROW (w->current_matrix, w->cursor.vpos)->ends_at_zv_p;
15331 if (rv && !at_zv_p
15332 && w->cursor.hpos >= 0
15333 && w->cursor.hpos < MATRIX_ROW_USED (w->current_matrix,
15334 w->cursor.vpos))
15335 {
15336 struct glyph_row *candidate =
15337 MATRIX_ROW (w->current_matrix, w->cursor.vpos);
15338 struct glyph *g =
15339 candidate->glyphs[TEXT_AREA] + w->cursor.hpos;
15340 ptrdiff_t endpos = MATRIX_ROW_END_CHARPOS (candidate);
15341
15342 exact_match_p =
15343 (BUFFERP (g->object) && g->charpos == PT)
15344 || (INTEGERP (g->object)
15345 && (g->charpos == PT
15346 || (g->charpos == 0 && endpos - 1 == PT)));
15347 }
15348 if (rv && (at_zv_p || exact_match_p))
15349 {
15350 rc = CURSOR_MOVEMENT_SUCCESS;
15351 break;
15352 }
15353 if (MATRIX_ROW_BOTTOM_Y (row) == last_y)
15354 break;
15355 ++row;
15356 }
15357 while (((MATRIX_ROW_CONTINUATION_LINE_P (row)
15358 || row->continued_p)
15359 && MATRIX_ROW_BOTTOM_Y (row) <= last_y)
15360 || (MATRIX_ROW_START_CHARPOS (row) == PT
15361 && MATRIX_ROW_BOTTOM_Y (row) < last_y));
15362 /* If we didn't find any candidate rows, or exited the
15363 loop before all the candidates were examined, signal
15364 to the caller that this method failed. */
15365 if (rc != CURSOR_MOVEMENT_SUCCESS
15366 && !(rv
15367 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
15368 && !row->continued_p))
15369 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15370 else if (rv)
15371 rc = CURSOR_MOVEMENT_SUCCESS;
15372 }
15373 else
15374 {
15375 do
15376 {
15377 if (set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0))
15378 {
15379 rc = CURSOR_MOVEMENT_SUCCESS;
15380 break;
15381 }
15382 ++row;
15383 }
15384 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
15385 && MATRIX_ROW_START_CHARPOS (row) == PT
15386 && cursor_row_p (row));
15387 }
15388 }
15389 }
15390
15391 return rc;
15392 }
15393
15394 #if !defined USE_TOOLKIT_SCROLL_BARS || defined USE_GTK
15395 static
15396 #endif
15397 void
15398 set_vertical_scroll_bar (struct window *w)
15399 {
15400 ptrdiff_t start, end, whole;
15401
15402 /* Calculate the start and end positions for the current window.
15403 At some point, it would be nice to choose between scrollbars
15404 which reflect the whole buffer size, with special markers
15405 indicating narrowing, and scrollbars which reflect only the
15406 visible region.
15407
15408 Note that mini-buffers sometimes aren't displaying any text. */
15409 if (!MINI_WINDOW_P (w)
15410 || (w == XWINDOW (minibuf_window)
15411 && NILP (echo_area_buffer[0])))
15412 {
15413 struct buffer *buf = XBUFFER (w->buffer);
15414 whole = BUF_ZV (buf) - BUF_BEGV (buf);
15415 start = marker_position (w->start) - BUF_BEGV (buf);
15416 /* I don't think this is guaranteed to be right. For the
15417 moment, we'll pretend it is. */
15418 end = BUF_Z (buf) - XFASTINT (w->window_end_pos) - BUF_BEGV (buf);
15419
15420 if (end < start)
15421 end = start;
15422 if (whole < (end - start))
15423 whole = end - start;
15424 }
15425 else
15426 start = end = whole = 0;
15427
15428 /* Indicate what this scroll bar ought to be displaying now. */
15429 if (FRAME_TERMINAL (XFRAME (w->frame))->set_vertical_scroll_bar_hook)
15430 (*FRAME_TERMINAL (XFRAME (w->frame))->set_vertical_scroll_bar_hook)
15431 (w, end - start, whole, start);
15432 }
15433
15434
15435 /* Redisplay leaf window WINDOW. JUST_THIS_ONE_P non-zero means only
15436 selected_window is redisplayed.
15437
15438 We can return without actually redisplaying the window if
15439 fonts_changed_p. In that case, redisplay_internal will
15440 retry. */
15441
15442 static void
15443 redisplay_window (Lisp_Object window, int just_this_one_p)
15444 {
15445 struct window *w = XWINDOW (window);
15446 struct frame *f = XFRAME (w->frame);
15447 struct buffer *buffer = XBUFFER (w->buffer);
15448 struct buffer *old = current_buffer;
15449 struct text_pos lpoint, opoint, startp;
15450 int update_mode_line;
15451 int tem;
15452 struct it it;
15453 /* Record it now because it's overwritten. */
15454 int current_matrix_up_to_date_p = 0;
15455 int used_current_matrix_p = 0;
15456 /* This is less strict than current_matrix_up_to_date_p.
15457 It indicates that the buffer contents and narrowing are unchanged. */
15458 int buffer_unchanged_p = 0;
15459 int temp_scroll_step = 0;
15460 ptrdiff_t count = SPECPDL_INDEX ();
15461 int rc;
15462 int centering_position = -1;
15463 int last_line_misfit = 0;
15464 ptrdiff_t beg_unchanged, end_unchanged;
15465
15466 SET_TEXT_POS (lpoint, PT, PT_BYTE);
15467 opoint = lpoint;
15468
15469 /* W must be a leaf window here. */
15470 eassert (!NILP (w->buffer));
15471 #ifdef GLYPH_DEBUG
15472 *w->desired_matrix->method = 0;
15473 #endif
15474
15475 restart:
15476 reconsider_clip_changes (w, buffer);
15477
15478 /* Has the mode line to be updated? */
15479 update_mode_line = (w->update_mode_line
15480 || update_mode_lines
15481 || buffer->clip_changed
15482 || buffer->prevent_redisplay_optimizations_p);
15483
15484 if (MINI_WINDOW_P (w))
15485 {
15486 if (w == XWINDOW (echo_area_window)
15487 && !NILP (echo_area_buffer[0]))
15488 {
15489 if (update_mode_line)
15490 /* We may have to update a tty frame's menu bar or a
15491 tool-bar. Example `M-x C-h C-h C-g'. */
15492 goto finish_menu_bars;
15493 else
15494 /* We've already displayed the echo area glyphs in this window. */
15495 goto finish_scroll_bars;
15496 }
15497 else if ((w != XWINDOW (minibuf_window)
15498 || minibuf_level == 0)
15499 /* When buffer is nonempty, redisplay window normally. */
15500 && BUF_Z (XBUFFER (w->buffer)) == BUF_BEG (XBUFFER (w->buffer))
15501 /* Quail displays non-mini buffers in minibuffer window.
15502 In that case, redisplay the window normally. */
15503 && !NILP (Fmemq (w->buffer, Vminibuffer_list)))
15504 {
15505 /* W is a mini-buffer window, but it's not active, so clear
15506 it. */
15507 int yb = window_text_bottom_y (w);
15508 struct glyph_row *row;
15509 int y;
15510
15511 for (y = 0, row = w->desired_matrix->rows;
15512 y < yb;
15513 y += row->height, ++row)
15514 blank_row (w, row, y);
15515 goto finish_scroll_bars;
15516 }
15517
15518 clear_glyph_matrix (w->desired_matrix);
15519 }
15520
15521 /* Otherwise set up data on this window; select its buffer and point
15522 value. */
15523 /* Really select the buffer, for the sake of buffer-local
15524 variables. */
15525 set_buffer_internal_1 (XBUFFER (w->buffer));
15526
15527 current_matrix_up_to_date_p
15528 = (!NILP (w->window_end_valid)
15529 && !current_buffer->clip_changed
15530 && !current_buffer->prevent_redisplay_optimizations_p
15531 && w->last_modified >= MODIFF
15532 && w->last_overlay_modified >= OVERLAY_MODIFF);
15533
15534 /* Run the window-bottom-change-functions
15535 if it is possible that the text on the screen has changed
15536 (either due to modification of the text, or any other reason). */
15537 if (!current_matrix_up_to_date_p
15538 && !NILP (Vwindow_text_change_functions))
15539 {
15540 safe_run_hooks (Qwindow_text_change_functions);
15541 goto restart;
15542 }
15543
15544 beg_unchanged = BEG_UNCHANGED;
15545 end_unchanged = END_UNCHANGED;
15546
15547 SET_TEXT_POS (opoint, PT, PT_BYTE);
15548
15549 specbind (Qinhibit_point_motion_hooks, Qt);
15550
15551 buffer_unchanged_p
15552 = (!NILP (w->window_end_valid)
15553 && !current_buffer->clip_changed
15554 && w->last_modified >= MODIFF
15555 && w->last_overlay_modified >= OVERLAY_MODIFF);
15556
15557 /* When windows_or_buffers_changed is non-zero, we can't rely on
15558 the window end being valid, so set it to nil there. */
15559 if (windows_or_buffers_changed)
15560 {
15561 /* If window starts on a continuation line, maybe adjust the
15562 window start in case the window's width changed. */
15563 if (XMARKER (w->start)->buffer == current_buffer)
15564 compute_window_start_on_continuation_line (w);
15565
15566 wset_window_end_valid (w, Qnil);
15567 }
15568
15569 /* Some sanity checks. */
15570 CHECK_WINDOW_END (w);
15571 if (Z == Z_BYTE && CHARPOS (opoint) != BYTEPOS (opoint))
15572 emacs_abort ();
15573 if (BYTEPOS (opoint) < CHARPOS (opoint))
15574 emacs_abort ();
15575
15576 /* If %c is in mode line, update it if needed. */
15577 if (!NILP (w->column_number_displayed)
15578 /* This alternative quickly identifies a common case
15579 where no change is needed. */
15580 && !(PT == w->last_point
15581 && w->last_modified >= MODIFF
15582 && w->last_overlay_modified >= OVERLAY_MODIFF)
15583 && (XFASTINT (w->column_number_displayed) != current_column ()))
15584 update_mode_line = 1;
15585
15586 /* Count number of windows showing the selected buffer. An indirect
15587 buffer counts as its base buffer. */
15588 if (!just_this_one_p)
15589 {
15590 struct buffer *current_base, *window_base;
15591 current_base = current_buffer;
15592 window_base = XBUFFER (XWINDOW (selected_window)->buffer);
15593 if (current_base->base_buffer)
15594 current_base = current_base->base_buffer;
15595 if (window_base->base_buffer)
15596 window_base = window_base->base_buffer;
15597 if (current_base == window_base)
15598 buffer_shared++;
15599 }
15600
15601 /* Point refers normally to the selected window. For any other
15602 window, set up appropriate value. */
15603 if (!EQ (window, selected_window))
15604 {
15605 ptrdiff_t new_pt = XMARKER (w->pointm)->charpos;
15606 ptrdiff_t new_pt_byte = marker_byte_position (w->pointm);
15607 if (new_pt < BEGV)
15608 {
15609 new_pt = BEGV;
15610 new_pt_byte = BEGV_BYTE;
15611 set_marker_both (w->pointm, Qnil, BEGV, BEGV_BYTE);
15612 }
15613 else if (new_pt > (ZV - 1))
15614 {
15615 new_pt = ZV;
15616 new_pt_byte = ZV_BYTE;
15617 set_marker_both (w->pointm, Qnil, ZV, ZV_BYTE);
15618 }
15619
15620 /* We don't use SET_PT so that the point-motion hooks don't run. */
15621 TEMP_SET_PT_BOTH (new_pt, new_pt_byte);
15622 }
15623
15624 /* If any of the character widths specified in the display table
15625 have changed, invalidate the width run cache. It's true that
15626 this may be a bit late to catch such changes, but the rest of
15627 redisplay goes (non-fatally) haywire when the display table is
15628 changed, so why should we worry about doing any better? */
15629 if (current_buffer->width_run_cache)
15630 {
15631 struct Lisp_Char_Table *disptab = buffer_display_table ();
15632
15633 if (! disptab_matches_widthtab
15634 (disptab, XVECTOR (BVAR (current_buffer, width_table))))
15635 {
15636 invalidate_region_cache (current_buffer,
15637 current_buffer->width_run_cache,
15638 BEG, Z);
15639 recompute_width_table (current_buffer, disptab);
15640 }
15641 }
15642
15643 /* If window-start is screwed up, choose a new one. */
15644 if (XMARKER (w->start)->buffer != current_buffer)
15645 goto recenter;
15646
15647 SET_TEXT_POS_FROM_MARKER (startp, w->start);
15648
15649 /* If someone specified a new starting point but did not insist,
15650 check whether it can be used. */
15651 if (w->optional_new_start
15652 && CHARPOS (startp) >= BEGV
15653 && CHARPOS (startp) <= ZV)
15654 {
15655 w->optional_new_start = 0;
15656 start_display (&it, w, startp);
15657 move_it_to (&it, PT, 0, it.last_visible_y, -1,
15658 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
15659 if (IT_CHARPOS (it) == PT)
15660 w->force_start = 1;
15661 /* IT may overshoot PT if text at PT is invisible. */
15662 else if (IT_CHARPOS (it) > PT && CHARPOS (startp) <= PT)
15663 w->force_start = 1;
15664 }
15665
15666 force_start:
15667
15668 /* Handle case where place to start displaying has been specified,
15669 unless the specified location is outside the accessible range. */
15670 if (w->force_start || w->frozen_window_start_p)
15671 {
15672 /* We set this later on if we have to adjust point. */
15673 int new_vpos = -1;
15674
15675 w->force_start = 0;
15676 w->vscroll = 0;
15677 wset_window_end_valid (w, Qnil);
15678
15679 /* Forget any recorded base line for line number display. */
15680 if (!buffer_unchanged_p)
15681 wset_base_line_number (w, Qnil);
15682
15683 /* Redisplay the mode line. Select the buffer properly for that.
15684 Also, run the hook window-scroll-functions
15685 because we have scrolled. */
15686 /* Note, we do this after clearing force_start because
15687 if there's an error, it is better to forget about force_start
15688 than to get into an infinite loop calling the hook functions
15689 and having them get more errors. */
15690 if (!update_mode_line
15691 || ! NILP (Vwindow_scroll_functions))
15692 {
15693 update_mode_line = 1;
15694 w->update_mode_line = 1;
15695 startp = run_window_scroll_functions (window, startp);
15696 }
15697
15698 w->last_modified = 0;
15699 w->last_overlay_modified = 0;
15700 if (CHARPOS (startp) < BEGV)
15701 SET_TEXT_POS (startp, BEGV, BEGV_BYTE);
15702 else if (CHARPOS (startp) > ZV)
15703 SET_TEXT_POS (startp, ZV, ZV_BYTE);
15704
15705 /* Redisplay, then check if cursor has been set during the
15706 redisplay. Give up if new fonts were loaded. */
15707 /* We used to issue a CHECK_MARGINS argument to try_window here,
15708 but this causes scrolling to fail when point begins inside
15709 the scroll margin (bug#148) -- cyd */
15710 if (!try_window (window, startp, 0))
15711 {
15712 w->force_start = 1;
15713 clear_glyph_matrix (w->desired_matrix);
15714 goto need_larger_matrices;
15715 }
15716
15717 if (w->cursor.vpos < 0 && !w->frozen_window_start_p)
15718 {
15719 /* If point does not appear, try to move point so it does
15720 appear. The desired matrix has been built above, so we
15721 can use it here. */
15722 new_vpos = window_box_height (w) / 2;
15723 }
15724
15725 if (!cursor_row_fully_visible_p (w, 0, 0))
15726 {
15727 /* Point does appear, but on a line partly visible at end of window.
15728 Move it back to a fully-visible line. */
15729 new_vpos = window_box_height (w);
15730 }
15731
15732 /* If we need to move point for either of the above reasons,
15733 now actually do it. */
15734 if (new_vpos >= 0)
15735 {
15736 struct glyph_row *row;
15737
15738 row = MATRIX_FIRST_TEXT_ROW (w->desired_matrix);
15739 while (MATRIX_ROW_BOTTOM_Y (row) < new_vpos)
15740 ++row;
15741
15742 TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row),
15743 MATRIX_ROW_START_BYTEPOS (row));
15744
15745 if (w != XWINDOW (selected_window))
15746 set_marker_both (w->pointm, Qnil, PT, PT_BYTE);
15747 else if (current_buffer == old)
15748 SET_TEXT_POS (lpoint, PT, PT_BYTE);
15749
15750 set_cursor_from_row (w, row, w->desired_matrix, 0, 0, 0, 0);
15751
15752 /* If we are highlighting the region, then we just changed
15753 the region, so redisplay to show it. */
15754 if (!NILP (Vtransient_mark_mode)
15755 && !NILP (BVAR (current_buffer, mark_active)))
15756 {
15757 clear_glyph_matrix (w->desired_matrix);
15758 if (!try_window (window, startp, 0))
15759 goto need_larger_matrices;
15760 }
15761 }
15762
15763 #ifdef GLYPH_DEBUG
15764 debug_method_add (w, "forced window start");
15765 #endif
15766 goto done;
15767 }
15768
15769 /* Handle case where text has not changed, only point, and it has
15770 not moved off the frame, and we are not retrying after hscroll.
15771 (current_matrix_up_to_date_p is nonzero when retrying.) */
15772 if (current_matrix_up_to_date_p
15773 && (rc = try_cursor_movement (window, startp, &temp_scroll_step),
15774 rc != CURSOR_MOVEMENT_CANNOT_BE_USED))
15775 {
15776 switch (rc)
15777 {
15778 case CURSOR_MOVEMENT_SUCCESS:
15779 used_current_matrix_p = 1;
15780 goto done;
15781
15782 case CURSOR_MOVEMENT_MUST_SCROLL:
15783 goto try_to_scroll;
15784
15785 default:
15786 emacs_abort ();
15787 }
15788 }
15789 /* If current starting point was originally the beginning of a line
15790 but no longer is, find a new starting point. */
15791 else if (w->start_at_line_beg
15792 && !(CHARPOS (startp) <= BEGV
15793 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n'))
15794 {
15795 #ifdef GLYPH_DEBUG
15796 debug_method_add (w, "recenter 1");
15797 #endif
15798 goto recenter;
15799 }
15800
15801 /* Try scrolling with try_window_id. Value is > 0 if update has
15802 been done, it is -1 if we know that the same window start will
15803 not work. It is 0 if unsuccessful for some other reason. */
15804 else if ((tem = try_window_id (w)) != 0)
15805 {
15806 #ifdef GLYPH_DEBUG
15807 debug_method_add (w, "try_window_id %d", tem);
15808 #endif
15809
15810 if (fonts_changed_p)
15811 goto need_larger_matrices;
15812 if (tem > 0)
15813 goto done;
15814
15815 /* Otherwise try_window_id has returned -1 which means that we
15816 don't want the alternative below this comment to execute. */
15817 }
15818 else if (CHARPOS (startp) >= BEGV
15819 && CHARPOS (startp) <= ZV
15820 && PT >= CHARPOS (startp)
15821 && (CHARPOS (startp) < ZV
15822 /* Avoid starting at end of buffer. */
15823 || CHARPOS (startp) == BEGV
15824 || (w->last_modified >= MODIFF
15825 && w->last_overlay_modified >= OVERLAY_MODIFF)))
15826 {
15827 int d1, d2, d3, d4, d5, d6;
15828
15829 /* If first window line is a continuation line, and window start
15830 is inside the modified region, but the first change is before
15831 current window start, we must select a new window start.
15832
15833 However, if this is the result of a down-mouse event (e.g. by
15834 extending the mouse-drag-overlay), we don't want to select a
15835 new window start, since that would change the position under
15836 the mouse, resulting in an unwanted mouse-movement rather
15837 than a simple mouse-click. */
15838 if (!w->start_at_line_beg
15839 && NILP (do_mouse_tracking)
15840 && CHARPOS (startp) > BEGV
15841 && CHARPOS (startp) > BEG + beg_unchanged
15842 && CHARPOS (startp) <= Z - end_unchanged
15843 /* Even if w->start_at_line_beg is nil, a new window may
15844 start at a line_beg, since that's how set_buffer_window
15845 sets it. So, we need to check the return value of
15846 compute_window_start_on_continuation_line. (See also
15847 bug#197). */
15848 && XMARKER (w->start)->buffer == current_buffer
15849 && compute_window_start_on_continuation_line (w)
15850 /* It doesn't make sense to force the window start like we
15851 do at label force_start if it is already known that point
15852 will not be visible in the resulting window, because
15853 doing so will move point from its correct position
15854 instead of scrolling the window to bring point into view.
15855 See bug#9324. */
15856 && pos_visible_p (w, PT, &d1, &d2, &d3, &d4, &d5, &d6))
15857 {
15858 w->force_start = 1;
15859 SET_TEXT_POS_FROM_MARKER (startp, w->start);
15860 goto force_start;
15861 }
15862
15863 #ifdef GLYPH_DEBUG
15864 debug_method_add (w, "same window start");
15865 #endif
15866
15867 /* Try to redisplay starting at same place as before.
15868 If point has not moved off frame, accept the results. */
15869 if (!current_matrix_up_to_date_p
15870 /* Don't use try_window_reusing_current_matrix in this case
15871 because a window scroll function can have changed the
15872 buffer. */
15873 || !NILP (Vwindow_scroll_functions)
15874 || MINI_WINDOW_P (w)
15875 || !(used_current_matrix_p
15876 = try_window_reusing_current_matrix (w)))
15877 {
15878 IF_DEBUG (debug_method_add (w, "1"));
15879 if (try_window (window, startp, TRY_WINDOW_CHECK_MARGINS) < 0)
15880 /* -1 means we need to scroll.
15881 0 means we need new matrices, but fonts_changed_p
15882 is set in that case, so we will detect it below. */
15883 goto try_to_scroll;
15884 }
15885
15886 if (fonts_changed_p)
15887 goto need_larger_matrices;
15888
15889 if (w->cursor.vpos >= 0)
15890 {
15891 if (!just_this_one_p
15892 || current_buffer->clip_changed
15893 || BEG_UNCHANGED < CHARPOS (startp))
15894 /* Forget any recorded base line for line number display. */
15895 wset_base_line_number (w, Qnil);
15896
15897 if (!cursor_row_fully_visible_p (w, 1, 0))
15898 {
15899 clear_glyph_matrix (w->desired_matrix);
15900 last_line_misfit = 1;
15901 }
15902 /* Drop through and scroll. */
15903 else
15904 goto done;
15905 }
15906 else
15907 clear_glyph_matrix (w->desired_matrix);
15908 }
15909
15910 try_to_scroll:
15911
15912 w->last_modified = 0;
15913 w->last_overlay_modified = 0;
15914
15915 /* Redisplay the mode line. Select the buffer properly for that. */
15916 if (!update_mode_line)
15917 {
15918 update_mode_line = 1;
15919 w->update_mode_line = 1;
15920 }
15921
15922 /* Try to scroll by specified few lines. */
15923 if ((scroll_conservatively
15924 || emacs_scroll_step
15925 || temp_scroll_step
15926 || NUMBERP (BVAR (current_buffer, scroll_up_aggressively))
15927 || NUMBERP (BVAR (current_buffer, scroll_down_aggressively)))
15928 && CHARPOS (startp) >= BEGV
15929 && CHARPOS (startp) <= ZV)
15930 {
15931 /* The function returns -1 if new fonts were loaded, 1 if
15932 successful, 0 if not successful. */
15933 int ss = try_scrolling (window, just_this_one_p,
15934 scroll_conservatively,
15935 emacs_scroll_step,
15936 temp_scroll_step, last_line_misfit);
15937 switch (ss)
15938 {
15939 case SCROLLING_SUCCESS:
15940 goto done;
15941
15942 case SCROLLING_NEED_LARGER_MATRICES:
15943 goto need_larger_matrices;
15944
15945 case SCROLLING_FAILED:
15946 break;
15947
15948 default:
15949 emacs_abort ();
15950 }
15951 }
15952
15953 /* Finally, just choose a place to start which positions point
15954 according to user preferences. */
15955
15956 recenter:
15957
15958 #ifdef GLYPH_DEBUG
15959 debug_method_add (w, "recenter");
15960 #endif
15961
15962 /* w->vscroll = 0; */
15963
15964 /* Forget any previously recorded base line for line number display. */
15965 if (!buffer_unchanged_p)
15966 wset_base_line_number (w, Qnil);
15967
15968 /* Determine the window start relative to point. */
15969 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
15970 it.current_y = it.last_visible_y;
15971 if (centering_position < 0)
15972 {
15973 int margin =
15974 scroll_margin > 0
15975 ? min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4)
15976 : 0;
15977 ptrdiff_t margin_pos = CHARPOS (startp);
15978 Lisp_Object aggressive;
15979 int scrolling_up;
15980
15981 /* If there is a scroll margin at the top of the window, find
15982 its character position. */
15983 if (margin
15984 /* Cannot call start_display if startp is not in the
15985 accessible region of the buffer. This can happen when we
15986 have just switched to a different buffer and/or changed
15987 its restriction. In that case, startp is initialized to
15988 the character position 1 (BEGV) because we did not yet
15989 have chance to display the buffer even once. */
15990 && BEGV <= CHARPOS (startp) && CHARPOS (startp) <= ZV)
15991 {
15992 struct it it1;
15993 void *it1data = NULL;
15994
15995 SAVE_IT (it1, it, it1data);
15996 start_display (&it1, w, startp);
15997 move_it_vertically (&it1, margin * FRAME_LINE_HEIGHT (f));
15998 margin_pos = IT_CHARPOS (it1);
15999 RESTORE_IT (&it, &it, it1data);
16000 }
16001 scrolling_up = PT > margin_pos;
16002 aggressive =
16003 scrolling_up
16004 ? BVAR (current_buffer, scroll_up_aggressively)
16005 : BVAR (current_buffer, scroll_down_aggressively);
16006
16007 if (!MINI_WINDOW_P (w)
16008 && (scroll_conservatively > SCROLL_LIMIT || NUMBERP (aggressive)))
16009 {
16010 int pt_offset = 0;
16011
16012 /* Setting scroll-conservatively overrides
16013 scroll-*-aggressively. */
16014 if (!scroll_conservatively && NUMBERP (aggressive))
16015 {
16016 double float_amount = XFLOATINT (aggressive);
16017
16018 pt_offset = float_amount * WINDOW_BOX_TEXT_HEIGHT (w);
16019 if (pt_offset == 0 && float_amount > 0)
16020 pt_offset = 1;
16021 if (pt_offset && margin > 0)
16022 margin -= 1;
16023 }
16024 /* Compute how much to move the window start backward from
16025 point so that point will be displayed where the user
16026 wants it. */
16027 if (scrolling_up)
16028 {
16029 centering_position = it.last_visible_y;
16030 if (pt_offset)
16031 centering_position -= pt_offset;
16032 centering_position -=
16033 FRAME_LINE_HEIGHT (f) * (1 + margin + (last_line_misfit != 0))
16034 + WINDOW_HEADER_LINE_HEIGHT (w);
16035 /* Don't let point enter the scroll margin near top of
16036 the window. */
16037 if (centering_position < margin * FRAME_LINE_HEIGHT (f))
16038 centering_position = margin * FRAME_LINE_HEIGHT (f);
16039 }
16040 else
16041 centering_position = margin * FRAME_LINE_HEIGHT (f) + pt_offset;
16042 }
16043 else
16044 /* Set the window start half the height of the window backward
16045 from point. */
16046 centering_position = window_box_height (w) / 2;
16047 }
16048 move_it_vertically_backward (&it, centering_position);
16049
16050 eassert (IT_CHARPOS (it) >= BEGV);
16051
16052 /* The function move_it_vertically_backward may move over more
16053 than the specified y-distance. If it->w is small, e.g. a
16054 mini-buffer window, we may end up in front of the window's
16055 display area. Start displaying at the start of the line
16056 containing PT in this case. */
16057 if (it.current_y <= 0)
16058 {
16059 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
16060 move_it_vertically_backward (&it, 0);
16061 it.current_y = 0;
16062 }
16063
16064 it.current_x = it.hpos = 0;
16065
16066 /* Set the window start position here explicitly, to avoid an
16067 infinite loop in case the functions in window-scroll-functions
16068 get errors. */
16069 set_marker_both (w->start, Qnil, IT_CHARPOS (it), IT_BYTEPOS (it));
16070
16071 /* Run scroll hooks. */
16072 startp = run_window_scroll_functions (window, it.current.pos);
16073
16074 /* Redisplay the window. */
16075 if (!current_matrix_up_to_date_p
16076 || windows_or_buffers_changed
16077 || cursor_type_changed
16078 /* Don't use try_window_reusing_current_matrix in this case
16079 because it can have changed the buffer. */
16080 || !NILP (Vwindow_scroll_functions)
16081 || !just_this_one_p
16082 || MINI_WINDOW_P (w)
16083 || !(used_current_matrix_p
16084 = try_window_reusing_current_matrix (w)))
16085 try_window (window, startp, 0);
16086
16087 /* If new fonts have been loaded (due to fontsets), give up. We
16088 have to start a new redisplay since we need to re-adjust glyph
16089 matrices. */
16090 if (fonts_changed_p)
16091 goto need_larger_matrices;
16092
16093 /* If cursor did not appear assume that the middle of the window is
16094 in the first line of the window. Do it again with the next line.
16095 (Imagine a window of height 100, displaying two lines of height
16096 60. Moving back 50 from it->last_visible_y will end in the first
16097 line.) */
16098 if (w->cursor.vpos < 0)
16099 {
16100 if (!NILP (w->window_end_valid)
16101 && PT >= Z - XFASTINT (w->window_end_pos))
16102 {
16103 clear_glyph_matrix (w->desired_matrix);
16104 move_it_by_lines (&it, 1);
16105 try_window (window, it.current.pos, 0);
16106 }
16107 else if (PT < IT_CHARPOS (it))
16108 {
16109 clear_glyph_matrix (w->desired_matrix);
16110 move_it_by_lines (&it, -1);
16111 try_window (window, it.current.pos, 0);
16112 }
16113 else
16114 {
16115 /* Not much we can do about it. */
16116 }
16117 }
16118
16119 /* Consider the following case: Window starts at BEGV, there is
16120 invisible, intangible text at BEGV, so that display starts at
16121 some point START > BEGV. It can happen that we are called with
16122 PT somewhere between BEGV and START. Try to handle that case. */
16123 if (w->cursor.vpos < 0)
16124 {
16125 struct glyph_row *row = w->current_matrix->rows;
16126 if (row->mode_line_p)
16127 ++row;
16128 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
16129 }
16130
16131 if (!cursor_row_fully_visible_p (w, 0, 0))
16132 {
16133 /* If vscroll is enabled, disable it and try again. */
16134 if (w->vscroll)
16135 {
16136 w->vscroll = 0;
16137 clear_glyph_matrix (w->desired_matrix);
16138 goto recenter;
16139 }
16140
16141 /* Users who set scroll-conservatively to a large number want
16142 point just above/below the scroll margin. If we ended up
16143 with point's row partially visible, move the window start to
16144 make that row fully visible and out of the margin. */
16145 if (scroll_conservatively > SCROLL_LIMIT)
16146 {
16147 int margin =
16148 scroll_margin > 0
16149 ? min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4)
16150 : 0;
16151 int move_down = w->cursor.vpos >= WINDOW_TOTAL_LINES (w) / 2;
16152
16153 move_it_by_lines (&it, move_down ? margin + 1 : -(margin + 1));
16154 clear_glyph_matrix (w->desired_matrix);
16155 if (1 == try_window (window, it.current.pos,
16156 TRY_WINDOW_CHECK_MARGINS))
16157 goto done;
16158 }
16159
16160 /* If centering point failed to make the whole line visible,
16161 put point at the top instead. That has to make the whole line
16162 visible, if it can be done. */
16163 if (centering_position == 0)
16164 goto done;
16165
16166 clear_glyph_matrix (w->desired_matrix);
16167 centering_position = 0;
16168 goto recenter;
16169 }
16170
16171 done:
16172
16173 SET_TEXT_POS_FROM_MARKER (startp, w->start);
16174 w->start_at_line_beg = (CHARPOS (startp) == BEGV
16175 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n');
16176
16177 /* Display the mode line, if we must. */
16178 if ((update_mode_line
16179 /* If window not full width, must redo its mode line
16180 if (a) the window to its side is being redone and
16181 (b) we do a frame-based redisplay. This is a consequence
16182 of how inverted lines are drawn in frame-based redisplay. */
16183 || (!just_this_one_p
16184 && !FRAME_WINDOW_P (f)
16185 && !WINDOW_FULL_WIDTH_P (w))
16186 /* Line number to display. */
16187 || INTEGERP (w->base_line_pos)
16188 /* Column number is displayed and different from the one displayed. */
16189 || (!NILP (w->column_number_displayed)
16190 && (XFASTINT (w->column_number_displayed) != current_column ())))
16191 /* This means that the window has a mode line. */
16192 && (WINDOW_WANTS_MODELINE_P (w)
16193 || WINDOW_WANTS_HEADER_LINE_P (w)))
16194 {
16195 display_mode_lines (w);
16196
16197 /* If mode line height has changed, arrange for a thorough
16198 immediate redisplay using the correct mode line height. */
16199 if (WINDOW_WANTS_MODELINE_P (w)
16200 && CURRENT_MODE_LINE_HEIGHT (w) != DESIRED_MODE_LINE_HEIGHT (w))
16201 {
16202 fonts_changed_p = 1;
16203 MATRIX_MODE_LINE_ROW (w->current_matrix)->height
16204 = DESIRED_MODE_LINE_HEIGHT (w);
16205 }
16206
16207 /* If header line height has changed, arrange for a thorough
16208 immediate redisplay using the correct header line height. */
16209 if (WINDOW_WANTS_HEADER_LINE_P (w)
16210 && CURRENT_HEADER_LINE_HEIGHT (w) != DESIRED_HEADER_LINE_HEIGHT (w))
16211 {
16212 fonts_changed_p = 1;
16213 MATRIX_HEADER_LINE_ROW (w->current_matrix)->height
16214 = DESIRED_HEADER_LINE_HEIGHT (w);
16215 }
16216
16217 if (fonts_changed_p)
16218 goto need_larger_matrices;
16219 }
16220
16221 if (!line_number_displayed
16222 && !BUFFERP (w->base_line_pos))
16223 {
16224 wset_base_line_pos (w, Qnil);
16225 wset_base_line_number (w, Qnil);
16226 }
16227
16228 finish_menu_bars:
16229
16230 /* When we reach a frame's selected window, redo the frame's menu bar. */
16231 if (update_mode_line
16232 && EQ (FRAME_SELECTED_WINDOW (f), window))
16233 {
16234 int redisplay_menu_p = 0;
16235
16236 if (FRAME_WINDOW_P (f))
16237 {
16238 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
16239 || defined (HAVE_NS) || defined (USE_GTK)
16240 redisplay_menu_p = FRAME_EXTERNAL_MENU_BAR (f);
16241 #else
16242 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
16243 #endif
16244 }
16245 else
16246 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
16247
16248 if (redisplay_menu_p)
16249 display_menu_bar (w);
16250
16251 #ifdef HAVE_WINDOW_SYSTEM
16252 if (FRAME_WINDOW_P (f))
16253 {
16254 #if defined (USE_GTK) || defined (HAVE_NS)
16255 if (FRAME_EXTERNAL_TOOL_BAR (f))
16256 redisplay_tool_bar (f);
16257 #else
16258 if (WINDOWP (f->tool_bar_window)
16259 && (FRAME_TOOL_BAR_LINES (f) > 0
16260 || !NILP (Vauto_resize_tool_bars))
16261 && redisplay_tool_bar (f))
16262 ignore_mouse_drag_p = 1;
16263 #endif
16264 }
16265 #endif
16266 }
16267
16268 #ifdef HAVE_WINDOW_SYSTEM
16269 if (FRAME_WINDOW_P (f)
16270 && update_window_fringes (w, (just_this_one_p
16271 || (!used_current_matrix_p && !overlay_arrow_seen)
16272 || w->pseudo_window_p)))
16273 {
16274 update_begin (f);
16275 BLOCK_INPUT;
16276 if (draw_window_fringes (w, 1))
16277 x_draw_vertical_border (w);
16278 UNBLOCK_INPUT;
16279 update_end (f);
16280 }
16281 #endif /* HAVE_WINDOW_SYSTEM */
16282
16283 /* We go to this label, with fonts_changed_p set,
16284 if it is necessary to try again using larger glyph matrices.
16285 We have to redeem the scroll bar even in this case,
16286 because the loop in redisplay_internal expects that. */
16287 need_larger_matrices:
16288 ;
16289 finish_scroll_bars:
16290
16291 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
16292 {
16293 /* Set the thumb's position and size. */
16294 set_vertical_scroll_bar (w);
16295
16296 /* Note that we actually used the scroll bar attached to this
16297 window, so it shouldn't be deleted at the end of redisplay. */
16298 if (FRAME_TERMINAL (f)->redeem_scroll_bar_hook)
16299 (*FRAME_TERMINAL (f)->redeem_scroll_bar_hook) (w);
16300 }
16301
16302 /* Restore current_buffer and value of point in it. The window
16303 update may have changed the buffer, so first make sure `opoint'
16304 is still valid (Bug#6177). */
16305 if (CHARPOS (opoint) < BEGV)
16306 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
16307 else if (CHARPOS (opoint) > ZV)
16308 TEMP_SET_PT_BOTH (Z, Z_BYTE);
16309 else
16310 TEMP_SET_PT_BOTH (CHARPOS (opoint), BYTEPOS (opoint));
16311
16312 set_buffer_internal_1 (old);
16313 /* Avoid an abort in TEMP_SET_PT_BOTH if the buffer has become
16314 shorter. This can be caused by log truncation in *Messages*. */
16315 if (CHARPOS (lpoint) <= ZV)
16316 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
16317
16318 unbind_to (count, Qnil);
16319 }
16320
16321
16322 /* Build the complete desired matrix of WINDOW with a window start
16323 buffer position POS.
16324
16325 Value is 1 if successful. It is zero if fonts were loaded during
16326 redisplay which makes re-adjusting glyph matrices necessary, and -1
16327 if point would appear in the scroll margins.
16328 (We check the former only if TRY_WINDOW_IGNORE_FONTS_CHANGE is
16329 unset in FLAGS, and the latter only if TRY_WINDOW_CHECK_MARGINS is
16330 set in FLAGS.) */
16331
16332 int
16333 try_window (Lisp_Object window, struct text_pos pos, int flags)
16334 {
16335 struct window *w = XWINDOW (window);
16336 struct it it;
16337 struct glyph_row *last_text_row = NULL;
16338 struct frame *f = XFRAME (w->frame);
16339
16340 /* Make POS the new window start. */
16341 set_marker_both (w->start, Qnil, CHARPOS (pos), BYTEPOS (pos));
16342
16343 /* Mark cursor position as unknown. No overlay arrow seen. */
16344 w->cursor.vpos = -1;
16345 overlay_arrow_seen = 0;
16346
16347 /* Initialize iterator and info to start at POS. */
16348 start_display (&it, w, pos);
16349
16350
16351
16352 /* Display all lines of W. */
16353 while (it.current_y < it.last_visible_y)
16354 {
16355 if (display_line (&it))
16356 last_text_row = it.glyph_row - 1;
16357 if (fonts_changed_p && !(flags & TRY_WINDOW_IGNORE_FONTS_CHANGE))
16358 return 0;
16359 }
16360 #ifdef HAVE_XWIDGETS_xxx
16361 //currently this is needed to detect xwidget movement reliably. or probably not.
16362 printf("try_window\n");
16363 return 0;
16364 #endif
16365
16366 /* Don't let the cursor end in the scroll margins. */
16367 if ((flags & TRY_WINDOW_CHECK_MARGINS)
16368 && !MINI_WINDOW_P (w))
16369 {
16370 int this_scroll_margin;
16371
16372 if (scroll_margin > 0)
16373 {
16374 this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
16375 this_scroll_margin *= FRAME_LINE_HEIGHT (f);
16376 }
16377 else
16378 this_scroll_margin = 0;
16379
16380 if ((w->cursor.y >= 0 /* not vscrolled */
16381 && w->cursor.y < this_scroll_margin
16382 && CHARPOS (pos) > BEGV
16383 && IT_CHARPOS (it) < ZV)
16384 /* rms: considering make_cursor_line_fully_visible_p here
16385 seems to give wrong results. We don't want to recenter
16386 when the last line is partly visible, we want to allow
16387 that case to be handled in the usual way. */
16388 || w->cursor.y > it.last_visible_y - this_scroll_margin - 1)
16389 {
16390 w->cursor.vpos = -1;
16391 clear_glyph_matrix (w->desired_matrix);
16392 return -1;
16393 }
16394 }
16395
16396 /* If bottom moved off end of frame, change mode line percentage. */
16397 if (XFASTINT (w->window_end_pos) <= 0
16398 && Z != IT_CHARPOS (it))
16399 w->update_mode_line = 1;
16400
16401 /* Set window_end_pos to the offset of the last character displayed
16402 on the window from the end of current_buffer. Set
16403 window_end_vpos to its row number. */
16404 if (last_text_row)
16405 {
16406 eassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row));
16407 w->window_end_bytepos
16408 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
16409 wset_window_end_pos
16410 (w, make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row)));
16411 wset_window_end_vpos
16412 (w, make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix)));
16413 eassert
16414 (MATRIX_ROW (w->desired_matrix,
16415 XFASTINT (w->window_end_vpos))->displays_text_p);
16416 }
16417 else
16418 {
16419 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
16420 wset_window_end_pos (w, make_number (Z - ZV));
16421 wset_window_end_vpos (w, make_number (0));
16422 }
16423
16424 /* But that is not valid info until redisplay finishes. */
16425 wset_window_end_valid (w, Qnil);
16426 return 1;
16427 }
16428
16429
16430 \f
16431 /************************************************************************
16432 Window redisplay reusing current matrix when buffer has not changed
16433 ************************************************************************/
16434
16435 /* Try redisplay of window W showing an unchanged buffer with a
16436 different window start than the last time it was displayed by
16437 reusing its current matrix. Value is non-zero if successful.
16438 W->start is the new window start. */
16439
16440 static int
16441 try_window_reusing_current_matrix (struct window *w)
16442 {
16443 struct frame *f = XFRAME (w->frame);
16444 struct glyph_row *bottom_row;
16445 struct it it;
16446 struct run run;
16447 struct text_pos start, new_start;
16448 int nrows_scrolled, i;
16449 struct glyph_row *last_text_row;
16450 struct glyph_row *last_reused_text_row;
16451 struct glyph_row *start_row;
16452 int start_vpos, min_y, max_y;
16453
16454 #ifdef GLYPH_DEBUG
16455 if (inhibit_try_window_reusing)
16456 return 0;
16457 #endif
16458
16459 #ifdef HAVE_XWIDGETS_xxx
16460 //currently this is needed to detect xwidget movement reliably. or probably not.
16461 printf("try_window_reusing_current_matrix\n");
16462 return 0;
16463 #endif
16464
16465
16466 if (/* This function doesn't handle terminal frames. */
16467 !FRAME_WINDOW_P (f)
16468 /* Don't try to reuse the display if windows have been split
16469 or such. */
16470 || windows_or_buffers_changed
16471 || cursor_type_changed)
16472 return 0;
16473
16474 /* Can't do this if region may have changed. */
16475 if ((!NILP (Vtransient_mark_mode)
16476 && !NILP (BVAR (current_buffer, mark_active)))
16477 || !NILP (w->region_showing)
16478 || !NILP (Vshow_trailing_whitespace))
16479 return 0;
16480
16481 /* If top-line visibility has changed, give up. */
16482 if (WINDOW_WANTS_HEADER_LINE_P (w)
16483 != MATRIX_HEADER_LINE_ROW (w->current_matrix)->mode_line_p)
16484 return 0;
16485
16486 /* Give up if old or new display is scrolled vertically. We could
16487 make this function handle this, but right now it doesn't. */
16488 start_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
16489 if (w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row))
16490 return 0;
16491
16492 /* The variable new_start now holds the new window start. The old
16493 start `start' can be determined from the current matrix. */
16494 SET_TEXT_POS_FROM_MARKER (new_start, w->start);
16495 start = start_row->minpos;
16496 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
16497
16498 /* Clear the desired matrix for the display below. */
16499 clear_glyph_matrix (w->desired_matrix);
16500
16501 if (CHARPOS (new_start) <= CHARPOS (start))
16502 {
16503 /* Don't use this method if the display starts with an ellipsis
16504 displayed for invisible text. It's not easy to handle that case
16505 below, and it's certainly not worth the effort since this is
16506 not a frequent case. */
16507 if (in_ellipses_for_invisible_text_p (&start_row->start, w))
16508 return 0;
16509
16510 IF_DEBUG (debug_method_add (w, "twu1"));
16511
16512 /* Display up to a row that can be reused. The variable
16513 last_text_row is set to the last row displayed that displays
16514 text. Note that it.vpos == 0 if or if not there is a
16515 header-line; it's not the same as the MATRIX_ROW_VPOS! */
16516 start_display (&it, w, new_start);
16517 w->cursor.vpos = -1;
16518 last_text_row = last_reused_text_row = NULL;
16519
16520 while (it.current_y < it.last_visible_y
16521 && !fonts_changed_p)
16522 {
16523 /* If we have reached into the characters in the START row,
16524 that means the line boundaries have changed. So we
16525 can't start copying with the row START. Maybe it will
16526 work to start copying with the following row. */
16527 while (IT_CHARPOS (it) > CHARPOS (start))
16528 {
16529 /* Advance to the next row as the "start". */
16530 start_row++;
16531 start = start_row->minpos;
16532 /* If there are no more rows to try, or just one, give up. */
16533 if (start_row == MATRIX_MODE_LINE_ROW (w->current_matrix) - 1
16534 || w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row)
16535 || CHARPOS (start) == ZV)
16536 {
16537 clear_glyph_matrix (w->desired_matrix);
16538 return 0;
16539 }
16540
16541 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
16542 }
16543 /* If we have reached alignment, we can copy the rest of the
16544 rows. */
16545 if (IT_CHARPOS (it) == CHARPOS (start)
16546 /* Don't accept "alignment" inside a display vector,
16547 since start_row could have started in the middle of
16548 that same display vector (thus their character
16549 positions match), and we have no way of telling if
16550 that is the case. */
16551 && it.current.dpvec_index < 0)
16552 break;
16553
16554 if (display_line (&it))
16555 last_text_row = it.glyph_row - 1;
16556
16557 }
16558
16559 /* A value of current_y < last_visible_y means that we stopped
16560 at the previous window start, which in turn means that we
16561 have at least one reusable row. */
16562 if (it.current_y < it.last_visible_y)
16563 {
16564 struct glyph_row *row;
16565
16566 /* IT.vpos always starts from 0; it counts text lines. */
16567 nrows_scrolled = it.vpos - (start_row - MATRIX_FIRST_TEXT_ROW (w->current_matrix));
16568
16569 /* Find PT if not already found in the lines displayed. */
16570 if (w->cursor.vpos < 0)
16571 {
16572 int dy = it.current_y - start_row->y;
16573
16574 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
16575 row = row_containing_pos (w, PT, row, NULL, dy);
16576 if (row)
16577 set_cursor_from_row (w, row, w->current_matrix, 0, 0,
16578 dy, nrows_scrolled);
16579 else
16580 {
16581 clear_glyph_matrix (w->desired_matrix);
16582 return 0;
16583 }
16584 }
16585
16586 /* Scroll the display. Do it before the current matrix is
16587 changed. The problem here is that update has not yet
16588 run, i.e. part of the current matrix is not up to date.
16589 scroll_run_hook will clear the cursor, and use the
16590 current matrix to get the height of the row the cursor is
16591 in. */
16592 run.current_y = start_row->y;
16593 run.desired_y = it.current_y;
16594 run.height = it.last_visible_y - it.current_y;
16595
16596 if (run.height > 0 && run.current_y != run.desired_y)
16597 {
16598 update_begin (f);
16599 FRAME_RIF (f)->update_window_begin_hook (w);
16600 FRAME_RIF (f)->clear_window_mouse_face (w);
16601 FRAME_RIF (f)->scroll_run_hook (w, &run);
16602 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
16603 update_end (f);
16604 }
16605
16606 /* Shift current matrix down by nrows_scrolled lines. */
16607 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
16608 rotate_matrix (w->current_matrix,
16609 start_vpos,
16610 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
16611 nrows_scrolled);
16612
16613 /* Disable lines that must be updated. */
16614 for (i = 0; i < nrows_scrolled; ++i)
16615 (start_row + i)->enabled_p = 0;
16616
16617 /* Re-compute Y positions. */
16618 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
16619 max_y = it.last_visible_y;
16620 for (row = start_row + nrows_scrolled;
16621 row < bottom_row;
16622 ++row)
16623 {
16624 row->y = it.current_y;
16625 row->visible_height = row->height;
16626
16627 if (row->y < min_y)
16628 row->visible_height -= min_y - row->y;
16629 if (row->y + row->height > max_y)
16630 row->visible_height -= row->y + row->height - max_y;
16631 if (row->fringe_bitmap_periodic_p)
16632 row->redraw_fringe_bitmaps_p = 1;
16633
16634 it.current_y += row->height;
16635
16636 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
16637 last_reused_text_row = row;
16638 if (MATRIX_ROW_BOTTOM_Y (row) >= it.last_visible_y)
16639 break;
16640 }
16641
16642 /* Disable lines in the current matrix which are now
16643 below the window. */
16644 for (++row; row < bottom_row; ++row)
16645 row->enabled_p = row->mode_line_p = 0;
16646 }
16647
16648 /* Update window_end_pos etc.; last_reused_text_row is the last
16649 reused row from the current matrix containing text, if any.
16650 The value of last_text_row is the last displayed line
16651 containing text. */
16652 if (last_reused_text_row)
16653 {
16654 w->window_end_bytepos
16655 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_reused_text_row);
16656 wset_window_end_pos
16657 (w, make_number (Z
16658 - MATRIX_ROW_END_CHARPOS (last_reused_text_row)));
16659 wset_window_end_vpos
16660 (w, make_number (MATRIX_ROW_VPOS (last_reused_text_row,
16661 w->current_matrix)));
16662 }
16663 else if (last_text_row)
16664 {
16665 w->window_end_bytepos
16666 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
16667 wset_window_end_pos
16668 (w, make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row)));
16669 wset_window_end_vpos
16670 (w, make_number (MATRIX_ROW_VPOS (last_text_row,
16671 w->desired_matrix)));
16672 }
16673 else
16674 {
16675 /* This window must be completely empty. */
16676 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
16677 wset_window_end_pos (w, make_number (Z - ZV));
16678 wset_window_end_vpos (w, make_number (0));
16679 }
16680 wset_window_end_valid (w, Qnil);
16681
16682 /* Update hint: don't try scrolling again in update_window. */
16683 w->desired_matrix->no_scrolling_p = 1;
16684
16685 #ifdef GLYPH_DEBUG
16686 debug_method_add (w, "try_window_reusing_current_matrix 1");
16687 #endif
16688 return 1;
16689 }
16690 else if (CHARPOS (new_start) > CHARPOS (start))
16691 {
16692 struct glyph_row *pt_row, *row;
16693 struct glyph_row *first_reusable_row;
16694 struct glyph_row *first_row_to_display;
16695 int dy;
16696 int yb = window_text_bottom_y (w);
16697
16698 /* Find the row starting at new_start, if there is one. Don't
16699 reuse a partially visible line at the end. */
16700 first_reusable_row = start_row;
16701 while (first_reusable_row->enabled_p
16702 && MATRIX_ROW_BOTTOM_Y (first_reusable_row) < yb
16703 && (MATRIX_ROW_START_CHARPOS (first_reusable_row)
16704 < CHARPOS (new_start)))
16705 ++first_reusable_row;
16706
16707 /* Give up if there is no row to reuse. */
16708 if (MATRIX_ROW_BOTTOM_Y (first_reusable_row) >= yb
16709 || !first_reusable_row->enabled_p
16710 || (MATRIX_ROW_START_CHARPOS (first_reusable_row)
16711 != CHARPOS (new_start)))
16712 return 0;
16713
16714 /* We can reuse fully visible rows beginning with
16715 first_reusable_row to the end of the window. Set
16716 first_row_to_display to the first row that cannot be reused.
16717 Set pt_row to the row containing point, if there is any. */
16718 pt_row = NULL;
16719 for (first_row_to_display = first_reusable_row;
16720 MATRIX_ROW_BOTTOM_Y (first_row_to_display) < yb;
16721 ++first_row_to_display)
16722 {
16723 if (PT >= MATRIX_ROW_START_CHARPOS (first_row_to_display)
16724 && (PT < MATRIX_ROW_END_CHARPOS (first_row_to_display)
16725 || (PT == MATRIX_ROW_END_CHARPOS (first_row_to_display)
16726 && first_row_to_display->ends_at_zv_p
16727 && pt_row == NULL)))
16728 pt_row = first_row_to_display;
16729 }
16730
16731 /* Start displaying at the start of first_row_to_display. */
16732 eassert (first_row_to_display->y < yb);
16733 init_to_row_start (&it, w, first_row_to_display);
16734
16735 nrows_scrolled = (MATRIX_ROW_VPOS (first_reusable_row, w->current_matrix)
16736 - start_vpos);
16737 it.vpos = (MATRIX_ROW_VPOS (first_row_to_display, w->current_matrix)
16738 - nrows_scrolled);
16739 it.current_y = (first_row_to_display->y - first_reusable_row->y
16740 + WINDOW_HEADER_LINE_HEIGHT (w));
16741
16742 /* Display lines beginning with first_row_to_display in the
16743 desired matrix. Set last_text_row to the last row displayed
16744 that displays text. */
16745 it.glyph_row = MATRIX_ROW (w->desired_matrix, it.vpos);
16746 if (pt_row == NULL)
16747 w->cursor.vpos = -1;
16748 last_text_row = NULL;
16749 while (it.current_y < it.last_visible_y && !fonts_changed_p)
16750 if (display_line (&it))
16751 last_text_row = it.glyph_row - 1;
16752
16753 /* If point is in a reused row, adjust y and vpos of the cursor
16754 position. */
16755 if (pt_row)
16756 {
16757 w->cursor.vpos -= nrows_scrolled;
16758 w->cursor.y -= first_reusable_row->y - start_row->y;
16759 }
16760
16761 /* Give up if point isn't in a row displayed or reused. (This
16762 also handles the case where w->cursor.vpos < nrows_scrolled
16763 after the calls to display_line, which can happen with scroll
16764 margins. See bug#1295.) */
16765 if (w->cursor.vpos < 0)
16766 {
16767 clear_glyph_matrix (w->desired_matrix);
16768 return 0;
16769 }
16770
16771 /* Scroll the display. */
16772 run.current_y = first_reusable_row->y;
16773 run.desired_y = WINDOW_HEADER_LINE_HEIGHT (w);
16774 run.height = it.last_visible_y - run.current_y;
16775 dy = run.current_y - run.desired_y;
16776
16777 if (run.height)
16778 {
16779 update_begin (f);
16780 FRAME_RIF (f)->update_window_begin_hook (w);
16781 FRAME_RIF (f)->clear_window_mouse_face (w);
16782 FRAME_RIF (f)->scroll_run_hook (w, &run);
16783 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
16784 update_end (f);
16785 }
16786
16787 /* Adjust Y positions of reused rows. */
16788 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
16789 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
16790 max_y = it.last_visible_y;
16791 for (row = first_reusable_row; row < first_row_to_display; ++row)
16792 {
16793 row->y -= dy;
16794 row->visible_height = row->height;
16795 if (row->y < min_y)
16796 row->visible_height -= min_y - row->y;
16797 if (row->y + row->height > max_y)
16798 row->visible_height -= row->y + row->height - max_y;
16799 if (row->fringe_bitmap_periodic_p)
16800 row->redraw_fringe_bitmaps_p = 1;
16801 }
16802
16803 /* Scroll the current matrix. */
16804 eassert (nrows_scrolled > 0);
16805 rotate_matrix (w->current_matrix,
16806 start_vpos,
16807 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
16808 -nrows_scrolled);
16809
16810 /* Disable rows not reused. */
16811 for (row -= nrows_scrolled; row < bottom_row; ++row)
16812 row->enabled_p = 0;
16813
16814 /* Point may have moved to a different line, so we cannot assume that
16815 the previous cursor position is valid; locate the correct row. */
16816 if (pt_row)
16817 {
16818 for (row = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
16819 row < bottom_row
16820 && PT >= MATRIX_ROW_END_CHARPOS (row)
16821 && !row->ends_at_zv_p;
16822 row++)
16823 {
16824 w->cursor.vpos++;
16825 w->cursor.y = row->y;
16826 }
16827 if (row < bottom_row)
16828 {
16829 struct glyph *glyph = row->glyphs[TEXT_AREA] + w->cursor.hpos;
16830 struct glyph *end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
16831
16832 /* Can't use this optimization with bidi-reordered glyph
16833 rows, unless cursor is already at point. */
16834 if (!NILP (BVAR (XBUFFER (w->buffer), bidi_display_reordering)))
16835 {
16836 if (!(w->cursor.hpos >= 0
16837 && w->cursor.hpos < row->used[TEXT_AREA]
16838 && BUFFERP (glyph->object)
16839 && glyph->charpos == PT))
16840 return 0;
16841 }
16842 else
16843 for (; glyph < end
16844 && (!BUFFERP (glyph->object)
16845 || glyph->charpos < PT);
16846 glyph++)
16847 {
16848 w->cursor.hpos++;
16849 w->cursor.x += glyph->pixel_width;
16850 }
16851 }
16852 }
16853
16854 /* Adjust window end. A null value of last_text_row means that
16855 the window end is in reused rows which in turn means that
16856 only its vpos can have changed. */
16857 if (last_text_row)
16858 {
16859 w->window_end_bytepos
16860 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
16861 wset_window_end_pos
16862 (w, make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row)));
16863 wset_window_end_vpos
16864 (w, make_number (MATRIX_ROW_VPOS (last_text_row,
16865 w->desired_matrix)));
16866 }
16867 else
16868 {
16869 wset_window_end_vpos
16870 (w, make_number (XFASTINT (w->window_end_vpos) - nrows_scrolled));
16871 }
16872
16873 wset_window_end_valid (w, Qnil);
16874 w->desired_matrix->no_scrolling_p = 1;
16875
16876 #ifdef GLYPH_DEBUG
16877 debug_method_add (w, "try_window_reusing_current_matrix 2");
16878 #endif
16879 return 1;
16880 }
16881
16882 return 0;
16883 }
16884
16885
16886 \f
16887 /************************************************************************
16888 Window redisplay reusing current matrix when buffer has changed
16889 ************************************************************************/
16890
16891 static struct glyph_row *find_last_unchanged_at_beg_row (struct window *);
16892 static struct glyph_row *find_first_unchanged_at_end_row (struct window *,
16893 ptrdiff_t *, ptrdiff_t *);
16894 static struct glyph_row *
16895 find_last_row_displaying_text (struct glyph_matrix *, struct it *,
16896 struct glyph_row *);
16897
16898
16899 /* Return the last row in MATRIX displaying text. If row START is
16900 non-null, start searching with that row. IT gives the dimensions
16901 of the display. Value is null if matrix is empty; otherwise it is
16902 a pointer to the row found. */
16903
16904 static struct glyph_row *
16905 find_last_row_displaying_text (struct glyph_matrix *matrix, struct it *it,
16906 struct glyph_row *start)
16907 {
16908 struct glyph_row *row, *row_found;
16909
16910 /* Set row_found to the last row in IT->w's current matrix
16911 displaying text. The loop looks funny but think of partially
16912 visible lines. */
16913 row_found = NULL;
16914 row = start ? start : MATRIX_FIRST_TEXT_ROW (matrix);
16915 while (MATRIX_ROW_DISPLAYS_TEXT_P (row))
16916 {
16917 eassert (row->enabled_p);
16918 row_found = row;
16919 if (MATRIX_ROW_BOTTOM_Y (row) >= it->last_visible_y)
16920 break;
16921 ++row;
16922 }
16923
16924 return row_found;
16925 }
16926
16927
16928 /* Return the last row in the current matrix of W that is not affected
16929 by changes at the start of current_buffer that occurred since W's
16930 current matrix was built. Value is null if no such row exists.
16931
16932 BEG_UNCHANGED us the number of characters unchanged at the start of
16933 current_buffer. BEG + BEG_UNCHANGED is the buffer position of the
16934 first changed character in current_buffer. Characters at positions <
16935 BEG + BEG_UNCHANGED are at the same buffer positions as they were
16936 when the current matrix was built. */
16937
16938 static struct glyph_row *
16939 find_last_unchanged_at_beg_row (struct window *w)
16940 {
16941 ptrdiff_t first_changed_pos = BEG + BEG_UNCHANGED;
16942 struct glyph_row *row;
16943 struct glyph_row *row_found = NULL;
16944 int yb = window_text_bottom_y (w);
16945
16946 /* Find the last row displaying unchanged text. */
16947 for (row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
16948 MATRIX_ROW_DISPLAYS_TEXT_P (row)
16949 && MATRIX_ROW_START_CHARPOS (row) < first_changed_pos;
16950 ++row)
16951 {
16952 if (/* If row ends before first_changed_pos, it is unchanged,
16953 except in some case. */
16954 MATRIX_ROW_END_CHARPOS (row) <= first_changed_pos
16955 /* When row ends in ZV and we write at ZV it is not
16956 unchanged. */
16957 && !row->ends_at_zv_p
16958 /* When first_changed_pos is the end of a continued line,
16959 row is not unchanged because it may be no longer
16960 continued. */
16961 && !(MATRIX_ROW_END_CHARPOS (row) == first_changed_pos
16962 && (row->continued_p
16963 || row->exact_window_width_line_p))
16964 /* If ROW->end is beyond ZV, then ROW->end is outdated and
16965 needs to be recomputed, so don't consider this row as
16966 unchanged. This happens when the last line was
16967 bidi-reordered and was killed immediately before this
16968 redisplay cycle. In that case, ROW->end stores the
16969 buffer position of the first visual-order character of
16970 the killed text, which is now beyond ZV. */
16971 && CHARPOS (row->end.pos) <= ZV)
16972 row_found = row;
16973
16974 /* Stop if last visible row. */
16975 if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
16976 break;
16977 }
16978
16979 return row_found;
16980 }
16981
16982
16983 /* Find the first glyph row in the current matrix of W that is not
16984 affected by changes at the end of current_buffer since the
16985 time W's current matrix was built.
16986
16987 Return in *DELTA the number of chars by which buffer positions in
16988 unchanged text at the end of current_buffer must be adjusted.
16989
16990 Return in *DELTA_BYTES the corresponding number of bytes.
16991
16992 Value is null if no such row exists, i.e. all rows are affected by
16993 changes. */
16994
16995 static struct glyph_row *
16996 find_first_unchanged_at_end_row (struct window *w,
16997 ptrdiff_t *delta, ptrdiff_t *delta_bytes)
16998 {
16999 struct glyph_row *row;
17000 struct glyph_row *row_found = NULL;
17001
17002 *delta = *delta_bytes = 0;
17003
17004 /* Display must not have been paused, otherwise the current matrix
17005 is not up to date. */
17006 eassert (!NILP (w->window_end_valid));
17007
17008 /* A value of window_end_pos >= END_UNCHANGED means that the window
17009 end is in the range of changed text. If so, there is no
17010 unchanged row at the end of W's current matrix. */
17011 if (XFASTINT (w->window_end_pos) >= END_UNCHANGED)
17012 return NULL;
17013
17014 /* Set row to the last row in W's current matrix displaying text. */
17015 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
17016
17017 /* If matrix is entirely empty, no unchanged row exists. */
17018 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
17019 {
17020 /* The value of row is the last glyph row in the matrix having a
17021 meaningful buffer position in it. The end position of row
17022 corresponds to window_end_pos. This allows us to translate
17023 buffer positions in the current matrix to current buffer
17024 positions for characters not in changed text. */
17025 ptrdiff_t Z_old =
17026 MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
17027 ptrdiff_t Z_BYTE_old =
17028 MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
17029 ptrdiff_t last_unchanged_pos, last_unchanged_pos_old;
17030 struct glyph_row *first_text_row
17031 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
17032
17033 *delta = Z - Z_old;
17034 *delta_bytes = Z_BYTE - Z_BYTE_old;
17035
17036 /* Set last_unchanged_pos to the buffer position of the last
17037 character in the buffer that has not been changed. Z is the
17038 index + 1 of the last character in current_buffer, i.e. by
17039 subtracting END_UNCHANGED we get the index of the last
17040 unchanged character, and we have to add BEG to get its buffer
17041 position. */
17042 last_unchanged_pos = Z - END_UNCHANGED + BEG;
17043 last_unchanged_pos_old = last_unchanged_pos - *delta;
17044
17045 /* Search backward from ROW for a row displaying a line that
17046 starts at a minimum position >= last_unchanged_pos_old. */
17047 for (; row > first_text_row; --row)
17048 {
17049 /* This used to abort, but it can happen.
17050 It is ok to just stop the search instead here. KFS. */
17051 if (!row->enabled_p || !MATRIX_ROW_DISPLAYS_TEXT_P (row))
17052 break;
17053
17054 if (MATRIX_ROW_START_CHARPOS (row) >= last_unchanged_pos_old)
17055 row_found = row;
17056 }
17057 }
17058
17059 eassert (!row_found || MATRIX_ROW_DISPLAYS_TEXT_P (row_found));
17060
17061 return row_found;
17062 }
17063
17064
17065 /* Make sure that glyph rows in the current matrix of window W
17066 reference the same glyph memory as corresponding rows in the
17067 frame's frame matrix. This function is called after scrolling W's
17068 current matrix on a terminal frame in try_window_id and
17069 try_window_reusing_current_matrix. */
17070
17071 static void
17072 sync_frame_with_window_matrix_rows (struct window *w)
17073 {
17074 struct frame *f = XFRAME (w->frame);
17075 struct glyph_row *window_row, *window_row_end, *frame_row;
17076
17077 /* Preconditions: W must be a leaf window and full-width. Its frame
17078 must have a frame matrix. */
17079 eassert (NILP (w->hchild) && NILP (w->vchild));
17080 eassert (WINDOW_FULL_WIDTH_P (w));
17081 eassert (!FRAME_WINDOW_P (f));
17082
17083 /* If W is a full-width window, glyph pointers in W's current matrix
17084 have, by definition, to be the same as glyph pointers in the
17085 corresponding frame matrix. Note that frame matrices have no
17086 marginal areas (see build_frame_matrix). */
17087 window_row = w->current_matrix->rows;
17088 window_row_end = window_row + w->current_matrix->nrows;
17089 frame_row = f->current_matrix->rows + WINDOW_TOP_EDGE_LINE (w);
17090 while (window_row < window_row_end)
17091 {
17092 struct glyph *start = window_row->glyphs[LEFT_MARGIN_AREA];
17093 struct glyph *end = window_row->glyphs[LAST_AREA];
17094
17095 frame_row->glyphs[LEFT_MARGIN_AREA] = start;
17096 frame_row->glyphs[TEXT_AREA] = start;
17097 frame_row->glyphs[RIGHT_MARGIN_AREA] = end;
17098 frame_row->glyphs[LAST_AREA] = end;
17099
17100 /* Disable frame rows whose corresponding window rows have
17101 been disabled in try_window_id. */
17102 if (!window_row->enabled_p)
17103 frame_row->enabled_p = 0;
17104
17105 ++window_row, ++frame_row;
17106 }
17107 }
17108
17109
17110 /* Find the glyph row in window W containing CHARPOS. Consider all
17111 rows between START and END (not inclusive). END null means search
17112 all rows to the end of the display area of W. Value is the row
17113 containing CHARPOS or null. */
17114
17115 struct glyph_row *
17116 row_containing_pos (struct window *w, ptrdiff_t charpos,
17117 struct glyph_row *start, struct glyph_row *end, int dy)
17118 {
17119 struct glyph_row *row = start;
17120 struct glyph_row *best_row = NULL;
17121 ptrdiff_t mindif = BUF_ZV (XBUFFER (w->buffer)) + 1;
17122 int last_y;
17123
17124 /* If we happen to start on a header-line, skip that. */
17125 if (row->mode_line_p)
17126 ++row;
17127
17128 if ((end && row >= end) || !row->enabled_p)
17129 return NULL;
17130
17131 last_y = window_text_bottom_y (w) - dy;
17132
17133 while (1)
17134 {
17135 /* Give up if we have gone too far. */
17136 if (end && row >= end)
17137 return NULL;
17138 /* This formerly returned if they were equal.
17139 I think that both quantities are of a "last plus one" type;
17140 if so, when they are equal, the row is within the screen. -- rms. */
17141 if (MATRIX_ROW_BOTTOM_Y (row) > last_y)
17142 return NULL;
17143
17144 /* If it is in this row, return this row. */
17145 if (! (MATRIX_ROW_END_CHARPOS (row) < charpos
17146 || (MATRIX_ROW_END_CHARPOS (row) == charpos
17147 /* The end position of a row equals the start
17148 position of the next row. If CHARPOS is there, we
17149 would rather display it in the next line, except
17150 when this line ends in ZV. */
17151 && !row->ends_at_zv_p
17152 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
17153 && charpos >= MATRIX_ROW_START_CHARPOS (row))
17154 {
17155 struct glyph *g;
17156
17157 if (NILP (BVAR (XBUFFER (w->buffer), bidi_display_reordering))
17158 || (!best_row && !row->continued_p))
17159 return row;
17160 /* In bidi-reordered rows, there could be several rows
17161 occluding point, all of them belonging to the same
17162 continued line. We need to find the row which fits
17163 CHARPOS the best. */
17164 for (g = row->glyphs[TEXT_AREA];
17165 g < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
17166 g++)
17167 {
17168 if (!STRINGP (g->object))
17169 {
17170 if (g->charpos > 0 && eabs (g->charpos - charpos) < mindif)
17171 {
17172 mindif = eabs (g->charpos - charpos);
17173 best_row = row;
17174 /* Exact match always wins. */
17175 if (mindif == 0)
17176 return best_row;
17177 }
17178 }
17179 }
17180 }
17181 else if (best_row && !row->continued_p)
17182 return best_row;
17183 ++row;
17184 }
17185 }
17186
17187
17188 /* Try to redisplay window W by reusing its existing display. W's
17189 current matrix must be up to date when this function is called,
17190 i.e. window_end_valid must not be nil.
17191
17192 Value is
17193
17194 1 if display has been updated
17195 0 if otherwise unsuccessful
17196 -1 if redisplay with same window start is known not to succeed
17197
17198 The following steps are performed:
17199
17200 1. Find the last row in the current matrix of W that is not
17201 affected by changes at the start of current_buffer. If no such row
17202 is found, give up.
17203
17204 2. Find the first row in W's current matrix that is not affected by
17205 changes at the end of current_buffer. Maybe there is no such row.
17206
17207 3. Display lines beginning with the row + 1 found in step 1 to the
17208 row found in step 2 or, if step 2 didn't find a row, to the end of
17209 the window.
17210
17211 4. If cursor is not known to appear on the window, give up.
17212
17213 5. If display stopped at the row found in step 2, scroll the
17214 display and current matrix as needed.
17215
17216 6. Maybe display some lines at the end of W, if we must. This can
17217 happen under various circumstances, like a partially visible line
17218 becoming fully visible, or because newly displayed lines are displayed
17219 in smaller font sizes.
17220
17221 7. Update W's window end information. */
17222
17223 static int
17224 try_window_id (struct window *w)
17225 {
17226 struct frame *f = XFRAME (w->frame);
17227 struct glyph_matrix *current_matrix = w->current_matrix;
17228 struct glyph_matrix *desired_matrix = w->desired_matrix;
17229 struct glyph_row *last_unchanged_at_beg_row;
17230 struct glyph_row *first_unchanged_at_end_row;
17231 struct glyph_row *row;
17232 struct glyph_row *bottom_row;
17233 int bottom_vpos;
17234 struct it it;
17235 ptrdiff_t delta = 0, delta_bytes = 0, stop_pos;
17236 int dvpos, dy;
17237 struct text_pos start_pos;
17238 struct run run;
17239 int first_unchanged_at_end_vpos = 0;
17240 struct glyph_row *last_text_row, *last_text_row_at_end;
17241 struct text_pos start;
17242 ptrdiff_t first_changed_charpos, last_changed_charpos;
17243
17244 #ifdef GLYPH_DEBUG
17245 if (inhibit_try_window_id)
17246 return 0;
17247 #endif
17248
17249 #ifdef HAVE_XWIDGETS_xxx
17250 //maybe needed for proper xwidget movement
17251 printf("try_window_id\n");
17252 return -1;
17253 #endif
17254
17255
17256 /* This is handy for debugging. */
17257 #if 0
17258 #define GIVE_UP(X) \
17259 do { \
17260 fprintf (stderr, "try_window_id give up %d\n", (X)); \
17261 return 0; \
17262 } while (0)
17263 #else
17264 #define GIVE_UP(X) return 0
17265 #endif
17266
17267 SET_TEXT_POS_FROM_MARKER (start, w->start);
17268
17269 /* Don't use this for mini-windows because these can show
17270 messages and mini-buffers, and we don't handle that here. */
17271 if (MINI_WINDOW_P (w))
17272 GIVE_UP (1);
17273
17274 /* This flag is used to prevent redisplay optimizations. */
17275 if (windows_or_buffers_changed || cursor_type_changed)
17276 GIVE_UP (2);
17277
17278 /* Verify that narrowing has not changed.
17279 Also verify that we were not told to prevent redisplay optimizations.
17280 It would be nice to further
17281 reduce the number of cases where this prevents try_window_id. */
17282 if (current_buffer->clip_changed
17283 || current_buffer->prevent_redisplay_optimizations_p)
17284 GIVE_UP (3);
17285
17286 /* Window must either use window-based redisplay or be full width. */
17287 if (!FRAME_WINDOW_P (f)
17288 && (!FRAME_LINE_INS_DEL_OK (f)
17289 || !WINDOW_FULL_WIDTH_P (w)))
17290 GIVE_UP (4);
17291
17292 /* Give up if point is known NOT to appear in W. */
17293 if (PT < CHARPOS (start))
17294 GIVE_UP (5);
17295
17296 /* Another way to prevent redisplay optimizations. */
17297 if (w->last_modified == 0)
17298 GIVE_UP (6);
17299
17300 /* Verify that window is not hscrolled. */
17301 if (w->hscroll != 0)
17302 GIVE_UP (7);
17303
17304 /* Verify that display wasn't paused. */
17305 if (NILP (w->window_end_valid))
17306 GIVE_UP (8);
17307
17308 /* Can't use this if highlighting a region because a cursor movement
17309 will do more than just set the cursor. */
17310 if (!NILP (Vtransient_mark_mode)
17311 && !NILP (BVAR (current_buffer, mark_active)))
17312 GIVE_UP (9);
17313
17314 /* Likewise if highlighting trailing whitespace. */
17315 if (!NILP (Vshow_trailing_whitespace))
17316 GIVE_UP (11);
17317
17318 /* Likewise if showing a region. */
17319 if (!NILP (w->region_showing))
17320 GIVE_UP (10);
17321
17322 /* Can't use this if overlay arrow position and/or string have
17323 changed. */
17324 if (overlay_arrows_changed_p ())
17325 GIVE_UP (12);
17326
17327 /* When word-wrap is on, adding a space to the first word of a
17328 wrapped line can change the wrap position, altering the line
17329 above it. It might be worthwhile to handle this more
17330 intelligently, but for now just redisplay from scratch. */
17331 if (!NILP (BVAR (XBUFFER (w->buffer), word_wrap)))
17332 GIVE_UP (21);
17333
17334 /* Under bidi reordering, adding or deleting a character in the
17335 beginning of a paragraph, before the first strong directional
17336 character, can change the base direction of the paragraph (unless
17337 the buffer specifies a fixed paragraph direction), which will
17338 require to redisplay the whole paragraph. It might be worthwhile
17339 to find the paragraph limits and widen the range of redisplayed
17340 lines to that, but for now just give up this optimization and
17341 redisplay from scratch. */
17342 if (!NILP (BVAR (XBUFFER (w->buffer), bidi_display_reordering))
17343 && NILP (BVAR (XBUFFER (w->buffer), bidi_paragraph_direction)))
17344 GIVE_UP (22);
17345
17346 /* Make sure beg_unchanged and end_unchanged are up to date. Do it
17347 only if buffer has really changed. The reason is that the gap is
17348 initially at Z for freshly visited files. The code below would
17349 set end_unchanged to 0 in that case. */
17350 if (MODIFF > SAVE_MODIFF
17351 /* This seems to happen sometimes after saving a buffer. */
17352 || BEG_UNCHANGED + END_UNCHANGED > Z_BYTE)
17353 {
17354 if (GPT - BEG < BEG_UNCHANGED)
17355 BEG_UNCHANGED = GPT - BEG;
17356 if (Z - GPT < END_UNCHANGED)
17357 END_UNCHANGED = Z - GPT;
17358 }
17359
17360 /* The position of the first and last character that has been changed. */
17361 first_changed_charpos = BEG + BEG_UNCHANGED;
17362 last_changed_charpos = Z - END_UNCHANGED;
17363
17364 /* If window starts after a line end, and the last change is in
17365 front of that newline, then changes don't affect the display.
17366 This case happens with stealth-fontification. Note that although
17367 the display is unchanged, glyph positions in the matrix have to
17368 be adjusted, of course. */
17369 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
17370 if (MATRIX_ROW_DISPLAYS_TEXT_P (row)
17371 && ((last_changed_charpos < CHARPOS (start)
17372 && CHARPOS (start) == BEGV)
17373 || (last_changed_charpos < CHARPOS (start) - 1
17374 && FETCH_BYTE (BYTEPOS (start) - 1) == '\n')))
17375 {
17376 ptrdiff_t Z_old, Z_delta, Z_BYTE_old, Z_delta_bytes;
17377 struct glyph_row *r0;
17378
17379 /* Compute how many chars/bytes have been added to or removed
17380 from the buffer. */
17381 Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
17382 Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
17383 Z_delta = Z - Z_old;
17384 Z_delta_bytes = Z_BYTE - Z_BYTE_old;
17385
17386 /* Give up if PT is not in the window. Note that it already has
17387 been checked at the start of try_window_id that PT is not in
17388 front of the window start. */
17389 if (PT >= MATRIX_ROW_END_CHARPOS (row) + Z_delta)
17390 GIVE_UP (13);
17391
17392 /* If window start is unchanged, we can reuse the whole matrix
17393 as is, after adjusting glyph positions. No need to compute
17394 the window end again, since its offset from Z hasn't changed. */
17395 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
17396 if (CHARPOS (start) == MATRIX_ROW_START_CHARPOS (r0) + Z_delta
17397 && BYTEPOS (start) == MATRIX_ROW_START_BYTEPOS (r0) + Z_delta_bytes
17398 /* PT must not be in a partially visible line. */
17399 && !(PT >= MATRIX_ROW_START_CHARPOS (row) + Z_delta
17400 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
17401 {
17402 /* Adjust positions in the glyph matrix. */
17403 if (Z_delta || Z_delta_bytes)
17404 {
17405 struct glyph_row *r1
17406 = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
17407 increment_matrix_positions (w->current_matrix,
17408 MATRIX_ROW_VPOS (r0, current_matrix),
17409 MATRIX_ROW_VPOS (r1, current_matrix),
17410 Z_delta, Z_delta_bytes);
17411 }
17412
17413 /* Set the cursor. */
17414 row = row_containing_pos (w, PT, r0, NULL, 0);
17415 if (row)
17416 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
17417 else
17418 emacs_abort ();
17419 return 1;
17420 }
17421 }
17422
17423 /* Handle the case that changes are all below what is displayed in
17424 the window, and that PT is in the window. This shortcut cannot
17425 be taken if ZV is visible in the window, and text has been added
17426 there that is visible in the window. */
17427 if (first_changed_charpos >= MATRIX_ROW_END_CHARPOS (row)
17428 /* ZV is not visible in the window, or there are no
17429 changes at ZV, actually. */
17430 && (current_matrix->zv > MATRIX_ROW_END_CHARPOS (row)
17431 || first_changed_charpos == last_changed_charpos))
17432 {
17433 struct glyph_row *r0;
17434
17435 /* Give up if PT is not in the window. Note that it already has
17436 been checked at the start of try_window_id that PT is not in
17437 front of the window start. */
17438 if (PT >= MATRIX_ROW_END_CHARPOS (row))
17439 GIVE_UP (14);
17440
17441 /* If window start is unchanged, we can reuse the whole matrix
17442 as is, without changing glyph positions since no text has
17443 been added/removed in front of the window end. */
17444 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
17445 if (TEXT_POS_EQUAL_P (start, r0->minpos)
17446 /* PT must not be in a partially visible line. */
17447 && !(PT >= MATRIX_ROW_START_CHARPOS (row)
17448 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
17449 {
17450 /* We have to compute the window end anew since text
17451 could have been added/removed after it. */
17452 wset_window_end_pos
17453 (w, make_number (Z - MATRIX_ROW_END_CHARPOS (row)));
17454 w->window_end_bytepos
17455 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
17456
17457 /* Set the cursor. */
17458 row = row_containing_pos (w, PT, r0, NULL, 0);
17459 if (row)
17460 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
17461 else
17462 emacs_abort ();
17463 return 2;
17464 }
17465 }
17466
17467 /* Give up if window start is in the changed area.
17468
17469 The condition used to read
17470
17471 (BEG_UNCHANGED + END_UNCHANGED != Z - BEG && ...)
17472
17473 but why that was tested escapes me at the moment. */
17474 if (CHARPOS (start) >= first_changed_charpos
17475 && CHARPOS (start) <= last_changed_charpos)
17476 GIVE_UP (15);
17477
17478 /* Check that window start agrees with the start of the first glyph
17479 row in its current matrix. Check this after we know the window
17480 start is not in changed text, otherwise positions would not be
17481 comparable. */
17482 row = MATRIX_FIRST_TEXT_ROW (current_matrix);
17483 if (!TEXT_POS_EQUAL_P (start, row->minpos))
17484 GIVE_UP (16);
17485
17486 /* Give up if the window ends in strings. Overlay strings
17487 at the end are difficult to handle, so don't try. */
17488 row = MATRIX_ROW (current_matrix, XFASTINT (w->window_end_vpos));
17489 if (MATRIX_ROW_START_CHARPOS (row) == MATRIX_ROW_END_CHARPOS (row))
17490 GIVE_UP (20);
17491
17492 /* Compute the position at which we have to start displaying new
17493 lines. Some of the lines at the top of the window might be
17494 reusable because they are not displaying changed text. Find the
17495 last row in W's current matrix not affected by changes at the
17496 start of current_buffer. Value is null if changes start in the
17497 first line of window. */
17498 last_unchanged_at_beg_row = find_last_unchanged_at_beg_row (w);
17499 if (last_unchanged_at_beg_row)
17500 {
17501 /* Avoid starting to display in the middle of a character, a TAB
17502 for instance. This is easier than to set up the iterator
17503 exactly, and it's not a frequent case, so the additional
17504 effort wouldn't really pay off. */
17505 while ((MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row)
17506 || last_unchanged_at_beg_row->ends_in_newline_from_string_p)
17507 && last_unchanged_at_beg_row > w->current_matrix->rows)
17508 --last_unchanged_at_beg_row;
17509
17510 if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row))
17511 GIVE_UP (17);
17512
17513 if (init_to_row_end (&it, w, last_unchanged_at_beg_row) == 0)
17514 GIVE_UP (18);
17515 start_pos = it.current.pos;
17516
17517 /* Start displaying new lines in the desired matrix at the same
17518 vpos we would use in the current matrix, i.e. below
17519 last_unchanged_at_beg_row. */
17520 it.vpos = 1 + MATRIX_ROW_VPOS (last_unchanged_at_beg_row,
17521 current_matrix);
17522 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
17523 it.current_y = MATRIX_ROW_BOTTOM_Y (last_unchanged_at_beg_row);
17524
17525 eassert (it.hpos == 0 && it.current_x == 0);
17526 }
17527 else
17528 {
17529 /* There are no reusable lines at the start of the window.
17530 Start displaying in the first text line. */
17531 start_display (&it, w, start);
17532 it.vpos = it.first_vpos;
17533 start_pos = it.current.pos;
17534 }
17535
17536 /* Find the first row that is not affected by changes at the end of
17537 the buffer. Value will be null if there is no unchanged row, in
17538 which case we must redisplay to the end of the window. delta
17539 will be set to the value by which buffer positions beginning with
17540 first_unchanged_at_end_row have to be adjusted due to text
17541 changes. */
17542 first_unchanged_at_end_row
17543 = find_first_unchanged_at_end_row (w, &delta, &delta_bytes);
17544 IF_DEBUG (debug_delta = delta);
17545 IF_DEBUG (debug_delta_bytes = delta_bytes);
17546
17547 /* Set stop_pos to the buffer position up to which we will have to
17548 display new lines. If first_unchanged_at_end_row != NULL, this
17549 is the buffer position of the start of the line displayed in that
17550 row. For first_unchanged_at_end_row == NULL, use 0 to indicate
17551 that we don't stop at a buffer position. */
17552 stop_pos = 0;
17553 if (first_unchanged_at_end_row)
17554 {
17555 eassert (last_unchanged_at_beg_row == NULL
17556 || first_unchanged_at_end_row >= last_unchanged_at_beg_row);
17557
17558 /* If this is a continuation line, move forward to the next one
17559 that isn't. Changes in lines above affect this line.
17560 Caution: this may move first_unchanged_at_end_row to a row
17561 not displaying text. */
17562 while (MATRIX_ROW_CONTINUATION_LINE_P (first_unchanged_at_end_row)
17563 && MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
17564 && (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
17565 < it.last_visible_y))
17566 ++first_unchanged_at_end_row;
17567
17568 if (!MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
17569 || (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
17570 >= it.last_visible_y))
17571 first_unchanged_at_end_row = NULL;
17572 else
17573 {
17574 stop_pos = (MATRIX_ROW_START_CHARPOS (first_unchanged_at_end_row)
17575 + delta);
17576 first_unchanged_at_end_vpos
17577 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, current_matrix);
17578 eassert (stop_pos >= Z - END_UNCHANGED);
17579 }
17580 }
17581 else if (last_unchanged_at_beg_row == NULL)
17582 GIVE_UP (19);
17583
17584
17585 #ifdef GLYPH_DEBUG
17586
17587 /* Either there is no unchanged row at the end, or the one we have
17588 now displays text. This is a necessary condition for the window
17589 end pos calculation at the end of this function. */
17590 eassert (first_unchanged_at_end_row == NULL
17591 || MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
17592
17593 debug_last_unchanged_at_beg_vpos
17594 = (last_unchanged_at_beg_row
17595 ? MATRIX_ROW_VPOS (last_unchanged_at_beg_row, current_matrix)
17596 : -1);
17597 debug_first_unchanged_at_end_vpos = first_unchanged_at_end_vpos;
17598
17599 #endif /* GLYPH_DEBUG */
17600
17601
17602 /* Display new lines. Set last_text_row to the last new line
17603 displayed which has text on it, i.e. might end up as being the
17604 line where the window_end_vpos is. */
17605 w->cursor.vpos = -1;
17606 last_text_row = NULL;
17607 overlay_arrow_seen = 0;
17608 while (it.current_y < it.last_visible_y
17609 && !fonts_changed_p
17610 && (first_unchanged_at_end_row == NULL
17611 || IT_CHARPOS (it) < stop_pos))
17612 {
17613 if (display_line (&it))
17614 last_text_row = it.glyph_row - 1;
17615 }
17616
17617 if (fonts_changed_p)
17618 return -1;
17619
17620
17621 /* Compute differences in buffer positions, y-positions etc. for
17622 lines reused at the bottom of the window. Compute what we can
17623 scroll. */
17624 if (first_unchanged_at_end_row
17625 /* No lines reused because we displayed everything up to the
17626 bottom of the window. */
17627 && it.current_y < it.last_visible_y)
17628 {
17629 dvpos = (it.vpos
17630 - MATRIX_ROW_VPOS (first_unchanged_at_end_row,
17631 current_matrix));
17632 dy = it.current_y - first_unchanged_at_end_row->y;
17633 run.current_y = first_unchanged_at_end_row->y;
17634 run.desired_y = run.current_y + dy;
17635 run.height = it.last_visible_y - max (run.current_y, run.desired_y);
17636 }
17637 else
17638 {
17639 delta = delta_bytes = dvpos = dy
17640 = run.current_y = run.desired_y = run.height = 0;
17641 first_unchanged_at_end_row = NULL;
17642 }
17643 IF_DEBUG (debug_dvpos = dvpos; debug_dy = dy);
17644
17645
17646 /* Find the cursor if not already found. We have to decide whether
17647 PT will appear on this window (it sometimes doesn't, but this is
17648 not a very frequent case.) This decision has to be made before
17649 the current matrix is altered. A value of cursor.vpos < 0 means
17650 that PT is either in one of the lines beginning at
17651 first_unchanged_at_end_row or below the window. Don't care for
17652 lines that might be displayed later at the window end; as
17653 mentioned, this is not a frequent case. */
17654 if (w->cursor.vpos < 0)
17655 {
17656 /* Cursor in unchanged rows at the top? */
17657 if (PT < CHARPOS (start_pos)
17658 && last_unchanged_at_beg_row)
17659 {
17660 row = row_containing_pos (w, PT,
17661 MATRIX_FIRST_TEXT_ROW (w->current_matrix),
17662 last_unchanged_at_beg_row + 1, 0);
17663 if (row)
17664 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
17665 }
17666
17667 /* Start from first_unchanged_at_end_row looking for PT. */
17668 else if (first_unchanged_at_end_row)
17669 {
17670 row = row_containing_pos (w, PT - delta,
17671 first_unchanged_at_end_row, NULL, 0);
17672 if (row)
17673 set_cursor_from_row (w, row, w->current_matrix, delta,
17674 delta_bytes, dy, dvpos);
17675 }
17676
17677 /* Give up if cursor was not found. */
17678 if (w->cursor.vpos < 0)
17679 {
17680 clear_glyph_matrix (w->desired_matrix);
17681 return -1;
17682 }
17683 }
17684
17685 /* Don't let the cursor end in the scroll margins. */
17686 {
17687 int this_scroll_margin, cursor_height;
17688
17689 this_scroll_margin =
17690 max (0, min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4));
17691 this_scroll_margin *= FRAME_LINE_HEIGHT (it.f);
17692 cursor_height = MATRIX_ROW (w->desired_matrix, w->cursor.vpos)->height;
17693
17694 if ((w->cursor.y < this_scroll_margin
17695 && CHARPOS (start) > BEGV)
17696 /* Old redisplay didn't take scroll margin into account at the bottom,
17697 but then global-hl-line-mode doesn't scroll. KFS 2004-06-14 */
17698 || (w->cursor.y + (make_cursor_line_fully_visible_p
17699 ? cursor_height + this_scroll_margin
17700 : 1)) > it.last_visible_y)
17701 {
17702 w->cursor.vpos = -1;
17703 clear_glyph_matrix (w->desired_matrix);
17704 return -1;
17705 }
17706 }
17707
17708 /* Scroll the display. Do it before changing the current matrix so
17709 that xterm.c doesn't get confused about where the cursor glyph is
17710 found. */
17711 if (dy && run.height)
17712 {
17713 update_begin (f);
17714
17715 if (FRAME_WINDOW_P (f))
17716 {
17717 FRAME_RIF (f)->update_window_begin_hook (w);
17718 FRAME_RIF (f)->clear_window_mouse_face (w);
17719 FRAME_RIF (f)->scroll_run_hook (w, &run);
17720 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
17721 }
17722 else
17723 {
17724 /* Terminal frame. In this case, dvpos gives the number of
17725 lines to scroll by; dvpos < 0 means scroll up. */
17726 int from_vpos
17727 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, w->current_matrix);
17728 int from = WINDOW_TOP_EDGE_LINE (w) + from_vpos;
17729 int end = (WINDOW_TOP_EDGE_LINE (w)
17730 + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0)
17731 + window_internal_height (w));
17732
17733 #if defined (HAVE_GPM) || defined (MSDOS)
17734 x_clear_window_mouse_face (w);
17735 #endif
17736 /* Perform the operation on the screen. */
17737 if (dvpos > 0)
17738 {
17739 /* Scroll last_unchanged_at_beg_row to the end of the
17740 window down dvpos lines. */
17741 set_terminal_window (f, end);
17742
17743 /* On dumb terminals delete dvpos lines at the end
17744 before inserting dvpos empty lines. */
17745 if (!FRAME_SCROLL_REGION_OK (f))
17746 ins_del_lines (f, end - dvpos, -dvpos);
17747
17748 /* Insert dvpos empty lines in front of
17749 last_unchanged_at_beg_row. */
17750 ins_del_lines (f, from, dvpos);
17751 }
17752 else if (dvpos < 0)
17753 {
17754 /* Scroll up last_unchanged_at_beg_vpos to the end of
17755 the window to last_unchanged_at_beg_vpos - |dvpos|. */
17756 set_terminal_window (f, end);
17757
17758 /* Delete dvpos lines in front of
17759 last_unchanged_at_beg_vpos. ins_del_lines will set
17760 the cursor to the given vpos and emit |dvpos| delete
17761 line sequences. */
17762 ins_del_lines (f, from + dvpos, dvpos);
17763
17764 /* On a dumb terminal insert dvpos empty lines at the
17765 end. */
17766 if (!FRAME_SCROLL_REGION_OK (f))
17767 ins_del_lines (f, end + dvpos, -dvpos);
17768 }
17769
17770 set_terminal_window (f, 0);
17771 }
17772
17773 update_end (f);
17774 }
17775
17776 /* Shift reused rows of the current matrix to the right position.
17777 BOTTOM_ROW is the last + 1 row in the current matrix reserved for
17778 text. */
17779 bottom_row = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
17780 bottom_vpos = MATRIX_ROW_VPOS (bottom_row, current_matrix);
17781 if (dvpos < 0)
17782 {
17783 rotate_matrix (current_matrix, first_unchanged_at_end_vpos + dvpos,
17784 bottom_vpos, dvpos);
17785 clear_glyph_matrix_rows (current_matrix, bottom_vpos + dvpos,
17786 bottom_vpos);
17787 }
17788 else if (dvpos > 0)
17789 {
17790 rotate_matrix (current_matrix, first_unchanged_at_end_vpos,
17791 bottom_vpos, dvpos);
17792 clear_glyph_matrix_rows (current_matrix, first_unchanged_at_end_vpos,
17793 first_unchanged_at_end_vpos + dvpos);
17794 }
17795
17796 /* For frame-based redisplay, make sure that current frame and window
17797 matrix are in sync with respect to glyph memory. */
17798 if (!FRAME_WINDOW_P (f))
17799 sync_frame_with_window_matrix_rows (w);
17800
17801 /* Adjust buffer positions in reused rows. */
17802 if (delta || delta_bytes)
17803 increment_matrix_positions (current_matrix,
17804 first_unchanged_at_end_vpos + dvpos,
17805 bottom_vpos, delta, delta_bytes);
17806
17807 /* Adjust Y positions. */
17808 if (dy)
17809 shift_glyph_matrix (w, current_matrix,
17810 first_unchanged_at_end_vpos + dvpos,
17811 bottom_vpos, dy);
17812
17813 if (first_unchanged_at_end_row)
17814 {
17815 first_unchanged_at_end_row += dvpos;
17816 if (first_unchanged_at_end_row->y >= it.last_visible_y
17817 || !MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row))
17818 first_unchanged_at_end_row = NULL;
17819 }
17820
17821 /* If scrolling up, there may be some lines to display at the end of
17822 the window. */
17823 last_text_row_at_end = NULL;
17824 if (dy < 0)
17825 {
17826 /* Scrolling up can leave for example a partially visible line
17827 at the end of the window to be redisplayed. */
17828 /* Set last_row to the glyph row in the current matrix where the
17829 window end line is found. It has been moved up or down in
17830 the matrix by dvpos. */
17831 int last_vpos = XFASTINT (w->window_end_vpos) + dvpos;
17832 struct glyph_row *last_row = MATRIX_ROW (current_matrix, last_vpos);
17833
17834 /* If last_row is the window end line, it should display text. */
17835 eassert (last_row->displays_text_p);
17836
17837 /* If window end line was partially visible before, begin
17838 displaying at that line. Otherwise begin displaying with the
17839 line following it. */
17840 if (MATRIX_ROW_BOTTOM_Y (last_row) - dy >= it.last_visible_y)
17841 {
17842 init_to_row_start (&it, w, last_row);
17843 it.vpos = last_vpos;
17844 it.current_y = last_row->y;
17845 }
17846 else
17847 {
17848 init_to_row_end (&it, w, last_row);
17849 it.vpos = 1 + last_vpos;
17850 it.current_y = MATRIX_ROW_BOTTOM_Y (last_row);
17851 ++last_row;
17852 }
17853
17854 /* We may start in a continuation line. If so, we have to
17855 get the right continuation_lines_width and current_x. */
17856 it.continuation_lines_width = last_row->continuation_lines_width;
17857 it.hpos = it.current_x = 0;
17858
17859 /* Display the rest of the lines at the window end. */
17860 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
17861 while (it.current_y < it.last_visible_y
17862 && !fonts_changed_p)
17863 {
17864 /* Is it always sure that the display agrees with lines in
17865 the current matrix? I don't think so, so we mark rows
17866 displayed invalid in the current matrix by setting their
17867 enabled_p flag to zero. */
17868 MATRIX_ROW (w->current_matrix, it.vpos)->enabled_p = 0;
17869 if (display_line (&it))
17870 last_text_row_at_end = it.glyph_row - 1;
17871 }
17872 }
17873
17874 /* Update window_end_pos and window_end_vpos. */
17875 if (first_unchanged_at_end_row
17876 && !last_text_row_at_end)
17877 {
17878 /* Window end line if one of the preserved rows from the current
17879 matrix. Set row to the last row displaying text in current
17880 matrix starting at first_unchanged_at_end_row, after
17881 scrolling. */
17882 eassert (first_unchanged_at_end_row->displays_text_p);
17883 row = find_last_row_displaying_text (w->current_matrix, &it,
17884 first_unchanged_at_end_row);
17885 eassert (row && MATRIX_ROW_DISPLAYS_TEXT_P (row));
17886
17887 wset_window_end_pos (w, make_number (Z - MATRIX_ROW_END_CHARPOS (row)));
17888 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
17889 wset_window_end_vpos
17890 (w, make_number (MATRIX_ROW_VPOS (row, w->current_matrix)));
17891 eassert (w->window_end_bytepos >= 0);
17892 IF_DEBUG (debug_method_add (w, "A"));
17893 }
17894 else if (last_text_row_at_end)
17895 {
17896 wset_window_end_pos
17897 (w, make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row_at_end)));
17898 w->window_end_bytepos
17899 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row_at_end);
17900 wset_window_end_vpos
17901 (w, make_number (MATRIX_ROW_VPOS (last_text_row_at_end,
17902 desired_matrix)));
17903 eassert (w->window_end_bytepos >= 0);
17904 IF_DEBUG (debug_method_add (w, "B"));
17905 }
17906 else if (last_text_row)
17907 {
17908 /* We have displayed either to the end of the window or at the
17909 end of the window, i.e. the last row with text is to be found
17910 in the desired matrix. */
17911 wset_window_end_pos
17912 (w, make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row)));
17913 w->window_end_bytepos
17914 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
17915 wset_window_end_vpos
17916 (w, make_number (MATRIX_ROW_VPOS (last_text_row, desired_matrix)));
17917 eassert (w->window_end_bytepos >= 0);
17918 }
17919 else if (first_unchanged_at_end_row == NULL
17920 && last_text_row == NULL
17921 && last_text_row_at_end == NULL)
17922 {
17923 /* Displayed to end of window, but no line containing text was
17924 displayed. Lines were deleted at the end of the window. */
17925 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
17926 int vpos = XFASTINT (w->window_end_vpos);
17927 struct glyph_row *current_row = current_matrix->rows + vpos;
17928 struct glyph_row *desired_row = desired_matrix->rows + vpos;
17929
17930 for (row = NULL;
17931 row == NULL && vpos >= first_vpos;
17932 --vpos, --current_row, --desired_row)
17933 {
17934 if (desired_row->enabled_p)
17935 {
17936 if (desired_row->displays_text_p)
17937 row = desired_row;
17938 }
17939 else if (current_row->displays_text_p)
17940 row = current_row;
17941 }
17942
17943 eassert (row != NULL);
17944 wset_window_end_vpos (w, make_number (vpos + 1));
17945 wset_window_end_pos (w, make_number (Z - MATRIX_ROW_END_CHARPOS (row)));
17946 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
17947 eassert (w->window_end_bytepos >= 0);
17948 IF_DEBUG (debug_method_add (w, "C"));
17949 }
17950 else
17951 emacs_abort ();
17952
17953 IF_DEBUG (debug_end_pos = XFASTINT (w->window_end_pos);
17954 debug_end_vpos = XFASTINT (w->window_end_vpos));
17955
17956 /* Record that display has not been completed. */
17957 wset_window_end_valid (w, Qnil);
17958 w->desired_matrix->no_scrolling_p = 1;
17959 return 3;
17960
17961 #undef GIVE_UP
17962 }
17963
17964
17965 \f
17966 /***********************************************************************
17967 More debugging support
17968 ***********************************************************************/
17969
17970 #ifdef GLYPH_DEBUG
17971
17972 void dump_glyph_row (struct glyph_row *, int, int) EXTERNALLY_VISIBLE;
17973 void dump_glyph_matrix (struct glyph_matrix *, int) EXTERNALLY_VISIBLE;
17974 void dump_glyph (struct glyph_row *, struct glyph *, int) EXTERNALLY_VISIBLE;
17975
17976
17977 /* Dump the contents of glyph matrix MATRIX on stderr.
17978
17979 GLYPHS 0 means don't show glyph contents.
17980 GLYPHS 1 means show glyphs in short form
17981 GLYPHS > 1 means show glyphs in long form. */
17982
17983 void
17984 dump_glyph_matrix (struct glyph_matrix *matrix, int glyphs)
17985 {
17986 int i;
17987 for (i = 0; i < matrix->nrows; ++i)
17988 dump_glyph_row (MATRIX_ROW (matrix, i), i, glyphs);
17989 }
17990
17991
17992 /* Dump contents of glyph GLYPH to stderr. ROW and AREA are
17993 the glyph row and area where the glyph comes from. */
17994
17995 void
17996 dump_glyph (struct glyph_row *row, struct glyph *glyph, int area)
17997 {
17998 if (glyph->type == CHAR_GLYPH)
17999 {
18000 fprintf (stderr,
18001 " %5td %4c %6"pI"d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
18002 glyph - row->glyphs[TEXT_AREA],
18003 'C',
18004 glyph->charpos,
18005 (BUFFERP (glyph->object)
18006 ? 'B'
18007 : (STRINGP (glyph->object)
18008 ? 'S'
18009 : '-')),
18010 glyph->pixel_width,
18011 glyph->u.ch,
18012 (glyph->u.ch < 0x80 && glyph->u.ch >= ' '
18013 ? glyph->u.ch
18014 : '.'),
18015 glyph->face_id,
18016 glyph->left_box_line_p,
18017 glyph->right_box_line_p);
18018 }
18019 else if (glyph->type == STRETCH_GLYPH)
18020 {
18021 fprintf (stderr,
18022 " %5td %4c %6"pI"d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
18023 glyph - row->glyphs[TEXT_AREA],
18024 'S',
18025 glyph->charpos,
18026 (BUFFERP (glyph->object)
18027 ? 'B'
18028 : (STRINGP (glyph->object)
18029 ? 'S'
18030 : '-')),
18031 glyph->pixel_width,
18032 0,
18033 '.',
18034 glyph->face_id,
18035 glyph->left_box_line_p,
18036 glyph->right_box_line_p);
18037 }
18038 else if (glyph->type == IMAGE_GLYPH)
18039 {
18040 fprintf (stderr,
18041 " %5td %4c %6"pI"d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
18042 glyph - row->glyphs[TEXT_AREA],
18043 'I',
18044 glyph->charpos,
18045 (BUFFERP (glyph->object)
18046 ? 'B'
18047 : (STRINGP (glyph->object)
18048 ? 'S'
18049 : '-')),
18050 glyph->pixel_width,
18051 glyph->u.img_id,
18052 '.',
18053 glyph->face_id,
18054 glyph->left_box_line_p,
18055 glyph->right_box_line_p);
18056 }
18057 else if (glyph->type == COMPOSITE_GLYPH)
18058 {
18059 fprintf (stderr,
18060 " %5td %4c %6"pI"d %c %3d 0x%05x",
18061 glyph - row->glyphs[TEXT_AREA],
18062 '+',
18063 glyph->charpos,
18064 (BUFFERP (glyph->object)
18065 ? 'B'
18066 : (STRINGP (glyph->object)
18067 ? 'S'
18068 : '-')),
18069 glyph->pixel_width,
18070 glyph->u.cmp.id);
18071 if (glyph->u.cmp.automatic)
18072 fprintf (stderr,
18073 "[%d-%d]",
18074 glyph->slice.cmp.from, glyph->slice.cmp.to);
18075 fprintf (stderr, " . %4d %1.1d%1.1d\n",
18076 glyph->face_id,
18077 glyph->left_box_line_p,
18078 glyph->right_box_line_p);
18079 }
18080 #ifdef HAVE_XWIDGETS
18081 else if (glyph->type == XWIDGET_GLYPH)
18082 {
18083 fprintf (stderr,
18084 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
18085 glyph - row->glyphs[TEXT_AREA],
18086 'X',
18087 glyph->charpos,
18088 (BUFFERP (glyph->object)
18089 ? 'B'
18090 : (STRINGP (glyph->object)
18091 ? 'S'
18092 : '-')),
18093 glyph->pixel_width,
18094 glyph->u.xwidget,
18095 '.',
18096 glyph->face_id,
18097 glyph->left_box_line_p,
18098 glyph->right_box_line_p);
18099
18100 // printf("dump xwidget glyph\n");
18101 }
18102 #endif
18103 }
18104
18105
18106 /* Dump the contents of glyph row at VPOS in MATRIX to stderr.
18107 GLYPHS 0 means don't show glyph contents.
18108 GLYPHS 1 means show glyphs in short form
18109 GLYPHS > 1 means show glyphs in long form. */
18110
18111 void
18112 dump_glyph_row (struct glyph_row *row, int vpos, int glyphs)
18113 {
18114 if (glyphs != 1)
18115 {
18116 fprintf (stderr, "Row Start End Used oE><\\CTZFesm X Y W H V A P\n");
18117 fprintf (stderr, "======================================================================\n");
18118
18119 fprintf (stderr, "%3d %5"pI"d %5"pI"d %4d %1.1d%1.1d%1.1d%1.1d\
18120 %1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d %4d %4d %4d %4d %4d %4d %4d\n",
18121 vpos,
18122 MATRIX_ROW_START_CHARPOS (row),
18123 MATRIX_ROW_END_CHARPOS (row),
18124 row->used[TEXT_AREA],
18125 row->contains_overlapping_glyphs_p,
18126 row->enabled_p,
18127 row->truncated_on_left_p,
18128 row->truncated_on_right_p,
18129 row->continued_p,
18130 MATRIX_ROW_CONTINUATION_LINE_P (row),
18131 row->displays_text_p,
18132 row->ends_at_zv_p,
18133 row->fill_line_p,
18134 row->ends_in_middle_of_char_p,
18135 row->starts_in_middle_of_char_p,
18136 row->mouse_face_p,
18137 row->x,
18138 row->y,
18139 row->pixel_width,
18140 row->height,
18141 row->visible_height,
18142 row->ascent,
18143 row->phys_ascent);
18144 fprintf (stderr, "%9"pD"d %5"pD"d\t%5d\n", row->start.overlay_string_index,
18145 row->end.overlay_string_index,
18146 row->continuation_lines_width);
18147 fprintf (stderr, "%9"pI"d %5"pI"d\n",
18148 CHARPOS (row->start.string_pos),
18149 CHARPOS (row->end.string_pos));
18150 fprintf (stderr, "%9d %5d\n", row->start.dpvec_index,
18151 row->end.dpvec_index);
18152 }
18153
18154 if (glyphs > 1)
18155 {
18156 int area;
18157
18158 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
18159 {
18160 struct glyph *glyph = row->glyphs[area];
18161 struct glyph *glyph_end = glyph + row->used[area];
18162
18163 /* Glyph for a line end in text. */
18164 if (area == TEXT_AREA && glyph == glyph_end && glyph->charpos > 0)
18165 ++glyph_end;
18166
18167 if (glyph < glyph_end)
18168 fprintf (stderr, " Glyph Type Pos O W Code C Face LR\n");
18169
18170 for (; glyph < glyph_end; ++glyph)
18171 dump_glyph (row, glyph, area);
18172 }
18173 }
18174 else if (glyphs == 1)
18175 {
18176 int area;
18177
18178 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
18179 {
18180 char *s = alloca (row->used[area] + 1);
18181 int i;
18182
18183 for (i = 0; i < row->used[area]; ++i)
18184 {
18185 struct glyph *glyph = row->glyphs[area] + i;
18186 if (glyph->type == CHAR_GLYPH
18187 && glyph->u.ch < 0x80
18188 && glyph->u.ch >= ' ')
18189 s[i] = glyph->u.ch;
18190 else
18191 s[i] = '.';
18192 }
18193
18194 s[i] = '\0';
18195 fprintf (stderr, "%3d: (%d) '%s'\n", vpos, row->enabled_p, s);
18196 }
18197 }
18198 }
18199
18200
18201 DEFUN ("dump-glyph-matrix", Fdump_glyph_matrix,
18202 Sdump_glyph_matrix, 0, 1, "p",
18203 doc: /* Dump the current matrix of the selected window to stderr.
18204 Shows contents of glyph row structures. With non-nil
18205 parameter GLYPHS, dump glyphs as well. If GLYPHS is 1 show
18206 glyphs in short form, otherwise show glyphs in long form. */)
18207 (Lisp_Object glyphs)
18208 {
18209 struct window *w = XWINDOW (selected_window);
18210 struct buffer *buffer = XBUFFER (w->buffer);
18211
18212 fprintf (stderr, "PT = %"pI"d, BEGV = %"pI"d. ZV = %"pI"d\n",
18213 BUF_PT (buffer), BUF_BEGV (buffer), BUF_ZV (buffer));
18214 fprintf (stderr, "Cursor x = %d, y = %d, hpos = %d, vpos = %d\n",
18215 w->cursor.x, w->cursor.y, w->cursor.hpos, w->cursor.vpos);
18216 fprintf (stderr, "=============================================\n");
18217 dump_glyph_matrix (w->current_matrix,
18218 TYPE_RANGED_INTEGERP (int, glyphs) ? XINT (glyphs) : 0);
18219 return Qnil;
18220 }
18221
18222
18223 DEFUN ("dump-frame-glyph-matrix", Fdump_frame_glyph_matrix,
18224 Sdump_frame_glyph_matrix, 0, 0, "", doc: /* */)
18225 (void)
18226 {
18227 struct frame *f = XFRAME (selected_frame);
18228 dump_glyph_matrix (f->current_matrix, 1);
18229 return Qnil;
18230 }
18231
18232
18233 DEFUN ("dump-glyph-row", Fdump_glyph_row, Sdump_glyph_row, 1, 2, "",
18234 doc: /* Dump glyph row ROW to stderr.
18235 GLYPH 0 means don't dump glyphs.
18236 GLYPH 1 means dump glyphs in short form.
18237 GLYPH > 1 or omitted means dump glyphs in long form. */)
18238 (Lisp_Object row, Lisp_Object glyphs)
18239 {
18240 struct glyph_matrix *matrix;
18241 EMACS_INT vpos;
18242
18243 CHECK_NUMBER (row);
18244 matrix = XWINDOW (selected_window)->current_matrix;
18245 vpos = XINT (row);
18246 if (vpos >= 0 && vpos < matrix->nrows)
18247 dump_glyph_row (MATRIX_ROW (matrix, vpos),
18248 vpos,
18249 TYPE_RANGED_INTEGERP (int, glyphs) ? XINT (glyphs) : 2);
18250 return Qnil;
18251 }
18252
18253
18254 DEFUN ("dump-tool-bar-row", Fdump_tool_bar_row, Sdump_tool_bar_row, 1, 2, "",
18255 doc: /* Dump glyph row ROW of the tool-bar of the current frame to stderr.
18256 GLYPH 0 means don't dump glyphs.
18257 GLYPH 1 means dump glyphs in short form.
18258 GLYPH > 1 or omitted means dump glyphs in long form. */)
18259 (Lisp_Object row, Lisp_Object glyphs)
18260 {
18261 struct frame *sf = SELECTED_FRAME ();
18262 struct glyph_matrix *m = XWINDOW (sf->tool_bar_window)->current_matrix;
18263 EMACS_INT vpos;
18264
18265 CHECK_NUMBER (row);
18266 vpos = XINT (row);
18267 if (vpos >= 0 && vpos < m->nrows)
18268 dump_glyph_row (MATRIX_ROW (m, vpos), vpos,
18269 TYPE_RANGED_INTEGERP (int, glyphs) ? XINT (glyphs) : 2);
18270 return Qnil;
18271 }
18272
18273
18274 DEFUN ("trace-redisplay", Ftrace_redisplay, Strace_redisplay, 0, 1, "P",
18275 doc: /* Toggle tracing of redisplay.
18276 With ARG, turn tracing on if and only if ARG is positive. */)
18277 (Lisp_Object arg)
18278 {
18279 if (NILP (arg))
18280 trace_redisplay_p = !trace_redisplay_p;
18281 else
18282 {
18283 arg = Fprefix_numeric_value (arg);
18284 trace_redisplay_p = XINT (arg) > 0;
18285 }
18286
18287 return Qnil;
18288 }
18289
18290
18291 DEFUN ("trace-to-stderr", Ftrace_to_stderr, Strace_to_stderr, 1, MANY, "",
18292 doc: /* Like `format', but print result to stderr.
18293 usage: (trace-to-stderr STRING &rest OBJECTS) */)
18294 (ptrdiff_t nargs, Lisp_Object *args)
18295 {
18296 Lisp_Object s = Fformat (nargs, args);
18297 fprintf (stderr, "%s", SDATA (s));
18298 return Qnil;
18299 }
18300
18301 #endif /* GLYPH_DEBUG */
18302
18303
18304 \f
18305 /***********************************************************************
18306 Building Desired Matrix Rows
18307 ***********************************************************************/
18308
18309 /* Return a temporary glyph row holding the glyphs of an overlay arrow.
18310 Used for non-window-redisplay windows, and for windows w/o left fringe. */
18311
18312 static struct glyph_row *
18313 get_overlay_arrow_glyph_row (struct window *w, Lisp_Object overlay_arrow_string)
18314 {
18315 struct frame *f = XFRAME (WINDOW_FRAME (w));
18316 struct buffer *buffer = XBUFFER (w->buffer);
18317 struct buffer *old = current_buffer;
18318 const unsigned char *arrow_string = SDATA (overlay_arrow_string);
18319 int arrow_len = SCHARS (overlay_arrow_string);
18320 const unsigned char *arrow_end = arrow_string + arrow_len;
18321 const unsigned char *p;
18322 struct it it;
18323 int multibyte_p;
18324 int n_glyphs_before;
18325
18326 set_buffer_temp (buffer);
18327 init_iterator (&it, w, -1, -1, &scratch_glyph_row, DEFAULT_FACE_ID);
18328 it.glyph_row->used[TEXT_AREA] = 0;
18329 SET_TEXT_POS (it.position, 0, 0);
18330
18331 multibyte_p = !NILP (BVAR (buffer, enable_multibyte_characters));
18332 p = arrow_string;
18333 while (p < arrow_end)
18334 {
18335 Lisp_Object face, ilisp;
18336
18337 /* Get the next character. */
18338 if (multibyte_p)
18339 it.c = it.char_to_display = string_char_and_length (p, &it.len);
18340 else
18341 {
18342 it.c = it.char_to_display = *p, it.len = 1;
18343 if (! ASCII_CHAR_P (it.c))
18344 it.char_to_display = BYTE8_TO_CHAR (it.c);
18345 }
18346 p += it.len;
18347
18348 /* Get its face. */
18349 ilisp = make_number (p - arrow_string);
18350 face = Fget_text_property (ilisp, Qface, overlay_arrow_string);
18351 it.face_id = compute_char_face (f, it.char_to_display, face);
18352
18353 /* Compute its width, get its glyphs. */
18354 n_glyphs_before = it.glyph_row->used[TEXT_AREA];
18355 SET_TEXT_POS (it.position, -1, -1);
18356 PRODUCE_GLYPHS (&it);
18357
18358 /* If this character doesn't fit any more in the line, we have
18359 to remove some glyphs. */
18360 if (it.current_x > it.last_visible_x)
18361 {
18362 it.glyph_row->used[TEXT_AREA] = n_glyphs_before;
18363 break;
18364 }
18365 }
18366
18367 set_buffer_temp (old);
18368 return it.glyph_row;
18369 }
18370
18371
18372 /* Insert truncation glyphs at the start of IT->glyph_row. Which
18373 glyphs to insert is determined by produce_special_glyphs. */
18374
18375 static void
18376 insert_left_trunc_glyphs (struct it *it)
18377 {
18378 struct it truncate_it;
18379 struct glyph *from, *end, *to, *toend;
18380
18381 eassert (!FRAME_WINDOW_P (it->f)
18382 || (!it->glyph_row->reversed_p
18383 && WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0)
18384 || (it->glyph_row->reversed_p
18385 && WINDOW_RIGHT_FRINGE_WIDTH (it->w) == 0));
18386
18387 /* Get the truncation glyphs. */
18388 truncate_it = *it;
18389 truncate_it.current_x = 0;
18390 truncate_it.face_id = DEFAULT_FACE_ID;
18391 truncate_it.glyph_row = &scratch_glyph_row;
18392 truncate_it.glyph_row->used[TEXT_AREA] = 0;
18393 CHARPOS (truncate_it.position) = BYTEPOS (truncate_it.position) = -1;
18394 truncate_it.object = make_number (0);
18395 produce_special_glyphs (&truncate_it, IT_TRUNCATION);
18396
18397 /* Overwrite glyphs from IT with truncation glyphs. */
18398 if (!it->glyph_row->reversed_p)
18399 {
18400 short tused = truncate_it.glyph_row->used[TEXT_AREA];
18401
18402 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
18403 end = from + tused;
18404 to = it->glyph_row->glyphs[TEXT_AREA];
18405 toend = to + it->glyph_row->used[TEXT_AREA];
18406 if (FRAME_WINDOW_P (it->f))
18407 {
18408 /* On GUI frames, when variable-size fonts are displayed,
18409 the truncation glyphs may need more pixels than the row's
18410 glyphs they overwrite. We overwrite more glyphs to free
18411 enough screen real estate, and enlarge the stretch glyph
18412 on the right (see display_line), if there is one, to
18413 preserve the screen position of the truncation glyphs on
18414 the right. */
18415 int w = 0;
18416 struct glyph *g = to;
18417 short used;
18418
18419 /* The first glyph could be partially visible, in which case
18420 it->glyph_row->x will be negative. But we want the left
18421 truncation glyphs to be aligned at the left margin of the
18422 window, so we override the x coordinate at which the row
18423 will begin. */
18424 it->glyph_row->x = 0;
18425 while (g < toend && w < it->truncation_pixel_width)
18426 {
18427 w += g->pixel_width;
18428 ++g;
18429 }
18430 if (g - to - tused > 0)
18431 {
18432 memmove (to + tused, g, (toend - g) * sizeof(*g));
18433 it->glyph_row->used[TEXT_AREA] -= g - to - tused;
18434 }
18435 used = it->glyph_row->used[TEXT_AREA];
18436 if (it->glyph_row->truncated_on_right_p
18437 && WINDOW_RIGHT_FRINGE_WIDTH (it->w) == 0
18438 && it->glyph_row->glyphs[TEXT_AREA][used - 2].type
18439 == STRETCH_GLYPH)
18440 {
18441 int extra = w - it->truncation_pixel_width;
18442
18443 it->glyph_row->glyphs[TEXT_AREA][used - 2].pixel_width += extra;
18444 }
18445 }
18446
18447 while (from < end)
18448 *to++ = *from++;
18449
18450 /* There may be padding glyphs left over. Overwrite them too. */
18451 if (!FRAME_WINDOW_P (it->f))
18452 {
18453 while (to < toend && CHAR_GLYPH_PADDING_P (*to))
18454 {
18455 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
18456 while (from < end)
18457 *to++ = *from++;
18458 }
18459 }
18460
18461 if (to > toend)
18462 it->glyph_row->used[TEXT_AREA] = to - it->glyph_row->glyphs[TEXT_AREA];
18463 }
18464 else
18465 {
18466 short tused = truncate_it.glyph_row->used[TEXT_AREA];
18467
18468 /* In R2L rows, overwrite the last (rightmost) glyphs, and do
18469 that back to front. */
18470 end = truncate_it.glyph_row->glyphs[TEXT_AREA];
18471 from = end + truncate_it.glyph_row->used[TEXT_AREA] - 1;
18472 toend = it->glyph_row->glyphs[TEXT_AREA];
18473 to = toend + it->glyph_row->used[TEXT_AREA] - 1;
18474 if (FRAME_WINDOW_P (it->f))
18475 {
18476 int w = 0;
18477 struct glyph *g = to;
18478
18479 while (g >= toend && w < it->truncation_pixel_width)
18480 {
18481 w += g->pixel_width;
18482 --g;
18483 }
18484 if (to - g - tused > 0)
18485 to = g + tused;
18486 if (it->glyph_row->truncated_on_right_p
18487 && WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0
18488 && it->glyph_row->glyphs[TEXT_AREA][1].type == STRETCH_GLYPH)
18489 {
18490 int extra = w - it->truncation_pixel_width;
18491
18492 it->glyph_row->glyphs[TEXT_AREA][1].pixel_width += extra;
18493 }
18494 }
18495
18496 while (from >= end && to >= toend)
18497 *to-- = *from--;
18498 if (!FRAME_WINDOW_P (it->f))
18499 {
18500 while (to >= toend && CHAR_GLYPH_PADDING_P (*to))
18501 {
18502 from =
18503 truncate_it.glyph_row->glyphs[TEXT_AREA]
18504 + truncate_it.glyph_row->used[TEXT_AREA] - 1;
18505 while (from >= end && to >= toend)
18506 *to-- = *from--;
18507 }
18508 }
18509 if (from >= end)
18510 {
18511 /* Need to free some room before prepending additional
18512 glyphs. */
18513 int move_by = from - end + 1;
18514 struct glyph *g0 = it->glyph_row->glyphs[TEXT_AREA];
18515 struct glyph *g = g0 + it->glyph_row->used[TEXT_AREA] - 1;
18516
18517 for ( ; g >= g0; g--)
18518 g[move_by] = *g;
18519 while (from >= end)
18520 *to-- = *from--;
18521 it->glyph_row->used[TEXT_AREA] += move_by;
18522 }
18523 }
18524 }
18525
18526 /* Compute the hash code for ROW. */
18527 unsigned
18528 row_hash (struct glyph_row *row)
18529 {
18530 int area, k;
18531 unsigned hashval = 0;
18532
18533 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
18534 for (k = 0; k < row->used[area]; ++k)
18535 hashval = ((((hashval << 4) + (hashval >> 24)) & 0x0fffffff)
18536 + row->glyphs[area][k].u.val
18537 + row->glyphs[area][k].face_id
18538 + row->glyphs[area][k].padding_p
18539 + (row->glyphs[area][k].type << 2));
18540
18541 return hashval;
18542 }
18543
18544 /* Compute the pixel height and width of IT->glyph_row.
18545
18546 Most of the time, ascent and height of a display line will be equal
18547 to the max_ascent and max_height values of the display iterator
18548 structure. This is not the case if
18549
18550 1. We hit ZV without displaying anything. In this case, max_ascent
18551 and max_height will be zero.
18552
18553 2. We have some glyphs that don't contribute to the line height.
18554 (The glyph row flag contributes_to_line_height_p is for future
18555 pixmap extensions).
18556
18557 The first case is easily covered by using default values because in
18558 these cases, the line height does not really matter, except that it
18559 must not be zero. */
18560
18561 static void
18562 compute_line_metrics (struct it *it)
18563 {
18564 struct glyph_row *row = it->glyph_row;
18565
18566 if (FRAME_WINDOW_P (it->f))
18567 {
18568 int i, min_y, max_y;
18569
18570 /* The line may consist of one space only, that was added to
18571 place the cursor on it. If so, the row's height hasn't been
18572 computed yet. */
18573 if (row->height == 0)
18574 {
18575 if (it->max_ascent + it->max_descent == 0)
18576 it->max_descent = it->max_phys_descent = FRAME_LINE_HEIGHT (it->f);
18577 row->ascent = it->max_ascent;
18578 row->height = it->max_ascent + it->max_descent;
18579 row->phys_ascent = it->max_phys_ascent;
18580 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
18581 row->extra_line_spacing = it->max_extra_line_spacing;
18582 }
18583
18584 /* Compute the width of this line. */
18585 row->pixel_width = row->x;
18586 for (i = 0; i < row->used[TEXT_AREA]; ++i)
18587 row->pixel_width += row->glyphs[TEXT_AREA][i].pixel_width;
18588
18589 eassert (row->pixel_width >= 0);
18590 eassert (row->ascent >= 0 && row->height > 0);
18591
18592 row->overlapping_p = (MATRIX_ROW_OVERLAPS_SUCC_P (row)
18593 || MATRIX_ROW_OVERLAPS_PRED_P (row));
18594
18595 /* If first line's physical ascent is larger than its logical
18596 ascent, use the physical ascent, and make the row taller.
18597 This makes accented characters fully visible. */
18598 if (row == MATRIX_FIRST_TEXT_ROW (it->w->desired_matrix)
18599 && row->phys_ascent > row->ascent)
18600 {
18601 row->height += row->phys_ascent - row->ascent;
18602 row->ascent = row->phys_ascent;
18603 }
18604
18605 /* Compute how much of the line is visible. */
18606 row->visible_height = row->height;
18607
18608 min_y = WINDOW_HEADER_LINE_HEIGHT (it->w);
18609 max_y = WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w);
18610
18611 if (row->y < min_y)
18612 row->visible_height -= min_y - row->y;
18613 if (row->y + row->height > max_y)
18614 row->visible_height -= row->y + row->height - max_y;
18615 }
18616 else
18617 {
18618 row->pixel_width = row->used[TEXT_AREA];
18619 if (row->continued_p)
18620 row->pixel_width -= it->continuation_pixel_width;
18621 else if (row->truncated_on_right_p)
18622 row->pixel_width -= it->truncation_pixel_width;
18623 row->ascent = row->phys_ascent = 0;
18624 row->height = row->phys_height = row->visible_height = 1;
18625 row->extra_line_spacing = 0;
18626 }
18627
18628 /* Compute a hash code for this row. */
18629 row->hash = row_hash (row);
18630
18631 it->max_ascent = it->max_descent = 0;
18632 it->max_phys_ascent = it->max_phys_descent = 0;
18633 }
18634
18635
18636 /* Append one space to the glyph row of iterator IT if doing a
18637 window-based redisplay. The space has the same face as
18638 IT->face_id. Value is non-zero if a space was added.
18639
18640 This function is called to make sure that there is always one glyph
18641 at the end of a glyph row that the cursor can be set on under
18642 window-systems. (If there weren't such a glyph we would not know
18643 how wide and tall a box cursor should be displayed).
18644
18645 At the same time this space let's a nicely handle clearing to the
18646 end of the line if the row ends in italic text. */
18647
18648 static int
18649 append_space_for_newline (struct it *it, int default_face_p)
18650 {
18651 if (FRAME_WINDOW_P (it->f))
18652 {
18653 int n = it->glyph_row->used[TEXT_AREA];
18654
18655 if (it->glyph_row->glyphs[TEXT_AREA] + n
18656 < it->glyph_row->glyphs[1 + TEXT_AREA])
18657 {
18658 /* Save some values that must not be changed.
18659 Must save IT->c and IT->len because otherwise
18660 ITERATOR_AT_END_P wouldn't work anymore after
18661 append_space_for_newline has been called. */
18662 enum display_element_type saved_what = it->what;
18663 int saved_c = it->c, saved_len = it->len;
18664 int saved_char_to_display = it->char_to_display;
18665 int saved_x = it->current_x;
18666 int saved_face_id = it->face_id;
18667 struct text_pos saved_pos;
18668 Lisp_Object saved_object;
18669 struct face *face;
18670
18671 saved_object = it->object;
18672 saved_pos = it->position;
18673
18674 it->what = IT_CHARACTER;
18675 memset (&it->position, 0, sizeof it->position);
18676 it->object = make_number (0);
18677 it->c = it->char_to_display = ' ';
18678 it->len = 1;
18679
18680 /* If the default face was remapped, be sure to use the
18681 remapped face for the appended newline. */
18682 if (default_face_p)
18683 it->face_id = lookup_basic_face (it->f, DEFAULT_FACE_ID);
18684 else if (it->face_before_selective_p)
18685 it->face_id = it->saved_face_id;
18686 face = FACE_FROM_ID (it->f, it->face_id);
18687 it->face_id = FACE_FOR_CHAR (it->f, face, 0, -1, Qnil);
18688
18689 PRODUCE_GLYPHS (it);
18690
18691 it->override_ascent = -1;
18692 it->constrain_row_ascent_descent_p = 0;
18693 it->current_x = saved_x;
18694 it->object = saved_object;
18695 it->position = saved_pos;
18696 it->what = saved_what;
18697 it->face_id = saved_face_id;
18698 it->len = saved_len;
18699 it->c = saved_c;
18700 it->char_to_display = saved_char_to_display;
18701 return 1;
18702 }
18703 }
18704
18705 return 0;
18706 }
18707
18708
18709 /* Extend the face of the last glyph in the text area of IT->glyph_row
18710 to the end of the display line. Called from display_line. If the
18711 glyph row is empty, add a space glyph to it so that we know the
18712 face to draw. Set the glyph row flag fill_line_p. If the glyph
18713 row is R2L, prepend a stretch glyph to cover the empty space to the
18714 left of the leftmost glyph. */
18715
18716 static void
18717 extend_face_to_end_of_line (struct it *it)
18718 {
18719 struct face *face, *default_face;
18720 struct frame *f = it->f;
18721
18722 /* If line is already filled, do nothing. Non window-system frames
18723 get a grace of one more ``pixel'' because their characters are
18724 1-``pixel'' wide, so they hit the equality too early. This grace
18725 is needed only for R2L rows that are not continued, to produce
18726 one extra blank where we could display the cursor. */
18727 if (it->current_x >= it->last_visible_x
18728 + (!FRAME_WINDOW_P (f)
18729 && it->glyph_row->reversed_p
18730 && !it->glyph_row->continued_p))
18731 return;
18732
18733 /* The default face, possibly remapped. */
18734 default_face = FACE_FROM_ID (f, lookup_basic_face (f, DEFAULT_FACE_ID));
18735
18736 /* Face extension extends the background and box of IT->face_id
18737 to the end of the line. If the background equals the background
18738 of the frame, we don't have to do anything. */
18739 if (it->face_before_selective_p)
18740 face = FACE_FROM_ID (f, it->saved_face_id);
18741 else
18742 face = FACE_FROM_ID (f, it->face_id);
18743
18744 if (FRAME_WINDOW_P (f)
18745 && it->glyph_row->displays_text_p
18746 && face->box == FACE_NO_BOX
18747 && face->background == FRAME_BACKGROUND_PIXEL (f)
18748 && !face->stipple
18749 && !it->glyph_row->reversed_p)
18750 return;
18751
18752 /* Set the glyph row flag indicating that the face of the last glyph
18753 in the text area has to be drawn to the end of the text area. */
18754 it->glyph_row->fill_line_p = 1;
18755
18756 /* If current character of IT is not ASCII, make sure we have the
18757 ASCII face. This will be automatically undone the next time
18758 get_next_display_element returns a multibyte character. Note
18759 that the character will always be single byte in unibyte
18760 text. */
18761 if (!ASCII_CHAR_P (it->c))
18762 {
18763 it->face_id = FACE_FOR_CHAR (f, face, 0, -1, Qnil);
18764 }
18765
18766 if (FRAME_WINDOW_P (f))
18767 {
18768 /* If the row is empty, add a space with the current face of IT,
18769 so that we know which face to draw. */
18770 if (it->glyph_row->used[TEXT_AREA] == 0)
18771 {
18772 it->glyph_row->glyphs[TEXT_AREA][0] = space_glyph;
18773 it->glyph_row->glyphs[TEXT_AREA][0].face_id = face->id;
18774 it->glyph_row->used[TEXT_AREA] = 1;
18775 }
18776 #ifdef HAVE_WINDOW_SYSTEM
18777 if (it->glyph_row->reversed_p)
18778 {
18779 /* Prepend a stretch glyph to the row, such that the
18780 rightmost glyph will be drawn flushed all the way to the
18781 right margin of the window. The stretch glyph that will
18782 occupy the empty space, if any, to the left of the
18783 glyphs. */
18784 struct font *font = face->font ? face->font : FRAME_FONT (f);
18785 struct glyph *row_start = it->glyph_row->glyphs[TEXT_AREA];
18786 struct glyph *row_end = row_start + it->glyph_row->used[TEXT_AREA];
18787 struct glyph *g;
18788 int row_width, stretch_ascent, stretch_width;
18789 struct text_pos saved_pos;
18790 int saved_face_id, saved_avoid_cursor;
18791
18792 for (row_width = 0, g = row_start; g < row_end; g++)
18793 row_width += g->pixel_width;
18794 stretch_width = window_box_width (it->w, TEXT_AREA) - row_width;
18795 if (stretch_width > 0)
18796 {
18797 stretch_ascent =
18798 (((it->ascent + it->descent)
18799 * FONT_BASE (font)) / FONT_HEIGHT (font));
18800 saved_pos = it->position;
18801 memset (&it->position, 0, sizeof it->position);
18802 saved_avoid_cursor = it->avoid_cursor_p;
18803 it->avoid_cursor_p = 1;
18804 saved_face_id = it->face_id;
18805 /* The last row's stretch glyph should get the default
18806 face, to avoid painting the rest of the window with
18807 the region face, if the region ends at ZV. */
18808 if (it->glyph_row->ends_at_zv_p)
18809 it->face_id = default_face->id;
18810 else
18811 it->face_id = face->id;
18812 append_stretch_glyph (it, make_number (0), stretch_width,
18813 it->ascent + it->descent, stretch_ascent);
18814 it->position = saved_pos;
18815 it->avoid_cursor_p = saved_avoid_cursor;
18816 it->face_id = saved_face_id;
18817 }
18818 }
18819 #endif /* HAVE_WINDOW_SYSTEM */
18820 }
18821 else
18822 {
18823 /* Save some values that must not be changed. */
18824 int saved_x = it->current_x;
18825 struct text_pos saved_pos;
18826 Lisp_Object saved_object;
18827 enum display_element_type saved_what = it->what;
18828 int saved_face_id = it->face_id;
18829
18830 saved_object = it->object;
18831 saved_pos = it->position;
18832
18833 it->what = IT_CHARACTER;
18834 memset (&it->position, 0, sizeof it->position);
18835 it->object = make_number (0);
18836 it->c = it->char_to_display = ' ';
18837 it->len = 1;
18838 /* The last row's blank glyphs should get the default face, to
18839 avoid painting the rest of the window with the region face,
18840 if the region ends at ZV. */
18841 if (it->glyph_row->ends_at_zv_p)
18842 it->face_id = default_face->id;
18843 else
18844 it->face_id = face->id;
18845
18846 PRODUCE_GLYPHS (it);
18847
18848 while (it->current_x <= it->last_visible_x)
18849 PRODUCE_GLYPHS (it);
18850
18851 /* Don't count these blanks really. It would let us insert a left
18852 truncation glyph below and make us set the cursor on them, maybe. */
18853 it->current_x = saved_x;
18854 it->object = saved_object;
18855 it->position = saved_pos;
18856 it->what = saved_what;
18857 it->face_id = saved_face_id;
18858 }
18859 }
18860
18861
18862 /* Value is non-zero if text starting at CHARPOS in current_buffer is
18863 trailing whitespace. */
18864
18865 static int
18866 trailing_whitespace_p (ptrdiff_t charpos)
18867 {
18868 ptrdiff_t bytepos = CHAR_TO_BYTE (charpos);
18869 int c = 0;
18870
18871 while (bytepos < ZV_BYTE
18872 && (c = FETCH_CHAR (bytepos),
18873 c == ' ' || c == '\t'))
18874 ++bytepos;
18875
18876 if (bytepos >= ZV_BYTE || c == '\n' || c == '\r')
18877 {
18878 if (bytepos != PT_BYTE)
18879 return 1;
18880 }
18881 return 0;
18882 }
18883
18884
18885 /* Highlight trailing whitespace, if any, in ROW. */
18886
18887 static void
18888 highlight_trailing_whitespace (struct frame *f, struct glyph_row *row)
18889 {
18890 int used = row->used[TEXT_AREA];
18891
18892 if (used)
18893 {
18894 struct glyph *start = row->glyphs[TEXT_AREA];
18895 struct glyph *glyph = start + used - 1;
18896
18897 if (row->reversed_p)
18898 {
18899 /* Right-to-left rows need to be processed in the opposite
18900 direction, so swap the edge pointers. */
18901 glyph = start;
18902 start = row->glyphs[TEXT_AREA] + used - 1;
18903 }
18904
18905 /* Skip over glyphs inserted to display the cursor at the
18906 end of a line, for extending the face of the last glyph
18907 to the end of the line on terminals, and for truncation
18908 and continuation glyphs. */
18909 if (!row->reversed_p)
18910 {
18911 while (glyph >= start
18912 && glyph->type == CHAR_GLYPH
18913 && INTEGERP (glyph->object))
18914 --glyph;
18915 }
18916 else
18917 {
18918 while (glyph <= start
18919 && glyph->type == CHAR_GLYPH
18920 && INTEGERP (glyph->object))
18921 ++glyph;
18922 }
18923
18924 /* If last glyph is a space or stretch, and it's trailing
18925 whitespace, set the face of all trailing whitespace glyphs in
18926 IT->glyph_row to `trailing-whitespace'. */
18927 if ((row->reversed_p ? glyph <= start : glyph >= start)
18928 && BUFFERP (glyph->object)
18929 && (glyph->type == STRETCH_GLYPH
18930 || (glyph->type == CHAR_GLYPH
18931 && glyph->u.ch == ' '))
18932 && trailing_whitespace_p (glyph->charpos))
18933 {
18934 int face_id = lookup_named_face (f, Qtrailing_whitespace, 0);
18935 if (face_id < 0)
18936 return;
18937
18938 if (!row->reversed_p)
18939 {
18940 while (glyph >= start
18941 && BUFFERP (glyph->object)
18942 && (glyph->type == STRETCH_GLYPH
18943 || (glyph->type == CHAR_GLYPH
18944 && glyph->u.ch == ' ')))
18945 (glyph--)->face_id = face_id;
18946 }
18947 else
18948 {
18949 while (glyph <= start
18950 && BUFFERP (glyph->object)
18951 && (glyph->type == STRETCH_GLYPH
18952 || (glyph->type == CHAR_GLYPH
18953 && glyph->u.ch == ' ')))
18954 (glyph++)->face_id = face_id;
18955 }
18956 }
18957 }
18958 }
18959
18960
18961 /* Value is non-zero if glyph row ROW should be
18962 used to hold the cursor. */
18963
18964 static int
18965 cursor_row_p (struct glyph_row *row)
18966 {
18967 int result = 1;
18968
18969 if (PT == CHARPOS (row->end.pos)
18970 || PT == MATRIX_ROW_END_CHARPOS (row))
18971 {
18972 /* Suppose the row ends on a string.
18973 Unless the row is continued, that means it ends on a newline
18974 in the string. If it's anything other than a display string
18975 (e.g., a before-string from an overlay), we don't want the
18976 cursor there. (This heuristic seems to give the optimal
18977 behavior for the various types of multi-line strings.)
18978 One exception: if the string has `cursor' property on one of
18979 its characters, we _do_ want the cursor there. */
18980 if (CHARPOS (row->end.string_pos) >= 0)
18981 {
18982 if (row->continued_p)
18983 result = 1;
18984 else
18985 {
18986 /* Check for `display' property. */
18987 struct glyph *beg = row->glyphs[TEXT_AREA];
18988 struct glyph *end = beg + row->used[TEXT_AREA] - 1;
18989 struct glyph *glyph;
18990
18991 result = 0;
18992 for (glyph = end; glyph >= beg; --glyph)
18993 if (STRINGP (glyph->object))
18994 {
18995 Lisp_Object prop
18996 = Fget_char_property (make_number (PT),
18997 Qdisplay, Qnil);
18998 result =
18999 (!NILP (prop)
19000 && display_prop_string_p (prop, glyph->object));
19001 /* If there's a `cursor' property on one of the
19002 string's characters, this row is a cursor row,
19003 even though this is not a display string. */
19004 if (!result)
19005 {
19006 Lisp_Object s = glyph->object;
19007
19008 for ( ; glyph >= beg && EQ (glyph->object, s); --glyph)
19009 {
19010 ptrdiff_t gpos = glyph->charpos;
19011
19012 if (!NILP (Fget_char_property (make_number (gpos),
19013 Qcursor, s)))
19014 {
19015 result = 1;
19016 break;
19017 }
19018 }
19019 }
19020 break;
19021 }
19022 }
19023 }
19024 else if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
19025 {
19026 /* If the row ends in middle of a real character,
19027 and the line is continued, we want the cursor here.
19028 That's because CHARPOS (ROW->end.pos) would equal
19029 PT if PT is before the character. */
19030 if (!row->ends_in_ellipsis_p)
19031 result = row->continued_p;
19032 else
19033 /* If the row ends in an ellipsis, then
19034 CHARPOS (ROW->end.pos) will equal point after the
19035 invisible text. We want that position to be displayed
19036 after the ellipsis. */
19037 result = 0;
19038 }
19039 /* If the row ends at ZV, display the cursor at the end of that
19040 row instead of at the start of the row below. */
19041 else if (row->ends_at_zv_p)
19042 result = 1;
19043 else
19044 result = 0;
19045 }
19046
19047 return result;
19048 }
19049
19050 \f
19051
19052 /* Push the property PROP so that it will be rendered at the current
19053 position in IT. Return 1 if PROP was successfully pushed, 0
19054 otherwise. Called from handle_line_prefix to handle the
19055 `line-prefix' and `wrap-prefix' properties. */
19056
19057 static int
19058 push_prefix_prop (struct it *it, Lisp_Object prop)
19059 {
19060 struct text_pos pos =
19061 STRINGP (it->string) ? it->current.string_pos : it->current.pos;
19062
19063 eassert (it->method == GET_FROM_BUFFER
19064 || it->method == GET_FROM_DISPLAY_VECTOR
19065 || it->method == GET_FROM_STRING);
19066
19067 /* We need to save the current buffer/string position, so it will be
19068 restored by pop_it, because iterate_out_of_display_property
19069 depends on that being set correctly, but some situations leave
19070 it->position not yet set when this function is called. */
19071 push_it (it, &pos);
19072
19073 if (STRINGP (prop))
19074 {
19075 if (SCHARS (prop) == 0)
19076 {
19077 pop_it (it);
19078 return 0;
19079 }
19080
19081 it->string = prop;
19082 it->string_from_prefix_prop_p = 1;
19083 it->multibyte_p = STRING_MULTIBYTE (it->string);
19084 it->current.overlay_string_index = -1;
19085 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
19086 it->end_charpos = it->string_nchars = SCHARS (it->string);
19087 it->method = GET_FROM_STRING;
19088 it->stop_charpos = 0;
19089 it->prev_stop = 0;
19090 it->base_level_stop = 0;
19091
19092 /* Force paragraph direction to be that of the parent
19093 buffer/string. */
19094 if (it->bidi_p && it->bidi_it.paragraph_dir == R2L)
19095 it->paragraph_embedding = it->bidi_it.paragraph_dir;
19096 else
19097 it->paragraph_embedding = L2R;
19098
19099 /* Set up the bidi iterator for this display string. */
19100 if (it->bidi_p)
19101 {
19102 it->bidi_it.string.lstring = it->string;
19103 it->bidi_it.string.s = NULL;
19104 it->bidi_it.string.schars = it->end_charpos;
19105 it->bidi_it.string.bufpos = IT_CHARPOS (*it);
19106 it->bidi_it.string.from_disp_str = it->string_from_display_prop_p;
19107 it->bidi_it.string.unibyte = !it->multibyte_p;
19108 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
19109 }
19110 }
19111 else if (CONSP (prop) && EQ (XCAR (prop), Qspace))
19112 {
19113 it->method = GET_FROM_STRETCH;
19114 it->object = prop;
19115 }
19116 #ifdef HAVE_WINDOW_SYSTEM
19117 else if (IMAGEP (prop))
19118 {
19119 it->what = IT_IMAGE;
19120 it->image_id = lookup_image (it->f, prop);
19121 it->method = GET_FROM_IMAGE;
19122 }
19123 #endif /* HAVE_WINDOW_SYSTEM */
19124 else
19125 {
19126 pop_it (it); /* bogus display property, give up */
19127 return 0;
19128 }
19129
19130 return 1;
19131 }
19132
19133 /* Return the character-property PROP at the current position in IT. */
19134
19135 static Lisp_Object
19136 get_it_property (struct it *it, Lisp_Object prop)
19137 {
19138 Lisp_Object position;
19139
19140 if (STRINGP (it->object))
19141 position = make_number (IT_STRING_CHARPOS (*it));
19142 else if (BUFFERP (it->object))
19143 position = make_number (IT_CHARPOS (*it));
19144 else
19145 return Qnil;
19146
19147 return Fget_char_property (position, prop, it->object);
19148 }
19149
19150 /* See if there's a line- or wrap-prefix, and if so, push it on IT. */
19151
19152 static void
19153 handle_line_prefix (struct it *it)
19154 {
19155 Lisp_Object prefix;
19156
19157 if (it->continuation_lines_width > 0)
19158 {
19159 prefix = get_it_property (it, Qwrap_prefix);
19160 if (NILP (prefix))
19161 prefix = Vwrap_prefix;
19162 }
19163 else
19164 {
19165 prefix = get_it_property (it, Qline_prefix);
19166 if (NILP (prefix))
19167 prefix = Vline_prefix;
19168 }
19169 if (! NILP (prefix) && push_prefix_prop (it, prefix))
19170 {
19171 /* If the prefix is wider than the window, and we try to wrap
19172 it, it would acquire its own wrap prefix, and so on till the
19173 iterator stack overflows. So, don't wrap the prefix. */
19174 it->line_wrap = TRUNCATE;
19175 it->avoid_cursor_p = 1;
19176 }
19177 }
19178
19179 \f
19180
19181 /* Remove N glyphs at the start of a reversed IT->glyph_row. Called
19182 only for R2L lines from display_line and display_string, when they
19183 decide that too many glyphs were produced by PRODUCE_GLYPHS, and
19184 the line/string needs to be continued on the next glyph row. */
19185 static void
19186 unproduce_glyphs (struct it *it, int n)
19187 {
19188 struct glyph *glyph, *end;
19189
19190 eassert (it->glyph_row);
19191 eassert (it->glyph_row->reversed_p);
19192 eassert (it->area == TEXT_AREA);
19193 eassert (n <= it->glyph_row->used[TEXT_AREA]);
19194
19195 if (n > it->glyph_row->used[TEXT_AREA])
19196 n = it->glyph_row->used[TEXT_AREA];
19197 glyph = it->glyph_row->glyphs[TEXT_AREA] + n;
19198 end = it->glyph_row->glyphs[TEXT_AREA] + it->glyph_row->used[TEXT_AREA];
19199 for ( ; glyph < end; glyph++)
19200 glyph[-n] = *glyph;
19201 }
19202
19203 /* Find the positions in a bidi-reordered ROW to serve as ROW->minpos
19204 and ROW->maxpos. */
19205 static void
19206 find_row_edges (struct it *it, struct glyph_row *row,
19207 ptrdiff_t min_pos, ptrdiff_t min_bpos,
19208 ptrdiff_t max_pos, ptrdiff_t max_bpos)
19209 {
19210 /* FIXME: Revisit this when glyph ``spilling'' in continuation
19211 lines' rows is implemented for bidi-reordered rows. */
19212
19213 /* ROW->minpos is the value of min_pos, the minimal buffer position
19214 we have in ROW, or ROW->start.pos if that is smaller. */
19215 if (min_pos <= ZV && min_pos < row->start.pos.charpos)
19216 SET_TEXT_POS (row->minpos, min_pos, min_bpos);
19217 else
19218 /* We didn't find buffer positions smaller than ROW->start, or
19219 didn't find _any_ valid buffer positions in any of the glyphs,
19220 so we must trust the iterator's computed positions. */
19221 row->minpos = row->start.pos;
19222 if (max_pos <= 0)
19223 {
19224 max_pos = CHARPOS (it->current.pos);
19225 max_bpos = BYTEPOS (it->current.pos);
19226 }
19227
19228 /* Here are the various use-cases for ending the row, and the
19229 corresponding values for ROW->maxpos:
19230
19231 Line ends in a newline from buffer eol_pos + 1
19232 Line is continued from buffer max_pos + 1
19233 Line is truncated on right it->current.pos
19234 Line ends in a newline from string max_pos + 1(*)
19235 (*) + 1 only when line ends in a forward scan
19236 Line is continued from string max_pos
19237 Line is continued from display vector max_pos
19238 Line is entirely from a string min_pos == max_pos
19239 Line is entirely from a display vector min_pos == max_pos
19240 Line that ends at ZV ZV
19241
19242 If you discover other use-cases, please add them here as
19243 appropriate. */
19244 if (row->ends_at_zv_p)
19245 row->maxpos = it->current.pos;
19246 else if (row->used[TEXT_AREA])
19247 {
19248 int seen_this_string = 0;
19249 struct glyph_row *r1 = row - 1;
19250
19251 /* Did we see the same display string on the previous row? */
19252 if (STRINGP (it->object)
19253 /* this is not the first row */
19254 && row > it->w->desired_matrix->rows
19255 /* previous row is not the header line */
19256 && !r1->mode_line_p
19257 /* previous row also ends in a newline from a string */
19258 && r1->ends_in_newline_from_string_p)
19259 {
19260 struct glyph *start, *end;
19261
19262 /* Search for the last glyph of the previous row that came
19263 from buffer or string. Depending on whether the row is
19264 L2R or R2L, we need to process it front to back or the
19265 other way round. */
19266 if (!r1->reversed_p)
19267 {
19268 start = r1->glyphs[TEXT_AREA];
19269 end = start + r1->used[TEXT_AREA];
19270 /* Glyphs inserted by redisplay have an integer (zero)
19271 as their object. */
19272 while (end > start
19273 && INTEGERP ((end - 1)->object)
19274 && (end - 1)->charpos <= 0)
19275 --end;
19276 if (end > start)
19277 {
19278 if (EQ ((end - 1)->object, it->object))
19279 seen_this_string = 1;
19280 }
19281 else
19282 /* If all the glyphs of the previous row were inserted
19283 by redisplay, it means the previous row was
19284 produced from a single newline, which is only
19285 possible if that newline came from the same string
19286 as the one which produced this ROW. */
19287 seen_this_string = 1;
19288 }
19289 else
19290 {
19291 end = r1->glyphs[TEXT_AREA] - 1;
19292 start = end + r1->used[TEXT_AREA];
19293 while (end < start
19294 && INTEGERP ((end + 1)->object)
19295 && (end + 1)->charpos <= 0)
19296 ++end;
19297 if (end < start)
19298 {
19299 if (EQ ((end + 1)->object, it->object))
19300 seen_this_string = 1;
19301 }
19302 else
19303 seen_this_string = 1;
19304 }
19305 }
19306 /* Take note of each display string that covers a newline only
19307 once, the first time we see it. This is for when a display
19308 string includes more than one newline in it. */
19309 if (row->ends_in_newline_from_string_p && !seen_this_string)
19310 {
19311 /* If we were scanning the buffer forward when we displayed
19312 the string, we want to account for at least one buffer
19313 position that belongs to this row (position covered by
19314 the display string), so that cursor positioning will
19315 consider this row as a candidate when point is at the end
19316 of the visual line represented by this row. This is not
19317 required when scanning back, because max_pos will already
19318 have a much larger value. */
19319 if (CHARPOS (row->end.pos) > max_pos)
19320 INC_BOTH (max_pos, max_bpos);
19321 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
19322 }
19323 else if (CHARPOS (it->eol_pos) > 0)
19324 SET_TEXT_POS (row->maxpos,
19325 CHARPOS (it->eol_pos) + 1, BYTEPOS (it->eol_pos) + 1);
19326 else if (row->continued_p)
19327 {
19328 /* If max_pos is different from IT's current position, it
19329 means IT->method does not belong to the display element
19330 at max_pos. However, it also means that the display
19331 element at max_pos was displayed in its entirety on this
19332 line, which is equivalent to saying that the next line
19333 starts at the next buffer position. */
19334 if (IT_CHARPOS (*it) == max_pos && it->method != GET_FROM_BUFFER)
19335 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
19336 else
19337 {
19338 INC_BOTH (max_pos, max_bpos);
19339 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
19340 }
19341 }
19342 else if (row->truncated_on_right_p)
19343 /* display_line already called reseat_at_next_visible_line_start,
19344 which puts the iterator at the beginning of the next line, in
19345 the logical order. */
19346 row->maxpos = it->current.pos;
19347 else if (max_pos == min_pos && it->method != GET_FROM_BUFFER)
19348 /* A line that is entirely from a string/image/stretch... */
19349 row->maxpos = row->minpos;
19350 else
19351 emacs_abort ();
19352 }
19353 else
19354 row->maxpos = it->current.pos;
19355 }
19356
19357 /* Construct the glyph row IT->glyph_row in the desired matrix of
19358 IT->w from text at the current position of IT. See dispextern.h
19359 for an overview of struct it. Value is non-zero if
19360 IT->glyph_row displays text, as opposed to a line displaying ZV
19361 only. */
19362
19363 static int
19364 display_line (struct it *it)
19365 {
19366 struct glyph_row *row = it->glyph_row;
19367 Lisp_Object overlay_arrow_string;
19368 struct it wrap_it;
19369 void *wrap_data = NULL;
19370 int may_wrap = 0, wrap_x IF_LINT (= 0);
19371 int wrap_row_used = -1;
19372 int wrap_row_ascent IF_LINT (= 0), wrap_row_height IF_LINT (= 0);
19373 int wrap_row_phys_ascent IF_LINT (= 0), wrap_row_phys_height IF_LINT (= 0);
19374 int wrap_row_extra_line_spacing IF_LINT (= 0);
19375 ptrdiff_t wrap_row_min_pos IF_LINT (= 0), wrap_row_min_bpos IF_LINT (= 0);
19376 ptrdiff_t wrap_row_max_pos IF_LINT (= 0), wrap_row_max_bpos IF_LINT (= 0);
19377 int cvpos;
19378 ptrdiff_t min_pos = ZV + 1, max_pos = 0;
19379 ptrdiff_t min_bpos IF_LINT (= 0), max_bpos IF_LINT (= 0);
19380
19381 /* We always start displaying at hpos zero even if hscrolled. */
19382 eassert (it->hpos == 0 && it->current_x == 0);
19383
19384 if (MATRIX_ROW_VPOS (row, it->w->desired_matrix)
19385 >= it->w->desired_matrix->nrows)
19386 {
19387 it->w->nrows_scale_factor++;
19388 fonts_changed_p = 1;
19389 return 0;
19390 }
19391
19392 /* Is IT->w showing the region? */
19393 wset_region_showing (it->w, it->region_beg_charpos > 0 ? Qt : Qnil);
19394
19395 /* Clear the result glyph row and enable it. */
19396 prepare_desired_row (row);
19397
19398 row->y = it->current_y;
19399 row->start = it->start;
19400 row->continuation_lines_width = it->continuation_lines_width;
19401 row->displays_text_p = 1;
19402 row->starts_in_middle_of_char_p = it->starts_in_middle_of_char_p;
19403 it->starts_in_middle_of_char_p = 0;
19404
19405 /* Arrange the overlays nicely for our purposes. Usually, we call
19406 display_line on only one line at a time, in which case this
19407 can't really hurt too much, or we call it on lines which appear
19408 one after another in the buffer, in which case all calls to
19409 recenter_overlay_lists but the first will be pretty cheap. */
19410 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
19411
19412 /* Move over display elements that are not visible because we are
19413 hscrolled. This may stop at an x-position < IT->first_visible_x
19414 if the first glyph is partially visible or if we hit a line end. */
19415 if (it->current_x < it->first_visible_x)
19416 {
19417 enum move_it_result move_result;
19418
19419 this_line_min_pos = row->start.pos;
19420 move_result = move_it_in_display_line_to (it, ZV, it->first_visible_x,
19421 MOVE_TO_POS | MOVE_TO_X);
19422 /* If we are under a large hscroll, move_it_in_display_line_to
19423 could hit the end of the line without reaching
19424 it->first_visible_x. Pretend that we did reach it. This is
19425 especially important on a TTY, where we will call
19426 extend_face_to_end_of_line, which needs to know how many
19427 blank glyphs to produce. */
19428 if (it->current_x < it->first_visible_x
19429 && (move_result == MOVE_NEWLINE_OR_CR
19430 || move_result == MOVE_POS_MATCH_OR_ZV))
19431 it->current_x = it->first_visible_x;
19432
19433 /* Record the smallest positions seen while we moved over
19434 display elements that are not visible. This is needed by
19435 redisplay_internal for optimizing the case where the cursor
19436 stays inside the same line. The rest of this function only
19437 considers positions that are actually displayed, so
19438 RECORD_MAX_MIN_POS will not otherwise record positions that
19439 are hscrolled to the left of the left edge of the window. */
19440 min_pos = CHARPOS (this_line_min_pos);
19441 min_bpos = BYTEPOS (this_line_min_pos);
19442 }
19443 else
19444 {
19445 /* We only do this when not calling `move_it_in_display_line_to'
19446 above, because move_it_in_display_line_to calls
19447 handle_line_prefix itself. */
19448 handle_line_prefix (it);
19449 }
19450
19451 /* Get the initial row height. This is either the height of the
19452 text hscrolled, if there is any, or zero. */
19453 row->ascent = it->max_ascent;
19454 row->height = it->max_ascent + it->max_descent;
19455 row->phys_ascent = it->max_phys_ascent;
19456 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
19457 row->extra_line_spacing = it->max_extra_line_spacing;
19458
19459 /* Utility macro to record max and min buffer positions seen until now. */
19460 #define RECORD_MAX_MIN_POS(IT) \
19461 do \
19462 { \
19463 int composition_p = !STRINGP ((IT)->string) \
19464 && ((IT)->what == IT_COMPOSITION); \
19465 ptrdiff_t current_pos = \
19466 composition_p ? (IT)->cmp_it.charpos \
19467 : IT_CHARPOS (*(IT)); \
19468 ptrdiff_t current_bpos = \
19469 composition_p ? CHAR_TO_BYTE (current_pos) \
19470 : IT_BYTEPOS (*(IT)); \
19471 if (current_pos < min_pos) \
19472 { \
19473 min_pos = current_pos; \
19474 min_bpos = current_bpos; \
19475 } \
19476 if (IT_CHARPOS (*it) > max_pos) \
19477 { \
19478 max_pos = IT_CHARPOS (*it); \
19479 max_bpos = IT_BYTEPOS (*it); \
19480 } \
19481 } \
19482 while (0)
19483
19484 /* Loop generating characters. The loop is left with IT on the next
19485 character to display. */
19486 while (1)
19487 {
19488 int n_glyphs_before, hpos_before, x_before;
19489 int x, nglyphs;
19490 int ascent = 0, descent = 0, phys_ascent = 0, phys_descent = 0;
19491
19492 /* Retrieve the next thing to display. Value is zero if end of
19493 buffer reached. */
19494 if (!get_next_display_element (it))
19495 {
19496 /* Maybe add a space at the end of this line that is used to
19497 display the cursor there under X. Set the charpos of the
19498 first glyph of blank lines not corresponding to any text
19499 to -1. */
19500 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
19501 row->exact_window_width_line_p = 1;
19502 else if ((append_space_for_newline (it, 1) && row->used[TEXT_AREA] == 1)
19503 || row->used[TEXT_AREA] == 0)
19504 {
19505 row->glyphs[TEXT_AREA]->charpos = -1;
19506 row->displays_text_p = 0;
19507
19508 if (!NILP (BVAR (XBUFFER (it->w->buffer), indicate_empty_lines))
19509 && (!MINI_WINDOW_P (it->w)
19510 || (minibuf_level && EQ (it->window, minibuf_window))))
19511 row->indicate_empty_line_p = 1;
19512 }
19513
19514 it->continuation_lines_width = 0;
19515 row->ends_at_zv_p = 1;
19516 /* A row that displays right-to-left text must always have
19517 its last face extended all the way to the end of line,
19518 even if this row ends in ZV, because we still write to
19519 the screen left to right. We also need to extend the
19520 last face if the default face is remapped to some
19521 different face, otherwise the functions that clear
19522 portions of the screen will clear with the default face's
19523 background color. */
19524 if (row->reversed_p
19525 || lookup_basic_face (it->f, DEFAULT_FACE_ID) != DEFAULT_FACE_ID)
19526 extend_face_to_end_of_line (it);
19527 break;
19528 }
19529
19530 /* Now, get the metrics of what we want to display. This also
19531 generates glyphs in `row' (which is IT->glyph_row). */
19532 n_glyphs_before = row->used[TEXT_AREA];
19533 x = it->current_x;
19534
19535 /* Remember the line height so far in case the next element doesn't
19536 fit on the line. */
19537 if (it->line_wrap != TRUNCATE)
19538 {
19539 ascent = it->max_ascent;
19540 descent = it->max_descent;
19541 phys_ascent = it->max_phys_ascent;
19542 phys_descent = it->max_phys_descent;
19543
19544 if (it->line_wrap == WORD_WRAP && it->area == TEXT_AREA)
19545 {
19546 if (IT_DISPLAYING_WHITESPACE (it))
19547 may_wrap = 1;
19548 else if (may_wrap)
19549 {
19550 SAVE_IT (wrap_it, *it, wrap_data);
19551 wrap_x = x;
19552 wrap_row_used = row->used[TEXT_AREA];
19553 wrap_row_ascent = row->ascent;
19554 wrap_row_height = row->height;
19555 wrap_row_phys_ascent = row->phys_ascent;
19556 wrap_row_phys_height = row->phys_height;
19557 wrap_row_extra_line_spacing = row->extra_line_spacing;
19558 wrap_row_min_pos = min_pos;
19559 wrap_row_min_bpos = min_bpos;
19560 wrap_row_max_pos = max_pos;
19561 wrap_row_max_bpos = max_bpos;
19562 may_wrap = 0;
19563 }
19564 }
19565 }
19566
19567 PRODUCE_GLYPHS (it);
19568
19569 /* If this display element was in marginal areas, continue with
19570 the next one. */
19571 if (it->area != TEXT_AREA)
19572 {
19573 row->ascent = max (row->ascent, it->max_ascent);
19574 row->height = max (row->height, it->max_ascent + it->max_descent);
19575 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
19576 row->phys_height = max (row->phys_height,
19577 it->max_phys_ascent + it->max_phys_descent);
19578 row->extra_line_spacing = max (row->extra_line_spacing,
19579 it->max_extra_line_spacing);
19580 set_iterator_to_next (it, 1);
19581 continue;
19582 }
19583
19584 /* Does the display element fit on the line? If we truncate
19585 lines, we should draw past the right edge of the window. If
19586 we don't truncate, we want to stop so that we can display the
19587 continuation glyph before the right margin. If lines are
19588 continued, there are two possible strategies for characters
19589 resulting in more than 1 glyph (e.g. tabs): Display as many
19590 glyphs as possible in this line and leave the rest for the
19591 continuation line, or display the whole element in the next
19592 line. Original redisplay did the former, so we do it also. */
19593 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
19594 hpos_before = it->hpos;
19595 x_before = x;
19596
19597 if (/* Not a newline. */
19598 nglyphs > 0
19599 /* Glyphs produced fit entirely in the line. */
19600 && it->current_x < it->last_visible_x)
19601 {
19602 it->hpos += nglyphs;
19603 row->ascent = max (row->ascent, it->max_ascent);
19604 row->height = max (row->height, it->max_ascent + it->max_descent);
19605 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
19606 row->phys_height = max (row->phys_height,
19607 it->max_phys_ascent + it->max_phys_descent);
19608 row->extra_line_spacing = max (row->extra_line_spacing,
19609 it->max_extra_line_spacing);
19610 if (it->current_x - it->pixel_width < it->first_visible_x)
19611 row->x = x - it->first_visible_x;
19612 /* Record the maximum and minimum buffer positions seen so
19613 far in glyphs that will be displayed by this row. */
19614 if (it->bidi_p)
19615 RECORD_MAX_MIN_POS (it);
19616 }
19617 else
19618 {
19619 int i, new_x;
19620 struct glyph *glyph;
19621
19622 for (i = 0; i < nglyphs; ++i, x = new_x)
19623 {
19624 glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
19625 new_x = x + glyph->pixel_width;
19626
19627 if (/* Lines are continued. */
19628 it->line_wrap != TRUNCATE
19629 && (/* Glyph doesn't fit on the line. */
19630 new_x > it->last_visible_x
19631 /* Or it fits exactly on a window system frame. */
19632 || (new_x == it->last_visible_x
19633 && FRAME_WINDOW_P (it->f)
19634 && (row->reversed_p
19635 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
19636 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)))))
19637 {
19638 /* End of a continued line. */
19639
19640 if (it->hpos == 0
19641 || (new_x == it->last_visible_x
19642 && FRAME_WINDOW_P (it->f)
19643 && (row->reversed_p
19644 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
19645 : WINDOW_RIGHT_FRINGE_WIDTH (it->w))))
19646 {
19647 /* Current glyph is the only one on the line or
19648 fits exactly on the line. We must continue
19649 the line because we can't draw the cursor
19650 after the glyph. */
19651 row->continued_p = 1;
19652 it->current_x = new_x;
19653 it->continuation_lines_width += new_x;
19654 ++it->hpos;
19655 if (i == nglyphs - 1)
19656 {
19657 /* If line-wrap is on, check if a previous
19658 wrap point was found. */
19659 if (wrap_row_used > 0
19660 /* Even if there is a previous wrap
19661 point, continue the line here as
19662 usual, if (i) the previous character
19663 was a space or tab AND (ii) the
19664 current character is not. */
19665 && (!may_wrap
19666 || IT_DISPLAYING_WHITESPACE (it)))
19667 goto back_to_wrap;
19668
19669 /* Record the maximum and minimum buffer
19670 positions seen so far in glyphs that will be
19671 displayed by this row. */
19672 if (it->bidi_p)
19673 RECORD_MAX_MIN_POS (it);
19674 set_iterator_to_next (it, 1);
19675 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
19676 {
19677 if (!get_next_display_element (it))
19678 {
19679 row->exact_window_width_line_p = 1;
19680 it->continuation_lines_width = 0;
19681 row->continued_p = 0;
19682 row->ends_at_zv_p = 1;
19683 }
19684 else if (ITERATOR_AT_END_OF_LINE_P (it))
19685 {
19686 row->continued_p = 0;
19687 row->exact_window_width_line_p = 1;
19688 }
19689 }
19690 }
19691 else if (it->bidi_p)
19692 RECORD_MAX_MIN_POS (it);
19693 }
19694 else if (CHAR_GLYPH_PADDING_P (*glyph)
19695 && !FRAME_WINDOW_P (it->f))
19696 {
19697 /* A padding glyph that doesn't fit on this line.
19698 This means the whole character doesn't fit
19699 on the line. */
19700 if (row->reversed_p)
19701 unproduce_glyphs (it, row->used[TEXT_AREA]
19702 - n_glyphs_before);
19703 row->used[TEXT_AREA] = n_glyphs_before;
19704
19705 /* Fill the rest of the row with continuation
19706 glyphs like in 20.x. */
19707 while (row->glyphs[TEXT_AREA] + row->used[TEXT_AREA]
19708 < row->glyphs[1 + TEXT_AREA])
19709 produce_special_glyphs (it, IT_CONTINUATION);
19710
19711 row->continued_p = 1;
19712 it->current_x = x_before;
19713 it->continuation_lines_width += x_before;
19714
19715 /* Restore the height to what it was before the
19716 element not fitting on the line. */
19717 it->max_ascent = ascent;
19718 it->max_descent = descent;
19719 it->max_phys_ascent = phys_ascent;
19720 it->max_phys_descent = phys_descent;
19721 }
19722 else if (wrap_row_used > 0)
19723 {
19724 back_to_wrap:
19725 if (row->reversed_p)
19726 unproduce_glyphs (it,
19727 row->used[TEXT_AREA] - wrap_row_used);
19728 RESTORE_IT (it, &wrap_it, wrap_data);
19729 it->continuation_lines_width += wrap_x;
19730 row->used[TEXT_AREA] = wrap_row_used;
19731 row->ascent = wrap_row_ascent;
19732 row->height = wrap_row_height;
19733 row->phys_ascent = wrap_row_phys_ascent;
19734 row->phys_height = wrap_row_phys_height;
19735 row->extra_line_spacing = wrap_row_extra_line_spacing;
19736 min_pos = wrap_row_min_pos;
19737 min_bpos = wrap_row_min_bpos;
19738 max_pos = wrap_row_max_pos;
19739 max_bpos = wrap_row_max_bpos;
19740 row->continued_p = 1;
19741 row->ends_at_zv_p = 0;
19742 row->exact_window_width_line_p = 0;
19743 it->continuation_lines_width += x;
19744
19745 /* Make sure that a non-default face is extended
19746 up to the right margin of the window. */
19747 extend_face_to_end_of_line (it);
19748 }
19749 else if (it->c == '\t' && FRAME_WINDOW_P (it->f))
19750 {
19751 /* A TAB that extends past the right edge of the
19752 window. This produces a single glyph on
19753 window system frames. We leave the glyph in
19754 this row and let it fill the row, but don't
19755 consume the TAB. */
19756 if ((row->reversed_p
19757 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
19758 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0)
19759 produce_special_glyphs (it, IT_CONTINUATION);
19760 it->continuation_lines_width += it->last_visible_x;
19761 row->ends_in_middle_of_char_p = 1;
19762 row->continued_p = 1;
19763 glyph->pixel_width = it->last_visible_x - x;
19764 it->starts_in_middle_of_char_p = 1;
19765 }
19766 else
19767 {
19768 /* Something other than a TAB that draws past
19769 the right edge of the window. Restore
19770 positions to values before the element. */
19771 if (row->reversed_p)
19772 unproduce_glyphs (it, row->used[TEXT_AREA]
19773 - (n_glyphs_before + i));
19774 row->used[TEXT_AREA] = n_glyphs_before + i;
19775
19776 /* Display continuation glyphs. */
19777 it->current_x = x_before;
19778 it->continuation_lines_width += x;
19779 if (!FRAME_WINDOW_P (it->f)
19780 || (row->reversed_p
19781 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
19782 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0)
19783 produce_special_glyphs (it, IT_CONTINUATION);
19784 row->continued_p = 1;
19785
19786 extend_face_to_end_of_line (it);
19787
19788 if (nglyphs > 1 && i > 0)
19789 {
19790 row->ends_in_middle_of_char_p = 1;
19791 it->starts_in_middle_of_char_p = 1;
19792 }
19793
19794 /* Restore the height to what it was before the
19795 element not fitting on the line. */
19796 it->max_ascent = ascent;
19797 it->max_descent = descent;
19798 it->max_phys_ascent = phys_ascent;
19799 it->max_phys_descent = phys_descent;
19800 }
19801
19802 break;
19803 }
19804 else if (new_x > it->first_visible_x)
19805 {
19806 /* Increment number of glyphs actually displayed. */
19807 ++it->hpos;
19808
19809 /* Record the maximum and minimum buffer positions
19810 seen so far in glyphs that will be displayed by
19811 this row. */
19812 if (it->bidi_p)
19813 RECORD_MAX_MIN_POS (it);
19814
19815 if (x < it->first_visible_x)
19816 /* Glyph is partially visible, i.e. row starts at
19817 negative X position. */
19818 row->x = x - it->first_visible_x;
19819 }
19820 else
19821 {
19822 /* Glyph is completely off the left margin of the
19823 window. This should not happen because of the
19824 move_it_in_display_line at the start of this
19825 function, unless the text display area of the
19826 window is empty. */
19827 eassert (it->first_visible_x <= it->last_visible_x);
19828 }
19829 }
19830 /* Even if this display element produced no glyphs at all,
19831 we want to record its position. */
19832 if (it->bidi_p && nglyphs == 0)
19833 RECORD_MAX_MIN_POS (it);
19834
19835 row->ascent = max (row->ascent, it->max_ascent);
19836 row->height = max (row->height, it->max_ascent + it->max_descent);
19837 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
19838 row->phys_height = max (row->phys_height,
19839 it->max_phys_ascent + it->max_phys_descent);
19840 row->extra_line_spacing = max (row->extra_line_spacing,
19841 it->max_extra_line_spacing);
19842
19843 /* End of this display line if row is continued. */
19844 if (row->continued_p || row->ends_at_zv_p)
19845 break;
19846 }
19847
19848 at_end_of_line:
19849 /* Is this a line end? If yes, we're also done, after making
19850 sure that a non-default face is extended up to the right
19851 margin of the window. */
19852 if (ITERATOR_AT_END_OF_LINE_P (it))
19853 {
19854 int used_before = row->used[TEXT_AREA];
19855
19856 row->ends_in_newline_from_string_p = STRINGP (it->object);
19857
19858 /* Add a space at the end of the line that is used to
19859 display the cursor there. */
19860 if (!IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
19861 append_space_for_newline (it, 0);
19862
19863 /* Extend the face to the end of the line. */
19864 extend_face_to_end_of_line (it);
19865
19866 /* Make sure we have the position. */
19867 if (used_before == 0)
19868 row->glyphs[TEXT_AREA]->charpos = CHARPOS (it->position);
19869
19870 /* Record the position of the newline, for use in
19871 find_row_edges. */
19872 it->eol_pos = it->current.pos;
19873
19874 /* Consume the line end. This skips over invisible lines. */
19875 set_iterator_to_next (it, 1);
19876 it->continuation_lines_width = 0;
19877 break;
19878 }
19879
19880 /* Proceed with next display element. Note that this skips
19881 over lines invisible because of selective display. */
19882 set_iterator_to_next (it, 1);
19883
19884 /* If we truncate lines, we are done when the last displayed
19885 glyphs reach past the right margin of the window. */
19886 if (it->line_wrap == TRUNCATE
19887 && (FRAME_WINDOW_P (it->f) && WINDOW_RIGHT_FRINGE_WIDTH (it->w)
19888 ? (it->current_x >= it->last_visible_x)
19889 : (it->current_x > it->last_visible_x)))
19890 {
19891 /* Maybe add truncation glyphs. */
19892 if (!FRAME_WINDOW_P (it->f)
19893 || (row->reversed_p
19894 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
19895 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0)
19896 {
19897 int i, n;
19898
19899 if (!row->reversed_p)
19900 {
19901 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
19902 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
19903 break;
19904 }
19905 else
19906 {
19907 for (i = 0; i < row->used[TEXT_AREA]; i++)
19908 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
19909 break;
19910 /* Remove any padding glyphs at the front of ROW, to
19911 make room for the truncation glyphs we will be
19912 adding below. The loop below always inserts at
19913 least one truncation glyph, so also remove the
19914 last glyph added to ROW. */
19915 unproduce_glyphs (it, i + 1);
19916 /* Adjust i for the loop below. */
19917 i = row->used[TEXT_AREA] - (i + 1);
19918 }
19919
19920 it->current_x = x_before;
19921 if (!FRAME_WINDOW_P (it->f))
19922 {
19923 for (n = row->used[TEXT_AREA]; i < n; ++i)
19924 {
19925 row->used[TEXT_AREA] = i;
19926 produce_special_glyphs (it, IT_TRUNCATION);
19927 }
19928 }
19929 else
19930 {
19931 row->used[TEXT_AREA] = i;
19932 produce_special_glyphs (it, IT_TRUNCATION);
19933 }
19934 }
19935 else if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
19936 {
19937 /* Don't truncate if we can overflow newline into fringe. */
19938 if (!get_next_display_element (it))
19939 {
19940 it->continuation_lines_width = 0;
19941 row->ends_at_zv_p = 1;
19942 row->exact_window_width_line_p = 1;
19943 break;
19944 }
19945 if (ITERATOR_AT_END_OF_LINE_P (it))
19946 {
19947 row->exact_window_width_line_p = 1;
19948 goto at_end_of_line;
19949 }
19950 it->current_x = x_before;
19951 }
19952
19953 row->truncated_on_right_p = 1;
19954 it->continuation_lines_width = 0;
19955 reseat_at_next_visible_line_start (it, 0);
19956 row->ends_at_zv_p = FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n';
19957 it->hpos = hpos_before;
19958 break;
19959 }
19960 }
19961
19962 if (wrap_data)
19963 bidi_unshelve_cache (wrap_data, 1);
19964
19965 /* If line is not empty and hscrolled, maybe insert truncation glyphs
19966 at the left window margin. */
19967 if (it->first_visible_x
19968 && IT_CHARPOS (*it) != CHARPOS (row->start.pos))
19969 {
19970 if (!FRAME_WINDOW_P (it->f)
19971 || (row->reversed_p
19972 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
19973 : WINDOW_LEFT_FRINGE_WIDTH (it->w)) == 0)
19974 insert_left_trunc_glyphs (it);
19975 row->truncated_on_left_p = 1;
19976 }
19977
19978 /* Remember the position at which this line ends.
19979
19980 BIDI Note: any code that needs MATRIX_ROW_START/END_CHARPOS
19981 cannot be before the call to find_row_edges below, since that is
19982 where these positions are determined. */
19983 row->end = it->current;
19984 if (!it->bidi_p)
19985 {
19986 row->minpos = row->start.pos;
19987 row->maxpos = row->end.pos;
19988 }
19989 else
19990 {
19991 /* ROW->minpos and ROW->maxpos must be the smallest and
19992 `1 + the largest' buffer positions in ROW. But if ROW was
19993 bidi-reordered, these two positions can be anywhere in the
19994 row, so we must determine them now. */
19995 find_row_edges (it, row, min_pos, min_bpos, max_pos, max_bpos);
19996 }
19997
19998 /* If the start of this line is the overlay arrow-position, then
19999 mark this glyph row as the one containing the overlay arrow.
20000 This is clearly a mess with variable size fonts. It would be
20001 better to let it be displayed like cursors under X. */
20002 if ((row->displays_text_p || !overlay_arrow_seen)
20003 && (overlay_arrow_string = overlay_arrow_at_row (it, row),
20004 !NILP (overlay_arrow_string)))
20005 {
20006 /* Overlay arrow in window redisplay is a fringe bitmap. */
20007 if (STRINGP (overlay_arrow_string))
20008 {
20009 struct glyph_row *arrow_row
20010 = get_overlay_arrow_glyph_row (it->w, overlay_arrow_string);
20011 struct glyph *glyph = arrow_row->glyphs[TEXT_AREA];
20012 struct glyph *arrow_end = glyph + arrow_row->used[TEXT_AREA];
20013 struct glyph *p = row->glyphs[TEXT_AREA];
20014 struct glyph *p2, *end;
20015
20016 /* Copy the arrow glyphs. */
20017 while (glyph < arrow_end)
20018 *p++ = *glyph++;
20019
20020 /* Throw away padding glyphs. */
20021 p2 = p;
20022 end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
20023 while (p2 < end && CHAR_GLYPH_PADDING_P (*p2))
20024 ++p2;
20025 if (p2 > p)
20026 {
20027 while (p2 < end)
20028 *p++ = *p2++;
20029 row->used[TEXT_AREA] = p2 - row->glyphs[TEXT_AREA];
20030 }
20031 }
20032 else
20033 {
20034 eassert (INTEGERP (overlay_arrow_string));
20035 row->overlay_arrow_bitmap = XINT (overlay_arrow_string);
20036 }
20037 overlay_arrow_seen = 1;
20038 }
20039
20040 /* Highlight trailing whitespace. */
20041 if (!NILP (Vshow_trailing_whitespace))
20042 highlight_trailing_whitespace (it->f, it->glyph_row);
20043
20044 /* Compute pixel dimensions of this line. */
20045 compute_line_metrics (it);
20046
20047 /* Implementation note: No changes in the glyphs of ROW or in their
20048 faces can be done past this point, because compute_line_metrics
20049 computes ROW's hash value and stores it within the glyph_row
20050 structure. */
20051
20052 /* Record whether this row ends inside an ellipsis. */
20053 row->ends_in_ellipsis_p
20054 = (it->method == GET_FROM_DISPLAY_VECTOR
20055 && it->ellipsis_p);
20056
20057 /* Save fringe bitmaps in this row. */
20058 row->left_user_fringe_bitmap = it->left_user_fringe_bitmap;
20059 row->left_user_fringe_face_id = it->left_user_fringe_face_id;
20060 row->right_user_fringe_bitmap = it->right_user_fringe_bitmap;
20061 row->right_user_fringe_face_id = it->right_user_fringe_face_id;
20062
20063 it->left_user_fringe_bitmap = 0;
20064 it->left_user_fringe_face_id = 0;
20065 it->right_user_fringe_bitmap = 0;
20066 it->right_user_fringe_face_id = 0;
20067
20068 /* Maybe set the cursor. */
20069 cvpos = it->w->cursor.vpos;
20070 if ((cvpos < 0
20071 /* In bidi-reordered rows, keep checking for proper cursor
20072 position even if one has been found already, because buffer
20073 positions in such rows change non-linearly with ROW->VPOS,
20074 when a line is continued. One exception: when we are at ZV,
20075 display cursor on the first suitable glyph row, since all
20076 the empty rows after that also have their position set to ZV. */
20077 /* FIXME: Revisit this when glyph ``spilling'' in continuation
20078 lines' rows is implemented for bidi-reordered rows. */
20079 || (it->bidi_p
20080 && !MATRIX_ROW (it->w->desired_matrix, cvpos)->ends_at_zv_p))
20081 && PT >= MATRIX_ROW_START_CHARPOS (row)
20082 && PT <= MATRIX_ROW_END_CHARPOS (row)
20083 && cursor_row_p (row))
20084 set_cursor_from_row (it->w, row, it->w->desired_matrix, 0, 0, 0, 0);
20085
20086 /* Prepare for the next line. This line starts horizontally at (X
20087 HPOS) = (0 0). Vertical positions are incremented. As a
20088 convenience for the caller, IT->glyph_row is set to the next
20089 row to be used. */
20090 it->current_x = it->hpos = 0;
20091 it->current_y += row->height;
20092 SET_TEXT_POS (it->eol_pos, 0, 0);
20093 ++it->vpos;
20094 ++it->glyph_row;
20095 /* The next row should by default use the same value of the
20096 reversed_p flag as this one. set_iterator_to_next decides when
20097 it's a new paragraph, and PRODUCE_GLYPHS recomputes the value of
20098 the flag accordingly. */
20099 if (it->glyph_row < MATRIX_BOTTOM_TEXT_ROW (it->w->desired_matrix, it->w))
20100 it->glyph_row->reversed_p = row->reversed_p;
20101 it->start = row->end;
20102 return row->displays_text_p;
20103
20104 #undef RECORD_MAX_MIN_POS
20105 }
20106
20107 DEFUN ("current-bidi-paragraph-direction", Fcurrent_bidi_paragraph_direction,
20108 Scurrent_bidi_paragraph_direction, 0, 1, 0,
20109 doc: /* Return paragraph direction at point in BUFFER.
20110 Value is either `left-to-right' or `right-to-left'.
20111 If BUFFER is omitted or nil, it defaults to the current buffer.
20112
20113 Paragraph direction determines how the text in the paragraph is displayed.
20114 In left-to-right paragraphs, text begins at the left margin of the window
20115 and the reading direction is generally left to right. In right-to-left
20116 paragraphs, text begins at the right margin and is read from right to left.
20117
20118 See also `bidi-paragraph-direction'. */)
20119 (Lisp_Object buffer)
20120 {
20121 struct buffer *buf = current_buffer;
20122 struct buffer *old = buf;
20123
20124 if (! NILP (buffer))
20125 {
20126 CHECK_BUFFER (buffer);
20127 buf = XBUFFER (buffer);
20128 }
20129
20130 if (NILP (BVAR (buf, bidi_display_reordering))
20131 || NILP (BVAR (buf, enable_multibyte_characters))
20132 /* When we are loading loadup.el, the character property tables
20133 needed for bidi iteration are not yet available. */
20134 || !NILP (Vpurify_flag))
20135 return Qleft_to_right;
20136 else if (!NILP (BVAR (buf, bidi_paragraph_direction)))
20137 return BVAR (buf, bidi_paragraph_direction);
20138 else
20139 {
20140 /* Determine the direction from buffer text. We could try to
20141 use current_matrix if it is up to date, but this seems fast
20142 enough as it is. */
20143 struct bidi_it itb;
20144 ptrdiff_t pos = BUF_PT (buf);
20145 ptrdiff_t bytepos = BUF_PT_BYTE (buf);
20146 int c;
20147 void *itb_data = bidi_shelve_cache ();
20148
20149 set_buffer_temp (buf);
20150 /* bidi_paragraph_init finds the base direction of the paragraph
20151 by searching forward from paragraph start. We need the base
20152 direction of the current or _previous_ paragraph, so we need
20153 to make sure we are within that paragraph. To that end, find
20154 the previous non-empty line. */
20155 if (pos >= ZV && pos > BEGV)
20156 {
20157 pos--;
20158 bytepos = CHAR_TO_BYTE (pos);
20159 }
20160 if (fast_looking_at (build_string ("[\f\t ]*\n"),
20161 pos, bytepos, ZV, ZV_BYTE, Qnil) > 0)
20162 {
20163 while ((c = FETCH_BYTE (bytepos)) == '\n'
20164 || c == ' ' || c == '\t' || c == '\f')
20165 {
20166 if (bytepos <= BEGV_BYTE)
20167 break;
20168 bytepos--;
20169 pos--;
20170 }
20171 while (!CHAR_HEAD_P (FETCH_BYTE (bytepos)))
20172 bytepos--;
20173 }
20174 bidi_init_it (pos, bytepos, FRAME_WINDOW_P (SELECTED_FRAME ()), &itb);
20175 itb.paragraph_dir = NEUTRAL_DIR;
20176 itb.string.s = NULL;
20177 itb.string.lstring = Qnil;
20178 itb.string.bufpos = 0;
20179 itb.string.unibyte = 0;
20180 bidi_paragraph_init (NEUTRAL_DIR, &itb, 1);
20181 bidi_unshelve_cache (itb_data, 0);
20182 set_buffer_temp (old);
20183 switch (itb.paragraph_dir)
20184 {
20185 case L2R:
20186 return Qleft_to_right;
20187 break;
20188 case R2L:
20189 return Qright_to_left;
20190 break;
20191 default:
20192 emacs_abort ();
20193 }
20194 }
20195 }
20196
20197
20198 \f
20199 /***********************************************************************
20200 Menu Bar
20201 ***********************************************************************/
20202
20203 /* Redisplay the menu bar in the frame for window W.
20204
20205 The menu bar of X frames that don't have X toolkit support is
20206 displayed in a special window W->frame->menu_bar_window.
20207
20208 The menu bar of terminal frames is treated specially as far as
20209 glyph matrices are concerned. Menu bar lines are not part of
20210 windows, so the update is done directly on the frame matrix rows
20211 for the menu bar. */
20212
20213 static void
20214 display_menu_bar (struct window *w)
20215 {
20216 struct frame *f = XFRAME (WINDOW_FRAME (w));
20217 struct it it;
20218 Lisp_Object items;
20219 int i;
20220
20221 /* Don't do all this for graphical frames. */
20222 #ifdef HAVE_NTGUI
20223 if (FRAME_W32_P (f))
20224 return;
20225 #endif
20226 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
20227 if (FRAME_X_P (f))
20228 return;
20229 #endif
20230
20231 #ifdef HAVE_NS
20232 if (FRAME_NS_P (f))
20233 return;
20234 #endif /* HAVE_NS */
20235
20236 #ifdef USE_X_TOOLKIT
20237 eassert (!FRAME_WINDOW_P (f));
20238 init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MENU_FACE_ID);
20239 it.first_visible_x = 0;
20240 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
20241 #else /* not USE_X_TOOLKIT */
20242 if (FRAME_WINDOW_P (f))
20243 {
20244 /* Menu bar lines are displayed in the desired matrix of the
20245 dummy window menu_bar_window. */
20246 struct window *menu_w;
20247 eassert (WINDOWP (f->menu_bar_window));
20248 menu_w = XWINDOW (f->menu_bar_window);
20249 init_iterator (&it, menu_w, -1, -1, menu_w->desired_matrix->rows,
20250 MENU_FACE_ID);
20251 it.first_visible_x = 0;
20252 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
20253 }
20254 else
20255 {
20256 /* This is a TTY frame, i.e. character hpos/vpos are used as
20257 pixel x/y. */
20258 init_iterator (&it, w, -1, -1, f->desired_matrix->rows,
20259 MENU_FACE_ID);
20260 it.first_visible_x = 0;
20261 it.last_visible_x = FRAME_COLS (f);
20262 }
20263 #endif /* not USE_X_TOOLKIT */
20264
20265 /* FIXME: This should be controlled by a user option. See the
20266 comments in redisplay_tool_bar and display_mode_line about
20267 this. */
20268 it.paragraph_embedding = L2R;
20269
20270 if (! mode_line_inverse_video)
20271 /* Force the menu-bar to be displayed in the default face. */
20272 it.base_face_id = it.face_id = DEFAULT_FACE_ID;
20273
20274 /* Clear all rows of the menu bar. */
20275 for (i = 0; i < FRAME_MENU_BAR_LINES (f); ++i)
20276 {
20277 struct glyph_row *row = it.glyph_row + i;
20278 clear_glyph_row (row);
20279 row->enabled_p = 1;
20280 row->full_width_p = 1;
20281 }
20282
20283 /* Display all items of the menu bar. */
20284 items = FRAME_MENU_BAR_ITEMS (it.f);
20285 for (i = 0; i < ASIZE (items); i += 4)
20286 {
20287 Lisp_Object string;
20288
20289 /* Stop at nil string. */
20290 string = AREF (items, i + 1);
20291 if (NILP (string))
20292 break;
20293
20294 /* Remember where item was displayed. */
20295 ASET (items, i + 3, make_number (it.hpos));
20296
20297 /* Display the item, pad with one space. */
20298 if (it.current_x < it.last_visible_x)
20299 display_string (NULL, string, Qnil, 0, 0, &it,
20300 SCHARS (string) + 1, 0, 0, -1);
20301 }
20302
20303 /* Fill out the line with spaces. */
20304 if (it.current_x < it.last_visible_x)
20305 display_string ("", Qnil, Qnil, 0, 0, &it, -1, 0, 0, -1);
20306
20307 /* Compute the total height of the lines. */
20308 compute_line_metrics (&it);
20309 }
20310
20311
20312 \f
20313 /***********************************************************************
20314 Mode Line
20315 ***********************************************************************/
20316
20317 /* Redisplay mode lines in the window tree whose root is WINDOW. If
20318 FORCE is non-zero, redisplay mode lines unconditionally.
20319 Otherwise, redisplay only mode lines that are garbaged. Value is
20320 the number of windows whose mode lines were redisplayed. */
20321
20322 static int
20323 redisplay_mode_lines (Lisp_Object window, int force)
20324 {
20325 int nwindows = 0;
20326
20327 while (!NILP (window))
20328 {
20329 struct window *w = XWINDOW (window);
20330
20331 if (WINDOWP (w->hchild))
20332 nwindows += redisplay_mode_lines (w->hchild, force);
20333 else if (WINDOWP (w->vchild))
20334 nwindows += redisplay_mode_lines (w->vchild, force);
20335 else if (force
20336 || FRAME_GARBAGED_P (XFRAME (w->frame))
20337 || !MATRIX_MODE_LINE_ROW (w->current_matrix)->enabled_p)
20338 {
20339 struct text_pos lpoint;
20340 struct buffer *old = current_buffer;
20341
20342 /* Set the window's buffer for the mode line display. */
20343 SET_TEXT_POS (lpoint, PT, PT_BYTE);
20344 set_buffer_internal_1 (XBUFFER (w->buffer));
20345
20346 /* Point refers normally to the selected window. For any
20347 other window, set up appropriate value. */
20348 if (!EQ (window, selected_window))
20349 {
20350 struct text_pos pt;
20351
20352 SET_TEXT_POS_FROM_MARKER (pt, w->pointm);
20353 if (CHARPOS (pt) < BEGV)
20354 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
20355 else if (CHARPOS (pt) > (ZV - 1))
20356 TEMP_SET_PT_BOTH (ZV, ZV_BYTE);
20357 else
20358 TEMP_SET_PT_BOTH (CHARPOS (pt), BYTEPOS (pt));
20359 }
20360
20361 /* Display mode lines. */
20362 clear_glyph_matrix (w->desired_matrix);
20363 if (display_mode_lines (w))
20364 {
20365 ++nwindows;
20366 w->must_be_updated_p = 1;
20367 }
20368
20369 /* Restore old settings. */
20370 set_buffer_internal_1 (old);
20371 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
20372 }
20373
20374 window = w->next;
20375 }
20376
20377 return nwindows;
20378 }
20379
20380
20381 /* Display the mode and/or header line of window W. Value is the
20382 sum number of mode lines and header lines displayed. */
20383
20384 static int
20385 display_mode_lines (struct window *w)
20386 {
20387 Lisp_Object old_selected_window, old_selected_frame;
20388 int n = 0;
20389
20390 old_selected_frame = selected_frame;
20391 selected_frame = w->frame;
20392 old_selected_window = selected_window;
20393 XSETWINDOW (selected_window, w);
20394
20395 /* These will be set while the mode line specs are processed. */
20396 line_number_displayed = 0;
20397 wset_column_number_displayed (w, Qnil);
20398
20399 if (WINDOW_WANTS_MODELINE_P (w))
20400 {
20401 struct window *sel_w = XWINDOW (old_selected_window);
20402
20403 /* Select mode line face based on the real selected window. */
20404 display_mode_line (w, CURRENT_MODE_LINE_FACE_ID_3 (sel_w, sel_w, w),
20405 BVAR (current_buffer, mode_line_format));
20406 ++n;
20407 }
20408
20409 if (WINDOW_WANTS_HEADER_LINE_P (w))
20410 {
20411 display_mode_line (w, HEADER_LINE_FACE_ID,
20412 BVAR (current_buffer, header_line_format));
20413 ++n;
20414 }
20415
20416 selected_frame = old_selected_frame;
20417 selected_window = old_selected_window;
20418 return n;
20419 }
20420
20421
20422 /* Display mode or header line of window W. FACE_ID specifies which
20423 line to display; it is either MODE_LINE_FACE_ID or
20424 HEADER_LINE_FACE_ID. FORMAT is the mode/header line format to
20425 display. Value is the pixel height of the mode/header line
20426 displayed. */
20427
20428 static int
20429 display_mode_line (struct window *w, enum face_id face_id, Lisp_Object format)
20430 {
20431 struct it it;
20432 struct face *face;
20433 ptrdiff_t count = SPECPDL_INDEX ();
20434
20435 init_iterator (&it, w, -1, -1, NULL, face_id);
20436 /* Don't extend on a previously drawn mode-line.
20437 This may happen if called from pos_visible_p. */
20438 it.glyph_row->enabled_p = 0;
20439 prepare_desired_row (it.glyph_row);
20440
20441 it.glyph_row->mode_line_p = 1;
20442
20443 if (! mode_line_inverse_video)
20444 /* Force the mode-line to be displayed in the default face. */
20445 it.base_face_id = it.face_id = DEFAULT_FACE_ID;
20446
20447 /* FIXME: This should be controlled by a user option. But
20448 supporting such an option is not trivial, since the mode line is
20449 made up of many separate strings. */
20450 it.paragraph_embedding = L2R;
20451
20452 record_unwind_protect (unwind_format_mode_line,
20453 format_mode_line_unwind_data (NULL, NULL, Qnil, 0));
20454
20455 mode_line_target = MODE_LINE_DISPLAY;
20456
20457 /* Temporarily make frame's keyboard the current kboard so that
20458 kboard-local variables in the mode_line_format will get the right
20459 values. */
20460 push_kboard (FRAME_KBOARD (it.f));
20461 record_unwind_save_match_data ();
20462 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
20463 pop_kboard ();
20464
20465 unbind_to (count, Qnil);
20466
20467 /* Fill up with spaces. */
20468 display_string (" ", Qnil, Qnil, 0, 0, &it, 10000, -1, -1, 0);
20469
20470 compute_line_metrics (&it);
20471 it.glyph_row->full_width_p = 1;
20472 it.glyph_row->continued_p = 0;
20473 it.glyph_row->truncated_on_left_p = 0;
20474 it.glyph_row->truncated_on_right_p = 0;
20475
20476 /* Make a 3D mode-line have a shadow at its right end. */
20477 face = FACE_FROM_ID (it.f, face_id);
20478 extend_face_to_end_of_line (&it);
20479 if (face->box != FACE_NO_BOX)
20480 {
20481 struct glyph *last = (it.glyph_row->glyphs[TEXT_AREA]
20482 + it.glyph_row->used[TEXT_AREA] - 1);
20483 last->right_box_line_p = 1;
20484 }
20485
20486 return it.glyph_row->height;
20487 }
20488
20489 /* Move element ELT in LIST to the front of LIST.
20490 Return the updated list. */
20491
20492 static Lisp_Object
20493 move_elt_to_front (Lisp_Object elt, Lisp_Object list)
20494 {
20495 register Lisp_Object tail, prev;
20496 register Lisp_Object tem;
20497
20498 tail = list;
20499 prev = Qnil;
20500 while (CONSP (tail))
20501 {
20502 tem = XCAR (tail);
20503
20504 if (EQ (elt, tem))
20505 {
20506 /* Splice out the link TAIL. */
20507 if (NILP (prev))
20508 list = XCDR (tail);
20509 else
20510 Fsetcdr (prev, XCDR (tail));
20511
20512 /* Now make it the first. */
20513 Fsetcdr (tail, list);
20514 return tail;
20515 }
20516 else
20517 prev = tail;
20518 tail = XCDR (tail);
20519 QUIT;
20520 }
20521
20522 /* Not found--return unchanged LIST. */
20523 return list;
20524 }
20525
20526 /* Contribute ELT to the mode line for window IT->w. How it
20527 translates into text depends on its data type.
20528
20529 IT describes the display environment in which we display, as usual.
20530
20531 DEPTH is the depth in recursion. It is used to prevent
20532 infinite recursion here.
20533
20534 FIELD_WIDTH is the number of characters the display of ELT should
20535 occupy in the mode line, and PRECISION is the maximum number of
20536 characters to display from ELT's representation. See
20537 display_string for details.
20538
20539 Returns the hpos of the end of the text generated by ELT.
20540
20541 PROPS is a property list to add to any string we encounter.
20542
20543 If RISKY is nonzero, remove (disregard) any properties in any string
20544 we encounter, and ignore :eval and :propertize.
20545
20546 The global variable `mode_line_target' determines whether the
20547 output is passed to `store_mode_line_noprop',
20548 `store_mode_line_string', or `display_string'. */
20549
20550 static int
20551 display_mode_element (struct it *it, int depth, int field_width, int precision,
20552 Lisp_Object elt, Lisp_Object props, int risky)
20553 {
20554 int n = 0, field, prec;
20555 int literal = 0;
20556
20557 tail_recurse:
20558 if (depth > 100)
20559 elt = build_string ("*too-deep*");
20560
20561 depth++;
20562
20563 switch (XTYPE (elt))
20564 {
20565 case Lisp_String:
20566 {
20567 /* A string: output it and check for %-constructs within it. */
20568 unsigned char c;
20569 ptrdiff_t offset = 0;
20570
20571 if (SCHARS (elt) > 0
20572 && (!NILP (props) || risky))
20573 {
20574 Lisp_Object oprops, aelt;
20575 oprops = Ftext_properties_at (make_number (0), elt);
20576
20577 /* If the starting string's properties are not what
20578 we want, translate the string. Also, if the string
20579 is risky, do that anyway. */
20580
20581 if (NILP (Fequal (props, oprops)) || risky)
20582 {
20583 /* If the starting string has properties,
20584 merge the specified ones onto the existing ones. */
20585 if (! NILP (oprops) && !risky)
20586 {
20587 Lisp_Object tem;
20588
20589 oprops = Fcopy_sequence (oprops);
20590 tem = props;
20591 while (CONSP (tem))
20592 {
20593 oprops = Fplist_put (oprops, XCAR (tem),
20594 XCAR (XCDR (tem)));
20595 tem = XCDR (XCDR (tem));
20596 }
20597 props = oprops;
20598 }
20599
20600 aelt = Fassoc (elt, mode_line_proptrans_alist);
20601 if (! NILP (aelt) && !NILP (Fequal (props, XCDR (aelt))))
20602 {
20603 /* AELT is what we want. Move it to the front
20604 without consing. */
20605 elt = XCAR (aelt);
20606 mode_line_proptrans_alist
20607 = move_elt_to_front (aelt, mode_line_proptrans_alist);
20608 }
20609 else
20610 {
20611 Lisp_Object tem;
20612
20613 /* If AELT has the wrong props, it is useless.
20614 so get rid of it. */
20615 if (! NILP (aelt))
20616 mode_line_proptrans_alist
20617 = Fdelq (aelt, mode_line_proptrans_alist);
20618
20619 elt = Fcopy_sequence (elt);
20620 Fset_text_properties (make_number (0), Flength (elt),
20621 props, elt);
20622 /* Add this item to mode_line_proptrans_alist. */
20623 mode_line_proptrans_alist
20624 = Fcons (Fcons (elt, props),
20625 mode_line_proptrans_alist);
20626 /* Truncate mode_line_proptrans_alist
20627 to at most 50 elements. */
20628 tem = Fnthcdr (make_number (50),
20629 mode_line_proptrans_alist);
20630 if (! NILP (tem))
20631 XSETCDR (tem, Qnil);
20632 }
20633 }
20634 }
20635
20636 offset = 0;
20637
20638 if (literal)
20639 {
20640 prec = precision - n;
20641 switch (mode_line_target)
20642 {
20643 case MODE_LINE_NOPROP:
20644 case MODE_LINE_TITLE:
20645 n += store_mode_line_noprop (SSDATA (elt), -1, prec);
20646 break;
20647 case MODE_LINE_STRING:
20648 n += store_mode_line_string (NULL, elt, 1, 0, prec, Qnil);
20649 break;
20650 case MODE_LINE_DISPLAY:
20651 n += display_string (NULL, elt, Qnil, 0, 0, it,
20652 0, prec, 0, STRING_MULTIBYTE (elt));
20653 break;
20654 }
20655
20656 break;
20657 }
20658
20659 /* Handle the non-literal case. */
20660
20661 while ((precision <= 0 || n < precision)
20662 && SREF (elt, offset) != 0
20663 && (mode_line_target != MODE_LINE_DISPLAY
20664 || it->current_x < it->last_visible_x))
20665 {
20666 ptrdiff_t last_offset = offset;
20667
20668 /* Advance to end of string or next format specifier. */
20669 while ((c = SREF (elt, offset++)) != '\0' && c != '%')
20670 ;
20671
20672 if (offset - 1 != last_offset)
20673 {
20674 ptrdiff_t nchars, nbytes;
20675
20676 /* Output to end of string or up to '%'. Field width
20677 is length of string. Don't output more than
20678 PRECISION allows us. */
20679 offset--;
20680
20681 prec = c_string_width (SDATA (elt) + last_offset,
20682 offset - last_offset, precision - n,
20683 &nchars, &nbytes);
20684
20685 switch (mode_line_target)
20686 {
20687 case MODE_LINE_NOPROP:
20688 case MODE_LINE_TITLE:
20689 n += store_mode_line_noprop (SSDATA (elt) + last_offset, 0, prec);
20690 break;
20691 case MODE_LINE_STRING:
20692 {
20693 ptrdiff_t bytepos = last_offset;
20694 ptrdiff_t charpos = string_byte_to_char (elt, bytepos);
20695 ptrdiff_t endpos = (precision <= 0
20696 ? string_byte_to_char (elt, offset)
20697 : charpos + nchars);
20698
20699 n += store_mode_line_string (NULL,
20700 Fsubstring (elt, make_number (charpos),
20701 make_number (endpos)),
20702 0, 0, 0, Qnil);
20703 }
20704 break;
20705 case MODE_LINE_DISPLAY:
20706 {
20707 ptrdiff_t bytepos = last_offset;
20708 ptrdiff_t charpos = string_byte_to_char (elt, bytepos);
20709
20710 if (precision <= 0)
20711 nchars = string_byte_to_char (elt, offset) - charpos;
20712 n += display_string (NULL, elt, Qnil, 0, charpos,
20713 it, 0, nchars, 0,
20714 STRING_MULTIBYTE (elt));
20715 }
20716 break;
20717 }
20718 }
20719 else /* c == '%' */
20720 {
20721 ptrdiff_t percent_position = offset;
20722
20723 /* Get the specified minimum width. Zero means
20724 don't pad. */
20725 field = 0;
20726 while ((c = SREF (elt, offset++)) >= '0' && c <= '9')
20727 field = field * 10 + c - '0';
20728
20729 /* Don't pad beyond the total padding allowed. */
20730 if (field_width - n > 0 && field > field_width - n)
20731 field = field_width - n;
20732
20733 /* Note that either PRECISION <= 0 or N < PRECISION. */
20734 prec = precision - n;
20735
20736 if (c == 'M')
20737 n += display_mode_element (it, depth, field, prec,
20738 Vglobal_mode_string, props,
20739 risky);
20740 else if (c != 0)
20741 {
20742 int multibyte;
20743 ptrdiff_t bytepos, charpos;
20744 const char *spec;
20745 Lisp_Object string;
20746
20747 bytepos = percent_position;
20748 charpos = (STRING_MULTIBYTE (elt)
20749 ? string_byte_to_char (elt, bytepos)
20750 : bytepos);
20751 spec = decode_mode_spec (it->w, c, field, &string);
20752 multibyte = STRINGP (string) && STRING_MULTIBYTE (string);
20753
20754 switch (mode_line_target)
20755 {
20756 case MODE_LINE_NOPROP:
20757 case MODE_LINE_TITLE:
20758 n += store_mode_line_noprop (spec, field, prec);
20759 break;
20760 case MODE_LINE_STRING:
20761 {
20762 Lisp_Object tem = build_string (spec);
20763 props = Ftext_properties_at (make_number (charpos), elt);
20764 /* Should only keep face property in props */
20765 n += store_mode_line_string (NULL, tem, 0, field, prec, props);
20766 }
20767 break;
20768 case MODE_LINE_DISPLAY:
20769 {
20770 int nglyphs_before, nwritten;
20771
20772 nglyphs_before = it->glyph_row->used[TEXT_AREA];
20773 nwritten = display_string (spec, string, elt,
20774 charpos, 0, it,
20775 field, prec, 0,
20776 multibyte);
20777
20778 /* Assign to the glyphs written above the
20779 string where the `%x' came from, position
20780 of the `%'. */
20781 if (nwritten > 0)
20782 {
20783 struct glyph *glyph
20784 = (it->glyph_row->glyphs[TEXT_AREA]
20785 + nglyphs_before);
20786 int i;
20787
20788 for (i = 0; i < nwritten; ++i)
20789 {
20790 glyph[i].object = elt;
20791 glyph[i].charpos = charpos;
20792 }
20793
20794 n += nwritten;
20795 }
20796 }
20797 break;
20798 }
20799 }
20800 else /* c == 0 */
20801 break;
20802 }
20803 }
20804 }
20805 break;
20806
20807 case Lisp_Symbol:
20808 /* A symbol: process the value of the symbol recursively
20809 as if it appeared here directly. Avoid error if symbol void.
20810 Special case: if value of symbol is a string, output the string
20811 literally. */
20812 {
20813 register Lisp_Object tem;
20814
20815 /* If the variable is not marked as risky to set
20816 then its contents are risky to use. */
20817 if (NILP (Fget (elt, Qrisky_local_variable)))
20818 risky = 1;
20819
20820 tem = Fboundp (elt);
20821 if (!NILP (tem))
20822 {
20823 tem = Fsymbol_value (elt);
20824 /* If value is a string, output that string literally:
20825 don't check for % within it. */
20826 if (STRINGP (tem))
20827 literal = 1;
20828
20829 if (!EQ (tem, elt))
20830 {
20831 /* Give up right away for nil or t. */
20832 elt = tem;
20833 goto tail_recurse;
20834 }
20835 }
20836 }
20837 break;
20838
20839 case Lisp_Cons:
20840 {
20841 register Lisp_Object car, tem;
20842
20843 /* A cons cell: five distinct cases.
20844 If first element is :eval or :propertize, do something special.
20845 If first element is a string or a cons, process all the elements
20846 and effectively concatenate them.
20847 If first element is a negative number, truncate displaying cdr to
20848 at most that many characters. If positive, pad (with spaces)
20849 to at least that many characters.
20850 If first element is a symbol, process the cadr or caddr recursively
20851 according to whether the symbol's value is non-nil or nil. */
20852 car = XCAR (elt);
20853 if (EQ (car, QCeval))
20854 {
20855 /* An element of the form (:eval FORM) means evaluate FORM
20856 and use the result as mode line elements. */
20857
20858 if (risky)
20859 break;
20860
20861 if (CONSP (XCDR (elt)))
20862 {
20863 Lisp_Object spec;
20864 spec = safe_eval (XCAR (XCDR (elt)));
20865 n += display_mode_element (it, depth, field_width - n,
20866 precision - n, spec, props,
20867 risky);
20868 }
20869 }
20870 else if (EQ (car, QCpropertize))
20871 {
20872 /* An element of the form (:propertize ELT PROPS...)
20873 means display ELT but applying properties PROPS. */
20874
20875 if (risky)
20876 break;
20877
20878 if (CONSP (XCDR (elt)))
20879 n += display_mode_element (it, depth, field_width - n,
20880 precision - n, XCAR (XCDR (elt)),
20881 XCDR (XCDR (elt)), risky);
20882 }
20883 else if (SYMBOLP (car))
20884 {
20885 tem = Fboundp (car);
20886 elt = XCDR (elt);
20887 if (!CONSP (elt))
20888 goto invalid;
20889 /* elt is now the cdr, and we know it is a cons cell.
20890 Use its car if CAR has a non-nil value. */
20891 if (!NILP (tem))
20892 {
20893 tem = Fsymbol_value (car);
20894 if (!NILP (tem))
20895 {
20896 elt = XCAR (elt);
20897 goto tail_recurse;
20898 }
20899 }
20900 /* Symbol's value is nil (or symbol is unbound)
20901 Get the cddr of the original list
20902 and if possible find the caddr and use that. */
20903 elt = XCDR (elt);
20904 if (NILP (elt))
20905 break;
20906 else if (!CONSP (elt))
20907 goto invalid;
20908 elt = XCAR (elt);
20909 goto tail_recurse;
20910 }
20911 else if (INTEGERP (car))
20912 {
20913 register int lim = XINT (car);
20914 elt = XCDR (elt);
20915 if (lim < 0)
20916 {
20917 /* Negative int means reduce maximum width. */
20918 if (precision <= 0)
20919 precision = -lim;
20920 else
20921 precision = min (precision, -lim);
20922 }
20923 else if (lim > 0)
20924 {
20925 /* Padding specified. Don't let it be more than
20926 current maximum. */
20927 if (precision > 0)
20928 lim = min (precision, lim);
20929
20930 /* If that's more padding than already wanted, queue it.
20931 But don't reduce padding already specified even if
20932 that is beyond the current truncation point. */
20933 field_width = max (lim, field_width);
20934 }
20935 goto tail_recurse;
20936 }
20937 else if (STRINGP (car) || CONSP (car))
20938 {
20939 Lisp_Object halftail = elt;
20940 int len = 0;
20941
20942 while (CONSP (elt)
20943 && (precision <= 0 || n < precision))
20944 {
20945 n += display_mode_element (it, depth,
20946 /* Do padding only after the last
20947 element in the list. */
20948 (! CONSP (XCDR (elt))
20949 ? field_width - n
20950 : 0),
20951 precision - n, XCAR (elt),
20952 props, risky);
20953 elt = XCDR (elt);
20954 len++;
20955 if ((len & 1) == 0)
20956 halftail = XCDR (halftail);
20957 /* Check for cycle. */
20958 if (EQ (halftail, elt))
20959 break;
20960 }
20961 }
20962 }
20963 break;
20964
20965 default:
20966 invalid:
20967 elt = build_string ("*invalid*");
20968 goto tail_recurse;
20969 }
20970
20971 /* Pad to FIELD_WIDTH. */
20972 if (field_width > 0 && n < field_width)
20973 {
20974 switch (mode_line_target)
20975 {
20976 case MODE_LINE_NOPROP:
20977 case MODE_LINE_TITLE:
20978 n += store_mode_line_noprop ("", field_width - n, 0);
20979 break;
20980 case MODE_LINE_STRING:
20981 n += store_mode_line_string ("", Qnil, 0, field_width - n, 0, Qnil);
20982 break;
20983 case MODE_LINE_DISPLAY:
20984 n += display_string ("", Qnil, Qnil, 0, 0, it, field_width - n,
20985 0, 0, 0);
20986 break;
20987 }
20988 }
20989
20990 return n;
20991 }
20992
20993 /* Store a mode-line string element in mode_line_string_list.
20994
20995 If STRING is non-null, display that C string. Otherwise, the Lisp
20996 string LISP_STRING is displayed.
20997
20998 FIELD_WIDTH is the minimum number of output glyphs to produce.
20999 If STRING has fewer characters than FIELD_WIDTH, pad to the right
21000 with spaces. FIELD_WIDTH <= 0 means don't pad.
21001
21002 PRECISION is the maximum number of characters to output from
21003 STRING. PRECISION <= 0 means don't truncate the string.
21004
21005 If COPY_STRING is non-zero, make a copy of LISP_STRING before adding
21006 properties to the string.
21007
21008 PROPS are the properties to add to the string.
21009 The mode_line_string_face face property is always added to the string.
21010 */
21011
21012 static int
21013 store_mode_line_string (const char *string, Lisp_Object lisp_string, int copy_string,
21014 int field_width, int precision, Lisp_Object props)
21015 {
21016 ptrdiff_t len;
21017 int n = 0;
21018
21019 if (string != NULL)
21020 {
21021 len = strlen (string);
21022 if (precision > 0 && len > precision)
21023 len = precision;
21024 lisp_string = make_string (string, len);
21025 if (NILP (props))
21026 props = mode_line_string_face_prop;
21027 else if (!NILP (mode_line_string_face))
21028 {
21029 Lisp_Object face = Fplist_get (props, Qface);
21030 props = Fcopy_sequence (props);
21031 if (NILP (face))
21032 face = mode_line_string_face;
21033 else
21034 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
21035 props = Fplist_put (props, Qface, face);
21036 }
21037 Fadd_text_properties (make_number (0), make_number (len),
21038 props, lisp_string);
21039 }
21040 else
21041 {
21042 len = XFASTINT (Flength (lisp_string));
21043 if (precision > 0 && len > precision)
21044 {
21045 len = precision;
21046 lisp_string = Fsubstring (lisp_string, make_number (0), make_number (len));
21047 precision = -1;
21048 }
21049 if (!NILP (mode_line_string_face))
21050 {
21051 Lisp_Object face;
21052 if (NILP (props))
21053 props = Ftext_properties_at (make_number (0), lisp_string);
21054 face = Fplist_get (props, Qface);
21055 if (NILP (face))
21056 face = mode_line_string_face;
21057 else
21058 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
21059 props = Fcons (Qface, Fcons (face, Qnil));
21060 if (copy_string)
21061 lisp_string = Fcopy_sequence (lisp_string);
21062 }
21063 if (!NILP (props))
21064 Fadd_text_properties (make_number (0), make_number (len),
21065 props, lisp_string);
21066 }
21067
21068 if (len > 0)
21069 {
21070 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
21071 n += len;
21072 }
21073
21074 if (field_width > len)
21075 {
21076 field_width -= len;
21077 lisp_string = Fmake_string (make_number (field_width), make_number (' '));
21078 if (!NILP (props))
21079 Fadd_text_properties (make_number (0), make_number (field_width),
21080 props, lisp_string);
21081 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
21082 n += field_width;
21083 }
21084
21085 return n;
21086 }
21087
21088
21089 DEFUN ("format-mode-line", Fformat_mode_line, Sformat_mode_line,
21090 1, 4, 0,
21091 doc: /* Format a string out of a mode line format specification.
21092 First arg FORMAT specifies the mode line format (see `mode-line-format'
21093 for details) to use.
21094
21095 By default, the format is evaluated for the currently selected window.
21096
21097 Optional second arg FACE specifies the face property to put on all
21098 characters for which no face is specified. The value nil means the
21099 default face. The value t means whatever face the window's mode line
21100 currently uses (either `mode-line' or `mode-line-inactive',
21101 depending on whether the window is the selected window or not).
21102 An integer value means the value string has no text
21103 properties.
21104
21105 Optional third and fourth args WINDOW and BUFFER specify the window
21106 and buffer to use as the context for the formatting (defaults
21107 are the selected window and the WINDOW's buffer). */)
21108 (Lisp_Object format, Lisp_Object face,
21109 Lisp_Object window, Lisp_Object buffer)
21110 {
21111 struct it it;
21112 int len;
21113 struct window *w;
21114 struct buffer *old_buffer = NULL;
21115 int face_id;
21116 int no_props = INTEGERP (face);
21117 ptrdiff_t count = SPECPDL_INDEX ();
21118 Lisp_Object str;
21119 int string_start = 0;
21120
21121 if (NILP (window))
21122 window = selected_window;
21123 CHECK_WINDOW (window);
21124 w = XWINDOW (window);
21125
21126 if (NILP (buffer))
21127 buffer = w->buffer;
21128 CHECK_BUFFER (buffer);
21129
21130 /* Make formatting the modeline a non-op when noninteractive, otherwise
21131 there will be problems later caused by a partially initialized frame. */
21132 if (NILP (format) || noninteractive)
21133 return empty_unibyte_string;
21134
21135 if (no_props)
21136 face = Qnil;
21137
21138 face_id = (NILP (face) || EQ (face, Qdefault)) ? DEFAULT_FACE_ID
21139 : EQ (face, Qt) ? (EQ (window, selected_window)
21140 ? MODE_LINE_FACE_ID : MODE_LINE_INACTIVE_FACE_ID)
21141 : EQ (face, Qmode_line) ? MODE_LINE_FACE_ID
21142 : EQ (face, Qmode_line_inactive) ? MODE_LINE_INACTIVE_FACE_ID
21143 : EQ (face, Qheader_line) ? HEADER_LINE_FACE_ID
21144 : EQ (face, Qtool_bar) ? TOOL_BAR_FACE_ID
21145 : DEFAULT_FACE_ID;
21146
21147 if (XBUFFER (buffer) != current_buffer)
21148 old_buffer = current_buffer;
21149
21150 /* Save things including mode_line_proptrans_alist,
21151 and set that to nil so that we don't alter the outer value. */
21152 record_unwind_protect (unwind_format_mode_line,
21153 format_mode_line_unwind_data
21154 (XFRAME (WINDOW_FRAME (XWINDOW (window))),
21155 old_buffer, selected_window, 1));
21156 mode_line_proptrans_alist = Qnil;
21157
21158 Fselect_window (window, Qt);
21159 if (old_buffer)
21160 set_buffer_internal_1 (XBUFFER (buffer));
21161
21162 init_iterator (&it, w, -1, -1, NULL, face_id);
21163
21164 if (no_props)
21165 {
21166 mode_line_target = MODE_LINE_NOPROP;
21167 mode_line_string_face_prop = Qnil;
21168 mode_line_string_list = Qnil;
21169 string_start = MODE_LINE_NOPROP_LEN (0);
21170 }
21171 else
21172 {
21173 mode_line_target = MODE_LINE_STRING;
21174 mode_line_string_list = Qnil;
21175 mode_line_string_face = face;
21176 mode_line_string_face_prop
21177 = (NILP (face) ? Qnil : Fcons (Qface, Fcons (face, Qnil)));
21178 }
21179
21180 push_kboard (FRAME_KBOARD (it.f));
21181 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
21182 pop_kboard ();
21183
21184 if (no_props)
21185 {
21186 len = MODE_LINE_NOPROP_LEN (string_start);
21187 str = make_string (mode_line_noprop_buf + string_start, len);
21188 }
21189 else
21190 {
21191 mode_line_string_list = Fnreverse (mode_line_string_list);
21192 str = Fmapconcat (intern ("identity"), mode_line_string_list,
21193 empty_unibyte_string);
21194 }
21195
21196 unbind_to (count, Qnil);
21197 return str;
21198 }
21199
21200 /* Write a null-terminated, right justified decimal representation of
21201 the positive integer D to BUF using a minimal field width WIDTH. */
21202
21203 static void
21204 pint2str (register char *buf, register int width, register ptrdiff_t d)
21205 {
21206 register char *p = buf;
21207
21208 if (d <= 0)
21209 *p++ = '0';
21210 else
21211 {
21212 while (d > 0)
21213 {
21214 *p++ = d % 10 + '0';
21215 d /= 10;
21216 }
21217 }
21218
21219 for (width -= (int) (p - buf); width > 0; --width)
21220 *p++ = ' ';
21221 *p-- = '\0';
21222 while (p > buf)
21223 {
21224 d = *buf;
21225 *buf++ = *p;
21226 *p-- = d;
21227 }
21228 }
21229
21230 /* Write a null-terminated, right justified decimal and "human
21231 readable" representation of the nonnegative integer D to BUF using
21232 a minimal field width WIDTH. D should be smaller than 999.5e24. */
21233
21234 static const char power_letter[] =
21235 {
21236 0, /* no letter */
21237 'k', /* kilo */
21238 'M', /* mega */
21239 'G', /* giga */
21240 'T', /* tera */
21241 'P', /* peta */
21242 'E', /* exa */
21243 'Z', /* zetta */
21244 'Y' /* yotta */
21245 };
21246
21247 static void
21248 pint2hrstr (char *buf, int width, ptrdiff_t d)
21249 {
21250 /* We aim to represent the nonnegative integer D as
21251 QUOTIENT.TENTHS * 10 ^ (3 * EXPONENT). */
21252 ptrdiff_t quotient = d;
21253 int remainder = 0;
21254 /* -1 means: do not use TENTHS. */
21255 int tenths = -1;
21256 int exponent = 0;
21257
21258 /* Length of QUOTIENT.TENTHS as a string. */
21259 int length;
21260
21261 char * psuffix;
21262 char * p;
21263
21264 if (1000 <= quotient)
21265 {
21266 /* Scale to the appropriate EXPONENT. */
21267 do
21268 {
21269 remainder = quotient % 1000;
21270 quotient /= 1000;
21271 exponent++;
21272 }
21273 while (1000 <= quotient);
21274
21275 /* Round to nearest and decide whether to use TENTHS or not. */
21276 if (quotient <= 9)
21277 {
21278 tenths = remainder / 100;
21279 if (50 <= remainder % 100)
21280 {
21281 if (tenths < 9)
21282 tenths++;
21283 else
21284 {
21285 quotient++;
21286 if (quotient == 10)
21287 tenths = -1;
21288 else
21289 tenths = 0;
21290 }
21291 }
21292 }
21293 else
21294 if (500 <= remainder)
21295 {
21296 if (quotient < 999)
21297 quotient++;
21298 else
21299 {
21300 quotient = 1;
21301 exponent++;
21302 tenths = 0;
21303 }
21304 }
21305 }
21306
21307 /* Calculate the LENGTH of QUOTIENT.TENTHS as a string. */
21308 if (tenths == -1 && quotient <= 99)
21309 if (quotient <= 9)
21310 length = 1;
21311 else
21312 length = 2;
21313 else
21314 length = 3;
21315 p = psuffix = buf + max (width, length);
21316
21317 /* Print EXPONENT. */
21318 *psuffix++ = power_letter[exponent];
21319 *psuffix = '\0';
21320
21321 /* Print TENTHS. */
21322 if (tenths >= 0)
21323 {
21324 *--p = '0' + tenths;
21325 *--p = '.';
21326 }
21327
21328 /* Print QUOTIENT. */
21329 do
21330 {
21331 int digit = quotient % 10;
21332 *--p = '0' + digit;
21333 }
21334 while ((quotient /= 10) != 0);
21335
21336 /* Print leading spaces. */
21337 while (buf < p)
21338 *--p = ' ';
21339 }
21340
21341 /* Set a mnemonic character for coding_system (Lisp symbol) in BUF.
21342 If EOL_FLAG is 1, set also a mnemonic character for end-of-line
21343 type of CODING_SYSTEM. Return updated pointer into BUF. */
21344
21345 static unsigned char invalid_eol_type[] = "(*invalid*)";
21346
21347 static char *
21348 decode_mode_spec_coding (Lisp_Object coding_system, register char *buf, int eol_flag)
21349 {
21350 Lisp_Object val;
21351 int multibyte = !NILP (BVAR (current_buffer, enable_multibyte_characters));
21352 const unsigned char *eol_str;
21353 int eol_str_len;
21354 /* The EOL conversion we are using. */
21355 Lisp_Object eoltype;
21356
21357 val = CODING_SYSTEM_SPEC (coding_system);
21358 eoltype = Qnil;
21359
21360 if (!VECTORP (val)) /* Not yet decided. */
21361 {
21362 *buf++ = multibyte ? '-' : ' ';
21363 if (eol_flag)
21364 eoltype = eol_mnemonic_undecided;
21365 /* Don't mention EOL conversion if it isn't decided. */
21366 }
21367 else
21368 {
21369 Lisp_Object attrs;
21370 Lisp_Object eolvalue;
21371
21372 attrs = AREF (val, 0);
21373 eolvalue = AREF (val, 2);
21374
21375 *buf++ = multibyte
21376 ? XFASTINT (CODING_ATTR_MNEMONIC (attrs))
21377 : ' ';
21378
21379 if (eol_flag)
21380 {
21381 /* The EOL conversion that is normal on this system. */
21382
21383 if (NILP (eolvalue)) /* Not yet decided. */
21384 eoltype = eol_mnemonic_undecided;
21385 else if (VECTORP (eolvalue)) /* Not yet decided. */
21386 eoltype = eol_mnemonic_undecided;
21387 else /* eolvalue is Qunix, Qdos, or Qmac. */
21388 eoltype = (EQ (eolvalue, Qunix)
21389 ? eol_mnemonic_unix
21390 : (EQ (eolvalue, Qdos) == 1
21391 ? eol_mnemonic_dos : eol_mnemonic_mac));
21392 }
21393 }
21394
21395 if (eol_flag)
21396 {
21397 /* Mention the EOL conversion if it is not the usual one. */
21398 if (STRINGP (eoltype))
21399 {
21400 eol_str = SDATA (eoltype);
21401 eol_str_len = SBYTES (eoltype);
21402 }
21403 else if (CHARACTERP (eoltype))
21404 {
21405 unsigned char *tmp = alloca (MAX_MULTIBYTE_LENGTH);
21406 int c = XFASTINT (eoltype);
21407 eol_str_len = CHAR_STRING (c, tmp);
21408 eol_str = tmp;
21409 }
21410 else
21411 {
21412 eol_str = invalid_eol_type;
21413 eol_str_len = sizeof (invalid_eol_type) - 1;
21414 }
21415 memcpy (buf, eol_str, eol_str_len);
21416 buf += eol_str_len;
21417 }
21418
21419 return buf;
21420 }
21421
21422 /* Return a string for the output of a mode line %-spec for window W,
21423 generated by character C. FIELD_WIDTH > 0 means pad the string
21424 returned with spaces to that value. Return a Lisp string in
21425 *STRING if the resulting string is taken from that Lisp string.
21426
21427 Note we operate on the current buffer for most purposes,
21428 the exception being w->base_line_pos. */
21429
21430 static char lots_of_dashes[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
21431
21432 static const char *
21433 decode_mode_spec (struct window *w, register int c, int field_width,
21434 Lisp_Object *string)
21435 {
21436 Lisp_Object obj;
21437 struct frame *f = XFRAME (WINDOW_FRAME (w));
21438 char *decode_mode_spec_buf = f->decode_mode_spec_buffer;
21439 struct buffer *b = current_buffer;
21440
21441 obj = Qnil;
21442 *string = Qnil;
21443
21444 switch (c)
21445 {
21446 case '*':
21447 if (!NILP (BVAR (b, read_only)))
21448 return "%";
21449 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
21450 return "*";
21451 return "-";
21452
21453 case '+':
21454 /* This differs from %* only for a modified read-only buffer. */
21455 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
21456 return "*";
21457 if (!NILP (BVAR (b, read_only)))
21458 return "%";
21459 return "-";
21460
21461 case '&':
21462 /* This differs from %* in ignoring read-only-ness. */
21463 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
21464 return "*";
21465 return "-";
21466
21467 case '%':
21468 return "%";
21469
21470 case '[':
21471 {
21472 int i;
21473 char *p;
21474
21475 if (command_loop_level > 5)
21476 return "[[[... ";
21477 p = decode_mode_spec_buf;
21478 for (i = 0; i < command_loop_level; i++)
21479 *p++ = '[';
21480 *p = 0;
21481 return decode_mode_spec_buf;
21482 }
21483
21484 case ']':
21485 {
21486 int i;
21487 char *p;
21488
21489 if (command_loop_level > 5)
21490 return " ...]]]";
21491 p = decode_mode_spec_buf;
21492 for (i = 0; i < command_loop_level; i++)
21493 *p++ = ']';
21494 *p = 0;
21495 return decode_mode_spec_buf;
21496 }
21497
21498 case '-':
21499 {
21500 register int i;
21501
21502 /* Let lots_of_dashes be a string of infinite length. */
21503 if (mode_line_target == MODE_LINE_NOPROP ||
21504 mode_line_target == MODE_LINE_STRING)
21505 return "--";
21506 if (field_width <= 0
21507 || field_width > sizeof (lots_of_dashes))
21508 {
21509 for (i = 0; i < FRAME_MESSAGE_BUF_SIZE (f) - 1; ++i)
21510 decode_mode_spec_buf[i] = '-';
21511 decode_mode_spec_buf[i] = '\0';
21512 return decode_mode_spec_buf;
21513 }
21514 else
21515 return lots_of_dashes;
21516 }
21517
21518 case 'b':
21519 obj = BVAR (b, name);
21520 break;
21521
21522 case 'c':
21523 /* %c and %l are ignored in `frame-title-format'.
21524 (In redisplay_internal, the frame title is drawn _before_ the
21525 windows are updated, so the stuff which depends on actual
21526 window contents (such as %l) may fail to render properly, or
21527 even crash emacs.) */
21528 if (mode_line_target == MODE_LINE_TITLE)
21529 return "";
21530 else
21531 {
21532 ptrdiff_t col = current_column ();
21533 wset_column_number_displayed (w, make_number (col));
21534 pint2str (decode_mode_spec_buf, field_width, col);
21535 return decode_mode_spec_buf;
21536 }
21537
21538 case 'e':
21539 #ifndef SYSTEM_MALLOC
21540 {
21541 if (NILP (Vmemory_full))
21542 return "";
21543 else
21544 return "!MEM FULL! ";
21545 }
21546 #else
21547 return "";
21548 #endif
21549
21550 case 'F':
21551 /* %F displays the frame name. */
21552 if (!NILP (f->title))
21553 return SSDATA (f->title);
21554 if (f->explicit_name || ! FRAME_WINDOW_P (f))
21555 return SSDATA (f->name);
21556 return "Emacs";
21557
21558 case 'f':
21559 obj = BVAR (b, filename);
21560 break;
21561
21562 case 'i':
21563 {
21564 ptrdiff_t size = ZV - BEGV;
21565 pint2str (decode_mode_spec_buf, field_width, size);
21566 return decode_mode_spec_buf;
21567 }
21568
21569 case 'I':
21570 {
21571 ptrdiff_t size = ZV - BEGV;
21572 pint2hrstr (decode_mode_spec_buf, field_width, size);
21573 return decode_mode_spec_buf;
21574 }
21575
21576 case 'l':
21577 {
21578 ptrdiff_t startpos, startpos_byte, line, linepos, linepos_byte;
21579 ptrdiff_t topline, nlines, height;
21580 ptrdiff_t junk;
21581
21582 /* %c and %l are ignored in `frame-title-format'. */
21583 if (mode_line_target == MODE_LINE_TITLE)
21584 return "";
21585
21586 startpos = XMARKER (w->start)->charpos;
21587 startpos_byte = marker_byte_position (w->start);
21588 height = WINDOW_TOTAL_LINES (w);
21589
21590 /* If we decided that this buffer isn't suitable for line numbers,
21591 don't forget that too fast. */
21592 if (EQ (w->base_line_pos, w->buffer))
21593 goto no_value;
21594 /* But do forget it, if the window shows a different buffer now. */
21595 else if (BUFFERP (w->base_line_pos))
21596 wset_base_line_pos (w, Qnil);
21597
21598 /* If the buffer is very big, don't waste time. */
21599 if (INTEGERP (Vline_number_display_limit)
21600 && BUF_ZV (b) - BUF_BEGV (b) > XINT (Vline_number_display_limit))
21601 {
21602 wset_base_line_pos (w, Qnil);
21603 wset_base_line_number (w, Qnil);
21604 goto no_value;
21605 }
21606
21607 if (INTEGERP (w->base_line_number)
21608 && INTEGERP (w->base_line_pos)
21609 && XFASTINT (w->base_line_pos) <= startpos)
21610 {
21611 line = XFASTINT (w->base_line_number);
21612 linepos = XFASTINT (w->base_line_pos);
21613 linepos_byte = buf_charpos_to_bytepos (b, linepos);
21614 }
21615 else
21616 {
21617 line = 1;
21618 linepos = BUF_BEGV (b);
21619 linepos_byte = BUF_BEGV_BYTE (b);
21620 }
21621
21622 /* Count lines from base line to window start position. */
21623 nlines = display_count_lines (linepos_byte,
21624 startpos_byte,
21625 startpos, &junk);
21626
21627 topline = nlines + line;
21628
21629 /* Determine a new base line, if the old one is too close
21630 or too far away, or if we did not have one.
21631 "Too close" means it's plausible a scroll-down would
21632 go back past it. */
21633 if (startpos == BUF_BEGV (b))
21634 {
21635 wset_base_line_number (w, make_number (topline));
21636 wset_base_line_pos (w, make_number (BUF_BEGV (b)));
21637 }
21638 else if (nlines < height + 25 || nlines > height * 3 + 50
21639 || linepos == BUF_BEGV (b))
21640 {
21641 ptrdiff_t limit = BUF_BEGV (b);
21642 ptrdiff_t limit_byte = BUF_BEGV_BYTE (b);
21643 ptrdiff_t position;
21644 ptrdiff_t distance =
21645 (height * 2 + 30) * line_number_display_limit_width;
21646
21647 if (startpos - distance > limit)
21648 {
21649 limit = startpos - distance;
21650 limit_byte = CHAR_TO_BYTE (limit);
21651 }
21652
21653 nlines = display_count_lines (startpos_byte,
21654 limit_byte,
21655 - (height * 2 + 30),
21656 &position);
21657 /* If we couldn't find the lines we wanted within
21658 line_number_display_limit_width chars per line,
21659 give up on line numbers for this window. */
21660 if (position == limit_byte && limit == startpos - distance)
21661 {
21662 wset_base_line_pos (w, w->buffer);
21663 wset_base_line_number (w, Qnil);
21664 goto no_value;
21665 }
21666
21667 wset_base_line_number (w, make_number (topline - nlines));
21668 wset_base_line_pos (w, make_number (BYTE_TO_CHAR (position)));
21669 }
21670
21671 /* Now count lines from the start pos to point. */
21672 nlines = display_count_lines (startpos_byte,
21673 PT_BYTE, PT, &junk);
21674
21675 /* Record that we did display the line number. */
21676 line_number_displayed = 1;
21677
21678 /* Make the string to show. */
21679 pint2str (decode_mode_spec_buf, field_width, topline + nlines);
21680 return decode_mode_spec_buf;
21681 no_value:
21682 {
21683 char* p = decode_mode_spec_buf;
21684 int pad = field_width - 2;
21685 while (pad-- > 0)
21686 *p++ = ' ';
21687 *p++ = '?';
21688 *p++ = '?';
21689 *p = '\0';
21690 return decode_mode_spec_buf;
21691 }
21692 }
21693 break;
21694
21695 case 'm':
21696 obj = BVAR (b, mode_name);
21697 break;
21698
21699 case 'n':
21700 if (BUF_BEGV (b) > BUF_BEG (b) || BUF_ZV (b) < BUF_Z (b))
21701 return " Narrow";
21702 break;
21703
21704 case 'p':
21705 {
21706 ptrdiff_t pos = marker_position (w->start);
21707 ptrdiff_t total = BUF_ZV (b) - BUF_BEGV (b);
21708
21709 if (XFASTINT (w->window_end_pos) <= BUF_Z (b) - BUF_ZV (b))
21710 {
21711 if (pos <= BUF_BEGV (b))
21712 return "All";
21713 else
21714 return "Bottom";
21715 }
21716 else if (pos <= BUF_BEGV (b))
21717 return "Top";
21718 else
21719 {
21720 if (total > 1000000)
21721 /* Do it differently for a large value, to avoid overflow. */
21722 total = ((pos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
21723 else
21724 total = ((pos - BUF_BEGV (b)) * 100 + total - 1) / total;
21725 /* We can't normally display a 3-digit number,
21726 so get us a 2-digit number that is close. */
21727 if (total == 100)
21728 total = 99;
21729 sprintf (decode_mode_spec_buf, "%2"pD"d%%", total);
21730 return decode_mode_spec_buf;
21731 }
21732 }
21733
21734 /* Display percentage of size above the bottom of the screen. */
21735 case 'P':
21736 {
21737 ptrdiff_t toppos = marker_position (w->start);
21738 ptrdiff_t botpos = BUF_Z (b) - XFASTINT (w->window_end_pos);
21739 ptrdiff_t total = BUF_ZV (b) - BUF_BEGV (b);
21740
21741 if (botpos >= BUF_ZV (b))
21742 {
21743 if (toppos <= BUF_BEGV (b))
21744 return "All";
21745 else
21746 return "Bottom";
21747 }
21748 else
21749 {
21750 if (total > 1000000)
21751 /* Do it differently for a large value, to avoid overflow. */
21752 total = ((botpos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
21753 else
21754 total = ((botpos - BUF_BEGV (b)) * 100 + total - 1) / total;
21755 /* We can't normally display a 3-digit number,
21756 so get us a 2-digit number that is close. */
21757 if (total == 100)
21758 total = 99;
21759 if (toppos <= BUF_BEGV (b))
21760 sprintf (decode_mode_spec_buf, "Top%2"pD"d%%", total);
21761 else
21762 sprintf (decode_mode_spec_buf, "%2"pD"d%%", total);
21763 return decode_mode_spec_buf;
21764 }
21765 }
21766
21767 case 's':
21768 /* status of process */
21769 obj = Fget_buffer_process (Fcurrent_buffer ());
21770 if (NILP (obj))
21771 return "no process";
21772 #ifndef MSDOS
21773 obj = Fsymbol_name (Fprocess_status (obj));
21774 #endif
21775 break;
21776
21777 case '@':
21778 {
21779 ptrdiff_t count = inhibit_garbage_collection ();
21780 Lisp_Object val = call1 (intern ("file-remote-p"),
21781 BVAR (current_buffer, directory));
21782 unbind_to (count, Qnil);
21783
21784 if (NILP (val))
21785 return "-";
21786 else
21787 return "@";
21788 }
21789
21790 case 't': /* indicate TEXT or BINARY */
21791 return "T";
21792
21793 case 'z':
21794 /* coding-system (not including end-of-line format) */
21795 case 'Z':
21796 /* coding-system (including end-of-line type) */
21797 {
21798 int eol_flag = (c == 'Z');
21799 char *p = decode_mode_spec_buf;
21800
21801 if (! FRAME_WINDOW_P (f))
21802 {
21803 /* No need to mention EOL here--the terminal never needs
21804 to do EOL conversion. */
21805 p = decode_mode_spec_coding (CODING_ID_NAME
21806 (FRAME_KEYBOARD_CODING (f)->id),
21807 p, 0);
21808 p = decode_mode_spec_coding (CODING_ID_NAME
21809 (FRAME_TERMINAL_CODING (f)->id),
21810 p, 0);
21811 }
21812 p = decode_mode_spec_coding (BVAR (b, buffer_file_coding_system),
21813 p, eol_flag);
21814
21815 #if 0 /* This proves to be annoying; I think we can do without. -- rms. */
21816 #ifdef subprocesses
21817 obj = Fget_buffer_process (Fcurrent_buffer ());
21818 if (PROCESSP (obj))
21819 {
21820 p = decode_mode_spec_coding
21821 (XPROCESS (obj)->decode_coding_system, p, eol_flag);
21822 p = decode_mode_spec_coding
21823 (XPROCESS (obj)->encode_coding_system, p, eol_flag);
21824 }
21825 #endif /* subprocesses */
21826 #endif /* 0 */
21827 *p = 0;
21828 return decode_mode_spec_buf;
21829 }
21830 }
21831
21832 if (STRINGP (obj))
21833 {
21834 *string = obj;
21835 return SSDATA (obj);
21836 }
21837 else
21838 return "";
21839 }
21840
21841
21842 /* Count up to COUNT lines starting from START_BYTE.
21843 But don't go beyond LIMIT_BYTE.
21844 Return the number of lines thus found (always nonnegative).
21845
21846 Set *BYTE_POS_PTR to 1 if we found COUNT lines, 0 if we hit LIMIT. */
21847
21848 static ptrdiff_t
21849 display_count_lines (ptrdiff_t start_byte,
21850 ptrdiff_t limit_byte, ptrdiff_t count,
21851 ptrdiff_t *byte_pos_ptr)
21852 {
21853 register unsigned char *cursor;
21854 unsigned char *base;
21855
21856 register ptrdiff_t ceiling;
21857 register unsigned char *ceiling_addr;
21858 ptrdiff_t orig_count = count;
21859
21860 /* If we are not in selective display mode,
21861 check only for newlines. */
21862 int selective_display = (!NILP (BVAR (current_buffer, selective_display))
21863 && !INTEGERP (BVAR (current_buffer, selective_display)));
21864
21865 if (count > 0)
21866 {
21867 while (start_byte < limit_byte)
21868 {
21869 ceiling = BUFFER_CEILING_OF (start_byte);
21870 ceiling = min (limit_byte - 1, ceiling);
21871 ceiling_addr = BYTE_POS_ADDR (ceiling) + 1;
21872 base = (cursor = BYTE_POS_ADDR (start_byte));
21873 while (1)
21874 {
21875 if (selective_display)
21876 while (*cursor != '\n' && *cursor != 015 && ++cursor != ceiling_addr)
21877 ;
21878 else
21879 while (*cursor != '\n' && ++cursor != ceiling_addr)
21880 ;
21881
21882 if (cursor != ceiling_addr)
21883 {
21884 if (--count == 0)
21885 {
21886 start_byte += cursor - base + 1;
21887 *byte_pos_ptr = start_byte;
21888 return orig_count;
21889 }
21890 else
21891 if (++cursor == ceiling_addr)
21892 break;
21893 }
21894 else
21895 break;
21896 }
21897 start_byte += cursor - base;
21898 }
21899 }
21900 else
21901 {
21902 while (start_byte > limit_byte)
21903 {
21904 ceiling = BUFFER_FLOOR_OF (start_byte - 1);
21905 ceiling = max (limit_byte, ceiling);
21906 ceiling_addr = BYTE_POS_ADDR (ceiling) - 1;
21907 base = (cursor = BYTE_POS_ADDR (start_byte - 1) + 1);
21908 while (1)
21909 {
21910 if (selective_display)
21911 while (--cursor != ceiling_addr
21912 && *cursor != '\n' && *cursor != 015)
21913 ;
21914 else
21915 while (--cursor != ceiling_addr && *cursor != '\n')
21916 ;
21917
21918 if (cursor != ceiling_addr)
21919 {
21920 if (++count == 0)
21921 {
21922 start_byte += cursor - base + 1;
21923 *byte_pos_ptr = start_byte;
21924 /* When scanning backwards, we should
21925 not count the newline posterior to which we stop. */
21926 return - orig_count - 1;
21927 }
21928 }
21929 else
21930 break;
21931 }
21932 /* Here we add 1 to compensate for the last decrement
21933 of CURSOR, which took it past the valid range. */
21934 start_byte += cursor - base + 1;
21935 }
21936 }
21937
21938 *byte_pos_ptr = limit_byte;
21939
21940 if (count < 0)
21941 return - orig_count + count;
21942 return orig_count - count;
21943
21944 }
21945
21946
21947 \f
21948 /***********************************************************************
21949 Displaying strings
21950 ***********************************************************************/
21951
21952 /* Display a NUL-terminated string, starting with index START.
21953
21954 If STRING is non-null, display that C string. Otherwise, the Lisp
21955 string LISP_STRING is displayed. There's a case that STRING is
21956 non-null and LISP_STRING is not nil. It means STRING is a string
21957 data of LISP_STRING. In that case, we display LISP_STRING while
21958 ignoring its text properties.
21959
21960 If FACE_STRING is not nil, FACE_STRING_POS is a position in
21961 FACE_STRING. Display STRING or LISP_STRING with the face at
21962 FACE_STRING_POS in FACE_STRING:
21963
21964 Display the string in the environment given by IT, but use the
21965 standard display table, temporarily.
21966
21967 FIELD_WIDTH is the minimum number of output glyphs to produce.
21968 If STRING has fewer characters than FIELD_WIDTH, pad to the right
21969 with spaces. If STRING has more characters, more than FIELD_WIDTH
21970 glyphs will be produced. FIELD_WIDTH <= 0 means don't pad.
21971
21972 PRECISION is the maximum number of characters to output from
21973 STRING. PRECISION < 0 means don't truncate the string.
21974
21975 This is roughly equivalent to printf format specifiers:
21976
21977 FIELD_WIDTH PRECISION PRINTF
21978 ----------------------------------------
21979 -1 -1 %s
21980 -1 10 %.10s
21981 10 -1 %10s
21982 20 10 %20.10s
21983
21984 MULTIBYTE zero means do not display multibyte chars, > 0 means do
21985 display them, and < 0 means obey the current buffer's value of
21986 enable_multibyte_characters.
21987
21988 Value is the number of columns displayed. */
21989
21990 static int
21991 display_string (const char *string, Lisp_Object lisp_string, Lisp_Object face_string,
21992 ptrdiff_t face_string_pos, ptrdiff_t start, struct it *it,
21993 int field_width, int precision, int max_x, int multibyte)
21994 {
21995 int hpos_at_start = it->hpos;
21996 int saved_face_id = it->face_id;
21997 struct glyph_row *row = it->glyph_row;
21998 ptrdiff_t it_charpos;
21999
22000 /* Initialize the iterator IT for iteration over STRING beginning
22001 with index START. */
22002 reseat_to_string (it, NILP (lisp_string) ? string : NULL, lisp_string, start,
22003 precision, field_width, multibyte);
22004 if (string && STRINGP (lisp_string))
22005 /* LISP_STRING is the one returned by decode_mode_spec. We should
22006 ignore its text properties. */
22007 it->stop_charpos = it->end_charpos;
22008
22009 /* If displaying STRING, set up the face of the iterator from
22010 FACE_STRING, if that's given. */
22011 if (STRINGP (face_string))
22012 {
22013 ptrdiff_t endptr;
22014 struct face *face;
22015
22016 it->face_id
22017 = face_at_string_position (it->w, face_string, face_string_pos,
22018 0, it->region_beg_charpos,
22019 it->region_end_charpos,
22020 &endptr, it->base_face_id, 0);
22021 face = FACE_FROM_ID (it->f, it->face_id);
22022 it->face_box_p = face->box != FACE_NO_BOX;
22023 }
22024
22025 /* Set max_x to the maximum allowed X position. Don't let it go
22026 beyond the right edge of the window. */
22027 if (max_x <= 0)
22028 max_x = it->last_visible_x;
22029 else
22030 max_x = min (max_x, it->last_visible_x);
22031
22032 /* Skip over display elements that are not visible. because IT->w is
22033 hscrolled. */
22034 if (it->current_x < it->first_visible_x)
22035 move_it_in_display_line_to (it, 100000, it->first_visible_x,
22036 MOVE_TO_POS | MOVE_TO_X);
22037
22038 row->ascent = it->max_ascent;
22039 row->height = it->max_ascent + it->max_descent;
22040 row->phys_ascent = it->max_phys_ascent;
22041 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
22042 row->extra_line_spacing = it->max_extra_line_spacing;
22043
22044 if (STRINGP (it->string))
22045 it_charpos = IT_STRING_CHARPOS (*it);
22046 else
22047 it_charpos = IT_CHARPOS (*it);
22048
22049 /* This condition is for the case that we are called with current_x
22050 past last_visible_x. */
22051 while (it->current_x < max_x)
22052 {
22053 int x_before, x, n_glyphs_before, i, nglyphs;
22054
22055 /* Get the next display element. */
22056 if (!get_next_display_element (it))
22057 break;
22058
22059 /* Produce glyphs. */
22060 x_before = it->current_x;
22061 n_glyphs_before = row->used[TEXT_AREA];
22062 PRODUCE_GLYPHS (it);
22063
22064 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
22065 i = 0;
22066 x = x_before;
22067 while (i < nglyphs)
22068 {
22069 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
22070
22071 if (it->line_wrap != TRUNCATE
22072 && x + glyph->pixel_width > max_x)
22073 {
22074 /* End of continued line or max_x reached. */
22075 if (CHAR_GLYPH_PADDING_P (*glyph))
22076 {
22077 /* A wide character is unbreakable. */
22078 if (row->reversed_p)
22079 unproduce_glyphs (it, row->used[TEXT_AREA]
22080 - n_glyphs_before);
22081 row->used[TEXT_AREA] = n_glyphs_before;
22082 it->current_x = x_before;
22083 }
22084 else
22085 {
22086 if (row->reversed_p)
22087 unproduce_glyphs (it, row->used[TEXT_AREA]
22088 - (n_glyphs_before + i));
22089 row->used[TEXT_AREA] = n_glyphs_before + i;
22090 it->current_x = x;
22091 }
22092 break;
22093 }
22094 else if (x + glyph->pixel_width >= it->first_visible_x)
22095 {
22096 /* Glyph is at least partially visible. */
22097 ++it->hpos;
22098 if (x < it->first_visible_x)
22099 row->x = x - it->first_visible_x;
22100 }
22101 else
22102 {
22103 /* Glyph is off the left margin of the display area.
22104 Should not happen. */
22105 emacs_abort ();
22106 }
22107
22108 row->ascent = max (row->ascent, it->max_ascent);
22109 row->height = max (row->height, it->max_ascent + it->max_descent);
22110 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
22111 row->phys_height = max (row->phys_height,
22112 it->max_phys_ascent + it->max_phys_descent);
22113 row->extra_line_spacing = max (row->extra_line_spacing,
22114 it->max_extra_line_spacing);
22115 x += glyph->pixel_width;
22116 ++i;
22117 }
22118
22119 /* Stop if max_x reached. */
22120 if (i < nglyphs)
22121 break;
22122
22123 /* Stop at line ends. */
22124 if (ITERATOR_AT_END_OF_LINE_P (it))
22125 {
22126 it->continuation_lines_width = 0;
22127 break;
22128 }
22129
22130 set_iterator_to_next (it, 1);
22131 if (STRINGP (it->string))
22132 it_charpos = IT_STRING_CHARPOS (*it);
22133 else
22134 it_charpos = IT_CHARPOS (*it);
22135
22136 /* Stop if truncating at the right edge. */
22137 if (it->line_wrap == TRUNCATE
22138 && it->current_x >= it->last_visible_x)
22139 {
22140 /* Add truncation mark, but don't do it if the line is
22141 truncated at a padding space. */
22142 if (it_charpos < it->string_nchars)
22143 {
22144 if (!FRAME_WINDOW_P (it->f))
22145 {
22146 int ii, n;
22147
22148 if (it->current_x > it->last_visible_x)
22149 {
22150 if (!row->reversed_p)
22151 {
22152 for (ii = row->used[TEXT_AREA] - 1; ii > 0; --ii)
22153 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][ii]))
22154 break;
22155 }
22156 else
22157 {
22158 for (ii = 0; ii < row->used[TEXT_AREA]; ii++)
22159 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][ii]))
22160 break;
22161 unproduce_glyphs (it, ii + 1);
22162 ii = row->used[TEXT_AREA] - (ii + 1);
22163 }
22164 for (n = row->used[TEXT_AREA]; ii < n; ++ii)
22165 {
22166 row->used[TEXT_AREA] = ii;
22167 produce_special_glyphs (it, IT_TRUNCATION);
22168 }
22169 }
22170 produce_special_glyphs (it, IT_TRUNCATION);
22171 }
22172 row->truncated_on_right_p = 1;
22173 }
22174 break;
22175 }
22176 }
22177
22178 /* Maybe insert a truncation at the left. */
22179 if (it->first_visible_x
22180 && it_charpos > 0)
22181 {
22182 if (!FRAME_WINDOW_P (it->f)
22183 || (row->reversed_p
22184 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
22185 : WINDOW_LEFT_FRINGE_WIDTH (it->w)) == 0)
22186 insert_left_trunc_glyphs (it);
22187 row->truncated_on_left_p = 1;
22188 }
22189
22190 it->face_id = saved_face_id;
22191
22192 /* Value is number of columns displayed. */
22193 return it->hpos - hpos_at_start;
22194 }
22195
22196
22197 \f
22198 /* This is like a combination of memq and assq. Return 1/2 if PROPVAL
22199 appears as an element of LIST or as the car of an element of LIST.
22200 If PROPVAL is a list, compare each element against LIST in that
22201 way, and return 1/2 if any element of PROPVAL is found in LIST.
22202 Otherwise return 0. This function cannot quit.
22203 The return value is 2 if the text is invisible but with an ellipsis
22204 and 1 if it's invisible and without an ellipsis. */
22205
22206 int
22207 invisible_p (register Lisp_Object propval, Lisp_Object list)
22208 {
22209 register Lisp_Object tail, proptail;
22210
22211 for (tail = list; CONSP (tail); tail = XCDR (tail))
22212 {
22213 register Lisp_Object tem;
22214 tem = XCAR (tail);
22215 if (EQ (propval, tem))
22216 return 1;
22217 if (CONSP (tem) && EQ (propval, XCAR (tem)))
22218 return NILP (XCDR (tem)) ? 1 : 2;
22219 }
22220
22221 if (CONSP (propval))
22222 {
22223 for (proptail = propval; CONSP (proptail); proptail = XCDR (proptail))
22224 {
22225 Lisp_Object propelt;
22226 propelt = XCAR (proptail);
22227 for (tail = list; CONSP (tail); tail = XCDR (tail))
22228 {
22229 register Lisp_Object tem;
22230 tem = XCAR (tail);
22231 if (EQ (propelt, tem))
22232 return 1;
22233 if (CONSP (tem) && EQ (propelt, XCAR (tem)))
22234 return NILP (XCDR (tem)) ? 1 : 2;
22235 }
22236 }
22237 }
22238
22239 return 0;
22240 }
22241
22242 DEFUN ("invisible-p", Finvisible_p, Sinvisible_p, 1, 1, 0,
22243 doc: /* Non-nil if the property makes the text invisible.
22244 POS-OR-PROP can be a marker or number, in which case it is taken to be
22245 a position in the current buffer and the value of the `invisible' property
22246 is checked; or it can be some other value, which is then presumed to be the
22247 value of the `invisible' property of the text of interest.
22248 The non-nil value returned can be t for truly invisible text or something
22249 else if the text is replaced by an ellipsis. */)
22250 (Lisp_Object pos_or_prop)
22251 {
22252 Lisp_Object prop
22253 = (NATNUMP (pos_or_prop) || MARKERP (pos_or_prop)
22254 ? Fget_char_property (pos_or_prop, Qinvisible, Qnil)
22255 : pos_or_prop);
22256 int invis = TEXT_PROP_MEANS_INVISIBLE (prop);
22257 return (invis == 0 ? Qnil
22258 : invis == 1 ? Qt
22259 : make_number (invis));
22260 }
22261
22262 /* Calculate a width or height in pixels from a specification using
22263 the following elements:
22264
22265 SPEC ::=
22266 NUM - a (fractional) multiple of the default font width/height
22267 (NUM) - specifies exactly NUM pixels
22268 UNIT - a fixed number of pixels, see below.
22269 ELEMENT - size of a display element in pixels, see below.
22270 (NUM . SPEC) - equals NUM * SPEC
22271 (+ SPEC SPEC ...) - add pixel values
22272 (- SPEC SPEC ...) - subtract pixel values
22273 (- SPEC) - negate pixel value
22274
22275 NUM ::=
22276 INT or FLOAT - a number constant
22277 SYMBOL - use symbol's (buffer local) variable binding.
22278
22279 UNIT ::=
22280 in - pixels per inch *)
22281 mm - pixels per 1/1000 meter *)
22282 cm - pixels per 1/100 meter *)
22283 width - width of current font in pixels.
22284 height - height of current font in pixels.
22285
22286 *) using the ratio(s) defined in display-pixels-per-inch.
22287
22288 ELEMENT ::=
22289
22290 left-fringe - left fringe width in pixels
22291 right-fringe - right fringe width in pixels
22292
22293 left-margin - left margin width in pixels
22294 right-margin - right margin width in pixels
22295
22296 scroll-bar - scroll-bar area width in pixels
22297
22298 Examples:
22299
22300 Pixels corresponding to 5 inches:
22301 (5 . in)
22302
22303 Total width of non-text areas on left side of window (if scroll-bar is on left):
22304 '(space :width (+ left-fringe left-margin scroll-bar))
22305
22306 Align to first text column (in header line):
22307 '(space :align-to 0)
22308
22309 Align to middle of text area minus half the width of variable `my-image'
22310 containing a loaded image:
22311 '(space :align-to (0.5 . (- text my-image)))
22312
22313 Width of left margin minus width of 1 character in the default font:
22314 '(space :width (- left-margin 1))
22315
22316 Width of left margin minus width of 2 characters in the current font:
22317 '(space :width (- left-margin (2 . width)))
22318
22319 Center 1 character over left-margin (in header line):
22320 '(space :align-to (+ left-margin (0.5 . left-margin) -0.5))
22321
22322 Different ways to express width of left fringe plus left margin minus one pixel:
22323 '(space :width (- (+ left-fringe left-margin) (1)))
22324 '(space :width (+ left-fringe left-margin (- (1))))
22325 '(space :width (+ left-fringe left-margin (-1)))
22326
22327 */
22328
22329 #define NUMVAL(X) \
22330 ((INTEGERP (X) || FLOATP (X)) \
22331 ? XFLOATINT (X) \
22332 : - 1)
22333
22334 static int
22335 calc_pixel_width_or_height (double *res, struct it *it, Lisp_Object prop,
22336 struct font *font, int width_p, int *align_to)
22337 {
22338 double pixels;
22339
22340 #define OK_PIXELS(val) ((*res = (double)(val)), 1)
22341 #define OK_ALIGN_TO(val) ((*align_to = (int)(val)), 1)
22342
22343 if (NILP (prop))
22344 return OK_PIXELS (0);
22345
22346 eassert (FRAME_LIVE_P (it->f));
22347
22348 if (SYMBOLP (prop))
22349 {
22350 if (SCHARS (SYMBOL_NAME (prop)) == 2)
22351 {
22352 char *unit = SSDATA (SYMBOL_NAME (prop));
22353
22354 if (unit[0] == 'i' && unit[1] == 'n')
22355 pixels = 1.0;
22356 else if (unit[0] == 'm' && unit[1] == 'm')
22357 pixels = 25.4;
22358 else if (unit[0] == 'c' && unit[1] == 'm')
22359 pixels = 2.54;
22360 else
22361 pixels = 0;
22362 if (pixels > 0)
22363 {
22364 double ppi;
22365 #ifdef HAVE_WINDOW_SYSTEM
22366 if (FRAME_WINDOW_P (it->f)
22367 && (ppi = (width_p
22368 ? FRAME_X_DISPLAY_INFO (it->f)->resx
22369 : FRAME_X_DISPLAY_INFO (it->f)->resy),
22370 ppi > 0))
22371 return OK_PIXELS (ppi / pixels);
22372 #endif
22373
22374 if ((ppi = NUMVAL (Vdisplay_pixels_per_inch), ppi > 0)
22375 || (CONSP (Vdisplay_pixels_per_inch)
22376 && (ppi = (width_p
22377 ? NUMVAL (XCAR (Vdisplay_pixels_per_inch))
22378 : NUMVAL (XCDR (Vdisplay_pixels_per_inch))),
22379 ppi > 0)))
22380 return OK_PIXELS (ppi / pixels);
22381
22382 return 0;
22383 }
22384 }
22385
22386 #ifdef HAVE_WINDOW_SYSTEM
22387 if (EQ (prop, Qheight))
22388 return OK_PIXELS (font ? FONT_HEIGHT (font) : FRAME_LINE_HEIGHT (it->f));
22389 if (EQ (prop, Qwidth))
22390 return OK_PIXELS (font ? FONT_WIDTH (font) : FRAME_COLUMN_WIDTH (it->f));
22391 #else
22392 if (EQ (prop, Qheight) || EQ (prop, Qwidth))
22393 return OK_PIXELS (1);
22394 #endif
22395
22396 if (EQ (prop, Qtext))
22397 return OK_PIXELS (width_p
22398 ? window_box_width (it->w, TEXT_AREA)
22399 : WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w));
22400
22401 if (align_to && *align_to < 0)
22402 {
22403 *res = 0;
22404 if (EQ (prop, Qleft))
22405 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA));
22406 if (EQ (prop, Qright))
22407 return OK_ALIGN_TO (window_box_right_offset (it->w, TEXT_AREA));
22408 if (EQ (prop, Qcenter))
22409 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA)
22410 + window_box_width (it->w, TEXT_AREA) / 2);
22411 if (EQ (prop, Qleft_fringe))
22412 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
22413 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (it->w)
22414 : window_box_right_offset (it->w, LEFT_MARGIN_AREA));
22415 if (EQ (prop, Qright_fringe))
22416 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
22417 ? window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
22418 : window_box_right_offset (it->w, TEXT_AREA));
22419 if (EQ (prop, Qleft_margin))
22420 return OK_ALIGN_TO (window_box_left_offset (it->w, LEFT_MARGIN_AREA));
22421 if (EQ (prop, Qright_margin))
22422 return OK_ALIGN_TO (window_box_left_offset (it->w, RIGHT_MARGIN_AREA));
22423 if (EQ (prop, Qscroll_bar))
22424 return OK_ALIGN_TO (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (it->w)
22425 ? 0
22426 : (window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
22427 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
22428 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
22429 : 0)));
22430 }
22431 else
22432 {
22433 if (EQ (prop, Qleft_fringe))
22434 return OK_PIXELS (WINDOW_LEFT_FRINGE_WIDTH (it->w));
22435 if (EQ (prop, Qright_fringe))
22436 return OK_PIXELS (WINDOW_RIGHT_FRINGE_WIDTH (it->w));
22437 if (EQ (prop, Qleft_margin))
22438 return OK_PIXELS (WINDOW_LEFT_MARGIN_WIDTH (it->w));
22439 if (EQ (prop, Qright_margin))
22440 return OK_PIXELS (WINDOW_RIGHT_MARGIN_WIDTH (it->w));
22441 if (EQ (prop, Qscroll_bar))
22442 return OK_PIXELS (WINDOW_SCROLL_BAR_AREA_WIDTH (it->w));
22443 }
22444
22445 prop = buffer_local_value_1 (prop, it->w->buffer);
22446 if (EQ (prop, Qunbound))
22447 prop = Qnil;
22448 }
22449
22450 if (INTEGERP (prop) || FLOATP (prop))
22451 {
22452 int base_unit = (width_p
22453 ? FRAME_COLUMN_WIDTH (it->f)
22454 : FRAME_LINE_HEIGHT (it->f));
22455 return OK_PIXELS (XFLOATINT (prop) * base_unit);
22456 }
22457
22458 if (CONSP (prop))
22459 {
22460 Lisp_Object car = XCAR (prop);
22461 Lisp_Object cdr = XCDR (prop);
22462
22463 if (SYMBOLP (car))
22464 {
22465 #ifdef HAVE_WINDOW_SYSTEM
22466 if (FRAME_WINDOW_P (it->f)
22467 && valid_image_p (prop))
22468 {
22469 ptrdiff_t id = lookup_image (it->f, prop);
22470 struct image *img = IMAGE_FROM_ID (it->f, id);
22471
22472 return OK_PIXELS (width_p ? img->width : img->height);
22473 }
22474 #ifdef HAVE_XWIDGETS
22475 if (FRAME_WINDOW_P (it->f) && valid_xwidget_p (prop))
22476 {
22477 printf("calc_pixel_width_or_height: return dummy size FIXME\n");
22478 return OK_PIXELS (width_p ? 100 : 100);
22479 }
22480 #endif
22481 #endif
22482 if (EQ (car, Qplus) || EQ (car, Qminus))
22483 {
22484 int first = 1;
22485 double px;
22486
22487 pixels = 0;
22488 while (CONSP (cdr))
22489 {
22490 if (!calc_pixel_width_or_height (&px, it, XCAR (cdr),
22491 font, width_p, align_to))
22492 return 0;
22493 if (first)
22494 pixels = (EQ (car, Qplus) ? px : -px), first = 0;
22495 else
22496 pixels += px;
22497 cdr = XCDR (cdr);
22498 }
22499 if (EQ (car, Qminus))
22500 pixels = -pixels;
22501 return OK_PIXELS (pixels);
22502 }
22503
22504 car = buffer_local_value_1 (car, it->w->buffer);
22505 if (EQ (car, Qunbound))
22506 car = Qnil;
22507 }
22508
22509 if (INTEGERP (car) || FLOATP (car))
22510 {
22511 double fact;
22512 pixels = XFLOATINT (car);
22513 if (NILP (cdr))
22514 return OK_PIXELS (pixels);
22515 if (calc_pixel_width_or_height (&fact, it, cdr,
22516 font, width_p, align_to))
22517 return OK_PIXELS (pixels * fact);
22518 return 0;
22519 }
22520
22521 return 0;
22522 }
22523
22524 return 0;
22525 }
22526
22527 \f
22528 /***********************************************************************
22529 Glyph Display
22530 ***********************************************************************/
22531
22532 #ifdef HAVE_WINDOW_SYSTEM
22533
22534 #ifdef GLYPH_DEBUG
22535
22536 void
22537 dump_glyph_string (struct glyph_string *s)
22538 {
22539 fprintf (stderr, "glyph string\n");
22540 fprintf (stderr, " x, y, w, h = %d, %d, %d, %d\n",
22541 s->x, s->y, s->width, s->height);
22542 fprintf (stderr, " ybase = %d\n", s->ybase);
22543 fprintf (stderr, " hl = %d\n", s->hl);
22544 fprintf (stderr, " left overhang = %d, right = %d\n",
22545 s->left_overhang, s->right_overhang);
22546 fprintf (stderr, " nchars = %d\n", s->nchars);
22547 fprintf (stderr, " extends to end of line = %d\n",
22548 s->extends_to_end_of_line_p);
22549 fprintf (stderr, " font height = %d\n", FONT_HEIGHT (s->font));
22550 fprintf (stderr, " bg width = %d\n", s->background_width);
22551 }
22552
22553 #endif /* GLYPH_DEBUG */
22554
22555 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
22556 of XChar2b structures for S; it can't be allocated in
22557 init_glyph_string because it must be allocated via `alloca'. W
22558 is the window on which S is drawn. ROW and AREA are the glyph row
22559 and area within the row from which S is constructed. START is the
22560 index of the first glyph structure covered by S. HL is a
22561 face-override for drawing S. */
22562
22563 #ifdef HAVE_NTGUI
22564 #define OPTIONAL_HDC(hdc) HDC hdc,
22565 #define DECLARE_HDC(hdc) HDC hdc;
22566 #define ALLOCATE_HDC(hdc, f) hdc = get_frame_dc ((f))
22567 #define RELEASE_HDC(hdc, f) release_frame_dc ((f), (hdc))
22568 #endif
22569
22570 #ifndef OPTIONAL_HDC
22571 #define OPTIONAL_HDC(hdc)
22572 #define DECLARE_HDC(hdc)
22573 #define ALLOCATE_HDC(hdc, f)
22574 #define RELEASE_HDC(hdc, f)
22575 #endif
22576
22577 static void
22578 init_glyph_string (struct glyph_string *s,
22579 OPTIONAL_HDC (hdc)
22580 XChar2b *char2b, struct window *w, struct glyph_row *row,
22581 enum glyph_row_area area, int start, enum draw_glyphs_face hl)
22582 {
22583 memset (s, 0, sizeof *s);
22584 s->w = w;
22585 s->f = XFRAME (w->frame);
22586 #ifdef HAVE_NTGUI
22587 s->hdc = hdc;
22588 #endif
22589 s->display = FRAME_X_DISPLAY (s->f);
22590 s->window = FRAME_X_WINDOW (s->f);
22591 s->char2b = char2b;
22592 s->hl = hl;
22593 s->row = row;
22594 s->area = area;
22595 s->first_glyph = row->glyphs[area] + start;
22596 s->height = row->height;
22597 s->y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
22598 s->ybase = s->y + row->ascent;
22599 }
22600
22601
22602 /* Append the list of glyph strings with head H and tail T to the list
22603 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
22604
22605 static inline void
22606 append_glyph_string_lists (struct glyph_string **head, struct glyph_string **tail,
22607 struct glyph_string *h, struct glyph_string *t)
22608 {
22609 if (h)
22610 {
22611 if (*head)
22612 (*tail)->next = h;
22613 else
22614 *head = h;
22615 h->prev = *tail;
22616 *tail = t;
22617 }
22618 }
22619
22620
22621 /* Prepend the list of glyph strings with head H and tail T to the
22622 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
22623 result. */
22624
22625 static inline void
22626 prepend_glyph_string_lists (struct glyph_string **head, struct glyph_string **tail,
22627 struct glyph_string *h, struct glyph_string *t)
22628 {
22629 if (h)
22630 {
22631 if (*head)
22632 (*head)->prev = t;
22633 else
22634 *tail = t;
22635 t->next = *head;
22636 *head = h;
22637 }
22638 }
22639
22640
22641 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
22642 Set *HEAD and *TAIL to the resulting list. */
22643
22644 static inline void
22645 append_glyph_string (struct glyph_string **head, struct glyph_string **tail,
22646 struct glyph_string *s)
22647 {
22648 s->next = s->prev = NULL;
22649 append_glyph_string_lists (head, tail, s, s);
22650 }
22651
22652
22653 /* Get face and two-byte form of character C in face FACE_ID on frame F.
22654 The encoding of C is returned in *CHAR2B. DISPLAY_P non-zero means
22655 make sure that X resources for the face returned are allocated.
22656 Value is a pointer to a realized face that is ready for display if
22657 DISPLAY_P is non-zero. */
22658
22659 static inline struct face *
22660 get_char_face_and_encoding (struct frame *f, int c, int face_id,
22661 XChar2b *char2b, int display_p)
22662 {
22663 struct face *face = FACE_FROM_ID (f, face_id);
22664
22665 if (face->font)
22666 {
22667 unsigned code = face->font->driver->encode_char (face->font, c);
22668
22669 if (code != FONT_INVALID_CODE)
22670 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
22671 else
22672 STORE_XCHAR2B (char2b, 0, 0);
22673 }
22674
22675 /* Make sure X resources of the face are allocated. */
22676 #ifdef HAVE_X_WINDOWS
22677 if (display_p)
22678 #endif
22679 {
22680 eassert (face != NULL);
22681 PREPARE_FACE_FOR_DISPLAY (f, face);
22682 }
22683
22684 return face;
22685 }
22686
22687
22688 /* Get face and two-byte form of character glyph GLYPH on frame F.
22689 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
22690 a pointer to a realized face that is ready for display. */
22691
22692 static inline struct face *
22693 get_glyph_face_and_encoding (struct frame *f, struct glyph *glyph,
22694 XChar2b *char2b, int *two_byte_p)
22695 {
22696 struct face *face;
22697
22698 eassert (glyph->type == CHAR_GLYPH);
22699 face = FACE_FROM_ID (f, glyph->face_id);
22700
22701 if (two_byte_p)
22702 *two_byte_p = 0;
22703
22704 if (face->font)
22705 {
22706 unsigned code;
22707
22708 if (CHAR_BYTE8_P (glyph->u.ch))
22709 code = CHAR_TO_BYTE8 (glyph->u.ch);
22710 else
22711 code = face->font->driver->encode_char (face->font, glyph->u.ch);
22712
22713 if (code != FONT_INVALID_CODE)
22714 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
22715 else
22716 STORE_XCHAR2B (char2b, 0, 0);
22717 }
22718
22719 /* Make sure X resources of the face are allocated. */
22720 eassert (face != NULL);
22721 PREPARE_FACE_FOR_DISPLAY (f, face);
22722 return face;
22723 }
22724
22725
22726 /* Get glyph code of character C in FONT in the two-byte form CHAR2B.
22727 Return 1 if FONT has a glyph for C, otherwise return 0. */
22728
22729 static inline int
22730 get_char_glyph_code (int c, struct font *font, XChar2b *char2b)
22731 {
22732 unsigned code;
22733
22734 if (CHAR_BYTE8_P (c))
22735 code = CHAR_TO_BYTE8 (c);
22736 else
22737 code = font->driver->encode_char (font, c);
22738
22739 if (code == FONT_INVALID_CODE)
22740 return 0;
22741 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
22742 return 1;
22743 }
22744
22745
22746 /* Fill glyph string S with composition components specified by S->cmp.
22747
22748 BASE_FACE is the base face of the composition.
22749 S->cmp_from is the index of the first component for S.
22750
22751 OVERLAPS non-zero means S should draw the foreground only, and use
22752 its physical height for clipping. See also draw_glyphs.
22753
22754 Value is the index of a component not in S. */
22755
22756 static int
22757 fill_composite_glyph_string (struct glyph_string *s, struct face *base_face,
22758 int overlaps)
22759 {
22760 int i;
22761 /* For all glyphs of this composition, starting at the offset
22762 S->cmp_from, until we reach the end of the definition or encounter a
22763 glyph that requires the different face, add it to S. */
22764 struct face *face;
22765
22766 eassert (s);
22767
22768 s->for_overlaps = overlaps;
22769 s->face = NULL;
22770 s->font = NULL;
22771 for (i = s->cmp_from; i < s->cmp->glyph_len; i++)
22772 {
22773 int c = COMPOSITION_GLYPH (s->cmp, i);
22774
22775 /* TAB in a composition means display glyphs with padding space
22776 on the left or right. */
22777 if (c != '\t')
22778 {
22779 int face_id = FACE_FOR_CHAR (s->f, base_face->ascii_face, c,
22780 -1, Qnil);
22781
22782 face = get_char_face_and_encoding (s->f, c, face_id,
22783 s->char2b + i, 1);
22784 if (face)
22785 {
22786 if (! s->face)
22787 {
22788 s->face = face;
22789 s->font = s->face->font;
22790 }
22791 else if (s->face != face)
22792 break;
22793 }
22794 }
22795 ++s->nchars;
22796 }
22797 s->cmp_to = i;
22798
22799 if (s->face == NULL)
22800 {
22801 s->face = base_face->ascii_face;
22802 s->font = s->face->font;
22803 }
22804
22805 /* All glyph strings for the same composition has the same width,
22806 i.e. the width set for the first component of the composition. */
22807 s->width = s->first_glyph->pixel_width;
22808
22809 /* If the specified font could not be loaded, use the frame's
22810 default font, but record the fact that we couldn't load it in
22811 the glyph string so that we can draw rectangles for the
22812 characters of the glyph string. */
22813 if (s->font == NULL)
22814 {
22815 s->font_not_found_p = 1;
22816 s->font = FRAME_FONT (s->f);
22817 }
22818
22819 /* Adjust base line for subscript/superscript text. */
22820 s->ybase += s->first_glyph->voffset;
22821
22822 /* This glyph string must always be drawn with 16-bit functions. */
22823 s->two_byte_p = 1;
22824
22825 return s->cmp_to;
22826 }
22827
22828 static int
22829 fill_gstring_glyph_string (struct glyph_string *s, int face_id,
22830 int start, int end, int overlaps)
22831 {
22832 struct glyph *glyph, *last;
22833 Lisp_Object lgstring;
22834 int i;
22835
22836 s->for_overlaps = overlaps;
22837 glyph = s->row->glyphs[s->area] + start;
22838 last = s->row->glyphs[s->area] + end;
22839 s->cmp_id = glyph->u.cmp.id;
22840 s->cmp_from = glyph->slice.cmp.from;
22841 s->cmp_to = glyph->slice.cmp.to + 1;
22842 s->face = FACE_FROM_ID (s->f, face_id);
22843 lgstring = composition_gstring_from_id (s->cmp_id);
22844 s->font = XFONT_OBJECT (LGSTRING_FONT (lgstring));
22845 glyph++;
22846 while (glyph < last
22847 && glyph->u.cmp.automatic
22848 && glyph->u.cmp.id == s->cmp_id
22849 && s->cmp_to == glyph->slice.cmp.from)
22850 s->cmp_to = (glyph++)->slice.cmp.to + 1;
22851
22852 for (i = s->cmp_from; i < s->cmp_to; i++)
22853 {
22854 Lisp_Object lglyph = LGSTRING_GLYPH (lgstring, i);
22855 unsigned code = LGLYPH_CODE (lglyph);
22856
22857 STORE_XCHAR2B ((s->char2b + i), code >> 8, code & 0xFF);
22858 }
22859 s->width = composition_gstring_width (lgstring, s->cmp_from, s->cmp_to, NULL);
22860 return glyph - s->row->glyphs[s->area];
22861 }
22862
22863
22864 /* Fill glyph string S from a sequence glyphs for glyphless characters.
22865 See the comment of fill_glyph_string for arguments.
22866 Value is the index of the first glyph not in S. */
22867
22868
22869 static int
22870 fill_glyphless_glyph_string (struct glyph_string *s, int face_id,
22871 int start, int end, int overlaps)
22872 {
22873 struct glyph *glyph, *last;
22874 int voffset;
22875
22876 eassert (s->first_glyph->type == GLYPHLESS_GLYPH);
22877 s->for_overlaps = overlaps;
22878 glyph = s->row->glyphs[s->area] + start;
22879 last = s->row->glyphs[s->area] + end;
22880 voffset = glyph->voffset;
22881 s->face = FACE_FROM_ID (s->f, face_id);
22882 s->font = s->face->font ? s->face->font : FRAME_FONT (s->f);
22883 s->nchars = 1;
22884 s->width = glyph->pixel_width;
22885 glyph++;
22886 while (glyph < last
22887 && glyph->type == GLYPHLESS_GLYPH
22888 && glyph->voffset == voffset
22889 && glyph->face_id == face_id)
22890 {
22891 s->nchars++;
22892 s->width += glyph->pixel_width;
22893 glyph++;
22894 }
22895 s->ybase += voffset;
22896 return glyph - s->row->glyphs[s->area];
22897 }
22898
22899
22900 /* Fill glyph string S from a sequence of character glyphs.
22901
22902 FACE_ID is the face id of the string. START is the index of the
22903 first glyph to consider, END is the index of the last + 1.
22904 OVERLAPS non-zero means S should draw the foreground only, and use
22905 its physical height for clipping. See also draw_glyphs.
22906
22907 Value is the index of the first glyph not in S. */
22908
22909 static int
22910 fill_glyph_string (struct glyph_string *s, int face_id,
22911 int start, int end, int overlaps)
22912 {
22913 struct glyph *glyph, *last;
22914 int voffset;
22915 int glyph_not_available_p;
22916
22917 eassert (s->f == XFRAME (s->w->frame));
22918 eassert (s->nchars == 0);
22919 eassert (start >= 0 && end > start);
22920
22921 s->for_overlaps = overlaps;
22922 glyph = s->row->glyphs[s->area] + start;
22923 last = s->row->glyphs[s->area] + end;
22924 voffset = glyph->voffset;
22925 s->padding_p = glyph->padding_p;
22926 glyph_not_available_p = glyph->glyph_not_available_p;
22927
22928 while (glyph < last
22929 && glyph->type == CHAR_GLYPH
22930 && glyph->voffset == voffset
22931 /* Same face id implies same font, nowadays. */
22932 && glyph->face_id == face_id
22933 && glyph->glyph_not_available_p == glyph_not_available_p)
22934 {
22935 int two_byte_p;
22936
22937 s->face = get_glyph_face_and_encoding (s->f, glyph,
22938 s->char2b + s->nchars,
22939 &two_byte_p);
22940 s->two_byte_p = two_byte_p;
22941 ++s->nchars;
22942 eassert (s->nchars <= end - start);
22943 s->width += glyph->pixel_width;
22944 if (glyph++->padding_p != s->padding_p)
22945 break;
22946 }
22947
22948 s->font = s->face->font;
22949
22950 /* If the specified font could not be loaded, use the frame's font,
22951 but record the fact that we couldn't load it in
22952 S->font_not_found_p so that we can draw rectangles for the
22953 characters of the glyph string. */
22954 if (s->font == NULL || glyph_not_available_p)
22955 {
22956 s->font_not_found_p = 1;
22957 s->font = FRAME_FONT (s->f);
22958 }
22959
22960 /* Adjust base line for subscript/superscript text. */
22961 s->ybase += voffset;
22962
22963 eassert (s->face && s->face->gc);
22964 return glyph - s->row->glyphs[s->area];
22965 }
22966
22967
22968 /* Fill glyph string S from image glyph S->first_glyph. */
22969
22970 static void
22971 fill_image_glyph_string (struct glyph_string *s)
22972 {
22973 eassert (s->first_glyph->type == IMAGE_GLYPH);
22974 s->img = IMAGE_FROM_ID (s->f, s->first_glyph->u.img_id);
22975 eassert (s->img);
22976 s->slice = s->first_glyph->slice.img;
22977 s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
22978 s->font = s->face->font;
22979 s->width = s->first_glyph->pixel_width;
22980
22981 /* Adjust base line for subscript/superscript text. */
22982 s->ybase += s->first_glyph->voffset;
22983 }
22984
22985 #ifdef HAVE_XWIDGETS
22986 static void
22987 fill_xwidget_glyph_string (struct glyph_string *s)
22988 {
22989 eassert (s->first_glyph->type == XWIDGET_GLYPH);
22990 printf("fill_xwidget_glyph_string: width:%d \n",s->first_glyph->pixel_width);
22991 s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
22992 s->font = s->face->font;
22993 s->width = s->first_glyph->pixel_width;
22994 s->ybase += s->first_glyph->voffset;
22995 s->xwidget = s->first_glyph->u.xwidget;
22996 //assert_valid_xwidget_id ( s->xwidget, "fill_xwidget_glyph_string");
22997 }
22998 #endif
22999 /* Fill glyph string S from a sequence of stretch glyphs.
23000
23001 START is the index of the first glyph to consider,
23002 END is the index of the last + 1.
23003
23004 Value is the index of the first glyph not in S. */
23005
23006 static int
23007 fill_stretch_glyph_string (struct glyph_string *s, int start, int end)
23008 {
23009 struct glyph *glyph, *last;
23010 int voffset, face_id;
23011
23012 eassert (s->first_glyph->type == STRETCH_GLYPH);
23013
23014 glyph = s->row->glyphs[s->area] + start;
23015 last = s->row->glyphs[s->area] + end;
23016 face_id = glyph->face_id;
23017 s->face = FACE_FROM_ID (s->f, face_id);
23018 s->font = s->face->font;
23019 s->width = glyph->pixel_width;
23020 s->nchars = 1;
23021 voffset = glyph->voffset;
23022
23023 for (++glyph;
23024 (glyph < last
23025 && glyph->type == STRETCH_GLYPH
23026 && glyph->voffset == voffset
23027 && glyph->face_id == face_id);
23028 ++glyph)
23029 s->width += glyph->pixel_width;
23030
23031 /* Adjust base line for subscript/superscript text. */
23032 s->ybase += voffset;
23033
23034 /* The case that face->gc == 0 is handled when drawing the glyph
23035 string by calling PREPARE_FACE_FOR_DISPLAY. */
23036 eassert (s->face);
23037 return glyph - s->row->glyphs[s->area];
23038 }
23039
23040 static struct font_metrics *
23041 get_per_char_metric (struct font *font, XChar2b *char2b)
23042 {
23043 static struct font_metrics metrics;
23044 unsigned code = (XCHAR2B_BYTE1 (char2b) << 8) | XCHAR2B_BYTE2 (char2b);
23045
23046 if (! font || code == FONT_INVALID_CODE)
23047 return NULL;
23048 font->driver->text_extents (font, &code, 1, &metrics);
23049 return &metrics;
23050 }
23051
23052 /* EXPORT for RIF:
23053 Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
23054 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
23055 assumed to be zero. */
23056
23057 void
23058 x_get_glyph_overhangs (struct glyph *glyph, struct frame *f, int *left, int *right)
23059 {
23060 *left = *right = 0;
23061
23062 if (glyph->type == CHAR_GLYPH)
23063 {
23064 struct face *face;
23065 XChar2b char2b;
23066 struct font_metrics *pcm;
23067
23068 face = get_glyph_face_and_encoding (f, glyph, &char2b, NULL);
23069 if (face->font && (pcm = get_per_char_metric (face->font, &char2b)))
23070 {
23071 if (pcm->rbearing > pcm->width)
23072 *right = pcm->rbearing - pcm->width;
23073 if (pcm->lbearing < 0)
23074 *left = -pcm->lbearing;
23075 }
23076 }
23077 else if (glyph->type == COMPOSITE_GLYPH)
23078 {
23079 if (! glyph->u.cmp.automatic)
23080 {
23081 struct composition *cmp = composition_table[glyph->u.cmp.id];
23082
23083 if (cmp->rbearing > cmp->pixel_width)
23084 *right = cmp->rbearing - cmp->pixel_width;
23085 if (cmp->lbearing < 0)
23086 *left = - cmp->lbearing;
23087 }
23088 else
23089 {
23090 Lisp_Object gstring = composition_gstring_from_id (glyph->u.cmp.id);
23091 struct font_metrics metrics;
23092
23093 composition_gstring_width (gstring, glyph->slice.cmp.from,
23094 glyph->slice.cmp.to + 1, &metrics);
23095 if (metrics.rbearing > metrics.width)
23096 *right = metrics.rbearing - metrics.width;
23097 if (metrics.lbearing < 0)
23098 *left = - metrics.lbearing;
23099 }
23100 }
23101 }
23102
23103
23104 /* Return the index of the first glyph preceding glyph string S that
23105 is overwritten by S because of S's left overhang. Value is -1
23106 if no glyphs are overwritten. */
23107
23108 static int
23109 left_overwritten (struct glyph_string *s)
23110 {
23111 int k;
23112
23113 if (s->left_overhang)
23114 {
23115 int x = 0, i;
23116 struct glyph *glyphs = s->row->glyphs[s->area];
23117 int first = s->first_glyph - glyphs;
23118
23119 for (i = first - 1; i >= 0 && x > -s->left_overhang; --i)
23120 x -= glyphs[i].pixel_width;
23121
23122 k = i + 1;
23123 }
23124 else
23125 k = -1;
23126
23127 return k;
23128 }
23129
23130
23131 /* Return the index of the first glyph preceding glyph string S that
23132 is overwriting S because of its right overhang. Value is -1 if no
23133 glyph in front of S overwrites S. */
23134
23135 static int
23136 left_overwriting (struct glyph_string *s)
23137 {
23138 int i, k, x;
23139 struct glyph *glyphs = s->row->glyphs[s->area];
23140 int first = s->first_glyph - glyphs;
23141
23142 k = -1;
23143 x = 0;
23144 for (i = first - 1; i >= 0; --i)
23145 {
23146 int left, right;
23147 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
23148 if (x + right > 0)
23149 k = i;
23150 x -= glyphs[i].pixel_width;
23151 }
23152
23153 return k;
23154 }
23155
23156
23157 /* Return the index of the last glyph following glyph string S that is
23158 overwritten by S because of S's right overhang. Value is -1 if
23159 no such glyph is found. */
23160
23161 static int
23162 right_overwritten (struct glyph_string *s)
23163 {
23164 int k = -1;
23165
23166 if (s->right_overhang)
23167 {
23168 int x = 0, i;
23169 struct glyph *glyphs = s->row->glyphs[s->area];
23170 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
23171 int end = s->row->used[s->area];
23172
23173 for (i = first; i < end && s->right_overhang > x; ++i)
23174 x += glyphs[i].pixel_width;
23175
23176 k = i;
23177 }
23178
23179 return k;
23180 }
23181
23182
23183 /* Return the index of the last glyph following glyph string S that
23184 overwrites S because of its left overhang. Value is negative
23185 if no such glyph is found. */
23186
23187 static int
23188 right_overwriting (struct glyph_string *s)
23189 {
23190 int i, k, x;
23191 int end = s->row->used[s->area];
23192 struct glyph *glyphs = s->row->glyphs[s->area];
23193 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
23194
23195 k = -1;
23196 x = 0;
23197 for (i = first; i < end; ++i)
23198 {
23199 int left, right;
23200 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
23201 if (x - left < 0)
23202 k = i;
23203 x += glyphs[i].pixel_width;
23204 }
23205
23206 return k;
23207 }
23208
23209
23210 /* Set background width of glyph string S. START is the index of the
23211 first glyph following S. LAST_X is the right-most x-position + 1
23212 in the drawing area. */
23213
23214 static inline void
23215 set_glyph_string_background_width (struct glyph_string *s, int start, int last_x)
23216 {
23217 /* If the face of this glyph string has to be drawn to the end of
23218 the drawing area, set S->extends_to_end_of_line_p. */
23219
23220 if (start == s->row->used[s->area]
23221 && s->area == TEXT_AREA
23222 && ((s->row->fill_line_p
23223 && (s->hl == DRAW_NORMAL_TEXT
23224 || s->hl == DRAW_IMAGE_RAISED
23225 || s->hl == DRAW_IMAGE_SUNKEN))
23226 || s->hl == DRAW_MOUSE_FACE))
23227 s->extends_to_end_of_line_p = 1;
23228
23229 /* If S extends its face to the end of the line, set its
23230 background_width to the distance to the right edge of the drawing
23231 area. */
23232 if (s->extends_to_end_of_line_p)
23233 s->background_width = last_x - s->x + 1;
23234 else
23235 s->background_width = s->width;
23236 }
23237
23238
23239 /* Compute overhangs and x-positions for glyph string S and its
23240 predecessors, or successors. X is the starting x-position for S.
23241 BACKWARD_P non-zero means process predecessors. */
23242
23243 static void
23244 compute_overhangs_and_x (struct glyph_string *s, int x, int backward_p)
23245 {
23246 if (backward_p)
23247 {
23248 while (s)
23249 {
23250 if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
23251 FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
23252 x -= s->width;
23253 s->x = x;
23254 s = s->prev;
23255 }
23256 }
23257 else
23258 {
23259 while (s)
23260 {
23261 if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
23262 FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
23263 s->x = x;
23264 x += s->width;
23265 s = s->next;
23266 }
23267 }
23268 }
23269
23270
23271
23272 /* The following macros are only called from draw_glyphs below.
23273 They reference the following parameters of that function directly:
23274 `w', `row', `area', and `overlap_p'
23275 as well as the following local variables:
23276 `s', `f', and `hdc' (in W32) */
23277
23278 #ifdef HAVE_NTGUI
23279 /* On W32, silently add local `hdc' variable to argument list of
23280 init_glyph_string. */
23281 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
23282 init_glyph_string (s, hdc, char2b, w, row, area, start, hl)
23283 #else
23284 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
23285 init_glyph_string (s, char2b, w, row, area, start, hl)
23286 #endif
23287
23288 /* Add a glyph string for a stretch glyph to the list of strings
23289 between HEAD and TAIL. START is the index of the stretch glyph in
23290 row area AREA of glyph row ROW. END is the index of the last glyph
23291 in that glyph row area. X is the current output position assigned
23292 to the new glyph string constructed. HL overrides that face of the
23293 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
23294 is the right-most x-position of the drawing area. */
23295
23296 /* SunOS 4 bundled cc, barfed on continuations in the arg lists here
23297 and below -- keep them on one line. */
23298 #define BUILD_STRETCH_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
23299 do \
23300 { \
23301 s = alloca (sizeof *s); \
23302 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
23303 START = fill_stretch_glyph_string (s, START, END); \
23304 append_glyph_string (&HEAD, &TAIL, s); \
23305 s->x = (X); \
23306 } \
23307 while (0)
23308
23309
23310 /* Add a glyph string for an image glyph to the list of strings
23311 between HEAD and TAIL. START is the index of the image glyph in
23312 row area AREA of glyph row ROW. END is the index of the last glyph
23313 in that glyph row area. X is the current output position assigned
23314 to the new glyph string constructed. HL overrides that face of the
23315 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
23316 is the right-most x-position of the drawing area. */
23317
23318 #define BUILD_IMAGE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
23319 do \
23320 { \
23321 s = alloca (sizeof *s); \
23322 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
23323 fill_image_glyph_string (s); \
23324 append_glyph_string (&HEAD, &TAIL, s); \
23325 ++START; \
23326 s->x = (X); \
23327 } \
23328 while (0)
23329
23330 #ifdef HAVE_XWIDGETS
23331 #define BUILD_XWIDGET_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
23332 do \
23333 { \
23334 printf("BUILD_XWIDGET_GLYPH_STRING\n"); \
23335 s = (struct glyph_string *) alloca (sizeof *s); \
23336 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
23337 fill_xwidget_glyph_string (s); \
23338 append_glyph_string (&HEAD, &TAIL, s); \
23339 ++START; \
23340 s->x = (X); \
23341 } \
23342 while (0)
23343 #endif
23344
23345
23346 /* Add a glyph string for a sequence of character glyphs to the list
23347 of strings between HEAD and TAIL. START is the index of the first
23348 glyph in row area AREA of glyph row ROW that is part of the new
23349 glyph string. END is the index of the last glyph in that glyph row
23350 area. X is the current output position assigned to the new glyph
23351 string constructed. HL overrides that face of the glyph; e.g. it
23352 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
23353 right-most x-position of the drawing area. */
23354
23355 #define BUILD_CHAR_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
23356 do \
23357 { \
23358 int face_id; \
23359 XChar2b *char2b; \
23360 \
23361 face_id = (row)->glyphs[area][START].face_id; \
23362 \
23363 s = alloca (sizeof *s); \
23364 char2b = alloca ((END - START) * sizeof *char2b); \
23365 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
23366 append_glyph_string (&HEAD, &TAIL, s); \
23367 s->x = (X); \
23368 START = fill_glyph_string (s, face_id, START, END, overlaps); \
23369 } \
23370 while (0)
23371
23372
23373 /* Add a glyph string for a composite sequence to the list of strings
23374 between HEAD and TAIL. START is the index of the first glyph in
23375 row area AREA of glyph row ROW that is part of the new glyph
23376 string. END is the index of the last glyph in that glyph row area.
23377 X is the current output position assigned to the new glyph string
23378 constructed. HL overrides that face of the glyph; e.g. it is
23379 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
23380 x-position of the drawing area. */
23381
23382 #define BUILD_COMPOSITE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
23383 do { \
23384 int face_id = (row)->glyphs[area][START].face_id; \
23385 struct face *base_face = FACE_FROM_ID (f, face_id); \
23386 ptrdiff_t cmp_id = (row)->glyphs[area][START].u.cmp.id; \
23387 struct composition *cmp = composition_table[cmp_id]; \
23388 XChar2b *char2b; \
23389 struct glyph_string *first_s = NULL; \
23390 int n; \
23391 \
23392 char2b = alloca (cmp->glyph_len * sizeof *char2b); \
23393 \
23394 /* Make glyph_strings for each glyph sequence that is drawable by \
23395 the same face, and append them to HEAD/TAIL. */ \
23396 for (n = 0; n < cmp->glyph_len;) \
23397 { \
23398 s = alloca (sizeof *s); \
23399 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
23400 append_glyph_string (&(HEAD), &(TAIL), s); \
23401 s->cmp = cmp; \
23402 s->cmp_from = n; \
23403 s->x = (X); \
23404 if (n == 0) \
23405 first_s = s; \
23406 n = fill_composite_glyph_string (s, base_face, overlaps); \
23407 } \
23408 \
23409 ++START; \
23410 s = first_s; \
23411 } while (0)
23412
23413
23414 /* Add a glyph string for a glyph-string sequence to the list of strings
23415 between HEAD and TAIL. */
23416
23417 #define BUILD_GSTRING_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
23418 do { \
23419 int face_id; \
23420 XChar2b *char2b; \
23421 Lisp_Object gstring; \
23422 \
23423 face_id = (row)->glyphs[area][START].face_id; \
23424 gstring = (composition_gstring_from_id \
23425 ((row)->glyphs[area][START].u.cmp.id)); \
23426 s = alloca (sizeof *s); \
23427 char2b = alloca (LGSTRING_GLYPH_LEN (gstring) * sizeof *char2b); \
23428 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
23429 append_glyph_string (&(HEAD), &(TAIL), s); \
23430 s->x = (X); \
23431 START = fill_gstring_glyph_string (s, face_id, START, END, overlaps); \
23432 } while (0)
23433
23434
23435 /* Add a glyph string for a sequence of glyphless character's glyphs
23436 to the list of strings between HEAD and TAIL. The meanings of
23437 arguments are the same as those of BUILD_CHAR_GLYPH_STRINGS. */
23438
23439 #define BUILD_GLYPHLESS_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
23440 do \
23441 { \
23442 int face_id; \
23443 \
23444 face_id = (row)->glyphs[area][START].face_id; \
23445 \
23446 s = alloca (sizeof *s); \
23447 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
23448 append_glyph_string (&HEAD, &TAIL, s); \
23449 s->x = (X); \
23450 START = fill_glyphless_glyph_string (s, face_id, START, END, \
23451 overlaps); \
23452 } \
23453 while (0)
23454
23455
23456 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
23457 of AREA of glyph row ROW on window W between indices START and END.
23458 HL overrides the face for drawing glyph strings, e.g. it is
23459 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
23460 x-positions of the drawing area.
23461
23462 This is an ugly monster macro construct because we must use alloca
23463 to allocate glyph strings (because draw_glyphs can be called
23464 asynchronously). */
23465
23466 #define BUILD_GLYPH_STRINGS_1(START, END, HEAD, TAIL, HL, X, LAST_X) \
23467 do \
23468 { \
23469 HEAD = TAIL = NULL; \
23470 while (START < END) \
23471 { \
23472 struct glyph *first_glyph = (row)->glyphs[area] + START; \
23473 switch (first_glyph->type) \
23474 { \
23475 case CHAR_GLYPH: \
23476 BUILD_CHAR_GLYPH_STRINGS (START, END, HEAD, TAIL, \
23477 HL, X, LAST_X); \
23478 break; \
23479 \
23480 case COMPOSITE_GLYPH: \
23481 if (first_glyph->u.cmp.automatic) \
23482 BUILD_GSTRING_GLYPH_STRING (START, END, HEAD, TAIL, \
23483 HL, X, LAST_X); \
23484 else \
23485 BUILD_COMPOSITE_GLYPH_STRING (START, END, HEAD, TAIL, \
23486 HL, X, LAST_X); \
23487 break; \
23488 \
23489 case STRETCH_GLYPH: \
23490 BUILD_STRETCH_GLYPH_STRING (START, END, HEAD, TAIL, \
23491 HL, X, LAST_X); \
23492 break; \
23493 \
23494 case IMAGE_GLYPH: \
23495 BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL, \
23496 HL, X, LAST_X); \
23497 break;
23498
23499 #define BUILD_GLYPH_STRINGS_XW(START, END, HEAD, TAIL, HL, X, LAST_X) \
23500 case XWIDGET_GLYPH: \
23501 BUILD_XWIDGET_GLYPH_STRING (START, END, HEAD, TAIL, \
23502 HL, X, LAST_X); \
23503 break;
23504
23505 #define BUILD_GLYPH_STRINGS_2(START, END, HEAD, TAIL, HL, X, LAST_X) \
23506 case GLYPHLESS_GLYPH: \
23507 BUILD_GLYPHLESS_GLYPH_STRING (START, END, HEAD, TAIL, \
23508 HL, X, LAST_X); \
23509 break; \
23510 \
23511 default: \
23512 emacs_abort (); \
23513 } \
23514 \
23515 if (s) \
23516 { \
23517 set_glyph_string_background_width (s, START, LAST_X); \
23518 (X) += s->width; \
23519 } \
23520 } \
23521 } while (0)
23522
23523
23524 #ifdef HAVE_XWIDGETS
23525 #define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
23526 BUILD_GLYPH_STRINGS_1(START, END, HEAD, TAIL, HL, X, LAST_X) \
23527 BUILD_GLYPH_STRINGS_XW(START, END, HEAD, TAIL, HL, X, LAST_X) \
23528 BUILD_GLYPH_STRINGS_2(START, END, HEAD, TAIL, HL, X, LAST_X)
23529 #else
23530 #define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
23531 BUILD_GLYPH_STRINGS_1(START, END, HEAD, TAIL, HL, X, LAST_X) \
23532 BUILD_GLYPH_STRINGS_2(START, END, HEAD, TAIL, HL, X, LAST_X)
23533 #endif
23534
23535
23536 /* Draw glyphs between START and END in AREA of ROW on window W,
23537 starting at x-position X. X is relative to AREA in W. HL is a
23538 face-override with the following meaning:
23539
23540 DRAW_NORMAL_TEXT draw normally
23541 DRAW_CURSOR draw in cursor face
23542 DRAW_MOUSE_FACE draw in mouse face.
23543 DRAW_INVERSE_VIDEO draw in mode line face
23544 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
23545 DRAW_IMAGE_RAISED draw an image with a raised relief around it
23546
23547 If OVERLAPS is non-zero, draw only the foreground of characters and
23548 clip to the physical height of ROW. Non-zero value also defines
23549 the overlapping part to be drawn:
23550
23551 OVERLAPS_PRED overlap with preceding rows
23552 OVERLAPS_SUCC overlap with succeeding rows
23553 OVERLAPS_BOTH overlap with both preceding/succeeding rows
23554 OVERLAPS_ERASED_CURSOR overlap with erased cursor area
23555
23556 Value is the x-position reached, relative to AREA of W. */
23557
23558 static int
23559 draw_glyphs (struct window *w, int x, struct glyph_row *row,
23560 enum glyph_row_area area, ptrdiff_t start, ptrdiff_t end,
23561 enum draw_glyphs_face hl, int overlaps)
23562 {
23563 struct glyph_string *head, *tail;
23564 struct glyph_string *s;
23565 struct glyph_string *clip_head = NULL, *clip_tail = NULL;
23566 int i, j, x_reached, last_x, area_left = 0;
23567 struct frame *f = XFRAME (WINDOW_FRAME (w));
23568 DECLARE_HDC (hdc);
23569
23570 ALLOCATE_HDC (hdc, f);
23571
23572 /* Let's rather be paranoid than getting a SEGV. */
23573 end = min (end, row->used[area]);
23574 start = max (0, start);
23575 start = min (end, start);
23576
23577 /* Translate X to frame coordinates. Set last_x to the right
23578 end of the drawing area. */
23579 if (row->full_width_p)
23580 {
23581 /* X is relative to the left edge of W, without scroll bars
23582 or fringes. */
23583 area_left = WINDOW_LEFT_EDGE_X (w);
23584 last_x = WINDOW_LEFT_EDGE_X (w) + WINDOW_TOTAL_WIDTH (w);
23585 }
23586 else
23587 {
23588 area_left = window_box_left (w, area);
23589 last_x = area_left + window_box_width (w, area);
23590 }
23591 x += area_left;
23592
23593 /* Build a doubly-linked list of glyph_string structures between
23594 head and tail from what we have to draw. Note that the macro
23595 BUILD_GLYPH_STRINGS will modify its start parameter. That's
23596 the reason we use a separate variable `i'. */
23597 i = start;
23598 BUILD_GLYPH_STRINGS (i, end, head, tail, hl, x, last_x);
23599 if (tail)
23600 x_reached = tail->x + tail->background_width;
23601 else
23602 x_reached = x;
23603
23604 /* If there are any glyphs with lbearing < 0 or rbearing > width in
23605 the row, redraw some glyphs in front or following the glyph
23606 strings built above. */
23607 if (head && !overlaps && row->contains_overlapping_glyphs_p)
23608 {
23609 struct glyph_string *h, *t;
23610 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
23611 int mouse_beg_col IF_LINT (= 0), mouse_end_col IF_LINT (= 0);
23612 int check_mouse_face = 0;
23613 int dummy_x = 0;
23614
23615 /* If mouse highlighting is on, we may need to draw adjacent
23616 glyphs using mouse-face highlighting. */
23617 if (area == TEXT_AREA && row->mouse_face_p)
23618 {
23619 struct glyph_row *mouse_beg_row, *mouse_end_row;
23620
23621 mouse_beg_row = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_beg_row);
23622 mouse_end_row = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_end_row);
23623
23624 if (row >= mouse_beg_row && row <= mouse_end_row)
23625 {
23626 check_mouse_face = 1;
23627 mouse_beg_col = (row == mouse_beg_row)
23628 ? hlinfo->mouse_face_beg_col : 0;
23629 mouse_end_col = (row == mouse_end_row)
23630 ? hlinfo->mouse_face_end_col
23631 : row->used[TEXT_AREA];
23632 }
23633 }
23634
23635 /* Compute overhangs for all glyph strings. */
23636 if (FRAME_RIF (f)->compute_glyph_string_overhangs)
23637 for (s = head; s; s = s->next)
23638 FRAME_RIF (f)->compute_glyph_string_overhangs (s);
23639
23640 /* Prepend glyph strings for glyphs in front of the first glyph
23641 string that are overwritten because of the first glyph
23642 string's left overhang. The background of all strings
23643 prepended must be drawn because the first glyph string
23644 draws over it. */
23645 i = left_overwritten (head);
23646 if (i >= 0)
23647 {
23648 enum draw_glyphs_face overlap_hl;
23649
23650 /* If this row contains mouse highlighting, attempt to draw
23651 the overlapped glyphs with the correct highlight. This
23652 code fails if the overlap encompasses more than one glyph
23653 and mouse-highlight spans only some of these glyphs.
23654 However, making it work perfectly involves a lot more
23655 code, and I don't know if the pathological case occurs in
23656 practice, so we'll stick to this for now. --- cyd */
23657 if (check_mouse_face
23658 && mouse_beg_col < start && mouse_end_col > i)
23659 overlap_hl = DRAW_MOUSE_FACE;
23660 else
23661 overlap_hl = DRAW_NORMAL_TEXT;
23662
23663 j = i;
23664 BUILD_GLYPH_STRINGS (j, start, h, t,
23665 overlap_hl, dummy_x, last_x);
23666 start = i;
23667 compute_overhangs_and_x (t, head->x, 1);
23668 prepend_glyph_string_lists (&head, &tail, h, t);
23669 clip_head = head;
23670 }
23671
23672 /* Prepend glyph strings for glyphs in front of the first glyph
23673 string that overwrite that glyph string because of their
23674 right overhang. For these strings, only the foreground must
23675 be drawn, because it draws over the glyph string at `head'.
23676 The background must not be drawn because this would overwrite
23677 right overhangs of preceding glyphs for which no glyph
23678 strings exist. */
23679 i = left_overwriting (head);
23680 if (i >= 0)
23681 {
23682 enum draw_glyphs_face overlap_hl;
23683
23684 if (check_mouse_face
23685 && mouse_beg_col < start && mouse_end_col > i)
23686 overlap_hl = DRAW_MOUSE_FACE;
23687 else
23688 overlap_hl = DRAW_NORMAL_TEXT;
23689
23690 clip_head = head;
23691 BUILD_GLYPH_STRINGS (i, start, h, t,
23692 overlap_hl, dummy_x, last_x);
23693 for (s = h; s; s = s->next)
23694 s->background_filled_p = 1;
23695 compute_overhangs_and_x (t, head->x, 1);
23696 prepend_glyph_string_lists (&head, &tail, h, t);
23697 }
23698
23699 /* Append glyphs strings for glyphs following the last glyph
23700 string tail that are overwritten by tail. The background of
23701 these strings has to be drawn because tail's foreground draws
23702 over it. */
23703 i = right_overwritten (tail);
23704 if (i >= 0)
23705 {
23706 enum draw_glyphs_face overlap_hl;
23707
23708 if (check_mouse_face
23709 && mouse_beg_col < i && mouse_end_col > end)
23710 overlap_hl = DRAW_MOUSE_FACE;
23711 else
23712 overlap_hl = DRAW_NORMAL_TEXT;
23713
23714 BUILD_GLYPH_STRINGS (end, i, h, t,
23715 overlap_hl, x, last_x);
23716 /* Because BUILD_GLYPH_STRINGS updates the first argument,
23717 we don't have `end = i;' here. */
23718 compute_overhangs_and_x (h, tail->x + tail->width, 0);
23719 append_glyph_string_lists (&head, &tail, h, t);
23720 clip_tail = tail;
23721 }
23722
23723 /* Append glyph strings for glyphs following the last glyph
23724 string tail that overwrite tail. The foreground of such
23725 glyphs has to be drawn because it writes into the background
23726 of tail. The background must not be drawn because it could
23727 paint over the foreground of following glyphs. */
23728 i = right_overwriting (tail);
23729 if (i >= 0)
23730 {
23731 enum draw_glyphs_face overlap_hl;
23732 if (check_mouse_face
23733 && mouse_beg_col < i && mouse_end_col > end)
23734 overlap_hl = DRAW_MOUSE_FACE;
23735 else
23736 overlap_hl = DRAW_NORMAL_TEXT;
23737
23738 clip_tail = tail;
23739 i++; /* We must include the Ith glyph. */
23740 BUILD_GLYPH_STRINGS (end, i, h, t,
23741 overlap_hl, x, last_x);
23742 for (s = h; s; s = s->next)
23743 s->background_filled_p = 1;
23744 compute_overhangs_and_x (h, tail->x + tail->width, 0);
23745 append_glyph_string_lists (&head, &tail, h, t);
23746 }
23747 if (clip_head || clip_tail)
23748 for (s = head; s; s = s->next)
23749 {
23750 s->clip_head = clip_head;
23751 s->clip_tail = clip_tail;
23752 }
23753 }
23754
23755 /* Draw all strings. */
23756 for (s = head; s; s = s->next)
23757 FRAME_RIF (f)->draw_glyph_string (s);
23758
23759 #ifndef HAVE_NS
23760 /* When focus a sole frame and move horizontally, this sets on_p to 0
23761 causing a failure to erase prev cursor position. */
23762 if (area == TEXT_AREA
23763 && !row->full_width_p
23764 /* When drawing overlapping rows, only the glyph strings'
23765 foreground is drawn, which doesn't erase a cursor
23766 completely. */
23767 && !overlaps)
23768 {
23769 int x0 = clip_head ? clip_head->x : (head ? head->x : x);
23770 int x1 = (clip_tail ? clip_tail->x + clip_tail->background_width
23771 : (tail ? tail->x + tail->background_width : x));
23772 x0 -= area_left;
23773 x1 -= area_left;
23774
23775 notice_overwritten_cursor (w, TEXT_AREA, x0, x1,
23776 row->y, MATRIX_ROW_BOTTOM_Y (row));
23777 }
23778 #endif
23779
23780 /* Value is the x-position up to which drawn, relative to AREA of W.
23781 This doesn't include parts drawn because of overhangs. */
23782 if (row->full_width_p)
23783 x_reached = FRAME_TO_WINDOW_PIXEL_X (w, x_reached);
23784 else
23785 x_reached -= area_left;
23786
23787 RELEASE_HDC (hdc, f);
23788
23789 return x_reached;
23790 }
23791
23792 /* Expand row matrix if too narrow. Don't expand if area
23793 is not present. */
23794
23795 #define IT_EXPAND_MATRIX_WIDTH(it, area) \
23796 { \
23797 if (!fonts_changed_p \
23798 && (it->glyph_row->glyphs[area] \
23799 < it->glyph_row->glyphs[area + 1])) \
23800 { \
23801 it->w->ncols_scale_factor++; \
23802 fonts_changed_p = 1; \
23803 } \
23804 }
23805
23806 /* Store one glyph for IT->char_to_display in IT->glyph_row.
23807 Called from x_produce_glyphs when IT->glyph_row is non-null. */
23808
23809 static inline void
23810 append_glyph (struct it *it)
23811 {
23812 struct glyph *glyph;
23813 enum glyph_row_area area = it->area;
23814
23815 eassert (it->glyph_row);
23816 eassert (it->char_to_display != '\n' && it->char_to_display != '\t');
23817
23818 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
23819 if (glyph < it->glyph_row->glyphs[area + 1])
23820 {
23821 /* If the glyph row is reversed, we need to prepend the glyph
23822 rather than append it. */
23823 if (it->glyph_row->reversed_p && area == TEXT_AREA)
23824 {
23825 struct glyph *g;
23826
23827 /* Make room for the additional glyph. */
23828 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
23829 g[1] = *g;
23830 glyph = it->glyph_row->glyphs[area];
23831 }
23832 glyph->charpos = CHARPOS (it->position);
23833 glyph->object = it->object;
23834 if (it->pixel_width > 0)
23835 {
23836 glyph->pixel_width = it->pixel_width;
23837 glyph->padding_p = 0;
23838 }
23839 else
23840 {
23841 /* Assure at least 1-pixel width. Otherwise, cursor can't
23842 be displayed correctly. */
23843 glyph->pixel_width = 1;
23844 glyph->padding_p = 1;
23845 }
23846 glyph->ascent = it->ascent;
23847 glyph->descent = it->descent;
23848 glyph->voffset = it->voffset;
23849 glyph->type = CHAR_GLYPH;
23850 glyph->avoid_cursor_p = it->avoid_cursor_p;
23851 glyph->multibyte_p = it->multibyte_p;
23852 glyph->left_box_line_p = it->start_of_box_run_p;
23853 glyph->right_box_line_p = it->end_of_box_run_p;
23854 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
23855 || it->phys_descent > it->descent);
23856 glyph->glyph_not_available_p = it->glyph_not_available_p;
23857 glyph->face_id = it->face_id;
23858 glyph->u.ch = it->char_to_display;
23859 glyph->slice.img = null_glyph_slice;
23860 glyph->font_type = FONT_TYPE_UNKNOWN;
23861 if (it->bidi_p)
23862 {
23863 glyph->resolved_level = it->bidi_it.resolved_level;
23864 if ((it->bidi_it.type & 7) != it->bidi_it.type)
23865 emacs_abort ();
23866 glyph->bidi_type = it->bidi_it.type;
23867 }
23868 else
23869 {
23870 glyph->resolved_level = 0;
23871 glyph->bidi_type = UNKNOWN_BT;
23872 }
23873 ++it->glyph_row->used[area];
23874 }
23875 else
23876 IT_EXPAND_MATRIX_WIDTH (it, area);
23877 }
23878
23879 /* Store one glyph for the composition IT->cmp_it.id in
23880 IT->glyph_row. Called from x_produce_glyphs when IT->glyph_row is
23881 non-null. */
23882
23883 static inline void
23884 append_composite_glyph (struct it *it)
23885 {
23886 struct glyph *glyph;
23887 enum glyph_row_area area = it->area;
23888
23889 eassert (it->glyph_row);
23890
23891 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
23892 if (glyph < it->glyph_row->glyphs[area + 1])
23893 {
23894 /* If the glyph row is reversed, we need to prepend the glyph
23895 rather than append it. */
23896 if (it->glyph_row->reversed_p && it->area == TEXT_AREA)
23897 {
23898 struct glyph *g;
23899
23900 /* Make room for the new glyph. */
23901 for (g = glyph - 1; g >= it->glyph_row->glyphs[it->area]; g--)
23902 g[1] = *g;
23903 glyph = it->glyph_row->glyphs[it->area];
23904 }
23905 glyph->charpos = it->cmp_it.charpos;
23906 glyph->object = it->object;
23907 glyph->pixel_width = it->pixel_width;
23908 glyph->ascent = it->ascent;
23909 glyph->descent = it->descent;
23910 glyph->voffset = it->voffset;
23911 glyph->type = COMPOSITE_GLYPH;
23912 if (it->cmp_it.ch < 0)
23913 {
23914 glyph->u.cmp.automatic = 0;
23915 glyph->u.cmp.id = it->cmp_it.id;
23916 glyph->slice.cmp.from = glyph->slice.cmp.to = 0;
23917 }
23918 else
23919 {
23920 glyph->u.cmp.automatic = 1;
23921 glyph->u.cmp.id = it->cmp_it.id;
23922 glyph->slice.cmp.from = it->cmp_it.from;
23923 glyph->slice.cmp.to = it->cmp_it.to - 1;
23924 }
23925 glyph->avoid_cursor_p = it->avoid_cursor_p;
23926 glyph->multibyte_p = it->multibyte_p;
23927 glyph->left_box_line_p = it->start_of_box_run_p;
23928 glyph->right_box_line_p = it->end_of_box_run_p;
23929 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
23930 || it->phys_descent > it->descent);
23931 glyph->padding_p = 0;
23932 glyph->glyph_not_available_p = 0;
23933 glyph->face_id = it->face_id;
23934 glyph->font_type = FONT_TYPE_UNKNOWN;
23935 if (it->bidi_p)
23936 {
23937 glyph->resolved_level = it->bidi_it.resolved_level;
23938 if ((it->bidi_it.type & 7) != it->bidi_it.type)
23939 emacs_abort ();
23940 glyph->bidi_type = it->bidi_it.type;
23941 }
23942 ++it->glyph_row->used[area];
23943 }
23944 else
23945 IT_EXPAND_MATRIX_WIDTH (it, area);
23946 }
23947
23948
23949 /* Change IT->ascent and IT->height according to the setting of
23950 IT->voffset. */
23951
23952 static inline void
23953 take_vertical_position_into_account (struct it *it)
23954 {
23955 if (it->voffset)
23956 {
23957 if (it->voffset < 0)
23958 /* Increase the ascent so that we can display the text higher
23959 in the line. */
23960 it->ascent -= it->voffset;
23961 else
23962 /* Increase the descent so that we can display the text lower
23963 in the line. */
23964 it->descent += it->voffset;
23965 }
23966 }
23967
23968
23969 /* Produce glyphs/get display metrics for the image IT is loaded with.
23970 See the description of struct display_iterator in dispextern.h for
23971 an overview of struct display_iterator. */
23972
23973 static void
23974 produce_image_glyph (struct it *it)
23975 {
23976 struct image *img;
23977 struct face *face;
23978 int glyph_ascent, crop;
23979 struct glyph_slice slice;
23980
23981 eassert (it->what == IT_IMAGE);
23982
23983 face = FACE_FROM_ID (it->f, it->face_id);
23984 eassert (face);
23985 /* Make sure X resources of the face is loaded. */
23986 PREPARE_FACE_FOR_DISPLAY (it->f, face);
23987
23988 if (it->image_id < 0)
23989 {
23990 /* Fringe bitmap. */
23991 it->ascent = it->phys_ascent = 0;
23992 it->descent = it->phys_descent = 0;
23993 it->pixel_width = 0;
23994 it->nglyphs = 0;
23995 return;
23996 }
23997
23998 img = IMAGE_FROM_ID (it->f, it->image_id);
23999 eassert (img);
24000 /* Make sure X resources of the image is loaded. */
24001 prepare_image_for_display (it->f, img);
24002
24003 slice.x = slice.y = 0;
24004 slice.width = img->width;
24005 slice.height = img->height;
24006
24007 if (INTEGERP (it->slice.x))
24008 slice.x = XINT (it->slice.x);
24009 else if (FLOATP (it->slice.x))
24010 slice.x = XFLOAT_DATA (it->slice.x) * img->width;
24011
24012 if (INTEGERP (it->slice.y))
24013 slice.y = XINT (it->slice.y);
24014 else if (FLOATP (it->slice.y))
24015 slice.y = XFLOAT_DATA (it->slice.y) * img->height;
24016
24017 if (INTEGERP (it->slice.width))
24018 slice.width = XINT (it->slice.width);
24019 else if (FLOATP (it->slice.width))
24020 slice.width = XFLOAT_DATA (it->slice.width) * img->width;
24021
24022 if (INTEGERP (it->slice.height))
24023 slice.height = XINT (it->slice.height);
24024 else if (FLOATP (it->slice.height))
24025 slice.height = XFLOAT_DATA (it->slice.height) * img->height;
24026
24027 if (slice.x >= img->width)
24028 slice.x = img->width;
24029 if (slice.y >= img->height)
24030 slice.y = img->height;
24031 if (slice.x + slice.width >= img->width)
24032 slice.width = img->width - slice.x;
24033 if (slice.y + slice.height > img->height)
24034 slice.height = img->height - slice.y;
24035
24036 if (slice.width == 0 || slice.height == 0)
24037 return;
24038
24039 it->ascent = it->phys_ascent = glyph_ascent = image_ascent (img, face, &slice);
24040
24041 it->descent = slice.height - glyph_ascent;
24042 if (slice.y == 0)
24043 it->descent += img->vmargin;
24044 if (slice.y + slice.height == img->height)
24045 it->descent += img->vmargin;
24046 it->phys_descent = it->descent;
24047
24048 it->pixel_width = slice.width;
24049 if (slice.x == 0)
24050 it->pixel_width += img->hmargin;
24051 if (slice.x + slice.width == img->width)
24052 it->pixel_width += img->hmargin;
24053
24054 /* It's quite possible for images to have an ascent greater than
24055 their height, so don't get confused in that case. */
24056 if (it->descent < 0)
24057 it->descent = 0;
24058
24059 it->nglyphs = 1;
24060
24061 if (face->box != FACE_NO_BOX)
24062 {
24063 if (face->box_line_width > 0)
24064 {
24065 if (slice.y == 0)
24066 it->ascent += face->box_line_width;
24067 if (slice.y + slice.height == img->height)
24068 it->descent += face->box_line_width;
24069 }
24070
24071 if (it->start_of_box_run_p && slice.x == 0)
24072 it->pixel_width += eabs (face->box_line_width);
24073 if (it->end_of_box_run_p && slice.x + slice.width == img->width)
24074 it->pixel_width += eabs (face->box_line_width);
24075 }
24076
24077 take_vertical_position_into_account (it);
24078
24079 /* Automatically crop wide image glyphs at right edge so we can
24080 draw the cursor on same display row. */
24081 if ((crop = it->pixel_width - (it->last_visible_x - it->current_x), crop > 0)
24082 && (it->hpos == 0 || it->pixel_width > it->last_visible_x / 4))
24083 {
24084 it->pixel_width -= crop;
24085 slice.width -= crop;
24086 }
24087
24088 if (it->glyph_row)
24089 {
24090 struct glyph *glyph;
24091 enum glyph_row_area area = it->area;
24092
24093 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
24094 if (glyph < it->glyph_row->glyphs[area + 1])
24095 {
24096 glyph->charpos = CHARPOS (it->position);
24097 glyph->object = it->object;
24098 glyph->pixel_width = it->pixel_width;
24099 glyph->ascent = glyph_ascent;
24100 glyph->descent = it->descent;
24101 glyph->voffset = it->voffset;
24102 glyph->type = IMAGE_GLYPH;
24103 glyph->avoid_cursor_p = it->avoid_cursor_p;
24104 glyph->multibyte_p = it->multibyte_p;
24105 glyph->left_box_line_p = it->start_of_box_run_p;
24106 glyph->right_box_line_p = it->end_of_box_run_p;
24107 glyph->overlaps_vertically_p = 0;
24108 glyph->padding_p = 0;
24109 glyph->glyph_not_available_p = 0;
24110 glyph->face_id = it->face_id;
24111 glyph->u.img_id = img->id;
24112 glyph->slice.img = slice;
24113 glyph->font_type = FONT_TYPE_UNKNOWN;
24114 if (it->bidi_p)
24115 {
24116 glyph->resolved_level = it->bidi_it.resolved_level;
24117 if ((it->bidi_it.type & 7) != it->bidi_it.type)
24118 emacs_abort ();
24119 glyph->bidi_type = it->bidi_it.type;
24120 }
24121 ++it->glyph_row->used[area];
24122 }
24123 else
24124 IT_EXPAND_MATRIX_WIDTH (it, area);
24125 }
24126 }
24127
24128 #ifdef HAVE_XWIDGETS
24129 static void
24130 produce_xwidget_glyph (struct it *it)
24131 {
24132 struct xwidget* xw;
24133 struct face *face;
24134 int glyph_ascent, crop;
24135 printf("produce_xwidget_glyph:\n");
24136 eassert (it->what == IT_XWIDGET);
24137
24138 face = FACE_FROM_ID (it->f, it->face_id);
24139 eassert (face);
24140 /* Make sure X resources of the face is loaded. */
24141 PREPARE_FACE_FOR_DISPLAY (it->f, face);
24142
24143 xw = it->xwidget;
24144 it->ascent = it->phys_ascent = glyph_ascent = xw->height/2;
24145 it->descent = xw->height/2;
24146 it->phys_descent = it->descent;
24147 it->pixel_width = xw->width;
24148 /* It's quite possible for images to have an ascent greater than
24149 their height, so don't get confused in that case. */
24150 if (it->descent < 0)
24151 it->descent = 0;
24152
24153 it->nglyphs = 1;
24154
24155 if (face->box != FACE_NO_BOX)
24156 {
24157 if (face->box_line_width > 0)
24158 {
24159 it->ascent += face->box_line_width;
24160 it->descent += face->box_line_width;
24161 }
24162
24163 if (it->start_of_box_run_p)
24164 it->pixel_width += eabs (face->box_line_width);
24165 it->pixel_width += eabs (face->box_line_width);
24166 }
24167
24168 take_vertical_position_into_account (it);
24169
24170 /* Automatically crop wide image glyphs at right edge so we can
24171 draw the cursor on same display row. */
24172 if ((crop = it->pixel_width - (it->last_visible_x - it->current_x), crop > 0)
24173 && (it->hpos == 0 || it->pixel_width > it->last_visible_x / 4))
24174 {
24175 it->pixel_width -= crop;
24176 }
24177
24178 if (it->glyph_row)
24179 {
24180 struct glyph *glyph;
24181 enum glyph_row_area area = it->area;
24182
24183 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
24184 if (glyph < it->glyph_row->glyphs[area + 1])
24185 {
24186 glyph->charpos = CHARPOS (it->position);
24187 glyph->object = it->object;
24188 glyph->pixel_width = it->pixel_width;
24189 glyph->ascent = glyph_ascent;
24190 glyph->descent = it->descent;
24191 glyph->voffset = it->voffset;
24192 glyph->type = XWIDGET_GLYPH;
24193
24194 glyph->multibyte_p = it->multibyte_p;
24195 glyph->left_box_line_p = it->start_of_box_run_p;
24196 glyph->right_box_line_p = it->end_of_box_run_p;
24197 glyph->overlaps_vertically_p = 0;
24198 glyph->padding_p = 0;
24199 glyph->glyph_not_available_p = 0;
24200 glyph->face_id = it->face_id;
24201 glyph->u.xwidget = it->xwidget;
24202 //assert_valid_xwidget_id(glyph->u.xwidget_id,"produce_xwidget_glyph");
24203 glyph->font_type = FONT_TYPE_UNKNOWN;
24204 ++it->glyph_row->used[area];
24205 }
24206 else
24207 IT_EXPAND_MATRIX_WIDTH (it, area);
24208 }
24209 }
24210 #endif
24211
24212 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
24213 of the glyph, WIDTH and HEIGHT are the width and height of the
24214 stretch. ASCENT is the ascent of the glyph (0 <= ASCENT <= HEIGHT). */
24215
24216 static void
24217 append_stretch_glyph (struct it *it, Lisp_Object object,
24218 int width, int height, int ascent)
24219 {
24220 struct glyph *glyph;
24221 enum glyph_row_area area = it->area;
24222
24223 eassert (ascent >= 0 && ascent <= height);
24224
24225 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
24226 if (glyph < it->glyph_row->glyphs[area + 1])
24227 {
24228 /* If the glyph row is reversed, we need to prepend the glyph
24229 rather than append it. */
24230 if (it->glyph_row->reversed_p && area == TEXT_AREA)
24231 {
24232 struct glyph *g;
24233
24234 /* Make room for the additional glyph. */
24235 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
24236 g[1] = *g;
24237 glyph = it->glyph_row->glyphs[area];
24238 }
24239 glyph->charpos = CHARPOS (it->position);
24240 glyph->object = object;
24241 glyph->pixel_width = width;
24242 glyph->ascent = ascent;
24243 glyph->descent = height - ascent;
24244 glyph->voffset = it->voffset;
24245 glyph->type = STRETCH_GLYPH;
24246 glyph->avoid_cursor_p = it->avoid_cursor_p;
24247 glyph->multibyte_p = it->multibyte_p;
24248 glyph->left_box_line_p = it->start_of_box_run_p;
24249 glyph->right_box_line_p = it->end_of_box_run_p;
24250 glyph->overlaps_vertically_p = 0;
24251 glyph->padding_p = 0;
24252 glyph->glyph_not_available_p = 0;
24253 glyph->face_id = it->face_id;
24254 glyph->u.stretch.ascent = ascent;
24255 glyph->u.stretch.height = height;
24256 glyph->slice.img = null_glyph_slice;
24257 glyph->font_type = FONT_TYPE_UNKNOWN;
24258 if (it->bidi_p)
24259 {
24260 glyph->resolved_level = it->bidi_it.resolved_level;
24261 if ((it->bidi_it.type & 7) != it->bidi_it.type)
24262 emacs_abort ();
24263 glyph->bidi_type = it->bidi_it.type;
24264 }
24265 else
24266 {
24267 glyph->resolved_level = 0;
24268 glyph->bidi_type = UNKNOWN_BT;
24269 }
24270 ++it->glyph_row->used[area];
24271 }
24272 else
24273 IT_EXPAND_MATRIX_WIDTH (it, area);
24274 }
24275
24276 #endif /* HAVE_WINDOW_SYSTEM */
24277
24278 /* Produce a stretch glyph for iterator IT. IT->object is the value
24279 of the glyph property displayed. The value must be a list
24280 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
24281 being recognized:
24282
24283 1. `:width WIDTH' specifies that the space should be WIDTH *
24284 canonical char width wide. WIDTH may be an integer or floating
24285 point number.
24286
24287 2. `:relative-width FACTOR' specifies that the width of the stretch
24288 should be computed from the width of the first character having the
24289 `glyph' property, and should be FACTOR times that width.
24290
24291 3. `:align-to HPOS' specifies that the space should be wide enough
24292 to reach HPOS, a value in canonical character units.
24293
24294 Exactly one of the above pairs must be present.
24295
24296 4. `:height HEIGHT' specifies that the height of the stretch produced
24297 should be HEIGHT, measured in canonical character units.
24298
24299 5. `:relative-height FACTOR' specifies that the height of the
24300 stretch should be FACTOR times the height of the characters having
24301 the glyph property.
24302
24303 Either none or exactly one of 4 or 5 must be present.
24304
24305 6. `:ascent ASCENT' specifies that ASCENT percent of the height
24306 of the stretch should be used for the ascent of the stretch.
24307 ASCENT must be in the range 0 <= ASCENT <= 100. */
24308
24309 void
24310 produce_stretch_glyph (struct it *it)
24311 {
24312 /* (space :width WIDTH :height HEIGHT ...) */
24313 Lisp_Object prop, plist;
24314 int width = 0, height = 0, align_to = -1;
24315 int zero_width_ok_p = 0;
24316 int ascent = 0;
24317 double tem;
24318 struct face *face = NULL;
24319 struct font *font = NULL;
24320
24321 #ifdef HAVE_WINDOW_SYSTEM
24322 int zero_height_ok_p = 0;
24323
24324 if (FRAME_WINDOW_P (it->f))
24325 {
24326 face = FACE_FROM_ID (it->f, it->face_id);
24327 font = face->font ? face->font : FRAME_FONT (it->f);
24328 PREPARE_FACE_FOR_DISPLAY (it->f, face);
24329 }
24330 #endif
24331
24332 /* List should start with `space'. */
24333 eassert (CONSP (it->object) && EQ (XCAR (it->object), Qspace));
24334 plist = XCDR (it->object);
24335
24336 /* Compute the width of the stretch. */
24337 if ((prop = Fplist_get (plist, QCwidth), !NILP (prop))
24338 && calc_pixel_width_or_height (&tem, it, prop, font, 1, 0))
24339 {
24340 /* Absolute width `:width WIDTH' specified and valid. */
24341 zero_width_ok_p = 1;
24342 width = (int)tem;
24343 }
24344 #ifdef HAVE_WINDOW_SYSTEM
24345 else if (FRAME_WINDOW_P (it->f)
24346 && (prop = Fplist_get (plist, QCrelative_width), NUMVAL (prop) > 0))
24347 {
24348 /* Relative width `:relative-width FACTOR' specified and valid.
24349 Compute the width of the characters having the `glyph'
24350 property. */
24351 struct it it2;
24352 unsigned char *p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
24353
24354 it2 = *it;
24355 if (it->multibyte_p)
24356 it2.c = it2.char_to_display = STRING_CHAR_AND_LENGTH (p, it2.len);
24357 else
24358 {
24359 it2.c = it2.char_to_display = *p, it2.len = 1;
24360 if (! ASCII_CHAR_P (it2.c))
24361 it2.char_to_display = BYTE8_TO_CHAR (it2.c);
24362 }
24363
24364 it2.glyph_row = NULL;
24365 it2.what = IT_CHARACTER;
24366 x_produce_glyphs (&it2);
24367 width = NUMVAL (prop) * it2.pixel_width;
24368 }
24369 #endif /* HAVE_WINDOW_SYSTEM */
24370 else if ((prop = Fplist_get (plist, QCalign_to), !NILP (prop))
24371 && calc_pixel_width_or_height (&tem, it, prop, font, 1, &align_to))
24372 {
24373 if (it->glyph_row == NULL || !it->glyph_row->mode_line_p)
24374 align_to = (align_to < 0
24375 ? 0
24376 : align_to - window_box_left_offset (it->w, TEXT_AREA));
24377 else if (align_to < 0)
24378 align_to = window_box_left_offset (it->w, TEXT_AREA);
24379 width = max (0, (int)tem + align_to - it->current_x);
24380 zero_width_ok_p = 1;
24381 }
24382 else
24383 /* Nothing specified -> width defaults to canonical char width. */
24384 width = FRAME_COLUMN_WIDTH (it->f);
24385
24386 if (width <= 0 && (width < 0 || !zero_width_ok_p))
24387 width = 1;
24388
24389 #ifdef HAVE_WINDOW_SYSTEM
24390 /* Compute height. */
24391 if (FRAME_WINDOW_P (it->f))
24392 {
24393 if ((prop = Fplist_get (plist, QCheight), !NILP (prop))
24394 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
24395 {
24396 height = (int)tem;
24397 zero_height_ok_p = 1;
24398 }
24399 else if (prop = Fplist_get (plist, QCrelative_height),
24400 NUMVAL (prop) > 0)
24401 height = FONT_HEIGHT (font) * NUMVAL (prop);
24402 else
24403 height = FONT_HEIGHT (font);
24404
24405 if (height <= 0 && (height < 0 || !zero_height_ok_p))
24406 height = 1;
24407
24408 /* Compute percentage of height used for ascent. If
24409 `:ascent ASCENT' is present and valid, use that. Otherwise,
24410 derive the ascent from the font in use. */
24411 if (prop = Fplist_get (plist, QCascent),
24412 NUMVAL (prop) > 0 && NUMVAL (prop) <= 100)
24413 ascent = height * NUMVAL (prop) / 100.0;
24414 else if (!NILP (prop)
24415 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
24416 ascent = min (max (0, (int)tem), height);
24417 else
24418 ascent = (height * FONT_BASE (font)) / FONT_HEIGHT (font);
24419 }
24420 else
24421 #endif /* HAVE_WINDOW_SYSTEM */
24422 height = 1;
24423
24424 if (width > 0 && it->line_wrap != TRUNCATE
24425 && it->current_x + width > it->last_visible_x)
24426 {
24427 width = it->last_visible_x - it->current_x;
24428 #ifdef HAVE_WINDOW_SYSTEM
24429 /* Subtract one more pixel from the stretch width, but only on
24430 GUI frames, since on a TTY each glyph is one "pixel" wide. */
24431 width -= FRAME_WINDOW_P (it->f);
24432 #endif
24433 }
24434
24435 if (width > 0 && height > 0 && it->glyph_row)
24436 {
24437 Lisp_Object o_object = it->object;
24438 Lisp_Object object = it->stack[it->sp - 1].string;
24439 int n = width;
24440
24441 if (!STRINGP (object))
24442 object = it->w->buffer;
24443 #ifdef HAVE_WINDOW_SYSTEM
24444 if (FRAME_WINDOW_P (it->f))
24445 append_stretch_glyph (it, object, width, height, ascent);
24446 else
24447 #endif
24448 {
24449 it->object = object;
24450 it->char_to_display = ' ';
24451 it->pixel_width = it->len = 1;
24452 while (n--)
24453 tty_append_glyph (it);
24454 it->object = o_object;
24455 }
24456 }
24457
24458 it->pixel_width = width;
24459 #ifdef HAVE_WINDOW_SYSTEM
24460 if (FRAME_WINDOW_P (it->f))
24461 {
24462 it->ascent = it->phys_ascent = ascent;
24463 it->descent = it->phys_descent = height - it->ascent;
24464 it->nglyphs = width > 0 && height > 0 ? 1 : 0;
24465 take_vertical_position_into_account (it);
24466 }
24467 else
24468 #endif
24469 it->nglyphs = width;
24470 }
24471
24472 /* Get information about special display element WHAT in an
24473 environment described by IT. WHAT is one of IT_TRUNCATION or
24474 IT_CONTINUATION. Maybe produce glyphs for WHAT if IT has a
24475 non-null glyph_row member. This function ensures that fields like
24476 face_id, c, len of IT are left untouched. */
24477
24478 static void
24479 produce_special_glyphs (struct it *it, enum display_element_type what)
24480 {
24481 struct it temp_it;
24482 Lisp_Object gc;
24483 GLYPH glyph;
24484
24485 temp_it = *it;
24486 temp_it.object = make_number (0);
24487 memset (&temp_it.current, 0, sizeof temp_it.current);
24488
24489 if (what == IT_CONTINUATION)
24490 {
24491 /* Continuation glyph. For R2L lines, we mirror it by hand. */
24492 if (it->bidi_it.paragraph_dir == R2L)
24493 SET_GLYPH_FROM_CHAR (glyph, '/');
24494 else
24495 SET_GLYPH_FROM_CHAR (glyph, '\\');
24496 if (it->dp
24497 && (gc = DISP_CONTINUE_GLYPH (it->dp), GLYPH_CODE_P (gc)))
24498 {
24499 /* FIXME: Should we mirror GC for R2L lines? */
24500 SET_GLYPH_FROM_GLYPH_CODE (glyph, gc);
24501 spec_glyph_lookup_face (XWINDOW (it->window), &glyph);
24502 }
24503 }
24504 else if (what == IT_TRUNCATION)
24505 {
24506 /* Truncation glyph. */
24507 SET_GLYPH_FROM_CHAR (glyph, '$');
24508 if (it->dp
24509 && (gc = DISP_TRUNC_GLYPH (it->dp), GLYPH_CODE_P (gc)))
24510 {
24511 /* FIXME: Should we mirror GC for R2L lines? */
24512 SET_GLYPH_FROM_GLYPH_CODE (glyph, gc);
24513 spec_glyph_lookup_face (XWINDOW (it->window), &glyph);
24514 }
24515 }
24516 else
24517 emacs_abort ();
24518
24519 #ifdef HAVE_WINDOW_SYSTEM
24520 /* On a GUI frame, when the right fringe (left fringe for R2L rows)
24521 is turned off, we precede the truncation/continuation glyphs by a
24522 stretch glyph whose width is computed such that these special
24523 glyphs are aligned at the window margin, even when very different
24524 fonts are used in different glyph rows. */
24525 if (FRAME_WINDOW_P (temp_it.f)
24526 /* init_iterator calls this with it->glyph_row == NULL, and it
24527 wants only the pixel width of the truncation/continuation
24528 glyphs. */
24529 && temp_it.glyph_row
24530 /* insert_left_trunc_glyphs calls us at the beginning of the
24531 row, and it has its own calculation of the stretch glyph
24532 width. */
24533 && temp_it.glyph_row->used[TEXT_AREA] > 0
24534 && (temp_it.glyph_row->reversed_p
24535 ? WINDOW_LEFT_FRINGE_WIDTH (temp_it.w)
24536 : WINDOW_RIGHT_FRINGE_WIDTH (temp_it.w)) == 0)
24537 {
24538 int stretch_width = temp_it.last_visible_x - temp_it.current_x;
24539
24540 if (stretch_width > 0)
24541 {
24542 struct face *face = FACE_FROM_ID (temp_it.f, temp_it.face_id);
24543 struct font *font =
24544 face->font ? face->font : FRAME_FONT (temp_it.f);
24545 int stretch_ascent =
24546 (((temp_it.ascent + temp_it.descent)
24547 * FONT_BASE (font)) / FONT_HEIGHT (font));
24548
24549 append_stretch_glyph (&temp_it, make_number (0), stretch_width,
24550 temp_it.ascent + temp_it.descent,
24551 stretch_ascent);
24552 }
24553 }
24554 #endif
24555
24556 temp_it.dp = NULL;
24557 temp_it.what = IT_CHARACTER;
24558 temp_it.len = 1;
24559 temp_it.c = temp_it.char_to_display = GLYPH_CHAR (glyph);
24560 temp_it.face_id = GLYPH_FACE (glyph);
24561 temp_it.len = CHAR_BYTES (temp_it.c);
24562
24563 PRODUCE_GLYPHS (&temp_it);
24564 it->pixel_width = temp_it.pixel_width;
24565 it->nglyphs = temp_it.pixel_width;
24566 }
24567
24568 #ifdef HAVE_WINDOW_SYSTEM
24569
24570 /* Calculate line-height and line-spacing properties.
24571 An integer value specifies explicit pixel value.
24572 A float value specifies relative value to current face height.
24573 A cons (float . face-name) specifies relative value to
24574 height of specified face font.
24575
24576 Returns height in pixels, or nil. */
24577
24578
24579 static Lisp_Object
24580 calc_line_height_property (struct it *it, Lisp_Object val, struct font *font,
24581 int boff, int override)
24582 {
24583 Lisp_Object face_name = Qnil;
24584 int ascent, descent, height;
24585
24586 if (NILP (val) || INTEGERP (val) || (override && EQ (val, Qt)))
24587 return val;
24588
24589 if (CONSP (val))
24590 {
24591 face_name = XCAR (val);
24592 val = XCDR (val);
24593 if (!NUMBERP (val))
24594 val = make_number (1);
24595 if (NILP (face_name))
24596 {
24597 height = it->ascent + it->descent;
24598 goto scale;
24599 }
24600 }
24601
24602 if (NILP (face_name))
24603 {
24604 font = FRAME_FONT (it->f);
24605 boff = FRAME_BASELINE_OFFSET (it->f);
24606 }
24607 else if (EQ (face_name, Qt))
24608 {
24609 override = 0;
24610 }
24611 else
24612 {
24613 int face_id;
24614 struct face *face;
24615
24616 face_id = lookup_named_face (it->f, face_name, 0);
24617 if (face_id < 0)
24618 return make_number (-1);
24619
24620 face = FACE_FROM_ID (it->f, face_id);
24621 font = face->font;
24622 if (font == NULL)
24623 return make_number (-1);
24624 boff = font->baseline_offset;
24625 if (font->vertical_centering)
24626 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
24627 }
24628
24629 ascent = FONT_BASE (font) + boff;
24630 descent = FONT_DESCENT (font) - boff;
24631
24632 if (override)
24633 {
24634 it->override_ascent = ascent;
24635 it->override_descent = descent;
24636 it->override_boff = boff;
24637 }
24638
24639 height = ascent + descent;
24640
24641 scale:
24642 if (FLOATP (val))
24643 height = (int)(XFLOAT_DATA (val) * height);
24644 else if (INTEGERP (val))
24645 height *= XINT (val);
24646
24647 return make_number (height);
24648 }
24649
24650
24651 /* Append a glyph for a glyphless character to IT->glyph_row. FACE_ID
24652 is a face ID to be used for the glyph. FOR_NO_FONT is nonzero if
24653 and only if this is for a character for which no font was found.
24654
24655 If the display method (it->glyphless_method) is
24656 GLYPHLESS_DISPLAY_ACRONYM or GLYPHLESS_DISPLAY_HEX_CODE, LEN is a
24657 length of the acronym or the hexadecimal string, UPPER_XOFF and
24658 UPPER_YOFF are pixel offsets for the upper part of the string,
24659 LOWER_XOFF and LOWER_YOFF are for the lower part.
24660
24661 For the other display methods, LEN through LOWER_YOFF are zero. */
24662
24663 static void
24664 append_glyphless_glyph (struct it *it, int face_id, int for_no_font, int len,
24665 short upper_xoff, short upper_yoff,
24666 short lower_xoff, short lower_yoff)
24667 {
24668 struct glyph *glyph;
24669 enum glyph_row_area area = it->area;
24670
24671 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
24672 if (glyph < it->glyph_row->glyphs[area + 1])
24673 {
24674 /* If the glyph row is reversed, we need to prepend the glyph
24675 rather than append it. */
24676 if (it->glyph_row->reversed_p && area == TEXT_AREA)
24677 {
24678 struct glyph *g;
24679
24680 /* Make room for the additional glyph. */
24681 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
24682 g[1] = *g;
24683 glyph = it->glyph_row->glyphs[area];
24684 }
24685 glyph->charpos = CHARPOS (it->position);
24686 glyph->object = it->object;
24687 glyph->pixel_width = it->pixel_width;
24688 glyph->ascent = it->ascent;
24689 glyph->descent = it->descent;
24690 glyph->voffset = it->voffset;
24691 glyph->type = GLYPHLESS_GLYPH;
24692 glyph->u.glyphless.method = it->glyphless_method;
24693 glyph->u.glyphless.for_no_font = for_no_font;
24694 glyph->u.glyphless.len = len;
24695 glyph->u.glyphless.ch = it->c;
24696 glyph->slice.glyphless.upper_xoff = upper_xoff;
24697 glyph->slice.glyphless.upper_yoff = upper_yoff;
24698 glyph->slice.glyphless.lower_xoff = lower_xoff;
24699 glyph->slice.glyphless.lower_yoff = lower_yoff;
24700 glyph->avoid_cursor_p = it->avoid_cursor_p;
24701 glyph->multibyte_p = it->multibyte_p;
24702 glyph->left_box_line_p = it->start_of_box_run_p;
24703 glyph->right_box_line_p = it->end_of_box_run_p;
24704 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
24705 || it->phys_descent > it->descent);
24706 glyph->padding_p = 0;
24707 glyph->glyph_not_available_p = 0;
24708 glyph->face_id = face_id;
24709 glyph->font_type = FONT_TYPE_UNKNOWN;
24710 if (it->bidi_p)
24711 {
24712 glyph->resolved_level = it->bidi_it.resolved_level;
24713 if ((it->bidi_it.type & 7) != it->bidi_it.type)
24714 emacs_abort ();
24715 glyph->bidi_type = it->bidi_it.type;
24716 }
24717 ++it->glyph_row->used[area];
24718 }
24719 else
24720 IT_EXPAND_MATRIX_WIDTH (it, area);
24721 }
24722
24723
24724 /* Produce a glyph for a glyphless character for iterator IT.
24725 IT->glyphless_method specifies which method to use for displaying
24726 the character. See the description of enum
24727 glyphless_display_method in dispextern.h for the detail.
24728
24729 FOR_NO_FONT is nonzero if and only if this is for a character for
24730 which no font was found. ACRONYM, if non-nil, is an acronym string
24731 for the character. */
24732
24733 static void
24734 produce_glyphless_glyph (struct it *it, int for_no_font, Lisp_Object acronym)
24735 {
24736 int face_id;
24737 struct face *face;
24738 struct font *font;
24739 int base_width, base_height, width, height;
24740 short upper_xoff, upper_yoff, lower_xoff, lower_yoff;
24741 int len;
24742
24743 /* Get the metrics of the base font. We always refer to the current
24744 ASCII face. */
24745 face = FACE_FROM_ID (it->f, it->face_id)->ascii_face;
24746 font = face->font ? face->font : FRAME_FONT (it->f);
24747 it->ascent = FONT_BASE (font) + font->baseline_offset;
24748 it->descent = FONT_DESCENT (font) - font->baseline_offset;
24749 base_height = it->ascent + it->descent;
24750 base_width = font->average_width;
24751
24752 /* Get a face ID for the glyph by utilizing a cache (the same way as
24753 done for `escape-glyph' in get_next_display_element). */
24754 if (it->f == last_glyphless_glyph_frame
24755 && it->face_id == last_glyphless_glyph_face_id)
24756 {
24757 face_id = last_glyphless_glyph_merged_face_id;
24758 }
24759 else
24760 {
24761 /* Merge the `glyphless-char' face into the current face. */
24762 face_id = merge_faces (it->f, Qglyphless_char, 0, it->face_id);
24763 last_glyphless_glyph_frame = it->f;
24764 last_glyphless_glyph_face_id = it->face_id;
24765 last_glyphless_glyph_merged_face_id = face_id;
24766 }
24767
24768 if (it->glyphless_method == GLYPHLESS_DISPLAY_THIN_SPACE)
24769 {
24770 it->pixel_width = THIN_SPACE_WIDTH;
24771 len = 0;
24772 upper_xoff = upper_yoff = lower_xoff = lower_yoff = 0;
24773 }
24774 else if (it->glyphless_method == GLYPHLESS_DISPLAY_EMPTY_BOX)
24775 {
24776 width = CHAR_WIDTH (it->c);
24777 if (width == 0)
24778 width = 1;
24779 else if (width > 4)
24780 width = 4;
24781 it->pixel_width = base_width * width;
24782 len = 0;
24783 upper_xoff = upper_yoff = lower_xoff = lower_yoff = 0;
24784 }
24785 else
24786 {
24787 char buf[7];
24788 const char *str;
24789 unsigned int code[6];
24790 int upper_len;
24791 int ascent, descent;
24792 struct font_metrics metrics_upper, metrics_lower;
24793
24794 face = FACE_FROM_ID (it->f, face_id);
24795 font = face->font ? face->font : FRAME_FONT (it->f);
24796 PREPARE_FACE_FOR_DISPLAY (it->f, face);
24797
24798 if (it->glyphless_method == GLYPHLESS_DISPLAY_ACRONYM)
24799 {
24800 if (! STRINGP (acronym) && CHAR_TABLE_P (Vglyphless_char_display))
24801 acronym = CHAR_TABLE_REF (Vglyphless_char_display, it->c);
24802 if (CONSP (acronym))
24803 acronym = XCAR (acronym);
24804 str = STRINGP (acronym) ? SSDATA (acronym) : "";
24805 }
24806 else
24807 {
24808 eassert (it->glyphless_method == GLYPHLESS_DISPLAY_HEX_CODE);
24809 sprintf (buf, "%0*X", it->c < 0x10000 ? 4 : 6, it->c);
24810 str = buf;
24811 }
24812 for (len = 0; str[len] && ASCII_BYTE_P (str[len]) && len < 6; len++)
24813 code[len] = font->driver->encode_char (font, str[len]);
24814 upper_len = (len + 1) / 2;
24815 font->driver->text_extents (font, code, upper_len,
24816 &metrics_upper);
24817 font->driver->text_extents (font, code + upper_len, len - upper_len,
24818 &metrics_lower);
24819
24820
24821
24822 /* +4 is for vertical bars of a box plus 1-pixel spaces at both side. */
24823 width = max (metrics_upper.width, metrics_lower.width) + 4;
24824 upper_xoff = upper_yoff = 2; /* the typical case */
24825 if (base_width >= width)
24826 {
24827 /* Align the upper to the left, the lower to the right. */
24828 it->pixel_width = base_width;
24829 lower_xoff = base_width - 2 - metrics_lower.width;
24830 }
24831 else
24832 {
24833 /* Center the shorter one. */
24834 it->pixel_width = width;
24835 if (metrics_upper.width >= metrics_lower.width)
24836 lower_xoff = (width - metrics_lower.width) / 2;
24837 else
24838 {
24839 /* FIXME: This code doesn't look right. It formerly was
24840 missing the "lower_xoff = 0;", which couldn't have
24841 been right since it left lower_xoff uninitialized. */
24842 lower_xoff = 0;
24843 upper_xoff = (width - metrics_upper.width) / 2;
24844 }
24845 }
24846
24847 /* +5 is for horizontal bars of a box plus 1-pixel spaces at
24848 top, bottom, and between upper and lower strings. */
24849 height = (metrics_upper.ascent + metrics_upper.descent
24850 + metrics_lower.ascent + metrics_lower.descent) + 5;
24851 /* Center vertically.
24852 H:base_height, D:base_descent
24853 h:height, ld:lower_descent, la:lower_ascent, ud:upper_descent
24854
24855 ascent = - (D - H/2 - h/2 + 1); "+ 1" for rounding up
24856 descent = D - H/2 + h/2;
24857 lower_yoff = descent - 2 - ld;
24858 upper_yoff = lower_yoff - la - 1 - ud; */
24859 ascent = - (it->descent - (base_height + height + 1) / 2);
24860 descent = it->descent - (base_height - height) / 2;
24861 lower_yoff = descent - 2 - metrics_lower.descent;
24862 upper_yoff = (lower_yoff - metrics_lower.ascent - 1
24863 - metrics_upper.descent);
24864 /* Don't make the height shorter than the base height. */
24865 if (height > base_height)
24866 {
24867 it->ascent = ascent;
24868 it->descent = descent;
24869 }
24870 }
24871
24872 it->phys_ascent = it->ascent;
24873 it->phys_descent = it->descent;
24874 if (it->glyph_row)
24875 append_glyphless_glyph (it, face_id, for_no_font, len,
24876 upper_xoff, upper_yoff,
24877 lower_xoff, lower_yoff);
24878 it->nglyphs = 1;
24879 take_vertical_position_into_account (it);
24880 }
24881
24882
24883 /* RIF:
24884 Produce glyphs/get display metrics for the display element IT is
24885 loaded with. See the description of struct it in dispextern.h
24886 for an overview of struct it. */
24887
24888 void
24889 x_produce_glyphs (struct it *it)
24890 {
24891 int extra_line_spacing = it->extra_line_spacing;
24892
24893 it->glyph_not_available_p = 0;
24894
24895 if (it->what == IT_CHARACTER)
24896 {
24897 XChar2b char2b;
24898 struct face *face = FACE_FROM_ID (it->f, it->face_id);
24899 struct font *font = face->font;
24900 struct font_metrics *pcm = NULL;
24901 int boff; /* baseline offset */
24902
24903 if (font == NULL)
24904 {
24905 /* When no suitable font is found, display this character by
24906 the method specified in the first extra slot of
24907 Vglyphless_char_display. */
24908 Lisp_Object acronym = lookup_glyphless_char_display (-1, it);
24909
24910 eassert (it->what == IT_GLYPHLESS);
24911 produce_glyphless_glyph (it, 1, STRINGP (acronym) ? acronym : Qnil);
24912 goto done;
24913 }
24914
24915 boff = font->baseline_offset;
24916 if (font->vertical_centering)
24917 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
24918
24919 if (it->char_to_display != '\n' && it->char_to_display != '\t')
24920 {
24921 int stretched_p;
24922
24923 it->nglyphs = 1;
24924
24925 if (it->override_ascent >= 0)
24926 {
24927 it->ascent = it->override_ascent;
24928 it->descent = it->override_descent;
24929 boff = it->override_boff;
24930 }
24931 else
24932 {
24933 it->ascent = FONT_BASE (font) + boff;
24934 it->descent = FONT_DESCENT (font) - boff;
24935 }
24936
24937 if (get_char_glyph_code (it->char_to_display, font, &char2b))
24938 {
24939 pcm = get_per_char_metric (font, &char2b);
24940 if (pcm->width == 0
24941 && pcm->rbearing == 0 && pcm->lbearing == 0)
24942 pcm = NULL;
24943 }
24944
24945 if (pcm)
24946 {
24947 it->phys_ascent = pcm->ascent + boff;
24948 it->phys_descent = pcm->descent - boff;
24949 it->pixel_width = pcm->width;
24950 }
24951 else
24952 {
24953 it->glyph_not_available_p = 1;
24954 it->phys_ascent = it->ascent;
24955 it->phys_descent = it->descent;
24956 it->pixel_width = font->space_width;
24957 }
24958
24959 if (it->constrain_row_ascent_descent_p)
24960 {
24961 if (it->descent > it->max_descent)
24962 {
24963 it->ascent += it->descent - it->max_descent;
24964 it->descent = it->max_descent;
24965 }
24966 if (it->ascent > it->max_ascent)
24967 {
24968 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
24969 it->ascent = it->max_ascent;
24970 }
24971 it->phys_ascent = min (it->phys_ascent, it->ascent);
24972 it->phys_descent = min (it->phys_descent, it->descent);
24973 extra_line_spacing = 0;
24974 }
24975
24976 /* If this is a space inside a region of text with
24977 `space-width' property, change its width. */
24978 stretched_p = it->char_to_display == ' ' && !NILP (it->space_width);
24979 if (stretched_p)
24980 it->pixel_width *= XFLOATINT (it->space_width);
24981
24982 /* If face has a box, add the box thickness to the character
24983 height. If character has a box line to the left and/or
24984 right, add the box line width to the character's width. */
24985 if (face->box != FACE_NO_BOX)
24986 {
24987 int thick = face->box_line_width;
24988
24989 if (thick > 0)
24990 {
24991 it->ascent += thick;
24992 it->descent += thick;
24993 }
24994 else
24995 thick = -thick;
24996
24997 if (it->start_of_box_run_p)
24998 it->pixel_width += thick;
24999 if (it->end_of_box_run_p)
25000 it->pixel_width += thick;
25001 }
25002
25003 /* If face has an overline, add the height of the overline
25004 (1 pixel) and a 1 pixel margin to the character height. */
25005 if (face->overline_p)
25006 it->ascent += overline_margin;
25007
25008 if (it->constrain_row_ascent_descent_p)
25009 {
25010 if (it->ascent > it->max_ascent)
25011 it->ascent = it->max_ascent;
25012 if (it->descent > it->max_descent)
25013 it->descent = it->max_descent;
25014 }
25015
25016 take_vertical_position_into_account (it);
25017
25018 /* If we have to actually produce glyphs, do it. */
25019 if (it->glyph_row)
25020 {
25021 if (stretched_p)
25022 {
25023 /* Translate a space with a `space-width' property
25024 into a stretch glyph. */
25025 int ascent = (((it->ascent + it->descent) * FONT_BASE (font))
25026 / FONT_HEIGHT (font));
25027 append_stretch_glyph (it, it->object, it->pixel_width,
25028 it->ascent + it->descent, ascent);
25029 }
25030 else
25031 append_glyph (it);
25032
25033 /* If characters with lbearing or rbearing are displayed
25034 in this line, record that fact in a flag of the
25035 glyph row. This is used to optimize X output code. */
25036 if (pcm && (pcm->lbearing < 0 || pcm->rbearing > pcm->width))
25037 it->glyph_row->contains_overlapping_glyphs_p = 1;
25038 }
25039 if (! stretched_p && it->pixel_width == 0)
25040 /* We assure that all visible glyphs have at least 1-pixel
25041 width. */
25042 it->pixel_width = 1;
25043 }
25044 else if (it->char_to_display == '\n')
25045 {
25046 /* A newline has no width, but we need the height of the
25047 line. But if previous part of the line sets a height,
25048 don't increase that height */
25049
25050 Lisp_Object height;
25051 Lisp_Object total_height = Qnil;
25052
25053 it->override_ascent = -1;
25054 it->pixel_width = 0;
25055 it->nglyphs = 0;
25056
25057 height = get_it_property (it, Qline_height);
25058 /* Split (line-height total-height) list */
25059 if (CONSP (height)
25060 && CONSP (XCDR (height))
25061 && NILP (XCDR (XCDR (height))))
25062 {
25063 total_height = XCAR (XCDR (height));
25064 height = XCAR (height);
25065 }
25066 height = calc_line_height_property (it, height, font, boff, 1);
25067
25068 if (it->override_ascent >= 0)
25069 {
25070 it->ascent = it->override_ascent;
25071 it->descent = it->override_descent;
25072 boff = it->override_boff;
25073 }
25074 else
25075 {
25076 it->ascent = FONT_BASE (font) + boff;
25077 it->descent = FONT_DESCENT (font) - boff;
25078 }
25079
25080 if (EQ (height, Qt))
25081 {
25082 if (it->descent > it->max_descent)
25083 {
25084 it->ascent += it->descent - it->max_descent;
25085 it->descent = it->max_descent;
25086 }
25087 if (it->ascent > it->max_ascent)
25088 {
25089 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
25090 it->ascent = it->max_ascent;
25091 }
25092 it->phys_ascent = min (it->phys_ascent, it->ascent);
25093 it->phys_descent = min (it->phys_descent, it->descent);
25094 it->constrain_row_ascent_descent_p = 1;
25095 extra_line_spacing = 0;
25096 }
25097 else
25098 {
25099 Lisp_Object spacing;
25100
25101 it->phys_ascent = it->ascent;
25102 it->phys_descent = it->descent;
25103
25104 if ((it->max_ascent > 0 || it->max_descent > 0)
25105 && face->box != FACE_NO_BOX
25106 && face->box_line_width > 0)
25107 {
25108 it->ascent += face->box_line_width;
25109 it->descent += face->box_line_width;
25110 }
25111 if (!NILP (height)
25112 && XINT (height) > it->ascent + it->descent)
25113 it->ascent = XINT (height) - it->descent;
25114
25115 if (!NILP (total_height))
25116 spacing = calc_line_height_property (it, total_height, font, boff, 0);
25117 else
25118 {
25119 spacing = get_it_property (it, Qline_spacing);
25120 spacing = calc_line_height_property (it, spacing, font, boff, 0);
25121 }
25122 if (INTEGERP (spacing))
25123 {
25124 extra_line_spacing = XINT (spacing);
25125 if (!NILP (total_height))
25126 extra_line_spacing -= (it->phys_ascent + it->phys_descent);
25127 }
25128 }
25129 }
25130 else /* i.e. (it->char_to_display == '\t') */
25131 {
25132 if (font->space_width > 0)
25133 {
25134 int tab_width = it->tab_width * font->space_width;
25135 int x = it->current_x + it->continuation_lines_width;
25136 int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width;
25137
25138 /* If the distance from the current position to the next tab
25139 stop is less than a space character width, use the
25140 tab stop after that. */
25141 if (next_tab_x - x < font->space_width)
25142 next_tab_x += tab_width;
25143
25144 it->pixel_width = next_tab_x - x;
25145 it->nglyphs = 1;
25146 it->ascent = it->phys_ascent = FONT_BASE (font) + boff;
25147 it->descent = it->phys_descent = FONT_DESCENT (font) - boff;
25148
25149 if (it->glyph_row)
25150 {
25151 append_stretch_glyph (it, it->object, it->pixel_width,
25152 it->ascent + it->descent, it->ascent);
25153 }
25154 }
25155 else
25156 {
25157 it->pixel_width = 0;
25158 it->nglyphs = 1;
25159 }
25160 }
25161 }
25162 else if (it->what == IT_COMPOSITION && it->cmp_it.ch < 0)
25163 {
25164 /* A static composition.
25165
25166 Note: A composition is represented as one glyph in the
25167 glyph matrix. There are no padding glyphs.
25168
25169 Important note: pixel_width, ascent, and descent are the
25170 values of what is drawn by draw_glyphs (i.e. the values of
25171 the overall glyphs composed). */
25172 struct face *face = FACE_FROM_ID (it->f, it->face_id);
25173 int boff; /* baseline offset */
25174 struct composition *cmp = composition_table[it->cmp_it.id];
25175 int glyph_len = cmp->glyph_len;
25176 struct font *font = face->font;
25177
25178 it->nglyphs = 1;
25179
25180 /* If we have not yet calculated pixel size data of glyphs of
25181 the composition for the current face font, calculate them
25182 now. Theoretically, we have to check all fonts for the
25183 glyphs, but that requires much time and memory space. So,
25184 here we check only the font of the first glyph. This may
25185 lead to incorrect display, but it's very rare, and C-l
25186 (recenter-top-bottom) can correct the display anyway. */
25187 if (! cmp->font || cmp->font != font)
25188 {
25189 /* Ascent and descent of the font of the first character
25190 of this composition (adjusted by baseline offset).
25191 Ascent and descent of overall glyphs should not be less
25192 than these, respectively. */
25193 int font_ascent, font_descent, font_height;
25194 /* Bounding box of the overall glyphs. */
25195 int leftmost, rightmost, lowest, highest;
25196 int lbearing, rbearing;
25197 int i, width, ascent, descent;
25198 int left_padded = 0, right_padded = 0;
25199 int c IF_LINT (= 0); /* cmp->glyph_len can't be zero; see Bug#8512 */
25200 XChar2b char2b;
25201 struct font_metrics *pcm;
25202 int font_not_found_p;
25203 ptrdiff_t pos;
25204
25205 for (glyph_len = cmp->glyph_len; glyph_len > 0; glyph_len--)
25206 if ((c = COMPOSITION_GLYPH (cmp, glyph_len - 1)) != '\t')
25207 break;
25208 if (glyph_len < cmp->glyph_len)
25209 right_padded = 1;
25210 for (i = 0; i < glyph_len; i++)
25211 {
25212 if ((c = COMPOSITION_GLYPH (cmp, i)) != '\t')
25213 break;
25214 cmp->offsets[i * 2] = cmp->offsets[i * 2 + 1] = 0;
25215 }
25216 if (i > 0)
25217 left_padded = 1;
25218
25219 pos = (STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
25220 : IT_CHARPOS (*it));
25221 /* If no suitable font is found, use the default font. */
25222 font_not_found_p = font == NULL;
25223 if (font_not_found_p)
25224 {
25225 face = face->ascii_face;
25226 font = face->font;
25227 }
25228 boff = font->baseline_offset;
25229 if (font->vertical_centering)
25230 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
25231 font_ascent = FONT_BASE (font) + boff;
25232 font_descent = FONT_DESCENT (font) - boff;
25233 font_height = FONT_HEIGHT (font);
25234
25235 cmp->font = font;
25236
25237 pcm = NULL;
25238 if (! font_not_found_p)
25239 {
25240 get_char_face_and_encoding (it->f, c, it->face_id,
25241 &char2b, 0);
25242 pcm = get_per_char_metric (font, &char2b);
25243 }
25244
25245 /* Initialize the bounding box. */
25246 if (pcm)
25247 {
25248 width = cmp->glyph_len > 0 ? pcm->width : 0;
25249 ascent = pcm->ascent;
25250 descent = pcm->descent;
25251 lbearing = pcm->lbearing;
25252 rbearing = pcm->rbearing;
25253 }
25254 else
25255 {
25256 width = cmp->glyph_len > 0 ? font->space_width : 0;
25257 ascent = FONT_BASE (font);
25258 descent = FONT_DESCENT (font);
25259 lbearing = 0;
25260 rbearing = width;
25261 }
25262
25263 rightmost = width;
25264 leftmost = 0;
25265 lowest = - descent + boff;
25266 highest = ascent + boff;
25267
25268 if (! font_not_found_p
25269 && font->default_ascent
25270 && CHAR_TABLE_P (Vuse_default_ascent)
25271 && !NILP (Faref (Vuse_default_ascent,
25272 make_number (it->char_to_display))))
25273 highest = font->default_ascent + boff;
25274
25275 /* Draw the first glyph at the normal position. It may be
25276 shifted to right later if some other glyphs are drawn
25277 at the left. */
25278 cmp->offsets[i * 2] = 0;
25279 cmp->offsets[i * 2 + 1] = boff;
25280 cmp->lbearing = lbearing;
25281 cmp->rbearing = rbearing;
25282
25283 /* Set cmp->offsets for the remaining glyphs. */
25284 for (i++; i < glyph_len; i++)
25285 {
25286 int left, right, btm, top;
25287 int ch = COMPOSITION_GLYPH (cmp, i);
25288 int face_id;
25289 struct face *this_face;
25290
25291 if (ch == '\t')
25292 ch = ' ';
25293 face_id = FACE_FOR_CHAR (it->f, face, ch, pos, it->string);
25294 this_face = FACE_FROM_ID (it->f, face_id);
25295 font = this_face->font;
25296
25297 if (font == NULL)
25298 pcm = NULL;
25299 else
25300 {
25301 get_char_face_and_encoding (it->f, ch, face_id,
25302 &char2b, 0);
25303 pcm = get_per_char_metric (font, &char2b);
25304 }
25305 if (! pcm)
25306 cmp->offsets[i * 2] = cmp->offsets[i * 2 + 1] = 0;
25307 else
25308 {
25309 width = pcm->width;
25310 ascent = pcm->ascent;
25311 descent = pcm->descent;
25312 lbearing = pcm->lbearing;
25313 rbearing = pcm->rbearing;
25314 if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS)
25315 {
25316 /* Relative composition with or without
25317 alternate chars. */
25318 left = (leftmost + rightmost - width) / 2;
25319 btm = - descent + boff;
25320 if (font->relative_compose
25321 && (! CHAR_TABLE_P (Vignore_relative_composition)
25322 || NILP (Faref (Vignore_relative_composition,
25323 make_number (ch)))))
25324 {
25325
25326 if (- descent >= font->relative_compose)
25327 /* One extra pixel between two glyphs. */
25328 btm = highest + 1;
25329 else if (ascent <= 0)
25330 /* One extra pixel between two glyphs. */
25331 btm = lowest - 1 - ascent - descent;
25332 }
25333 }
25334 else
25335 {
25336 /* A composition rule is specified by an integer
25337 value that encodes global and new reference
25338 points (GREF and NREF). GREF and NREF are
25339 specified by numbers as below:
25340
25341 0---1---2 -- ascent
25342 | |
25343 | |
25344 | |
25345 9--10--11 -- center
25346 | |
25347 ---3---4---5--- baseline
25348 | |
25349 6---7---8 -- descent
25350 */
25351 int rule = COMPOSITION_RULE (cmp, i);
25352 int gref, nref, grefx, grefy, nrefx, nrefy, xoff, yoff;
25353
25354 COMPOSITION_DECODE_RULE (rule, gref, nref, xoff, yoff);
25355 grefx = gref % 3, nrefx = nref % 3;
25356 grefy = gref / 3, nrefy = nref / 3;
25357 if (xoff)
25358 xoff = font_height * (xoff - 128) / 256;
25359 if (yoff)
25360 yoff = font_height * (yoff - 128) / 256;
25361
25362 left = (leftmost
25363 + grefx * (rightmost - leftmost) / 2
25364 - nrefx * width / 2
25365 + xoff);
25366
25367 btm = ((grefy == 0 ? highest
25368 : grefy == 1 ? 0
25369 : grefy == 2 ? lowest
25370 : (highest + lowest) / 2)
25371 - (nrefy == 0 ? ascent + descent
25372 : nrefy == 1 ? descent - boff
25373 : nrefy == 2 ? 0
25374 : (ascent + descent) / 2)
25375 + yoff);
25376 }
25377
25378 cmp->offsets[i * 2] = left;
25379 cmp->offsets[i * 2 + 1] = btm + descent;
25380
25381 /* Update the bounding box of the overall glyphs. */
25382 if (width > 0)
25383 {
25384 right = left + width;
25385 if (left < leftmost)
25386 leftmost = left;
25387 if (right > rightmost)
25388 rightmost = right;
25389 }
25390 top = btm + descent + ascent;
25391 if (top > highest)
25392 highest = top;
25393 if (btm < lowest)
25394 lowest = btm;
25395
25396 if (cmp->lbearing > left + lbearing)
25397 cmp->lbearing = left + lbearing;
25398 if (cmp->rbearing < left + rbearing)
25399 cmp->rbearing = left + rbearing;
25400 }
25401 }
25402
25403 /* If there are glyphs whose x-offsets are negative,
25404 shift all glyphs to the right and make all x-offsets
25405 non-negative. */
25406 if (leftmost < 0)
25407 {
25408 for (i = 0; i < cmp->glyph_len; i++)
25409 cmp->offsets[i * 2] -= leftmost;
25410 rightmost -= leftmost;
25411 cmp->lbearing -= leftmost;
25412 cmp->rbearing -= leftmost;
25413 }
25414
25415 if (left_padded && cmp->lbearing < 0)
25416 {
25417 for (i = 0; i < cmp->glyph_len; i++)
25418 cmp->offsets[i * 2] -= cmp->lbearing;
25419 rightmost -= cmp->lbearing;
25420 cmp->rbearing -= cmp->lbearing;
25421 cmp->lbearing = 0;
25422 }
25423 if (right_padded && rightmost < cmp->rbearing)
25424 {
25425 rightmost = cmp->rbearing;
25426 }
25427
25428 cmp->pixel_width = rightmost;
25429 cmp->ascent = highest;
25430 cmp->descent = - lowest;
25431 if (cmp->ascent < font_ascent)
25432 cmp->ascent = font_ascent;
25433 if (cmp->descent < font_descent)
25434 cmp->descent = font_descent;
25435 }
25436
25437 if (it->glyph_row
25438 && (cmp->lbearing < 0
25439 || cmp->rbearing > cmp->pixel_width))
25440 it->glyph_row->contains_overlapping_glyphs_p = 1;
25441
25442 it->pixel_width = cmp->pixel_width;
25443 it->ascent = it->phys_ascent = cmp->ascent;
25444 it->descent = it->phys_descent = cmp->descent;
25445 if (face->box != FACE_NO_BOX)
25446 {
25447 int thick = face->box_line_width;
25448
25449 if (thick > 0)
25450 {
25451 it->ascent += thick;
25452 it->descent += thick;
25453 }
25454 else
25455 thick = - thick;
25456
25457 if (it->start_of_box_run_p)
25458 it->pixel_width += thick;
25459 if (it->end_of_box_run_p)
25460 it->pixel_width += thick;
25461 }
25462
25463 /* If face has an overline, add the height of the overline
25464 (1 pixel) and a 1 pixel margin to the character height. */
25465 if (face->overline_p)
25466 it->ascent += overline_margin;
25467
25468 take_vertical_position_into_account (it);
25469 if (it->ascent < 0)
25470 it->ascent = 0;
25471 if (it->descent < 0)
25472 it->descent = 0;
25473
25474 if (it->glyph_row && cmp->glyph_len > 0)
25475 append_composite_glyph (it);
25476 }
25477 else if (it->what == IT_COMPOSITION)
25478 {
25479 /* A dynamic (automatic) composition. */
25480 struct face *face = FACE_FROM_ID (it->f, it->face_id);
25481 Lisp_Object gstring;
25482 struct font_metrics metrics;
25483
25484 it->nglyphs = 1;
25485
25486 gstring = composition_gstring_from_id (it->cmp_it.id);
25487 it->pixel_width
25488 = composition_gstring_width (gstring, it->cmp_it.from, it->cmp_it.to,
25489 &metrics);
25490 if (it->glyph_row
25491 && (metrics.lbearing < 0 || metrics.rbearing > metrics.width))
25492 it->glyph_row->contains_overlapping_glyphs_p = 1;
25493 it->ascent = it->phys_ascent = metrics.ascent;
25494 it->descent = it->phys_descent = metrics.descent;
25495 if (face->box != FACE_NO_BOX)
25496 {
25497 int thick = face->box_line_width;
25498
25499 if (thick > 0)
25500 {
25501 it->ascent += thick;
25502 it->descent += thick;
25503 }
25504 else
25505 thick = - thick;
25506
25507 if (it->start_of_box_run_p)
25508 it->pixel_width += thick;
25509 if (it->end_of_box_run_p)
25510 it->pixel_width += thick;
25511 }
25512 /* If face has an overline, add the height of the overline
25513 (1 pixel) and a 1 pixel margin to the character height. */
25514 if (face->overline_p)
25515 it->ascent += overline_margin;
25516 take_vertical_position_into_account (it);
25517 if (it->ascent < 0)
25518 it->ascent = 0;
25519 if (it->descent < 0)
25520 it->descent = 0;
25521
25522 if (it->glyph_row)
25523 append_composite_glyph (it);
25524 }
25525 else if (it->what == IT_GLYPHLESS)
25526 produce_glyphless_glyph (it, 0, Qnil);
25527 else if (it->what == IT_IMAGE)
25528 produce_image_glyph (it);
25529 else if (it->what == IT_STRETCH)
25530 produce_stretch_glyph (it);
25531 #ifdef HAVE_XWIDGETS
25532 else if (it->what == IT_XWIDGET)
25533 produce_xwidget_glyph (it);
25534 #endif
25535 done:
25536 /* Accumulate dimensions. Note: can't assume that it->descent > 0
25537 because this isn't true for images with `:ascent 100'. */
25538 eassert (it->ascent >= 0 && it->descent >= 0);
25539 if (it->area == TEXT_AREA)
25540 it->current_x += it->pixel_width;
25541
25542 if (extra_line_spacing > 0)
25543 {
25544 it->descent += extra_line_spacing;
25545 if (extra_line_spacing > it->max_extra_line_spacing)
25546 it->max_extra_line_spacing = extra_line_spacing;
25547 }
25548
25549 it->max_ascent = max (it->max_ascent, it->ascent);
25550 it->max_descent = max (it->max_descent, it->descent);
25551 it->max_phys_ascent = max (it->max_phys_ascent, it->phys_ascent);
25552 it->max_phys_descent = max (it->max_phys_descent, it->phys_descent);
25553 }
25554
25555 /* EXPORT for RIF:
25556 Output LEN glyphs starting at START at the nominal cursor position.
25557 Advance the nominal cursor over the text. The global variable
25558 updated_window contains the window being updated, updated_row is
25559 the glyph row being updated, and updated_area is the area of that
25560 row being updated. */
25561
25562 void
25563 x_write_glyphs (struct glyph *start, int len)
25564 {
25565 int x, hpos, chpos = updated_window->phys_cursor.hpos;
25566
25567 eassert (updated_window && updated_row);
25568 /* When the window is hscrolled, cursor hpos can legitimately be out
25569 of bounds, but we draw the cursor at the corresponding window
25570 margin in that case. */
25571 if (!updated_row->reversed_p && chpos < 0)
25572 chpos = 0;
25573 if (updated_row->reversed_p && chpos >= updated_row->used[TEXT_AREA])
25574 chpos = updated_row->used[TEXT_AREA] - 1;
25575
25576 BLOCK_INPUT;
25577
25578 /* Write glyphs. */
25579
25580 hpos = start - updated_row->glyphs[updated_area];
25581 x = draw_glyphs (updated_window, output_cursor.x,
25582 updated_row, updated_area,
25583 hpos, hpos + len,
25584 DRAW_NORMAL_TEXT, 0);
25585
25586 /* Invalidate old phys cursor if the glyph at its hpos is redrawn. */
25587 if (updated_area == TEXT_AREA
25588 && updated_window->phys_cursor_on_p
25589 && updated_window->phys_cursor.vpos == output_cursor.vpos
25590 && chpos >= hpos
25591 && chpos < hpos + len)
25592 updated_window->phys_cursor_on_p = 0;
25593
25594 UNBLOCK_INPUT;
25595
25596 /* Advance the output cursor. */
25597 output_cursor.hpos += len;
25598 output_cursor.x = x;
25599 }
25600
25601
25602 /* EXPORT for RIF:
25603 Insert LEN glyphs from START at the nominal cursor position. */
25604
25605 void
25606 x_insert_glyphs (struct glyph *start, int len)
25607 {
25608 struct frame *f;
25609 struct window *w;
25610 int line_height, shift_by_width, shifted_region_width;
25611 struct glyph_row *row;
25612 struct glyph *glyph;
25613 int frame_x, frame_y;
25614 ptrdiff_t hpos;
25615
25616 eassert (updated_window && updated_row);
25617 BLOCK_INPUT;
25618 w = updated_window;
25619 f = XFRAME (WINDOW_FRAME (w));
25620
25621 /* Get the height of the line we are in. */
25622 row = updated_row;
25623 line_height = row->height;
25624
25625 /* Get the width of the glyphs to insert. */
25626 shift_by_width = 0;
25627 for (glyph = start; glyph < start + len; ++glyph)
25628 shift_by_width += glyph->pixel_width;
25629
25630 /* Get the width of the region to shift right. */
25631 shifted_region_width = (window_box_width (w, updated_area)
25632 - output_cursor.x
25633 - shift_by_width);
25634
25635 /* Shift right. */
25636 frame_x = window_box_left (w, updated_area) + output_cursor.x;
25637 frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, output_cursor.y);
25638
25639 FRAME_RIF (f)->shift_glyphs_for_insert (f, frame_x, frame_y, shifted_region_width,
25640 line_height, shift_by_width);
25641
25642 /* Write the glyphs. */
25643 hpos = start - row->glyphs[updated_area];
25644 draw_glyphs (w, output_cursor.x, row, updated_area,
25645 hpos, hpos + len,
25646 DRAW_NORMAL_TEXT, 0);
25647
25648 /* Advance the output cursor. */
25649 output_cursor.hpos += len;
25650 output_cursor.x += shift_by_width;
25651 UNBLOCK_INPUT;
25652 }
25653
25654
25655 /* EXPORT for RIF:
25656 Erase the current text line from the nominal cursor position
25657 (inclusive) to pixel column TO_X (exclusive). The idea is that
25658 everything from TO_X onward is already erased.
25659
25660 TO_X is a pixel position relative to updated_area of
25661 updated_window. TO_X == -1 means clear to the end of this area. */
25662
25663 void
25664 x_clear_end_of_line (int to_x)
25665 {
25666 struct frame *f;
25667 struct window *w = updated_window;
25668 int max_x, min_y, max_y;
25669 int from_x, from_y, to_y;
25670
25671 eassert (updated_window && updated_row);
25672 f = XFRAME (w->frame);
25673
25674 if (updated_row->full_width_p)
25675 max_x = WINDOW_TOTAL_WIDTH (w);
25676 else
25677 max_x = window_box_width (w, updated_area);
25678 max_y = window_text_bottom_y (w);
25679
25680 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
25681 of window. For TO_X > 0, truncate to end of drawing area. */
25682 if (to_x == 0)
25683 return;
25684 else if (to_x < 0)
25685 to_x = max_x;
25686 else
25687 to_x = min (to_x, max_x);
25688
25689 to_y = min (max_y, output_cursor.y + updated_row->height);
25690
25691 /* Notice if the cursor will be cleared by this operation. */
25692 if (!updated_row->full_width_p)
25693 notice_overwritten_cursor (w, updated_area,
25694 output_cursor.x, -1,
25695 updated_row->y,
25696 MATRIX_ROW_BOTTOM_Y (updated_row));
25697
25698 from_x = output_cursor.x;
25699
25700 /* Translate to frame coordinates. */
25701 if (updated_row->full_width_p)
25702 {
25703 from_x = WINDOW_TO_FRAME_PIXEL_X (w, from_x);
25704 to_x = WINDOW_TO_FRAME_PIXEL_X (w, to_x);
25705 }
25706 else
25707 {
25708 int area_left = window_box_left (w, updated_area);
25709 from_x += area_left;
25710 to_x += area_left;
25711 }
25712
25713 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
25714 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, max (min_y, output_cursor.y));
25715 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, to_y);
25716
25717 /* Prevent inadvertently clearing to end of the X window. */
25718 if (to_x > from_x && to_y > from_y)
25719 {
25720 BLOCK_INPUT;
25721 FRAME_RIF (f)->clear_frame_area (f, from_x, from_y,
25722 to_x - from_x, to_y - from_y);
25723 UNBLOCK_INPUT;
25724 }
25725 }
25726
25727 #endif /* HAVE_WINDOW_SYSTEM */
25728
25729
25730 \f
25731 /***********************************************************************
25732 Cursor types
25733 ***********************************************************************/
25734
25735 /* Value is the internal representation of the specified cursor type
25736 ARG. If type is BAR_CURSOR, return in *WIDTH the specified width
25737 of the bar cursor. */
25738
25739 static enum text_cursor_kinds
25740 get_specified_cursor_type (Lisp_Object arg, int *width)
25741 {
25742 enum text_cursor_kinds type;
25743
25744 if (NILP (arg))
25745 return NO_CURSOR;
25746
25747 if (EQ (arg, Qbox))
25748 return FILLED_BOX_CURSOR;
25749
25750 if (EQ (arg, Qhollow))
25751 return HOLLOW_BOX_CURSOR;
25752
25753 if (EQ (arg, Qbar))
25754 {
25755 *width = 2;
25756 return BAR_CURSOR;
25757 }
25758
25759 if (CONSP (arg)
25760 && EQ (XCAR (arg), Qbar)
25761 && RANGED_INTEGERP (0, XCDR (arg), INT_MAX))
25762 {
25763 *width = XINT (XCDR (arg));
25764 return BAR_CURSOR;
25765 }
25766
25767 if (EQ (arg, Qhbar))
25768 {
25769 *width = 2;
25770 return HBAR_CURSOR;
25771 }
25772
25773 if (CONSP (arg)
25774 && EQ (XCAR (arg), Qhbar)
25775 && RANGED_INTEGERP (0, XCDR (arg), INT_MAX))
25776 {
25777 *width = XINT (XCDR (arg));
25778 return HBAR_CURSOR;
25779 }
25780
25781 /* Treat anything unknown as "hollow box cursor".
25782 It was bad to signal an error; people have trouble fixing
25783 .Xdefaults with Emacs, when it has something bad in it. */
25784 type = HOLLOW_BOX_CURSOR;
25785
25786 return type;
25787 }
25788
25789 /* Set the default cursor types for specified frame. */
25790 void
25791 set_frame_cursor_types (struct frame *f, Lisp_Object arg)
25792 {
25793 int width = 1;
25794 Lisp_Object tem;
25795
25796 FRAME_DESIRED_CURSOR (f) = get_specified_cursor_type (arg, &width);
25797 FRAME_CURSOR_WIDTH (f) = width;
25798
25799 /* By default, set up the blink-off state depending on the on-state. */
25800
25801 tem = Fassoc (arg, Vblink_cursor_alist);
25802 if (!NILP (tem))
25803 {
25804 FRAME_BLINK_OFF_CURSOR (f)
25805 = get_specified_cursor_type (XCDR (tem), &width);
25806 FRAME_BLINK_OFF_CURSOR_WIDTH (f) = width;
25807 }
25808 else
25809 FRAME_BLINK_OFF_CURSOR (f) = DEFAULT_CURSOR;
25810 }
25811
25812
25813 #ifdef HAVE_WINDOW_SYSTEM
25814
25815 /* Return the cursor we want to be displayed in window W. Return
25816 width of bar/hbar cursor through WIDTH arg. Return with
25817 ACTIVE_CURSOR arg set to 1 if cursor in window W is `active'
25818 (i.e. if the `system caret' should track this cursor).
25819
25820 In a mini-buffer window, we want the cursor only to appear if we
25821 are reading input from this window. For the selected window, we
25822 want the cursor type given by the frame parameter or buffer local
25823 setting of cursor-type. If explicitly marked off, draw no cursor.
25824 In all other cases, we want a hollow box cursor. */
25825
25826 static enum text_cursor_kinds
25827 get_window_cursor_type (struct window *w, struct glyph *glyph, int *width,
25828 int *active_cursor)
25829 {
25830 struct frame *f = XFRAME (w->frame);
25831 struct buffer *b = XBUFFER (w->buffer);
25832 int cursor_type = DEFAULT_CURSOR;
25833 Lisp_Object alt_cursor;
25834 int non_selected = 0;
25835
25836 *active_cursor = 1;
25837
25838 /* Echo area */
25839 if (cursor_in_echo_area
25840 && FRAME_HAS_MINIBUF_P (f)
25841 && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
25842 {
25843 if (w == XWINDOW (echo_area_window))
25844 {
25845 if (EQ (BVAR (b, cursor_type), Qt) || NILP (BVAR (b, cursor_type)))
25846 {
25847 *width = FRAME_CURSOR_WIDTH (f);
25848 return FRAME_DESIRED_CURSOR (f);
25849 }
25850 else
25851 return get_specified_cursor_type (BVAR (b, cursor_type), width);
25852 }
25853
25854 *active_cursor = 0;
25855 non_selected = 1;
25856 }
25857
25858 /* Detect a nonselected window or nonselected frame. */
25859 else if (w != XWINDOW (f->selected_window)
25860 || f != FRAME_X_DISPLAY_INFO (f)->x_highlight_frame)
25861 {
25862 *active_cursor = 0;
25863
25864 if (MINI_WINDOW_P (w) && minibuf_level == 0)
25865 return NO_CURSOR;
25866
25867 non_selected = 1;
25868 }
25869
25870 /* Never display a cursor in a window in which cursor-type is nil. */
25871 if (NILP (BVAR (b, cursor_type)))
25872 return NO_CURSOR;
25873
25874 /* Get the normal cursor type for this window. */
25875 if (EQ (BVAR (b, cursor_type), Qt))
25876 {
25877 cursor_type = FRAME_DESIRED_CURSOR (f);
25878 *width = FRAME_CURSOR_WIDTH (f);
25879 }
25880 else
25881 cursor_type = get_specified_cursor_type (BVAR (b, cursor_type), width);
25882
25883 /* Use cursor-in-non-selected-windows instead
25884 for non-selected window or frame. */
25885 if (non_selected)
25886 {
25887 alt_cursor = BVAR (b, cursor_in_non_selected_windows);
25888 if (!EQ (Qt, alt_cursor))
25889 return get_specified_cursor_type (alt_cursor, width);
25890 /* t means modify the normal cursor type. */
25891 if (cursor_type == FILLED_BOX_CURSOR)
25892 cursor_type = HOLLOW_BOX_CURSOR;
25893 else if (cursor_type == BAR_CURSOR && *width > 1)
25894 --*width;
25895 return cursor_type;
25896 }
25897
25898 /* Use normal cursor if not blinked off. */
25899 if (!w->cursor_off_p)
25900 {
25901
25902 #ifdef HAVE_XWIDGETS
25903 if (glyph != NULL && glyph->type == XWIDGET_GLYPH){
25904 //printf("attempt xwidget cursor avoidance in get_window_cursor_type\n");
25905 return NO_CURSOR;
25906 }
25907 #endif
25908 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
25909 {
25910 if (cursor_type == FILLED_BOX_CURSOR)
25911 {
25912 /* Using a block cursor on large images can be very annoying.
25913 So use a hollow cursor for "large" images.
25914 If image is not transparent (no mask), also use hollow cursor. */
25915 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
25916 if (img != NULL && IMAGEP (img->spec))
25917 {
25918 /* Arbitrarily, interpret "Large" as >32x32 and >NxN
25919 where N = size of default frame font size.
25920 This should cover most of the "tiny" icons people may use. */
25921 if (!img->mask
25922 || img->width > max (32, WINDOW_FRAME_COLUMN_WIDTH (w))
25923 || img->height > max (32, WINDOW_FRAME_LINE_HEIGHT (w)))
25924 cursor_type = HOLLOW_BOX_CURSOR;
25925 }
25926 }
25927 else if (cursor_type != NO_CURSOR)
25928 {
25929 /* Display current only supports BOX and HOLLOW cursors for images.
25930 So for now, unconditionally use a HOLLOW cursor when cursor is
25931 not a solid box cursor. */
25932 cursor_type = HOLLOW_BOX_CURSOR;
25933 }
25934 }
25935 return cursor_type;
25936 }
25937
25938 /* Cursor is blinked off, so determine how to "toggle" it. */
25939
25940 /* First look for an entry matching the buffer's cursor-type in blink-cursor-alist. */
25941 if ((alt_cursor = Fassoc (BVAR (b, cursor_type), Vblink_cursor_alist), !NILP (alt_cursor)))
25942 return get_specified_cursor_type (XCDR (alt_cursor), width);
25943
25944 /* Then see if frame has specified a specific blink off cursor type. */
25945 if (FRAME_BLINK_OFF_CURSOR (f) != DEFAULT_CURSOR)
25946 {
25947 *width = FRAME_BLINK_OFF_CURSOR_WIDTH (f);
25948 return FRAME_BLINK_OFF_CURSOR (f);
25949 }
25950
25951 #if 0
25952 /* Some people liked having a permanently visible blinking cursor,
25953 while others had very strong opinions against it. So it was
25954 decided to remove it. KFS 2003-09-03 */
25955
25956 /* Finally perform built-in cursor blinking:
25957 filled box <-> hollow box
25958 wide [h]bar <-> narrow [h]bar
25959 narrow [h]bar <-> no cursor
25960 other type <-> no cursor */
25961
25962 if (cursor_type == FILLED_BOX_CURSOR)
25963 return HOLLOW_BOX_CURSOR;
25964
25965 if ((cursor_type == BAR_CURSOR || cursor_type == HBAR_CURSOR) && *width > 1)
25966 {
25967 *width = 1;
25968 return cursor_type;
25969 }
25970 #endif
25971
25972 return NO_CURSOR;
25973 }
25974
25975
25976 /* Notice when the text cursor of window W has been completely
25977 overwritten by a drawing operation that outputs glyphs in AREA
25978 starting at X0 and ending at X1 in the line starting at Y0 and
25979 ending at Y1. X coordinates are area-relative. X1 < 0 means all
25980 the rest of the line after X0 has been written. Y coordinates
25981 are window-relative. */
25982
25983 static void
25984 notice_overwritten_cursor (struct window *w, enum glyph_row_area area,
25985 int x0, int x1, int y0, int y1)
25986 {
25987 int cx0, cx1, cy0, cy1;
25988 struct glyph_row *row;
25989
25990 if (!w->phys_cursor_on_p)
25991 return;
25992 if (area != TEXT_AREA)
25993 return;
25994
25995 if (w->phys_cursor.vpos < 0
25996 || w->phys_cursor.vpos >= w->current_matrix->nrows
25997 || (row = w->current_matrix->rows + w->phys_cursor.vpos,
25998 !(row->enabled_p && row->displays_text_p)))
25999 return;
26000
26001 if (row->cursor_in_fringe_p)
26002 {
26003 row->cursor_in_fringe_p = 0;
26004 draw_fringe_bitmap (w, row, row->reversed_p);
26005 w->phys_cursor_on_p = 0;
26006 return;
26007 }
26008
26009 cx0 = w->phys_cursor.x;
26010 cx1 = cx0 + w->phys_cursor_width;
26011 if (x0 > cx0 || (x1 >= 0 && x1 < cx1))
26012 return;
26013
26014 /* The cursor image will be completely removed from the
26015 screen if the output area intersects the cursor area in
26016 y-direction. When we draw in [y0 y1[, and some part of
26017 the cursor is at y < y0, that part must have been drawn
26018 before. When scrolling, the cursor is erased before
26019 actually scrolling, so we don't come here. When not
26020 scrolling, the rows above the old cursor row must have
26021 changed, and in this case these rows must have written
26022 over the cursor image.
26023
26024 Likewise if part of the cursor is below y1, with the
26025 exception of the cursor being in the first blank row at
26026 the buffer and window end because update_text_area
26027 doesn't draw that row. (Except when it does, but
26028 that's handled in update_text_area.) */
26029
26030 cy0 = w->phys_cursor.y;
26031 cy1 = cy0 + w->phys_cursor_height;
26032 if ((y0 < cy0 || y0 >= cy1) && (y1 <= cy0 || y1 >= cy1))
26033 return;
26034
26035 w->phys_cursor_on_p = 0;
26036 }
26037
26038 #endif /* HAVE_WINDOW_SYSTEM */
26039
26040 \f
26041 /************************************************************************
26042 Mouse Face
26043 ************************************************************************/
26044
26045 #ifdef HAVE_WINDOW_SYSTEM
26046
26047 /* EXPORT for RIF:
26048 Fix the display of area AREA of overlapping row ROW in window W
26049 with respect to the overlapping part OVERLAPS. */
26050
26051 void
26052 x_fix_overlapping_area (struct window *w, struct glyph_row *row,
26053 enum glyph_row_area area, int overlaps)
26054 {
26055 int i, x;
26056
26057 BLOCK_INPUT;
26058
26059 x = 0;
26060 for (i = 0; i < row->used[area];)
26061 {
26062 if (row->glyphs[area][i].overlaps_vertically_p)
26063 {
26064 int start = i, start_x = x;
26065
26066 do
26067 {
26068 x += row->glyphs[area][i].pixel_width;
26069 ++i;
26070 }
26071 while (i < row->used[area]
26072 && row->glyphs[area][i].overlaps_vertically_p);
26073
26074 draw_glyphs (w, start_x, row, area,
26075 start, i,
26076 DRAW_NORMAL_TEXT, overlaps);
26077 }
26078 else
26079 {
26080 x += row->glyphs[area][i].pixel_width;
26081 ++i;
26082 }
26083 }
26084
26085 UNBLOCK_INPUT;
26086 }
26087
26088
26089 /* EXPORT:
26090 Draw the cursor glyph of window W in glyph row ROW. See the
26091 comment of draw_glyphs for the meaning of HL. */
26092
26093 void
26094 draw_phys_cursor_glyph (struct window *w, struct glyph_row *row,
26095 enum draw_glyphs_face hl)
26096 {
26097 /* If cursor hpos is out of bounds, don't draw garbage. This can
26098 happen in mini-buffer windows when switching between echo area
26099 glyphs and mini-buffer. */
26100 if ((row->reversed_p
26101 ? (w->phys_cursor.hpos >= 0)
26102 : (w->phys_cursor.hpos < row->used[TEXT_AREA])))
26103 {
26104 int on_p = w->phys_cursor_on_p;
26105 int x1;
26106 int hpos = w->phys_cursor.hpos;
26107
26108 /* When the window is hscrolled, cursor hpos can legitimately be
26109 out of bounds, but we draw the cursor at the corresponding
26110 window margin in that case. */
26111 if (!row->reversed_p && hpos < 0)
26112 hpos = 0;
26113 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
26114 hpos = row->used[TEXT_AREA] - 1;
26115
26116 x1 = draw_glyphs (w, w->phys_cursor.x, row, TEXT_AREA, hpos, hpos + 1,
26117 hl, 0);
26118 w->phys_cursor_on_p = on_p;
26119
26120 if (hl == DRAW_CURSOR)
26121 w->phys_cursor_width = x1 - w->phys_cursor.x;
26122 /* When we erase the cursor, and ROW is overlapped by other
26123 rows, make sure that these overlapping parts of other rows
26124 are redrawn. */
26125 else if (hl == DRAW_NORMAL_TEXT && row->overlapped_p)
26126 {
26127 w->phys_cursor_width = x1 - w->phys_cursor.x;
26128
26129 if (row > w->current_matrix->rows
26130 && MATRIX_ROW_OVERLAPS_SUCC_P (row - 1))
26131 x_fix_overlapping_area (w, row - 1, TEXT_AREA,
26132 OVERLAPS_ERASED_CURSOR);
26133
26134 if (MATRIX_ROW_BOTTOM_Y (row) < window_text_bottom_y (w)
26135 && MATRIX_ROW_OVERLAPS_PRED_P (row + 1))
26136 x_fix_overlapping_area (w, row + 1, TEXT_AREA,
26137 OVERLAPS_ERASED_CURSOR);
26138 }
26139 }
26140 }
26141
26142
26143 /* EXPORT:
26144 Erase the image of a cursor of window W from the screen. */
26145
26146 void
26147 erase_phys_cursor (struct window *w)
26148 {
26149 struct frame *f = XFRAME (w->frame);
26150 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
26151 int hpos = w->phys_cursor.hpos;
26152 int vpos = w->phys_cursor.vpos;
26153 int mouse_face_here_p = 0;
26154 struct glyph_matrix *active_glyphs = w->current_matrix;
26155 struct glyph_row *cursor_row;
26156 struct glyph *cursor_glyph;
26157 enum draw_glyphs_face hl;
26158
26159 /* No cursor displayed or row invalidated => nothing to do on the
26160 screen. */
26161 if (w->phys_cursor_type == NO_CURSOR)
26162 goto mark_cursor_off;
26163
26164 /* VPOS >= active_glyphs->nrows means that window has been resized.
26165 Don't bother to erase the cursor. */
26166 if (vpos >= active_glyphs->nrows)
26167 goto mark_cursor_off;
26168
26169 /* If row containing cursor is marked invalid, there is nothing we
26170 can do. */
26171 cursor_row = MATRIX_ROW (active_glyphs, vpos);
26172 if (!cursor_row->enabled_p)
26173 goto mark_cursor_off;
26174
26175 /* If line spacing is > 0, old cursor may only be partially visible in
26176 window after split-window. So adjust visible height. */
26177 cursor_row->visible_height = min (cursor_row->visible_height,
26178 window_text_bottom_y (w) - cursor_row->y);
26179
26180 /* If row is completely invisible, don't attempt to delete a cursor which
26181 isn't there. This can happen if cursor is at top of a window, and
26182 we switch to a buffer with a header line in that window. */
26183 if (cursor_row->visible_height <= 0)
26184 goto mark_cursor_off;
26185
26186 /* If cursor is in the fringe, erase by drawing actual bitmap there. */
26187 if (cursor_row->cursor_in_fringe_p)
26188 {
26189 cursor_row->cursor_in_fringe_p = 0;
26190 draw_fringe_bitmap (w, cursor_row, cursor_row->reversed_p);
26191 goto mark_cursor_off;
26192 }
26193
26194 /* This can happen when the new row is shorter than the old one.
26195 In this case, either draw_glyphs or clear_end_of_line
26196 should have cleared the cursor. Note that we wouldn't be
26197 able to erase the cursor in this case because we don't have a
26198 cursor glyph at hand. */
26199 if ((cursor_row->reversed_p
26200 ? (w->phys_cursor.hpos < 0)
26201 : (w->phys_cursor.hpos >= cursor_row->used[TEXT_AREA])))
26202 goto mark_cursor_off;
26203
26204 /* When the window is hscrolled, cursor hpos can legitimately be out
26205 of bounds, but we draw the cursor at the corresponding window
26206 margin in that case. */
26207 if (!cursor_row->reversed_p && hpos < 0)
26208 hpos = 0;
26209 if (cursor_row->reversed_p && hpos >= cursor_row->used[TEXT_AREA])
26210 hpos = cursor_row->used[TEXT_AREA] - 1;
26211
26212 /* If the cursor is in the mouse face area, redisplay that when
26213 we clear the cursor. */
26214 if (! NILP (hlinfo->mouse_face_window)
26215 && coords_in_mouse_face_p (w, hpos, vpos)
26216 /* Don't redraw the cursor's spot in mouse face if it is at the
26217 end of a line (on a newline). The cursor appears there, but
26218 mouse highlighting does not. */
26219 && cursor_row->used[TEXT_AREA] > hpos && hpos >= 0)
26220 mouse_face_here_p = 1;
26221
26222 /* Maybe clear the display under the cursor. */
26223 if (w->phys_cursor_type == HOLLOW_BOX_CURSOR)
26224 {
26225 int x, y, left_x;
26226 int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
26227 int width;
26228
26229 cursor_glyph = get_phys_cursor_glyph (w);
26230 if (cursor_glyph == NULL)
26231 goto mark_cursor_off;
26232
26233 width = cursor_glyph->pixel_width;
26234 left_x = window_box_left_offset (w, TEXT_AREA);
26235 x = w->phys_cursor.x;
26236 if (x < left_x)
26237 width -= left_x - x;
26238 width = min (width, window_box_width (w, TEXT_AREA) - x);
26239 y = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, cursor_row->y));
26240 x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, max (x, left_x));
26241
26242 if (width > 0)
26243 FRAME_RIF (f)->clear_frame_area (f, x, y, width, cursor_row->visible_height);
26244 }
26245
26246 /* Erase the cursor by redrawing the character underneath it. */
26247 if (mouse_face_here_p)
26248 hl = DRAW_MOUSE_FACE;
26249 else
26250 hl = DRAW_NORMAL_TEXT;
26251 draw_phys_cursor_glyph (w, cursor_row, hl);
26252
26253 mark_cursor_off:
26254 w->phys_cursor_on_p = 0;
26255 w->phys_cursor_type = NO_CURSOR;
26256 }
26257
26258
26259 /* EXPORT:
26260 Display or clear cursor of window W. If ON is zero, clear the
26261 cursor. If it is non-zero, display the cursor. If ON is nonzero,
26262 where to put the cursor is specified by HPOS, VPOS, X and Y. */
26263
26264 void
26265 display_and_set_cursor (struct window *w, int on,
26266 int hpos, int vpos, int x, int y)
26267 {
26268 struct frame *f = XFRAME (w->frame);
26269 int new_cursor_type;
26270 int new_cursor_width;
26271 int active_cursor;
26272 struct glyph_row *glyph_row;
26273 struct glyph *glyph;
26274
26275 /* This is pointless on invisible frames, and dangerous on garbaged
26276 windows and frames; in the latter case, the frame or window may
26277 be in the midst of changing its size, and x and y may be off the
26278 window. */
26279 if (! FRAME_VISIBLE_P (f)
26280 || FRAME_GARBAGED_P (f)
26281 || vpos >= w->current_matrix->nrows
26282 || hpos >= w->current_matrix->matrix_w)
26283 return;
26284
26285 /* If cursor is off and we want it off, return quickly. */
26286 if (!on && !w->phys_cursor_on_p)
26287 return;
26288
26289 glyph_row = MATRIX_ROW (w->current_matrix, vpos);
26290 /* If cursor row is not enabled, we don't really know where to
26291 display the cursor. */
26292 if (!glyph_row->enabled_p)
26293 {
26294 w->phys_cursor_on_p = 0;
26295 return;
26296 }
26297
26298 glyph = NULL;
26299 if (!glyph_row->exact_window_width_line_p
26300 || (0 <= hpos && hpos < glyph_row->used[TEXT_AREA]))
26301 glyph = glyph_row->glyphs[TEXT_AREA] + hpos;
26302
26303 eassert (interrupt_input_blocked);
26304
26305 /* Set new_cursor_type to the cursor we want to be displayed. */
26306 new_cursor_type = get_window_cursor_type (w, glyph,
26307 &new_cursor_width, &active_cursor);
26308
26309 /* If cursor is currently being shown and we don't want it to be or
26310 it is in the wrong place, or the cursor type is not what we want,
26311 erase it. */
26312 if (w->phys_cursor_on_p
26313 && (!on
26314 || w->phys_cursor.x != x
26315 || w->phys_cursor.y != y
26316 || new_cursor_type != w->phys_cursor_type
26317 || ((new_cursor_type == BAR_CURSOR || new_cursor_type == HBAR_CURSOR)
26318 && new_cursor_width != w->phys_cursor_width)))
26319 erase_phys_cursor (w);
26320
26321 /* Don't check phys_cursor_on_p here because that flag is only set
26322 to zero in some cases where we know that the cursor has been
26323 completely erased, to avoid the extra work of erasing the cursor
26324 twice. In other words, phys_cursor_on_p can be 1 and the cursor
26325 still not be visible, or it has only been partly erased. */
26326 if (on)
26327 {
26328 w->phys_cursor_ascent = glyph_row->ascent;
26329 w->phys_cursor_height = glyph_row->height;
26330
26331 /* Set phys_cursor_.* before x_draw_.* is called because some
26332 of them may need the information. */
26333 w->phys_cursor.x = x;
26334 w->phys_cursor.y = glyph_row->y;
26335 w->phys_cursor.hpos = hpos;
26336 w->phys_cursor.vpos = vpos;
26337 }
26338
26339 FRAME_RIF (f)->draw_window_cursor (w, glyph_row, x, y,
26340 new_cursor_type, new_cursor_width,
26341 on, active_cursor);
26342 }
26343
26344
26345 /* Switch the display of W's cursor on or off, according to the value
26346 of ON. */
26347
26348 static void
26349 update_window_cursor (struct window *w, int on)
26350 {
26351 /* Don't update cursor in windows whose frame is in the process
26352 of being deleted. */
26353 if (w->current_matrix)
26354 {
26355 int hpos = w->phys_cursor.hpos;
26356 int vpos = w->phys_cursor.vpos;
26357 struct glyph_row *row;
26358
26359 if (vpos >= w->current_matrix->nrows
26360 || hpos >= w->current_matrix->matrix_w)
26361 return;
26362
26363 row = MATRIX_ROW (w->current_matrix, vpos);
26364
26365 /* When the window is hscrolled, cursor hpos can legitimately be
26366 out of bounds, but we draw the cursor at the corresponding
26367 window margin in that case. */
26368 if (!row->reversed_p && hpos < 0)
26369 hpos = 0;
26370 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
26371 hpos = row->used[TEXT_AREA] - 1;
26372
26373 BLOCK_INPUT;
26374 display_and_set_cursor (w, on, hpos, vpos,
26375 w->phys_cursor.x, w->phys_cursor.y);
26376 UNBLOCK_INPUT;
26377 }
26378 }
26379
26380
26381 /* Call update_window_cursor with parameter ON_P on all leaf windows
26382 in the window tree rooted at W. */
26383
26384 static void
26385 update_cursor_in_window_tree (struct window *w, int on_p)
26386 {
26387 while (w)
26388 {
26389 if (!NILP (w->hchild))
26390 update_cursor_in_window_tree (XWINDOW (w->hchild), on_p);
26391 else if (!NILP (w->vchild))
26392 update_cursor_in_window_tree (XWINDOW (w->vchild), on_p);
26393 else
26394 update_window_cursor (w, on_p);
26395
26396 w = NILP (w->next) ? 0 : XWINDOW (w->next);
26397 }
26398 }
26399
26400
26401 /* EXPORT:
26402 Display the cursor on window W, or clear it, according to ON_P.
26403 Don't change the cursor's position. */
26404
26405 void
26406 x_update_cursor (struct frame *f, int on_p)
26407 {
26408 update_cursor_in_window_tree (XWINDOW (f->root_window), on_p);
26409 }
26410
26411
26412 /* EXPORT:
26413 Clear the cursor of window W to background color, and mark the
26414 cursor as not shown. This is used when the text where the cursor
26415 is about to be rewritten. */
26416
26417 void
26418 x_clear_cursor (struct window *w)
26419 {
26420 if (FRAME_VISIBLE_P (XFRAME (w->frame)) && w->phys_cursor_on_p)
26421 update_window_cursor (w, 0);
26422 }
26423
26424 #endif /* HAVE_WINDOW_SYSTEM */
26425
26426 /* Implementation of draw_row_with_mouse_face for GUI sessions, GPM,
26427 and MSDOS. */
26428 static void
26429 draw_row_with_mouse_face (struct window *w, int start_x, struct glyph_row *row,
26430 int start_hpos, int end_hpos,
26431 enum draw_glyphs_face draw)
26432 {
26433 #ifdef HAVE_WINDOW_SYSTEM
26434 if (FRAME_WINDOW_P (XFRAME (w->frame)))
26435 {
26436 draw_glyphs (w, start_x, row, TEXT_AREA, start_hpos, end_hpos, draw, 0);
26437 return;
26438 }
26439 #endif
26440 #if defined (HAVE_GPM) || defined (MSDOS) || defined (WINDOWSNT)
26441 tty_draw_row_with_mouse_face (w, row, start_hpos, end_hpos, draw);
26442 #endif
26443 }
26444
26445 /* Display the active region described by mouse_face_* according to DRAW. */
26446
26447 static void
26448 show_mouse_face (Mouse_HLInfo *hlinfo, enum draw_glyphs_face draw)
26449 {
26450 struct window *w = XWINDOW (hlinfo->mouse_face_window);
26451 struct frame *f = XFRAME (WINDOW_FRAME (w));
26452
26453 if (/* If window is in the process of being destroyed, don't bother
26454 to do anything. */
26455 w->current_matrix != NULL
26456 /* Don't update mouse highlight if hidden */
26457 && (draw != DRAW_MOUSE_FACE || !hlinfo->mouse_face_hidden)
26458 /* Recognize when we are called to operate on rows that don't exist
26459 anymore. This can happen when a window is split. */
26460 && hlinfo->mouse_face_end_row < w->current_matrix->nrows)
26461 {
26462 int phys_cursor_on_p = w->phys_cursor_on_p;
26463 struct glyph_row *row, *first, *last;
26464
26465 first = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_beg_row);
26466 last = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_end_row);
26467
26468 for (row = first; row <= last && row->enabled_p; ++row)
26469 {
26470 int start_hpos, end_hpos, start_x;
26471
26472 /* For all but the first row, the highlight starts at column 0. */
26473 if (row == first)
26474 {
26475 /* R2L rows have BEG and END in reversed order, but the
26476 screen drawing geometry is always left to right. So
26477 we need to mirror the beginning and end of the
26478 highlighted area in R2L rows. */
26479 if (!row->reversed_p)
26480 {
26481 start_hpos = hlinfo->mouse_face_beg_col;
26482 start_x = hlinfo->mouse_face_beg_x;
26483 }
26484 else if (row == last)
26485 {
26486 start_hpos = hlinfo->mouse_face_end_col;
26487 start_x = hlinfo->mouse_face_end_x;
26488 }
26489 else
26490 {
26491 start_hpos = 0;
26492 start_x = 0;
26493 }
26494 }
26495 else if (row->reversed_p && row == last)
26496 {
26497 start_hpos = hlinfo->mouse_face_end_col;
26498 start_x = hlinfo->mouse_face_end_x;
26499 }
26500 else
26501 {
26502 start_hpos = 0;
26503 start_x = 0;
26504 }
26505
26506 if (row == last)
26507 {
26508 if (!row->reversed_p)
26509 end_hpos = hlinfo->mouse_face_end_col;
26510 else if (row == first)
26511 end_hpos = hlinfo->mouse_face_beg_col;
26512 else
26513 {
26514 end_hpos = row->used[TEXT_AREA];
26515 if (draw == DRAW_NORMAL_TEXT)
26516 row->fill_line_p = 1; /* Clear to end of line */
26517 }
26518 }
26519 else if (row->reversed_p && row == first)
26520 end_hpos = hlinfo->mouse_face_beg_col;
26521 else
26522 {
26523 end_hpos = row->used[TEXT_AREA];
26524 if (draw == DRAW_NORMAL_TEXT)
26525 row->fill_line_p = 1; /* Clear to end of line */
26526 }
26527
26528 if (end_hpos > start_hpos)
26529 {
26530 draw_row_with_mouse_face (w, start_x, row,
26531 start_hpos, end_hpos, draw);
26532
26533 row->mouse_face_p
26534 = draw == DRAW_MOUSE_FACE || draw == DRAW_IMAGE_RAISED;
26535 }
26536 }
26537
26538 #ifdef HAVE_WINDOW_SYSTEM
26539 /* When we've written over the cursor, arrange for it to
26540 be displayed again. */
26541 if (FRAME_WINDOW_P (f)
26542 && phys_cursor_on_p && !w->phys_cursor_on_p)
26543 {
26544 int hpos = w->phys_cursor.hpos;
26545
26546 /* When the window is hscrolled, cursor hpos can legitimately be
26547 out of bounds, but we draw the cursor at the corresponding
26548 window margin in that case. */
26549 if (!row->reversed_p && hpos < 0)
26550 hpos = 0;
26551 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
26552 hpos = row->used[TEXT_AREA] - 1;
26553
26554 BLOCK_INPUT;
26555 display_and_set_cursor (w, 1, hpos, w->phys_cursor.vpos,
26556 w->phys_cursor.x, w->phys_cursor.y);
26557 UNBLOCK_INPUT;
26558 }
26559 #endif /* HAVE_WINDOW_SYSTEM */
26560 }
26561
26562 #ifdef HAVE_WINDOW_SYSTEM
26563 /* Change the mouse cursor. */
26564 if (FRAME_WINDOW_P (f))
26565 {
26566 if (draw == DRAW_NORMAL_TEXT
26567 && !EQ (hlinfo->mouse_face_window, f->tool_bar_window))
26568 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->text_cursor);
26569 else if (draw == DRAW_MOUSE_FACE)
26570 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->hand_cursor);
26571 else
26572 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->nontext_cursor);
26573 }
26574 #endif /* HAVE_WINDOW_SYSTEM */
26575 }
26576
26577 /* EXPORT:
26578 Clear out the mouse-highlighted active region.
26579 Redraw it un-highlighted first. Value is non-zero if mouse
26580 face was actually drawn unhighlighted. */
26581
26582 int
26583 clear_mouse_face (Mouse_HLInfo *hlinfo)
26584 {
26585 int cleared = 0;
26586
26587 if (!hlinfo->mouse_face_hidden && !NILP (hlinfo->mouse_face_window))
26588 {
26589 show_mouse_face (hlinfo, DRAW_NORMAL_TEXT);
26590 cleared = 1;
26591 }
26592
26593 hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
26594 hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
26595 hlinfo->mouse_face_window = Qnil;
26596 hlinfo->mouse_face_overlay = Qnil;
26597 return cleared;
26598 }
26599
26600 /* Return non-zero if the coordinates HPOS and VPOS on windows W are
26601 within the mouse face on that window. */
26602 static int
26603 coords_in_mouse_face_p (struct window *w, int hpos, int vpos)
26604 {
26605 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame));
26606
26607 /* Quickly resolve the easy cases. */
26608 if (!(WINDOWP (hlinfo->mouse_face_window)
26609 && XWINDOW (hlinfo->mouse_face_window) == w))
26610 return 0;
26611 if (vpos < hlinfo->mouse_face_beg_row
26612 || vpos > hlinfo->mouse_face_end_row)
26613 return 0;
26614 if (vpos > hlinfo->mouse_face_beg_row
26615 && vpos < hlinfo->mouse_face_end_row)
26616 return 1;
26617
26618 if (!MATRIX_ROW (w->current_matrix, vpos)->reversed_p)
26619 {
26620 if (hlinfo->mouse_face_beg_row == hlinfo->mouse_face_end_row)
26621 {
26622 if (hlinfo->mouse_face_beg_col <= hpos && hpos < hlinfo->mouse_face_end_col)
26623 return 1;
26624 }
26625 else if ((vpos == hlinfo->mouse_face_beg_row
26626 && hpos >= hlinfo->mouse_face_beg_col)
26627 || (vpos == hlinfo->mouse_face_end_row
26628 && hpos < hlinfo->mouse_face_end_col))
26629 return 1;
26630 }
26631 else
26632 {
26633 if (hlinfo->mouse_face_beg_row == hlinfo->mouse_face_end_row)
26634 {
26635 if (hlinfo->mouse_face_end_col < hpos && hpos <= hlinfo->mouse_face_beg_col)
26636 return 1;
26637 }
26638 else if ((vpos == hlinfo->mouse_face_beg_row
26639 && hpos <= hlinfo->mouse_face_beg_col)
26640 || (vpos == hlinfo->mouse_face_end_row
26641 && hpos > hlinfo->mouse_face_end_col))
26642 return 1;
26643 }
26644 return 0;
26645 }
26646
26647
26648 /* EXPORT:
26649 Non-zero if physical cursor of window W is within mouse face. */
26650
26651 int
26652 cursor_in_mouse_face_p (struct window *w)
26653 {
26654 int hpos = w->phys_cursor.hpos;
26655 int vpos = w->phys_cursor.vpos;
26656 struct glyph_row *row = MATRIX_ROW (w->current_matrix, vpos);
26657
26658 /* When the window is hscrolled, cursor hpos can legitimately be out
26659 of bounds, but we draw the cursor at the corresponding window
26660 margin in that case. */
26661 if (!row->reversed_p && hpos < 0)
26662 hpos = 0;
26663 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
26664 hpos = row->used[TEXT_AREA] - 1;
26665
26666 return coords_in_mouse_face_p (w, hpos, vpos);
26667 }
26668
26669
26670 \f
26671 /* Find the glyph rows START_ROW and END_ROW of window W that display
26672 characters between buffer positions START_CHARPOS and END_CHARPOS
26673 (excluding END_CHARPOS). DISP_STRING is a display string that
26674 covers these buffer positions. This is similar to
26675 row_containing_pos, but is more accurate when bidi reordering makes
26676 buffer positions change non-linearly with glyph rows. */
26677 static void
26678 rows_from_pos_range (struct window *w,
26679 ptrdiff_t start_charpos, ptrdiff_t end_charpos,
26680 Lisp_Object disp_string,
26681 struct glyph_row **start, struct glyph_row **end)
26682 {
26683 struct glyph_row *first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
26684 int last_y = window_text_bottom_y (w);
26685 struct glyph_row *row;
26686
26687 *start = NULL;
26688 *end = NULL;
26689
26690 while (!first->enabled_p
26691 && first < MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w))
26692 first++;
26693
26694 /* Find the START row. */
26695 for (row = first;
26696 row->enabled_p && MATRIX_ROW_BOTTOM_Y (row) <= last_y;
26697 row++)
26698 {
26699 /* A row can potentially be the START row if the range of the
26700 characters it displays intersects the range
26701 [START_CHARPOS..END_CHARPOS). */
26702 if (! ((start_charpos < MATRIX_ROW_START_CHARPOS (row)
26703 && end_charpos < MATRIX_ROW_START_CHARPOS (row))
26704 /* See the commentary in row_containing_pos, for the
26705 explanation of the complicated way to check whether
26706 some position is beyond the end of the characters
26707 displayed by a row. */
26708 || ((start_charpos > MATRIX_ROW_END_CHARPOS (row)
26709 || (start_charpos == MATRIX_ROW_END_CHARPOS (row)
26710 && !row->ends_at_zv_p
26711 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
26712 && (end_charpos > MATRIX_ROW_END_CHARPOS (row)
26713 || (end_charpos == MATRIX_ROW_END_CHARPOS (row)
26714 && !row->ends_at_zv_p
26715 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))))))
26716 {
26717 /* Found a candidate row. Now make sure at least one of the
26718 glyphs it displays has a charpos from the range
26719 [START_CHARPOS..END_CHARPOS).
26720
26721 This is not obvious because bidi reordering could make
26722 buffer positions of a row be 1,2,3,102,101,100, and if we
26723 want to highlight characters in [50..60), we don't want
26724 this row, even though [50..60) does intersect [1..103),
26725 the range of character positions given by the row's start
26726 and end positions. */
26727 struct glyph *g = row->glyphs[TEXT_AREA];
26728 struct glyph *e = g + row->used[TEXT_AREA];
26729
26730 while (g < e)
26731 {
26732 if (((BUFFERP (g->object) || INTEGERP (g->object))
26733 && start_charpos <= g->charpos && g->charpos < end_charpos)
26734 /* A glyph that comes from DISP_STRING is by
26735 definition to be highlighted. */
26736 || EQ (g->object, disp_string))
26737 *start = row;
26738 g++;
26739 }
26740 if (*start)
26741 break;
26742 }
26743 }
26744
26745 /* Find the END row. */
26746 if (!*start
26747 /* If the last row is partially visible, start looking for END
26748 from that row, instead of starting from FIRST. */
26749 && !(row->enabled_p
26750 && row->y < last_y && MATRIX_ROW_BOTTOM_Y (row) > last_y))
26751 row = first;
26752 for ( ; row->enabled_p && MATRIX_ROW_BOTTOM_Y (row) <= last_y; row++)
26753 {
26754 struct glyph_row *next = row + 1;
26755 ptrdiff_t next_start = MATRIX_ROW_START_CHARPOS (next);
26756
26757 if (!next->enabled_p
26758 || next >= MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w)
26759 /* The first row >= START whose range of displayed characters
26760 does NOT intersect the range [START_CHARPOS..END_CHARPOS]
26761 is the row END + 1. */
26762 || (start_charpos < next_start
26763 && end_charpos < next_start)
26764 || ((start_charpos > MATRIX_ROW_END_CHARPOS (next)
26765 || (start_charpos == MATRIX_ROW_END_CHARPOS (next)
26766 && !next->ends_at_zv_p
26767 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (next)))
26768 && (end_charpos > MATRIX_ROW_END_CHARPOS (next)
26769 || (end_charpos == MATRIX_ROW_END_CHARPOS (next)
26770 && !next->ends_at_zv_p
26771 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (next)))))
26772 {
26773 *end = row;
26774 break;
26775 }
26776 else
26777 {
26778 /* If the next row's edges intersect [START_CHARPOS..END_CHARPOS],
26779 but none of the characters it displays are in the range, it is
26780 also END + 1. */
26781 struct glyph *g = next->glyphs[TEXT_AREA];
26782 struct glyph *s = g;
26783 struct glyph *e = g + next->used[TEXT_AREA];
26784
26785 while (g < e)
26786 {
26787 if (((BUFFERP (g->object) || INTEGERP (g->object))
26788 && ((start_charpos <= g->charpos && g->charpos < end_charpos)
26789 /* If the buffer position of the first glyph in
26790 the row is equal to END_CHARPOS, it means
26791 the last character to be highlighted is the
26792 newline of ROW, and we must consider NEXT as
26793 END, not END+1. */
26794 || (((!next->reversed_p && g == s)
26795 || (next->reversed_p && g == e - 1))
26796 && (g->charpos == end_charpos
26797 /* Special case for when NEXT is an
26798 empty line at ZV. */
26799 || (g->charpos == -1
26800 && !row->ends_at_zv_p
26801 && next_start == end_charpos)))))
26802 /* A glyph that comes from DISP_STRING is by
26803 definition to be highlighted. */
26804 || EQ (g->object, disp_string))
26805 break;
26806 g++;
26807 }
26808 if (g == e)
26809 {
26810 *end = row;
26811 break;
26812 }
26813 /* The first row that ends at ZV must be the last to be
26814 highlighted. */
26815 else if (next->ends_at_zv_p)
26816 {
26817 *end = next;
26818 break;
26819 }
26820 }
26821 }
26822 }
26823
26824 /* This function sets the mouse_face_* elements of HLINFO, assuming
26825 the mouse cursor is on a glyph with buffer charpos MOUSE_CHARPOS in
26826 window WINDOW. START_CHARPOS and END_CHARPOS are buffer positions
26827 for the overlay or run of text properties specifying the mouse
26828 face. BEFORE_STRING and AFTER_STRING, if non-nil, are a
26829 before-string and after-string that must also be highlighted.
26830 DISP_STRING, if non-nil, is a display string that may cover some
26831 or all of the highlighted text. */
26832
26833 static void
26834 mouse_face_from_buffer_pos (Lisp_Object window,
26835 Mouse_HLInfo *hlinfo,
26836 ptrdiff_t mouse_charpos,
26837 ptrdiff_t start_charpos,
26838 ptrdiff_t end_charpos,
26839 Lisp_Object before_string,
26840 Lisp_Object after_string,
26841 Lisp_Object disp_string)
26842 {
26843 struct window *w = XWINDOW (window);
26844 struct glyph_row *first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
26845 struct glyph_row *r1, *r2;
26846 struct glyph *glyph, *end;
26847 ptrdiff_t ignore, pos;
26848 int x;
26849
26850 eassert (NILP (disp_string) || STRINGP (disp_string));
26851 eassert (NILP (before_string) || STRINGP (before_string));
26852 eassert (NILP (after_string) || STRINGP (after_string));
26853
26854 /* Find the rows corresponding to START_CHARPOS and END_CHARPOS. */
26855 rows_from_pos_range (w, start_charpos, end_charpos, disp_string, &r1, &r2);
26856 if (r1 == NULL)
26857 r1 = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
26858 /* If the before-string or display-string contains newlines,
26859 rows_from_pos_range skips to its last row. Move back. */
26860 if (!NILP (before_string) || !NILP (disp_string))
26861 {
26862 struct glyph_row *prev;
26863 while ((prev = r1 - 1, prev >= first)
26864 && MATRIX_ROW_END_CHARPOS (prev) == start_charpos
26865 && prev->used[TEXT_AREA] > 0)
26866 {
26867 struct glyph *beg = prev->glyphs[TEXT_AREA];
26868 glyph = beg + prev->used[TEXT_AREA];
26869 while (--glyph >= beg && INTEGERP (glyph->object));
26870 if (glyph < beg
26871 || !(EQ (glyph->object, before_string)
26872 || EQ (glyph->object, disp_string)))
26873 break;
26874 r1 = prev;
26875 }
26876 }
26877 if (r2 == NULL)
26878 {
26879 r2 = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
26880 hlinfo->mouse_face_past_end = 1;
26881 }
26882 else if (!NILP (after_string))
26883 {
26884 /* If the after-string has newlines, advance to its last row. */
26885 struct glyph_row *next;
26886 struct glyph_row *last
26887 = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
26888
26889 for (next = r2 + 1;
26890 next <= last
26891 && next->used[TEXT_AREA] > 0
26892 && EQ (next->glyphs[TEXT_AREA]->object, after_string);
26893 ++next)
26894 r2 = next;
26895 }
26896 /* The rest of the display engine assumes that mouse_face_beg_row is
26897 either above mouse_face_end_row or identical to it. But with
26898 bidi-reordered continued lines, the row for START_CHARPOS could
26899 be below the row for END_CHARPOS. If so, swap the rows and store
26900 them in correct order. */
26901 if (r1->y > r2->y)
26902 {
26903 struct glyph_row *tem = r2;
26904
26905 r2 = r1;
26906 r1 = tem;
26907 }
26908
26909 hlinfo->mouse_face_beg_y = r1->y;
26910 hlinfo->mouse_face_beg_row = MATRIX_ROW_VPOS (r1, w->current_matrix);
26911 hlinfo->mouse_face_end_y = r2->y;
26912 hlinfo->mouse_face_end_row = MATRIX_ROW_VPOS (r2, w->current_matrix);
26913
26914 /* For a bidi-reordered row, the positions of BEFORE_STRING,
26915 AFTER_STRING, DISP_STRING, START_CHARPOS, and END_CHARPOS
26916 could be anywhere in the row and in any order. The strategy
26917 below is to find the leftmost and the rightmost glyph that
26918 belongs to either of these 3 strings, or whose position is
26919 between START_CHARPOS and END_CHARPOS, and highlight all the
26920 glyphs between those two. This may cover more than just the text
26921 between START_CHARPOS and END_CHARPOS if the range of characters
26922 strides the bidi level boundary, e.g. if the beginning is in R2L
26923 text while the end is in L2R text or vice versa. */
26924 if (!r1->reversed_p)
26925 {
26926 /* This row is in a left to right paragraph. Scan it left to
26927 right. */
26928 glyph = r1->glyphs[TEXT_AREA];
26929 end = glyph + r1->used[TEXT_AREA];
26930 x = r1->x;
26931
26932 /* Skip truncation glyphs at the start of the glyph row. */
26933 if (r1->displays_text_p)
26934 for (; glyph < end
26935 && INTEGERP (glyph->object)
26936 && glyph->charpos < 0;
26937 ++glyph)
26938 x += glyph->pixel_width;
26939
26940 /* Scan the glyph row, looking for BEFORE_STRING, AFTER_STRING,
26941 or DISP_STRING, and the first glyph from buffer whose
26942 position is between START_CHARPOS and END_CHARPOS. */
26943 for (; glyph < end
26944 && !INTEGERP (glyph->object)
26945 && !EQ (glyph->object, disp_string)
26946 && !(BUFFERP (glyph->object)
26947 && (glyph->charpos >= start_charpos
26948 && glyph->charpos < end_charpos));
26949 ++glyph)
26950 {
26951 /* BEFORE_STRING or AFTER_STRING are only relevant if they
26952 are present at buffer positions between START_CHARPOS and
26953 END_CHARPOS, or if they come from an overlay. */
26954 if (EQ (glyph->object, before_string))
26955 {
26956 pos = string_buffer_position (before_string,
26957 start_charpos);
26958 /* If pos == 0, it means before_string came from an
26959 overlay, not from a buffer position. */
26960 if (!pos || (pos >= start_charpos && pos < end_charpos))
26961 break;
26962 }
26963 else if (EQ (glyph->object, after_string))
26964 {
26965 pos = string_buffer_position (after_string, end_charpos);
26966 if (!pos || (pos >= start_charpos && pos < end_charpos))
26967 break;
26968 }
26969 x += glyph->pixel_width;
26970 }
26971 hlinfo->mouse_face_beg_x = x;
26972 hlinfo->mouse_face_beg_col = glyph - r1->glyphs[TEXT_AREA];
26973 }
26974 else
26975 {
26976 /* This row is in a right to left paragraph. Scan it right to
26977 left. */
26978 struct glyph *g;
26979
26980 end = r1->glyphs[TEXT_AREA] - 1;
26981 glyph = end + r1->used[TEXT_AREA];
26982
26983 /* Skip truncation glyphs at the start of the glyph row. */
26984 if (r1->displays_text_p)
26985 for (; glyph > end
26986 && INTEGERP (glyph->object)
26987 && glyph->charpos < 0;
26988 --glyph)
26989 ;
26990
26991 /* Scan the glyph row, looking for BEFORE_STRING, AFTER_STRING,
26992 or DISP_STRING, and the first glyph from buffer whose
26993 position is between START_CHARPOS and END_CHARPOS. */
26994 for (; glyph > end
26995 && !INTEGERP (glyph->object)
26996 && !EQ (glyph->object, disp_string)
26997 && !(BUFFERP (glyph->object)
26998 && (glyph->charpos >= start_charpos
26999 && glyph->charpos < end_charpos));
27000 --glyph)
27001 {
27002 /* BEFORE_STRING or AFTER_STRING are only relevant if they
27003 are present at buffer positions between START_CHARPOS and
27004 END_CHARPOS, or if they come from an overlay. */
27005 if (EQ (glyph->object, before_string))
27006 {
27007 pos = string_buffer_position (before_string, start_charpos);
27008 /* If pos == 0, it means before_string came from an
27009 overlay, not from a buffer position. */
27010 if (!pos || (pos >= start_charpos && pos < end_charpos))
27011 break;
27012 }
27013 else if (EQ (glyph->object, after_string))
27014 {
27015 pos = string_buffer_position (after_string, end_charpos);
27016 if (!pos || (pos >= start_charpos && pos < end_charpos))
27017 break;
27018 }
27019 }
27020
27021 glyph++; /* first glyph to the right of the highlighted area */
27022 for (g = r1->glyphs[TEXT_AREA], x = r1->x; g < glyph; g++)
27023 x += g->pixel_width;
27024 hlinfo->mouse_face_beg_x = x;
27025 hlinfo->mouse_face_beg_col = glyph - r1->glyphs[TEXT_AREA];
27026 }
27027
27028 /* If the highlight ends in a different row, compute GLYPH and END
27029 for the end row. Otherwise, reuse the values computed above for
27030 the row where the highlight begins. */
27031 if (r2 != r1)
27032 {
27033 if (!r2->reversed_p)
27034 {
27035 glyph = r2->glyphs[TEXT_AREA];
27036 end = glyph + r2->used[TEXT_AREA];
27037 x = r2->x;
27038 }
27039 else
27040 {
27041 end = r2->glyphs[TEXT_AREA] - 1;
27042 glyph = end + r2->used[TEXT_AREA];
27043 }
27044 }
27045
27046 if (!r2->reversed_p)
27047 {
27048 /* Skip truncation and continuation glyphs near the end of the
27049 row, and also blanks and stretch glyphs inserted by
27050 extend_face_to_end_of_line. */
27051 while (end > glyph
27052 && INTEGERP ((end - 1)->object))
27053 --end;
27054 /* Scan the rest of the glyph row from the end, looking for the
27055 first glyph that comes from BEFORE_STRING, AFTER_STRING, or
27056 DISP_STRING, or whose position is between START_CHARPOS
27057 and END_CHARPOS */
27058 for (--end;
27059 end > glyph
27060 && !INTEGERP (end->object)
27061 && !EQ (end->object, disp_string)
27062 && !(BUFFERP (end->object)
27063 && (end->charpos >= start_charpos
27064 && end->charpos < end_charpos));
27065 --end)
27066 {
27067 /* BEFORE_STRING or AFTER_STRING are only relevant if they
27068 are present at buffer positions between START_CHARPOS and
27069 END_CHARPOS, or if they come from an overlay. */
27070 if (EQ (end->object, before_string))
27071 {
27072 pos = string_buffer_position (before_string, start_charpos);
27073 if (!pos || (pos >= start_charpos && pos < end_charpos))
27074 break;
27075 }
27076 else if (EQ (end->object, after_string))
27077 {
27078 pos = string_buffer_position (after_string, end_charpos);
27079 if (!pos || (pos >= start_charpos && pos < end_charpos))
27080 break;
27081 }
27082 }
27083 /* Find the X coordinate of the last glyph to be highlighted. */
27084 for (; glyph <= end; ++glyph)
27085 x += glyph->pixel_width;
27086
27087 hlinfo->mouse_face_end_x = x;
27088 hlinfo->mouse_face_end_col = glyph - r2->glyphs[TEXT_AREA];
27089 }
27090 else
27091 {
27092 /* Skip truncation and continuation glyphs near the end of the
27093 row, and also blanks and stretch glyphs inserted by
27094 extend_face_to_end_of_line. */
27095 x = r2->x;
27096 end++;
27097 while (end < glyph
27098 && INTEGERP (end->object))
27099 {
27100 x += end->pixel_width;
27101 ++end;
27102 }
27103 /* Scan the rest of the glyph row from the end, looking for the
27104 first glyph that comes from BEFORE_STRING, AFTER_STRING, or
27105 DISP_STRING, or whose position is between START_CHARPOS
27106 and END_CHARPOS */
27107 for ( ;
27108 end < glyph
27109 && !INTEGERP (end->object)
27110 && !EQ (end->object, disp_string)
27111 && !(BUFFERP (end->object)
27112 && (end->charpos >= start_charpos
27113 && end->charpos < end_charpos));
27114 ++end)
27115 {
27116 /* BEFORE_STRING or AFTER_STRING are only relevant if they
27117 are present at buffer positions between START_CHARPOS and
27118 END_CHARPOS, or if they come from an overlay. */
27119 if (EQ (end->object, before_string))
27120 {
27121 pos = string_buffer_position (before_string, start_charpos);
27122 if (!pos || (pos >= start_charpos && pos < end_charpos))
27123 break;
27124 }
27125 else if (EQ (end->object, after_string))
27126 {
27127 pos = string_buffer_position (after_string, end_charpos);
27128 if (!pos || (pos >= start_charpos && pos < end_charpos))
27129 break;
27130 }
27131 x += end->pixel_width;
27132 }
27133 /* If we exited the above loop because we arrived at the last
27134 glyph of the row, and its buffer position is still not in
27135 range, it means the last character in range is the preceding
27136 newline. Bump the end column and x values to get past the
27137 last glyph. */
27138 if (end == glyph
27139 && BUFFERP (end->object)
27140 && (end->charpos < start_charpos
27141 || end->charpos >= end_charpos))
27142 {
27143 x += end->pixel_width;
27144 ++end;
27145 }
27146 hlinfo->mouse_face_end_x = x;
27147 hlinfo->mouse_face_end_col = end - r2->glyphs[TEXT_AREA];
27148 }
27149
27150 hlinfo->mouse_face_window = window;
27151 hlinfo->mouse_face_face_id
27152 = face_at_buffer_position (w, mouse_charpos, 0, 0, &ignore,
27153 mouse_charpos + 1,
27154 !hlinfo->mouse_face_hidden, -1);
27155 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
27156 }
27157
27158 /* The following function is not used anymore (replaced with
27159 mouse_face_from_string_pos), but I leave it here for the time
27160 being, in case someone would. */
27161
27162 #if 0 /* not used */
27163
27164 /* Find the position of the glyph for position POS in OBJECT in
27165 window W's current matrix, and return in *X, *Y the pixel
27166 coordinates, and return in *HPOS, *VPOS the column/row of the glyph.
27167
27168 RIGHT_P non-zero means return the position of the right edge of the
27169 glyph, RIGHT_P zero means return the left edge position.
27170
27171 If no glyph for POS exists in the matrix, return the position of
27172 the glyph with the next smaller position that is in the matrix, if
27173 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS
27174 exists in the matrix, return the position of the glyph with the
27175 next larger position in OBJECT.
27176
27177 Value is non-zero if a glyph was found. */
27178
27179 static int
27180 fast_find_string_pos (struct window *w, ptrdiff_t pos, Lisp_Object object,
27181 int *hpos, int *vpos, int *x, int *y, int right_p)
27182 {
27183 int yb = window_text_bottom_y (w);
27184 struct glyph_row *r;
27185 struct glyph *best_glyph = NULL;
27186 struct glyph_row *best_row = NULL;
27187 int best_x = 0;
27188
27189 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
27190 r->enabled_p && r->y < yb;
27191 ++r)
27192 {
27193 struct glyph *g = r->glyphs[TEXT_AREA];
27194 struct glyph *e = g + r->used[TEXT_AREA];
27195 int gx;
27196
27197 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
27198 if (EQ (g->object, object))
27199 {
27200 if (g->charpos == pos)
27201 {
27202 best_glyph = g;
27203 best_x = gx;
27204 best_row = r;
27205 goto found;
27206 }
27207 else if (best_glyph == NULL
27208 || ((eabs (g->charpos - pos)
27209 < eabs (best_glyph->charpos - pos))
27210 && (right_p
27211 ? g->charpos < pos
27212 : g->charpos > pos)))
27213 {
27214 best_glyph = g;
27215 best_x = gx;
27216 best_row = r;
27217 }
27218 }
27219 }
27220
27221 found:
27222
27223 if (best_glyph)
27224 {
27225 *x = best_x;
27226 *hpos = best_glyph - best_row->glyphs[TEXT_AREA];
27227
27228 if (right_p)
27229 {
27230 *x += best_glyph->pixel_width;
27231 ++*hpos;
27232 }
27233
27234 *y = best_row->y;
27235 *vpos = best_row - w->current_matrix->rows;
27236 }
27237
27238 return best_glyph != NULL;
27239 }
27240 #endif /* not used */
27241
27242 /* Find the positions of the first and the last glyphs in window W's
27243 current matrix that occlude positions [STARTPOS..ENDPOS] in OBJECT
27244 (assumed to be a string), and return in HLINFO's mouse_face_*
27245 members the pixel and column/row coordinates of those glyphs. */
27246
27247 static void
27248 mouse_face_from_string_pos (struct window *w, Mouse_HLInfo *hlinfo,
27249 Lisp_Object object,
27250 ptrdiff_t startpos, ptrdiff_t endpos)
27251 {
27252 int yb = window_text_bottom_y (w);
27253 struct glyph_row *r;
27254 struct glyph *g, *e;
27255 int gx;
27256 int found = 0;
27257
27258 /* Find the glyph row with at least one position in the range
27259 [STARTPOS..ENDPOS], and the first glyph in that row whose
27260 position belongs to that range. */
27261 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
27262 r->enabled_p && r->y < yb;
27263 ++r)
27264 {
27265 if (!r->reversed_p)
27266 {
27267 g = r->glyphs[TEXT_AREA];
27268 e = g + r->used[TEXT_AREA];
27269 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
27270 if (EQ (g->object, object)
27271 && startpos <= g->charpos && g->charpos <= endpos)
27272 {
27273 hlinfo->mouse_face_beg_row = r - w->current_matrix->rows;
27274 hlinfo->mouse_face_beg_y = r->y;
27275 hlinfo->mouse_face_beg_col = g - r->glyphs[TEXT_AREA];
27276 hlinfo->mouse_face_beg_x = gx;
27277 found = 1;
27278 break;
27279 }
27280 }
27281 else
27282 {
27283 struct glyph *g1;
27284
27285 e = r->glyphs[TEXT_AREA];
27286 g = e + r->used[TEXT_AREA];
27287 for ( ; g > e; --g)
27288 if (EQ ((g-1)->object, object)
27289 && startpos <= (g-1)->charpos && (g-1)->charpos <= endpos)
27290 {
27291 hlinfo->mouse_face_beg_row = r - w->current_matrix->rows;
27292 hlinfo->mouse_face_beg_y = r->y;
27293 hlinfo->mouse_face_beg_col = g - r->glyphs[TEXT_AREA];
27294 for (gx = r->x, g1 = r->glyphs[TEXT_AREA]; g1 < g; ++g1)
27295 gx += g1->pixel_width;
27296 hlinfo->mouse_face_beg_x = gx;
27297 found = 1;
27298 break;
27299 }
27300 }
27301 if (found)
27302 break;
27303 }
27304
27305 if (!found)
27306 return;
27307
27308 /* Starting with the next row, look for the first row which does NOT
27309 include any glyphs whose positions are in the range. */
27310 for (++r; r->enabled_p && r->y < yb; ++r)
27311 {
27312 g = r->glyphs[TEXT_AREA];
27313 e = g + r->used[TEXT_AREA];
27314 found = 0;
27315 for ( ; g < e; ++g)
27316 if (EQ (g->object, object)
27317 && startpos <= g->charpos && g->charpos <= endpos)
27318 {
27319 found = 1;
27320 break;
27321 }
27322 if (!found)
27323 break;
27324 }
27325
27326 /* The highlighted region ends on the previous row. */
27327 r--;
27328
27329 /* Set the end row and its vertical pixel coordinate. */
27330 hlinfo->mouse_face_end_row = r - w->current_matrix->rows;
27331 hlinfo->mouse_face_end_y = r->y;
27332
27333 /* Compute and set the end column and the end column's horizontal
27334 pixel coordinate. */
27335 if (!r->reversed_p)
27336 {
27337 g = r->glyphs[TEXT_AREA];
27338 e = g + r->used[TEXT_AREA];
27339 for ( ; e > g; --e)
27340 if (EQ ((e-1)->object, object)
27341 && startpos <= (e-1)->charpos && (e-1)->charpos <= endpos)
27342 break;
27343 hlinfo->mouse_face_end_col = e - g;
27344
27345 for (gx = r->x; g < e; ++g)
27346 gx += g->pixel_width;
27347 hlinfo->mouse_face_end_x = gx;
27348 }
27349 else
27350 {
27351 e = r->glyphs[TEXT_AREA];
27352 g = e + r->used[TEXT_AREA];
27353 for (gx = r->x ; e < g; ++e)
27354 {
27355 if (EQ (e->object, object)
27356 && startpos <= e->charpos && e->charpos <= endpos)
27357 break;
27358 gx += e->pixel_width;
27359 }
27360 hlinfo->mouse_face_end_col = e - r->glyphs[TEXT_AREA];
27361 hlinfo->mouse_face_end_x = gx;
27362 }
27363 }
27364
27365 #ifdef HAVE_WINDOW_SYSTEM
27366
27367 /* See if position X, Y is within a hot-spot of an image. */
27368
27369 static int
27370 on_hot_spot_p (Lisp_Object hot_spot, int x, int y)
27371 {
27372 if (!CONSP (hot_spot))
27373 return 0;
27374
27375 if (EQ (XCAR (hot_spot), Qrect))
27376 {
27377 /* CDR is (Top-Left . Bottom-Right) = ((x0 . y0) . (x1 . y1)) */
27378 Lisp_Object rect = XCDR (hot_spot);
27379 Lisp_Object tem;
27380 if (!CONSP (rect))
27381 return 0;
27382 if (!CONSP (XCAR (rect)))
27383 return 0;
27384 if (!CONSP (XCDR (rect)))
27385 return 0;
27386 if (!(tem = XCAR (XCAR (rect)), INTEGERP (tem) && x >= XINT (tem)))
27387 return 0;
27388 if (!(tem = XCDR (XCAR (rect)), INTEGERP (tem) && y >= XINT (tem)))
27389 return 0;
27390 if (!(tem = XCAR (XCDR (rect)), INTEGERP (tem) && x <= XINT (tem)))
27391 return 0;
27392 if (!(tem = XCDR (XCDR (rect)), INTEGERP (tem) && y <= XINT (tem)))
27393 return 0;
27394 return 1;
27395 }
27396 else if (EQ (XCAR (hot_spot), Qcircle))
27397 {
27398 /* CDR is (Center . Radius) = ((x0 . y0) . r) */
27399 Lisp_Object circ = XCDR (hot_spot);
27400 Lisp_Object lr, lx0, ly0;
27401 if (CONSP (circ)
27402 && CONSP (XCAR (circ))
27403 && (lr = XCDR (circ), INTEGERP (lr) || FLOATP (lr))
27404 && (lx0 = XCAR (XCAR (circ)), INTEGERP (lx0))
27405 && (ly0 = XCDR (XCAR (circ)), INTEGERP (ly0)))
27406 {
27407 double r = XFLOATINT (lr);
27408 double dx = XINT (lx0) - x;
27409 double dy = XINT (ly0) - y;
27410 return (dx * dx + dy * dy <= r * r);
27411 }
27412 }
27413 else if (EQ (XCAR (hot_spot), Qpoly))
27414 {
27415 /* CDR is [x0 y0 x1 y1 x2 y2 ...x(n-1) y(n-1)] */
27416 if (VECTORP (XCDR (hot_spot)))
27417 {
27418 struct Lisp_Vector *v = XVECTOR (XCDR (hot_spot));
27419 Lisp_Object *poly = v->contents;
27420 ptrdiff_t n = v->header.size;
27421 ptrdiff_t i;
27422 int inside = 0;
27423 Lisp_Object lx, ly;
27424 int x0, y0;
27425
27426 /* Need an even number of coordinates, and at least 3 edges. */
27427 if (n < 6 || n & 1)
27428 return 0;
27429
27430 /* Count edge segments intersecting line from (X,Y) to (X,infinity).
27431 If count is odd, we are inside polygon. Pixels on edges
27432 may or may not be included depending on actual geometry of the
27433 polygon. */
27434 if ((lx = poly[n-2], !INTEGERP (lx))
27435 || (ly = poly[n-1], !INTEGERP (lx)))
27436 return 0;
27437 x0 = XINT (lx), y0 = XINT (ly);
27438 for (i = 0; i < n; i += 2)
27439 {
27440 int x1 = x0, y1 = y0;
27441 if ((lx = poly[i], !INTEGERP (lx))
27442 || (ly = poly[i+1], !INTEGERP (ly)))
27443 return 0;
27444 x0 = XINT (lx), y0 = XINT (ly);
27445
27446 /* Does this segment cross the X line? */
27447 if (x0 >= x)
27448 {
27449 if (x1 >= x)
27450 continue;
27451 }
27452 else if (x1 < x)
27453 continue;
27454 if (y > y0 && y > y1)
27455 continue;
27456 if (y < y0 + ((y1 - y0) * (x - x0)) / (x1 - x0))
27457 inside = !inside;
27458 }
27459 return inside;
27460 }
27461 }
27462 return 0;
27463 }
27464
27465 Lisp_Object
27466 find_hot_spot (Lisp_Object map, int x, int y)
27467 {
27468 while (CONSP (map))
27469 {
27470 if (CONSP (XCAR (map))
27471 && on_hot_spot_p (XCAR (XCAR (map)), x, y))
27472 return XCAR (map);
27473 map = XCDR (map);
27474 }
27475
27476 return Qnil;
27477 }
27478
27479 DEFUN ("lookup-image-map", Flookup_image_map, Slookup_image_map,
27480 3, 3, 0,
27481 doc: /* Lookup in image map MAP coordinates X and Y.
27482 An image map is an alist where each element has the format (AREA ID PLIST).
27483 An AREA is specified as either a rectangle, a circle, or a polygon:
27484 A rectangle is a cons (rect . ((x0 . y0) . (x1 . y1))) specifying the
27485 pixel coordinates of the upper left and bottom right corners.
27486 A circle is a cons (circle . ((x0 . y0) . r)) specifying the center
27487 and the radius of the circle; r may be a float or integer.
27488 A polygon is a cons (poly . [x0 y0 x1 y1 ...]) where each pair in the
27489 vector describes one corner in the polygon.
27490 Returns the alist element for the first matching AREA in MAP. */)
27491 (Lisp_Object map, Lisp_Object x, Lisp_Object y)
27492 {
27493 if (NILP (map))
27494 return Qnil;
27495
27496 CHECK_NUMBER (x);
27497 CHECK_NUMBER (y);
27498
27499 return find_hot_spot (map,
27500 clip_to_bounds (INT_MIN, XINT (x), INT_MAX),
27501 clip_to_bounds (INT_MIN, XINT (y), INT_MAX));
27502 }
27503
27504
27505 /* Display frame CURSOR, optionally using shape defined by POINTER. */
27506 static void
27507 define_frame_cursor1 (struct frame *f, Cursor cursor, Lisp_Object pointer)
27508 {
27509 /* Do not change cursor shape while dragging mouse. */
27510 if (!NILP (do_mouse_tracking))
27511 return;
27512
27513 if (!NILP (pointer))
27514 {
27515 if (EQ (pointer, Qarrow))
27516 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
27517 else if (EQ (pointer, Qhand))
27518 cursor = FRAME_X_OUTPUT (f)->hand_cursor;
27519 else if (EQ (pointer, Qtext))
27520 cursor = FRAME_X_OUTPUT (f)->text_cursor;
27521 else if (EQ (pointer, intern ("hdrag")))
27522 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
27523 #ifdef HAVE_X_WINDOWS
27524 else if (EQ (pointer, intern ("vdrag")))
27525 cursor = FRAME_X_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
27526 #endif
27527 else if (EQ (pointer, intern ("hourglass")))
27528 cursor = FRAME_X_OUTPUT (f)->hourglass_cursor;
27529 else if (EQ (pointer, Qmodeline))
27530 cursor = FRAME_X_OUTPUT (f)->modeline_cursor;
27531 else
27532 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
27533 }
27534
27535 if (cursor != No_Cursor)
27536 FRAME_RIF (f)->define_frame_cursor (f, cursor);
27537 }
27538
27539 #endif /* HAVE_WINDOW_SYSTEM */
27540
27541 /* Take proper action when mouse has moved to the mode or header line
27542 or marginal area AREA of window W, x-position X and y-position Y.
27543 X is relative to the start of the text display area of W, so the
27544 width of bitmap areas and scroll bars must be subtracted to get a
27545 position relative to the start of the mode line. */
27546
27547 static void
27548 note_mode_line_or_margin_highlight (Lisp_Object window, int x, int y,
27549 enum window_part area)
27550 {
27551 struct window *w = XWINDOW (window);
27552 struct frame *f = XFRAME (w->frame);
27553 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
27554 #ifdef HAVE_WINDOW_SYSTEM
27555 Display_Info *dpyinfo;
27556 #endif
27557 Cursor cursor = No_Cursor;
27558 Lisp_Object pointer = Qnil;
27559 int dx, dy, width, height;
27560 ptrdiff_t charpos;
27561 Lisp_Object string, object = Qnil;
27562 Lisp_Object pos IF_LINT (= Qnil), help;
27563
27564 Lisp_Object mouse_face;
27565 int original_x_pixel = x;
27566 struct glyph * glyph = NULL, * row_start_glyph = NULL;
27567 struct glyph_row *row IF_LINT (= 0);
27568
27569 if (area == ON_MODE_LINE || area == ON_HEADER_LINE)
27570 {
27571 int x0;
27572 struct glyph *end;
27573
27574 /* Kludge alert: mode_line_string takes X/Y in pixels, but
27575 returns them in row/column units! */
27576 string = mode_line_string (w, area, &x, &y, &charpos,
27577 &object, &dx, &dy, &width, &height);
27578
27579 row = (area == ON_MODE_LINE
27580 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
27581 : MATRIX_HEADER_LINE_ROW (w->current_matrix));
27582
27583 /* Find the glyph under the mouse pointer. */
27584 if (row->mode_line_p && row->enabled_p)
27585 {
27586 glyph = row_start_glyph = row->glyphs[TEXT_AREA];
27587 end = glyph + row->used[TEXT_AREA];
27588
27589 for (x0 = original_x_pixel;
27590 glyph < end && x0 >= glyph->pixel_width;
27591 ++glyph)
27592 x0 -= glyph->pixel_width;
27593
27594 if (glyph >= end)
27595 glyph = NULL;
27596 }
27597 }
27598 else
27599 {
27600 x -= WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
27601 /* Kludge alert: marginal_area_string takes X/Y in pixels, but
27602 returns them in row/column units! */
27603 string = marginal_area_string (w, area, &x, &y, &charpos,
27604 &object, &dx, &dy, &width, &height);
27605 }
27606
27607 help = Qnil;
27608
27609 #ifdef HAVE_WINDOW_SYSTEM
27610 if (IMAGEP (object))
27611 {
27612 Lisp_Object image_map, hotspot;
27613 if ((image_map = Fplist_get (XCDR (object), QCmap),
27614 !NILP (image_map))
27615 && (hotspot = find_hot_spot (image_map, dx, dy),
27616 CONSP (hotspot))
27617 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
27618 {
27619 Lisp_Object plist;
27620
27621 /* Could check XCAR (hotspot) to see if we enter/leave this hot-spot.
27622 If so, we could look for mouse-enter, mouse-leave
27623 properties in PLIST (and do something...). */
27624 hotspot = XCDR (hotspot);
27625 if (CONSP (hotspot)
27626 && (plist = XCAR (hotspot), CONSP (plist)))
27627 {
27628 pointer = Fplist_get (plist, Qpointer);
27629 if (NILP (pointer))
27630 pointer = Qhand;
27631 help = Fplist_get (plist, Qhelp_echo);
27632 if (!NILP (help))
27633 {
27634 help_echo_string = help;
27635 XSETWINDOW (help_echo_window, w);
27636 help_echo_object = w->buffer;
27637 help_echo_pos = charpos;
27638 }
27639 }
27640 }
27641 if (NILP (pointer))
27642 pointer = Fplist_get (XCDR (object), QCpointer);
27643 }
27644 #endif /* HAVE_WINDOW_SYSTEM */
27645
27646 if (STRINGP (string))
27647 pos = make_number (charpos);
27648
27649 /* Set the help text and mouse pointer. If the mouse is on a part
27650 of the mode line without any text (e.g. past the right edge of
27651 the mode line text), use the default help text and pointer. */
27652 if (STRINGP (string) || area == ON_MODE_LINE)
27653 {
27654 /* Arrange to display the help by setting the global variables
27655 help_echo_string, help_echo_object, and help_echo_pos. */
27656 if (NILP (help))
27657 {
27658 if (STRINGP (string))
27659 help = Fget_text_property (pos, Qhelp_echo, string);
27660
27661 if (!NILP (help))
27662 {
27663 help_echo_string = help;
27664 XSETWINDOW (help_echo_window, w);
27665 help_echo_object = string;
27666 help_echo_pos = charpos;
27667 }
27668 else if (area == ON_MODE_LINE)
27669 {
27670 Lisp_Object default_help
27671 = buffer_local_value_1 (Qmode_line_default_help_echo,
27672 w->buffer);
27673
27674 if (STRINGP (default_help))
27675 {
27676 help_echo_string = default_help;
27677 XSETWINDOW (help_echo_window, w);
27678 help_echo_object = Qnil;
27679 help_echo_pos = -1;
27680 }
27681 }
27682 }
27683
27684 #ifdef HAVE_WINDOW_SYSTEM
27685 /* Change the mouse pointer according to what is under it. */
27686 if (FRAME_WINDOW_P (f))
27687 {
27688 dpyinfo = FRAME_X_DISPLAY_INFO (f);
27689 if (STRINGP (string))
27690 {
27691 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
27692
27693 if (NILP (pointer))
27694 pointer = Fget_text_property (pos, Qpointer, string);
27695
27696 /* Change the mouse pointer according to what is under X/Y. */
27697 if (NILP (pointer)
27698 && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE)))
27699 {
27700 Lisp_Object map;
27701 map = Fget_text_property (pos, Qlocal_map, string);
27702 if (!KEYMAPP (map))
27703 map = Fget_text_property (pos, Qkeymap, string);
27704 if (!KEYMAPP (map))
27705 cursor = dpyinfo->vertical_scroll_bar_cursor;
27706 }
27707 }
27708 else
27709 /* Default mode-line pointer. */
27710 cursor = FRAME_X_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
27711 }
27712 #endif
27713 }
27714
27715 /* Change the mouse face according to what is under X/Y. */
27716 if (STRINGP (string))
27717 {
27718 mouse_face = Fget_text_property (pos, Qmouse_face, string);
27719 if (!NILP (mouse_face)
27720 && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE))
27721 && glyph)
27722 {
27723 Lisp_Object b, e;
27724
27725 struct glyph * tmp_glyph;
27726
27727 int gpos;
27728 int gseq_length;
27729 int total_pixel_width;
27730 ptrdiff_t begpos, endpos, ignore;
27731
27732 int vpos, hpos;
27733
27734 b = Fprevious_single_property_change (make_number (charpos + 1),
27735 Qmouse_face, string, Qnil);
27736 if (NILP (b))
27737 begpos = 0;
27738 else
27739 begpos = XINT (b);
27740
27741 e = Fnext_single_property_change (pos, Qmouse_face, string, Qnil);
27742 if (NILP (e))
27743 endpos = SCHARS (string);
27744 else
27745 endpos = XINT (e);
27746
27747 /* Calculate the glyph position GPOS of GLYPH in the
27748 displayed string, relative to the beginning of the
27749 highlighted part of the string.
27750
27751 Note: GPOS is different from CHARPOS. CHARPOS is the
27752 position of GLYPH in the internal string object. A mode
27753 line string format has structures which are converted to
27754 a flattened string by the Emacs Lisp interpreter. The
27755 internal string is an element of those structures. The
27756 displayed string is the flattened string. */
27757 tmp_glyph = row_start_glyph;
27758 while (tmp_glyph < glyph
27759 && (!(EQ (tmp_glyph->object, glyph->object)
27760 && begpos <= tmp_glyph->charpos
27761 && tmp_glyph->charpos < endpos)))
27762 tmp_glyph++;
27763 gpos = glyph - tmp_glyph;
27764
27765 /* Calculate the length GSEQ_LENGTH of the glyph sequence of
27766 the highlighted part of the displayed string to which
27767 GLYPH belongs. Note: GSEQ_LENGTH is different from
27768 SCHARS (STRING), because the latter returns the length of
27769 the internal string. */
27770 for (tmp_glyph = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
27771 tmp_glyph > glyph
27772 && (!(EQ (tmp_glyph->object, glyph->object)
27773 && begpos <= tmp_glyph->charpos
27774 && tmp_glyph->charpos < endpos));
27775 tmp_glyph--)
27776 ;
27777 gseq_length = gpos + (tmp_glyph - glyph) + 1;
27778
27779 /* Calculate the total pixel width of all the glyphs between
27780 the beginning of the highlighted area and GLYPH. */
27781 total_pixel_width = 0;
27782 for (tmp_glyph = glyph - gpos; tmp_glyph != glyph; tmp_glyph++)
27783 total_pixel_width += tmp_glyph->pixel_width;
27784
27785 /* Pre calculation of re-rendering position. Note: X is in
27786 column units here, after the call to mode_line_string or
27787 marginal_area_string. */
27788 hpos = x - gpos;
27789 vpos = (area == ON_MODE_LINE
27790 ? (w->current_matrix)->nrows - 1
27791 : 0);
27792
27793 /* If GLYPH's position is included in the region that is
27794 already drawn in mouse face, we have nothing to do. */
27795 if ( EQ (window, hlinfo->mouse_face_window)
27796 && (!row->reversed_p
27797 ? (hlinfo->mouse_face_beg_col <= hpos
27798 && hpos < hlinfo->mouse_face_end_col)
27799 /* In R2L rows we swap BEG and END, see below. */
27800 : (hlinfo->mouse_face_end_col <= hpos
27801 && hpos < hlinfo->mouse_face_beg_col))
27802 && hlinfo->mouse_face_beg_row == vpos )
27803 return;
27804
27805 if (clear_mouse_face (hlinfo))
27806 cursor = No_Cursor;
27807
27808 if (!row->reversed_p)
27809 {
27810 hlinfo->mouse_face_beg_col = hpos;
27811 hlinfo->mouse_face_beg_x = original_x_pixel
27812 - (total_pixel_width + dx);
27813 hlinfo->mouse_face_end_col = hpos + gseq_length;
27814 hlinfo->mouse_face_end_x = 0;
27815 }
27816 else
27817 {
27818 /* In R2L rows, show_mouse_face expects BEG and END
27819 coordinates to be swapped. */
27820 hlinfo->mouse_face_end_col = hpos;
27821 hlinfo->mouse_face_end_x = original_x_pixel
27822 - (total_pixel_width + dx);
27823 hlinfo->mouse_face_beg_col = hpos + gseq_length;
27824 hlinfo->mouse_face_beg_x = 0;
27825 }
27826
27827 hlinfo->mouse_face_beg_row = vpos;
27828 hlinfo->mouse_face_end_row = hlinfo->mouse_face_beg_row;
27829 hlinfo->mouse_face_beg_y = 0;
27830 hlinfo->mouse_face_end_y = 0;
27831 hlinfo->mouse_face_past_end = 0;
27832 hlinfo->mouse_face_window = window;
27833
27834 hlinfo->mouse_face_face_id = face_at_string_position (w, string,
27835 charpos,
27836 0, 0, 0,
27837 &ignore,
27838 glyph->face_id,
27839 1);
27840 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
27841
27842 if (NILP (pointer))
27843 pointer = Qhand;
27844 }
27845 else if ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE))
27846 clear_mouse_face (hlinfo);
27847 }
27848 #ifdef HAVE_WINDOW_SYSTEM
27849 if (FRAME_WINDOW_P (f))
27850 define_frame_cursor1 (f, cursor, pointer);
27851 #endif
27852 }
27853
27854
27855 /* EXPORT:
27856 Take proper action when the mouse has moved to position X, Y on
27857 frame F as regards highlighting characters that have mouse-face
27858 properties. Also de-highlighting chars where the mouse was before.
27859 X and Y can be negative or out of range. */
27860
27861 void
27862 note_mouse_highlight (struct frame *f, int x, int y)
27863 {
27864 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
27865 enum window_part part = ON_NOTHING;
27866 Lisp_Object window;
27867 struct window *w;
27868 Cursor cursor = No_Cursor;
27869 Lisp_Object pointer = Qnil; /* Takes precedence over cursor! */
27870 struct buffer *b;
27871
27872 /* When a menu is active, don't highlight because this looks odd. */
27873 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS) || defined (MSDOS)
27874 if (popup_activated ())
27875 return;
27876 #endif
27877
27878 if (NILP (Vmouse_highlight)
27879 || !f->glyphs_initialized_p
27880 || f->pointer_invisible)
27881 return;
27882
27883 hlinfo->mouse_face_mouse_x = x;
27884 hlinfo->mouse_face_mouse_y = y;
27885 hlinfo->mouse_face_mouse_frame = f;
27886
27887 if (hlinfo->mouse_face_defer)
27888 return;
27889
27890 if (gc_in_progress)
27891 {
27892 hlinfo->mouse_face_deferred_gc = 1;
27893 return;
27894 }
27895
27896 /* Which window is that in? */
27897 window = window_from_coordinates (f, x, y, &part, 1);
27898
27899 /* If displaying active text in another window, clear that. */
27900 if (! EQ (window, hlinfo->mouse_face_window)
27901 /* Also clear if we move out of text area in same window. */
27902 || (!NILP (hlinfo->mouse_face_window)
27903 && !NILP (window)
27904 && part != ON_TEXT
27905 && part != ON_MODE_LINE
27906 && part != ON_HEADER_LINE))
27907 clear_mouse_face (hlinfo);
27908
27909 /* Not on a window -> return. */
27910 if (!WINDOWP (window))
27911 return;
27912
27913 /* Reset help_echo_string. It will get recomputed below. */
27914 help_echo_string = Qnil;
27915
27916 /* Convert to window-relative pixel coordinates. */
27917 w = XWINDOW (window);
27918 frame_to_window_pixel_xy (w, &x, &y);
27919
27920 #ifdef HAVE_WINDOW_SYSTEM
27921 /* Handle tool-bar window differently since it doesn't display a
27922 buffer. */
27923 if (EQ (window, f->tool_bar_window))
27924 {
27925 note_tool_bar_highlight (f, x, y);
27926 return;
27927 }
27928 #endif
27929
27930 /* Mouse is on the mode, header line or margin? */
27931 if (part == ON_MODE_LINE || part == ON_HEADER_LINE
27932 || part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
27933 {
27934 note_mode_line_or_margin_highlight (window, x, y, part);
27935 return;
27936 }
27937
27938 #ifdef HAVE_WINDOW_SYSTEM
27939 if (part == ON_VERTICAL_BORDER)
27940 {
27941 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
27942 help_echo_string = build_string ("drag-mouse-1: resize");
27943 }
27944 else if (part == ON_LEFT_FRINGE || part == ON_RIGHT_FRINGE
27945 || part == ON_SCROLL_BAR)
27946 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
27947 else
27948 cursor = FRAME_X_OUTPUT (f)->text_cursor;
27949 #endif
27950
27951 /* Are we in a window whose display is up to date?
27952 And verify the buffer's text has not changed. */
27953 b = XBUFFER (w->buffer);
27954 if (part == ON_TEXT
27955 && EQ (w->window_end_valid, w->buffer)
27956 && w->last_modified == BUF_MODIFF (b)
27957 && w->last_overlay_modified == BUF_OVERLAY_MODIFF (b))
27958 {
27959 int hpos, vpos, dx, dy, area = LAST_AREA;
27960 ptrdiff_t pos;
27961 struct glyph *glyph;
27962 Lisp_Object object;
27963 Lisp_Object mouse_face = Qnil, position;
27964 Lisp_Object *overlay_vec = NULL;
27965 ptrdiff_t i, noverlays;
27966 struct buffer *obuf;
27967 ptrdiff_t obegv, ozv;
27968 int same_region;
27969
27970 /* Find the glyph under X/Y. */
27971 glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, &dx, &dy, &area);
27972
27973 #ifdef HAVE_WINDOW_SYSTEM
27974 /* Look for :pointer property on image. */
27975 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
27976 {
27977 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
27978 if (img != NULL && IMAGEP (img->spec))
27979 {
27980 Lisp_Object image_map, hotspot;
27981 if ((image_map = Fplist_get (XCDR (img->spec), QCmap),
27982 !NILP (image_map))
27983 && (hotspot = find_hot_spot (image_map,
27984 glyph->slice.img.x + dx,
27985 glyph->slice.img.y + dy),
27986 CONSP (hotspot))
27987 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
27988 {
27989 Lisp_Object plist;
27990
27991 /* Could check XCAR (hotspot) to see if we enter/leave
27992 this hot-spot.
27993 If so, we could look for mouse-enter, mouse-leave
27994 properties in PLIST (and do something...). */
27995 hotspot = XCDR (hotspot);
27996 if (CONSP (hotspot)
27997 && (plist = XCAR (hotspot), CONSP (plist)))
27998 {
27999 pointer = Fplist_get (plist, Qpointer);
28000 if (NILP (pointer))
28001 pointer = Qhand;
28002 help_echo_string = Fplist_get (plist, Qhelp_echo);
28003 if (!NILP (help_echo_string))
28004 {
28005 help_echo_window = window;
28006 help_echo_object = glyph->object;
28007 help_echo_pos = glyph->charpos;
28008 }
28009 }
28010 }
28011 if (NILP (pointer))
28012 pointer = Fplist_get (XCDR (img->spec), QCpointer);
28013 }
28014 }
28015 #endif /* HAVE_WINDOW_SYSTEM */
28016
28017 /* Clear mouse face if X/Y not over text. */
28018 if (glyph == NULL
28019 || area != TEXT_AREA
28020 || !MATRIX_ROW (w->current_matrix, vpos)->displays_text_p
28021 /* Glyph's OBJECT is an integer for glyphs inserted by the
28022 display engine for its internal purposes, like truncation
28023 and continuation glyphs and blanks beyond the end of
28024 line's text on text terminals. If we are over such a
28025 glyph, we are not over any text. */
28026 || INTEGERP (glyph->object)
28027 /* R2L rows have a stretch glyph at their front, which
28028 stands for no text, whereas L2R rows have no glyphs at
28029 all beyond the end of text. Treat such stretch glyphs
28030 like we do with NULL glyphs in L2R rows. */
28031 || (MATRIX_ROW (w->current_matrix, vpos)->reversed_p
28032 && glyph == MATRIX_ROW (w->current_matrix, vpos)->glyphs[TEXT_AREA]
28033 && glyph->type == STRETCH_GLYPH
28034 && glyph->avoid_cursor_p))
28035 {
28036 if (clear_mouse_face (hlinfo))
28037 cursor = No_Cursor;
28038 #ifdef HAVE_WINDOW_SYSTEM
28039 if (FRAME_WINDOW_P (f) && NILP (pointer))
28040 {
28041 if (area != TEXT_AREA)
28042 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
28043 else
28044 pointer = Vvoid_text_area_pointer;
28045 }
28046 #endif
28047 goto set_cursor;
28048 }
28049
28050 pos = glyph->charpos;
28051 object = glyph->object;
28052 if (!STRINGP (object) && !BUFFERP (object))
28053 goto set_cursor;
28054
28055 /* If we get an out-of-range value, return now; avoid an error. */
28056 if (BUFFERP (object) && pos > BUF_Z (b))
28057 goto set_cursor;
28058
28059 /* Make the window's buffer temporarily current for
28060 overlays_at and compute_char_face. */
28061 obuf = current_buffer;
28062 current_buffer = b;
28063 obegv = BEGV;
28064 ozv = ZV;
28065 BEGV = BEG;
28066 ZV = Z;
28067
28068 /* Is this char mouse-active or does it have help-echo? */
28069 position = make_number (pos);
28070
28071 if (BUFFERP (object))
28072 {
28073 /* Put all the overlays we want in a vector in overlay_vec. */
28074 GET_OVERLAYS_AT (pos, overlay_vec, noverlays, NULL, 0);
28075 /* Sort overlays into increasing priority order. */
28076 noverlays = sort_overlays (overlay_vec, noverlays, w);
28077 }
28078 else
28079 noverlays = 0;
28080
28081 same_region = coords_in_mouse_face_p (w, hpos, vpos);
28082
28083 if (same_region)
28084 cursor = No_Cursor;
28085
28086 /* Check mouse-face highlighting. */
28087 if (! same_region
28088 /* If there exists an overlay with mouse-face overlapping
28089 the one we are currently highlighting, we have to
28090 check if we enter the overlapping overlay, and then
28091 highlight only that. */
28092 || (OVERLAYP (hlinfo->mouse_face_overlay)
28093 && mouse_face_overlay_overlaps (hlinfo->mouse_face_overlay)))
28094 {
28095 /* Find the highest priority overlay with a mouse-face. */
28096 Lisp_Object overlay = Qnil;
28097 for (i = noverlays - 1; i >= 0 && NILP (overlay); --i)
28098 {
28099 mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face);
28100 if (!NILP (mouse_face))
28101 overlay = overlay_vec[i];
28102 }
28103
28104 /* If we're highlighting the same overlay as before, there's
28105 no need to do that again. */
28106 if (!NILP (overlay) && EQ (overlay, hlinfo->mouse_face_overlay))
28107 goto check_help_echo;
28108 hlinfo->mouse_face_overlay = overlay;
28109
28110 /* Clear the display of the old active region, if any. */
28111 if (clear_mouse_face (hlinfo))
28112 cursor = No_Cursor;
28113
28114 /* If no overlay applies, get a text property. */
28115 if (NILP (overlay))
28116 mouse_face = Fget_text_property (position, Qmouse_face, object);
28117
28118 /* Next, compute the bounds of the mouse highlighting and
28119 display it. */
28120 if (!NILP (mouse_face) && STRINGP (object))
28121 {
28122 /* The mouse-highlighting comes from a display string
28123 with a mouse-face. */
28124 Lisp_Object s, e;
28125 ptrdiff_t ignore;
28126
28127 s = Fprevious_single_property_change
28128 (make_number (pos + 1), Qmouse_face, object, Qnil);
28129 e = Fnext_single_property_change
28130 (position, Qmouse_face, object, Qnil);
28131 if (NILP (s))
28132 s = make_number (0);
28133 if (NILP (e))
28134 e = make_number (SCHARS (object) - 1);
28135 mouse_face_from_string_pos (w, hlinfo, object,
28136 XINT (s), XINT (e));
28137 hlinfo->mouse_face_past_end = 0;
28138 hlinfo->mouse_face_window = window;
28139 hlinfo->mouse_face_face_id
28140 = face_at_string_position (w, object, pos, 0, 0, 0, &ignore,
28141 glyph->face_id, 1);
28142 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
28143 cursor = No_Cursor;
28144 }
28145 else
28146 {
28147 /* The mouse-highlighting, if any, comes from an overlay
28148 or text property in the buffer. */
28149 Lisp_Object buffer IF_LINT (= Qnil);
28150 Lisp_Object disp_string IF_LINT (= Qnil);
28151
28152 if (STRINGP (object))
28153 {
28154 /* If we are on a display string with no mouse-face,
28155 check if the text under it has one. */
28156 struct glyph_row *r = MATRIX_ROW (w->current_matrix, vpos);
28157 ptrdiff_t start = MATRIX_ROW_START_CHARPOS (r);
28158 pos = string_buffer_position (object, start);
28159 if (pos > 0)
28160 {
28161 mouse_face = get_char_property_and_overlay
28162 (make_number (pos), Qmouse_face, w->buffer, &overlay);
28163 buffer = w->buffer;
28164 disp_string = object;
28165 }
28166 }
28167 else
28168 {
28169 buffer = object;
28170 disp_string = Qnil;
28171 }
28172
28173 if (!NILP (mouse_face))
28174 {
28175 Lisp_Object before, after;
28176 Lisp_Object before_string, after_string;
28177 /* To correctly find the limits of mouse highlight
28178 in a bidi-reordered buffer, we must not use the
28179 optimization of limiting the search in
28180 previous-single-property-change and
28181 next-single-property-change, because
28182 rows_from_pos_range needs the real start and end
28183 positions to DTRT in this case. That's because
28184 the first row visible in a window does not
28185 necessarily display the character whose position
28186 is the smallest. */
28187 Lisp_Object lim1 =
28188 NILP (BVAR (XBUFFER (buffer), bidi_display_reordering))
28189 ? Fmarker_position (w->start)
28190 : Qnil;
28191 Lisp_Object lim2 =
28192 NILP (BVAR (XBUFFER (buffer), bidi_display_reordering))
28193 ? make_number (BUF_Z (XBUFFER (buffer))
28194 - XFASTINT (w->window_end_pos))
28195 : Qnil;
28196
28197 if (NILP (overlay))
28198 {
28199 /* Handle the text property case. */
28200 before = Fprevious_single_property_change
28201 (make_number (pos + 1), Qmouse_face, buffer, lim1);
28202 after = Fnext_single_property_change
28203 (make_number (pos), Qmouse_face, buffer, lim2);
28204 before_string = after_string = Qnil;
28205 }
28206 else
28207 {
28208 /* Handle the overlay case. */
28209 before = Foverlay_start (overlay);
28210 after = Foverlay_end (overlay);
28211 before_string = Foverlay_get (overlay, Qbefore_string);
28212 after_string = Foverlay_get (overlay, Qafter_string);
28213
28214 if (!STRINGP (before_string)) before_string = Qnil;
28215 if (!STRINGP (after_string)) after_string = Qnil;
28216 }
28217
28218 mouse_face_from_buffer_pos (window, hlinfo, pos,
28219 NILP (before)
28220 ? 1
28221 : XFASTINT (before),
28222 NILP (after)
28223 ? BUF_Z (XBUFFER (buffer))
28224 : XFASTINT (after),
28225 before_string, after_string,
28226 disp_string);
28227 cursor = No_Cursor;
28228 }
28229 }
28230 }
28231
28232 check_help_echo:
28233
28234 /* Look for a `help-echo' property. */
28235 if (NILP (help_echo_string)) {
28236 Lisp_Object help, overlay;
28237
28238 /* Check overlays first. */
28239 help = overlay = Qnil;
28240 for (i = noverlays - 1; i >= 0 && NILP (help); --i)
28241 {
28242 overlay = overlay_vec[i];
28243 help = Foverlay_get (overlay, Qhelp_echo);
28244 }
28245
28246 if (!NILP (help))
28247 {
28248 help_echo_string = help;
28249 help_echo_window = window;
28250 help_echo_object = overlay;
28251 help_echo_pos = pos;
28252 }
28253 else
28254 {
28255 Lisp_Object obj = glyph->object;
28256 ptrdiff_t charpos = glyph->charpos;
28257
28258 /* Try text properties. */
28259 if (STRINGP (obj)
28260 && charpos >= 0
28261 && charpos < SCHARS (obj))
28262 {
28263 help = Fget_text_property (make_number (charpos),
28264 Qhelp_echo, obj);
28265 if (NILP (help))
28266 {
28267 /* If the string itself doesn't specify a help-echo,
28268 see if the buffer text ``under'' it does. */
28269 struct glyph_row *r
28270 = MATRIX_ROW (w->current_matrix, vpos);
28271 ptrdiff_t start = MATRIX_ROW_START_CHARPOS (r);
28272 ptrdiff_t p = string_buffer_position (obj, start);
28273 if (p > 0)
28274 {
28275 help = Fget_char_property (make_number (p),
28276 Qhelp_echo, w->buffer);
28277 if (!NILP (help))
28278 {
28279 charpos = p;
28280 obj = w->buffer;
28281 }
28282 }
28283 }
28284 }
28285 else if (BUFFERP (obj)
28286 && charpos >= BEGV
28287 && charpos < ZV)
28288 help = Fget_text_property (make_number (charpos), Qhelp_echo,
28289 obj);
28290
28291 if (!NILP (help))
28292 {
28293 help_echo_string = help;
28294 help_echo_window = window;
28295 help_echo_object = obj;
28296 help_echo_pos = charpos;
28297 }
28298 }
28299 }
28300
28301 #ifdef HAVE_WINDOW_SYSTEM
28302 /* Look for a `pointer' property. */
28303 if (FRAME_WINDOW_P (f) && NILP (pointer))
28304 {
28305 /* Check overlays first. */
28306 for (i = noverlays - 1; i >= 0 && NILP (pointer); --i)
28307 pointer = Foverlay_get (overlay_vec[i], Qpointer);
28308
28309 if (NILP (pointer))
28310 {
28311 Lisp_Object obj = glyph->object;
28312 ptrdiff_t charpos = glyph->charpos;
28313
28314 /* Try text properties. */
28315 if (STRINGP (obj)
28316 && charpos >= 0
28317 && charpos < SCHARS (obj))
28318 {
28319 pointer = Fget_text_property (make_number (charpos),
28320 Qpointer, obj);
28321 if (NILP (pointer))
28322 {
28323 /* If the string itself doesn't specify a pointer,
28324 see if the buffer text ``under'' it does. */
28325 struct glyph_row *r
28326 = MATRIX_ROW (w->current_matrix, vpos);
28327 ptrdiff_t start = MATRIX_ROW_START_CHARPOS (r);
28328 ptrdiff_t p = string_buffer_position (obj, start);
28329 if (p > 0)
28330 pointer = Fget_char_property (make_number (p),
28331 Qpointer, w->buffer);
28332 }
28333 }
28334 else if (BUFFERP (obj)
28335 && charpos >= BEGV
28336 && charpos < ZV)
28337 pointer = Fget_text_property (make_number (charpos),
28338 Qpointer, obj);
28339 }
28340 }
28341 #endif /* HAVE_WINDOW_SYSTEM */
28342
28343 BEGV = obegv;
28344 ZV = ozv;
28345 current_buffer = obuf;
28346 }
28347
28348 set_cursor:
28349
28350 #ifdef HAVE_WINDOW_SYSTEM
28351 if (FRAME_WINDOW_P (f))
28352 define_frame_cursor1 (f, cursor, pointer);
28353 #else
28354 /* This is here to prevent a compiler error, about "label at end of
28355 compound statement". */
28356 return;
28357 #endif
28358 }
28359
28360
28361 /* EXPORT for RIF:
28362 Clear any mouse-face on window W. This function is part of the
28363 redisplay interface, and is called from try_window_id and similar
28364 functions to ensure the mouse-highlight is off. */
28365
28366 void
28367 x_clear_window_mouse_face (struct window *w)
28368 {
28369 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame));
28370 Lisp_Object window;
28371
28372 BLOCK_INPUT;
28373 XSETWINDOW (window, w);
28374 if (EQ (window, hlinfo->mouse_face_window))
28375 clear_mouse_face (hlinfo);
28376 UNBLOCK_INPUT;
28377 }
28378
28379
28380 /* EXPORT:
28381 Just discard the mouse face information for frame F, if any.
28382 This is used when the size of F is changed. */
28383
28384 void
28385 cancel_mouse_face (struct frame *f)
28386 {
28387 Lisp_Object window;
28388 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
28389
28390 window = hlinfo->mouse_face_window;
28391 if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f)
28392 {
28393 hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
28394 hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
28395 hlinfo->mouse_face_window = Qnil;
28396 }
28397 }
28398
28399
28400 \f
28401 /***********************************************************************
28402 Exposure Events
28403 ***********************************************************************/
28404
28405 #ifdef HAVE_WINDOW_SYSTEM
28406
28407 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
28408 which intersects rectangle R. R is in window-relative coordinates. */
28409
28410 static void
28411 expose_area (struct window *w, struct glyph_row *row, XRectangle *r,
28412 enum glyph_row_area area)
28413 {
28414 struct glyph *first = row->glyphs[area];
28415 struct glyph *end = row->glyphs[area] + row->used[area];
28416 struct glyph *last;
28417 int first_x, start_x, x;
28418
28419 if (area == TEXT_AREA && row->fill_line_p)
28420 /* If row extends face to end of line write the whole line. */
28421 draw_glyphs (w, 0, row, area,
28422 0, row->used[area],
28423 DRAW_NORMAL_TEXT, 0);
28424 else
28425 {
28426 /* Set START_X to the window-relative start position for drawing glyphs of
28427 AREA. The first glyph of the text area can be partially visible.
28428 The first glyphs of other areas cannot. */
28429 start_x = window_box_left_offset (w, area);
28430 x = start_x;
28431 if (area == TEXT_AREA)
28432 x += row->x;
28433
28434 /* Find the first glyph that must be redrawn. */
28435 while (first < end
28436 && x + first->pixel_width < r->x)
28437 {
28438 x += first->pixel_width;
28439 ++first;
28440 }
28441
28442 /* Find the last one. */
28443 last = first;
28444 first_x = x;
28445 while (last < end
28446 && x < r->x + r->width)
28447 {
28448 x += last->pixel_width;
28449 ++last;
28450 }
28451
28452 /* Repaint. */
28453 if (last > first)
28454 draw_glyphs (w, first_x - start_x, row, area,
28455 first - row->glyphs[area], last - row->glyphs[area],
28456 DRAW_NORMAL_TEXT, 0);
28457 }
28458 }
28459
28460
28461 /* Redraw the parts of the glyph row ROW on window W intersecting
28462 rectangle R. R is in window-relative coordinates. Value is
28463 non-zero if mouse-face was overwritten. */
28464
28465 static int
28466 expose_line (struct window *w, struct glyph_row *row, XRectangle *r)
28467 {
28468 eassert (row->enabled_p);
28469
28470 if (row->mode_line_p || w->pseudo_window_p)
28471 draw_glyphs (w, 0, row, TEXT_AREA,
28472 0, row->used[TEXT_AREA],
28473 DRAW_NORMAL_TEXT, 0);
28474 else
28475 {
28476 if (row->used[LEFT_MARGIN_AREA])
28477 expose_area (w, row, r, LEFT_MARGIN_AREA);
28478 if (row->used[TEXT_AREA])
28479 expose_area (w, row, r, TEXT_AREA);
28480 if (row->used[RIGHT_MARGIN_AREA])
28481 expose_area (w, row, r, RIGHT_MARGIN_AREA);
28482 draw_row_fringe_bitmaps (w, row);
28483 }
28484
28485 return row->mouse_face_p;
28486 }
28487
28488
28489 /* Redraw those parts of glyphs rows during expose event handling that
28490 overlap other rows. Redrawing of an exposed line writes over parts
28491 of lines overlapping that exposed line; this function fixes that.
28492
28493 W is the window being exposed. FIRST_OVERLAPPING_ROW is the first
28494 row in W's current matrix that is exposed and overlaps other rows.
28495 LAST_OVERLAPPING_ROW is the last such row. */
28496
28497 static void
28498 expose_overlaps (struct window *w,
28499 struct glyph_row *first_overlapping_row,
28500 struct glyph_row *last_overlapping_row,
28501 XRectangle *r)
28502 {
28503 struct glyph_row *row;
28504
28505 for (row = first_overlapping_row; row <= last_overlapping_row; ++row)
28506 if (row->overlapping_p)
28507 {
28508 eassert (row->enabled_p && !row->mode_line_p);
28509
28510 row->clip = r;
28511 if (row->used[LEFT_MARGIN_AREA])
28512 x_fix_overlapping_area (w, row, LEFT_MARGIN_AREA, OVERLAPS_BOTH);
28513
28514 if (row->used[TEXT_AREA])
28515 x_fix_overlapping_area (w, row, TEXT_AREA, OVERLAPS_BOTH);
28516
28517 if (row->used[RIGHT_MARGIN_AREA])
28518 x_fix_overlapping_area (w, row, RIGHT_MARGIN_AREA, OVERLAPS_BOTH);
28519 row->clip = NULL;
28520 }
28521 }
28522
28523
28524 /* Return non-zero if W's cursor intersects rectangle R. */
28525
28526 static int
28527 phys_cursor_in_rect_p (struct window *w, XRectangle *r)
28528 {
28529 XRectangle cr, result;
28530 struct glyph *cursor_glyph;
28531 struct glyph_row *row;
28532
28533 if (w->phys_cursor.vpos >= 0
28534 && w->phys_cursor.vpos < w->current_matrix->nrows
28535 && (row = MATRIX_ROW (w->current_matrix, w->phys_cursor.vpos),
28536 row->enabled_p)
28537 && row->cursor_in_fringe_p)
28538 {
28539 /* Cursor is in the fringe. */
28540 cr.x = window_box_right_offset (w,
28541 (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
28542 ? RIGHT_MARGIN_AREA
28543 : TEXT_AREA));
28544 cr.y = row->y;
28545 cr.width = WINDOW_RIGHT_FRINGE_WIDTH (w);
28546 cr.height = row->height;
28547 return x_intersect_rectangles (&cr, r, &result);
28548 }
28549
28550 cursor_glyph = get_phys_cursor_glyph (w);
28551 if (cursor_glyph)
28552 {
28553 /* r is relative to W's box, but w->phys_cursor.x is relative
28554 to left edge of W's TEXT area. Adjust it. */
28555 cr.x = window_box_left_offset (w, TEXT_AREA) + w->phys_cursor.x;
28556 cr.y = w->phys_cursor.y;
28557 cr.width = cursor_glyph->pixel_width;
28558 cr.height = w->phys_cursor_height;
28559 /* ++KFS: W32 version used W32-specific IntersectRect here, but
28560 I assume the effect is the same -- and this is portable. */
28561 return x_intersect_rectangles (&cr, r, &result);
28562 }
28563 /* If we don't understand the format, pretend we're not in the hot-spot. */
28564 return 0;
28565 }
28566
28567
28568 /* EXPORT:
28569 Draw a vertical window border to the right of window W if W doesn't
28570 have vertical scroll bars. */
28571
28572 void
28573 x_draw_vertical_border (struct window *w)
28574 {
28575 struct frame *f = XFRAME (WINDOW_FRAME (w));
28576
28577 /* We could do better, if we knew what type of scroll-bar the adjacent
28578 windows (on either side) have... But we don't :-(
28579 However, I think this works ok. ++KFS 2003-04-25 */
28580
28581 /* Redraw borders between horizontally adjacent windows. Don't
28582 do it for frames with vertical scroll bars because either the
28583 right scroll bar of a window, or the left scroll bar of its
28584 neighbor will suffice as a border. */
28585 if (FRAME_HAS_VERTICAL_SCROLL_BARS (XFRAME (w->frame)))
28586 return;
28587
28588 if (!WINDOW_RIGHTMOST_P (w)
28589 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w))
28590 {
28591 int x0, x1, y0, y1;
28592
28593 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
28594 y1 -= 1;
28595
28596 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
28597 x1 -= 1;
28598
28599 FRAME_RIF (f)->draw_vertical_window_border (w, x1, y0, y1);
28600 }
28601 else if (!WINDOW_LEFTMOST_P (w)
28602 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
28603 {
28604 int x0, x1, y0, y1;
28605
28606 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
28607 y1 -= 1;
28608
28609 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
28610 x0 -= 1;
28611
28612 FRAME_RIF (f)->draw_vertical_window_border (w, x0, y0, y1);
28613 }
28614 }
28615
28616
28617 /* Redraw the part of window W intersection rectangle FR. Pixel
28618 coordinates in FR are frame-relative. Call this function with
28619 input blocked. Value is non-zero if the exposure overwrites
28620 mouse-face. */
28621
28622 static int
28623 expose_window (struct window *w, XRectangle *fr)
28624 {
28625 struct frame *f = XFRAME (w->frame);
28626 XRectangle wr, r;
28627 int mouse_face_overwritten_p = 0;
28628
28629 /* If window is not yet fully initialized, do nothing. This can
28630 happen when toolkit scroll bars are used and a window is split.
28631 Reconfiguring the scroll bar will generate an expose for a newly
28632 created window. */
28633 if (w->current_matrix == NULL)
28634 return 0;
28635
28636 /* When we're currently updating the window, display and current
28637 matrix usually don't agree. Arrange for a thorough display
28638 later. */
28639 if (w == updated_window)
28640 {
28641 SET_FRAME_GARBAGED (f);
28642 return 0;
28643 }
28644
28645 /* Frame-relative pixel rectangle of W. */
28646 wr.x = WINDOW_LEFT_EDGE_X (w);
28647 wr.y = WINDOW_TOP_EDGE_Y (w);
28648 wr.width = WINDOW_TOTAL_WIDTH (w);
28649 wr.height = WINDOW_TOTAL_HEIGHT (w);
28650
28651 if (x_intersect_rectangles (fr, &wr, &r))
28652 {
28653 int yb = window_text_bottom_y (w);
28654 struct glyph_row *row;
28655 int cursor_cleared_p, phys_cursor_on_p;
28656 struct glyph_row *first_overlapping_row, *last_overlapping_row;
28657
28658 TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n",
28659 r.x, r.y, r.width, r.height));
28660
28661 /* Convert to window coordinates. */
28662 r.x -= WINDOW_LEFT_EDGE_X (w);
28663 r.y -= WINDOW_TOP_EDGE_Y (w);
28664
28665 /* Turn off the cursor. */
28666 if (!w->pseudo_window_p
28667 && phys_cursor_in_rect_p (w, &r))
28668 {
28669 x_clear_cursor (w);
28670 cursor_cleared_p = 1;
28671 }
28672 else
28673 cursor_cleared_p = 0;
28674
28675 /* If the row containing the cursor extends face to end of line,
28676 then expose_area might overwrite the cursor outside the
28677 rectangle and thus notice_overwritten_cursor might clear
28678 w->phys_cursor_on_p. We remember the original value and
28679 check later if it is changed. */
28680 phys_cursor_on_p = w->phys_cursor_on_p;
28681
28682 /* Update lines intersecting rectangle R. */
28683 first_overlapping_row = last_overlapping_row = NULL;
28684 for (row = w->current_matrix->rows;
28685 row->enabled_p;
28686 ++row)
28687 {
28688 int y0 = row->y;
28689 int y1 = MATRIX_ROW_BOTTOM_Y (row);
28690
28691 if ((y0 >= r.y && y0 < r.y + r.height)
28692 || (y1 > r.y && y1 < r.y + r.height)
28693 || (r.y >= y0 && r.y < y1)
28694 || (r.y + r.height > y0 && r.y + r.height < y1))
28695 {
28696 /* A header line may be overlapping, but there is no need
28697 to fix overlapping areas for them. KFS 2005-02-12 */
28698 if (row->overlapping_p && !row->mode_line_p)
28699 {
28700 if (first_overlapping_row == NULL)
28701 first_overlapping_row = row;
28702 last_overlapping_row = row;
28703 }
28704
28705 row->clip = fr;
28706 if (expose_line (w, row, &r))
28707 mouse_face_overwritten_p = 1;
28708 row->clip = NULL;
28709 }
28710 else if (row->overlapping_p)
28711 {
28712 /* We must redraw a row overlapping the exposed area. */
28713 if (y0 < r.y
28714 ? y0 + row->phys_height > r.y
28715 : y0 + row->ascent - row->phys_ascent < r.y +r.height)
28716 {
28717 if (first_overlapping_row == NULL)
28718 first_overlapping_row = row;
28719 last_overlapping_row = row;
28720 }
28721 }
28722
28723 if (y1 >= yb)
28724 break;
28725 }
28726
28727 /* Display the mode line if there is one. */
28728 if (WINDOW_WANTS_MODELINE_P (w)
28729 && (row = MATRIX_MODE_LINE_ROW (w->current_matrix),
28730 row->enabled_p)
28731 && row->y < r.y + r.height)
28732 {
28733 if (expose_line (w, row, &r))
28734 mouse_face_overwritten_p = 1;
28735 }
28736
28737 if (!w->pseudo_window_p)
28738 {
28739 /* Fix the display of overlapping rows. */
28740 if (first_overlapping_row)
28741 expose_overlaps (w, first_overlapping_row, last_overlapping_row,
28742 fr);
28743
28744 /* Draw border between windows. */
28745 x_draw_vertical_border (w);
28746
28747 /* Turn the cursor on again. */
28748 if (cursor_cleared_p
28749 || (phys_cursor_on_p && !w->phys_cursor_on_p))
28750 update_window_cursor (w, 1);
28751 }
28752 }
28753
28754 return mouse_face_overwritten_p;
28755 }
28756
28757
28758
28759 /* Redraw (parts) of all windows in the window tree rooted at W that
28760 intersect R. R contains frame pixel coordinates. Value is
28761 non-zero if the exposure overwrites mouse-face. */
28762
28763 static int
28764 expose_window_tree (struct window *w, XRectangle *r)
28765 {
28766 struct frame *f = XFRAME (w->frame);
28767 int mouse_face_overwritten_p = 0;
28768
28769 while (w && !FRAME_GARBAGED_P (f))
28770 {
28771 if (!NILP (w->hchild))
28772 mouse_face_overwritten_p
28773 |= expose_window_tree (XWINDOW (w->hchild), r);
28774 else if (!NILP (w->vchild))
28775 mouse_face_overwritten_p
28776 |= expose_window_tree (XWINDOW (w->vchild), r);
28777 else
28778 mouse_face_overwritten_p |= expose_window (w, r);
28779
28780 w = NILP (w->next) ? NULL : XWINDOW (w->next);
28781 }
28782
28783 return mouse_face_overwritten_p;
28784 }
28785
28786
28787 /* EXPORT:
28788 Redisplay an exposed area of frame F. X and Y are the upper-left
28789 corner of the exposed rectangle. W and H are width and height of
28790 the exposed area. All are pixel values. W or H zero means redraw
28791 the entire frame. */
28792
28793 void
28794 expose_frame (struct frame *f, int x, int y, int w, int h)
28795 {
28796 XRectangle r;
28797 int mouse_face_overwritten_p = 0;
28798
28799 TRACE ((stderr, "expose_frame "));
28800
28801 /* No need to redraw if frame will be redrawn soon. */
28802 if (FRAME_GARBAGED_P (f))
28803 {
28804 TRACE ((stderr, " garbaged\n"));
28805 return;
28806 }
28807
28808 /* If basic faces haven't been realized yet, there is no point in
28809 trying to redraw anything. This can happen when we get an expose
28810 event while Emacs is starting, e.g. by moving another window. */
28811 if (FRAME_FACE_CACHE (f) == NULL
28812 || FRAME_FACE_CACHE (f)->used < BASIC_FACE_ID_SENTINEL)
28813 {
28814 TRACE ((stderr, " no faces\n"));
28815 return;
28816 }
28817
28818 if (w == 0 || h == 0)
28819 {
28820 r.x = r.y = 0;
28821 r.width = FRAME_COLUMN_WIDTH (f) * FRAME_COLS (f);
28822 r.height = FRAME_LINE_HEIGHT (f) * FRAME_LINES (f);
28823 }
28824 else
28825 {
28826 r.x = x;
28827 r.y = y;
28828 r.width = w;
28829 r.height = h;
28830 }
28831
28832 TRACE ((stderr, "(%d, %d, %d, %d)\n", r.x, r.y, r.width, r.height));
28833 mouse_face_overwritten_p = expose_window_tree (XWINDOW (f->root_window), &r);
28834
28835 if (WINDOWP (f->tool_bar_window))
28836 mouse_face_overwritten_p
28837 |= expose_window (XWINDOW (f->tool_bar_window), &r);
28838
28839 #ifdef HAVE_X_WINDOWS
28840 #ifndef MSDOS
28841 #ifndef USE_X_TOOLKIT
28842 if (WINDOWP (f->menu_bar_window))
28843 mouse_face_overwritten_p
28844 |= expose_window (XWINDOW (f->menu_bar_window), &r);
28845 #endif /* not USE_X_TOOLKIT */
28846 #endif
28847 #endif
28848
28849 /* Some window managers support a focus-follows-mouse style with
28850 delayed raising of frames. Imagine a partially obscured frame,
28851 and moving the mouse into partially obscured mouse-face on that
28852 frame. The visible part of the mouse-face will be highlighted,
28853 then the WM raises the obscured frame. With at least one WM, KDE
28854 2.1, Emacs is not getting any event for the raising of the frame
28855 (even tried with SubstructureRedirectMask), only Expose events.
28856 These expose events will draw text normally, i.e. not
28857 highlighted. Which means we must redo the highlight here.
28858 Subsume it under ``we love X''. --gerd 2001-08-15 */
28859 /* Included in Windows version because Windows most likely does not
28860 do the right thing if any third party tool offers
28861 focus-follows-mouse with delayed raise. --jason 2001-10-12 */
28862 if (mouse_face_overwritten_p && !FRAME_GARBAGED_P (f))
28863 {
28864 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
28865 if (f == hlinfo->mouse_face_mouse_frame)
28866 {
28867 int mouse_x = hlinfo->mouse_face_mouse_x;
28868 int mouse_y = hlinfo->mouse_face_mouse_y;
28869 clear_mouse_face (hlinfo);
28870 note_mouse_highlight (f, mouse_x, mouse_y);
28871 }
28872 }
28873 }
28874
28875
28876 /* EXPORT:
28877 Determine the intersection of two rectangles R1 and R2. Return
28878 the intersection in *RESULT. Value is non-zero if RESULT is not
28879 empty. */
28880
28881 int
28882 x_intersect_rectangles (XRectangle *r1, XRectangle *r2, XRectangle *result)
28883 {
28884 XRectangle *left, *right;
28885 XRectangle *upper, *lower;
28886 int intersection_p = 0;
28887
28888 /* Rearrange so that R1 is the left-most rectangle. */
28889 if (r1->x < r2->x)
28890 left = r1, right = r2;
28891 else
28892 left = r2, right = r1;
28893
28894 /* X0 of the intersection is right.x0, if this is inside R1,
28895 otherwise there is no intersection. */
28896 if (right->x <= left->x + left->width)
28897 {
28898 result->x = right->x;
28899
28900 /* The right end of the intersection is the minimum of
28901 the right ends of left and right. */
28902 result->width = (min (left->x + left->width, right->x + right->width)
28903 - result->x);
28904
28905 /* Same game for Y. */
28906 if (r1->y < r2->y)
28907 upper = r1, lower = r2;
28908 else
28909 upper = r2, lower = r1;
28910
28911 /* The upper end of the intersection is lower.y0, if this is inside
28912 of upper. Otherwise, there is no intersection. */
28913 if (lower->y <= upper->y + upper->height)
28914 {
28915 result->y = lower->y;
28916
28917 /* The lower end of the intersection is the minimum of the lower
28918 ends of upper and lower. */
28919 result->height = (min (lower->y + lower->height,
28920 upper->y + upper->height)
28921 - result->y);
28922 intersection_p = 1;
28923 }
28924 }
28925
28926 return intersection_p;
28927 }
28928
28929 #endif /* HAVE_WINDOW_SYSTEM */
28930
28931 \f
28932 /***********************************************************************
28933 Initialization
28934 ***********************************************************************/
28935
28936 void
28937 syms_of_xdisp (void)
28938 {
28939 Vwith_echo_area_save_vector = Qnil;
28940 staticpro (&Vwith_echo_area_save_vector);
28941
28942 Vmessage_stack = Qnil;
28943 staticpro (&Vmessage_stack);
28944
28945 DEFSYM (Qinhibit_redisplay, "inhibit-redisplay");
28946
28947 message_dolog_marker1 = Fmake_marker ();
28948 staticpro (&message_dolog_marker1);
28949 message_dolog_marker2 = Fmake_marker ();
28950 staticpro (&message_dolog_marker2);
28951 message_dolog_marker3 = Fmake_marker ();
28952 staticpro (&message_dolog_marker3);
28953
28954 #ifdef GLYPH_DEBUG
28955 defsubr (&Sdump_frame_glyph_matrix);
28956 defsubr (&Sdump_glyph_matrix);
28957 defsubr (&Sdump_glyph_row);
28958 defsubr (&Sdump_tool_bar_row);
28959 defsubr (&Strace_redisplay);
28960 defsubr (&Strace_to_stderr);
28961 #endif
28962 #ifdef HAVE_WINDOW_SYSTEM
28963 defsubr (&Stool_bar_lines_needed);
28964 defsubr (&Slookup_image_map);
28965 #endif
28966 defsubr (&Sformat_mode_line);
28967 defsubr (&Sinvisible_p);
28968 defsubr (&Scurrent_bidi_paragraph_direction);
28969
28970 DEFSYM (Qmenu_bar_update_hook, "menu-bar-update-hook");
28971 DEFSYM (Qoverriding_terminal_local_map, "overriding-terminal-local-map");
28972 DEFSYM (Qoverriding_local_map, "overriding-local-map");
28973 DEFSYM (Qwindow_scroll_functions, "window-scroll-functions");
28974 DEFSYM (Qwindow_text_change_functions, "window-text-change-functions");
28975 DEFSYM (Qredisplay_end_trigger_functions, "redisplay-end-trigger-functions");
28976 DEFSYM (Qinhibit_point_motion_hooks, "inhibit-point-motion-hooks");
28977 DEFSYM (Qeval, "eval");
28978 DEFSYM (QCdata, ":data");
28979 DEFSYM (Qdisplay, "display");
28980 DEFSYM (Qspace_width, "space-width");
28981 DEFSYM (Qraise, "raise");
28982 DEFSYM (Qslice, "slice");
28983 DEFSYM (Qspace, "space");
28984 DEFSYM (Qmargin, "margin");
28985 DEFSYM (Qpointer, "pointer");
28986 DEFSYM (Qleft_margin, "left-margin");
28987 DEFSYM (Qright_margin, "right-margin");
28988 DEFSYM (Qcenter, "center");
28989 DEFSYM (Qline_height, "line-height");
28990 DEFSYM (QCalign_to, ":align-to");
28991 DEFSYM (QCrelative_width, ":relative-width");
28992 DEFSYM (QCrelative_height, ":relative-height");
28993 DEFSYM (QCeval, ":eval");
28994 DEFSYM (QCpropertize, ":propertize");
28995 DEFSYM (QCfile, ":file");
28996 DEFSYM (Qfontified, "fontified");
28997 DEFSYM (Qfontification_functions, "fontification-functions");
28998 DEFSYM (Qtrailing_whitespace, "trailing-whitespace");
28999 DEFSYM (Qescape_glyph, "escape-glyph");
29000 DEFSYM (Qnobreak_space, "nobreak-space");
29001 DEFSYM (Qimage, "image");
29002 DEFSYM (Qtext, "text");
29003 DEFSYM (Qboth, "both");
29004 DEFSYM (Qboth_horiz, "both-horiz");
29005 DEFSYM (Qtext_image_horiz, "text-image-horiz");
29006 DEFSYM (QCmap, ":map");
29007 DEFSYM (QCpointer, ":pointer");
29008 DEFSYM (Qrect, "rect");
29009 DEFSYM (Qcircle, "circle");
29010 DEFSYM (Qpoly, "poly");
29011 DEFSYM (Qmessage_truncate_lines, "message-truncate-lines");
29012 DEFSYM (Qgrow_only, "grow-only");
29013 DEFSYM (Qinhibit_menubar_update, "inhibit-menubar-update");
29014 DEFSYM (Qinhibit_eval_during_redisplay, "inhibit-eval-during-redisplay");
29015 DEFSYM (Qposition, "position");
29016 DEFSYM (Qbuffer_position, "buffer-position");
29017 DEFSYM (Qobject, "object");
29018 DEFSYM (Qbar, "bar");
29019 DEFSYM (Qhbar, "hbar");
29020 DEFSYM (Qbox, "box");
29021 DEFSYM (Qhollow, "hollow");
29022 DEFSYM (Qhand, "hand");
29023 DEFSYM (Qarrow, "arrow");
29024 DEFSYM (Qinhibit_free_realized_faces, "inhibit-free-realized-faces");
29025
29026 list_of_error = Fcons (Fcons (intern_c_string ("error"),
29027 Fcons (intern_c_string ("void-variable"), Qnil)),
29028 Qnil);
29029 staticpro (&list_of_error);
29030
29031 DEFSYM (Qlast_arrow_position, "last-arrow-position");
29032 DEFSYM (Qlast_arrow_string, "last-arrow-string");
29033 DEFSYM (Qoverlay_arrow_string, "overlay-arrow-string");
29034 DEFSYM (Qoverlay_arrow_bitmap, "overlay-arrow-bitmap");
29035
29036 echo_buffer[0] = echo_buffer[1] = Qnil;
29037 staticpro (&echo_buffer[0]);
29038 staticpro (&echo_buffer[1]);
29039
29040 echo_area_buffer[0] = echo_area_buffer[1] = Qnil;
29041 staticpro (&echo_area_buffer[0]);
29042 staticpro (&echo_area_buffer[1]);
29043
29044 Vmessages_buffer_name = build_pure_c_string ("*Messages*");
29045 staticpro (&Vmessages_buffer_name);
29046
29047 mode_line_proptrans_alist = Qnil;
29048 staticpro (&mode_line_proptrans_alist);
29049 mode_line_string_list = Qnil;
29050 staticpro (&mode_line_string_list);
29051 mode_line_string_face = Qnil;
29052 staticpro (&mode_line_string_face);
29053 mode_line_string_face_prop = Qnil;
29054 staticpro (&mode_line_string_face_prop);
29055 Vmode_line_unwind_vector = Qnil;
29056 staticpro (&Vmode_line_unwind_vector);
29057
29058 DEFSYM (Qmode_line_default_help_echo, "mode-line-default-help-echo");
29059
29060 help_echo_string = Qnil;
29061 staticpro (&help_echo_string);
29062 help_echo_object = Qnil;
29063 staticpro (&help_echo_object);
29064 help_echo_window = Qnil;
29065 staticpro (&help_echo_window);
29066 previous_help_echo_string = Qnil;
29067 staticpro (&previous_help_echo_string);
29068 help_echo_pos = -1;
29069
29070 DEFSYM (Qright_to_left, "right-to-left");
29071 DEFSYM (Qleft_to_right, "left-to-right");
29072
29073 #ifdef HAVE_WINDOW_SYSTEM
29074 DEFVAR_BOOL ("x-stretch-cursor", x_stretch_cursor_p,
29075 doc: /* Non-nil means draw block cursor as wide as the glyph under it.
29076 For example, if a block cursor is over a tab, it will be drawn as
29077 wide as that tab on the display. */);
29078 x_stretch_cursor_p = 0;
29079 #endif
29080
29081 DEFVAR_LISP ("show-trailing-whitespace", Vshow_trailing_whitespace,
29082 doc: /* Non-nil means highlight trailing whitespace.
29083 The face used for trailing whitespace is `trailing-whitespace'. */);
29084 Vshow_trailing_whitespace = Qnil;
29085
29086 DEFVAR_LISP ("nobreak-char-display", Vnobreak_char_display,
29087 doc: /* Control highlighting of non-ASCII space and hyphen chars.
29088 If the value is t, Emacs highlights non-ASCII chars which have the
29089 same appearance as an ASCII space or hyphen, using the `nobreak-space'
29090 or `escape-glyph' face respectively.
29091
29092 U+00A0 (no-break space), U+00AD (soft hyphen), U+2010 (hyphen), and
29093 U+2011 (non-breaking hyphen) are affected.
29094
29095 Any other non-nil value means to display these characters as a escape
29096 glyph followed by an ordinary space or hyphen.
29097
29098 A value of nil means no special handling of these characters. */);
29099 Vnobreak_char_display = Qt;
29100
29101 DEFVAR_LISP ("void-text-area-pointer", Vvoid_text_area_pointer,
29102 doc: /* The pointer shape to show in void text areas.
29103 A value of nil means to show the text pointer. Other options are `arrow',
29104 `text', `hand', `vdrag', `hdrag', `modeline', and `hourglass'. */);
29105 Vvoid_text_area_pointer = Qarrow;
29106
29107 DEFVAR_LISP ("inhibit-redisplay", Vinhibit_redisplay,
29108 doc: /* Non-nil means don't actually do any redisplay.
29109 This is used for internal purposes. */);
29110 Vinhibit_redisplay = Qnil;
29111
29112 DEFVAR_LISP ("global-mode-string", Vglobal_mode_string,
29113 doc: /* String (or mode line construct) included (normally) in `mode-line-format'. */);
29114 Vglobal_mode_string = Qnil;
29115
29116 DEFVAR_LISP ("overlay-arrow-position", Voverlay_arrow_position,
29117 doc: /* Marker for where to display an arrow on top of the buffer text.
29118 This must be the beginning of a line in order to work.
29119 See also `overlay-arrow-string'. */);
29120 Voverlay_arrow_position = Qnil;
29121
29122 DEFVAR_LISP ("overlay-arrow-string", Voverlay_arrow_string,
29123 doc: /* String to display as an arrow in non-window frames.
29124 See also `overlay-arrow-position'. */);
29125 Voverlay_arrow_string = build_pure_c_string ("=>");
29126
29127 DEFVAR_LISP ("overlay-arrow-variable-list", Voverlay_arrow_variable_list,
29128 doc: /* List of variables (symbols) which hold markers for overlay arrows.
29129 The symbols on this list are examined during redisplay to determine
29130 where to display overlay arrows. */);
29131 Voverlay_arrow_variable_list
29132 = Fcons (intern_c_string ("overlay-arrow-position"), Qnil);
29133
29134 DEFVAR_INT ("scroll-step", emacs_scroll_step,
29135 doc: /* The number of lines to try scrolling a window by when point moves out.
29136 If that fails to bring point back on frame, point is centered instead.
29137 If this is zero, point is always centered after it moves off frame.
29138 If you want scrolling to always be a line at a time, you should set
29139 `scroll-conservatively' to a large value rather than set this to 1. */);
29140
29141 DEFVAR_INT ("scroll-conservatively", scroll_conservatively,
29142 doc: /* Scroll up to this many lines, to bring point back on screen.
29143 If point moves off-screen, redisplay will scroll by up to
29144 `scroll-conservatively' lines in order to bring point just barely
29145 onto the screen again. If that cannot be done, then redisplay
29146 recenters point as usual.
29147
29148 If the value is greater than 100, redisplay will never recenter point,
29149 but will always scroll just enough text to bring point into view, even
29150 if you move far away.
29151
29152 A value of zero means always recenter point if it moves off screen. */);
29153 scroll_conservatively = 0;
29154
29155 DEFVAR_INT ("scroll-margin", scroll_margin,
29156 doc: /* Number of lines of margin at the top and bottom of a window.
29157 Recenter the window whenever point gets within this many lines
29158 of the top or bottom of the window. */);
29159 scroll_margin = 0;
29160
29161 DEFVAR_LISP ("display-pixels-per-inch", Vdisplay_pixels_per_inch,
29162 doc: /* Pixels per inch value for non-window system displays.
29163 Value is a number or a cons (WIDTH-DPI . HEIGHT-DPI). */);
29164 Vdisplay_pixels_per_inch = make_float (72.0);
29165
29166 #ifdef GLYPH_DEBUG
29167 DEFVAR_INT ("debug-end-pos", debug_end_pos, doc: /* Don't ask. */);
29168 #endif
29169
29170 DEFVAR_LISP ("truncate-partial-width-windows",
29171 Vtruncate_partial_width_windows,
29172 doc: /* Non-nil means truncate lines in windows narrower than the frame.
29173 For an integer value, truncate lines in each window narrower than the
29174 full frame width, provided the window width is less than that integer;
29175 otherwise, respect the value of `truncate-lines'.
29176
29177 For any other non-nil value, truncate lines in all windows that do
29178 not span the full frame width.
29179
29180 A value of nil means to respect the value of `truncate-lines'.
29181
29182 If `word-wrap' is enabled, you might want to reduce this. */);
29183 Vtruncate_partial_width_windows = make_number (50);
29184
29185 DEFVAR_BOOL ("mode-line-inverse-video", mode_line_inverse_video,
29186 doc: /* When nil, display the mode-line/header-line/menu-bar in the default face.
29187 Any other value means to use the appropriate face, `mode-line',
29188 `header-line', or `menu' respectively. */);
29189 mode_line_inverse_video = 1;
29190
29191 DEFVAR_LISP ("line-number-display-limit", Vline_number_display_limit,
29192 doc: /* Maximum buffer size for which line number should be displayed.
29193 If the buffer is bigger than this, the line number does not appear
29194 in the mode line. A value of nil means no limit. */);
29195 Vline_number_display_limit = Qnil;
29196
29197 DEFVAR_INT ("line-number-display-limit-width",
29198 line_number_display_limit_width,
29199 doc: /* Maximum line width (in characters) for line number display.
29200 If the average length of the lines near point is bigger than this, then the
29201 line number may be omitted from the mode line. */);
29202 line_number_display_limit_width = 200;
29203
29204 DEFVAR_BOOL ("highlight-nonselected-windows", highlight_nonselected_windows,
29205 doc: /* Non-nil means highlight region even in nonselected windows. */);
29206 highlight_nonselected_windows = 0;
29207
29208 DEFVAR_BOOL ("multiple-frames", multiple_frames,
29209 doc: /* Non-nil if more than one frame is visible on this display.
29210 Minibuffer-only frames don't count, but iconified frames do.
29211 This variable is not guaranteed to be accurate except while processing
29212 `frame-title-format' and `icon-title-format'. */);
29213
29214 DEFVAR_LISP ("frame-title-format", Vframe_title_format,
29215 doc: /* Template for displaying the title bar of visible frames.
29216 \(Assuming the window manager supports this feature.)
29217
29218 This variable has the same structure as `mode-line-format', except that
29219 the %c and %l constructs are ignored. It is used only on frames for
29220 which no explicit name has been set \(see `modify-frame-parameters'). */);
29221
29222 DEFVAR_LISP ("icon-title-format", Vicon_title_format,
29223 doc: /* Template for displaying the title bar of an iconified frame.
29224 \(Assuming the window manager supports this feature.)
29225 This variable has the same structure as `mode-line-format' (which see),
29226 and is used only on frames for which no explicit name has been set
29227 \(see `modify-frame-parameters'). */);
29228 Vicon_title_format
29229 = Vframe_title_format
29230 = listn (CONSTYPE_PURE, 3,
29231 intern_c_string ("multiple-frames"),
29232 build_pure_c_string ("%b"),
29233 listn (CONSTYPE_PURE, 4,
29234 empty_unibyte_string,
29235 intern_c_string ("invocation-name"),
29236 build_pure_c_string ("@"),
29237 intern_c_string ("system-name")));
29238
29239 DEFVAR_LISP ("message-log-max", Vmessage_log_max,
29240 doc: /* Maximum number of lines to keep in the message log buffer.
29241 If nil, disable message logging. If t, log messages but don't truncate
29242 the buffer when it becomes large. */);
29243 Vmessage_log_max = make_number (100);
29244
29245 DEFVAR_LISP ("window-size-change-functions", Vwindow_size_change_functions,
29246 doc: /* Functions called before redisplay, if window sizes have changed.
29247 The value should be a list of functions that take one argument.
29248 Just before redisplay, for each frame, if any of its windows have changed
29249 size since the last redisplay, or have been split or deleted,
29250 all the functions in the list are called, with the frame as argument. */);
29251 Vwindow_size_change_functions = Qnil;
29252
29253 DEFVAR_LISP ("window-scroll-functions", Vwindow_scroll_functions,
29254 doc: /* List of functions to call before redisplaying a window with scrolling.
29255 Each function is called with two arguments, the window and its new
29256 display-start position. Note that these functions are also called by
29257 `set-window-buffer'. Also note that the value of `window-end' is not
29258 valid when these functions are called.
29259
29260 Warning: Do not use this feature to alter the way the window
29261 is scrolled. It is not designed for that, and such use probably won't
29262 work. */);
29263 Vwindow_scroll_functions = Qnil;
29264
29265 DEFVAR_LISP ("window-text-change-functions",
29266 Vwindow_text_change_functions,
29267 doc: /* Functions to call in redisplay when text in the window might change. */);
29268 Vwindow_text_change_functions = Qnil;
29269
29270 DEFVAR_LISP ("redisplay-end-trigger-functions", Vredisplay_end_trigger_functions,
29271 doc: /* Functions called when redisplay of a window reaches the end trigger.
29272 Each function is called with two arguments, the window and the end trigger value.
29273 See `set-window-redisplay-end-trigger'. */);
29274 Vredisplay_end_trigger_functions = Qnil;
29275
29276 DEFVAR_LISP ("mouse-autoselect-window", Vmouse_autoselect_window,
29277 doc: /* Non-nil means autoselect window with mouse pointer.
29278 If nil, do not autoselect windows.
29279 A positive number means delay autoselection by that many seconds: a
29280 window is autoselected only after the mouse has remained in that
29281 window for the duration of the delay.
29282 A negative number has a similar effect, but causes windows to be
29283 autoselected only after the mouse has stopped moving. \(Because of
29284 the way Emacs compares mouse events, you will occasionally wait twice
29285 that time before the window gets selected.\)
29286 Any other value means to autoselect window instantaneously when the
29287 mouse pointer enters it.
29288
29289 Autoselection selects the minibuffer only if it is active, and never
29290 unselects the minibuffer if it is active.
29291
29292 When customizing this variable make sure that the actual value of
29293 `focus-follows-mouse' matches the behavior of your window manager. */);
29294 Vmouse_autoselect_window = Qnil;
29295
29296 DEFVAR_LISP ("auto-resize-tool-bars", Vauto_resize_tool_bars,
29297 doc: /* Non-nil means automatically resize tool-bars.
29298 This dynamically changes the tool-bar's height to the minimum height
29299 that is needed to make all tool-bar items visible.
29300 If value is `grow-only', the tool-bar's height is only increased
29301 automatically; to decrease the tool-bar height, use \\[recenter]. */);
29302 Vauto_resize_tool_bars = Qt;
29303
29304 DEFVAR_BOOL ("auto-raise-tool-bar-buttons", auto_raise_tool_bar_buttons_p,
29305 doc: /* Non-nil means raise tool-bar buttons when the mouse moves over them. */);
29306 auto_raise_tool_bar_buttons_p = 1;
29307
29308 DEFVAR_BOOL ("make-cursor-line-fully-visible", make_cursor_line_fully_visible_p,
29309 doc: /* Non-nil means to scroll (recenter) cursor line if it is not fully visible. */);
29310 make_cursor_line_fully_visible_p = 1;
29311
29312 DEFVAR_LISP ("tool-bar-border", Vtool_bar_border,
29313 doc: /* Border below tool-bar in pixels.
29314 If an integer, use it as the height of the border.
29315 If it is one of `internal-border-width' or `border-width', use the
29316 value of the corresponding frame parameter.
29317 Otherwise, no border is added below the tool-bar. */);
29318 Vtool_bar_border = Qinternal_border_width;
29319
29320 DEFVAR_LISP ("tool-bar-button-margin", Vtool_bar_button_margin,
29321 doc: /* Margin around tool-bar buttons in pixels.
29322 If an integer, use that for both horizontal and vertical margins.
29323 Otherwise, value should be a pair of integers `(HORZ . VERT)' with
29324 HORZ specifying the horizontal margin, and VERT specifying the
29325 vertical margin. */);
29326 Vtool_bar_button_margin = make_number (DEFAULT_TOOL_BAR_BUTTON_MARGIN);
29327
29328 DEFVAR_INT ("tool-bar-button-relief", tool_bar_button_relief,
29329 doc: /* Relief thickness of tool-bar buttons. */);
29330 tool_bar_button_relief = DEFAULT_TOOL_BAR_BUTTON_RELIEF;
29331
29332 DEFVAR_LISP ("tool-bar-style", Vtool_bar_style,
29333 doc: /* Tool bar style to use.
29334 It can be one of
29335 image - show images only
29336 text - show text only
29337 both - show both, text below image
29338 both-horiz - show text to the right of the image
29339 text-image-horiz - show text to the left of the image
29340 any other - use system default or image if no system default.
29341
29342 This variable only affects the GTK+ toolkit version of Emacs. */);
29343 Vtool_bar_style = Qnil;
29344
29345 DEFVAR_INT ("tool-bar-max-label-size", tool_bar_max_label_size,
29346 doc: /* Maximum number of characters a label can have to be shown.
29347 The tool bar style must also show labels for this to have any effect, see
29348 `tool-bar-style'. */);
29349 tool_bar_max_label_size = DEFAULT_TOOL_BAR_LABEL_SIZE;
29350
29351 DEFVAR_LISP ("fontification-functions", Vfontification_functions,
29352 doc: /* List of functions to call to fontify regions of text.
29353 Each function is called with one argument POS. Functions must
29354 fontify a region starting at POS in the current buffer, and give
29355 fontified regions the property `fontified'. */);
29356 Vfontification_functions = Qnil;
29357 Fmake_variable_buffer_local (Qfontification_functions);
29358
29359 DEFVAR_BOOL ("unibyte-display-via-language-environment",
29360 unibyte_display_via_language_environment,
29361 doc: /* Non-nil means display unibyte text according to language environment.
29362 Specifically, this means that raw bytes in the range 160-255 decimal
29363 are displayed by converting them to the equivalent multibyte characters
29364 according to the current language environment. As a result, they are
29365 displayed according to the current fontset.
29366
29367 Note that this variable affects only how these bytes are displayed,
29368 but does not change the fact they are interpreted as raw bytes. */);
29369 unibyte_display_via_language_environment = 0;
29370
29371 DEFVAR_LISP ("max-mini-window-height", Vmax_mini_window_height,
29372 doc: /* Maximum height for resizing mini-windows (the minibuffer and the echo area).
29373 If a float, it specifies a fraction of the mini-window frame's height.
29374 If an integer, it specifies a number of lines. */);
29375 Vmax_mini_window_height = make_float (0.25);
29376
29377 DEFVAR_LISP ("resize-mini-windows", Vresize_mini_windows,
29378 doc: /* How to resize mini-windows (the minibuffer and the echo area).
29379 A value of nil means don't automatically resize mini-windows.
29380 A value of t means resize them to fit the text displayed in them.
29381 A value of `grow-only', the default, means let mini-windows grow only;
29382 they return to their normal size when the minibuffer is closed, or the
29383 echo area becomes empty. */);
29384 Vresize_mini_windows = Qgrow_only;
29385
29386 DEFVAR_LISP ("blink-cursor-alist", Vblink_cursor_alist,
29387 doc: /* Alist specifying how to blink the cursor off.
29388 Each element has the form (ON-STATE . OFF-STATE). Whenever the
29389 `cursor-type' frame-parameter or variable equals ON-STATE,
29390 comparing using `equal', Emacs uses OFF-STATE to specify
29391 how to blink it off. ON-STATE and OFF-STATE are values for
29392 the `cursor-type' frame parameter.
29393
29394 If a frame's ON-STATE has no entry in this list,
29395 the frame's other specifications determine how to blink the cursor off. */);
29396 Vblink_cursor_alist = Qnil;
29397
29398 DEFVAR_BOOL ("auto-hscroll-mode", automatic_hscrolling_p,
29399 doc: /* Allow or disallow automatic horizontal scrolling of windows.
29400 If non-nil, windows are automatically scrolled horizontally to make
29401 point visible. */);
29402 automatic_hscrolling_p = 1;
29403 DEFSYM (Qauto_hscroll_mode, "auto-hscroll-mode");
29404
29405 DEFVAR_INT ("hscroll-margin", hscroll_margin,
29406 doc: /* How many columns away from the window edge point is allowed to get
29407 before automatic hscrolling will horizontally scroll the window. */);
29408 hscroll_margin = 5;
29409
29410 DEFVAR_LISP ("hscroll-step", Vhscroll_step,
29411 doc: /* How many columns to scroll the window when point gets too close to the edge.
29412 When point is less than `hscroll-margin' columns from the window
29413 edge, automatic hscrolling will scroll the window by the amount of columns
29414 determined by this variable. If its value is a positive integer, scroll that
29415 many columns. If it's a positive floating-point number, it specifies the
29416 fraction of the window's width to scroll. If it's nil or zero, point will be
29417 centered horizontally after the scroll. Any other value, including negative
29418 numbers, are treated as if the value were zero.
29419
29420 Automatic hscrolling always moves point outside the scroll margin, so if
29421 point was more than scroll step columns inside the margin, the window will
29422 scroll more than the value given by the scroll step.
29423
29424 Note that the lower bound for automatic hscrolling specified by `scroll-left'
29425 and `scroll-right' overrides this variable's effect. */);
29426 Vhscroll_step = make_number (0);
29427
29428 DEFVAR_BOOL ("message-truncate-lines", message_truncate_lines,
29429 doc: /* If non-nil, messages are truncated instead of resizing the echo area.
29430 Bind this around calls to `message' to let it take effect. */);
29431 message_truncate_lines = 0;
29432
29433 DEFVAR_LISP ("menu-bar-update-hook", Vmenu_bar_update_hook,
29434 doc: /* Normal hook run to update the menu bar definitions.
29435 Redisplay runs this hook before it redisplays the menu bar.
29436 This is used to update submenus such as Buffers,
29437 whose contents depend on various data. */);
29438 Vmenu_bar_update_hook = Qnil;
29439
29440 DEFVAR_LISP ("menu-updating-frame", Vmenu_updating_frame,
29441 doc: /* Frame for which we are updating a menu.
29442 The enable predicate for a menu binding should check this variable. */);
29443 Vmenu_updating_frame = Qnil;
29444
29445 DEFVAR_BOOL ("inhibit-menubar-update", inhibit_menubar_update,
29446 doc: /* Non-nil means don't update menu bars. Internal use only. */);
29447 inhibit_menubar_update = 0;
29448
29449 DEFVAR_LISP ("wrap-prefix", Vwrap_prefix,
29450 doc: /* Prefix prepended to all continuation lines at display time.
29451 The value may be a string, an image, or a stretch-glyph; it is
29452 interpreted in the same way as the value of a `display' text property.
29453
29454 This variable is overridden by any `wrap-prefix' text or overlay
29455 property.
29456
29457 To add a prefix to non-continuation lines, use `line-prefix'. */);
29458 Vwrap_prefix = Qnil;
29459 DEFSYM (Qwrap_prefix, "wrap-prefix");
29460 Fmake_variable_buffer_local (Qwrap_prefix);
29461
29462 DEFVAR_LISP ("line-prefix", Vline_prefix,
29463 doc: /* Prefix prepended to all non-continuation lines at display time.
29464 The value may be a string, an image, or a stretch-glyph; it is
29465 interpreted in the same way as the value of a `display' text property.
29466
29467 This variable is overridden by any `line-prefix' text or overlay
29468 property.
29469
29470 To add a prefix to continuation lines, use `wrap-prefix'. */);
29471 Vline_prefix = Qnil;
29472 DEFSYM (Qline_prefix, "line-prefix");
29473 Fmake_variable_buffer_local (Qline_prefix);
29474
29475 DEFVAR_BOOL ("inhibit-eval-during-redisplay", inhibit_eval_during_redisplay,
29476 doc: /* Non-nil means don't eval Lisp during redisplay. */);
29477 inhibit_eval_during_redisplay = 0;
29478
29479 DEFVAR_BOOL ("inhibit-free-realized-faces", inhibit_free_realized_faces,
29480 doc: /* Non-nil means don't free realized faces. Internal use only. */);
29481 inhibit_free_realized_faces = 0;
29482
29483 #ifdef GLYPH_DEBUG
29484 DEFVAR_BOOL ("inhibit-try-window-id", inhibit_try_window_id,
29485 doc: /* Inhibit try_window_id display optimization. */);
29486 inhibit_try_window_id = 0;
29487
29488 DEFVAR_BOOL ("inhibit-try-window-reusing", inhibit_try_window_reusing,
29489 doc: /* Inhibit try_window_reusing display optimization. */);
29490 inhibit_try_window_reusing = 0;
29491
29492 DEFVAR_BOOL ("inhibit-try-cursor-movement", inhibit_try_cursor_movement,
29493 doc: /* Inhibit try_cursor_movement display optimization. */);
29494 inhibit_try_cursor_movement = 0;
29495 #endif /* GLYPH_DEBUG */
29496
29497 DEFVAR_INT ("overline-margin", overline_margin,
29498 doc: /* Space between overline and text, in pixels.
29499 The default value is 2: the height of the overline (1 pixel) plus 1 pixel
29500 margin to the character height. */);
29501 overline_margin = 2;
29502
29503 DEFVAR_INT ("underline-minimum-offset",
29504 underline_minimum_offset,
29505 doc: /* Minimum distance between baseline and underline.
29506 This can improve legibility of underlined text at small font sizes,
29507 particularly when using variable `x-use-underline-position-properties'
29508 with fonts that specify an UNDERLINE_POSITION relatively close to the
29509 baseline. The default value is 1. */);
29510 underline_minimum_offset = 1;
29511
29512 DEFVAR_BOOL ("display-hourglass", display_hourglass_p,
29513 doc: /* Non-nil means show an hourglass pointer, when Emacs is busy.
29514 This feature only works when on a window system that can change
29515 cursor shapes. */);
29516 display_hourglass_p = 1;
29517
29518 DEFVAR_LISP ("hourglass-delay", Vhourglass_delay,
29519 doc: /* Seconds to wait before displaying an hourglass pointer when Emacs is busy. */);
29520 Vhourglass_delay = make_number (DEFAULT_HOURGLASS_DELAY);
29521
29522 hourglass_atimer = NULL;
29523 hourglass_shown_p = 0;
29524
29525 DEFSYM (Qglyphless_char, "glyphless-char");
29526 DEFSYM (Qhex_code, "hex-code");
29527 DEFSYM (Qempty_box, "empty-box");
29528 DEFSYM (Qthin_space, "thin-space");
29529 DEFSYM (Qzero_width, "zero-width");
29530
29531 DEFSYM (Qglyphless_char_display, "glyphless-char-display");
29532 /* Intern this now in case it isn't already done.
29533 Setting this variable twice is harmless.
29534 But don't staticpro it here--that is done in alloc.c. */
29535 Qchar_table_extra_slots = intern_c_string ("char-table-extra-slots");
29536 Fput (Qglyphless_char_display, Qchar_table_extra_slots, make_number (1));
29537
29538 DEFVAR_LISP ("glyphless-char-display", Vglyphless_char_display,
29539 doc: /* Char-table defining glyphless characters.
29540 Each element, if non-nil, should be one of the following:
29541 an ASCII acronym string: display this string in a box
29542 `hex-code': display the hexadecimal code of a character in a box
29543 `empty-box': display as an empty box
29544 `thin-space': display as 1-pixel width space
29545 `zero-width': don't display
29546 An element may also be a cons cell (GRAPHICAL . TEXT), which specifies the
29547 display method for graphical terminals and text terminals respectively.
29548 GRAPHICAL and TEXT should each have one of the values listed above.
29549
29550 The char-table has one extra slot to control the display of a character for
29551 which no font is found. This slot only takes effect on graphical terminals.
29552 Its value should be an ASCII acronym string, `hex-code', `empty-box', or
29553 `thin-space'. The default is `empty-box'. */);
29554 Vglyphless_char_display = Fmake_char_table (Qglyphless_char_display, Qnil);
29555 Fset_char_table_extra_slot (Vglyphless_char_display, make_number (0),
29556 Qempty_box);
29557
29558 DEFVAR_LISP ("debug-on-message", Vdebug_on_message,
29559 doc: /* If non-nil, debug if a message matching this regexp is displayed. */);
29560 Vdebug_on_message = Qnil;
29561 }
29562
29563
29564 /* Initialize this module when Emacs starts. */
29565
29566 void
29567 init_xdisp (void)
29568 {
29569 current_header_line_height = current_mode_line_height = -1;
29570
29571 CHARPOS (this_line_start_pos) = 0;
29572
29573 if (!noninteractive)
29574 {
29575 struct window *m = XWINDOW (minibuf_window);
29576 Lisp_Object frame = m->frame;
29577 struct frame *f = XFRAME (frame);
29578 Lisp_Object root = FRAME_ROOT_WINDOW (f);
29579 struct window *r = XWINDOW (root);
29580 int i;
29581
29582 echo_area_window = minibuf_window;
29583
29584 wset_top_line (r, make_number (FRAME_TOP_MARGIN (f)));
29585 wset_total_lines
29586 (r, make_number (FRAME_LINES (f) - 1 - FRAME_TOP_MARGIN (f)));
29587 wset_total_cols (r, make_number (FRAME_COLS (f)));
29588 wset_top_line (m, make_number (FRAME_LINES (f) - 1));
29589 wset_total_lines (m, make_number (1));
29590 wset_total_cols (m, make_number (FRAME_COLS (f)));
29591
29592 scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs;
29593 scratch_glyph_row.glyphs[TEXT_AREA + 1]
29594 = scratch_glyphs + MAX_SCRATCH_GLYPHS;
29595
29596 /* The default ellipsis glyphs `...'. */
29597 for (i = 0; i < 3; ++i)
29598 default_invis_vector[i] = make_number ('.');
29599 }
29600
29601 {
29602 /* Allocate the buffer for frame titles.
29603 Also used for `format-mode-line'. */
29604 int size = 100;
29605 mode_line_noprop_buf = xmalloc (size);
29606 mode_line_noprop_buf_end = mode_line_noprop_buf + size;
29607 mode_line_noprop_ptr = mode_line_noprop_buf;
29608 mode_line_target = MODE_LINE_DISPLAY;
29609 }
29610
29611 help_echo_showing_p = 0;
29612 }
29613
29614 /* Since w32 does not support atimers, it defines its own implementation of
29615 the following three functions in w32fns.c. */
29616 #ifndef WINDOWSNT
29617
29618 /* Platform-independent portion of hourglass implementation. */
29619
29620 /* Cancel a currently active hourglass timer, and start a new one. */
29621 void
29622 start_hourglass (void)
29623 {
29624 #if defined (HAVE_WINDOW_SYSTEM)
29625 EMACS_TIME delay;
29626
29627 cancel_hourglass ();
29628
29629 if (INTEGERP (Vhourglass_delay)
29630 && XINT (Vhourglass_delay) > 0)
29631 delay = make_emacs_time (min (XINT (Vhourglass_delay),
29632 TYPE_MAXIMUM (time_t)),
29633 0);
29634 else if (FLOATP (Vhourglass_delay)
29635 && XFLOAT_DATA (Vhourglass_delay) > 0)
29636 delay = EMACS_TIME_FROM_DOUBLE (XFLOAT_DATA (Vhourglass_delay));
29637 else
29638 delay = make_emacs_time (DEFAULT_HOURGLASS_DELAY, 0);
29639
29640 hourglass_atimer = start_atimer (ATIMER_RELATIVE, delay,
29641 show_hourglass, NULL);
29642 #endif
29643 }
29644
29645
29646 /* Cancel the hourglass cursor timer if active, hide a busy cursor if
29647 shown. */
29648 void
29649 cancel_hourglass (void)
29650 {
29651 #if defined (HAVE_WINDOW_SYSTEM)
29652 if (hourglass_atimer)
29653 {
29654 cancel_atimer (hourglass_atimer);
29655 hourglass_atimer = NULL;
29656 }
29657
29658 if (hourglass_shown_p)
29659 hide_hourglass ();
29660 #endif
29661 }
29662 #endif /* ! WINDOWSNT */