]> code.delx.au - gnu-emacs/blob - src/xdisp.c
upstream, doesn build yet
[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 "buffer.h"
285 #include "character.h"
286 #include "charset.h"
287 #include "indent.h"
288 #include "commands.h"
289 #include "keymap.h"
290 #include "macros.h"
291 #include "disptab.h"
292 #include "termhooks.h"
293 #include "termopts.h"
294 #include "intervals.h"
295 #include "coding.h"
296 #include "process.h"
297 #include "region-cache.h"
298 #include "font.h"
299 #include "fontset.h"
300 #include "blockinput.h"
301
302 #ifdef HAVE_X_WINDOWS
303 #include "xterm.h"
304 #endif
305 #ifdef WINDOWSNT
306 #include "w32term.h"
307 #endif
308 #ifdef HAVE_NS
309 #include "nsterm.h"
310 #endif
311 #ifdef USE_GTK
312 #include "gtkutil.h"
313 #endif
314
315 #include "font.h"
316 #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 #ifdef HAVE_WINDOW_SYSTEM
371
372 /* Test if overflow newline into fringe. Called with iterator IT
373 at or past right window margin, and with IT->current_x set. */
374
375 #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(IT) \
376 (!NILP (Voverflow_newline_into_fringe) \
377 && FRAME_WINDOW_P ((IT)->f) \
378 && ((IT)->bidi_it.paragraph_dir == R2L \
379 ? (WINDOW_LEFT_FRINGE_WIDTH ((IT)->w) > 0) \
380 : (WINDOW_RIGHT_FRINGE_WIDTH ((IT)->w) > 0)) \
381 && (IT)->current_x == (IT)->last_visible_x \
382 && (IT)->line_wrap != WORD_WRAP)
383
384 #else /* !HAVE_WINDOW_SYSTEM */
385 #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(it) 0
386 #endif /* HAVE_WINDOW_SYSTEM */
387
388 /* Test if the display element loaded in IT, or the underlying buffer
389 or string character, is a space or a TAB character. This is used
390 to determine where word wrapping can occur. */
391
392 #define IT_DISPLAYING_WHITESPACE(it) \
393 ((it->what == IT_CHARACTER && (it->c == ' ' || it->c == '\t')) \
394 || ((STRINGP (it->string) \
395 && (SREF (it->string, IT_STRING_BYTEPOS (*it)) == ' ' \
396 || SREF (it->string, IT_STRING_BYTEPOS (*it)) == '\t')) \
397 || (it->s \
398 && (it->s[IT_BYTEPOS (*it)] == ' ' \
399 || it->s[IT_BYTEPOS (*it)] == '\t')) \
400 || (IT_BYTEPOS (*it) < ZV_BYTE \
401 && (*BYTE_POS_ADDR (IT_BYTEPOS (*it)) == ' ' \
402 || *BYTE_POS_ADDR (IT_BYTEPOS (*it)) == '\t')))) \
403
404 /* Name of the face used to highlight trailing whitespace. */
405
406 static Lisp_Object Qtrailing_whitespace;
407
408 /* Name and number of the face used to highlight escape glyphs. */
409
410 static Lisp_Object Qescape_glyph;
411
412 /* Name and number of the face used to highlight non-breaking spaces. */
413
414 static Lisp_Object Qnobreak_space;
415
416 /* The symbol `image' which is the car of the lists used to represent
417 images in Lisp. Also a tool bar style. */
418
419 Lisp_Object Qimage;
420
421 /* The image map types. */
422 Lisp_Object QCmap;
423 static Lisp_Object QCpointer;
424 static Lisp_Object Qrect, Qcircle, Qpoly;
425
426 /* Tool bar styles */
427 Lisp_Object Qboth, Qboth_horiz, Qtext_image_horiz;
428
429 /* Non-zero means print newline to stdout before next mini-buffer
430 message. */
431
432 int noninteractive_need_newline;
433
434 /* Non-zero means print newline to message log before next message. */
435
436 static int message_log_need_newline;
437
438 /* Three markers that message_dolog uses.
439 It could allocate them itself, but that causes trouble
440 in handling memory-full errors. */
441 static Lisp_Object message_dolog_marker1;
442 static Lisp_Object message_dolog_marker2;
443 static Lisp_Object message_dolog_marker3;
444 \f
445 /* The buffer position of the first character appearing entirely or
446 partially on the line of the selected window which contains the
447 cursor; <= 0 if not known. Set by set_cursor_from_row, used for
448 redisplay optimization in redisplay_internal. */
449
450 static struct text_pos this_line_start_pos;
451
452 /* Number of characters past the end of the line above, including the
453 terminating newline. */
454
455 static struct text_pos this_line_end_pos;
456
457 /* The vertical positions and the height of this line. */
458
459 static int this_line_vpos;
460 static int this_line_y;
461 static int this_line_pixel_height;
462
463 /* X position at which this display line starts. Usually zero;
464 negative if first character is partially visible. */
465
466 static int this_line_start_x;
467
468 /* The smallest character position seen by move_it_* functions as they
469 move across display lines. Used to set MATRIX_ROW_START_CHARPOS of
470 hscrolled lines, see display_line. */
471
472 static struct text_pos this_line_min_pos;
473
474 /* Buffer that this_line_.* variables are referring to. */
475
476 static struct buffer *this_line_buffer;
477
478
479 /* Values of those variables at last redisplay are stored as
480 properties on `overlay-arrow-position' symbol. However, if
481 Voverlay_arrow_position is a marker, last-arrow-position is its
482 numerical position. */
483
484 static Lisp_Object Qlast_arrow_position, Qlast_arrow_string;
485
486 /* Alternative overlay-arrow-string and overlay-arrow-bitmap
487 properties on a symbol in overlay-arrow-variable-list. */
488
489 static Lisp_Object Qoverlay_arrow_string, Qoverlay_arrow_bitmap;
490
491 Lisp_Object Qmenu_bar_update_hook;
492
493 /* Nonzero if an overlay arrow has been displayed in this window. */
494
495 static int overlay_arrow_seen;
496
497 /* Number of windows showing the buffer of the selected window (or
498 another buffer with the same base buffer). keyboard.c refers to
499 this. */
500
501 int buffer_shared;
502
503 /* Vector containing glyphs for an ellipsis `...'. */
504
505 static Lisp_Object default_invis_vector[3];
506
507 /* This is the window where the echo area message was displayed. It
508 is always a mini-buffer window, but it may not be the same window
509 currently active as a mini-buffer. */
510
511 Lisp_Object echo_area_window;
512
513 /* List of pairs (MESSAGE . MULTIBYTE). The function save_message
514 pushes the current message and the value of
515 message_enable_multibyte on the stack, the function restore_message
516 pops the stack and displays MESSAGE again. */
517
518 static Lisp_Object Vmessage_stack;
519
520 /* Nonzero means multibyte characters were enabled when the echo area
521 message was specified. */
522
523 static int message_enable_multibyte;
524
525 /* Nonzero if we should redraw the mode lines on the next redisplay. */
526
527 int update_mode_lines;
528
529 /* Nonzero if window sizes or contents have changed since last
530 redisplay that finished. */
531
532 int windows_or_buffers_changed;
533
534 /* Nonzero means a frame's cursor type has been changed. */
535
536 int cursor_type_changed;
537
538 /* Nonzero after display_mode_line if %l was used and it displayed a
539 line number. */
540
541 static int line_number_displayed;
542
543 /* The name of the *Messages* buffer, a string. */
544
545 static Lisp_Object Vmessages_buffer_name;
546
547 /* Current, index 0, and last displayed echo area message. Either
548 buffers from echo_buffers, or nil to indicate no message. */
549
550 Lisp_Object echo_area_buffer[2];
551
552 /* The buffers referenced from echo_area_buffer. */
553
554 static Lisp_Object echo_buffer[2];
555
556 /* A vector saved used in with_area_buffer to reduce consing. */
557
558 static Lisp_Object Vwith_echo_area_save_vector;
559
560 /* Non-zero means display_echo_area should display the last echo area
561 message again. Set by redisplay_preserve_echo_area. */
562
563 static int display_last_displayed_message_p;
564
565 /* Nonzero if echo area is being used by print; zero if being used by
566 message. */
567
568 static int message_buf_print;
569
570 /* The symbol `inhibit-menubar-update' and its DEFVAR_BOOL variable. */
571
572 static Lisp_Object Qinhibit_menubar_update;
573 static Lisp_Object Qmessage_truncate_lines;
574
575 /* Set to 1 in clear_message to make redisplay_internal aware
576 of an emptied echo area. */
577
578 static int message_cleared_p;
579
580 /* A scratch glyph row with contents used for generating truncation
581 glyphs. Also used in direct_output_for_insert. */
582
583 #define MAX_SCRATCH_GLYPHS 100
584 static struct glyph_row scratch_glyph_row;
585 static struct glyph scratch_glyphs[MAX_SCRATCH_GLYPHS];
586
587 /* Ascent and height of the last line processed by move_it_to. */
588
589 static int last_max_ascent, last_height;
590
591 /* Non-zero if there's a help-echo in the echo area. */
592
593 int help_echo_showing_p;
594
595 /* If >= 0, computed, exact values of mode-line and header-line height
596 to use in the macros CURRENT_MODE_LINE_HEIGHT and
597 CURRENT_HEADER_LINE_HEIGHT. */
598
599 int current_mode_line_height, current_header_line_height;
600
601 /* The maximum distance to look ahead for text properties. Values
602 that are too small let us call compute_char_face and similar
603 functions too often which is expensive. Values that are too large
604 let us call compute_char_face and alike too often because we
605 might not be interested in text properties that far away. */
606
607 #define TEXT_PROP_DISTANCE_LIMIT 100
608
609 /* SAVE_IT and RESTORE_IT are called when we save a snapshot of the
610 iterator state and later restore it. This is needed because the
611 bidi iterator on bidi.c keeps a stacked cache of its states, which
612 is really a singleton. When we use scratch iterator objects to
613 move around the buffer, we can cause the bidi cache to be pushed or
614 popped, and therefore we need to restore the cache state when we
615 return to the original iterator. */
616 #define SAVE_IT(ITCOPY,ITORIG,CACHE) \
617 do { \
618 if (CACHE) \
619 bidi_unshelve_cache (CACHE, 1); \
620 ITCOPY = ITORIG; \
621 CACHE = bidi_shelve_cache (); \
622 } while (0)
623
624 #define RESTORE_IT(pITORIG,pITCOPY,CACHE) \
625 do { \
626 if (pITORIG != pITCOPY) \
627 *(pITORIG) = *(pITCOPY); \
628 bidi_unshelve_cache (CACHE, 0); \
629 CACHE = NULL; \
630 } while (0)
631
632 #if GLYPH_DEBUG
633
634 /* Non-zero means print traces of redisplay if compiled with
635 GLYPH_DEBUG != 0. */
636
637 int trace_redisplay_p;
638
639 #endif /* GLYPH_DEBUG */
640
641 #ifdef DEBUG_TRACE_MOVE
642 /* Non-zero means trace with TRACE_MOVE to stderr. */
643 int trace_move;
644
645 #define TRACE_MOVE(x) if (trace_move) fprintf x; else (void) 0
646 #else
647 #define TRACE_MOVE(x) (void) 0
648 #endif
649
650 static Lisp_Object Qauto_hscroll_mode;
651
652 /* Buffer being redisplayed -- for redisplay_window_error. */
653
654 static struct buffer *displayed_buffer;
655
656 /* Value returned from text property handlers (see below). */
657
658 enum prop_handled
659 {
660 HANDLED_NORMALLY,
661 HANDLED_RECOMPUTE_PROPS,
662 HANDLED_OVERLAY_STRING_CONSUMED,
663 HANDLED_RETURN
664 };
665
666 /* A description of text properties that redisplay is interested
667 in. */
668
669 struct props
670 {
671 /* The name of the property. */
672 Lisp_Object *name;
673
674 /* A unique index for the property. */
675 enum prop_idx idx;
676
677 /* A handler function called to set up iterator IT from the property
678 at IT's current position. Value is used to steer handle_stop. */
679 enum prop_handled (*handler) (struct it *it);
680 };
681
682 static enum prop_handled handle_face_prop (struct it *);
683 static enum prop_handled handle_invisible_prop (struct it *);
684 static enum prop_handled handle_display_prop (struct it *);
685 static enum prop_handled handle_composition_prop (struct it *);
686 static enum prop_handled handle_overlay_change (struct it *);
687 static enum prop_handled handle_fontified_prop (struct it *);
688
689 /* Properties handled by iterators. */
690
691 static struct props it_props[] =
692 {
693 {&Qfontified, FONTIFIED_PROP_IDX, handle_fontified_prop},
694 /* Handle `face' before `display' because some sub-properties of
695 `display' need to know the face. */
696 {&Qface, FACE_PROP_IDX, handle_face_prop},
697 {&Qdisplay, DISPLAY_PROP_IDX, handle_display_prop},
698 {&Qinvisible, INVISIBLE_PROP_IDX, handle_invisible_prop},
699 {&Qcomposition, COMPOSITION_PROP_IDX, handle_composition_prop},
700 {NULL, 0, NULL}
701 };
702
703 /* Value is the position described by X. If X is a marker, value is
704 the marker_position of X. Otherwise, value is X. */
705
706 #define COERCE_MARKER(X) (MARKERP ((X)) ? Fmarker_position (X) : (X))
707
708 /* Enumeration returned by some move_it_.* functions internally. */
709
710 enum move_it_result
711 {
712 /* Not used. Undefined value. */
713 MOVE_UNDEFINED,
714
715 /* Move ended at the requested buffer position or ZV. */
716 MOVE_POS_MATCH_OR_ZV,
717
718 /* Move ended at the requested X pixel position. */
719 MOVE_X_REACHED,
720
721 /* Move within a line ended at the end of a line that must be
722 continued. */
723 MOVE_LINE_CONTINUED,
724
725 /* Move within a line ended at the end of a line that would
726 be displayed truncated. */
727 MOVE_LINE_TRUNCATED,
728
729 /* Move within a line ended at a line end. */
730 MOVE_NEWLINE_OR_CR
731 };
732
733 /* This counter is used to clear the face cache every once in a while
734 in redisplay_internal. It is incremented for each redisplay.
735 Every CLEAR_FACE_CACHE_COUNT full redisplays, the face cache is
736 cleared. */
737
738 #define CLEAR_FACE_CACHE_COUNT 500
739 static int clear_face_cache_count;
740
741 /* Similarly for the image cache. */
742
743 #ifdef HAVE_WINDOW_SYSTEM
744 #define CLEAR_IMAGE_CACHE_COUNT 101
745 static int clear_image_cache_count;
746
747 /* Null glyph slice */
748 static struct glyph_slice null_glyph_slice = { 0, 0, 0, 0 };
749 #endif
750
751 /* Non-zero while redisplay_internal is in progress. */
752
753 int redisplaying_p;
754
755 static Lisp_Object Qinhibit_free_realized_faces;
756 static Lisp_Object Qmode_line_default_help_echo;
757
758 /* If a string, XTread_socket generates an event to display that string.
759 (The display is done in read_char.) */
760
761 Lisp_Object help_echo_string;
762 Lisp_Object help_echo_window;
763 Lisp_Object help_echo_object;
764 ptrdiff_t help_echo_pos;
765
766 /* Temporary variable for XTread_socket. */
767
768 Lisp_Object previous_help_echo_string;
769
770 /* Platform-independent portion of hourglass implementation. */
771
772 /* Non-zero means an hourglass cursor is currently shown. */
773 int hourglass_shown_p;
774
775 /* If non-null, an asynchronous timer that, when it expires, displays
776 an hourglass cursor on all frames. */
777 struct atimer *hourglass_atimer;
778
779 /* Name of the face used to display glyphless characters. */
780 Lisp_Object Qglyphless_char;
781
782 /* Symbol for the purpose of Vglyphless_char_display. */
783 static Lisp_Object Qglyphless_char_display;
784
785 /* Method symbols for Vglyphless_char_display. */
786 static Lisp_Object Qhex_code, Qempty_box, Qthin_space, Qzero_width;
787
788 /* Default pixel width of `thin-space' display method. */
789 #define THIN_SPACE_WIDTH 1
790
791 /* Default number of seconds to wait before displaying an hourglass
792 cursor. */
793 #define DEFAULT_HOURGLASS_DELAY 1
794
795 \f
796 /* Function prototypes. */
797
798 static void setup_for_ellipsis (struct it *, int);
799 static void set_iterator_to_next (struct it *, int);
800 static void mark_window_display_accurate_1 (struct window *, int);
801 static int single_display_spec_string_p (Lisp_Object, Lisp_Object);
802 static int display_prop_string_p (Lisp_Object, Lisp_Object);
803 static int cursor_row_p (struct glyph_row *);
804 static int redisplay_mode_lines (Lisp_Object, int);
805 static char *decode_mode_spec_coding (Lisp_Object, char *, int);
806
807 static Lisp_Object get_it_property (struct it *it, Lisp_Object prop);
808
809 static void handle_line_prefix (struct it *);
810
811 static void pint2str (char *, int, ptrdiff_t);
812 static void pint2hrstr (char *, int, ptrdiff_t);
813 static struct text_pos run_window_scroll_functions (Lisp_Object,
814 struct text_pos);
815 static void reconsider_clip_changes (struct window *, struct buffer *);
816 static int text_outside_line_unchanged_p (struct window *,
817 ptrdiff_t, ptrdiff_t);
818 static void store_mode_line_noprop_char (char);
819 static int store_mode_line_noprop (const char *, int, int);
820 static void handle_stop (struct it *);
821 static void handle_stop_backwards (struct it *, ptrdiff_t);
822 static void vmessage (const char *, va_list) ATTRIBUTE_FORMAT_PRINTF (1, 0);
823 static void ensure_echo_area_buffers (void);
824 static Lisp_Object unwind_with_echo_area_buffer (Lisp_Object);
825 static Lisp_Object with_echo_area_buffer_unwind_data (struct window *);
826 static int with_echo_area_buffer (struct window *, int,
827 int (*) (ptrdiff_t, Lisp_Object, ptrdiff_t, ptrdiff_t),
828 ptrdiff_t, Lisp_Object, ptrdiff_t, ptrdiff_t);
829 static void clear_garbaged_frames (void);
830 static int current_message_1 (ptrdiff_t, Lisp_Object, ptrdiff_t, ptrdiff_t);
831 static void pop_message (void);
832 static int truncate_message_1 (ptrdiff_t, Lisp_Object, ptrdiff_t, ptrdiff_t);
833 static void set_message (const char *, Lisp_Object, ptrdiff_t, int);
834 static int set_message_1 (ptrdiff_t, Lisp_Object, ptrdiff_t, ptrdiff_t);
835 static int display_echo_area (struct window *);
836 static int display_echo_area_1 (ptrdiff_t, Lisp_Object, ptrdiff_t, ptrdiff_t);
837 static int resize_mini_window_1 (ptrdiff_t, Lisp_Object, ptrdiff_t, ptrdiff_t);
838 static Lisp_Object unwind_redisplay (Lisp_Object);
839 static int string_char_and_length (const unsigned char *, int *);
840 static struct text_pos display_prop_end (struct it *, Lisp_Object,
841 struct text_pos);
842 static int compute_window_start_on_continuation_line (struct window *);
843 static Lisp_Object safe_eval_handler (Lisp_Object);
844 static void insert_left_trunc_glyphs (struct it *);
845 static struct glyph_row *get_overlay_arrow_glyph_row (struct window *,
846 Lisp_Object);
847 static void extend_face_to_end_of_line (struct it *);
848 static int append_space_for_newline (struct it *, int);
849 static int cursor_row_fully_visible_p (struct window *, int, int);
850 static int try_scrolling (Lisp_Object, int, ptrdiff_t, ptrdiff_t, int, int);
851 static int try_cursor_movement (Lisp_Object, struct text_pos, int *);
852 static int trailing_whitespace_p (ptrdiff_t);
853 static intmax_t message_log_check_duplicate (ptrdiff_t, ptrdiff_t);
854 static void push_it (struct it *, struct text_pos *);
855 static void iterate_out_of_display_property (struct it *);
856 static void pop_it (struct it *);
857 static void sync_frame_with_window_matrix_rows (struct window *);
858 static void select_frame_for_redisplay (Lisp_Object);
859 static void redisplay_internal (void);
860 static int echo_area_display (int);
861 static void redisplay_windows (Lisp_Object);
862 static void redisplay_window (Lisp_Object, int);
863 static Lisp_Object redisplay_window_error (Lisp_Object);
864 static Lisp_Object redisplay_window_0 (Lisp_Object);
865 static Lisp_Object redisplay_window_1 (Lisp_Object);
866 static int set_cursor_from_row (struct window *, struct glyph_row *,
867 struct glyph_matrix *, ptrdiff_t, ptrdiff_t,
868 int, int);
869 static int update_menu_bar (struct frame *, int, int);
870 static int try_window_reusing_current_matrix (struct window *);
871 static int try_window_id (struct window *);
872 static int display_line (struct it *);
873 static int display_mode_lines (struct window *);
874 static int display_mode_line (struct window *, enum face_id, Lisp_Object);
875 static int display_mode_element (struct it *, int, int, int, Lisp_Object, Lisp_Object, int);
876 static int store_mode_line_string (const char *, Lisp_Object, int, int, int, Lisp_Object);
877 static const char *decode_mode_spec (struct window *, int, int, Lisp_Object *);
878 static void display_menu_bar (struct window *);
879 static ptrdiff_t display_count_lines (ptrdiff_t, ptrdiff_t, ptrdiff_t,
880 ptrdiff_t *);
881 static int display_string (const char *, Lisp_Object, Lisp_Object,
882 ptrdiff_t, ptrdiff_t, struct it *, int, int, int, int);
883 static void compute_line_metrics (struct it *);
884 static void run_redisplay_end_trigger_hook (struct it *);
885 static int get_overlay_strings (struct it *, ptrdiff_t);
886 static int get_overlay_strings_1 (struct it *, ptrdiff_t, int);
887 static void next_overlay_string (struct it *);
888 static void reseat (struct it *, struct text_pos, int);
889 static void reseat_1 (struct it *, struct text_pos, int);
890 static void back_to_previous_visible_line_start (struct it *);
891 void reseat_at_previous_visible_line_start (struct it *);
892 static void reseat_at_next_visible_line_start (struct it *, int);
893 static int next_element_from_ellipsis (struct it *);
894 static int next_element_from_display_vector (struct it *);
895 static int next_element_from_string (struct it *);
896 static int next_element_from_c_string (struct it *);
897 static int next_element_from_buffer (struct it *);
898 static int next_element_from_composition (struct it *);
899 static int next_element_from_image (struct it *);
900 #ifdef HAVE_XWIDGETS
901 static int next_element_from_xwidget(struct it *);
902 #endif
903 static int next_element_from_stretch (struct it *);
904 static void load_overlay_strings (struct it *, ptrdiff_t);
905 static int init_from_display_pos (struct it *, struct window *,
906 struct display_pos *);
907 static void reseat_to_string (struct it *, const char *,
908 Lisp_Object, ptrdiff_t, ptrdiff_t, int, int);
909 static int get_next_display_element (struct it *);
910 static enum move_it_result
911 move_it_in_display_line_to (struct it *, ptrdiff_t, int,
912 enum move_operation_enum);
913 void move_it_vertically_backward (struct it *, int);
914 static void init_to_row_start (struct it *, struct window *,
915 struct glyph_row *);
916 static int init_to_row_end (struct it *, struct window *,
917 struct glyph_row *);
918 static void back_to_previous_line_start (struct it *);
919 static int forward_to_next_line_start (struct it *, int *, struct bidi_it *);
920 static struct text_pos string_pos_nchars_ahead (struct text_pos,
921 Lisp_Object, ptrdiff_t);
922 static struct text_pos string_pos (ptrdiff_t, Lisp_Object);
923 static struct text_pos c_string_pos (ptrdiff_t, const char *, int);
924 static ptrdiff_t number_of_chars (const char *, int);
925 static void compute_stop_pos (struct it *);
926 static void compute_string_pos (struct text_pos *, struct text_pos,
927 Lisp_Object);
928 static int face_before_or_after_it_pos (struct it *, int);
929 static ptrdiff_t next_overlay_change (ptrdiff_t);
930 static int handle_display_spec (struct it *, Lisp_Object, Lisp_Object,
931 Lisp_Object, struct text_pos *, ptrdiff_t, int);
932 static int handle_single_display_spec (struct it *, Lisp_Object,
933 Lisp_Object, Lisp_Object,
934 struct text_pos *, ptrdiff_t, int, int);
935 static int underlying_face_id (struct it *);
936 static int in_ellipses_for_invisible_text_p (struct display_pos *,
937 struct window *);
938
939 #define face_before_it_pos(IT) face_before_or_after_it_pos ((IT), 1)
940 #define face_after_it_pos(IT) face_before_or_after_it_pos ((IT), 0)
941
942 #ifdef HAVE_WINDOW_SYSTEM
943
944 static void x_consider_frame_title (Lisp_Object);
945 static int tool_bar_lines_needed (struct frame *, int *);
946 static void update_tool_bar (struct frame *, int);
947 static void build_desired_tool_bar_string (struct frame *f);
948 static int redisplay_tool_bar (struct frame *);
949 static void display_tool_bar_line (struct it *, int);
950 static void notice_overwritten_cursor (struct window *,
951 enum glyph_row_area,
952 int, int, int, int);
953 static void append_stretch_glyph (struct it *, Lisp_Object,
954 int, int, int);
955
956
957 #endif /* HAVE_WINDOW_SYSTEM */
958
959 static void show_mouse_face (Mouse_HLInfo *, enum draw_glyphs_face);
960 static int coords_in_mouse_face_p (struct window *, int, int);
961
962
963 \f
964 /***********************************************************************
965 Window display dimensions
966 ***********************************************************************/
967
968 /* Return the bottom boundary y-position for text lines in window W.
969 This is the first y position at which a line cannot start.
970 It is relative to the top of the window.
971
972 This is the height of W minus the height of a mode line, if any. */
973
974 int
975 window_text_bottom_y (struct window *w)
976 {
977 int height = WINDOW_TOTAL_HEIGHT (w);
978
979 if (WINDOW_WANTS_MODELINE_P (w))
980 height -= CURRENT_MODE_LINE_HEIGHT (w);
981 return height;
982 }
983
984 /* Return the pixel width of display area AREA of window W. AREA < 0
985 means return the total width of W, not including fringes to
986 the left and right of the window. */
987
988 int
989 window_box_width (struct window *w, int area)
990 {
991 int cols = XFASTINT (w->total_cols);
992 int pixels = 0;
993
994 if (!w->pseudo_window_p)
995 {
996 cols -= WINDOW_SCROLL_BAR_COLS (w);
997
998 if (area == TEXT_AREA)
999 {
1000 if (INTEGERP (w->left_margin_cols))
1001 cols -= XFASTINT (w->left_margin_cols);
1002 if (INTEGERP (w->right_margin_cols))
1003 cols -= XFASTINT (w->right_margin_cols);
1004 pixels = -WINDOW_TOTAL_FRINGE_WIDTH (w);
1005 }
1006 else if (area == LEFT_MARGIN_AREA)
1007 {
1008 cols = (INTEGERP (w->left_margin_cols)
1009 ? XFASTINT (w->left_margin_cols) : 0);
1010 pixels = 0;
1011 }
1012 else if (area == RIGHT_MARGIN_AREA)
1013 {
1014 cols = (INTEGERP (w->right_margin_cols)
1015 ? XFASTINT (w->right_margin_cols) : 0);
1016 pixels = 0;
1017 }
1018 }
1019
1020 return cols * WINDOW_FRAME_COLUMN_WIDTH (w) + pixels;
1021 }
1022
1023
1024 /* Return the pixel height of the display area of window W, not
1025 including mode lines of W, if any. */
1026
1027 int
1028 window_box_height (struct window *w)
1029 {
1030 struct frame *f = XFRAME (w->frame);
1031 int height = WINDOW_TOTAL_HEIGHT (w);
1032
1033 xassert (height >= 0);
1034
1035 /* Note: the code below that determines the mode-line/header-line
1036 height is essentially the same as that contained in the macro
1037 CURRENT_{MODE,HEADER}_LINE_HEIGHT, except that it checks whether
1038 the appropriate glyph row has its `mode_line_p' flag set,
1039 and if it doesn't, uses estimate_mode_line_height instead. */
1040
1041 if (WINDOW_WANTS_MODELINE_P (w))
1042 {
1043 struct glyph_row *ml_row
1044 = (w->current_matrix && w->current_matrix->rows
1045 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
1046 : 0);
1047 if (ml_row && ml_row->mode_line_p)
1048 height -= ml_row->height;
1049 else
1050 height -= estimate_mode_line_height (f, CURRENT_MODE_LINE_FACE_ID (w));
1051 }
1052
1053 if (WINDOW_WANTS_HEADER_LINE_P (w))
1054 {
1055 struct glyph_row *hl_row
1056 = (w->current_matrix && w->current_matrix->rows
1057 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
1058 : 0);
1059 if (hl_row && hl_row->mode_line_p)
1060 height -= hl_row->height;
1061 else
1062 height -= estimate_mode_line_height (f, HEADER_LINE_FACE_ID);
1063 }
1064
1065 /* With a very small font and a mode-line that's taller than
1066 default, we might end up with a negative height. */
1067 return max (0, height);
1068 }
1069
1070 /* Return the window-relative coordinate of the left edge of display
1071 area AREA of window W. AREA < 0 means return the left edge of the
1072 whole window, to the right of the left fringe of W. */
1073
1074 int
1075 window_box_left_offset (struct window *w, int area)
1076 {
1077 int x;
1078
1079 if (w->pseudo_window_p)
1080 return 0;
1081
1082 x = WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
1083
1084 if (area == TEXT_AREA)
1085 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1086 + window_box_width (w, LEFT_MARGIN_AREA));
1087 else if (area == RIGHT_MARGIN_AREA)
1088 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1089 + window_box_width (w, LEFT_MARGIN_AREA)
1090 + window_box_width (w, TEXT_AREA)
1091 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
1092 ? 0
1093 : WINDOW_RIGHT_FRINGE_WIDTH (w)));
1094 else if (area == LEFT_MARGIN_AREA
1095 && WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w))
1096 x += WINDOW_LEFT_FRINGE_WIDTH (w);
1097
1098 return x;
1099 }
1100
1101
1102 /* Return the window-relative coordinate of the right edge of display
1103 area AREA of window W. AREA < 0 means return the right edge of the
1104 whole window, to the left of the right fringe of W. */
1105
1106 int
1107 window_box_right_offset (struct window *w, int area)
1108 {
1109 return window_box_left_offset (w, area) + window_box_width (w, area);
1110 }
1111
1112 /* Return the frame-relative coordinate of the left edge of display
1113 area AREA of window W. AREA < 0 means return the left edge of the
1114 whole window, to the right of the left fringe of W. */
1115
1116 int
1117 window_box_left (struct window *w, int area)
1118 {
1119 struct frame *f = XFRAME (w->frame);
1120 int x;
1121
1122 if (w->pseudo_window_p)
1123 return FRAME_INTERNAL_BORDER_WIDTH (f);
1124
1125 x = (WINDOW_LEFT_EDGE_X (w)
1126 + window_box_left_offset (w, area));
1127
1128 return x;
1129 }
1130
1131
1132 /* Return the frame-relative coordinate of the right edge of display
1133 area AREA of window W. AREA < 0 means return the right edge of the
1134 whole window, to the left of the right fringe of W. */
1135
1136 int
1137 window_box_right (struct window *w, int area)
1138 {
1139 return window_box_left (w, area) + window_box_width (w, area);
1140 }
1141
1142 /* Get the bounding box of the display area AREA of window W, without
1143 mode lines, in frame-relative coordinates. AREA < 0 means the
1144 whole window, not including the left and right fringes of
1145 the window. Return in *BOX_X and *BOX_Y the frame-relative pixel
1146 coordinates of the upper-left corner of the box. Return in
1147 *BOX_WIDTH, and *BOX_HEIGHT the pixel width and height of the box. */
1148
1149 void
1150 window_box (struct window *w, int area, int *box_x, int *box_y,
1151 int *box_width, int *box_height)
1152 {
1153 if (box_width)
1154 *box_width = window_box_width (w, area);
1155 if (box_height)
1156 *box_height = window_box_height (w);
1157 if (box_x)
1158 *box_x = window_box_left (w, area);
1159 if (box_y)
1160 {
1161 *box_y = WINDOW_TOP_EDGE_Y (w);
1162 if (WINDOW_WANTS_HEADER_LINE_P (w))
1163 *box_y += CURRENT_HEADER_LINE_HEIGHT (w);
1164 }
1165 }
1166
1167
1168 /* Get the bounding box of the display area AREA of window W, without
1169 mode lines. AREA < 0 means the whole window, not including the
1170 left and right fringe of the window. Return in *TOP_LEFT_X
1171 and TOP_LEFT_Y the frame-relative pixel coordinates of the
1172 upper-left corner of the box. Return in *BOTTOM_RIGHT_X, and
1173 *BOTTOM_RIGHT_Y the coordinates of the bottom-right corner of the
1174 box. */
1175
1176 static inline void
1177 window_box_edges (struct window *w, int area, int *top_left_x, int *top_left_y,
1178 int *bottom_right_x, int *bottom_right_y)
1179 {
1180 window_box (w, area, top_left_x, top_left_y, bottom_right_x,
1181 bottom_right_y);
1182 *bottom_right_x += *top_left_x;
1183 *bottom_right_y += *top_left_y;
1184 }
1185
1186
1187 \f
1188 /***********************************************************************
1189 Utilities
1190 ***********************************************************************/
1191
1192 /* Return the bottom y-position of the line the iterator IT is in.
1193 This can modify IT's settings. */
1194
1195 int
1196 line_bottom_y (struct it *it)
1197 {
1198 int line_height = it->max_ascent + it->max_descent;
1199 int line_top_y = it->current_y;
1200
1201 if (line_height == 0)
1202 {
1203 if (last_height)
1204 line_height = last_height;
1205 else if (IT_CHARPOS (*it) < ZV)
1206 {
1207 move_it_by_lines (it, 1);
1208 line_height = (it->max_ascent || it->max_descent
1209 ? it->max_ascent + it->max_descent
1210 : last_height);
1211 }
1212 else
1213 {
1214 struct glyph_row *row = it->glyph_row;
1215
1216 /* Use the default character height. */
1217 it->glyph_row = NULL;
1218 it->what = IT_CHARACTER;
1219 it->c = ' ';
1220 it->len = 1;
1221 PRODUCE_GLYPHS (it);
1222 line_height = it->ascent + it->descent;
1223 it->glyph_row = row;
1224 }
1225 }
1226
1227 return line_top_y + line_height;
1228 }
1229
1230 /* Subroutine of pos_visible_p below. Extracts a display string, if
1231 any, from the display spec given as its argument. */
1232 static Lisp_Object
1233 string_from_display_spec (Lisp_Object spec)
1234 {
1235 if (CONSP (spec))
1236 {
1237 while (CONSP (spec))
1238 {
1239 if (STRINGP (XCAR (spec)))
1240 return XCAR (spec);
1241 spec = XCDR (spec);
1242 }
1243 }
1244 else if (VECTORP (spec))
1245 {
1246 ptrdiff_t i;
1247
1248 for (i = 0; i < ASIZE (spec); i++)
1249 {
1250 if (STRINGP (AREF (spec, i)))
1251 return AREF (spec, i);
1252 }
1253 return Qnil;
1254 }
1255
1256 return spec;
1257 }
1258
1259 /* Return 1 if position CHARPOS is visible in window W.
1260 CHARPOS < 0 means return info about WINDOW_END position.
1261 If visible, set *X and *Y to pixel coordinates of top left corner.
1262 Set *RTOP and *RBOT to pixel height of an invisible area of glyph at POS.
1263 Set *ROWH and *VPOS to row's visible height and VPOS (row number). */
1264
1265 int
1266 pos_visible_p (struct window *w, ptrdiff_t charpos, int *x, int *y,
1267 int *rtop, int *rbot, int *rowh, int *vpos)
1268 {
1269 struct it it;
1270 void *itdata = bidi_shelve_cache ();
1271 struct text_pos top;
1272 int visible_p = 0;
1273 struct buffer *old_buffer = NULL;
1274
1275 if (FRAME_INITIAL_P (XFRAME (WINDOW_FRAME (w))))
1276 return visible_p;
1277
1278 if (XBUFFER (w->buffer) != current_buffer)
1279 {
1280 old_buffer = current_buffer;
1281 set_buffer_internal_1 (XBUFFER (w->buffer));
1282 }
1283
1284 SET_TEXT_POS_FROM_MARKER (top, w->start);
1285 /* Scrolling a minibuffer window via scroll bar when the echo area
1286 shows long text sometimes resets the minibuffer contents behind
1287 our backs. */
1288 if (CHARPOS (top) > ZV)
1289 SET_TEXT_POS (top, BEGV, BEGV_BYTE);
1290
1291 /* Compute exact mode line heights. */
1292 if (WINDOW_WANTS_MODELINE_P (w))
1293 current_mode_line_height
1294 = display_mode_line (w, CURRENT_MODE_LINE_FACE_ID (w),
1295 BVAR (current_buffer, mode_line_format));
1296
1297 if (WINDOW_WANTS_HEADER_LINE_P (w))
1298 current_header_line_height
1299 = display_mode_line (w, HEADER_LINE_FACE_ID,
1300 BVAR (current_buffer, header_line_format));
1301
1302 start_display (&it, w, top);
1303 move_it_to (&it, charpos, -1, it.last_visible_y-1, -1,
1304 (charpos >= 0 ? MOVE_TO_POS : 0) | MOVE_TO_Y);
1305
1306 if (charpos >= 0
1307 && (((!it.bidi_p || it.bidi_it.scan_dir == 1)
1308 && IT_CHARPOS (it) >= charpos)
1309 /* When scanning backwards under bidi iteration, move_it_to
1310 stops at or _before_ CHARPOS, because it stops at or to
1311 the _right_ of the character at CHARPOS. */
1312 || (it.bidi_p && it.bidi_it.scan_dir == -1
1313 && IT_CHARPOS (it) <= charpos)))
1314 {
1315 /* We have reached CHARPOS, or passed it. How the call to
1316 move_it_to can overshoot: (i) If CHARPOS is on invisible text
1317 or covered by a display property, move_it_to stops at the end
1318 of the invisible text, to the right of CHARPOS. (ii) If
1319 CHARPOS is in a display vector, move_it_to stops on its last
1320 glyph. */
1321 int top_x = it.current_x;
1322 int top_y = it.current_y;
1323 /* Calling line_bottom_y may change it.method, it.position, etc. */
1324 enum it_method it_method = it.method;
1325 int bottom_y = (last_height = 0, line_bottom_y (&it));
1326 int window_top_y = WINDOW_HEADER_LINE_HEIGHT (w);
1327
1328 if (top_y < window_top_y)
1329 visible_p = bottom_y > window_top_y;
1330 else if (top_y < it.last_visible_y)
1331 visible_p = 1;
1332 if (bottom_y >= it.last_visible_y
1333 && it.bidi_p && it.bidi_it.scan_dir == -1
1334 && IT_CHARPOS (it) < charpos)
1335 {
1336 /* When the last line of the window is scanned backwards
1337 under bidi iteration, we could be duped into thinking
1338 that we have passed CHARPOS, when in fact move_it_to
1339 simply stopped short of CHARPOS because it reached
1340 last_visible_y. To see if that's what happened, we call
1341 move_it_to again with a slightly larger vertical limit,
1342 and see if it actually moved vertically; if it did, we
1343 didn't really reach CHARPOS, which is beyond window end. */
1344 struct it save_it = it;
1345 /* Why 10? because we don't know how many canonical lines
1346 will the height of the next line(s) be. So we guess. */
1347 int ten_more_lines =
1348 10 * FRAME_LINE_HEIGHT (XFRAME (WINDOW_FRAME (w)));
1349
1350 move_it_to (&it, charpos, -1, bottom_y + ten_more_lines, -1,
1351 MOVE_TO_POS | MOVE_TO_Y);
1352 if (it.current_y > top_y)
1353 visible_p = 0;
1354
1355 it = save_it;
1356 }
1357 if (visible_p)
1358 {
1359 if (it_method == GET_FROM_DISPLAY_VECTOR)
1360 {
1361 /* We stopped on the last glyph of a display vector.
1362 Try and recompute. Hack alert! */
1363 if (charpos < 2 || top.charpos >= charpos)
1364 top_x = it.glyph_row->x;
1365 else
1366 {
1367 struct it it2;
1368 start_display (&it2, w, top);
1369 move_it_to (&it2, charpos - 1, -1, -1, -1, MOVE_TO_POS);
1370 get_next_display_element (&it2);
1371 PRODUCE_GLYPHS (&it2);
1372 if (ITERATOR_AT_END_OF_LINE_P (&it2)
1373 || it2.current_x > it2.last_visible_x)
1374 top_x = it.glyph_row->x;
1375 else
1376 {
1377 top_x = it2.current_x;
1378 top_y = it2.current_y;
1379 }
1380 }
1381 }
1382 else if (IT_CHARPOS (it) != charpos)
1383 {
1384 Lisp_Object cpos = make_number (charpos);
1385 Lisp_Object spec = Fget_char_property (cpos, Qdisplay, Qnil);
1386 Lisp_Object string = string_from_display_spec (spec);
1387 int newline_in_string = 0;
1388
1389 if (STRINGP (string))
1390 {
1391 const char *s = SSDATA (string);
1392 const char *e = s + SBYTES (string);
1393 while (s < e)
1394 {
1395 if (*s++ == '\n')
1396 {
1397 newline_in_string = 1;
1398 break;
1399 }
1400 }
1401 }
1402 /* The tricky code below is needed because there's a
1403 discrepancy between move_it_to and how we set cursor
1404 when the display line ends in a newline from a
1405 display string. move_it_to will stop _after_ such
1406 display strings, whereas set_cursor_from_row
1407 conspires with cursor_row_p to place the cursor on
1408 the first glyph produced from the display string. */
1409
1410 /* We have overshoot PT because it is covered by a
1411 display property whose value is a string. If the
1412 string includes embedded newlines, we are also in the
1413 wrong display line. Backtrack to the correct line,
1414 where the display string begins. */
1415 if (newline_in_string)
1416 {
1417 Lisp_Object startpos, endpos;
1418 EMACS_INT start, end;
1419 struct it it3;
1420 int it3_moved;
1421
1422 /* Find the first and the last buffer positions
1423 covered by the display string. */
1424 endpos =
1425 Fnext_single_char_property_change (cpos, Qdisplay,
1426 Qnil, Qnil);
1427 startpos =
1428 Fprevious_single_char_property_change (endpos, Qdisplay,
1429 Qnil, Qnil);
1430 start = XFASTINT (startpos);
1431 end = XFASTINT (endpos);
1432 /* Move to the last buffer position before the
1433 display property. */
1434 start_display (&it3, w, top);
1435 move_it_to (&it3, start - 1, -1, -1, -1, MOVE_TO_POS);
1436 /* Move forward one more line if the position before
1437 the display string is a newline or if it is the
1438 rightmost character on a line that is
1439 continued or word-wrapped. */
1440 if (it3.method == GET_FROM_BUFFER
1441 && it3.c == '\n')
1442 move_it_by_lines (&it3, 1);
1443 else if (move_it_in_display_line_to (&it3, -1,
1444 it3.current_x
1445 + it3.pixel_width,
1446 MOVE_TO_X)
1447 == MOVE_LINE_CONTINUED)
1448 {
1449 move_it_by_lines (&it3, 1);
1450 /* When we are under word-wrap, the #$@%!
1451 move_it_by_lines moves 2 lines, so we need to
1452 fix that up. */
1453 if (it3.line_wrap == WORD_WRAP)
1454 move_it_by_lines (&it3, -1);
1455 }
1456
1457 /* Record the vertical coordinate of the display
1458 line where we wound up. */
1459 top_y = it3.current_y;
1460 if (it3.bidi_p)
1461 {
1462 /* When characters are reordered for display,
1463 the character displayed to the left of the
1464 display string could be _after_ the display
1465 property in the logical order. Use the
1466 smallest vertical position of these two. */
1467 start_display (&it3, w, top);
1468 move_it_to (&it3, end + 1, -1, -1, -1, MOVE_TO_POS);
1469 if (it3.current_y < top_y)
1470 top_y = it3.current_y;
1471 }
1472 /* Move from the top of the window to the beginning
1473 of the display line where the display string
1474 begins. */
1475 start_display (&it3, w, top);
1476 move_it_to (&it3, -1, 0, top_y, -1, MOVE_TO_X | MOVE_TO_Y);
1477 /* If it3_moved stays zero after the 'while' loop
1478 below, that means we already were at a newline
1479 before the loop (e.g., the display string begins
1480 with a newline), so we don't need to (and cannot)
1481 inspect the glyphs of it3.glyph_row, because
1482 PRODUCE_GLYPHS will not produce anything for a
1483 newline, and thus it3.glyph_row stays at its
1484 stale content it got at top of the window. */
1485 it3_moved = 0;
1486 /* Finally, advance the iterator until we hit the
1487 first display element whose character position is
1488 CHARPOS, or until the first newline from the
1489 display string, which signals the end of the
1490 display line. */
1491 while (get_next_display_element (&it3))
1492 {
1493 PRODUCE_GLYPHS (&it3);
1494 if (IT_CHARPOS (it3) == charpos
1495 || ITERATOR_AT_END_OF_LINE_P (&it3))
1496 break;
1497 it3_moved = 1;
1498 set_iterator_to_next (&it3, 0);
1499 }
1500 top_x = it3.current_x - it3.pixel_width;
1501 /* Normally, we would exit the above loop because we
1502 found the display element whose character
1503 position is CHARPOS. For the contingency that we
1504 didn't, and stopped at the first newline from the
1505 display string, move back over the glyphs
1506 produced from the string, until we find the
1507 rightmost glyph not from the string. */
1508 if (it3_moved
1509 && IT_CHARPOS (it3) != charpos && EQ (it3.object, string))
1510 {
1511 struct glyph *g = it3.glyph_row->glyphs[TEXT_AREA]
1512 + it3.glyph_row->used[TEXT_AREA];
1513
1514 while (EQ ((g - 1)->object, string))
1515 {
1516 --g;
1517 top_x -= g->pixel_width;
1518 }
1519 xassert (g < it3.glyph_row->glyphs[TEXT_AREA]
1520 + it3.glyph_row->used[TEXT_AREA]);
1521 }
1522 }
1523 }
1524
1525 *x = top_x;
1526 *y = max (top_y + max (0, it.max_ascent - it.ascent), window_top_y);
1527 *rtop = max (0, window_top_y - top_y);
1528 *rbot = max (0, bottom_y - it.last_visible_y);
1529 *rowh = max (0, (min (bottom_y, it.last_visible_y)
1530 - max (top_y, window_top_y)));
1531 *vpos = it.vpos;
1532 }
1533 }
1534 else
1535 {
1536 /* We were asked to provide info about WINDOW_END. */
1537 struct it it2;
1538 void *it2data = NULL;
1539
1540 SAVE_IT (it2, it, it2data);
1541 if (IT_CHARPOS (it) < ZV && FETCH_BYTE (IT_BYTEPOS (it)) != '\n')
1542 move_it_by_lines (&it, 1);
1543 if (charpos < IT_CHARPOS (it)
1544 || (it.what == IT_EOB && charpos == IT_CHARPOS (it)))
1545 {
1546 visible_p = 1;
1547 RESTORE_IT (&it2, &it2, it2data);
1548 move_it_to (&it2, charpos, -1, -1, -1, MOVE_TO_POS);
1549 *x = it2.current_x;
1550 *y = it2.current_y + it2.max_ascent - it2.ascent;
1551 *rtop = max (0, -it2.current_y);
1552 *rbot = max (0, ((it2.current_y + it2.max_ascent + it2.max_descent)
1553 - it.last_visible_y));
1554 *rowh = max (0, (min (it2.current_y + it2.max_ascent + it2.max_descent,
1555 it.last_visible_y)
1556 - max (it2.current_y,
1557 WINDOW_HEADER_LINE_HEIGHT (w))));
1558 *vpos = it2.vpos;
1559 }
1560 else
1561 bidi_unshelve_cache (it2data, 1);
1562 }
1563 bidi_unshelve_cache (itdata, 0);
1564
1565 if (old_buffer)
1566 set_buffer_internal_1 (old_buffer);
1567
1568 current_header_line_height = current_mode_line_height = -1;
1569
1570 if (visible_p && XFASTINT (w->hscroll) > 0)
1571 *x -= XFASTINT (w->hscroll) * WINDOW_FRAME_COLUMN_WIDTH (w);
1572
1573 #if 0
1574 /* Debugging code. */
1575 if (visible_p)
1576 fprintf (stderr, "+pv pt=%d vs=%d --> x=%d y=%d rt=%d rb=%d rh=%d vp=%d\n",
1577 charpos, w->vscroll, *x, *y, *rtop, *rbot, *rowh, *vpos);
1578 else
1579 fprintf (stderr, "-pv pt=%d vs=%d\n", charpos, w->vscroll);
1580 #endif
1581
1582 return visible_p;
1583 }
1584
1585
1586 /* Return the next character from STR. Return in *LEN the length of
1587 the character. This is like STRING_CHAR_AND_LENGTH but never
1588 returns an invalid character. If we find one, we return a `?', but
1589 with the length of the invalid character. */
1590
1591 static inline int
1592 string_char_and_length (const unsigned char *str, int *len)
1593 {
1594 int c;
1595
1596 c = STRING_CHAR_AND_LENGTH (str, *len);
1597 if (!CHAR_VALID_P (c))
1598 /* We may not change the length here because other places in Emacs
1599 don't use this function, i.e. they silently accept invalid
1600 characters. */
1601 c = '?';
1602
1603 return c;
1604 }
1605
1606
1607
1608 /* Given a position POS containing a valid character and byte position
1609 in STRING, return the position NCHARS ahead (NCHARS >= 0). */
1610
1611 static struct text_pos
1612 string_pos_nchars_ahead (struct text_pos pos, Lisp_Object string, ptrdiff_t nchars)
1613 {
1614 xassert (STRINGP (string) && nchars >= 0);
1615
1616 if (STRING_MULTIBYTE (string))
1617 {
1618 const unsigned char *p = SDATA (string) + BYTEPOS (pos);
1619 int len;
1620
1621 while (nchars--)
1622 {
1623 string_char_and_length (p, &len);
1624 p += len;
1625 CHARPOS (pos) += 1;
1626 BYTEPOS (pos) += len;
1627 }
1628 }
1629 else
1630 SET_TEXT_POS (pos, CHARPOS (pos) + nchars, BYTEPOS (pos) + nchars);
1631
1632 return pos;
1633 }
1634
1635
1636 /* Value is the text position, i.e. character and byte position,
1637 for character position CHARPOS in STRING. */
1638
1639 static inline struct text_pos
1640 string_pos (ptrdiff_t charpos, Lisp_Object string)
1641 {
1642 struct text_pos pos;
1643 xassert (STRINGP (string));
1644 xassert (charpos >= 0);
1645 SET_TEXT_POS (pos, charpos, string_char_to_byte (string, charpos));
1646 return pos;
1647 }
1648
1649
1650 /* Value is a text position, i.e. character and byte position, for
1651 character position CHARPOS in C string S. MULTIBYTE_P non-zero
1652 means recognize multibyte characters. */
1653
1654 static struct text_pos
1655 c_string_pos (ptrdiff_t charpos, const char *s, int multibyte_p)
1656 {
1657 struct text_pos pos;
1658
1659 xassert (s != NULL);
1660 xassert (charpos >= 0);
1661
1662 if (multibyte_p)
1663 {
1664 int len;
1665
1666 SET_TEXT_POS (pos, 0, 0);
1667 while (charpos--)
1668 {
1669 string_char_and_length ((const unsigned char *) s, &len);
1670 s += len;
1671 CHARPOS (pos) += 1;
1672 BYTEPOS (pos) += len;
1673 }
1674 }
1675 else
1676 SET_TEXT_POS (pos, charpos, charpos);
1677
1678 return pos;
1679 }
1680
1681
1682 /* Value is the number of characters in C string S. MULTIBYTE_P
1683 non-zero means recognize multibyte characters. */
1684
1685 static ptrdiff_t
1686 number_of_chars (const char *s, int multibyte_p)
1687 {
1688 ptrdiff_t nchars;
1689
1690 if (multibyte_p)
1691 {
1692 ptrdiff_t rest = strlen (s);
1693 int len;
1694 const unsigned char *p = (const unsigned char *) s;
1695
1696 for (nchars = 0; rest > 0; ++nchars)
1697 {
1698 string_char_and_length (p, &len);
1699 rest -= len, p += len;
1700 }
1701 }
1702 else
1703 nchars = strlen (s);
1704
1705 return nchars;
1706 }
1707
1708
1709 /* Compute byte position NEWPOS->bytepos corresponding to
1710 NEWPOS->charpos. POS is a known position in string STRING.
1711 NEWPOS->charpos must be >= POS.charpos. */
1712
1713 static void
1714 compute_string_pos (struct text_pos *newpos, struct text_pos pos, Lisp_Object string)
1715 {
1716 xassert (STRINGP (string));
1717 xassert (CHARPOS (*newpos) >= CHARPOS (pos));
1718
1719 if (STRING_MULTIBYTE (string))
1720 *newpos = string_pos_nchars_ahead (pos, string,
1721 CHARPOS (*newpos) - CHARPOS (pos));
1722 else
1723 BYTEPOS (*newpos) = CHARPOS (*newpos);
1724 }
1725
1726 /* EXPORT:
1727 Return an estimation of the pixel height of mode or header lines on
1728 frame F. FACE_ID specifies what line's height to estimate. */
1729
1730 int
1731 estimate_mode_line_height (struct frame *f, enum face_id face_id)
1732 {
1733 #ifdef HAVE_WINDOW_SYSTEM
1734 if (FRAME_WINDOW_P (f))
1735 {
1736 int height = FONT_HEIGHT (FRAME_FONT (f));
1737
1738 /* This function is called so early when Emacs starts that the face
1739 cache and mode line face are not yet initialized. */
1740 if (FRAME_FACE_CACHE (f))
1741 {
1742 struct face *face = FACE_FROM_ID (f, face_id);
1743 if (face)
1744 {
1745 if (face->font)
1746 height = FONT_HEIGHT (face->font);
1747 if (face->box_line_width > 0)
1748 height += 2 * face->box_line_width;
1749 }
1750 }
1751
1752 return height;
1753 }
1754 #endif
1755
1756 return 1;
1757 }
1758
1759 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
1760 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
1761 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
1762 not force the value into range. */
1763
1764 void
1765 pixel_to_glyph_coords (FRAME_PTR f, register int pix_x, register int pix_y,
1766 int *x, int *y, NativeRectangle *bounds, int noclip)
1767 {
1768
1769 #ifdef HAVE_WINDOW_SYSTEM
1770 if (FRAME_WINDOW_P (f))
1771 {
1772 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to round down
1773 even for negative values. */
1774 if (pix_x < 0)
1775 pix_x -= FRAME_COLUMN_WIDTH (f) - 1;
1776 if (pix_y < 0)
1777 pix_y -= FRAME_LINE_HEIGHT (f) - 1;
1778
1779 pix_x = FRAME_PIXEL_X_TO_COL (f, pix_x);
1780 pix_y = FRAME_PIXEL_Y_TO_LINE (f, pix_y);
1781
1782 if (bounds)
1783 STORE_NATIVE_RECT (*bounds,
1784 FRAME_COL_TO_PIXEL_X (f, pix_x),
1785 FRAME_LINE_TO_PIXEL_Y (f, pix_y),
1786 FRAME_COLUMN_WIDTH (f) - 1,
1787 FRAME_LINE_HEIGHT (f) - 1);
1788
1789 if (!noclip)
1790 {
1791 if (pix_x < 0)
1792 pix_x = 0;
1793 else if (pix_x > FRAME_TOTAL_COLS (f))
1794 pix_x = FRAME_TOTAL_COLS (f);
1795
1796 if (pix_y < 0)
1797 pix_y = 0;
1798 else if (pix_y > FRAME_LINES (f))
1799 pix_y = FRAME_LINES (f);
1800 }
1801 }
1802 #endif
1803
1804 *x = pix_x;
1805 *y = pix_y;
1806 }
1807
1808
1809 /* Find the glyph under window-relative coordinates X/Y in window W.
1810 Consider only glyphs from buffer text, i.e. no glyphs from overlay
1811 strings. Return in *HPOS and *VPOS the row and column number of
1812 the glyph found. Return in *AREA the glyph area containing X.
1813 Value is a pointer to the glyph found or null if X/Y is not on
1814 text, or we can't tell because W's current matrix is not up to
1815 date. */
1816
1817 static
1818 struct glyph *
1819 x_y_to_hpos_vpos (struct window *w, int x, int y, int *hpos, int *vpos,
1820 int *dx, int *dy, int *area)
1821 {
1822 struct glyph *glyph, *end;
1823 struct glyph_row *row = NULL;
1824 int x0, i;
1825
1826 /* Find row containing Y. Give up if some row is not enabled. */
1827 for (i = 0; i < w->current_matrix->nrows; ++i)
1828 {
1829 row = MATRIX_ROW (w->current_matrix, i);
1830 if (!row->enabled_p)
1831 return NULL;
1832 if (y >= row->y && y < MATRIX_ROW_BOTTOM_Y (row))
1833 break;
1834 }
1835
1836 *vpos = i;
1837 *hpos = 0;
1838
1839 /* Give up if Y is not in the window. */
1840 if (i == w->current_matrix->nrows)
1841 return NULL;
1842
1843 /* Get the glyph area containing X. */
1844 if (w->pseudo_window_p)
1845 {
1846 *area = TEXT_AREA;
1847 x0 = 0;
1848 }
1849 else
1850 {
1851 if (x < window_box_left_offset (w, TEXT_AREA))
1852 {
1853 *area = LEFT_MARGIN_AREA;
1854 x0 = window_box_left_offset (w, LEFT_MARGIN_AREA);
1855 }
1856 else if (x < window_box_right_offset (w, TEXT_AREA))
1857 {
1858 *area = TEXT_AREA;
1859 x0 = window_box_left_offset (w, TEXT_AREA) + min (row->x, 0);
1860 }
1861 else
1862 {
1863 *area = RIGHT_MARGIN_AREA;
1864 x0 = window_box_left_offset (w, RIGHT_MARGIN_AREA);
1865 }
1866 }
1867
1868 /* Find glyph containing X. */
1869 glyph = row->glyphs[*area];
1870 end = glyph + row->used[*area];
1871 x -= x0;
1872 while (glyph < end && x >= glyph->pixel_width)
1873 {
1874 x -= glyph->pixel_width;
1875 ++glyph;
1876 }
1877
1878 if (glyph == end)
1879 return NULL;
1880
1881 if (dx)
1882 {
1883 *dx = x;
1884 *dy = y - (row->y + row->ascent - glyph->ascent);
1885 }
1886
1887 *hpos = glyph - row->glyphs[*area];
1888 return glyph;
1889 }
1890
1891 /* Convert frame-relative x/y to coordinates relative to window W.
1892 Takes pseudo-windows into account. */
1893
1894 static void
1895 frame_to_window_pixel_xy (struct window *w, int *x, int *y)
1896 {
1897 if (w->pseudo_window_p)
1898 {
1899 /* A pseudo-window is always full-width, and starts at the
1900 left edge of the frame, plus a frame border. */
1901 struct frame *f = XFRAME (w->frame);
1902 *x -= FRAME_INTERNAL_BORDER_WIDTH (f);
1903 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1904 }
1905 else
1906 {
1907 *x -= WINDOW_LEFT_EDGE_X (w);
1908 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1909 }
1910 }
1911
1912 #ifdef HAVE_WINDOW_SYSTEM
1913
1914 /* EXPORT:
1915 Return in RECTS[] at most N clipping rectangles for glyph string S.
1916 Return the number of stored rectangles. */
1917
1918 int
1919 get_glyph_string_clip_rects (struct glyph_string *s, NativeRectangle *rects, int n)
1920 {
1921 XRectangle r;
1922
1923 if (n <= 0)
1924 return 0;
1925
1926 if (s->row->full_width_p)
1927 {
1928 /* Draw full-width. X coordinates are relative to S->w->left_col. */
1929 r.x = WINDOW_LEFT_EDGE_X (s->w);
1930 r.width = WINDOW_TOTAL_WIDTH (s->w);
1931
1932 /* Unless displaying a mode or menu bar line, which are always
1933 fully visible, clip to the visible part of the row. */
1934 if (s->w->pseudo_window_p)
1935 r.height = s->row->visible_height;
1936 else
1937 r.height = s->height;
1938 }
1939 else
1940 {
1941 /* This is a text line that may be partially visible. */
1942 r.x = window_box_left (s->w, s->area);
1943 r.width = window_box_width (s->w, s->area);
1944 r.height = s->row->visible_height;
1945 }
1946
1947 if (s->clip_head)
1948 if (r.x < s->clip_head->x)
1949 {
1950 if (r.width >= s->clip_head->x - r.x)
1951 r.width -= s->clip_head->x - r.x;
1952 else
1953 r.width = 0;
1954 r.x = s->clip_head->x;
1955 }
1956 if (s->clip_tail)
1957 if (r.x + r.width > s->clip_tail->x + s->clip_tail->background_width)
1958 {
1959 if (s->clip_tail->x + s->clip_tail->background_width >= r.x)
1960 r.width = s->clip_tail->x + s->clip_tail->background_width - r.x;
1961 else
1962 r.width = 0;
1963 }
1964
1965 /* If S draws overlapping rows, it's sufficient to use the top and
1966 bottom of the window for clipping because this glyph string
1967 intentionally draws over other lines. */
1968 if (s->for_overlaps)
1969 {
1970 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
1971 r.height = window_text_bottom_y (s->w) - r.y;
1972
1973 /* Alas, the above simple strategy does not work for the
1974 environments with anti-aliased text: if the same text is
1975 drawn onto the same place multiple times, it gets thicker.
1976 If the overlap we are processing is for the erased cursor, we
1977 take the intersection with the rectangle of the cursor. */
1978 if (s->for_overlaps & OVERLAPS_ERASED_CURSOR)
1979 {
1980 XRectangle rc, r_save = r;
1981
1982 rc.x = WINDOW_TEXT_TO_FRAME_PIXEL_X (s->w, s->w->phys_cursor.x);
1983 rc.y = s->w->phys_cursor.y;
1984 rc.width = s->w->phys_cursor_width;
1985 rc.height = s->w->phys_cursor_height;
1986
1987 x_intersect_rectangles (&r_save, &rc, &r);
1988 }
1989 }
1990 else
1991 {
1992 /* Don't use S->y for clipping because it doesn't take partially
1993 visible lines into account. For example, it can be negative for
1994 partially visible lines at the top of a window. */
1995 if (!s->row->full_width_p
1996 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s->w, s->row))
1997 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
1998 else
1999 r.y = max (0, s->row->y);
2000 }
2001
2002 r.y = WINDOW_TO_FRAME_PIXEL_Y (s->w, r.y);
2003
2004 /* If drawing the cursor, don't let glyph draw outside its
2005 advertised boundaries. Cleartype does this under some circumstances. */
2006 if (s->hl == DRAW_CURSOR)
2007 {
2008 struct glyph *glyph = s->first_glyph;
2009 int height, max_y;
2010
2011 if (s->x > r.x)
2012 {
2013 r.width -= s->x - r.x;
2014 r.x = s->x;
2015 }
2016 r.width = min (r.width, glyph->pixel_width);
2017
2018 /* If r.y is below window bottom, ensure that we still see a cursor. */
2019 height = min (glyph->ascent + glyph->descent,
2020 min (FRAME_LINE_HEIGHT (s->f), s->row->visible_height));
2021 max_y = window_text_bottom_y (s->w) - height;
2022 max_y = WINDOW_TO_FRAME_PIXEL_Y (s->w, max_y);
2023 if (s->ybase - glyph->ascent > max_y)
2024 {
2025 r.y = max_y;
2026 r.height = height;
2027 }
2028 else
2029 {
2030 /* Don't draw cursor glyph taller than our actual glyph. */
2031 height = max (FRAME_LINE_HEIGHT (s->f), glyph->ascent + glyph->descent);
2032 if (height < r.height)
2033 {
2034 max_y = r.y + r.height;
2035 r.y = min (max_y, max (r.y, s->ybase + glyph->descent - height));
2036 r.height = min (max_y - r.y, height);
2037 }
2038 }
2039 }
2040
2041 if (s->row->clip)
2042 {
2043 XRectangle r_save = r;
2044
2045 if (! x_intersect_rectangles (&r_save, s->row->clip, &r))
2046 r.width = 0;
2047 }
2048
2049 if ((s->for_overlaps & OVERLAPS_BOTH) == 0
2050 || ((s->for_overlaps & OVERLAPS_BOTH) == OVERLAPS_BOTH && n == 1))
2051 {
2052 #ifdef CONVERT_FROM_XRECT
2053 CONVERT_FROM_XRECT (r, *rects);
2054 #else
2055 *rects = r;
2056 #endif
2057 return 1;
2058 }
2059 else
2060 {
2061 /* If we are processing overlapping and allowed to return
2062 multiple clipping rectangles, we exclude the row of the glyph
2063 string from the clipping rectangle. This is to avoid drawing
2064 the same text on the environment with anti-aliasing. */
2065 #ifdef CONVERT_FROM_XRECT
2066 XRectangle rs[2];
2067 #else
2068 XRectangle *rs = rects;
2069 #endif
2070 int i = 0, row_y = WINDOW_TO_FRAME_PIXEL_Y (s->w, s->row->y);
2071
2072 if (s->for_overlaps & OVERLAPS_PRED)
2073 {
2074 rs[i] = r;
2075 if (r.y + r.height > row_y)
2076 {
2077 if (r.y < row_y)
2078 rs[i].height = row_y - r.y;
2079 else
2080 rs[i].height = 0;
2081 }
2082 i++;
2083 }
2084 if (s->for_overlaps & OVERLAPS_SUCC)
2085 {
2086 rs[i] = r;
2087 if (r.y < row_y + s->row->visible_height)
2088 {
2089 if (r.y + r.height > row_y + s->row->visible_height)
2090 {
2091 rs[i].y = row_y + s->row->visible_height;
2092 rs[i].height = r.y + r.height - rs[i].y;
2093 }
2094 else
2095 rs[i].height = 0;
2096 }
2097 i++;
2098 }
2099
2100 n = i;
2101 #ifdef CONVERT_FROM_XRECT
2102 for (i = 0; i < n; i++)
2103 CONVERT_FROM_XRECT (rs[i], rects[i]);
2104 #endif
2105 return n;
2106 }
2107 }
2108
2109 /* EXPORT:
2110 Return in *NR the clipping rectangle for glyph string S. */
2111
2112 void
2113 get_glyph_string_clip_rect (struct glyph_string *s, NativeRectangle *nr)
2114 {
2115 get_glyph_string_clip_rects (s, nr, 1);
2116 }
2117
2118
2119 /* EXPORT:
2120 Return the position and height of the phys cursor in window W.
2121 Set w->phys_cursor_width to width of phys cursor.
2122 */
2123
2124 void
2125 get_phys_cursor_geometry (struct window *w, struct glyph_row *row,
2126 struct glyph *glyph, int *xp, int *yp, int *heightp)
2127 {
2128 struct frame *f = XFRAME (WINDOW_FRAME (w));
2129 int x, y, wd, h, h0, y0;
2130
2131 /* Compute the width of the rectangle to draw. If on a stretch
2132 glyph, and `x-stretch-block-cursor' is nil, don't draw a
2133 rectangle as wide as the glyph, but use a canonical character
2134 width instead. */
2135 wd = glyph->pixel_width - 1;
2136 #if defined (HAVE_NTGUI) || defined (HAVE_NS)
2137 wd++; /* Why? */
2138 #endif
2139
2140 x = w->phys_cursor.x;
2141 if (x < 0)
2142 {
2143 wd += x;
2144 x = 0;
2145 }
2146
2147 if (glyph->type == STRETCH_GLYPH
2148 && !x_stretch_cursor_p)
2149 wd = min (FRAME_COLUMN_WIDTH (f), wd);
2150 w->phys_cursor_width = wd;
2151
2152 y = w->phys_cursor.y + row->ascent - glyph->ascent;
2153
2154 /* If y is below window bottom, ensure that we still see a cursor. */
2155 h0 = min (FRAME_LINE_HEIGHT (f), row->visible_height);
2156
2157 h = max (h0, glyph->ascent + glyph->descent);
2158 h0 = min (h0, glyph->ascent + glyph->descent);
2159
2160 y0 = WINDOW_HEADER_LINE_HEIGHT (w);
2161 if (y < y0)
2162 {
2163 h = max (h - (y0 - y) + 1, h0);
2164 y = y0 - 1;
2165 }
2166 else
2167 {
2168 y0 = window_text_bottom_y (w) - h0;
2169 if (y > y0)
2170 {
2171 h += y - y0;
2172 y = y0;
2173 }
2174 }
2175
2176 *xp = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, x);
2177 *yp = WINDOW_TO_FRAME_PIXEL_Y (w, y);
2178 *heightp = h;
2179 }
2180
2181 /*
2182 * Remember which glyph the mouse is over.
2183 */
2184
2185 void
2186 remember_mouse_glyph (struct frame *f, int gx, int gy, NativeRectangle *rect)
2187 {
2188 Lisp_Object window;
2189 struct window *w;
2190 struct glyph_row *r, *gr, *end_row;
2191 enum window_part part;
2192 enum glyph_row_area area;
2193 int x, y, width, height;
2194
2195 /* Try to determine frame pixel position and size of the glyph under
2196 frame pixel coordinates X/Y on frame F. */
2197
2198 if (!f->glyphs_initialized_p
2199 || (window = window_from_coordinates (f, gx, gy, &part, 0),
2200 NILP (window)))
2201 {
2202 width = FRAME_SMALLEST_CHAR_WIDTH (f);
2203 height = FRAME_SMALLEST_FONT_HEIGHT (f);
2204 goto virtual_glyph;
2205 }
2206
2207 w = XWINDOW (window);
2208 width = WINDOW_FRAME_COLUMN_WIDTH (w);
2209 height = WINDOW_FRAME_LINE_HEIGHT (w);
2210
2211 x = window_relative_x_coord (w, part, gx);
2212 y = gy - WINDOW_TOP_EDGE_Y (w);
2213
2214 r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
2215 end_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
2216
2217 if (w->pseudo_window_p)
2218 {
2219 area = TEXT_AREA;
2220 part = ON_MODE_LINE; /* Don't adjust margin. */
2221 goto text_glyph;
2222 }
2223
2224 switch (part)
2225 {
2226 case ON_LEFT_MARGIN:
2227 area = LEFT_MARGIN_AREA;
2228 goto text_glyph;
2229
2230 case ON_RIGHT_MARGIN:
2231 area = RIGHT_MARGIN_AREA;
2232 goto text_glyph;
2233
2234 case ON_HEADER_LINE:
2235 case ON_MODE_LINE:
2236 gr = (part == ON_HEADER_LINE
2237 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
2238 : MATRIX_MODE_LINE_ROW (w->current_matrix));
2239 gy = gr->y;
2240 area = TEXT_AREA;
2241 goto text_glyph_row_found;
2242
2243 case ON_TEXT:
2244 area = TEXT_AREA;
2245
2246 text_glyph:
2247 gr = 0; gy = 0;
2248 for (; r <= end_row && r->enabled_p; ++r)
2249 if (r->y + r->height > y)
2250 {
2251 gr = r; gy = r->y;
2252 break;
2253 }
2254
2255 text_glyph_row_found:
2256 if (gr && gy <= y)
2257 {
2258 struct glyph *g = gr->glyphs[area];
2259 struct glyph *end = g + gr->used[area];
2260
2261 height = gr->height;
2262 for (gx = gr->x; g < end; gx += g->pixel_width, ++g)
2263 if (gx + g->pixel_width > x)
2264 break;
2265
2266 if (g < end)
2267 {
2268 if (g->type == IMAGE_GLYPH)
2269 {
2270 /* Don't remember when mouse is over image, as
2271 image may have hot-spots. */
2272 STORE_NATIVE_RECT (*rect, 0, 0, 0, 0);
2273 return;
2274 }
2275 width = g->pixel_width;
2276 }
2277 else
2278 {
2279 /* Use nominal char spacing at end of line. */
2280 x -= gx;
2281 gx += (x / width) * width;
2282 }
2283
2284 if (part != ON_MODE_LINE && part != ON_HEADER_LINE)
2285 gx += window_box_left_offset (w, area);
2286 }
2287 else
2288 {
2289 /* Use nominal line height at end of window. */
2290 gx = (x / width) * width;
2291 y -= gy;
2292 gy += (y / height) * height;
2293 }
2294 break;
2295
2296 case ON_LEFT_FRINGE:
2297 gx = (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2298 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w)
2299 : window_box_right_offset (w, LEFT_MARGIN_AREA));
2300 width = WINDOW_LEFT_FRINGE_WIDTH (w);
2301 goto row_glyph;
2302
2303 case ON_RIGHT_FRINGE:
2304 gx = (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2305 ? window_box_right_offset (w, RIGHT_MARGIN_AREA)
2306 : window_box_right_offset (w, TEXT_AREA));
2307 width = WINDOW_RIGHT_FRINGE_WIDTH (w);
2308 goto row_glyph;
2309
2310 case ON_SCROLL_BAR:
2311 gx = (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w)
2312 ? 0
2313 : (window_box_right_offset (w, RIGHT_MARGIN_AREA)
2314 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2315 ? WINDOW_RIGHT_FRINGE_WIDTH (w)
2316 : 0)));
2317 width = WINDOW_SCROLL_BAR_AREA_WIDTH (w);
2318
2319 row_glyph:
2320 gr = 0, gy = 0;
2321 for (; r <= end_row && r->enabled_p; ++r)
2322 if (r->y + r->height > y)
2323 {
2324 gr = r; gy = r->y;
2325 break;
2326 }
2327
2328 if (gr && gy <= y)
2329 height = gr->height;
2330 else
2331 {
2332 /* Use nominal line height at end of window. */
2333 y -= gy;
2334 gy += (y / height) * height;
2335 }
2336 break;
2337
2338 default:
2339 ;
2340 virtual_glyph:
2341 /* If there is no glyph under the mouse, then we divide the screen
2342 into a grid of the smallest glyph in the frame, and use that
2343 as our "glyph". */
2344
2345 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to
2346 round down even for negative values. */
2347 if (gx < 0)
2348 gx -= width - 1;
2349 if (gy < 0)
2350 gy -= height - 1;
2351
2352 gx = (gx / width) * width;
2353 gy = (gy / height) * height;
2354
2355 goto store_rect;
2356 }
2357
2358 gx += WINDOW_LEFT_EDGE_X (w);
2359 gy += WINDOW_TOP_EDGE_Y (w);
2360
2361 store_rect:
2362 STORE_NATIVE_RECT (*rect, gx, gy, width, height);
2363
2364 /* Visible feedback for debugging. */
2365 #if 0
2366 #if HAVE_X_WINDOWS
2367 XDrawRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2368 f->output_data.x->normal_gc,
2369 gx, gy, width, height);
2370 #endif
2371 #endif
2372 }
2373
2374
2375 #endif /* HAVE_WINDOW_SYSTEM */
2376
2377 \f
2378 /***********************************************************************
2379 Lisp form evaluation
2380 ***********************************************************************/
2381
2382 /* Error handler for safe_eval and safe_call. */
2383
2384 static Lisp_Object
2385 safe_eval_handler (Lisp_Object arg)
2386 {
2387 add_to_log ("Error during redisplay: %S", arg, Qnil);
2388 return Qnil;
2389 }
2390
2391
2392 /* Evaluate SEXPR and return the result, or nil if something went
2393 wrong. Prevent redisplay during the evaluation. */
2394
2395 /* Call function ARGS[0] with arguments ARGS[1] to ARGS[NARGS - 1].
2396 Return the result, or nil if something went wrong. Prevent
2397 redisplay during the evaluation. */
2398
2399 Lisp_Object
2400 safe_call (ptrdiff_t nargs, Lisp_Object *args)
2401 {
2402 Lisp_Object val;
2403
2404 if (inhibit_eval_during_redisplay)
2405 val = Qnil;
2406 else
2407 {
2408 ptrdiff_t count = SPECPDL_INDEX ();
2409 struct gcpro gcpro1;
2410
2411 GCPRO1 (args[0]);
2412 gcpro1.nvars = nargs;
2413 specbind (Qinhibit_redisplay, Qt);
2414 /* Use Qt to ensure debugger does not run,
2415 so there is no possibility of wanting to redisplay. */
2416 val = internal_condition_case_n (Ffuncall, nargs, args, Qt,
2417 safe_eval_handler);
2418 UNGCPRO;
2419 val = unbind_to (count, val);
2420 }
2421
2422 return val;
2423 }
2424
2425
2426 /* Call function FN with one argument ARG.
2427 Return the result, or nil if something went wrong. */
2428
2429 Lisp_Object
2430 safe_call1 (Lisp_Object fn, Lisp_Object arg)
2431 {
2432 Lisp_Object args[2];
2433 args[0] = fn;
2434 args[1] = arg;
2435 return safe_call (2, args);
2436 }
2437
2438 static Lisp_Object Qeval;
2439
2440 Lisp_Object
2441 safe_eval (Lisp_Object sexpr)
2442 {
2443 return safe_call1 (Qeval, sexpr);
2444 }
2445
2446 /* Call function FN with one argument ARG.
2447 Return the result, or nil if something went wrong. */
2448
2449 Lisp_Object
2450 safe_call2 (Lisp_Object fn, Lisp_Object arg1, Lisp_Object arg2)
2451 {
2452 Lisp_Object args[3];
2453 args[0] = fn;
2454 args[1] = arg1;
2455 args[2] = arg2;
2456 return safe_call (3, args);
2457 }
2458
2459
2460 \f
2461 /***********************************************************************
2462 Debugging
2463 ***********************************************************************/
2464
2465 #if 0
2466
2467 /* Define CHECK_IT to perform sanity checks on iterators.
2468 This is for debugging. It is too slow to do unconditionally. */
2469
2470 static void
2471 check_it (struct it *it)
2472 {
2473 if (it->method == GET_FROM_STRING)
2474 {
2475 xassert (STRINGP (it->string));
2476 xassert (IT_STRING_CHARPOS (*it) >= 0);
2477 }
2478 else
2479 {
2480 xassert (IT_STRING_CHARPOS (*it) < 0);
2481 if (it->method == GET_FROM_BUFFER)
2482 {
2483 /* Check that character and byte positions agree. */
2484 xassert (IT_CHARPOS (*it) == BYTE_TO_CHAR (IT_BYTEPOS (*it)));
2485 }
2486 }
2487
2488 if (it->dpvec)
2489 xassert (it->current.dpvec_index >= 0);
2490 else
2491 xassert (it->current.dpvec_index < 0);
2492 }
2493
2494 #define CHECK_IT(IT) check_it ((IT))
2495
2496 #else /* not 0 */
2497
2498 #define CHECK_IT(IT) (void) 0
2499
2500 #endif /* not 0 */
2501
2502
2503 #if GLYPH_DEBUG && XASSERTS
2504
2505 /* Check that the window end of window W is what we expect it
2506 to be---the last row in the current matrix displaying text. */
2507
2508 static void
2509 check_window_end (struct window *w)
2510 {
2511 if (!MINI_WINDOW_P (w)
2512 && !NILP (w->window_end_valid))
2513 {
2514 struct glyph_row *row;
2515 xassert ((row = MATRIX_ROW (w->current_matrix,
2516 XFASTINT (w->window_end_vpos)),
2517 !row->enabled_p
2518 || MATRIX_ROW_DISPLAYS_TEXT_P (row)
2519 || MATRIX_ROW_VPOS (row, w->current_matrix) == 0));
2520 }
2521 }
2522
2523 #define CHECK_WINDOW_END(W) check_window_end ((W))
2524
2525 #else
2526
2527 #define CHECK_WINDOW_END(W) (void) 0
2528
2529 #endif
2530
2531
2532 \f
2533 /***********************************************************************
2534 Iterator initialization
2535 ***********************************************************************/
2536
2537 /* Initialize IT for displaying current_buffer in window W, starting
2538 at character position CHARPOS. CHARPOS < 0 means that no buffer
2539 position is specified which is useful when the iterator is assigned
2540 a position later. BYTEPOS is the byte position corresponding to
2541 CHARPOS. BYTEPOS < 0 means compute it from CHARPOS.
2542
2543 If ROW is not null, calls to produce_glyphs with IT as parameter
2544 will produce glyphs in that row.
2545
2546 BASE_FACE_ID is the id of a base face to use. It must be one of
2547 DEFAULT_FACE_ID for normal text, MODE_LINE_FACE_ID,
2548 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID for displaying
2549 mode lines, or TOOL_BAR_FACE_ID for displaying the tool-bar.
2550
2551 If ROW is null and BASE_FACE_ID is equal to MODE_LINE_FACE_ID,
2552 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID, the iterator
2553 will be initialized to use the corresponding mode line glyph row of
2554 the desired matrix of W. */
2555
2556 void
2557 init_iterator (struct it *it, struct window *w,
2558 ptrdiff_t charpos, ptrdiff_t bytepos,
2559 struct glyph_row *row, enum face_id base_face_id)
2560 {
2561 int highlight_region_p;
2562 enum face_id remapped_base_face_id = base_face_id;
2563
2564 /* Some precondition checks. */
2565 xassert (w != NULL && it != NULL);
2566 xassert (charpos < 0 || (charpos >= BUF_BEG (current_buffer)
2567 && charpos <= ZV));
2568
2569 /* If face attributes have been changed since the last redisplay,
2570 free realized faces now because they depend on face definitions
2571 that might have changed. Don't free faces while there might be
2572 desired matrices pending which reference these faces. */
2573 if (face_change_count && !inhibit_free_realized_faces)
2574 {
2575 face_change_count = 0;
2576 free_all_realized_faces (Qnil);
2577 }
2578
2579 /* Perhaps remap BASE_FACE_ID to a user-specified alternative. */
2580 if (! NILP (Vface_remapping_alist))
2581 remapped_base_face_id = lookup_basic_face (XFRAME (w->frame), base_face_id);
2582
2583 /* Use one of the mode line rows of W's desired matrix if
2584 appropriate. */
2585 if (row == NULL)
2586 {
2587 if (base_face_id == MODE_LINE_FACE_ID
2588 || base_face_id == MODE_LINE_INACTIVE_FACE_ID)
2589 row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
2590 else if (base_face_id == HEADER_LINE_FACE_ID)
2591 row = MATRIX_HEADER_LINE_ROW (w->desired_matrix);
2592 }
2593
2594 /* Clear IT. */
2595 memset (it, 0, sizeof *it);
2596 it->current.overlay_string_index = -1;
2597 it->current.dpvec_index = -1;
2598 it->base_face_id = remapped_base_face_id;
2599 it->string = Qnil;
2600 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
2601 it->paragraph_embedding = L2R;
2602 it->bidi_it.string.lstring = Qnil;
2603 it->bidi_it.string.s = NULL;
2604 it->bidi_it.string.bufpos = 0;
2605
2606 /* The window in which we iterate over current_buffer: */
2607 XSETWINDOW (it->window, w);
2608 it->w = w;
2609 it->f = XFRAME (w->frame);
2610
2611 it->cmp_it.id = -1;
2612
2613 /* Extra space between lines (on window systems only). */
2614 if (base_face_id == DEFAULT_FACE_ID
2615 && FRAME_WINDOW_P (it->f))
2616 {
2617 if (NATNUMP (BVAR (current_buffer, extra_line_spacing)))
2618 it->extra_line_spacing = XFASTINT (BVAR (current_buffer, extra_line_spacing));
2619 else if (FLOATP (BVAR (current_buffer, extra_line_spacing)))
2620 it->extra_line_spacing = (XFLOAT_DATA (BVAR (current_buffer, extra_line_spacing))
2621 * FRAME_LINE_HEIGHT (it->f));
2622 else if (it->f->extra_line_spacing > 0)
2623 it->extra_line_spacing = it->f->extra_line_spacing;
2624 it->max_extra_line_spacing = 0;
2625 }
2626
2627 /* If realized faces have been removed, e.g. because of face
2628 attribute changes of named faces, recompute them. When running
2629 in batch mode, the face cache of the initial frame is null. If
2630 we happen to get called, make a dummy face cache. */
2631 if (FRAME_FACE_CACHE (it->f) == NULL)
2632 init_frame_faces (it->f);
2633 if (FRAME_FACE_CACHE (it->f)->used == 0)
2634 recompute_basic_faces (it->f);
2635
2636 /* Current value of the `slice', `space-width', and 'height' properties. */
2637 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
2638 it->space_width = Qnil;
2639 it->font_height = Qnil;
2640 it->override_ascent = -1;
2641
2642 /* Are control characters displayed as `^C'? */
2643 it->ctl_arrow_p = !NILP (BVAR (current_buffer, ctl_arrow));
2644
2645 /* -1 means everything between a CR and the following line end
2646 is invisible. >0 means lines indented more than this value are
2647 invisible. */
2648 it->selective = (INTEGERP (BVAR (current_buffer, selective_display))
2649 ? clip_to_bounds (-1, XINT (BVAR (current_buffer,
2650 selective_display)),
2651 PTRDIFF_MAX)
2652 : (!NILP (BVAR (current_buffer, selective_display))
2653 ? -1 : 0));
2654 it->selective_display_ellipsis_p
2655 = !NILP (BVAR (current_buffer, selective_display_ellipses));
2656
2657 /* Display table to use. */
2658 it->dp = window_display_table (w);
2659
2660 /* Are multibyte characters enabled in current_buffer? */
2661 it->multibyte_p = !NILP (BVAR (current_buffer, enable_multibyte_characters));
2662
2663 /* Non-zero if we should highlight the region. */
2664 highlight_region_p
2665 = (!NILP (Vtransient_mark_mode)
2666 && !NILP (BVAR (current_buffer, mark_active))
2667 && XMARKER (BVAR (current_buffer, mark))->buffer != 0);
2668
2669 /* Set IT->region_beg_charpos and IT->region_end_charpos to the
2670 start and end of a visible region in window IT->w. Set both to
2671 -1 to indicate no region. */
2672 if (highlight_region_p
2673 /* Maybe highlight only in selected window. */
2674 && (/* Either show region everywhere. */
2675 highlight_nonselected_windows
2676 /* Or show region in the selected window. */
2677 || w == XWINDOW (selected_window)
2678 /* Or show the region if we are in the mini-buffer and W is
2679 the window the mini-buffer refers to. */
2680 || (MINI_WINDOW_P (XWINDOW (selected_window))
2681 && WINDOWP (minibuf_selected_window)
2682 && w == XWINDOW (minibuf_selected_window))))
2683 {
2684 ptrdiff_t markpos = marker_position (BVAR (current_buffer, mark));
2685 it->region_beg_charpos = min (PT, markpos);
2686 it->region_end_charpos = max (PT, markpos);
2687 }
2688 else
2689 it->region_beg_charpos = it->region_end_charpos = -1;
2690
2691 /* Get the position at which the redisplay_end_trigger hook should
2692 be run, if it is to be run at all. */
2693 if (MARKERP (w->redisplay_end_trigger)
2694 && XMARKER (w->redisplay_end_trigger)->buffer != 0)
2695 it->redisplay_end_trigger_charpos
2696 = marker_position (w->redisplay_end_trigger);
2697 else if (INTEGERP (w->redisplay_end_trigger))
2698 it->redisplay_end_trigger_charpos =
2699 clip_to_bounds (PTRDIFF_MIN, XINT (w->redisplay_end_trigger), PTRDIFF_MAX);
2700
2701 it->tab_width = SANE_TAB_WIDTH (current_buffer);
2702
2703 /* Are lines in the display truncated? */
2704 if (base_face_id != DEFAULT_FACE_ID
2705 || XINT (it->w->hscroll)
2706 || (! WINDOW_FULL_WIDTH_P (it->w)
2707 && ((!NILP (Vtruncate_partial_width_windows)
2708 && !INTEGERP (Vtruncate_partial_width_windows))
2709 || (INTEGERP (Vtruncate_partial_width_windows)
2710 && (WINDOW_TOTAL_COLS (it->w)
2711 < XINT (Vtruncate_partial_width_windows))))))
2712 it->line_wrap = TRUNCATE;
2713 else if (NILP (BVAR (current_buffer, truncate_lines)))
2714 it->line_wrap = NILP (BVAR (current_buffer, word_wrap))
2715 ? WINDOW_WRAP : WORD_WRAP;
2716 else
2717 it->line_wrap = TRUNCATE;
2718
2719 /* Get dimensions of truncation and continuation glyphs. These are
2720 displayed as fringe bitmaps under X, so we don't need them for such
2721 frames. */
2722 if (!FRAME_WINDOW_P (it->f))
2723 {
2724 if (it->line_wrap == TRUNCATE)
2725 {
2726 /* We will need the truncation glyph. */
2727 xassert (it->glyph_row == NULL);
2728 produce_special_glyphs (it, IT_TRUNCATION);
2729 it->truncation_pixel_width = it->pixel_width;
2730 }
2731 else
2732 {
2733 /* We will need the continuation glyph. */
2734 xassert (it->glyph_row == NULL);
2735 produce_special_glyphs (it, IT_CONTINUATION);
2736 it->continuation_pixel_width = it->pixel_width;
2737 }
2738
2739 /* Reset these values to zero because the produce_special_glyphs
2740 above has changed them. */
2741 it->pixel_width = it->ascent = it->descent = 0;
2742 it->phys_ascent = it->phys_descent = 0;
2743 }
2744
2745 /* Set this after getting the dimensions of truncation and
2746 continuation glyphs, so that we don't produce glyphs when calling
2747 produce_special_glyphs, above. */
2748 it->glyph_row = row;
2749 it->area = TEXT_AREA;
2750
2751 /* Forget any previous info about this row being reversed. */
2752 if (it->glyph_row)
2753 it->glyph_row->reversed_p = 0;
2754
2755 /* Get the dimensions of the display area. The display area
2756 consists of the visible window area plus a horizontally scrolled
2757 part to the left of the window. All x-values are relative to the
2758 start of this total display area. */
2759 if (base_face_id != DEFAULT_FACE_ID)
2760 {
2761 /* Mode lines, menu bar in terminal frames. */
2762 it->first_visible_x = 0;
2763 it->last_visible_x = WINDOW_TOTAL_WIDTH (w);
2764 }
2765 else
2766 {
2767 it->first_visible_x
2768 = XFASTINT (it->w->hscroll) * FRAME_COLUMN_WIDTH (it->f);
2769 it->last_visible_x = (it->first_visible_x
2770 + window_box_width (w, TEXT_AREA));
2771
2772 /* If we truncate lines, leave room for the truncator glyph(s) at
2773 the right margin. Otherwise, leave room for the continuation
2774 glyph(s). Truncation and continuation glyphs are not inserted
2775 for window-based redisplay. */
2776 if (!FRAME_WINDOW_P (it->f))
2777 {
2778 if (it->line_wrap == TRUNCATE)
2779 it->last_visible_x -= it->truncation_pixel_width;
2780 else
2781 it->last_visible_x -= it->continuation_pixel_width;
2782 }
2783
2784 it->header_line_p = WINDOW_WANTS_HEADER_LINE_P (w);
2785 it->current_y = WINDOW_HEADER_LINE_HEIGHT (w) + w->vscroll;
2786 }
2787
2788 /* Leave room for a border glyph. */
2789 if (!FRAME_WINDOW_P (it->f)
2790 && !WINDOW_RIGHTMOST_P (it->w))
2791 it->last_visible_x -= 1;
2792
2793 it->last_visible_y = window_text_bottom_y (w);
2794
2795 /* For mode lines and alike, arrange for the first glyph having a
2796 left box line if the face specifies a box. */
2797 if (base_face_id != DEFAULT_FACE_ID)
2798 {
2799 struct face *face;
2800
2801 it->face_id = remapped_base_face_id;
2802
2803 /* If we have a boxed mode line, make the first character appear
2804 with a left box line. */
2805 face = FACE_FROM_ID (it->f, remapped_base_face_id);
2806 if (face->box != FACE_NO_BOX)
2807 it->start_of_box_run_p = 1;
2808 }
2809
2810 /* If a buffer position was specified, set the iterator there,
2811 getting overlays and face properties from that position. */
2812 if (charpos >= BUF_BEG (current_buffer))
2813 {
2814 it->end_charpos = ZV;
2815 IT_CHARPOS (*it) = charpos;
2816
2817 /* We will rely on `reseat' to set this up properly, via
2818 handle_face_prop. */
2819 it->face_id = it->base_face_id;
2820
2821 /* Compute byte position if not specified. */
2822 if (bytepos < charpos)
2823 IT_BYTEPOS (*it) = CHAR_TO_BYTE (charpos);
2824 else
2825 IT_BYTEPOS (*it) = bytepos;
2826
2827 it->start = it->current;
2828 /* Do we need to reorder bidirectional text? Not if this is a
2829 unibyte buffer: by definition, none of the single-byte
2830 characters are strong R2L, so no reordering is needed. And
2831 bidi.c doesn't support unibyte buffers anyway. Also, don't
2832 reorder while we are loading loadup.el, since the tables of
2833 character properties needed for reordering are not yet
2834 available. */
2835 it->bidi_p =
2836 NILP (Vpurify_flag)
2837 && !NILP (BVAR (current_buffer, bidi_display_reordering))
2838 && it->multibyte_p;
2839
2840 /* If we are to reorder bidirectional text, init the bidi
2841 iterator. */
2842 if (it->bidi_p)
2843 {
2844 /* Note the paragraph direction that this buffer wants to
2845 use. */
2846 if (EQ (BVAR (current_buffer, bidi_paragraph_direction),
2847 Qleft_to_right))
2848 it->paragraph_embedding = L2R;
2849 else if (EQ (BVAR (current_buffer, bidi_paragraph_direction),
2850 Qright_to_left))
2851 it->paragraph_embedding = R2L;
2852 else
2853 it->paragraph_embedding = NEUTRAL_DIR;
2854 bidi_unshelve_cache (NULL, 0);
2855 bidi_init_it (charpos, IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f),
2856 &it->bidi_it);
2857 }
2858
2859 /* Compute faces etc. */
2860 reseat (it, it->current.pos, 1);
2861 }
2862
2863 CHECK_IT (it);
2864 }
2865
2866
2867 /* Initialize IT for the display of window W with window start POS. */
2868
2869 void
2870 start_display (struct it *it, struct window *w, struct text_pos pos)
2871 {
2872 struct glyph_row *row;
2873 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
2874
2875 row = w->desired_matrix->rows + first_vpos;
2876 init_iterator (it, w, CHARPOS (pos), BYTEPOS (pos), row, DEFAULT_FACE_ID);
2877 it->first_vpos = first_vpos;
2878
2879 /* Don't reseat to previous visible line start if current start
2880 position is in a string or image. */
2881 if (it->method == GET_FROM_BUFFER && it->line_wrap != TRUNCATE)
2882 {
2883 int start_at_line_beg_p;
2884 int first_y = it->current_y;
2885
2886 /* If window start is not at a line start, skip forward to POS to
2887 get the correct continuation lines width. */
2888 start_at_line_beg_p = (CHARPOS (pos) == BEGV
2889 || FETCH_BYTE (BYTEPOS (pos) - 1) == '\n');
2890 if (!start_at_line_beg_p)
2891 {
2892 int new_x;
2893
2894 reseat_at_previous_visible_line_start (it);
2895 move_it_to (it, CHARPOS (pos), -1, -1, -1, MOVE_TO_POS);
2896
2897 new_x = it->current_x + it->pixel_width;
2898
2899 /* If lines are continued, this line may end in the middle
2900 of a multi-glyph character (e.g. a control character
2901 displayed as \003, or in the middle of an overlay
2902 string). In this case move_it_to above will not have
2903 taken us to the start of the continuation line but to the
2904 end of the continued line. */
2905 if (it->current_x > 0
2906 && it->line_wrap != TRUNCATE /* Lines are continued. */
2907 && (/* And glyph doesn't fit on the line. */
2908 new_x > it->last_visible_x
2909 /* Or it fits exactly and we're on a window
2910 system frame. */
2911 || (new_x == it->last_visible_x
2912 && FRAME_WINDOW_P (it->f))))
2913 {
2914 if ((it->current.dpvec_index >= 0
2915 || it->current.overlay_string_index >= 0)
2916 /* If we are on a newline from a display vector or
2917 overlay string, then we are already at the end of
2918 a screen line; no need to go to the next line in
2919 that case, as this line is not really continued.
2920 (If we do go to the next line, C-e will not DTRT.) */
2921 && it->c != '\n')
2922 {
2923 set_iterator_to_next (it, 1);
2924 move_it_in_display_line_to (it, -1, -1, 0);
2925 }
2926
2927 it->continuation_lines_width += it->current_x;
2928 }
2929 /* If the character at POS is displayed via a display
2930 vector, move_it_to above stops at the final glyph of
2931 IT->dpvec. To make the caller redisplay that character
2932 again (a.k.a. start at POS), we need to reset the
2933 dpvec_index to the beginning of IT->dpvec. */
2934 else if (it->current.dpvec_index >= 0)
2935 it->current.dpvec_index = 0;
2936
2937 /* We're starting a new display line, not affected by the
2938 height of the continued line, so clear the appropriate
2939 fields in the iterator structure. */
2940 it->max_ascent = it->max_descent = 0;
2941 it->max_phys_ascent = it->max_phys_descent = 0;
2942
2943 it->current_y = first_y;
2944 it->vpos = 0;
2945 it->current_x = it->hpos = 0;
2946 }
2947 }
2948 }
2949
2950
2951 /* Return 1 if POS is a position in ellipses displayed for invisible
2952 text. W is the window we display, for text property lookup. */
2953
2954 static int
2955 in_ellipses_for_invisible_text_p (struct display_pos *pos, struct window *w)
2956 {
2957 Lisp_Object prop, window;
2958 int ellipses_p = 0;
2959 ptrdiff_t charpos = CHARPOS (pos->pos);
2960
2961 /* If POS specifies a position in a display vector, this might
2962 be for an ellipsis displayed for invisible text. We won't
2963 get the iterator set up for delivering that ellipsis unless
2964 we make sure that it gets aware of the invisible text. */
2965 if (pos->dpvec_index >= 0
2966 && pos->overlay_string_index < 0
2967 && CHARPOS (pos->string_pos) < 0
2968 && charpos > BEGV
2969 && (XSETWINDOW (window, w),
2970 prop = Fget_char_property (make_number (charpos),
2971 Qinvisible, window),
2972 !TEXT_PROP_MEANS_INVISIBLE (prop)))
2973 {
2974 prop = Fget_char_property (make_number (charpos - 1), Qinvisible,
2975 window);
2976 ellipses_p = 2 == TEXT_PROP_MEANS_INVISIBLE (prop);
2977 }
2978
2979 return ellipses_p;
2980 }
2981
2982
2983 /* Initialize IT for stepping through current_buffer in window W,
2984 starting at position POS that includes overlay string and display
2985 vector/ control character translation position information. Value
2986 is zero if there are overlay strings with newlines at POS. */
2987
2988 static int
2989 init_from_display_pos (struct it *it, struct window *w, struct display_pos *pos)
2990 {
2991 ptrdiff_t charpos = CHARPOS (pos->pos), bytepos = BYTEPOS (pos->pos);
2992 int i, overlay_strings_with_newlines = 0;
2993
2994 /* If POS specifies a position in a display vector, this might
2995 be for an ellipsis displayed for invisible text. We won't
2996 get the iterator set up for delivering that ellipsis unless
2997 we make sure that it gets aware of the invisible text. */
2998 if (in_ellipses_for_invisible_text_p (pos, w))
2999 {
3000 --charpos;
3001 bytepos = 0;
3002 }
3003
3004 /* Keep in mind: the call to reseat in init_iterator skips invisible
3005 text, so we might end up at a position different from POS. This
3006 is only a problem when POS is a row start after a newline and an
3007 overlay starts there with an after-string, and the overlay has an
3008 invisible property. Since we don't skip invisible text in
3009 display_line and elsewhere immediately after consuming the
3010 newline before the row start, such a POS will not be in a string,
3011 but the call to init_iterator below will move us to the
3012 after-string. */
3013 init_iterator (it, w, charpos, bytepos, NULL, DEFAULT_FACE_ID);
3014
3015 /* This only scans the current chunk -- it should scan all chunks.
3016 However, OVERLAY_STRING_CHUNK_SIZE has been increased from 3 in 21.1
3017 to 16 in 22.1 to make this a lesser problem. */
3018 for (i = 0; i < it->n_overlay_strings && i < OVERLAY_STRING_CHUNK_SIZE; ++i)
3019 {
3020 const char *s = SSDATA (it->overlay_strings[i]);
3021 const char *e = s + SBYTES (it->overlay_strings[i]);
3022
3023 while (s < e && *s != '\n')
3024 ++s;
3025
3026 if (s < e)
3027 {
3028 overlay_strings_with_newlines = 1;
3029 break;
3030 }
3031 }
3032
3033 /* If position is within an overlay string, set up IT to the right
3034 overlay string. */
3035 if (pos->overlay_string_index >= 0)
3036 {
3037 int relative_index;
3038
3039 /* If the first overlay string happens to have a `display'
3040 property for an image, the iterator will be set up for that
3041 image, and we have to undo that setup first before we can
3042 correct the overlay string index. */
3043 if (it->method == GET_FROM_IMAGE)
3044 pop_it (it);
3045
3046 /* We already have the first chunk of overlay strings in
3047 IT->overlay_strings. Load more until the one for
3048 pos->overlay_string_index is in IT->overlay_strings. */
3049 if (pos->overlay_string_index >= OVERLAY_STRING_CHUNK_SIZE)
3050 {
3051 ptrdiff_t n = pos->overlay_string_index / OVERLAY_STRING_CHUNK_SIZE;
3052 it->current.overlay_string_index = 0;
3053 while (n--)
3054 {
3055 load_overlay_strings (it, 0);
3056 it->current.overlay_string_index += OVERLAY_STRING_CHUNK_SIZE;
3057 }
3058 }
3059
3060 it->current.overlay_string_index = pos->overlay_string_index;
3061 relative_index = (it->current.overlay_string_index
3062 % OVERLAY_STRING_CHUNK_SIZE);
3063 it->string = it->overlay_strings[relative_index];
3064 xassert (STRINGP (it->string));
3065 it->current.string_pos = pos->string_pos;
3066 it->method = GET_FROM_STRING;
3067 }
3068
3069 if (CHARPOS (pos->string_pos) >= 0)
3070 {
3071 /* Recorded position is not in an overlay string, but in another
3072 string. This can only be a string from a `display' property.
3073 IT should already be filled with that string. */
3074 it->current.string_pos = pos->string_pos;
3075 xassert (STRINGP (it->string));
3076 }
3077
3078 /* Restore position in display vector translations, control
3079 character translations or ellipses. */
3080 if (pos->dpvec_index >= 0)
3081 {
3082 if (it->dpvec == NULL)
3083 get_next_display_element (it);
3084 xassert (it->dpvec && it->current.dpvec_index == 0);
3085 it->current.dpvec_index = pos->dpvec_index;
3086 }
3087
3088 CHECK_IT (it);
3089 return !overlay_strings_with_newlines;
3090 }
3091
3092
3093 /* Initialize IT for stepping through current_buffer in window W
3094 starting at ROW->start. */
3095
3096 static void
3097 init_to_row_start (struct it *it, struct window *w, struct glyph_row *row)
3098 {
3099 init_from_display_pos (it, w, &row->start);
3100 it->start = row->start;
3101 it->continuation_lines_width = row->continuation_lines_width;
3102 CHECK_IT (it);
3103 }
3104
3105
3106 /* Initialize IT for stepping through current_buffer in window W
3107 starting in the line following ROW, i.e. starting at ROW->end.
3108 Value is zero if there are overlay strings with newlines at ROW's
3109 end position. */
3110
3111 static int
3112 init_to_row_end (struct it *it, struct window *w, struct glyph_row *row)
3113 {
3114 int success = 0;
3115
3116 if (init_from_display_pos (it, w, &row->end))
3117 {
3118 if (row->continued_p)
3119 it->continuation_lines_width
3120 = row->continuation_lines_width + row->pixel_width;
3121 CHECK_IT (it);
3122 success = 1;
3123 }
3124
3125 return success;
3126 }
3127
3128
3129
3130 \f
3131 /***********************************************************************
3132 Text properties
3133 ***********************************************************************/
3134
3135 /* Called when IT reaches IT->stop_charpos. Handle text property and
3136 overlay changes. Set IT->stop_charpos to the next position where
3137 to stop. */
3138
3139 static void
3140 handle_stop (struct it *it)
3141 {
3142 enum prop_handled handled;
3143 int handle_overlay_change_p;
3144 struct props *p;
3145
3146 it->dpvec = NULL;
3147 it->current.dpvec_index = -1;
3148 handle_overlay_change_p = !it->ignore_overlay_strings_at_pos_p;
3149 it->ignore_overlay_strings_at_pos_p = 0;
3150 it->ellipsis_p = 0;
3151
3152 /* Use face of preceding text for ellipsis (if invisible) */
3153 if (it->selective_display_ellipsis_p)
3154 it->saved_face_id = it->face_id;
3155
3156 do
3157 {
3158 handled = HANDLED_NORMALLY;
3159
3160 /* Call text property handlers. */
3161 for (p = it_props; p->handler; ++p)
3162 {
3163 handled = p->handler (it);
3164
3165 if (handled == HANDLED_RECOMPUTE_PROPS)
3166 break;
3167 else if (handled == HANDLED_RETURN)
3168 {
3169 /* We still want to show before and after strings from
3170 overlays even if the actual buffer text is replaced. */
3171 if (!handle_overlay_change_p
3172 || it->sp > 1
3173 /* Don't call get_overlay_strings_1 if we already
3174 have overlay strings loaded, because doing so
3175 will load them again and push the iterator state
3176 onto the stack one more time, which is not
3177 expected by the rest of the code that processes
3178 overlay strings. */
3179 || (it->current.overlay_string_index < 0
3180 ? !get_overlay_strings_1 (it, 0, 0)
3181 : 0))
3182 {
3183 if (it->ellipsis_p)
3184 setup_for_ellipsis (it, 0);
3185 /* When handling a display spec, we might load an
3186 empty string. In that case, discard it here. We
3187 used to discard it in handle_single_display_spec,
3188 but that causes get_overlay_strings_1, above, to
3189 ignore overlay strings that we must check. */
3190 if (STRINGP (it->string) && !SCHARS (it->string))
3191 pop_it (it);
3192 return;
3193 }
3194 else if (STRINGP (it->string) && !SCHARS (it->string))
3195 pop_it (it);
3196 else
3197 {
3198 it->ignore_overlay_strings_at_pos_p = 1;
3199 it->string_from_display_prop_p = 0;
3200 it->from_disp_prop_p = 0;
3201 handle_overlay_change_p = 0;
3202 }
3203 handled = HANDLED_RECOMPUTE_PROPS;
3204 break;
3205 }
3206 else if (handled == HANDLED_OVERLAY_STRING_CONSUMED)
3207 handle_overlay_change_p = 0;
3208 }
3209
3210 if (handled != HANDLED_RECOMPUTE_PROPS)
3211 {
3212 /* Don't check for overlay strings below when set to deliver
3213 characters from a display vector. */
3214 if (it->method == GET_FROM_DISPLAY_VECTOR)
3215 handle_overlay_change_p = 0;
3216
3217 /* Handle overlay changes.
3218 This sets HANDLED to HANDLED_RECOMPUTE_PROPS
3219 if it finds overlays. */
3220 if (handle_overlay_change_p)
3221 handled = handle_overlay_change (it);
3222 }
3223
3224 if (it->ellipsis_p)
3225 {
3226 setup_for_ellipsis (it, 0);
3227 break;
3228 }
3229 }
3230 while (handled == HANDLED_RECOMPUTE_PROPS);
3231
3232 /* Determine where to stop next. */
3233 if (handled == HANDLED_NORMALLY)
3234 compute_stop_pos (it);
3235 }
3236
3237
3238 /* Compute IT->stop_charpos from text property and overlay change
3239 information for IT's current position. */
3240
3241 static void
3242 compute_stop_pos (struct it *it)
3243 {
3244 register INTERVAL iv, next_iv;
3245 Lisp_Object object, limit, position;
3246 ptrdiff_t charpos, bytepos;
3247
3248 if (STRINGP (it->string))
3249 {
3250 /* Strings are usually short, so don't limit the search for
3251 properties. */
3252 it->stop_charpos = it->end_charpos;
3253 object = it->string;
3254 limit = Qnil;
3255 charpos = IT_STRING_CHARPOS (*it);
3256 bytepos = IT_STRING_BYTEPOS (*it);
3257 }
3258 else
3259 {
3260 ptrdiff_t pos;
3261
3262 /* If end_charpos is out of range for some reason, such as a
3263 misbehaving display function, rationalize it (Bug#5984). */
3264 if (it->end_charpos > ZV)
3265 it->end_charpos = ZV;
3266 it->stop_charpos = it->end_charpos;
3267
3268 /* If next overlay change is in front of the current stop pos
3269 (which is IT->end_charpos), stop there. Note: value of
3270 next_overlay_change is point-max if no overlay change
3271 follows. */
3272 charpos = IT_CHARPOS (*it);
3273 bytepos = IT_BYTEPOS (*it);
3274 pos = next_overlay_change (charpos);
3275 if (pos < it->stop_charpos)
3276 it->stop_charpos = pos;
3277
3278 /* If showing the region, we have to stop at the region
3279 start or end because the face might change there. */
3280 if (it->region_beg_charpos > 0)
3281 {
3282 if (IT_CHARPOS (*it) < it->region_beg_charpos)
3283 it->stop_charpos = min (it->stop_charpos, it->region_beg_charpos);
3284 else if (IT_CHARPOS (*it) < it->region_end_charpos)
3285 it->stop_charpos = min (it->stop_charpos, it->region_end_charpos);
3286 }
3287
3288 /* Set up variables for computing the stop position from text
3289 property changes. */
3290 XSETBUFFER (object, current_buffer);
3291 limit = make_number (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT);
3292 }
3293
3294 /* Get the interval containing IT's position. Value is a null
3295 interval if there isn't such an interval. */
3296 position = make_number (charpos);
3297 iv = validate_interval_range (object, &position, &position, 0);
3298 if (!NULL_INTERVAL_P (iv))
3299 {
3300 Lisp_Object values_here[LAST_PROP_IDX];
3301 struct props *p;
3302
3303 /* Get properties here. */
3304 for (p = it_props; p->handler; ++p)
3305 values_here[p->idx] = textget (iv->plist, *p->name);
3306
3307 /* Look for an interval following iv that has different
3308 properties. */
3309 for (next_iv = next_interval (iv);
3310 (!NULL_INTERVAL_P (next_iv)
3311 && (NILP (limit)
3312 || XFASTINT (limit) > next_iv->position));
3313 next_iv = next_interval (next_iv))
3314 {
3315 for (p = it_props; p->handler; ++p)
3316 {
3317 Lisp_Object new_value;
3318
3319 new_value = textget (next_iv->plist, *p->name);
3320 if (!EQ (values_here[p->idx], new_value))
3321 break;
3322 }
3323
3324 if (p->handler)
3325 break;
3326 }
3327
3328 if (!NULL_INTERVAL_P (next_iv))
3329 {
3330 if (INTEGERP (limit)
3331 && next_iv->position >= XFASTINT (limit))
3332 /* No text property change up to limit. */
3333 it->stop_charpos = min (XFASTINT (limit), it->stop_charpos);
3334 else
3335 /* Text properties change in next_iv. */
3336 it->stop_charpos = min (it->stop_charpos, next_iv->position);
3337 }
3338 }
3339
3340 if (it->cmp_it.id < 0)
3341 {
3342 ptrdiff_t stoppos = it->end_charpos;
3343
3344 if (it->bidi_p && it->bidi_it.scan_dir < 0)
3345 stoppos = -1;
3346 composition_compute_stop_pos (&it->cmp_it, charpos, bytepos,
3347 stoppos, it->string);
3348 }
3349
3350 xassert (STRINGP (it->string)
3351 || (it->stop_charpos >= BEGV
3352 && it->stop_charpos >= IT_CHARPOS (*it)));
3353 }
3354
3355
3356 /* Return the position of the next overlay change after POS in
3357 current_buffer. Value is point-max if no overlay change
3358 follows. This is like `next-overlay-change' but doesn't use
3359 xmalloc. */
3360
3361 static ptrdiff_t
3362 next_overlay_change (ptrdiff_t pos)
3363 {
3364 ptrdiff_t i, noverlays;
3365 ptrdiff_t endpos;
3366 Lisp_Object *overlays;
3367
3368 /* Get all overlays at the given position. */
3369 GET_OVERLAYS_AT (pos, overlays, noverlays, &endpos, 1);
3370
3371 /* If any of these overlays ends before endpos,
3372 use its ending point instead. */
3373 for (i = 0; i < noverlays; ++i)
3374 {
3375 Lisp_Object oend;
3376 ptrdiff_t oendpos;
3377
3378 oend = OVERLAY_END (overlays[i]);
3379 oendpos = OVERLAY_POSITION (oend);
3380 endpos = min (endpos, oendpos);
3381 }
3382
3383 return endpos;
3384 }
3385
3386 /* How many characters forward to search for a display property or
3387 display string. Searching too far forward makes the bidi display
3388 sluggish, especially in small windows. */
3389 #define MAX_DISP_SCAN 250
3390
3391 /* Return the character position of a display string at or after
3392 position specified by POSITION. If no display string exists at or
3393 after POSITION, return ZV. A display string is either an overlay
3394 with `display' property whose value is a string, or a `display'
3395 text property whose value is a string. STRING is data about the
3396 string to iterate; if STRING->lstring is nil, we are iterating a
3397 buffer. FRAME_WINDOW_P is non-zero when we are displaying a window
3398 on a GUI frame. DISP_PROP is set to zero if we searched
3399 MAX_DISP_SCAN characters forward without finding any display
3400 strings, non-zero otherwise. It is set to 2 if the display string
3401 uses any kind of `(space ...)' spec that will produce a stretch of
3402 white space in the text area. */
3403 ptrdiff_t
3404 compute_display_string_pos (struct text_pos *position,
3405 struct bidi_string_data *string,
3406 int frame_window_p, int *disp_prop)
3407 {
3408 /* OBJECT = nil means current buffer. */
3409 Lisp_Object object =
3410 (string && STRINGP (string->lstring)) ? string->lstring : Qnil;
3411 Lisp_Object pos, spec, limpos;
3412 int string_p = (string && (STRINGP (string->lstring) || string->s));
3413 ptrdiff_t eob = string_p ? string->schars : ZV;
3414 ptrdiff_t begb = string_p ? 0 : BEGV;
3415 ptrdiff_t bufpos, charpos = CHARPOS (*position);
3416 ptrdiff_t lim =
3417 (charpos < eob - MAX_DISP_SCAN) ? charpos + MAX_DISP_SCAN : eob;
3418 struct text_pos tpos;
3419 int rv = 0;
3420
3421 *disp_prop = 1;
3422
3423 if (charpos >= eob
3424 /* We don't support display properties whose values are strings
3425 that have display string properties. */
3426 || string->from_disp_str
3427 /* C strings cannot have display properties. */
3428 || (string->s && !STRINGP (object)))
3429 {
3430 *disp_prop = 0;
3431 return eob;
3432 }
3433
3434 /* If the character at CHARPOS is where the display string begins,
3435 return CHARPOS. */
3436 pos = make_number (charpos);
3437 if (STRINGP (object))
3438 bufpos = string->bufpos;
3439 else
3440 bufpos = charpos;
3441 tpos = *position;
3442 if (!NILP (spec = Fget_char_property (pos, Qdisplay, object))
3443 && (charpos <= begb
3444 || !EQ (Fget_char_property (make_number (charpos - 1), Qdisplay,
3445 object),
3446 spec))
3447 && (rv = handle_display_spec (NULL, spec, object, Qnil, &tpos, bufpos,
3448 frame_window_p)))
3449 {
3450 if (rv == 2)
3451 *disp_prop = 2;
3452 return charpos;
3453 }
3454
3455 /* Look forward for the first character with a `display' property
3456 that will replace the underlying text when displayed. */
3457 limpos = make_number (lim);
3458 do {
3459 pos = Fnext_single_char_property_change (pos, Qdisplay, object, limpos);
3460 CHARPOS (tpos) = XFASTINT (pos);
3461 if (CHARPOS (tpos) >= lim)
3462 {
3463 *disp_prop = 0;
3464 break;
3465 }
3466 if (STRINGP (object))
3467 BYTEPOS (tpos) = string_char_to_byte (object, CHARPOS (tpos));
3468 else
3469 BYTEPOS (tpos) = CHAR_TO_BYTE (CHARPOS (tpos));
3470 spec = Fget_char_property (pos, Qdisplay, object);
3471 if (!STRINGP (object))
3472 bufpos = CHARPOS (tpos);
3473 } while (NILP (spec)
3474 || !(rv = handle_display_spec (NULL, spec, object, Qnil, &tpos,
3475 bufpos, frame_window_p)));
3476 if (rv == 2)
3477 *disp_prop = 2;
3478
3479 return CHARPOS (tpos);
3480 }
3481
3482 /* Return the character position of the end of the display string that
3483 started at CHARPOS. If there's no display string at CHARPOS,
3484 return -1. A display string is either an overlay with `display'
3485 property whose value is a string or a `display' text property whose
3486 value is a string. */
3487 ptrdiff_t
3488 compute_display_string_end (ptrdiff_t charpos, struct bidi_string_data *string)
3489 {
3490 /* OBJECT = nil means current buffer. */
3491 Lisp_Object object =
3492 (string && STRINGP (string->lstring)) ? string->lstring : Qnil;
3493 Lisp_Object pos = make_number (charpos);
3494 ptrdiff_t eob =
3495 (STRINGP (object) || (string && string->s)) ? string->schars : ZV;
3496
3497 if (charpos >= eob || (string->s && !STRINGP (object)))
3498 return eob;
3499
3500 /* It could happen that the display property or overlay was removed
3501 since we found it in compute_display_string_pos above. One way
3502 this can happen is if JIT font-lock was called (through
3503 handle_fontified_prop), and jit-lock-functions remove text
3504 properties or overlays from the portion of buffer that includes
3505 CHARPOS. Muse mode is known to do that, for example. In this
3506 case, we return -1 to the caller, to signal that no display
3507 string is actually present at CHARPOS. See bidi_fetch_char for
3508 how this is handled.
3509
3510 An alternative would be to never look for display properties past
3511 it->stop_charpos. But neither compute_display_string_pos nor
3512 bidi_fetch_char that calls it know or care where the next
3513 stop_charpos is. */
3514 if (NILP (Fget_char_property (pos, Qdisplay, object)))
3515 return -1;
3516
3517 /* Look forward for the first character where the `display' property
3518 changes. */
3519 pos = Fnext_single_char_property_change (pos, Qdisplay, object, Qnil);
3520
3521 return XFASTINT (pos);
3522 }
3523
3524
3525 \f
3526 /***********************************************************************
3527 Fontification
3528 ***********************************************************************/
3529
3530 /* Handle changes in the `fontified' property of the current buffer by
3531 calling hook functions from Qfontification_functions to fontify
3532 regions of text. */
3533
3534 static enum prop_handled
3535 handle_fontified_prop (struct it *it)
3536 {
3537 Lisp_Object prop, pos;
3538 enum prop_handled handled = HANDLED_NORMALLY;
3539
3540 if (!NILP (Vmemory_full))
3541 return handled;
3542
3543 /* Get the value of the `fontified' property at IT's current buffer
3544 position. (The `fontified' property doesn't have a special
3545 meaning in strings.) If the value is nil, call functions from
3546 Qfontification_functions. */
3547 if (!STRINGP (it->string)
3548 && it->s == NULL
3549 && !NILP (Vfontification_functions)
3550 && !NILP (Vrun_hooks)
3551 && (pos = make_number (IT_CHARPOS (*it)),
3552 prop = Fget_char_property (pos, Qfontified, Qnil),
3553 /* Ignore the special cased nil value always present at EOB since
3554 no amount of fontifying will be able to change it. */
3555 NILP (prop) && IT_CHARPOS (*it) < Z))
3556 {
3557 ptrdiff_t count = SPECPDL_INDEX ();
3558 Lisp_Object val;
3559 struct buffer *obuf = current_buffer;
3560 int begv = BEGV, zv = ZV;
3561 int old_clip_changed = current_buffer->clip_changed;
3562
3563 val = Vfontification_functions;
3564 specbind (Qfontification_functions, Qnil);
3565
3566 xassert (it->end_charpos == ZV);
3567
3568 if (!CONSP (val) || EQ (XCAR (val), Qlambda))
3569 safe_call1 (val, pos);
3570 else
3571 {
3572 Lisp_Object fns, fn;
3573 struct gcpro gcpro1, gcpro2;
3574
3575 fns = Qnil;
3576 GCPRO2 (val, fns);
3577
3578 for (; CONSP (val); val = XCDR (val))
3579 {
3580 fn = XCAR (val);
3581
3582 if (EQ (fn, Qt))
3583 {
3584 /* A value of t indicates this hook has a local
3585 binding; it means to run the global binding too.
3586 In a global value, t should not occur. If it
3587 does, we must ignore it to avoid an endless
3588 loop. */
3589 for (fns = Fdefault_value (Qfontification_functions);
3590 CONSP (fns);
3591 fns = XCDR (fns))
3592 {
3593 fn = XCAR (fns);
3594 if (!EQ (fn, Qt))
3595 safe_call1 (fn, pos);
3596 }
3597 }
3598 else
3599 safe_call1 (fn, pos);
3600 }
3601
3602 UNGCPRO;
3603 }
3604
3605 unbind_to (count, Qnil);
3606
3607 /* Fontification functions routinely call `save-restriction'.
3608 Normally, this tags clip_changed, which can confuse redisplay
3609 (see discussion in Bug#6671). Since we don't perform any
3610 special handling of fontification changes in the case where
3611 `save-restriction' isn't called, there's no point doing so in
3612 this case either. So, if the buffer's restrictions are
3613 actually left unchanged, reset clip_changed. */
3614 if (obuf == current_buffer)
3615 {
3616 if (begv == BEGV && zv == ZV)
3617 current_buffer->clip_changed = old_clip_changed;
3618 }
3619 /* There isn't much we can reasonably do to protect against
3620 misbehaving fontification, but here's a fig leaf. */
3621 else if (!NILP (BVAR (obuf, name)))
3622 set_buffer_internal_1 (obuf);
3623
3624 /* The fontification code may have added/removed text.
3625 It could do even a lot worse, but let's at least protect against
3626 the most obvious case where only the text past `pos' gets changed',
3627 as is/was done in grep.el where some escapes sequences are turned
3628 into face properties (bug#7876). */
3629 it->end_charpos = ZV;
3630
3631 /* Return HANDLED_RECOMPUTE_PROPS only if function fontified
3632 something. This avoids an endless loop if they failed to
3633 fontify the text for which reason ever. */
3634 if (!NILP (Fget_char_property (pos, Qfontified, Qnil)))
3635 handled = HANDLED_RECOMPUTE_PROPS;
3636 }
3637
3638 return handled;
3639 }
3640
3641
3642 \f
3643 /***********************************************************************
3644 Faces
3645 ***********************************************************************/
3646
3647 /* Set up iterator IT from face properties at its current position.
3648 Called from handle_stop. */
3649
3650 static enum prop_handled
3651 handle_face_prop (struct it *it)
3652 {
3653 int new_face_id;
3654 ptrdiff_t next_stop;
3655
3656 if (!STRINGP (it->string))
3657 {
3658 new_face_id
3659 = face_at_buffer_position (it->w,
3660 IT_CHARPOS (*it),
3661 it->region_beg_charpos,
3662 it->region_end_charpos,
3663 &next_stop,
3664 (IT_CHARPOS (*it)
3665 + TEXT_PROP_DISTANCE_LIMIT),
3666 0, it->base_face_id);
3667
3668 /* Is this a start of a run of characters with box face?
3669 Caveat: this can be called for a freshly initialized
3670 iterator; face_id is -1 in this case. We know that the new
3671 face will not change until limit, i.e. if the new face has a
3672 box, all characters up to limit will have one. But, as
3673 usual, we don't know whether limit is really the end. */
3674 if (new_face_id != it->face_id)
3675 {
3676 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
3677
3678 /* If new face has a box but old face has not, this is
3679 the start of a run of characters with box, i.e. it has
3680 a shadow on the left side. The value of face_id of the
3681 iterator will be -1 if this is the initial call that gets
3682 the face. In this case, we have to look in front of IT's
3683 position and see whether there is a face != new_face_id. */
3684 it->start_of_box_run_p
3685 = (new_face->box != FACE_NO_BOX
3686 && (it->face_id >= 0
3687 || IT_CHARPOS (*it) == BEG
3688 || new_face_id != face_before_it_pos (it)));
3689 it->face_box_p = new_face->box != FACE_NO_BOX;
3690 }
3691 }
3692 else
3693 {
3694 int base_face_id;
3695 ptrdiff_t bufpos;
3696 int i;
3697 Lisp_Object from_overlay
3698 = (it->current.overlay_string_index >= 0
3699 ? it->string_overlays[it->current.overlay_string_index]
3700 : Qnil);
3701
3702 /* See if we got to this string directly or indirectly from
3703 an overlay property. That includes the before-string or
3704 after-string of an overlay, strings in display properties
3705 provided by an overlay, their text properties, etc.
3706
3707 FROM_OVERLAY is the overlay that brought us here, or nil if none. */
3708 if (! NILP (from_overlay))
3709 for (i = it->sp - 1; i >= 0; i--)
3710 {
3711 if (it->stack[i].current.overlay_string_index >= 0)
3712 from_overlay
3713 = it->string_overlays[it->stack[i].current.overlay_string_index];
3714 else if (! NILP (it->stack[i].from_overlay))
3715 from_overlay = it->stack[i].from_overlay;
3716
3717 if (!NILP (from_overlay))
3718 break;
3719 }
3720
3721 if (! NILP (from_overlay))
3722 {
3723 bufpos = IT_CHARPOS (*it);
3724 /* For a string from an overlay, the base face depends
3725 only on text properties and ignores overlays. */
3726 base_face_id
3727 = face_for_overlay_string (it->w,
3728 IT_CHARPOS (*it),
3729 it->region_beg_charpos,
3730 it->region_end_charpos,
3731 &next_stop,
3732 (IT_CHARPOS (*it)
3733 + TEXT_PROP_DISTANCE_LIMIT),
3734 0,
3735 from_overlay);
3736 }
3737 else
3738 {
3739 bufpos = 0;
3740
3741 /* For strings from a `display' property, use the face at
3742 IT's current buffer position as the base face to merge
3743 with, so that overlay strings appear in the same face as
3744 surrounding text, unless they specify their own
3745 faces. */
3746 base_face_id = it->string_from_prefix_prop_p
3747 ? DEFAULT_FACE_ID
3748 : underlying_face_id (it);
3749 }
3750
3751 new_face_id = face_at_string_position (it->w,
3752 it->string,
3753 IT_STRING_CHARPOS (*it),
3754 bufpos,
3755 it->region_beg_charpos,
3756 it->region_end_charpos,
3757 &next_stop,
3758 base_face_id, 0);
3759
3760 /* Is this a start of a run of characters with box? Caveat:
3761 this can be called for a freshly allocated iterator; face_id
3762 is -1 is this case. We know that the new face will not
3763 change until the next check pos, i.e. if the new face has a
3764 box, all characters up to that position will have a
3765 box. But, as usual, we don't know whether that position
3766 is really the end. */
3767 if (new_face_id != it->face_id)
3768 {
3769 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
3770 struct face *old_face = FACE_FROM_ID (it->f, it->face_id);
3771
3772 /* If new face has a box but old face hasn't, this is the
3773 start of a run of characters with box, i.e. it has a
3774 shadow on the left side. */
3775 it->start_of_box_run_p
3776 = new_face->box && (old_face == NULL || !old_face->box);
3777 it->face_box_p = new_face->box != FACE_NO_BOX;
3778 }
3779 }
3780
3781 it->face_id = new_face_id;
3782 return HANDLED_NORMALLY;
3783 }
3784
3785
3786 /* Return the ID of the face ``underlying'' IT's current position,
3787 which is in a string. If the iterator is associated with a
3788 buffer, return the face at IT's current buffer position.
3789 Otherwise, use the iterator's base_face_id. */
3790
3791 static int
3792 underlying_face_id (struct it *it)
3793 {
3794 int face_id = it->base_face_id, i;
3795
3796 xassert (STRINGP (it->string));
3797
3798 for (i = it->sp - 1; i >= 0; --i)
3799 if (NILP (it->stack[i].string))
3800 face_id = it->stack[i].face_id;
3801
3802 return face_id;
3803 }
3804
3805
3806 /* Compute the face one character before or after the current position
3807 of IT, in the visual order. BEFORE_P non-zero means get the face
3808 in front (to the left in L2R paragraphs, to the right in R2L
3809 paragraphs) of IT's screen position. Value is the ID of the face. */
3810
3811 static int
3812 face_before_or_after_it_pos (struct it *it, int before_p)
3813 {
3814 int face_id, limit;
3815 ptrdiff_t next_check_charpos;
3816 struct it it_copy;
3817 void *it_copy_data = NULL;
3818
3819 xassert (it->s == NULL);
3820
3821 if (STRINGP (it->string))
3822 {
3823 ptrdiff_t bufpos, charpos;
3824 int base_face_id;
3825
3826 /* No face change past the end of the string (for the case
3827 we are padding with spaces). No face change before the
3828 string start. */
3829 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string)
3830 || (IT_STRING_CHARPOS (*it) == 0 && before_p))
3831 return it->face_id;
3832
3833 if (!it->bidi_p)
3834 {
3835 /* Set charpos to the position before or after IT's current
3836 position, in the logical order, which in the non-bidi
3837 case is the same as the visual order. */
3838 if (before_p)
3839 charpos = IT_STRING_CHARPOS (*it) - 1;
3840 else if (it->what == IT_COMPOSITION)
3841 /* For composition, we must check the character after the
3842 composition. */
3843 charpos = IT_STRING_CHARPOS (*it) + it->cmp_it.nchars;
3844 else
3845 charpos = IT_STRING_CHARPOS (*it) + 1;
3846 }
3847 else
3848 {
3849 if (before_p)
3850 {
3851 /* With bidi iteration, the character before the current
3852 in the visual order cannot be found by simple
3853 iteration, because "reverse" reordering is not
3854 supported. Instead, we need to use the move_it_*
3855 family of functions. */
3856 /* Ignore face changes before the first visible
3857 character on this display line. */
3858 if (it->current_x <= it->first_visible_x)
3859 return it->face_id;
3860 SAVE_IT (it_copy, *it, it_copy_data);
3861 /* Implementation note: Since move_it_in_display_line
3862 works in the iterator geometry, and thinks the first
3863 character is always the leftmost, even in R2L lines,
3864 we don't need to distinguish between the R2L and L2R
3865 cases here. */
3866 move_it_in_display_line (&it_copy, SCHARS (it_copy.string),
3867 it_copy.current_x - 1, MOVE_TO_X);
3868 charpos = IT_STRING_CHARPOS (it_copy);
3869 RESTORE_IT (it, it, it_copy_data);
3870 }
3871 else
3872 {
3873 /* Set charpos to the string position of the character
3874 that comes after IT's current position in the visual
3875 order. */
3876 int n = (it->what == IT_COMPOSITION ? it->cmp_it.nchars : 1);
3877
3878 it_copy = *it;
3879 while (n--)
3880 bidi_move_to_visually_next (&it_copy.bidi_it);
3881
3882 charpos = it_copy.bidi_it.charpos;
3883 }
3884 }
3885 xassert (0 <= charpos && charpos <= SCHARS (it->string));
3886
3887 if (it->current.overlay_string_index >= 0)
3888 bufpos = IT_CHARPOS (*it);
3889 else
3890 bufpos = 0;
3891
3892 base_face_id = underlying_face_id (it);
3893
3894 /* Get the face for ASCII, or unibyte. */
3895 face_id = face_at_string_position (it->w,
3896 it->string,
3897 charpos,
3898 bufpos,
3899 it->region_beg_charpos,
3900 it->region_end_charpos,
3901 &next_check_charpos,
3902 base_face_id, 0);
3903
3904 /* Correct the face for charsets different from ASCII. Do it
3905 for the multibyte case only. The face returned above is
3906 suitable for unibyte text if IT->string is unibyte. */
3907 if (STRING_MULTIBYTE (it->string))
3908 {
3909 struct text_pos pos1 = string_pos (charpos, it->string);
3910 const unsigned char *p = SDATA (it->string) + BYTEPOS (pos1);
3911 int c, len;
3912 struct face *face = FACE_FROM_ID (it->f, face_id);
3913
3914 c = string_char_and_length (p, &len);
3915 face_id = FACE_FOR_CHAR (it->f, face, c, charpos, it->string);
3916 }
3917 }
3918 else
3919 {
3920 struct text_pos pos;
3921
3922 if ((IT_CHARPOS (*it) >= ZV && !before_p)
3923 || (IT_CHARPOS (*it) <= BEGV && before_p))
3924 return it->face_id;
3925
3926 limit = IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT;
3927 pos = it->current.pos;
3928
3929 if (!it->bidi_p)
3930 {
3931 if (before_p)
3932 DEC_TEXT_POS (pos, it->multibyte_p);
3933 else
3934 {
3935 if (it->what == IT_COMPOSITION)
3936 {
3937 /* For composition, we must check the position after
3938 the composition. */
3939 pos.charpos += it->cmp_it.nchars;
3940 pos.bytepos += it->len;
3941 }
3942 else
3943 INC_TEXT_POS (pos, it->multibyte_p);
3944 }
3945 }
3946 else
3947 {
3948 if (before_p)
3949 {
3950 /* With bidi iteration, the character before the current
3951 in the visual order cannot be found by simple
3952 iteration, because "reverse" reordering is not
3953 supported. Instead, we need to use the move_it_*
3954 family of functions. */
3955 /* Ignore face changes before the first visible
3956 character on this display line. */
3957 if (it->current_x <= it->first_visible_x)
3958 return it->face_id;
3959 SAVE_IT (it_copy, *it, it_copy_data);
3960 /* Implementation note: Since move_it_in_display_line
3961 works in the iterator geometry, and thinks the first
3962 character is always the leftmost, even in R2L lines,
3963 we don't need to distinguish between the R2L and L2R
3964 cases here. */
3965 move_it_in_display_line (&it_copy, ZV,
3966 it_copy.current_x - 1, MOVE_TO_X);
3967 pos = it_copy.current.pos;
3968 RESTORE_IT (it, it, it_copy_data);
3969 }
3970 else
3971 {
3972 /* Set charpos to the buffer position of the character
3973 that comes after IT's current position in the visual
3974 order. */
3975 int n = (it->what == IT_COMPOSITION ? it->cmp_it.nchars : 1);
3976
3977 it_copy = *it;
3978 while (n--)
3979 bidi_move_to_visually_next (&it_copy.bidi_it);
3980
3981 SET_TEXT_POS (pos,
3982 it_copy.bidi_it.charpos, it_copy.bidi_it.bytepos);
3983 }
3984 }
3985 xassert (BEGV <= CHARPOS (pos) && CHARPOS (pos) <= ZV);
3986
3987 /* Determine face for CHARSET_ASCII, or unibyte. */
3988 face_id = face_at_buffer_position (it->w,
3989 CHARPOS (pos),
3990 it->region_beg_charpos,
3991 it->region_end_charpos,
3992 &next_check_charpos,
3993 limit, 0, -1);
3994
3995 /* Correct the face for charsets different from ASCII. Do it
3996 for the multibyte case only. The face returned above is
3997 suitable for unibyte text if current_buffer is unibyte. */
3998 if (it->multibyte_p)
3999 {
4000 int c = FETCH_MULTIBYTE_CHAR (BYTEPOS (pos));
4001 struct face *face = FACE_FROM_ID (it->f, face_id);
4002 face_id = FACE_FOR_CHAR (it->f, face, c, CHARPOS (pos), Qnil);
4003 }
4004 }
4005
4006 return face_id;
4007 }
4008
4009
4010 \f
4011 /***********************************************************************
4012 Invisible text
4013 ***********************************************************************/
4014
4015 /* Set up iterator IT from invisible properties at its current
4016 position. Called from handle_stop. */
4017
4018 static enum prop_handled
4019 handle_invisible_prop (struct it *it)
4020 {
4021 enum prop_handled handled = HANDLED_NORMALLY;
4022
4023 if (STRINGP (it->string))
4024 {
4025 Lisp_Object prop, end_charpos, limit, charpos;
4026
4027 /* Get the value of the invisible text property at the
4028 current position. Value will be nil if there is no such
4029 property. */
4030 charpos = make_number (IT_STRING_CHARPOS (*it));
4031 prop = Fget_text_property (charpos, Qinvisible, it->string);
4032
4033 if (!NILP (prop)
4034 && IT_STRING_CHARPOS (*it) < it->end_charpos)
4035 {
4036 ptrdiff_t endpos;
4037
4038 handled = HANDLED_RECOMPUTE_PROPS;
4039
4040 /* Get the position at which the next change of the
4041 invisible text property can be found in IT->string.
4042 Value will be nil if the property value is the same for
4043 all the rest of IT->string. */
4044 XSETINT (limit, SCHARS (it->string));
4045 end_charpos = Fnext_single_property_change (charpos, Qinvisible,
4046 it->string, limit);
4047
4048 /* Text at current position is invisible. The next
4049 change in the property is at position end_charpos.
4050 Move IT's current position to that position. */
4051 if (INTEGERP (end_charpos)
4052 && (endpos = XFASTINT (end_charpos)) < XFASTINT (limit))
4053 {
4054 struct text_pos old;
4055 ptrdiff_t oldpos;
4056
4057 old = it->current.string_pos;
4058 oldpos = CHARPOS (old);
4059 if (it->bidi_p)
4060 {
4061 if (it->bidi_it.first_elt
4062 && it->bidi_it.charpos < SCHARS (it->string))
4063 bidi_paragraph_init (it->paragraph_embedding,
4064 &it->bidi_it, 1);
4065 /* Bidi-iterate out of the invisible text. */
4066 do
4067 {
4068 bidi_move_to_visually_next (&it->bidi_it);
4069 }
4070 while (oldpos <= it->bidi_it.charpos
4071 && it->bidi_it.charpos < endpos);
4072
4073 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
4074 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
4075 if (IT_CHARPOS (*it) >= endpos)
4076 it->prev_stop = endpos;
4077 }
4078 else
4079 {
4080 IT_STRING_CHARPOS (*it) = XFASTINT (end_charpos);
4081 compute_string_pos (&it->current.string_pos, old, it->string);
4082 }
4083 }
4084 else
4085 {
4086 /* The rest of the string is invisible. If this is an
4087 overlay string, proceed with the next overlay string
4088 or whatever comes and return a character from there. */
4089 if (it->current.overlay_string_index >= 0)
4090 {
4091 next_overlay_string (it);
4092 /* Don't check for overlay strings when we just
4093 finished processing them. */
4094 handled = HANDLED_OVERLAY_STRING_CONSUMED;
4095 }
4096 else
4097 {
4098 IT_STRING_CHARPOS (*it) = SCHARS (it->string);
4099 IT_STRING_BYTEPOS (*it) = SBYTES (it->string);
4100 }
4101 }
4102 }
4103 }
4104 else
4105 {
4106 int invis_p;
4107 ptrdiff_t newpos, next_stop, start_charpos, tem;
4108 Lisp_Object pos, prop, overlay;
4109
4110 /* First of all, is there invisible text at this position? */
4111 tem = start_charpos = IT_CHARPOS (*it);
4112 pos = make_number (tem);
4113 prop = get_char_property_and_overlay (pos, Qinvisible, it->window,
4114 &overlay);
4115 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
4116
4117 /* If we are on invisible text, skip over it. */
4118 if (invis_p && start_charpos < it->end_charpos)
4119 {
4120 /* Record whether we have to display an ellipsis for the
4121 invisible text. */
4122 int display_ellipsis_p = invis_p == 2;
4123
4124 handled = HANDLED_RECOMPUTE_PROPS;
4125
4126 /* Loop skipping over invisible text. The loop is left at
4127 ZV or with IT on the first char being visible again. */
4128 do
4129 {
4130 /* Try to skip some invisible text. Return value is the
4131 position reached which can be equal to where we start
4132 if there is nothing invisible there. This skips both
4133 over invisible text properties and overlays with
4134 invisible property. */
4135 newpos = skip_invisible (tem, &next_stop, ZV, it->window);
4136
4137 /* If we skipped nothing at all we weren't at invisible
4138 text in the first place. If everything to the end of
4139 the buffer was skipped, end the loop. */
4140 if (newpos == tem || newpos >= ZV)
4141 invis_p = 0;
4142 else
4143 {
4144 /* We skipped some characters but not necessarily
4145 all there are. Check if we ended up on visible
4146 text. Fget_char_property returns the property of
4147 the char before the given position, i.e. if we
4148 get invis_p = 0, this means that the char at
4149 newpos is visible. */
4150 pos = make_number (newpos);
4151 prop = Fget_char_property (pos, Qinvisible, it->window);
4152 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
4153 }
4154
4155 /* If we ended up on invisible text, proceed to
4156 skip starting with next_stop. */
4157 if (invis_p)
4158 tem = next_stop;
4159
4160 /* If there are adjacent invisible texts, don't lose the
4161 second one's ellipsis. */
4162 if (invis_p == 2)
4163 display_ellipsis_p = 1;
4164 }
4165 while (invis_p);
4166
4167 /* The position newpos is now either ZV or on visible text. */
4168 if (it->bidi_p)
4169 {
4170 ptrdiff_t bpos = CHAR_TO_BYTE (newpos);
4171 int on_newline =
4172 bpos == ZV_BYTE || FETCH_BYTE (bpos) == '\n';
4173 int after_newline =
4174 newpos <= BEGV || FETCH_BYTE (bpos - 1) == '\n';
4175
4176 /* If the invisible text ends on a newline or on a
4177 character after a newline, we can avoid the costly,
4178 character by character, bidi iteration to NEWPOS, and
4179 instead simply reseat the iterator there. That's
4180 because all bidi reordering information is tossed at
4181 the newline. This is a big win for modes that hide
4182 complete lines, like Outline, Org, etc. */
4183 if (on_newline || after_newline)
4184 {
4185 struct text_pos tpos;
4186 bidi_dir_t pdir = it->bidi_it.paragraph_dir;
4187
4188 SET_TEXT_POS (tpos, newpos, bpos);
4189 reseat_1 (it, tpos, 0);
4190 /* If we reseat on a newline/ZV, we need to prep the
4191 bidi iterator for advancing to the next character
4192 after the newline/EOB, keeping the current paragraph
4193 direction (so that PRODUCE_GLYPHS does TRT wrt
4194 prepending/appending glyphs to a glyph row). */
4195 if (on_newline)
4196 {
4197 it->bidi_it.first_elt = 0;
4198 it->bidi_it.paragraph_dir = pdir;
4199 it->bidi_it.ch = (bpos == ZV_BYTE) ? -1 : '\n';
4200 it->bidi_it.nchars = 1;
4201 it->bidi_it.ch_len = 1;
4202 }
4203 }
4204 else /* Must use the slow method. */
4205 {
4206 /* With bidi iteration, the region of invisible text
4207 could start and/or end in the middle of a
4208 non-base embedding level. Therefore, we need to
4209 skip invisible text using the bidi iterator,
4210 starting at IT's current position, until we find
4211 ourselves outside of the invisible text.
4212 Skipping invisible text _after_ bidi iteration
4213 avoids affecting the visual order of the
4214 displayed text when invisible properties are
4215 added or removed. */
4216 if (it->bidi_it.first_elt && it->bidi_it.charpos < ZV)
4217 {
4218 /* If we were `reseat'ed to a new paragraph,
4219 determine the paragraph base direction. We
4220 need to do it now because
4221 next_element_from_buffer may not have a
4222 chance to do it, if we are going to skip any
4223 text at the beginning, which resets the
4224 FIRST_ELT flag. */
4225 bidi_paragraph_init (it->paragraph_embedding,
4226 &it->bidi_it, 1);
4227 }
4228 do
4229 {
4230 bidi_move_to_visually_next (&it->bidi_it);
4231 }
4232 while (it->stop_charpos <= it->bidi_it.charpos
4233 && it->bidi_it.charpos < newpos);
4234 IT_CHARPOS (*it) = it->bidi_it.charpos;
4235 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
4236 /* If we overstepped NEWPOS, record its position in
4237 the iterator, so that we skip invisible text if
4238 later the bidi iteration lands us in the
4239 invisible region again. */
4240 if (IT_CHARPOS (*it) >= newpos)
4241 it->prev_stop = newpos;
4242 }
4243 }
4244 else
4245 {
4246 IT_CHARPOS (*it) = newpos;
4247 IT_BYTEPOS (*it) = CHAR_TO_BYTE (newpos);
4248 }
4249
4250 /* If there are before-strings at the start of invisible
4251 text, and the text is invisible because of a text
4252 property, arrange to show before-strings because 20.x did
4253 it that way. (If the text is invisible because of an
4254 overlay property instead of a text property, this is
4255 already handled in the overlay code.) */
4256 if (NILP (overlay)
4257 && get_overlay_strings (it, it->stop_charpos))
4258 {
4259 handled = HANDLED_RECOMPUTE_PROPS;
4260 it->stack[it->sp - 1].display_ellipsis_p = display_ellipsis_p;
4261 }
4262 else if (display_ellipsis_p)
4263 {
4264 /* Make sure that the glyphs of the ellipsis will get
4265 correct `charpos' values. If we would not update
4266 it->position here, the glyphs would belong to the
4267 last visible character _before_ the invisible
4268 text, which confuses `set_cursor_from_row'.
4269
4270 We use the last invisible position instead of the
4271 first because this way the cursor is always drawn on
4272 the first "." of the ellipsis, whenever PT is inside
4273 the invisible text. Otherwise the cursor would be
4274 placed _after_ the ellipsis when the point is after the
4275 first invisible character. */
4276 if (!STRINGP (it->object))
4277 {
4278 it->position.charpos = newpos - 1;
4279 it->position.bytepos = CHAR_TO_BYTE (it->position.charpos);
4280 }
4281 it->ellipsis_p = 1;
4282 /* Let the ellipsis display before
4283 considering any properties of the following char.
4284 Fixes jasonr@gnu.org 01 Oct 07 bug. */
4285 handled = HANDLED_RETURN;
4286 }
4287 }
4288 }
4289
4290 return handled;
4291 }
4292
4293
4294 /* Make iterator IT return `...' next.
4295 Replaces LEN characters from buffer. */
4296
4297 static void
4298 setup_for_ellipsis (struct it *it, int len)
4299 {
4300 /* Use the display table definition for `...'. Invalid glyphs
4301 will be handled by the method returning elements from dpvec. */
4302 if (it->dp && VECTORP (DISP_INVIS_VECTOR (it->dp)))
4303 {
4304 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
4305 it->dpvec = v->contents;
4306 it->dpend = v->contents + v->header.size;
4307 }
4308 else
4309 {
4310 /* Default `...'. */
4311 it->dpvec = default_invis_vector;
4312 it->dpend = default_invis_vector + 3;
4313 }
4314
4315 it->dpvec_char_len = len;
4316 it->current.dpvec_index = 0;
4317 it->dpvec_face_id = -1;
4318
4319 /* Remember the current face id in case glyphs specify faces.
4320 IT's face is restored in set_iterator_to_next.
4321 saved_face_id was set to preceding char's face in handle_stop. */
4322 if (it->saved_face_id < 0 || it->saved_face_id != it->face_id)
4323 it->saved_face_id = it->face_id = DEFAULT_FACE_ID;
4324
4325 it->method = GET_FROM_DISPLAY_VECTOR;
4326 it->ellipsis_p = 1;
4327 }
4328
4329
4330 \f
4331 /***********************************************************************
4332 'display' property
4333 ***********************************************************************/
4334
4335 /* Set up iterator IT from `display' property at its current position.
4336 Called from handle_stop.
4337 We return HANDLED_RETURN if some part of the display property
4338 overrides the display of the buffer text itself.
4339 Otherwise we return HANDLED_NORMALLY. */
4340
4341 static enum prop_handled
4342 handle_display_prop (struct it *it)
4343 {
4344 Lisp_Object propval, object, overlay;
4345 struct text_pos *position;
4346 ptrdiff_t bufpos;
4347 /* Nonzero if some property replaces the display of the text itself. */
4348 int display_replaced_p = 0;
4349
4350 if (STRINGP (it->string))
4351 {
4352 object = it->string;
4353 position = &it->current.string_pos;
4354 bufpos = CHARPOS (it->current.pos);
4355 }
4356 else
4357 {
4358 XSETWINDOW (object, it->w);
4359 position = &it->current.pos;
4360 bufpos = CHARPOS (*position);
4361 }
4362
4363 /* Reset those iterator values set from display property values. */
4364 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
4365 it->space_width = Qnil;
4366 it->font_height = Qnil;
4367 it->voffset = 0;
4368
4369 /* We don't support recursive `display' properties, i.e. string
4370 values that have a string `display' property, that have a string
4371 `display' property etc. */
4372 if (!it->string_from_display_prop_p)
4373 it->area = TEXT_AREA;
4374
4375 propval = get_char_property_and_overlay (make_number (position->charpos),
4376 Qdisplay, object, &overlay);
4377 if (NILP (propval))
4378 return HANDLED_NORMALLY;
4379 /* Now OVERLAY is the overlay that gave us this property, or nil
4380 if it was a text property. */
4381
4382 if (!STRINGP (it->string))
4383 object = it->w->buffer;
4384
4385 display_replaced_p = handle_display_spec (it, propval, object, overlay,
4386 position, bufpos,
4387 FRAME_WINDOW_P (it->f));
4388
4389 return display_replaced_p ? HANDLED_RETURN : HANDLED_NORMALLY;
4390 }
4391
4392 /* Subroutine of handle_display_prop. Returns non-zero if the display
4393 specification in SPEC is a replacing specification, i.e. it would
4394 replace the text covered by `display' property with something else,
4395 such as an image or a display string. If SPEC includes any kind or
4396 `(space ...) specification, the value is 2; this is used by
4397 compute_display_string_pos, which see.
4398
4399 See handle_single_display_spec for documentation of arguments.
4400 frame_window_p is non-zero if the window being redisplayed is on a
4401 GUI frame; this argument is used only if IT is NULL, see below.
4402
4403 IT can be NULL, if this is called by the bidi reordering code
4404 through compute_display_string_pos, which see. In that case, this
4405 function only examines SPEC, but does not otherwise "handle" it, in
4406 the sense that it doesn't set up members of IT from the display
4407 spec. */
4408 static int
4409 handle_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
4410 Lisp_Object overlay, struct text_pos *position,
4411 ptrdiff_t bufpos, int frame_window_p)
4412 {
4413 int replacing_p = 0;
4414 int rv;
4415
4416 if (CONSP (spec)
4417 /* Simple specifications. */
4418 && !EQ (XCAR (spec), Qimage)
4419 #ifdef HAVE_XWIDGETS
4420 && !EQ (XCAR (spec), Qxwidget)
4421 #endif
4422 && !EQ (XCAR (spec), Qspace)
4423 && !EQ (XCAR (spec), Qwhen)
4424 && !EQ (XCAR (spec), Qslice)
4425 && !EQ (XCAR (spec), Qspace_width)
4426 && !EQ (XCAR (spec), Qheight)
4427 && !EQ (XCAR (spec), Qraise)
4428 /* Marginal area specifications. */
4429 && !(CONSP (XCAR (spec)) && EQ (XCAR (XCAR (spec)), Qmargin))
4430 && !EQ (XCAR (spec), Qleft_fringe)
4431 && !EQ (XCAR (spec), Qright_fringe)
4432 && !NILP (XCAR (spec)))
4433 {
4434 for (; CONSP (spec); spec = XCDR (spec))
4435 {
4436 if ((rv = handle_single_display_spec (it, XCAR (spec), object,
4437 overlay, position, bufpos,
4438 replacing_p, frame_window_p)))
4439 {
4440 replacing_p = rv;
4441 /* If some text in a string is replaced, `position' no
4442 longer points to the position of `object'. */
4443 if (!it || STRINGP (object))
4444 break;
4445 }
4446 }
4447 }
4448 else if (VECTORP (spec))
4449 {
4450 ptrdiff_t i;
4451 for (i = 0; i < ASIZE (spec); ++i)
4452 if ((rv = handle_single_display_spec (it, AREF (spec, i), object,
4453 overlay, position, bufpos,
4454 replacing_p, frame_window_p)))
4455 {
4456 replacing_p = rv;
4457 /* If some text in a string is replaced, `position' no
4458 longer points to the position of `object'. */
4459 if (!it || STRINGP (object))
4460 break;
4461 }
4462 }
4463 else
4464 {
4465 if ((rv = handle_single_display_spec (it, spec, object, overlay,
4466 position, bufpos, 0,
4467 frame_window_p)))
4468 replacing_p = rv;
4469 }
4470
4471 return replacing_p;
4472 }
4473
4474 /* Value is the position of the end of the `display' property starting
4475 at START_POS in OBJECT. */
4476
4477 static struct text_pos
4478 display_prop_end (struct it *it, Lisp_Object object, struct text_pos start_pos)
4479 {
4480 Lisp_Object end;
4481 struct text_pos end_pos;
4482
4483 end = Fnext_single_char_property_change (make_number (CHARPOS (start_pos)),
4484 Qdisplay, object, Qnil);
4485 CHARPOS (end_pos) = XFASTINT (end);
4486 if (STRINGP (object))
4487 compute_string_pos (&end_pos, start_pos, it->string);
4488 else
4489 BYTEPOS (end_pos) = CHAR_TO_BYTE (XFASTINT (end));
4490
4491 return end_pos;
4492 }
4493
4494
4495 /* Set up IT from a single `display' property specification SPEC. OBJECT
4496 is the object in which the `display' property was found. *POSITION
4497 is the position in OBJECT at which the `display' property was found.
4498 BUFPOS is the buffer position of OBJECT (different from POSITION if
4499 OBJECT is not a buffer). DISPLAY_REPLACED_P non-zero means that we
4500 previously saw a display specification which already replaced text
4501 display with something else, for example an image; we ignore such
4502 properties after the first one has been processed.
4503
4504 OVERLAY is the overlay this `display' property came from,
4505 or nil if it was a text property.
4506
4507 If SPEC is a `space' or `image' specification, and in some other
4508 cases too, set *POSITION to the position where the `display'
4509 property ends.
4510
4511 If IT is NULL, only examine the property specification in SPEC, but
4512 don't set up IT. In that case, FRAME_WINDOW_P non-zero means SPEC
4513 is intended to be displayed in a window on a GUI frame.
4514
4515 Value is non-zero if something was found which replaces the display
4516 of buffer or string text. */
4517
4518 static int
4519 handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
4520 Lisp_Object overlay, struct text_pos *position,
4521 ptrdiff_t bufpos, int display_replaced_p,
4522 int frame_window_p)
4523 {
4524 Lisp_Object form;
4525 Lisp_Object location, value;
4526 struct text_pos start_pos = *position;
4527 int valid_p;
4528
4529 /* If SPEC is a list of the form `(when FORM . VALUE)', evaluate FORM.
4530 If the result is non-nil, use VALUE instead of SPEC. */
4531 form = Qt;
4532 if (CONSP (spec) && EQ (XCAR (spec), Qwhen))
4533 {
4534 spec = XCDR (spec);
4535 if (!CONSP (spec))
4536 return 0;
4537 form = XCAR (spec);
4538 spec = XCDR (spec);
4539 }
4540
4541 if (!NILP (form) && !EQ (form, Qt))
4542 {
4543 ptrdiff_t count = SPECPDL_INDEX ();
4544 struct gcpro gcpro1;
4545
4546 /* Bind `object' to the object having the `display' property, a
4547 buffer or string. Bind `position' to the position in the
4548 object where the property was found, and `buffer-position'
4549 to the current position in the buffer. */
4550
4551 if (NILP (object))
4552 XSETBUFFER (object, current_buffer);
4553 specbind (Qobject, object);
4554 specbind (Qposition, make_number (CHARPOS (*position)));
4555 specbind (Qbuffer_position, make_number (bufpos));
4556 GCPRO1 (form);
4557 form = safe_eval (form);
4558 UNGCPRO;
4559 unbind_to (count, Qnil);
4560 }
4561
4562 if (NILP (form))
4563 return 0;
4564
4565 /* Handle `(height HEIGHT)' specifications. */
4566 if (CONSP (spec)
4567 && EQ (XCAR (spec), Qheight)
4568 && CONSP (XCDR (spec)))
4569 {
4570 if (it)
4571 {
4572 if (!FRAME_WINDOW_P (it->f))
4573 return 0;
4574
4575 it->font_height = XCAR (XCDR (spec));
4576 if (!NILP (it->font_height))
4577 {
4578 struct face *face = FACE_FROM_ID (it->f, it->face_id);
4579 int new_height = -1;
4580
4581 if (CONSP (it->font_height)
4582 && (EQ (XCAR (it->font_height), Qplus)
4583 || EQ (XCAR (it->font_height), Qminus))
4584 && CONSP (XCDR (it->font_height))
4585 && RANGED_INTEGERP (0, XCAR (XCDR (it->font_height)), INT_MAX))
4586 {
4587 /* `(+ N)' or `(- N)' where N is an integer. */
4588 int steps = XINT (XCAR (XCDR (it->font_height)));
4589 if (EQ (XCAR (it->font_height), Qplus))
4590 steps = - steps;
4591 it->face_id = smaller_face (it->f, it->face_id, steps);
4592 }
4593 else if (FUNCTIONP (it->font_height))
4594 {
4595 /* Call function with current height as argument.
4596 Value is the new height. */
4597 Lisp_Object height;
4598 height = safe_call1 (it->font_height,
4599 face->lface[LFACE_HEIGHT_INDEX]);
4600 if (NUMBERP (height))
4601 new_height = XFLOATINT (height);
4602 }
4603 else if (NUMBERP (it->font_height))
4604 {
4605 /* Value is a multiple of the canonical char height. */
4606 struct face *f;
4607
4608 f = FACE_FROM_ID (it->f,
4609 lookup_basic_face (it->f, DEFAULT_FACE_ID));
4610 new_height = (XFLOATINT (it->font_height)
4611 * XINT (f->lface[LFACE_HEIGHT_INDEX]));
4612 }
4613 else
4614 {
4615 /* Evaluate IT->font_height with `height' bound to the
4616 current specified height to get the new height. */
4617 ptrdiff_t count = SPECPDL_INDEX ();
4618
4619 specbind (Qheight, face->lface[LFACE_HEIGHT_INDEX]);
4620 value = safe_eval (it->font_height);
4621 unbind_to (count, Qnil);
4622
4623 if (NUMBERP (value))
4624 new_height = XFLOATINT (value);
4625 }
4626
4627 if (new_height > 0)
4628 it->face_id = face_with_height (it->f, it->face_id, new_height);
4629 }
4630 }
4631
4632 return 0;
4633 }
4634
4635 /* Handle `(space-width WIDTH)'. */
4636 if (CONSP (spec)
4637 && EQ (XCAR (spec), Qspace_width)
4638 && CONSP (XCDR (spec)))
4639 {
4640 if (it)
4641 {
4642 if (!FRAME_WINDOW_P (it->f))
4643 return 0;
4644
4645 value = XCAR (XCDR (spec));
4646 if (NUMBERP (value) && XFLOATINT (value) > 0)
4647 it->space_width = value;
4648 }
4649
4650 return 0;
4651 }
4652
4653 /* Handle `(slice X Y WIDTH HEIGHT)'. */
4654 if (CONSP (spec)
4655 && EQ (XCAR (spec), Qslice))
4656 {
4657 Lisp_Object tem;
4658
4659 if (it)
4660 {
4661 if (!FRAME_WINDOW_P (it->f))
4662 return 0;
4663
4664 if (tem = XCDR (spec), CONSP (tem))
4665 {
4666 it->slice.x = XCAR (tem);
4667 if (tem = XCDR (tem), CONSP (tem))
4668 {
4669 it->slice.y = XCAR (tem);
4670 if (tem = XCDR (tem), CONSP (tem))
4671 {
4672 it->slice.width = XCAR (tem);
4673 if (tem = XCDR (tem), CONSP (tem))
4674 it->slice.height = XCAR (tem);
4675 }
4676 }
4677 }
4678 }
4679
4680 return 0;
4681 }
4682
4683 /* Handle `(raise FACTOR)'. */
4684 if (CONSP (spec)
4685 && EQ (XCAR (spec), Qraise)
4686 && CONSP (XCDR (spec)))
4687 {
4688 if (it)
4689 {
4690 if (!FRAME_WINDOW_P (it->f))
4691 return 0;
4692
4693 #ifdef HAVE_WINDOW_SYSTEM
4694 value = XCAR (XCDR (spec));
4695 if (NUMBERP (value))
4696 {
4697 struct face *face = FACE_FROM_ID (it->f, it->face_id);
4698 it->voffset = - (XFLOATINT (value)
4699 * (FONT_HEIGHT (face->font)));
4700 }
4701 #endif /* HAVE_WINDOW_SYSTEM */
4702 }
4703
4704 return 0;
4705 }
4706
4707 /* Don't handle the other kinds of display specifications
4708 inside a string that we got from a `display' property. */
4709 if (it && it->string_from_display_prop_p)
4710 return 0;
4711
4712 /* Characters having this form of property are not displayed, so
4713 we have to find the end of the property. */
4714 if (it)
4715 {
4716 start_pos = *position;
4717 *position = display_prop_end (it, object, start_pos);
4718 }
4719 value = Qnil;
4720
4721 /* Stop the scan at that end position--we assume that all
4722 text properties change there. */
4723 if (it)
4724 it->stop_charpos = position->charpos;
4725
4726 /* Handle `(left-fringe BITMAP [FACE])'
4727 and `(right-fringe BITMAP [FACE])'. */
4728 if (CONSP (spec)
4729 && (EQ (XCAR (spec), Qleft_fringe)
4730 || EQ (XCAR (spec), Qright_fringe))
4731 && CONSP (XCDR (spec)))
4732 {
4733 int fringe_bitmap;
4734
4735 if (it)
4736 {
4737 if (!FRAME_WINDOW_P (it->f))
4738 /* If we return here, POSITION has been advanced
4739 across the text with this property. */
4740 {
4741 /* Synchronize the bidi iterator with POSITION. This is
4742 needed because we are not going to push the iterator
4743 on behalf of this display property, so there will be
4744 no pop_it call to do this synchronization for us. */
4745 if (it->bidi_p)
4746 {
4747 it->position = *position;
4748 iterate_out_of_display_property (it);
4749 *position = it->position;
4750 }
4751 return 1;
4752 }
4753 }
4754 else if (!frame_window_p)
4755 return 1;
4756
4757 #ifdef HAVE_WINDOW_SYSTEM
4758 value = XCAR (XCDR (spec));
4759 if (!SYMBOLP (value)
4760 || !(fringe_bitmap = lookup_fringe_bitmap (value)))
4761 /* If we return here, POSITION has been advanced
4762 across the text with this property. */
4763 {
4764 if (it && it->bidi_p)
4765 {
4766 it->position = *position;
4767 iterate_out_of_display_property (it);
4768 *position = it->position;
4769 }
4770 return 1;
4771 }
4772
4773 if (it)
4774 {
4775 int face_id = lookup_basic_face (it->f, DEFAULT_FACE_ID);;
4776
4777 if (CONSP (XCDR (XCDR (spec))))
4778 {
4779 Lisp_Object face_name = XCAR (XCDR (XCDR (spec)));
4780 int face_id2 = lookup_derived_face (it->f, face_name,
4781 FRINGE_FACE_ID, 0);
4782 if (face_id2 >= 0)
4783 face_id = face_id2;
4784 }
4785
4786 /* Save current settings of IT so that we can restore them
4787 when we are finished with the glyph property value. */
4788 push_it (it, position);
4789
4790 it->area = TEXT_AREA;
4791 it->what = IT_IMAGE;
4792 it->image_id = -1; /* no image */
4793 it->position = start_pos;
4794 it->object = NILP (object) ? it->w->buffer : object;
4795 it->method = GET_FROM_IMAGE;
4796 it->from_overlay = Qnil;
4797 it->face_id = face_id;
4798 it->from_disp_prop_p = 1;
4799
4800 /* Say that we haven't consumed the characters with
4801 `display' property yet. The call to pop_it in
4802 set_iterator_to_next will clean this up. */
4803 *position = start_pos;
4804
4805 if (EQ (XCAR (spec), Qleft_fringe))
4806 {
4807 it->left_user_fringe_bitmap = fringe_bitmap;
4808 it->left_user_fringe_face_id = face_id;
4809 }
4810 else
4811 {
4812 it->right_user_fringe_bitmap = fringe_bitmap;
4813 it->right_user_fringe_face_id = face_id;
4814 }
4815 }
4816 #endif /* HAVE_WINDOW_SYSTEM */
4817 return 1;
4818 }
4819
4820 /* Prepare to handle `((margin left-margin) ...)',
4821 `((margin right-margin) ...)' and `((margin nil) ...)'
4822 prefixes for display specifications. */
4823 location = Qunbound;
4824 if (CONSP (spec) && CONSP (XCAR (spec)))
4825 {
4826 Lisp_Object tem;
4827
4828 value = XCDR (spec);
4829 if (CONSP (value))
4830 value = XCAR (value);
4831
4832 tem = XCAR (spec);
4833 if (EQ (XCAR (tem), Qmargin)
4834 && (tem = XCDR (tem),
4835 tem = CONSP (tem) ? XCAR (tem) : Qnil,
4836 (NILP (tem)
4837 || EQ (tem, Qleft_margin)
4838 || EQ (tem, Qright_margin))))
4839 location = tem;
4840 }
4841
4842 if (EQ (location, Qunbound))
4843 {
4844 location = Qnil;
4845 value = spec;
4846 }
4847
4848 /* After this point, VALUE is the property after any
4849 margin prefix has been stripped. It must be a string,
4850 an image specification, or `(space ...)'.
4851
4852 LOCATION specifies where to display: `left-margin',
4853 `right-margin' or nil. */
4854
4855 valid_p = (STRINGP (value)
4856 #ifdef HAVE_WINDOW_SYSTEM
4857 || ((it ? FRAME_WINDOW_P (it->f) : frame_window_p)
4858 && valid_image_p (value))
4859 #endif /* not HAVE_WINDOW_SYSTEM */
4860 || (CONSP (value) && EQ (XCAR (value), Qspace))
4861 #ifdef HAVE_XWIDGETS
4862 || XWIDGETP(value)
4863 #endif
4864 );
4865
4866 if (valid_p && !display_replaced_p)
4867 {
4868 int retval = 1;
4869
4870 if (!it)
4871 {
4872 /* Callers need to know whether the display spec is any kind
4873 of `(space ...)' spec that is about to affect text-area
4874 display. */
4875 if (CONSP (value) && EQ (XCAR (value), Qspace) && NILP (location))
4876 retval = 2;
4877 return retval;
4878 }
4879
4880 /* Save current settings of IT so that we can restore them
4881 when we are finished with the glyph property value. */
4882 push_it (it, position);
4883 it->from_overlay = overlay;
4884 it->from_disp_prop_p = 1;
4885
4886 if (NILP (location))
4887 it->area = TEXT_AREA;
4888 else if (EQ (location, Qleft_margin))
4889 it->area = LEFT_MARGIN_AREA;
4890 else
4891 it->area = RIGHT_MARGIN_AREA;
4892
4893 if (STRINGP (value))
4894 {
4895 it->string = value;
4896 it->multibyte_p = STRING_MULTIBYTE (it->string);
4897 it->current.overlay_string_index = -1;
4898 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
4899 it->end_charpos = it->string_nchars = SCHARS (it->string);
4900 it->method = GET_FROM_STRING;
4901 it->stop_charpos = 0;
4902 it->prev_stop = 0;
4903 it->base_level_stop = 0;
4904 it->string_from_display_prop_p = 1;
4905 /* Say that we haven't consumed the characters with
4906 `display' property yet. The call to pop_it in
4907 set_iterator_to_next will clean this up. */
4908 if (BUFFERP (object))
4909 *position = start_pos;
4910
4911 /* Force paragraph direction to be that of the parent
4912 object. If the parent object's paragraph direction is
4913 not yet determined, default to L2R. */
4914 if (it->bidi_p && it->bidi_it.paragraph_dir == R2L)
4915 it->paragraph_embedding = it->bidi_it.paragraph_dir;
4916 else
4917 it->paragraph_embedding = L2R;
4918
4919 /* Set up the bidi iterator for this display string. */
4920 if (it->bidi_p)
4921 {
4922 it->bidi_it.string.lstring = it->string;
4923 it->bidi_it.string.s = NULL;
4924 it->bidi_it.string.schars = it->end_charpos;
4925 it->bidi_it.string.bufpos = bufpos;
4926 it->bidi_it.string.from_disp_str = 1;
4927 it->bidi_it.string.unibyte = !it->multibyte_p;
4928 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
4929 }
4930 }
4931 else if (CONSP (value) && EQ (XCAR (value), Qspace))
4932 {
4933 it->method = GET_FROM_STRETCH;
4934 it->object = value;
4935 *position = it->position = start_pos;
4936 retval = 1 + (it->area == TEXT_AREA);
4937 }
4938 #ifdef HAVE_XWIDGETS
4939 else if (XWIDGETP(value))
4940 {
4941 //printf("handle_single_display_spec: im an xwidget!!\n");
4942 it->what = IT_XWIDGET;
4943 it->method = GET_FROM_XWIDGET;
4944 it->position = start_pos;
4945 it->object = NILP (object) ? it->w->buffer : object;
4946 *position = start_pos;
4947
4948 it->xwidget = lookup_xwidget(value);
4949 }
4950 #endif
4951 #ifdef HAVE_WINDOW_SYSTEM
4952 else
4953 {
4954 it->what = IT_IMAGE;
4955 it->image_id = lookup_image (it->f, value);
4956 it->position = start_pos;
4957 it->object = NILP (object) ? it->w->buffer : object;
4958 it->method = GET_FROM_IMAGE;
4959
4960 /* Say that we haven't consumed the characters with
4961 `display' property yet. The call to pop_it in
4962 set_iterator_to_next will clean this up. */
4963 *position = start_pos;
4964 }
4965 #endif /* HAVE_WINDOW_SYSTEM */
4966
4967 return retval;
4968 }
4969
4970 /* Invalid property or property not supported. Restore
4971 POSITION to what it was before. */
4972 *position = start_pos;
4973 return 0;
4974 }
4975
4976 /* Check if PROP is a display property value whose text should be
4977 treated as intangible. OVERLAY is the overlay from which PROP
4978 came, or nil if it came from a text property. CHARPOS and BYTEPOS
4979 specify the buffer position covered by PROP. */
4980
4981 int
4982 display_prop_intangible_p (Lisp_Object prop, Lisp_Object overlay,
4983 ptrdiff_t charpos, ptrdiff_t bytepos)
4984 {
4985 int frame_window_p = FRAME_WINDOW_P (XFRAME (selected_frame));
4986 struct text_pos position;
4987
4988 SET_TEXT_POS (position, charpos, bytepos);
4989 return handle_display_spec (NULL, prop, Qnil, overlay,
4990 &position, charpos, frame_window_p);
4991 }
4992
4993
4994 /* Return 1 if PROP is a display sub-property value containing STRING.
4995
4996 Implementation note: this and the following function are really
4997 special cases of handle_display_spec and
4998 handle_single_display_spec, and should ideally use the same code.
4999 Until they do, these two pairs must be consistent and must be
5000 modified in sync. */
5001
5002 static int
5003 single_display_spec_string_p (Lisp_Object prop, Lisp_Object string)
5004 {
5005 if (EQ (string, prop))
5006 return 1;
5007
5008 /* Skip over `when FORM'. */
5009 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
5010 {
5011 prop = XCDR (prop);
5012 if (!CONSP (prop))
5013 return 0;
5014 /* Actually, the condition following `when' should be eval'ed,
5015 like handle_single_display_spec does, and we should return
5016 zero if it evaluates to nil. However, this function is
5017 called only when the buffer was already displayed and some
5018 glyph in the glyph matrix was found to come from a display
5019 string. Therefore, the condition was already evaluated, and
5020 the result was non-nil, otherwise the display string wouldn't
5021 have been displayed and we would have never been called for
5022 this property. Thus, we can skip the evaluation and assume
5023 its result is non-nil. */
5024 prop = XCDR (prop);
5025 }
5026
5027 if (CONSP (prop))
5028 /* Skip over `margin LOCATION'. */
5029 if (EQ (XCAR (prop), Qmargin))
5030 {
5031 prop = XCDR (prop);
5032 if (!CONSP (prop))
5033 return 0;
5034
5035 prop = XCDR (prop);
5036 if (!CONSP (prop))
5037 return 0;
5038 }
5039
5040 return EQ (prop, string) || (CONSP (prop) && EQ (XCAR (prop), string));
5041 }
5042
5043
5044 /* Return 1 if STRING appears in the `display' property PROP. */
5045
5046 static int
5047 display_prop_string_p (Lisp_Object prop, Lisp_Object string)
5048 {
5049 if (CONSP (prop)
5050 && !EQ (XCAR (prop), Qwhen)
5051 && !(CONSP (XCAR (prop)) && EQ (Qmargin, XCAR (XCAR (prop)))))
5052 {
5053 /* A list of sub-properties. */
5054 while (CONSP (prop))
5055 {
5056 if (single_display_spec_string_p (XCAR (prop), string))
5057 return 1;
5058 prop = XCDR (prop);
5059 }
5060 }
5061 else if (VECTORP (prop))
5062 {
5063 /* A vector of sub-properties. */
5064 ptrdiff_t i;
5065 for (i = 0; i < ASIZE (prop); ++i)
5066 if (single_display_spec_string_p (AREF (prop, i), string))
5067 return 1;
5068 }
5069 else
5070 return single_display_spec_string_p (prop, string);
5071
5072 return 0;
5073 }
5074
5075 /* Look for STRING in overlays and text properties in the current
5076 buffer, between character positions FROM and TO (excluding TO).
5077 BACK_P non-zero means look back (in this case, TO is supposed to be
5078 less than FROM).
5079 Value is the first character position where STRING was found, or
5080 zero if it wasn't found before hitting TO.
5081
5082 This function may only use code that doesn't eval because it is
5083 called asynchronously from note_mouse_highlight. */
5084
5085 static ptrdiff_t
5086 string_buffer_position_lim (Lisp_Object string,
5087 ptrdiff_t from, ptrdiff_t to, int back_p)
5088 {
5089 Lisp_Object limit, prop, pos;
5090 int found = 0;
5091
5092 pos = make_number (max (from, BEGV));
5093
5094 if (!back_p) /* looking forward */
5095 {
5096 limit = make_number (min (to, ZV));
5097 while (!found && !EQ (pos, limit))
5098 {
5099 prop = Fget_char_property (pos, Qdisplay, Qnil);
5100 if (!NILP (prop) && display_prop_string_p (prop, string))
5101 found = 1;
5102 else
5103 pos = Fnext_single_char_property_change (pos, Qdisplay, Qnil,
5104 limit);
5105 }
5106 }
5107 else /* looking back */
5108 {
5109 limit = make_number (max (to, BEGV));
5110 while (!found && !EQ (pos, limit))
5111 {
5112 prop = Fget_char_property (pos, Qdisplay, Qnil);
5113 if (!NILP (prop) && display_prop_string_p (prop, string))
5114 found = 1;
5115 else
5116 pos = Fprevious_single_char_property_change (pos, Qdisplay, Qnil,
5117 limit);
5118 }
5119 }
5120
5121 return found ? XINT (pos) : 0;
5122 }
5123
5124 /* Determine which buffer position in current buffer STRING comes from.
5125 AROUND_CHARPOS is an approximate position where it could come from.
5126 Value is the buffer position or 0 if it couldn't be determined.
5127
5128 This function is necessary because we don't record buffer positions
5129 in glyphs generated from strings (to keep struct glyph small).
5130 This function may only use code that doesn't eval because it is
5131 called asynchronously from note_mouse_highlight. */
5132
5133 static ptrdiff_t
5134 string_buffer_position (Lisp_Object string, ptrdiff_t around_charpos)
5135 {
5136 const int MAX_DISTANCE = 1000;
5137 ptrdiff_t found = string_buffer_position_lim (string, around_charpos,
5138 around_charpos + MAX_DISTANCE,
5139 0);
5140
5141 if (!found)
5142 found = string_buffer_position_lim (string, around_charpos,
5143 around_charpos - MAX_DISTANCE, 1);
5144 return found;
5145 }
5146
5147
5148 \f
5149 /***********************************************************************
5150 `composition' property
5151 ***********************************************************************/
5152
5153 /* Set up iterator IT from `composition' property at its current
5154 position. Called from handle_stop. */
5155
5156 static enum prop_handled
5157 handle_composition_prop (struct it *it)
5158 {
5159 Lisp_Object prop, string;
5160 ptrdiff_t pos, pos_byte, start, end;
5161
5162 if (STRINGP (it->string))
5163 {
5164 unsigned char *s;
5165
5166 pos = IT_STRING_CHARPOS (*it);
5167 pos_byte = IT_STRING_BYTEPOS (*it);
5168 string = it->string;
5169 s = SDATA (string) + pos_byte;
5170 it->c = STRING_CHAR (s);
5171 }
5172 else
5173 {
5174 pos = IT_CHARPOS (*it);
5175 pos_byte = IT_BYTEPOS (*it);
5176 string = Qnil;
5177 it->c = FETCH_CHAR (pos_byte);
5178 }
5179
5180 /* If there's a valid composition and point is not inside of the
5181 composition (in the case that the composition is from the current
5182 buffer), draw a glyph composed from the composition components. */
5183 if (find_composition (pos, -1, &start, &end, &prop, string)
5184 && COMPOSITION_VALID_P (start, end, prop)
5185 && (STRINGP (it->string) || (PT <= start || PT >= end)))
5186 {
5187 if (start < pos)
5188 /* As we can't handle this situation (perhaps font-lock added
5189 a new composition), we just return here hoping that next
5190 redisplay will detect this composition much earlier. */
5191 return HANDLED_NORMALLY;
5192 if (start != pos)
5193 {
5194 if (STRINGP (it->string))
5195 pos_byte = string_char_to_byte (it->string, start);
5196 else
5197 pos_byte = CHAR_TO_BYTE (start);
5198 }
5199 it->cmp_it.id = get_composition_id (start, pos_byte, end - start,
5200 prop, string);
5201
5202 if (it->cmp_it.id >= 0)
5203 {
5204 it->cmp_it.ch = -1;
5205 it->cmp_it.nchars = COMPOSITION_LENGTH (prop);
5206 it->cmp_it.nglyphs = -1;
5207 }
5208 }
5209
5210 return HANDLED_NORMALLY;
5211 }
5212
5213
5214 \f
5215 /***********************************************************************
5216 Overlay strings
5217 ***********************************************************************/
5218
5219 /* The following structure is used to record overlay strings for
5220 later sorting in load_overlay_strings. */
5221
5222 struct overlay_entry
5223 {
5224 Lisp_Object overlay;
5225 Lisp_Object string;
5226 EMACS_INT priority;
5227 int after_string_p;
5228 };
5229
5230
5231 /* Set up iterator IT from overlay strings at its current position.
5232 Called from handle_stop. */
5233
5234 static enum prop_handled
5235 handle_overlay_change (struct it *it)
5236 {
5237 if (!STRINGP (it->string) && get_overlay_strings (it, 0))
5238 return HANDLED_RECOMPUTE_PROPS;
5239 else
5240 return HANDLED_NORMALLY;
5241 }
5242
5243
5244 /* Set up the next overlay string for delivery by IT, if there is an
5245 overlay string to deliver. Called by set_iterator_to_next when the
5246 end of the current overlay string is reached. If there are more
5247 overlay strings to display, IT->string and
5248 IT->current.overlay_string_index are set appropriately here.
5249 Otherwise IT->string is set to nil. */
5250
5251 static void
5252 next_overlay_string (struct it *it)
5253 {
5254 ++it->current.overlay_string_index;
5255 if (it->current.overlay_string_index == it->n_overlay_strings)
5256 {
5257 /* No more overlay strings. Restore IT's settings to what
5258 they were before overlay strings were processed, and
5259 continue to deliver from current_buffer. */
5260
5261 it->ellipsis_p = (it->stack[it->sp - 1].display_ellipsis_p != 0);
5262 pop_it (it);
5263 xassert (it->sp > 0
5264 || (NILP (it->string)
5265 && it->method == GET_FROM_BUFFER
5266 && it->stop_charpos >= BEGV
5267 && it->stop_charpos <= it->end_charpos));
5268 it->current.overlay_string_index = -1;
5269 it->n_overlay_strings = 0;
5270 it->overlay_strings_charpos = -1;
5271 /* If there's an empty display string on the stack, pop the
5272 stack, to resync the bidi iterator with IT's position. Such
5273 empty strings are pushed onto the stack in
5274 get_overlay_strings_1. */
5275 if (it->sp > 0 && STRINGP (it->string) && !SCHARS (it->string))
5276 pop_it (it);
5277
5278 /* If we're at the end of the buffer, record that we have
5279 processed the overlay strings there already, so that
5280 next_element_from_buffer doesn't try it again. */
5281 if (NILP (it->string) && IT_CHARPOS (*it) >= it->end_charpos)
5282 it->overlay_strings_at_end_processed_p = 1;
5283 }
5284 else
5285 {
5286 /* There are more overlay strings to process. If
5287 IT->current.overlay_string_index has advanced to a position
5288 where we must load IT->overlay_strings with more strings, do
5289 it. We must load at the IT->overlay_strings_charpos where
5290 IT->n_overlay_strings was originally computed; when invisible
5291 text is present, this might not be IT_CHARPOS (Bug#7016). */
5292 int i = it->current.overlay_string_index % OVERLAY_STRING_CHUNK_SIZE;
5293
5294 if (it->current.overlay_string_index && i == 0)
5295 load_overlay_strings (it, it->overlay_strings_charpos);
5296
5297 /* Initialize IT to deliver display elements from the overlay
5298 string. */
5299 it->string = it->overlay_strings[i];
5300 it->multibyte_p = STRING_MULTIBYTE (it->string);
5301 SET_TEXT_POS (it->current.string_pos, 0, 0);
5302 it->method = GET_FROM_STRING;
5303 it->stop_charpos = 0;
5304 if (it->cmp_it.stop_pos >= 0)
5305 it->cmp_it.stop_pos = 0;
5306 it->prev_stop = 0;
5307 it->base_level_stop = 0;
5308
5309 /* Set up the bidi iterator for this overlay string. */
5310 if (it->bidi_p)
5311 {
5312 it->bidi_it.string.lstring = it->string;
5313 it->bidi_it.string.s = NULL;
5314 it->bidi_it.string.schars = SCHARS (it->string);
5315 it->bidi_it.string.bufpos = it->overlay_strings_charpos;
5316 it->bidi_it.string.from_disp_str = it->string_from_display_prop_p;
5317 it->bidi_it.string.unibyte = !it->multibyte_p;
5318 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
5319 }
5320 }
5321
5322 CHECK_IT (it);
5323 }
5324
5325
5326 /* Compare two overlay_entry structures E1 and E2. Used as a
5327 comparison function for qsort in load_overlay_strings. Overlay
5328 strings for the same position are sorted so that
5329
5330 1. All after-strings come in front of before-strings, except
5331 when they come from the same overlay.
5332
5333 2. Within after-strings, strings are sorted so that overlay strings
5334 from overlays with higher priorities come first.
5335
5336 2. Within before-strings, strings are sorted so that overlay
5337 strings from overlays with higher priorities come last.
5338
5339 Value is analogous to strcmp. */
5340
5341
5342 static int
5343 compare_overlay_entries (const void *e1, const void *e2)
5344 {
5345 struct overlay_entry *entry1 = (struct overlay_entry *) e1;
5346 struct overlay_entry *entry2 = (struct overlay_entry *) e2;
5347 int result;
5348
5349 if (entry1->after_string_p != entry2->after_string_p)
5350 {
5351 /* Let after-strings appear in front of before-strings if
5352 they come from different overlays. */
5353 if (EQ (entry1->overlay, entry2->overlay))
5354 result = entry1->after_string_p ? 1 : -1;
5355 else
5356 result = entry1->after_string_p ? -1 : 1;
5357 }
5358 else if (entry1->priority != entry2->priority)
5359 {
5360 if (entry1->after_string_p)
5361 /* After-strings sorted in order of decreasing priority. */
5362 result = entry2->priority < entry1->priority ? -1 : 1;
5363 else
5364 /* Before-strings sorted in order of increasing priority. */
5365 result = entry1->priority < entry2->priority ? -1 : 1;
5366 }
5367 else
5368 result = 0;
5369
5370 return result;
5371 }
5372
5373
5374 /* Load the vector IT->overlay_strings with overlay strings from IT's
5375 current buffer position, or from CHARPOS if that is > 0. Set
5376 IT->n_overlays to the total number of overlay strings found.
5377
5378 Overlay strings are processed OVERLAY_STRING_CHUNK_SIZE strings at
5379 a time. On entry into load_overlay_strings,
5380 IT->current.overlay_string_index gives the number of overlay
5381 strings that have already been loaded by previous calls to this
5382 function.
5383
5384 IT->add_overlay_start contains an additional overlay start
5385 position to consider for taking overlay strings from, if non-zero.
5386 This position comes into play when the overlay has an `invisible'
5387 property, and both before and after-strings. When we've skipped to
5388 the end of the overlay, because of its `invisible' property, we
5389 nevertheless want its before-string to appear.
5390 IT->add_overlay_start will contain the overlay start position
5391 in this case.
5392
5393 Overlay strings are sorted so that after-string strings come in
5394 front of before-string strings. Within before and after-strings,
5395 strings are sorted by overlay priority. See also function
5396 compare_overlay_entries. */
5397
5398 static void
5399 load_overlay_strings (struct it *it, ptrdiff_t charpos)
5400 {
5401 Lisp_Object overlay, window, str, invisible;
5402 struct Lisp_Overlay *ov;
5403 ptrdiff_t start, end;
5404 ptrdiff_t size = 20;
5405 ptrdiff_t n = 0, i, j;
5406 int invis_p;
5407 struct overlay_entry *entries
5408 = (struct overlay_entry *) alloca (size * sizeof *entries);
5409 USE_SAFE_ALLOCA;
5410
5411 if (charpos <= 0)
5412 charpos = IT_CHARPOS (*it);
5413
5414 /* Append the overlay string STRING of overlay OVERLAY to vector
5415 `entries' which has size `size' and currently contains `n'
5416 elements. AFTER_P non-zero means STRING is an after-string of
5417 OVERLAY. */
5418 #define RECORD_OVERLAY_STRING(OVERLAY, STRING, AFTER_P) \
5419 do \
5420 { \
5421 Lisp_Object priority; \
5422 \
5423 if (n == size) \
5424 { \
5425 struct overlay_entry *old = entries; \
5426 SAFE_NALLOCA (entries, 2, size); \
5427 memcpy (entries, old, size * sizeof *entries); \
5428 size *= 2; \
5429 } \
5430 \
5431 entries[n].string = (STRING); \
5432 entries[n].overlay = (OVERLAY); \
5433 priority = Foverlay_get ((OVERLAY), Qpriority); \
5434 entries[n].priority = INTEGERP (priority) ? XINT (priority) : 0; \
5435 entries[n].after_string_p = (AFTER_P); \
5436 ++n; \
5437 } \
5438 while (0)
5439
5440 /* Process overlay before the overlay center. */
5441 for (ov = current_buffer->overlays_before; ov; ov = ov->next)
5442 {
5443 XSETMISC (overlay, ov);
5444 xassert (OVERLAYP (overlay));
5445 start = OVERLAY_POSITION (OVERLAY_START (overlay));
5446 end = OVERLAY_POSITION (OVERLAY_END (overlay));
5447
5448 if (end < charpos)
5449 break;
5450
5451 /* Skip this overlay if it doesn't start or end at IT's current
5452 position. */
5453 if (end != charpos && start != charpos)
5454 continue;
5455
5456 /* Skip this overlay if it doesn't apply to IT->w. */
5457 window = Foverlay_get (overlay, Qwindow);
5458 if (WINDOWP (window) && XWINDOW (window) != it->w)
5459 continue;
5460
5461 /* If the text ``under'' the overlay is invisible, both before-
5462 and after-strings from this overlay are visible; start and
5463 end position are indistinguishable. */
5464 invisible = Foverlay_get (overlay, Qinvisible);
5465 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
5466
5467 /* If overlay has a non-empty before-string, record it. */
5468 if ((start == charpos || (end == charpos && invis_p))
5469 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
5470 && SCHARS (str))
5471 RECORD_OVERLAY_STRING (overlay, str, 0);
5472
5473 /* If overlay has a non-empty after-string, record it. */
5474 if ((end == charpos || (start == charpos && invis_p))
5475 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
5476 && SCHARS (str))
5477 RECORD_OVERLAY_STRING (overlay, str, 1);
5478 }
5479
5480 /* Process overlays after the overlay center. */
5481 for (ov = current_buffer->overlays_after; ov; ov = ov->next)
5482 {
5483 XSETMISC (overlay, ov);
5484 xassert (OVERLAYP (overlay));
5485 start = OVERLAY_POSITION (OVERLAY_START (overlay));
5486 end = OVERLAY_POSITION (OVERLAY_END (overlay));
5487
5488 if (start > charpos)
5489 break;
5490
5491 /* Skip this overlay if it doesn't start or end at IT's current
5492 position. */
5493 if (end != charpos && start != charpos)
5494 continue;
5495
5496 /* Skip this overlay if it doesn't apply to IT->w. */
5497 window = Foverlay_get (overlay, Qwindow);
5498 if (WINDOWP (window) && XWINDOW (window) != it->w)
5499 continue;
5500
5501 /* If the text ``under'' the overlay is invisible, it has a zero
5502 dimension, and both before- and after-strings apply. */
5503 invisible = Foverlay_get (overlay, Qinvisible);
5504 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
5505
5506 /* If overlay has a non-empty before-string, record it. */
5507 if ((start == charpos || (end == charpos && invis_p))
5508 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
5509 && SCHARS (str))
5510 RECORD_OVERLAY_STRING (overlay, str, 0);
5511
5512 /* If overlay has a non-empty after-string, record it. */
5513 if ((end == charpos || (start == charpos && invis_p))
5514 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
5515 && SCHARS (str))
5516 RECORD_OVERLAY_STRING (overlay, str, 1);
5517 }
5518
5519 #undef RECORD_OVERLAY_STRING
5520
5521 /* Sort entries. */
5522 if (n > 1)
5523 qsort (entries, n, sizeof *entries, compare_overlay_entries);
5524
5525 /* Record number of overlay strings, and where we computed it. */
5526 it->n_overlay_strings = n;
5527 it->overlay_strings_charpos = charpos;
5528
5529 /* IT->current.overlay_string_index is the number of overlay strings
5530 that have already been consumed by IT. Copy some of the
5531 remaining overlay strings to IT->overlay_strings. */
5532 i = 0;
5533 j = it->current.overlay_string_index;
5534 while (i < OVERLAY_STRING_CHUNK_SIZE && j < n)
5535 {
5536 it->overlay_strings[i] = entries[j].string;
5537 it->string_overlays[i++] = entries[j++].overlay;
5538 }
5539
5540 CHECK_IT (it);
5541 SAFE_FREE ();
5542 }
5543
5544
5545 /* Get the first chunk of overlay strings at IT's current buffer
5546 position, or at CHARPOS if that is > 0. Value is non-zero if at
5547 least one overlay string was found. */
5548
5549 static int
5550 get_overlay_strings_1 (struct it *it, ptrdiff_t charpos, int compute_stop_p)
5551 {
5552 /* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to
5553 process. This fills IT->overlay_strings with strings, and sets
5554 IT->n_overlay_strings to the total number of strings to process.
5555 IT->pos.overlay_string_index has to be set temporarily to zero
5556 because load_overlay_strings needs this; it must be set to -1
5557 when no overlay strings are found because a zero value would
5558 indicate a position in the first overlay string. */
5559 it->current.overlay_string_index = 0;
5560 load_overlay_strings (it, charpos);
5561
5562 /* If we found overlay strings, set up IT to deliver display
5563 elements from the first one. Otherwise set up IT to deliver
5564 from current_buffer. */
5565 if (it->n_overlay_strings)
5566 {
5567 /* Make sure we know settings in current_buffer, so that we can
5568 restore meaningful values when we're done with the overlay
5569 strings. */
5570 if (compute_stop_p)
5571 compute_stop_pos (it);
5572 xassert (it->face_id >= 0);
5573
5574 /* Save IT's settings. They are restored after all overlay
5575 strings have been processed. */
5576 xassert (!compute_stop_p || it->sp == 0);
5577
5578 /* When called from handle_stop, there might be an empty display
5579 string loaded. In that case, don't bother saving it. But
5580 don't use this optimization with the bidi iterator, since we
5581 need the corresponding pop_it call to resync the bidi
5582 iterator's position with IT's position, after we are done
5583 with the overlay strings. (The corresponding call to pop_it
5584 in case of an empty display string is in
5585 next_overlay_string.) */
5586 if (!(!it->bidi_p
5587 && STRINGP (it->string) && !SCHARS (it->string)))
5588 push_it (it, NULL);
5589
5590 /* Set up IT to deliver display elements from the first overlay
5591 string. */
5592 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
5593 it->string = it->overlay_strings[0];
5594 it->from_overlay = Qnil;
5595 it->stop_charpos = 0;
5596 xassert (STRINGP (it->string));
5597 it->end_charpos = SCHARS (it->string);
5598 it->prev_stop = 0;
5599 it->base_level_stop = 0;
5600 it->multibyte_p = STRING_MULTIBYTE (it->string);
5601 it->method = GET_FROM_STRING;
5602 it->from_disp_prop_p = 0;
5603
5604 /* Force paragraph direction to be that of the parent
5605 buffer. */
5606 if (it->bidi_p && it->bidi_it.paragraph_dir == R2L)
5607 it->paragraph_embedding = it->bidi_it.paragraph_dir;
5608 else
5609 it->paragraph_embedding = L2R;
5610
5611 /* Set up the bidi iterator for this overlay string. */
5612 if (it->bidi_p)
5613 {
5614 ptrdiff_t pos = (charpos > 0 ? charpos : IT_CHARPOS (*it));
5615
5616 it->bidi_it.string.lstring = it->string;
5617 it->bidi_it.string.s = NULL;
5618 it->bidi_it.string.schars = SCHARS (it->string);
5619 it->bidi_it.string.bufpos = pos;
5620 it->bidi_it.string.from_disp_str = it->string_from_display_prop_p;
5621 it->bidi_it.string.unibyte = !it->multibyte_p;
5622 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
5623 }
5624 return 1;
5625 }
5626
5627 it->current.overlay_string_index = -1;
5628 return 0;
5629 }
5630
5631 static int
5632 get_overlay_strings (struct it *it, ptrdiff_t charpos)
5633 {
5634 it->string = Qnil;
5635 it->method = GET_FROM_BUFFER;
5636
5637 (void) get_overlay_strings_1 (it, charpos, 1);
5638
5639 CHECK_IT (it);
5640
5641 /* Value is non-zero if we found at least one overlay string. */
5642 return STRINGP (it->string);
5643 }
5644
5645
5646 \f
5647 /***********************************************************************
5648 Saving and restoring state
5649 ***********************************************************************/
5650
5651 /* Save current settings of IT on IT->stack. Called, for example,
5652 before setting up IT for an overlay string, to be able to restore
5653 IT's settings to what they were after the overlay string has been
5654 processed. If POSITION is non-NULL, it is the position to save on
5655 the stack instead of IT->position. */
5656
5657 static void
5658 push_it (struct it *it, struct text_pos *position)
5659 {
5660 struct iterator_stack_entry *p;
5661
5662 xassert (it->sp < IT_STACK_SIZE);
5663 p = it->stack + it->sp;
5664
5665 p->stop_charpos = it->stop_charpos;
5666 p->prev_stop = it->prev_stop;
5667 p->base_level_stop = it->base_level_stop;
5668 p->cmp_it = it->cmp_it;
5669 xassert (it->face_id >= 0);
5670 p->face_id = it->face_id;
5671 p->string = it->string;
5672 p->method = it->method;
5673 p->from_overlay = it->from_overlay;
5674 switch (p->method)
5675 {
5676 case GET_FROM_IMAGE:
5677 p->u.image.object = it->object;
5678 p->u.image.image_id = it->image_id;
5679 p->u.image.slice = it->slice;
5680 break;
5681 case GET_FROM_STRETCH:
5682 p->u.stretch.object = it->object;
5683 break;
5684 #ifdef HAVE_XWIDGETS
5685 case GET_FROM_XWIDGET:
5686 p->u.xwidget.object = it->object;
5687 break;
5688 #endif
5689 }
5690 p->position = position ? *position : it->position;
5691 p->current = it->current;
5692 p->end_charpos = it->end_charpos;
5693 p->string_nchars = it->string_nchars;
5694 p->area = it->area;
5695 p->multibyte_p = it->multibyte_p;
5696 p->avoid_cursor_p = it->avoid_cursor_p;
5697 p->space_width = it->space_width;
5698 p->font_height = it->font_height;
5699 p->voffset = it->voffset;
5700 p->string_from_display_prop_p = it->string_from_display_prop_p;
5701 p->string_from_prefix_prop_p = it->string_from_prefix_prop_p;
5702 p->display_ellipsis_p = 0;
5703 p->line_wrap = it->line_wrap;
5704 p->bidi_p = it->bidi_p;
5705 p->paragraph_embedding = it->paragraph_embedding;
5706 p->from_disp_prop_p = it->from_disp_prop_p;
5707 ++it->sp;
5708
5709 /* Save the state of the bidi iterator as well. */
5710 if (it->bidi_p)
5711 bidi_push_it (&it->bidi_it);
5712 }
5713
5714 static void
5715 iterate_out_of_display_property (struct it *it)
5716 {
5717 int buffer_p = !STRINGP (it->string);
5718 ptrdiff_t eob = (buffer_p ? ZV : it->end_charpos);
5719 ptrdiff_t bob = (buffer_p ? BEGV : 0);
5720
5721 xassert (eob >= CHARPOS (it->position) && CHARPOS (it->position) >= bob);
5722
5723 /* Maybe initialize paragraph direction. If we are at the beginning
5724 of a new paragraph, next_element_from_buffer may not have a
5725 chance to do that. */
5726 if (it->bidi_it.first_elt && it->bidi_it.charpos < eob)
5727 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1);
5728 /* prev_stop can be zero, so check against BEGV as well. */
5729 while (it->bidi_it.charpos >= bob
5730 && it->prev_stop <= it->bidi_it.charpos
5731 && it->bidi_it.charpos < CHARPOS (it->position)
5732 && it->bidi_it.charpos < eob)
5733 bidi_move_to_visually_next (&it->bidi_it);
5734 /* Record the stop_pos we just crossed, for when we cross it
5735 back, maybe. */
5736 if (it->bidi_it.charpos > CHARPOS (it->position))
5737 it->prev_stop = CHARPOS (it->position);
5738 /* If we ended up not where pop_it put us, resync IT's
5739 positional members with the bidi iterator. */
5740 if (it->bidi_it.charpos != CHARPOS (it->position))
5741 SET_TEXT_POS (it->position, it->bidi_it.charpos, it->bidi_it.bytepos);
5742 if (buffer_p)
5743 it->current.pos = it->position;
5744 else
5745 it->current.string_pos = it->position;
5746 }
5747
5748 /* Restore IT's settings from IT->stack. Called, for example, when no
5749 more overlay strings must be processed, and we return to delivering
5750 display elements from a buffer, or when the end of a string from a
5751 `display' property is reached and we return to delivering display
5752 elements from an overlay string, or from a buffer. */
5753
5754 static void
5755 pop_it (struct it *it)
5756 {
5757 struct iterator_stack_entry *p;
5758 int from_display_prop = it->from_disp_prop_p;
5759
5760 xassert (it->sp > 0);
5761 --it->sp;
5762 p = it->stack + it->sp;
5763 it->stop_charpos = p->stop_charpos;
5764 it->prev_stop = p->prev_stop;
5765 it->base_level_stop = p->base_level_stop;
5766 it->cmp_it = p->cmp_it;
5767 it->face_id = p->face_id;
5768 it->current = p->current;
5769 it->position = p->position;
5770 it->string = p->string;
5771 it->from_overlay = p->from_overlay;
5772 if (NILP (it->string))
5773 SET_TEXT_POS (it->current.string_pos, -1, -1);
5774 it->method = p->method;
5775 switch (it->method)
5776 {
5777 case GET_FROM_IMAGE:
5778 it->image_id = p->u.image.image_id;
5779 it->object = p->u.image.object;
5780 it->slice = p->u.image.slice;
5781 break;
5782 #ifdef HAVE_XWIDGETS
5783 case GET_FROM_XWIDGET:
5784 it->object = p->u.xwidget.object;
5785 break;
5786 #endif
5787 case GET_FROM_STRETCH:
5788 it->object = p->u.stretch.object;
5789 break;
5790 case GET_FROM_BUFFER:
5791 it->object = it->w->buffer;
5792 break;
5793 case GET_FROM_STRING:
5794 it->object = it->string;
5795 break;
5796 case GET_FROM_DISPLAY_VECTOR:
5797 if (it->s)
5798 it->method = GET_FROM_C_STRING;
5799 else if (STRINGP (it->string))
5800 it->method = GET_FROM_STRING;
5801 else
5802 {
5803 it->method = GET_FROM_BUFFER;
5804 it->object = it->w->buffer;
5805 }
5806 }
5807 it->end_charpos = p->end_charpos;
5808 it->string_nchars = p->string_nchars;
5809 it->area = p->area;
5810 it->multibyte_p = p->multibyte_p;
5811 it->avoid_cursor_p = p->avoid_cursor_p;
5812 it->space_width = p->space_width;
5813 it->font_height = p->font_height;
5814 it->voffset = p->voffset;
5815 it->string_from_display_prop_p = p->string_from_display_prop_p;
5816 it->string_from_prefix_prop_p = p->string_from_prefix_prop_p;
5817 it->line_wrap = p->line_wrap;
5818 it->bidi_p = p->bidi_p;
5819 it->paragraph_embedding = p->paragraph_embedding;
5820 it->from_disp_prop_p = p->from_disp_prop_p;
5821 if (it->bidi_p)
5822 {
5823 bidi_pop_it (&it->bidi_it);
5824 /* Bidi-iterate until we get out of the portion of text, if any,
5825 covered by a `display' text property or by an overlay with
5826 `display' property. (We cannot just jump there, because the
5827 internal coherency of the bidi iterator state can not be
5828 preserved across such jumps.) We also must determine the
5829 paragraph base direction if the overlay we just processed is
5830 at the beginning of a new paragraph. */
5831 if (from_display_prop
5832 && (it->method == GET_FROM_BUFFER || it->method == GET_FROM_STRING))
5833 iterate_out_of_display_property (it);
5834
5835 xassert ((BUFFERP (it->object)
5836 && IT_CHARPOS (*it) == it->bidi_it.charpos
5837 && IT_BYTEPOS (*it) == it->bidi_it.bytepos)
5838 || (STRINGP (it->object)
5839 && IT_STRING_CHARPOS (*it) == it->bidi_it.charpos
5840 && IT_STRING_BYTEPOS (*it) == it->bidi_it.bytepos)
5841 || (CONSP (it->object) && it->method == GET_FROM_STRETCH));
5842 }
5843 }
5844
5845
5846 \f
5847 /***********************************************************************
5848 Moving over lines
5849 ***********************************************************************/
5850
5851 /* Set IT's current position to the previous line start. */
5852
5853 static void
5854 back_to_previous_line_start (struct it *it)
5855 {
5856 IT_CHARPOS (*it) = find_next_newline_no_quit (IT_CHARPOS (*it) - 1, -1);
5857 IT_BYTEPOS (*it) = CHAR_TO_BYTE (IT_CHARPOS (*it));
5858 }
5859
5860
5861 /* Move IT to the next line start.
5862
5863 Value is non-zero if a newline was found. Set *SKIPPED_P to 1 if
5864 we skipped over part of the text (as opposed to moving the iterator
5865 continuously over the text). Otherwise, don't change the value
5866 of *SKIPPED_P.
5867
5868 If BIDI_IT_PREV is non-NULL, store into it the state of the bidi
5869 iterator on the newline, if it was found.
5870
5871 Newlines may come from buffer text, overlay strings, or strings
5872 displayed via the `display' property. That's the reason we can't
5873 simply use find_next_newline_no_quit.
5874
5875 Note that this function may not skip over invisible text that is so
5876 because of text properties and immediately follows a newline. If
5877 it would, function reseat_at_next_visible_line_start, when called
5878 from set_iterator_to_next, would effectively make invisible
5879 characters following a newline part of the wrong glyph row, which
5880 leads to wrong cursor motion. */
5881
5882 static int
5883 forward_to_next_line_start (struct it *it, int *skipped_p,
5884 struct bidi_it *bidi_it_prev)
5885 {
5886 ptrdiff_t old_selective;
5887 int newline_found_p, n;
5888 const int MAX_NEWLINE_DISTANCE = 500;
5889
5890 /* If already on a newline, just consume it to avoid unintended
5891 skipping over invisible text below. */
5892 if (it->what == IT_CHARACTER
5893 && it->c == '\n'
5894 && CHARPOS (it->position) == IT_CHARPOS (*it))
5895 {
5896 if (it->bidi_p && bidi_it_prev)
5897 *bidi_it_prev = it->bidi_it;
5898 set_iterator_to_next (it, 0);
5899 it->c = 0;
5900 return 1;
5901 }
5902
5903 /* Don't handle selective display in the following. It's (a)
5904 unnecessary because it's done by the caller, and (b) leads to an
5905 infinite recursion because next_element_from_ellipsis indirectly
5906 calls this function. */
5907 old_selective = it->selective;
5908 it->selective = 0;
5909
5910 /* Scan for a newline within MAX_NEWLINE_DISTANCE display elements
5911 from buffer text. */
5912 for (n = newline_found_p = 0;
5913 !newline_found_p && n < MAX_NEWLINE_DISTANCE;
5914 n += STRINGP (it->string) ? 0 : 1)
5915 {
5916 if (!get_next_display_element (it))
5917 return 0;
5918 newline_found_p = it->what == IT_CHARACTER && it->c == '\n';
5919 if (newline_found_p && it->bidi_p && bidi_it_prev)
5920 *bidi_it_prev = it->bidi_it;
5921 set_iterator_to_next (it, 0);
5922 }
5923
5924 /* If we didn't find a newline near enough, see if we can use a
5925 short-cut. */
5926 if (!newline_found_p)
5927 {
5928 ptrdiff_t start = IT_CHARPOS (*it);
5929 ptrdiff_t limit = find_next_newline_no_quit (start, 1);
5930 Lisp_Object pos;
5931
5932 xassert (!STRINGP (it->string));
5933
5934 /* If there isn't any `display' property in sight, and no
5935 overlays, we can just use the position of the newline in
5936 buffer text. */
5937 if (it->stop_charpos >= limit
5938 || ((pos = Fnext_single_property_change (make_number (start),
5939 Qdisplay, Qnil,
5940 make_number (limit)),
5941 NILP (pos))
5942 && next_overlay_change (start) == ZV))
5943 {
5944 if (!it->bidi_p)
5945 {
5946 IT_CHARPOS (*it) = limit;
5947 IT_BYTEPOS (*it) = CHAR_TO_BYTE (limit);
5948 }
5949 else
5950 {
5951 struct bidi_it bprev;
5952
5953 /* Help bidi.c avoid expensive searches for display
5954 properties and overlays, by telling it that there are
5955 none up to `limit'. */
5956 if (it->bidi_it.disp_pos < limit)
5957 {
5958 it->bidi_it.disp_pos = limit;
5959 it->bidi_it.disp_prop = 0;
5960 }
5961 do {
5962 bprev = it->bidi_it;
5963 bidi_move_to_visually_next (&it->bidi_it);
5964 } while (it->bidi_it.charpos != limit);
5965 IT_CHARPOS (*it) = limit;
5966 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
5967 if (bidi_it_prev)
5968 *bidi_it_prev = bprev;
5969 }
5970 *skipped_p = newline_found_p = 1;
5971 }
5972 else
5973 {
5974 while (get_next_display_element (it)
5975 && !newline_found_p)
5976 {
5977 newline_found_p = ITERATOR_AT_END_OF_LINE_P (it);
5978 if (newline_found_p && it->bidi_p && bidi_it_prev)
5979 *bidi_it_prev = it->bidi_it;
5980 set_iterator_to_next (it, 0);
5981 }
5982 }
5983 }
5984
5985 it->selective = old_selective;
5986 return newline_found_p;
5987 }
5988
5989
5990 /* Set IT's current position to the previous visible line start. Skip
5991 invisible text that is so either due to text properties or due to
5992 selective display. Caution: this does not change IT->current_x and
5993 IT->hpos. */
5994
5995 static void
5996 back_to_previous_visible_line_start (struct it *it)
5997 {
5998 while (IT_CHARPOS (*it) > BEGV)
5999 {
6000 back_to_previous_line_start (it);
6001
6002 if (IT_CHARPOS (*it) <= BEGV)
6003 break;
6004
6005 /* If selective > 0, then lines indented more than its value are
6006 invisible. */
6007 if (it->selective > 0
6008 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
6009 it->selective))
6010 continue;
6011
6012 /* Check the newline before point for invisibility. */
6013 {
6014 Lisp_Object prop;
6015 prop = Fget_char_property (make_number (IT_CHARPOS (*it) - 1),
6016 Qinvisible, it->window);
6017 if (TEXT_PROP_MEANS_INVISIBLE (prop))
6018 continue;
6019 }
6020
6021 if (IT_CHARPOS (*it) <= BEGV)
6022 break;
6023
6024 {
6025 struct it it2;
6026 void *it2data = NULL;
6027 ptrdiff_t pos;
6028 ptrdiff_t beg, end;
6029 Lisp_Object val, overlay;
6030
6031 SAVE_IT (it2, *it, it2data);
6032
6033 /* If newline is part of a composition, continue from start of composition */
6034 if (find_composition (IT_CHARPOS (*it), -1, &beg, &end, &val, Qnil)
6035 && beg < IT_CHARPOS (*it))
6036 goto replaced;
6037
6038 /* If newline is replaced by a display property, find start of overlay
6039 or interval and continue search from that point. */
6040 pos = --IT_CHARPOS (it2);
6041 --IT_BYTEPOS (it2);
6042 it2.sp = 0;
6043 bidi_unshelve_cache (NULL, 0);
6044 it2.string_from_display_prop_p = 0;
6045 it2.from_disp_prop_p = 0;
6046 if (handle_display_prop (&it2) == HANDLED_RETURN
6047 && !NILP (val = get_char_property_and_overlay
6048 (make_number (pos), Qdisplay, Qnil, &overlay))
6049 && (OVERLAYP (overlay)
6050 ? (beg = OVERLAY_POSITION (OVERLAY_START (overlay)))
6051 : get_property_and_range (pos, Qdisplay, &val, &beg, &end, Qnil)))
6052 {
6053 RESTORE_IT (it, it, it2data);
6054 goto replaced;
6055 }
6056
6057 /* Newline is not replaced by anything -- so we are done. */
6058 RESTORE_IT (it, it, it2data);
6059 break;
6060
6061 replaced:
6062 if (beg < BEGV)
6063 beg = BEGV;
6064 IT_CHARPOS (*it) = beg;
6065 IT_BYTEPOS (*it) = buf_charpos_to_bytepos (current_buffer, beg);
6066 }
6067 }
6068
6069 it->continuation_lines_width = 0;
6070
6071 xassert (IT_CHARPOS (*it) >= BEGV);
6072 xassert (IT_CHARPOS (*it) == BEGV
6073 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
6074 CHECK_IT (it);
6075 }
6076
6077
6078 /* Reseat iterator IT at the previous visible line start. Skip
6079 invisible text that is so either due to text properties or due to
6080 selective display. At the end, update IT's overlay information,
6081 face information etc. */
6082
6083 void
6084 reseat_at_previous_visible_line_start (struct it *it)
6085 {
6086 back_to_previous_visible_line_start (it);
6087 reseat (it, it->current.pos, 1);
6088 CHECK_IT (it);
6089 }
6090
6091
6092 /* Reseat iterator IT on the next visible line start in the current
6093 buffer. ON_NEWLINE_P non-zero means position IT on the newline
6094 preceding the line start. Skip over invisible text that is so
6095 because of selective display. Compute faces, overlays etc at the
6096 new position. Note that this function does not skip over text that
6097 is invisible because of text properties. */
6098
6099 static void
6100 reseat_at_next_visible_line_start (struct it *it, int on_newline_p)
6101 {
6102 int newline_found_p, skipped_p = 0;
6103 struct bidi_it bidi_it_prev;
6104
6105 newline_found_p = forward_to_next_line_start (it, &skipped_p, &bidi_it_prev);
6106
6107 /* Skip over lines that are invisible because they are indented
6108 more than the value of IT->selective. */
6109 if (it->selective > 0)
6110 while (IT_CHARPOS (*it) < ZV
6111 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
6112 it->selective))
6113 {
6114 xassert (IT_BYTEPOS (*it) == BEGV
6115 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
6116 newline_found_p =
6117 forward_to_next_line_start (it, &skipped_p, &bidi_it_prev);
6118 }
6119
6120 /* Position on the newline if that's what's requested. */
6121 if (on_newline_p && newline_found_p)
6122 {
6123 if (STRINGP (it->string))
6124 {
6125 if (IT_STRING_CHARPOS (*it) > 0)
6126 {
6127 if (!it->bidi_p)
6128 {
6129 --IT_STRING_CHARPOS (*it);
6130 --IT_STRING_BYTEPOS (*it);
6131 }
6132 else
6133 {
6134 /* We need to restore the bidi iterator to the state
6135 it had on the newline, and resync the IT's
6136 position with that. */
6137 it->bidi_it = bidi_it_prev;
6138 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
6139 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
6140 }
6141 }
6142 }
6143 else if (IT_CHARPOS (*it) > BEGV)
6144 {
6145 if (!it->bidi_p)
6146 {
6147 --IT_CHARPOS (*it);
6148 --IT_BYTEPOS (*it);
6149 }
6150 else
6151 {
6152 /* We need to restore the bidi iterator to the state it
6153 had on the newline and resync IT with that. */
6154 it->bidi_it = bidi_it_prev;
6155 IT_CHARPOS (*it) = it->bidi_it.charpos;
6156 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
6157 }
6158 reseat (it, it->current.pos, 0);
6159 }
6160 }
6161 else if (skipped_p)
6162 reseat (it, it->current.pos, 0);
6163
6164 CHECK_IT (it);
6165 }
6166
6167
6168 \f
6169 /***********************************************************************
6170 Changing an iterator's position
6171 ***********************************************************************/
6172
6173 /* Change IT's current position to POS in current_buffer. If FORCE_P
6174 is non-zero, always check for text properties at the new position.
6175 Otherwise, text properties are only looked up if POS >=
6176 IT->check_charpos of a property. */
6177
6178 static void
6179 reseat (struct it *it, struct text_pos pos, int force_p)
6180 {
6181 ptrdiff_t original_pos = IT_CHARPOS (*it);
6182
6183 reseat_1 (it, pos, 0);
6184
6185 /* Determine where to check text properties. Avoid doing it
6186 where possible because text property lookup is very expensive. */
6187 if (force_p
6188 || CHARPOS (pos) > it->stop_charpos
6189 || CHARPOS (pos) < original_pos)
6190 {
6191 if (it->bidi_p)
6192 {
6193 /* For bidi iteration, we need to prime prev_stop and
6194 base_level_stop with our best estimations. */
6195 /* Implementation note: Of course, POS is not necessarily a
6196 stop position, so assigning prev_pos to it is a lie; we
6197 should have called compute_stop_backwards. However, if
6198 the current buffer does not include any R2L characters,
6199 that call would be a waste of cycles, because the
6200 iterator will never move back, and thus never cross this
6201 "fake" stop position. So we delay that backward search
6202 until the time we really need it, in next_element_from_buffer. */
6203 if (CHARPOS (pos) != it->prev_stop)
6204 it->prev_stop = CHARPOS (pos);
6205 if (CHARPOS (pos) < it->base_level_stop)
6206 it->base_level_stop = 0; /* meaning it's unknown */
6207 handle_stop (it);
6208 }
6209 else
6210 {
6211 handle_stop (it);
6212 it->prev_stop = it->base_level_stop = 0;
6213 }
6214
6215 }
6216
6217 CHECK_IT (it);
6218 }
6219
6220
6221 /* Change IT's buffer position to POS. SET_STOP_P non-zero means set
6222 IT->stop_pos to POS, also. */
6223
6224 static void
6225 reseat_1 (struct it *it, struct text_pos pos, int set_stop_p)
6226 {
6227 /* Don't call this function when scanning a C string. */
6228 xassert (it->s == NULL);
6229
6230 /* POS must be a reasonable value. */
6231 xassert (CHARPOS (pos) >= BEGV && CHARPOS (pos) <= ZV);
6232
6233 it->current.pos = it->position = pos;
6234 it->end_charpos = ZV;
6235 it->dpvec = NULL;
6236 it->current.dpvec_index = -1;
6237 it->current.overlay_string_index = -1;
6238 IT_STRING_CHARPOS (*it) = -1;
6239 IT_STRING_BYTEPOS (*it) = -1;
6240 it->string = Qnil;
6241 it->method = GET_FROM_BUFFER;
6242 it->object = it->w->buffer;
6243 it->area = TEXT_AREA;
6244 it->multibyte_p = !NILP (BVAR (current_buffer, enable_multibyte_characters));
6245 it->sp = 0;
6246 it->string_from_display_prop_p = 0;
6247 it->string_from_prefix_prop_p = 0;
6248
6249 it->from_disp_prop_p = 0;
6250 it->face_before_selective_p = 0;
6251 if (it->bidi_p)
6252 {
6253 bidi_init_it (IT_CHARPOS (*it), IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f),
6254 &it->bidi_it);
6255 bidi_unshelve_cache (NULL, 0);
6256 it->bidi_it.paragraph_dir = NEUTRAL_DIR;
6257 it->bidi_it.string.s = NULL;
6258 it->bidi_it.string.lstring = Qnil;
6259 it->bidi_it.string.bufpos = 0;
6260 it->bidi_it.string.unibyte = 0;
6261 }
6262
6263 if (set_stop_p)
6264 {
6265 it->stop_charpos = CHARPOS (pos);
6266 it->base_level_stop = CHARPOS (pos);
6267 }
6268 }
6269
6270
6271 /* Set up IT for displaying a string, starting at CHARPOS in window W.
6272 If S is non-null, it is a C string to iterate over. Otherwise,
6273 STRING gives a Lisp string to iterate over.
6274
6275 If PRECISION > 0, don't return more then PRECISION number of
6276 characters from the string.
6277
6278 If FIELD_WIDTH > 0, return padding spaces until FIELD_WIDTH
6279 characters have been returned. FIELD_WIDTH < 0 means an infinite
6280 field width.
6281
6282 MULTIBYTE = 0 means disable processing of multibyte characters,
6283 MULTIBYTE > 0 means enable it,
6284 MULTIBYTE < 0 means use IT->multibyte_p.
6285
6286 IT must be initialized via a prior call to init_iterator before
6287 calling this function. */
6288
6289 static void
6290 reseat_to_string (struct it *it, const char *s, Lisp_Object string,
6291 ptrdiff_t charpos, ptrdiff_t precision, int field_width,
6292 int multibyte)
6293 {
6294 /* No region in strings. */
6295 it->region_beg_charpos = it->region_end_charpos = -1;
6296
6297 /* No text property checks performed by default, but see below. */
6298 it->stop_charpos = -1;
6299
6300 /* Set iterator position and end position. */
6301 memset (&it->current, 0, sizeof it->current);
6302 it->current.overlay_string_index = -1;
6303 it->current.dpvec_index = -1;
6304 xassert (charpos >= 0);
6305
6306 /* If STRING is specified, use its multibyteness, otherwise use the
6307 setting of MULTIBYTE, if specified. */
6308 if (multibyte >= 0)
6309 it->multibyte_p = multibyte > 0;
6310
6311 /* Bidirectional reordering of strings is controlled by the default
6312 value of bidi-display-reordering. Don't try to reorder while
6313 loading loadup.el, as the necessary character property tables are
6314 not yet available. */
6315 it->bidi_p =
6316 NILP (Vpurify_flag)
6317 && !NILP (BVAR (&buffer_defaults, bidi_display_reordering));
6318
6319 if (s == NULL)
6320 {
6321 xassert (STRINGP (string));
6322 it->string = string;
6323 it->s = NULL;
6324 it->end_charpos = it->string_nchars = SCHARS (string);
6325 it->method = GET_FROM_STRING;
6326 it->current.string_pos = string_pos (charpos, string);
6327
6328 if (it->bidi_p)
6329 {
6330 it->bidi_it.string.lstring = string;
6331 it->bidi_it.string.s = NULL;
6332 it->bidi_it.string.schars = it->end_charpos;
6333 it->bidi_it.string.bufpos = 0;
6334 it->bidi_it.string.from_disp_str = 0;
6335 it->bidi_it.string.unibyte = !it->multibyte_p;
6336 bidi_init_it (charpos, IT_STRING_BYTEPOS (*it),
6337 FRAME_WINDOW_P (it->f), &it->bidi_it);
6338 }
6339 }
6340 else
6341 {
6342 it->s = (const unsigned char *) s;
6343 it->string = Qnil;
6344
6345 /* Note that we use IT->current.pos, not it->current.string_pos,
6346 for displaying C strings. */
6347 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
6348 if (it->multibyte_p)
6349 {
6350 it->current.pos = c_string_pos (charpos, s, 1);
6351 it->end_charpos = it->string_nchars = number_of_chars (s, 1);
6352 }
6353 else
6354 {
6355 IT_CHARPOS (*it) = IT_BYTEPOS (*it) = charpos;
6356 it->end_charpos = it->string_nchars = strlen (s);
6357 }
6358
6359 if (it->bidi_p)
6360 {
6361 it->bidi_it.string.lstring = Qnil;
6362 it->bidi_it.string.s = (const unsigned char *) s;
6363 it->bidi_it.string.schars = it->end_charpos;
6364 it->bidi_it.string.bufpos = 0;
6365 it->bidi_it.string.from_disp_str = 0;
6366 it->bidi_it.string.unibyte = !it->multibyte_p;
6367 bidi_init_it (charpos, IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f),
6368 &it->bidi_it);
6369 }
6370 it->method = GET_FROM_C_STRING;
6371 }
6372
6373 /* PRECISION > 0 means don't return more than PRECISION characters
6374 from the string. */
6375 if (precision > 0 && it->end_charpos - charpos > precision)
6376 {
6377 it->end_charpos = it->string_nchars = charpos + precision;
6378 if (it->bidi_p)
6379 it->bidi_it.string.schars = it->end_charpos;
6380 }
6381
6382 /* FIELD_WIDTH > 0 means pad with spaces until FIELD_WIDTH
6383 characters have been returned. FIELD_WIDTH == 0 means don't pad,
6384 FIELD_WIDTH < 0 means infinite field width. This is useful for
6385 padding with `-' at the end of a mode line. */
6386 if (field_width < 0)
6387 field_width = INFINITY;
6388 /* Implementation note: We deliberately don't enlarge
6389 it->bidi_it.string.schars here to fit it->end_charpos, because
6390 the bidi iterator cannot produce characters out of thin air. */
6391 if (field_width > it->end_charpos - charpos)
6392 it->end_charpos = charpos + field_width;
6393
6394 /* Use the standard display table for displaying strings. */
6395 if (DISP_TABLE_P (Vstandard_display_table))
6396 it->dp = XCHAR_TABLE (Vstandard_display_table);
6397
6398 it->stop_charpos = charpos;
6399 it->prev_stop = charpos;
6400 it->base_level_stop = 0;
6401 if (it->bidi_p)
6402 {
6403 it->bidi_it.first_elt = 1;
6404 it->bidi_it.paragraph_dir = NEUTRAL_DIR;
6405 it->bidi_it.disp_pos = -1;
6406 }
6407 if (s == NULL && it->multibyte_p)
6408 {
6409 ptrdiff_t endpos = SCHARS (it->string);
6410 if (endpos > it->end_charpos)
6411 endpos = it->end_charpos;
6412 composition_compute_stop_pos (&it->cmp_it, charpos, -1, endpos,
6413 it->string);
6414 }
6415 CHECK_IT (it);
6416 }
6417
6418
6419 \f
6420 /***********************************************************************
6421 Iteration
6422 ***********************************************************************/
6423
6424 /* Map enum it_method value to corresponding next_element_from_* function. */
6425
6426 static int (* get_next_element[NUM_IT_METHODS]) (struct it *it) =
6427 {
6428 next_element_from_buffer,
6429 next_element_from_display_vector,
6430 next_element_from_string,
6431 next_element_from_c_string,
6432 next_element_from_image,
6433 next_element_from_stretch
6434 #ifdef HAVE_XWIDGETS
6435 ,next_element_from_xwidget
6436 #endif
6437 };
6438
6439 #define GET_NEXT_DISPLAY_ELEMENT(it) (*get_next_element[(it)->method]) (it)
6440
6441
6442 /* Return 1 iff a character at CHARPOS (and BYTEPOS) is composed
6443 (possibly with the following characters). */
6444
6445 #define CHAR_COMPOSED_P(IT,CHARPOS,BYTEPOS,END_CHARPOS) \
6446 ((IT)->cmp_it.id >= 0 \
6447 || ((IT)->cmp_it.stop_pos == (CHARPOS) \
6448 && composition_reseat_it (&(IT)->cmp_it, CHARPOS, BYTEPOS, \
6449 END_CHARPOS, (IT)->w, \
6450 FACE_FROM_ID ((IT)->f, (IT)->face_id), \
6451 (IT)->string)))
6452
6453
6454 /* Lookup the char-table Vglyphless_char_display for character C (-1
6455 if we want information for no-font case), and return the display
6456 method symbol. By side-effect, update it->what and
6457 it->glyphless_method. This function is called from
6458 get_next_display_element for each character element, and from
6459 x_produce_glyphs when no suitable font was found. */
6460
6461 Lisp_Object
6462 lookup_glyphless_char_display (int c, struct it *it)
6463 {
6464 Lisp_Object glyphless_method = Qnil;
6465
6466 if (CHAR_TABLE_P (Vglyphless_char_display)
6467 && CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (Vglyphless_char_display)) >= 1)
6468 {
6469 if (c >= 0)
6470 {
6471 glyphless_method = CHAR_TABLE_REF (Vglyphless_char_display, c);
6472 if (CONSP (glyphless_method))
6473 glyphless_method = FRAME_WINDOW_P (it->f)
6474 ? XCAR (glyphless_method)
6475 : XCDR (glyphless_method);
6476 }
6477 else
6478 glyphless_method = XCHAR_TABLE (Vglyphless_char_display)->extras[0];
6479 }
6480
6481 retry:
6482 if (NILP (glyphless_method))
6483 {
6484 if (c >= 0)
6485 /* The default is to display the character by a proper font. */
6486 return Qnil;
6487 /* The default for the no-font case is to display an empty box. */
6488 glyphless_method = Qempty_box;
6489 }
6490 if (EQ (glyphless_method, Qzero_width))
6491 {
6492 if (c >= 0)
6493 return glyphless_method;
6494 /* This method can't be used for the no-font case. */
6495 glyphless_method = Qempty_box;
6496 }
6497 if (EQ (glyphless_method, Qthin_space))
6498 it->glyphless_method = GLYPHLESS_DISPLAY_THIN_SPACE;
6499 else if (EQ (glyphless_method, Qempty_box))
6500 it->glyphless_method = GLYPHLESS_DISPLAY_EMPTY_BOX;
6501 else if (EQ (glyphless_method, Qhex_code))
6502 it->glyphless_method = GLYPHLESS_DISPLAY_HEX_CODE;
6503 else if (STRINGP (glyphless_method))
6504 it->glyphless_method = GLYPHLESS_DISPLAY_ACRONYM;
6505 else
6506 {
6507 /* Invalid value. We use the default method. */
6508 glyphless_method = Qnil;
6509 goto retry;
6510 }
6511 it->what = IT_GLYPHLESS;
6512 return glyphless_method;
6513 }
6514
6515 /* Load IT's display element fields with information about the next
6516 display element from the current position of IT. Value is zero if
6517 end of buffer (or C string) is reached. */
6518
6519 static struct frame *last_escape_glyph_frame = NULL;
6520 static int last_escape_glyph_face_id = (1 << FACE_ID_BITS);
6521 static int last_escape_glyph_merged_face_id = 0;
6522
6523 struct frame *last_glyphless_glyph_frame = NULL;
6524 int last_glyphless_glyph_face_id = (1 << FACE_ID_BITS);
6525 int last_glyphless_glyph_merged_face_id = 0;
6526
6527 static int
6528 get_next_display_element (struct it *it)
6529 {
6530 /* Non-zero means that we found a display element. Zero means that
6531 we hit the end of what we iterate over. Performance note: the
6532 function pointer `method' used here turns out to be faster than
6533 using a sequence of if-statements. */
6534 int success_p;
6535
6536 get_next:
6537 success_p = GET_NEXT_DISPLAY_ELEMENT (it);
6538
6539 if (it->what == IT_CHARACTER)
6540 {
6541 /* UAX#9, L4: "A character is depicted by a mirrored glyph if
6542 and only if (a) the resolved directionality of that character
6543 is R..." */
6544 /* FIXME: Do we need an exception for characters from display
6545 tables? */
6546 if (it->bidi_p && it->bidi_it.type == STRONG_R)
6547 it->c = bidi_mirror_char (it->c);
6548 /* Map via display table or translate control characters.
6549 IT->c, IT->len etc. have been set to the next character by
6550 the function call above. If we have a display table, and it
6551 contains an entry for IT->c, translate it. Don't do this if
6552 IT->c itself comes from a display table, otherwise we could
6553 end up in an infinite recursion. (An alternative could be to
6554 count the recursion depth of this function and signal an
6555 error when a certain maximum depth is reached.) Is it worth
6556 it? */
6557 if (success_p && it->dpvec == NULL)
6558 {
6559 Lisp_Object dv;
6560 struct charset *unibyte = CHARSET_FROM_ID (charset_unibyte);
6561 int nonascii_space_p = 0;
6562 int nonascii_hyphen_p = 0;
6563 int c = it->c; /* This is the character to display. */
6564
6565 if (! it->multibyte_p && ! ASCII_CHAR_P (c))
6566 {
6567 xassert (SINGLE_BYTE_CHAR_P (c));
6568 if (unibyte_display_via_language_environment)
6569 {
6570 c = DECODE_CHAR (unibyte, c);
6571 if (c < 0)
6572 c = BYTE8_TO_CHAR (it->c);
6573 }
6574 else
6575 c = BYTE8_TO_CHAR (it->c);
6576 }
6577
6578 if (it->dp
6579 && (dv = DISP_CHAR_VECTOR (it->dp, c),
6580 VECTORP (dv)))
6581 {
6582 struct Lisp_Vector *v = XVECTOR (dv);
6583
6584 /* Return the first character from the display table
6585 entry, if not empty. If empty, don't display the
6586 current character. */
6587 if (v->header.size)
6588 {
6589 it->dpvec_char_len = it->len;
6590 it->dpvec = v->contents;
6591 it->dpend = v->contents + v->header.size;
6592 it->current.dpvec_index = 0;
6593 it->dpvec_face_id = -1;
6594 it->saved_face_id = it->face_id;
6595 it->method = GET_FROM_DISPLAY_VECTOR;
6596 it->ellipsis_p = 0;
6597 }
6598 else
6599 {
6600 set_iterator_to_next (it, 0);
6601 }
6602 goto get_next;
6603 }
6604
6605 if (! NILP (lookup_glyphless_char_display (c, it)))
6606 {
6607 if (it->what == IT_GLYPHLESS)
6608 goto done;
6609 /* Don't display this character. */
6610 set_iterator_to_next (it, 0);
6611 goto get_next;
6612 }
6613
6614 /* If `nobreak-char-display' is non-nil, we display
6615 non-ASCII spaces and hyphens specially. */
6616 if (! ASCII_CHAR_P (c) && ! NILP (Vnobreak_char_display))
6617 {
6618 if (c == 0xA0)
6619 nonascii_space_p = 1;
6620 else if (c == 0xAD || c == 0x2010 || c == 0x2011)
6621 nonascii_hyphen_p = 1;
6622 }
6623
6624 /* Translate control characters into `\003' or `^C' form.
6625 Control characters coming from a display table entry are
6626 currently not translated because we use IT->dpvec to hold
6627 the translation. This could easily be changed but I
6628 don't believe that it is worth doing.
6629
6630 The characters handled by `nobreak-char-display' must be
6631 translated too.
6632
6633 Non-printable characters and raw-byte characters are also
6634 translated to octal form. */
6635 if (((c < ' ' || c == 127) /* ASCII control chars */
6636 ? (it->area != TEXT_AREA
6637 /* In mode line, treat \n, \t like other crl chars. */
6638 || (c != '\t'
6639 && it->glyph_row
6640 && (it->glyph_row->mode_line_p || it->avoid_cursor_p))
6641 || (c != '\n' && c != '\t'))
6642 : (nonascii_space_p
6643 || nonascii_hyphen_p
6644 || CHAR_BYTE8_P (c)
6645 || ! CHAR_PRINTABLE_P (c))))
6646 {
6647 /* C is a control character, non-ASCII space/hyphen,
6648 raw-byte, or a non-printable character which must be
6649 displayed either as '\003' or as `^C' where the '\\'
6650 and '^' can be defined in the display table. Fill
6651 IT->ctl_chars with glyphs for what we have to
6652 display. Then, set IT->dpvec to these glyphs. */
6653 Lisp_Object gc;
6654 int ctl_len;
6655 int face_id;
6656 int lface_id = 0;
6657 int escape_glyph;
6658
6659 /* Handle control characters with ^. */
6660
6661 if (ASCII_CHAR_P (c) && it->ctl_arrow_p)
6662 {
6663 int g;
6664
6665 g = '^'; /* default glyph for Control */
6666 /* Set IT->ctl_chars[0] to the glyph for `^'. */
6667 if (it->dp
6668 && (gc = DISP_CTRL_GLYPH (it->dp), GLYPH_CODE_P (gc)))
6669 {
6670 g = GLYPH_CODE_CHAR (gc);
6671 lface_id = GLYPH_CODE_FACE (gc);
6672 }
6673 if (lface_id)
6674 {
6675 face_id = merge_faces (it->f, Qt, lface_id, it->face_id);
6676 }
6677 else if (it->f == last_escape_glyph_frame
6678 && it->face_id == last_escape_glyph_face_id)
6679 {
6680 face_id = last_escape_glyph_merged_face_id;
6681 }
6682 else
6683 {
6684 /* Merge the escape-glyph face into the current face. */
6685 face_id = merge_faces (it->f, Qescape_glyph, 0,
6686 it->face_id);
6687 last_escape_glyph_frame = it->f;
6688 last_escape_glyph_face_id = it->face_id;
6689 last_escape_glyph_merged_face_id = face_id;
6690 }
6691
6692 XSETINT (it->ctl_chars[0], g);
6693 XSETINT (it->ctl_chars[1], c ^ 0100);
6694 ctl_len = 2;
6695 goto display_control;
6696 }
6697
6698 /* Handle non-ascii space in the mode where it only gets
6699 highlighting. */
6700
6701 if (nonascii_space_p && EQ (Vnobreak_char_display, Qt))
6702 {
6703 /* Merge `nobreak-space' into the current face. */
6704 face_id = merge_faces (it->f, Qnobreak_space, 0,
6705 it->face_id);
6706 XSETINT (it->ctl_chars[0], ' ');
6707 ctl_len = 1;
6708 goto display_control;
6709 }
6710
6711 /* Handle sequences that start with the "escape glyph". */
6712
6713 /* the default escape glyph is \. */
6714 escape_glyph = '\\';
6715
6716 if (it->dp
6717 && (gc = DISP_ESCAPE_GLYPH (it->dp), GLYPH_CODE_P (gc)))
6718 {
6719 escape_glyph = GLYPH_CODE_CHAR (gc);
6720 lface_id = GLYPH_CODE_FACE (gc);
6721 }
6722 if (lface_id)
6723 {
6724 /* The display table specified a face.
6725 Merge it into face_id and also into escape_glyph. */
6726 face_id = merge_faces (it->f, Qt, lface_id,
6727 it->face_id);
6728 }
6729 else if (it->f == last_escape_glyph_frame
6730 && it->face_id == last_escape_glyph_face_id)
6731 {
6732 face_id = last_escape_glyph_merged_face_id;
6733 }
6734 else
6735 {
6736 /* Merge the escape-glyph face into the current face. */
6737 face_id = merge_faces (it->f, Qescape_glyph, 0,
6738 it->face_id);
6739 last_escape_glyph_frame = it->f;
6740 last_escape_glyph_face_id = it->face_id;
6741 last_escape_glyph_merged_face_id = face_id;
6742 }
6743
6744 /* Draw non-ASCII hyphen with just highlighting: */
6745
6746 if (nonascii_hyphen_p && EQ (Vnobreak_char_display, Qt))
6747 {
6748 XSETINT (it->ctl_chars[0], '-');
6749 ctl_len = 1;
6750 goto display_control;
6751 }
6752
6753 /* Draw non-ASCII space/hyphen with escape glyph: */
6754
6755 if (nonascii_space_p || nonascii_hyphen_p)
6756 {
6757 XSETINT (it->ctl_chars[0], escape_glyph);
6758 XSETINT (it->ctl_chars[1], nonascii_space_p ? ' ' : '-');
6759 ctl_len = 2;
6760 goto display_control;
6761 }
6762
6763 {
6764 char str[10];
6765 int len, i;
6766
6767 if (CHAR_BYTE8_P (c))
6768 /* Display \200 instead of \17777600. */
6769 c = CHAR_TO_BYTE8 (c);
6770 len = sprintf (str, "%03o", c);
6771
6772 XSETINT (it->ctl_chars[0], escape_glyph);
6773 for (i = 0; i < len; i++)
6774 XSETINT (it->ctl_chars[i + 1], str[i]);
6775 ctl_len = len + 1;
6776 }
6777
6778 display_control:
6779 /* Set up IT->dpvec and return first character from it. */
6780 it->dpvec_char_len = it->len;
6781 it->dpvec = it->ctl_chars;
6782 it->dpend = it->dpvec + ctl_len;
6783 it->current.dpvec_index = 0;
6784 it->dpvec_face_id = face_id;
6785 it->saved_face_id = it->face_id;
6786 it->method = GET_FROM_DISPLAY_VECTOR;
6787 it->ellipsis_p = 0;
6788 goto get_next;
6789 }
6790 it->char_to_display = c;
6791 }
6792 else if (success_p)
6793 {
6794 it->char_to_display = it->c;
6795 }
6796 }
6797
6798 /* Adjust face id for a multibyte character. There are no multibyte
6799 character in unibyte text. */
6800 if ((it->what == IT_CHARACTER || it->what == IT_COMPOSITION)
6801 && it->multibyte_p
6802 && success_p
6803 && FRAME_WINDOW_P (it->f))
6804 {
6805 struct face *face = FACE_FROM_ID (it->f, it->face_id);
6806
6807 if (it->what == IT_COMPOSITION && it->cmp_it.ch >= 0)
6808 {
6809 /* Automatic composition with glyph-string. */
6810 Lisp_Object gstring = composition_gstring_from_id (it->cmp_it.id);
6811
6812 it->face_id = face_for_font (it->f, LGSTRING_FONT (gstring), face);
6813 }
6814 else
6815 {
6816 ptrdiff_t pos = (it->s ? -1
6817 : STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
6818 : IT_CHARPOS (*it));
6819 int c;
6820
6821 if (it->what == IT_CHARACTER)
6822 c = it->char_to_display;
6823 else
6824 {
6825 struct composition *cmp = composition_table[it->cmp_it.id];
6826 int i;
6827
6828 c = ' ';
6829 for (i = 0; i < cmp->glyph_len; i++)
6830 /* TAB in a composition means display glyphs with
6831 padding space on the left or right. */
6832 if ((c = COMPOSITION_GLYPH (cmp, i)) != '\t')
6833 break;
6834 }
6835 it->face_id = FACE_FOR_CHAR (it->f, face, c, pos, it->string);
6836 }
6837 }
6838
6839 done:
6840 /* Is this character the last one of a run of characters with
6841 box? If yes, set IT->end_of_box_run_p to 1. */
6842 if (it->face_box_p
6843 && it->s == NULL)
6844 {
6845 if (it->method == GET_FROM_STRING && it->sp)
6846 {
6847 int face_id = underlying_face_id (it);
6848 struct face *face = FACE_FROM_ID (it->f, face_id);
6849
6850 if (face)
6851 {
6852 if (face->box == FACE_NO_BOX)
6853 {
6854 /* If the box comes from face properties in a
6855 display string, check faces in that string. */
6856 int string_face_id = face_after_it_pos (it);
6857 it->end_of_box_run_p
6858 = (FACE_FROM_ID (it->f, string_face_id)->box
6859 == FACE_NO_BOX);
6860 }
6861 /* Otherwise, the box comes from the underlying face.
6862 If this is the last string character displayed, check
6863 the next buffer location. */
6864 else if ((IT_STRING_CHARPOS (*it) >= SCHARS (it->string) - 1)
6865 && (it->current.overlay_string_index
6866 == it->n_overlay_strings - 1))
6867 {
6868 ptrdiff_t ignore;
6869 int next_face_id;
6870 struct text_pos pos = it->current.pos;
6871 INC_TEXT_POS (pos, it->multibyte_p);
6872
6873 next_face_id = face_at_buffer_position
6874 (it->w, CHARPOS (pos), it->region_beg_charpos,
6875 it->region_end_charpos, &ignore,
6876 (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT), 0,
6877 -1);
6878 it->end_of_box_run_p
6879 = (FACE_FROM_ID (it->f, next_face_id)->box
6880 == FACE_NO_BOX);
6881 }
6882 }
6883 }
6884 else
6885 {
6886 int face_id = face_after_it_pos (it);
6887 it->end_of_box_run_p
6888 = (face_id != it->face_id
6889 && FACE_FROM_ID (it->f, face_id)->box == FACE_NO_BOX);
6890 }
6891 }
6892 /* If we reached the end of the object we've been iterating (e.g., a
6893 display string or an overlay string), and there's something on
6894 IT->stack, proceed with what's on the stack. It doesn't make
6895 sense to return zero if there's unprocessed stuff on the stack,
6896 because otherwise that stuff will never be displayed. */
6897 if (!success_p && it->sp > 0)
6898 {
6899 set_iterator_to_next (it, 0);
6900 success_p = get_next_display_element (it);
6901 }
6902
6903 /* Value is 0 if end of buffer or string reached. */
6904 return success_p;
6905 }
6906
6907
6908 /* Move IT to the next display element.
6909
6910 RESEAT_P non-zero means if called on a newline in buffer text,
6911 skip to the next visible line start.
6912
6913 Functions get_next_display_element and set_iterator_to_next are
6914 separate because I find this arrangement easier to handle than a
6915 get_next_display_element function that also increments IT's
6916 position. The way it is we can first look at an iterator's current
6917 display element, decide whether it fits on a line, and if it does,
6918 increment the iterator position. The other way around we probably
6919 would either need a flag indicating whether the iterator has to be
6920 incremented the next time, or we would have to implement a
6921 decrement position function which would not be easy to write. */
6922
6923 void
6924 set_iterator_to_next (struct it *it, int reseat_p)
6925 {
6926 /* Reset flags indicating start and end of a sequence of characters
6927 with box. Reset them at the start of this function because
6928 moving the iterator to a new position might set them. */
6929 it->start_of_box_run_p = it->end_of_box_run_p = 0;
6930
6931 switch (it->method)
6932 {
6933 case GET_FROM_BUFFER:
6934 /* The current display element of IT is a character from
6935 current_buffer. Advance in the buffer, and maybe skip over
6936 invisible lines that are so because of selective display. */
6937 if (ITERATOR_AT_END_OF_LINE_P (it) && reseat_p)
6938 reseat_at_next_visible_line_start (it, 0);
6939 else if (it->cmp_it.id >= 0)
6940 {
6941 /* We are currently getting glyphs from a composition. */
6942 int i;
6943
6944 if (! it->bidi_p)
6945 {
6946 IT_CHARPOS (*it) += it->cmp_it.nchars;
6947 IT_BYTEPOS (*it) += it->cmp_it.nbytes;
6948 if (it->cmp_it.to < it->cmp_it.nglyphs)
6949 {
6950 it->cmp_it.from = it->cmp_it.to;
6951 }
6952 else
6953 {
6954 it->cmp_it.id = -1;
6955 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
6956 IT_BYTEPOS (*it),
6957 it->end_charpos, Qnil);
6958 }
6959 }
6960 else if (! it->cmp_it.reversed_p)
6961 {
6962 /* Composition created while scanning forward. */
6963 /* Update IT's char/byte positions to point to the first
6964 character of the next grapheme cluster, or to the
6965 character visually after the current composition. */
6966 for (i = 0; i < it->cmp_it.nchars; i++)
6967 bidi_move_to_visually_next (&it->bidi_it);
6968 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
6969 IT_CHARPOS (*it) = it->bidi_it.charpos;
6970
6971 if (it->cmp_it.to < it->cmp_it.nglyphs)
6972 {
6973 /* Proceed to the next grapheme cluster. */
6974 it->cmp_it.from = it->cmp_it.to;
6975 }
6976 else
6977 {
6978 /* No more grapheme clusters in this composition.
6979 Find the next stop position. */
6980 ptrdiff_t stop = it->end_charpos;
6981 if (it->bidi_it.scan_dir < 0)
6982 /* Now we are scanning backward and don't know
6983 where to stop. */
6984 stop = -1;
6985 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
6986 IT_BYTEPOS (*it), stop, Qnil);
6987 }
6988 }
6989 else
6990 {
6991 /* Composition created while scanning backward. */
6992 /* Update IT's char/byte positions to point to the last
6993 character of the previous grapheme cluster, or the
6994 character visually after the current composition. */
6995 for (i = 0; i < it->cmp_it.nchars; i++)
6996 bidi_move_to_visually_next (&it->bidi_it);
6997 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
6998 IT_CHARPOS (*it) = it->bidi_it.charpos;
6999 if (it->cmp_it.from > 0)
7000 {
7001 /* Proceed to the previous grapheme cluster. */
7002 it->cmp_it.to = it->cmp_it.from;
7003 }
7004 else
7005 {
7006 /* No more grapheme clusters in this composition.
7007 Find the next stop position. */
7008 ptrdiff_t stop = it->end_charpos;
7009 if (it->bidi_it.scan_dir < 0)
7010 /* Now we are scanning backward and don't know
7011 where to stop. */
7012 stop = -1;
7013 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
7014 IT_BYTEPOS (*it), stop, Qnil);
7015 }
7016 }
7017 }
7018 else
7019 {
7020 xassert (it->len != 0);
7021
7022 if (!it->bidi_p)
7023 {
7024 IT_BYTEPOS (*it) += it->len;
7025 IT_CHARPOS (*it) += 1;
7026 }
7027 else
7028 {
7029 int prev_scan_dir = it->bidi_it.scan_dir;
7030 /* If this is a new paragraph, determine its base
7031 direction (a.k.a. its base embedding level). */
7032 if (it->bidi_it.new_paragraph)
7033 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 0);
7034 bidi_move_to_visually_next (&it->bidi_it);
7035 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
7036 IT_CHARPOS (*it) = it->bidi_it.charpos;
7037 if (prev_scan_dir != it->bidi_it.scan_dir)
7038 {
7039 /* As the scan direction was changed, we must
7040 re-compute the stop position for composition. */
7041 ptrdiff_t stop = it->end_charpos;
7042 if (it->bidi_it.scan_dir < 0)
7043 stop = -1;
7044 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
7045 IT_BYTEPOS (*it), stop, Qnil);
7046 }
7047 }
7048 xassert (IT_BYTEPOS (*it) == CHAR_TO_BYTE (IT_CHARPOS (*it)));
7049 }
7050 break;
7051
7052 case GET_FROM_C_STRING:
7053 /* Current display element of IT is from a C string. */
7054 if (!it->bidi_p
7055 /* If the string position is beyond string's end, it means
7056 next_element_from_c_string is padding the string with
7057 blanks, in which case we bypass the bidi iterator,
7058 because it cannot deal with such virtual characters. */
7059 || IT_CHARPOS (*it) >= it->bidi_it.string.schars)
7060 {
7061 IT_BYTEPOS (*it) += it->len;
7062 IT_CHARPOS (*it) += 1;
7063 }
7064 else
7065 {
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 }
7070 break;
7071
7072 case GET_FROM_DISPLAY_VECTOR:
7073 /* Current display element of IT is from a display table entry.
7074 Advance in the display table definition. Reset it to null if
7075 end reached, and continue with characters from buffers/
7076 strings. */
7077 ++it->current.dpvec_index;
7078
7079 /* Restore face of the iterator to what they were before the
7080 display vector entry (these entries may contain faces). */
7081 it->face_id = it->saved_face_id;
7082
7083 if (it->dpvec + it->current.dpvec_index >= it->dpend)
7084 {
7085 int recheck_faces = it->ellipsis_p;
7086
7087 if (it->s)
7088 it->method = GET_FROM_C_STRING;
7089 else if (STRINGP (it->string))
7090 it->method = GET_FROM_STRING;
7091 else
7092 {
7093 it->method = GET_FROM_BUFFER;
7094 it->object = it->w->buffer;
7095 }
7096
7097 it->dpvec = NULL;
7098 it->current.dpvec_index = -1;
7099
7100 /* Skip over characters which were displayed via IT->dpvec. */
7101 if (it->dpvec_char_len < 0)
7102 reseat_at_next_visible_line_start (it, 1);
7103 else if (it->dpvec_char_len > 0)
7104 {
7105 if (it->method == GET_FROM_STRING
7106 && it->n_overlay_strings > 0)
7107 it->ignore_overlay_strings_at_pos_p = 1;
7108 it->len = it->dpvec_char_len;
7109 set_iterator_to_next (it, reseat_p);
7110 }
7111
7112 /* Maybe recheck faces after display vector */
7113 if (recheck_faces)
7114 it->stop_charpos = IT_CHARPOS (*it);
7115 }
7116 break;
7117
7118 case GET_FROM_STRING:
7119 /* Current display element is a character from a Lisp string. */
7120 xassert (it->s == NULL && STRINGP (it->string));
7121 /* Don't advance past string end. These conditions are true
7122 when set_iterator_to_next is called at the end of
7123 get_next_display_element, in which case the Lisp string is
7124 already exhausted, and all we want is pop the iterator
7125 stack. */
7126 if (it->current.overlay_string_index >= 0)
7127 {
7128 /* This is an overlay string, so there's no padding with
7129 spaces, and the number of characters in the string is
7130 where the string ends. */
7131 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
7132 goto consider_string_end;
7133 }
7134 else
7135 {
7136 /* Not an overlay string. There could be padding, so test
7137 against it->end_charpos . */
7138 if (IT_STRING_CHARPOS (*it) >= it->end_charpos)
7139 goto consider_string_end;
7140 }
7141 if (it->cmp_it.id >= 0)
7142 {
7143 int i;
7144
7145 if (! it->bidi_p)
7146 {
7147 IT_STRING_CHARPOS (*it) += it->cmp_it.nchars;
7148 IT_STRING_BYTEPOS (*it) += it->cmp_it.nbytes;
7149 if (it->cmp_it.to < it->cmp_it.nglyphs)
7150 it->cmp_it.from = it->cmp_it.to;
7151 else
7152 {
7153 it->cmp_it.id = -1;
7154 composition_compute_stop_pos (&it->cmp_it,
7155 IT_STRING_CHARPOS (*it),
7156 IT_STRING_BYTEPOS (*it),
7157 it->end_charpos, it->string);
7158 }
7159 }
7160 else if (! it->cmp_it.reversed_p)
7161 {
7162 for (i = 0; i < it->cmp_it.nchars; i++)
7163 bidi_move_to_visually_next (&it->bidi_it);
7164 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
7165 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
7166
7167 if (it->cmp_it.to < it->cmp_it.nglyphs)
7168 it->cmp_it.from = it->cmp_it.to;
7169 else
7170 {
7171 ptrdiff_t stop = it->end_charpos;
7172 if (it->bidi_it.scan_dir < 0)
7173 stop = -1;
7174 composition_compute_stop_pos (&it->cmp_it,
7175 IT_STRING_CHARPOS (*it),
7176 IT_STRING_BYTEPOS (*it), stop,
7177 it->string);
7178 }
7179 }
7180 else
7181 {
7182 for (i = 0; i < it->cmp_it.nchars; i++)
7183 bidi_move_to_visually_next (&it->bidi_it);
7184 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
7185 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
7186 if (it->cmp_it.from > 0)
7187 it->cmp_it.to = it->cmp_it.from;
7188 else
7189 {
7190 ptrdiff_t stop = it->end_charpos;
7191 if (it->bidi_it.scan_dir < 0)
7192 stop = -1;
7193 composition_compute_stop_pos (&it->cmp_it,
7194 IT_STRING_CHARPOS (*it),
7195 IT_STRING_BYTEPOS (*it), stop,
7196 it->string);
7197 }
7198 }
7199 }
7200 else
7201 {
7202 if (!it->bidi_p
7203 /* If the string position is beyond string's end, it
7204 means next_element_from_string is padding the string
7205 with blanks, in which case we bypass the bidi
7206 iterator, because it cannot deal with such virtual
7207 characters. */
7208 || IT_STRING_CHARPOS (*it) >= it->bidi_it.string.schars)
7209 {
7210 IT_STRING_BYTEPOS (*it) += it->len;
7211 IT_STRING_CHARPOS (*it) += 1;
7212 }
7213 else
7214 {
7215 int prev_scan_dir = it->bidi_it.scan_dir;
7216
7217 bidi_move_to_visually_next (&it->bidi_it);
7218 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
7219 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
7220 if (prev_scan_dir != it->bidi_it.scan_dir)
7221 {
7222 ptrdiff_t stop = it->end_charpos;
7223
7224 if (it->bidi_it.scan_dir < 0)
7225 stop = -1;
7226 composition_compute_stop_pos (&it->cmp_it,
7227 IT_STRING_CHARPOS (*it),
7228 IT_STRING_BYTEPOS (*it), stop,
7229 it->string);
7230 }
7231 }
7232 }
7233
7234 consider_string_end:
7235
7236 if (it->current.overlay_string_index >= 0)
7237 {
7238 /* IT->string is an overlay string. Advance to the
7239 next, if there is one. */
7240 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
7241 {
7242 it->ellipsis_p = 0;
7243 next_overlay_string (it);
7244 if (it->ellipsis_p)
7245 setup_for_ellipsis (it, 0);
7246 }
7247 }
7248 else
7249 {
7250 /* IT->string is not an overlay string. If we reached
7251 its end, and there is something on IT->stack, proceed
7252 with what is on the stack. This can be either another
7253 string, this time an overlay string, or a buffer. */
7254 if (IT_STRING_CHARPOS (*it) == SCHARS (it->string)
7255 && it->sp > 0)
7256 {
7257 pop_it (it);
7258 if (it->method == GET_FROM_STRING)
7259 goto consider_string_end;
7260 }
7261 }
7262 break;
7263
7264 case GET_FROM_IMAGE:
7265 case GET_FROM_STRETCH:
7266 #ifdef HAVE_XWIDGETS
7267 case GET_FROM_XWIDGET:
7268
7269 /* The position etc with which we have to proceed are on
7270 the stack. The position may be at the end of a string,
7271 if the `display' property takes up the whole string. */
7272 xassert (it->sp > 0);
7273 pop_it (it);
7274 if (it->method == GET_FROM_STRING)
7275 goto consider_string_end;
7276 break;
7277 #endif
7278 default:
7279 /* There are no other methods defined, so this should be a bug. */
7280 abort ();
7281 }
7282
7283 xassert (it->method != GET_FROM_STRING
7284 || (STRINGP (it->string)
7285 && IT_STRING_CHARPOS (*it) >= 0));
7286 }
7287
7288 /* Load IT's display element fields with information about the next
7289 display element which comes from a display table entry or from the
7290 result of translating a control character to one of the forms `^C'
7291 or `\003'.
7292
7293 IT->dpvec holds the glyphs to return as characters.
7294 IT->saved_face_id holds the face id before the display vector--it
7295 is restored into IT->face_id in set_iterator_to_next. */
7296
7297 static int
7298 next_element_from_display_vector (struct it *it)
7299 {
7300 Lisp_Object gc;
7301
7302 /* Precondition. */
7303 xassert (it->dpvec && it->current.dpvec_index >= 0);
7304
7305 it->face_id = it->saved_face_id;
7306
7307 /* KFS: This code used to check ip->dpvec[0] instead of the current element.
7308 That seemed totally bogus - so I changed it... */
7309 gc = it->dpvec[it->current.dpvec_index];
7310
7311 if (GLYPH_CODE_P (gc))
7312 {
7313 it->c = GLYPH_CODE_CHAR (gc);
7314 it->len = CHAR_BYTES (it->c);
7315
7316 /* The entry may contain a face id to use. Such a face id is
7317 the id of a Lisp face, not a realized face. A face id of
7318 zero means no face is specified. */
7319 if (it->dpvec_face_id >= 0)
7320 it->face_id = it->dpvec_face_id;
7321 else
7322 {
7323 int lface_id = GLYPH_CODE_FACE (gc);
7324 if (lface_id > 0)
7325 it->face_id = merge_faces (it->f, Qt, lface_id,
7326 it->saved_face_id);
7327 }
7328 }
7329 else
7330 /* Display table entry is invalid. Return a space. */
7331 it->c = ' ', it->len = 1;
7332
7333 /* Don't change position and object of the iterator here. They are
7334 still the values of the character that had this display table
7335 entry or was translated, and that's what we want. */
7336 it->what = IT_CHARACTER;
7337 return 1;
7338 }
7339
7340 /* Get the first element of string/buffer in the visual order, after
7341 being reseated to a new position in a string or a buffer. */
7342 static void
7343 get_visually_first_element (struct it *it)
7344 {
7345 int string_p = STRINGP (it->string) || it->s;
7346 ptrdiff_t eob = (string_p ? it->bidi_it.string.schars : ZV);
7347 ptrdiff_t bob = (string_p ? 0 : BEGV);
7348
7349 if (STRINGP (it->string))
7350 {
7351 it->bidi_it.charpos = IT_STRING_CHARPOS (*it);
7352 it->bidi_it.bytepos = IT_STRING_BYTEPOS (*it);
7353 }
7354 else
7355 {
7356 it->bidi_it.charpos = IT_CHARPOS (*it);
7357 it->bidi_it.bytepos = IT_BYTEPOS (*it);
7358 }
7359
7360 if (it->bidi_it.charpos == eob)
7361 {
7362 /* Nothing to do, but reset the FIRST_ELT flag, like
7363 bidi_paragraph_init does, because we are not going to
7364 call it. */
7365 it->bidi_it.first_elt = 0;
7366 }
7367 else if (it->bidi_it.charpos == bob
7368 || (!string_p
7369 && (FETCH_CHAR (it->bidi_it.bytepos - 1) == '\n'
7370 || FETCH_CHAR (it->bidi_it.bytepos) == '\n')))
7371 {
7372 /* If we are at the beginning of a line/string, we can produce
7373 the next element right away. */
7374 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1);
7375 bidi_move_to_visually_next (&it->bidi_it);
7376 }
7377 else
7378 {
7379 ptrdiff_t orig_bytepos = it->bidi_it.bytepos;
7380
7381 /* We need to prime the bidi iterator starting at the line's or
7382 string's beginning, before we will be able to produce the
7383 next element. */
7384 if (string_p)
7385 it->bidi_it.charpos = it->bidi_it.bytepos = 0;
7386 else
7387 {
7388 it->bidi_it.charpos = find_next_newline_no_quit (IT_CHARPOS (*it),
7389 -1);
7390 it->bidi_it.bytepos = CHAR_TO_BYTE (it->bidi_it.charpos);
7391 }
7392 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1);
7393 do
7394 {
7395 /* Now return to buffer/string position where we were asked
7396 to get the next display element, and produce that. */
7397 bidi_move_to_visually_next (&it->bidi_it);
7398 }
7399 while (it->bidi_it.bytepos != orig_bytepos
7400 && it->bidi_it.charpos < eob);
7401 }
7402
7403 /* Adjust IT's position information to where we ended up. */
7404 if (STRINGP (it->string))
7405 {
7406 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
7407 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
7408 }
7409 else
7410 {
7411 IT_CHARPOS (*it) = it->bidi_it.charpos;
7412 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
7413 }
7414
7415 if (STRINGP (it->string) || !it->s)
7416 {
7417 ptrdiff_t stop, charpos, bytepos;
7418
7419 if (STRINGP (it->string))
7420 {
7421 xassert (!it->s);
7422 stop = SCHARS (it->string);
7423 if (stop > it->end_charpos)
7424 stop = it->end_charpos;
7425 charpos = IT_STRING_CHARPOS (*it);
7426 bytepos = IT_STRING_BYTEPOS (*it);
7427 }
7428 else
7429 {
7430 stop = it->end_charpos;
7431 charpos = IT_CHARPOS (*it);
7432 bytepos = IT_BYTEPOS (*it);
7433 }
7434 if (it->bidi_it.scan_dir < 0)
7435 stop = -1;
7436 composition_compute_stop_pos (&it->cmp_it, charpos, bytepos, stop,
7437 it->string);
7438 }
7439 }
7440
7441 /* Load IT with the next display element from Lisp string IT->string.
7442 IT->current.string_pos is the current position within the string.
7443 If IT->current.overlay_string_index >= 0, the Lisp string is an
7444 overlay string. */
7445
7446 static int
7447 next_element_from_string (struct it *it)
7448 {
7449 struct text_pos position;
7450
7451 xassert (STRINGP (it->string));
7452 xassert (!it->bidi_p || EQ (it->string, it->bidi_it.string.lstring));
7453 xassert (IT_STRING_CHARPOS (*it) >= 0);
7454 position = it->current.string_pos;
7455
7456 /* With bidi reordering, the character to display might not be the
7457 character at IT_STRING_CHARPOS. BIDI_IT.FIRST_ELT non-zero means
7458 that we were reseat()ed to a new string, whose paragraph
7459 direction is not known. */
7460 if (it->bidi_p && it->bidi_it.first_elt)
7461 {
7462 get_visually_first_element (it);
7463 SET_TEXT_POS (position, IT_STRING_CHARPOS (*it), IT_STRING_BYTEPOS (*it));
7464 }
7465
7466 /* Time to check for invisible text? */
7467 if (IT_STRING_CHARPOS (*it) < it->end_charpos)
7468 {
7469 if (IT_STRING_CHARPOS (*it) >= it->stop_charpos)
7470 {
7471 if (!(!it->bidi_p
7472 || BIDI_AT_BASE_LEVEL (it->bidi_it)
7473 || IT_STRING_CHARPOS (*it) == it->stop_charpos))
7474 {
7475 /* With bidi non-linear iteration, we could find
7476 ourselves far beyond the last computed stop_charpos,
7477 with several other stop positions in between that we
7478 missed. Scan them all now, in buffer's logical
7479 order, until we find and handle the last stop_charpos
7480 that precedes our current position. */
7481 handle_stop_backwards (it, it->stop_charpos);
7482 return GET_NEXT_DISPLAY_ELEMENT (it);
7483 }
7484 else
7485 {
7486 if (it->bidi_p)
7487 {
7488 /* Take note of the stop position we just moved
7489 across, for when we will move back across it. */
7490 it->prev_stop = it->stop_charpos;
7491 /* If we are at base paragraph embedding level, take
7492 note of the last stop position seen at this
7493 level. */
7494 if (BIDI_AT_BASE_LEVEL (it->bidi_it))
7495 it->base_level_stop = it->stop_charpos;
7496 }
7497 handle_stop (it);
7498
7499 /* Since a handler may have changed IT->method, we must
7500 recurse here. */
7501 return GET_NEXT_DISPLAY_ELEMENT (it);
7502 }
7503 }
7504 else if (it->bidi_p
7505 /* If we are before prev_stop, we may have overstepped
7506 on our way backwards a stop_pos, and if so, we need
7507 to handle that stop_pos. */
7508 && IT_STRING_CHARPOS (*it) < it->prev_stop
7509 /* We can sometimes back up for reasons that have nothing
7510 to do with bidi reordering. E.g., compositions. The
7511 code below is only needed when we are above the base
7512 embedding level, so test for that explicitly. */
7513 && !BIDI_AT_BASE_LEVEL (it->bidi_it))
7514 {
7515 /* If we lost track of base_level_stop, we have no better
7516 place for handle_stop_backwards to start from than string
7517 beginning. This happens, e.g., when we were reseated to
7518 the previous screenful of text by vertical-motion. */
7519 if (it->base_level_stop <= 0
7520 || IT_STRING_CHARPOS (*it) < it->base_level_stop)
7521 it->base_level_stop = 0;
7522 handle_stop_backwards (it, it->base_level_stop);
7523 return GET_NEXT_DISPLAY_ELEMENT (it);
7524 }
7525 }
7526
7527 if (it->current.overlay_string_index >= 0)
7528 {
7529 /* Get the next character from an overlay string. In overlay
7530 strings, there is no field width or padding with spaces to
7531 do. */
7532 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
7533 {
7534 it->what = IT_EOB;
7535 return 0;
7536 }
7537 else if (CHAR_COMPOSED_P (it, IT_STRING_CHARPOS (*it),
7538 IT_STRING_BYTEPOS (*it),
7539 it->bidi_it.scan_dir < 0
7540 ? -1
7541 : SCHARS (it->string))
7542 && next_element_from_composition (it))
7543 {
7544 return 1;
7545 }
7546 else if (STRING_MULTIBYTE (it->string))
7547 {
7548 const unsigned char *s = (SDATA (it->string)
7549 + IT_STRING_BYTEPOS (*it));
7550 it->c = string_char_and_length (s, &it->len);
7551 }
7552 else
7553 {
7554 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
7555 it->len = 1;
7556 }
7557 }
7558 else
7559 {
7560 /* Get the next character from a Lisp string that is not an
7561 overlay string. Such strings come from the mode line, for
7562 example. We may have to pad with spaces, or truncate the
7563 string. See also next_element_from_c_string. */
7564 if (IT_STRING_CHARPOS (*it) >= it->end_charpos)
7565 {
7566 it->what = IT_EOB;
7567 return 0;
7568 }
7569 else if (IT_STRING_CHARPOS (*it) >= it->string_nchars)
7570 {
7571 /* Pad with spaces. */
7572 it->c = ' ', it->len = 1;
7573 CHARPOS (position) = BYTEPOS (position) = -1;
7574 }
7575 else if (CHAR_COMPOSED_P (it, IT_STRING_CHARPOS (*it),
7576 IT_STRING_BYTEPOS (*it),
7577 it->bidi_it.scan_dir < 0
7578 ? -1
7579 : it->string_nchars)
7580 && next_element_from_composition (it))
7581 {
7582 return 1;
7583 }
7584 else if (STRING_MULTIBYTE (it->string))
7585 {
7586 const unsigned char *s = (SDATA (it->string)
7587 + IT_STRING_BYTEPOS (*it));
7588 it->c = string_char_and_length (s, &it->len);
7589 }
7590 else
7591 {
7592 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
7593 it->len = 1;
7594 }
7595 }
7596
7597 /* Record what we have and where it came from. */
7598 it->what = IT_CHARACTER;
7599 it->object = it->string;
7600 it->position = position;
7601 return 1;
7602 }
7603
7604
7605 /* Load IT with next display element from C string IT->s.
7606 IT->string_nchars is the maximum number of characters to return
7607 from the string. IT->end_charpos may be greater than
7608 IT->string_nchars when this function is called, in which case we
7609 may have to return padding spaces. Value is zero if end of string
7610 reached, including padding spaces. */
7611
7612 static int
7613 next_element_from_c_string (struct it *it)
7614 {
7615 int success_p = 1;
7616
7617 xassert (it->s);
7618 xassert (!it->bidi_p || it->s == it->bidi_it.string.s);
7619 it->what = IT_CHARACTER;
7620 BYTEPOS (it->position) = CHARPOS (it->position) = 0;
7621 it->object = Qnil;
7622
7623 /* With bidi reordering, the character to display might not be the
7624 character at IT_CHARPOS. BIDI_IT.FIRST_ELT non-zero means that
7625 we were reseated to a new string, whose paragraph direction is
7626 not known. */
7627 if (it->bidi_p && it->bidi_it.first_elt)
7628 get_visually_first_element (it);
7629
7630 /* IT's position can be greater than IT->string_nchars in case a
7631 field width or precision has been specified when the iterator was
7632 initialized. */
7633 if (IT_CHARPOS (*it) >= it->end_charpos)
7634 {
7635 /* End of the game. */
7636 it->what = IT_EOB;
7637 success_p = 0;
7638 }
7639 else if (IT_CHARPOS (*it) >= it->string_nchars)
7640 {
7641 /* Pad with spaces. */
7642 it->c = ' ', it->len = 1;
7643 BYTEPOS (it->position) = CHARPOS (it->position) = -1;
7644 }
7645 else if (it->multibyte_p)
7646 it->c = string_char_and_length (it->s + IT_BYTEPOS (*it), &it->len);
7647 else
7648 it->c = it->s[IT_BYTEPOS (*it)], it->len = 1;
7649
7650 return success_p;
7651 }
7652
7653
7654 /* Set up IT to return characters from an ellipsis, if appropriate.
7655 The definition of the ellipsis glyphs may come from a display table
7656 entry. This function fills IT with the first glyph from the
7657 ellipsis if an ellipsis is to be displayed. */
7658
7659 static int
7660 next_element_from_ellipsis (struct it *it)
7661 {
7662 if (it->selective_display_ellipsis_p)
7663 setup_for_ellipsis (it, it->len);
7664 else
7665 {
7666 /* The face at the current position may be different from the
7667 face we find after the invisible text. Remember what it
7668 was in IT->saved_face_id, and signal that it's there by
7669 setting face_before_selective_p. */
7670 it->saved_face_id = it->face_id;
7671 it->method = GET_FROM_BUFFER;
7672 it->object = it->w->buffer;
7673 reseat_at_next_visible_line_start (it, 1);
7674 it->face_before_selective_p = 1;
7675 }
7676
7677 return GET_NEXT_DISPLAY_ELEMENT (it);
7678 }
7679
7680
7681 /* Deliver an image display element. The iterator IT is already
7682 filled with image information (done in handle_display_prop). Value
7683 is always 1. */
7684
7685
7686 static int
7687 next_element_from_image (struct it *it)
7688 {
7689 it->what = IT_IMAGE;
7690 it->ignore_overlay_strings_at_pos_p = 0;
7691 return 1;
7692 }
7693
7694 #ifdef HAVE_XWIDGETS
7695 /* im not sure about this FIXME JAVE*/
7696 static int
7697 next_element_from_xwidget (struct it *it)
7698 {
7699 it->what = IT_XWIDGET;
7700 //assert_valid_xwidget_id(it->xwidget_id,"next_element_from_xwidget");
7701 //this is shaky because why do we set "what" if we dont set the other parts??
7702 //printf("xwidget_id %d: in next_element_from_xwidget: FIXME \n", it->xwidget_id);
7703 return 1;
7704 }
7705 #endif
7706
7707
7708 /* Fill iterator IT with next display element from a stretch glyph
7709 property. IT->object is the value of the text property. Value is
7710 always 1. */
7711
7712 static int
7713 next_element_from_stretch (struct it *it)
7714 {
7715 it->what = IT_STRETCH;
7716 return 1;
7717 }
7718
7719 /* Scan backwards from IT's current position until we find a stop
7720 position, or until BEGV. This is called when we find ourself
7721 before both the last known prev_stop and base_level_stop while
7722 reordering bidirectional text. */
7723
7724 static void
7725 compute_stop_pos_backwards (struct it *it)
7726 {
7727 const int SCAN_BACK_LIMIT = 1000;
7728 struct text_pos pos;
7729 struct display_pos save_current = it->current;
7730 struct text_pos save_position = it->position;
7731 ptrdiff_t charpos = IT_CHARPOS (*it);
7732 ptrdiff_t where_we_are = charpos;
7733 ptrdiff_t save_stop_pos = it->stop_charpos;
7734 ptrdiff_t save_end_pos = it->end_charpos;
7735
7736 xassert (NILP (it->string) && !it->s);
7737 xassert (it->bidi_p);
7738 it->bidi_p = 0;
7739 do
7740 {
7741 it->end_charpos = min (charpos + 1, ZV);
7742 charpos = max (charpos - SCAN_BACK_LIMIT, BEGV);
7743 SET_TEXT_POS (pos, charpos, BYTE_TO_CHAR (charpos));
7744 reseat_1 (it, pos, 0);
7745 compute_stop_pos (it);
7746 /* We must advance forward, right? */
7747 if (it->stop_charpos <= charpos)
7748 abort ();
7749 }
7750 while (charpos > BEGV && it->stop_charpos >= it->end_charpos);
7751
7752 if (it->stop_charpos <= where_we_are)
7753 it->prev_stop = it->stop_charpos;
7754 else
7755 it->prev_stop = BEGV;
7756 it->bidi_p = 1;
7757 it->current = save_current;
7758 it->position = save_position;
7759 it->stop_charpos = save_stop_pos;
7760 it->end_charpos = save_end_pos;
7761 }
7762
7763 /* Scan forward from CHARPOS in the current buffer/string, until we
7764 find a stop position > current IT's position. Then handle the stop
7765 position before that. This is called when we bump into a stop
7766 position while reordering bidirectional text. CHARPOS should be
7767 the last previously processed stop_pos (or BEGV/0, if none were
7768 processed yet) whose position is less that IT's current
7769 position. */
7770
7771 static void
7772 handle_stop_backwards (struct it *it, ptrdiff_t charpos)
7773 {
7774 int bufp = !STRINGP (it->string);
7775 ptrdiff_t where_we_are = (bufp ? IT_CHARPOS (*it) : IT_STRING_CHARPOS (*it));
7776 struct display_pos save_current = it->current;
7777 struct text_pos save_position = it->position;
7778 struct text_pos pos1;
7779 ptrdiff_t next_stop;
7780
7781 /* Scan in strict logical order. */
7782 xassert (it->bidi_p);
7783 it->bidi_p = 0;
7784 do
7785 {
7786 it->prev_stop = charpos;
7787 if (bufp)
7788 {
7789 SET_TEXT_POS (pos1, charpos, CHAR_TO_BYTE (charpos));
7790 reseat_1 (it, pos1, 0);
7791 }
7792 else
7793 it->current.string_pos = string_pos (charpos, it->string);
7794 compute_stop_pos (it);
7795 /* We must advance forward, right? */
7796 if (it->stop_charpos <= it->prev_stop)
7797 abort ();
7798 charpos = it->stop_charpos;
7799 }
7800 while (charpos <= where_we_are);
7801
7802 it->bidi_p = 1;
7803 it->current = save_current;
7804 it->position = save_position;
7805 next_stop = it->stop_charpos;
7806 it->stop_charpos = it->prev_stop;
7807 handle_stop (it);
7808 it->stop_charpos = next_stop;
7809 }
7810
7811 /* Load IT with the next display element from current_buffer. Value
7812 is zero if end of buffer reached. IT->stop_charpos is the next
7813 position at which to stop and check for text properties or buffer
7814 end. */
7815
7816 static int
7817 next_element_from_buffer (struct it *it)
7818 {
7819 int success_p = 1;
7820
7821 xassert (IT_CHARPOS (*it) >= BEGV);
7822 xassert (NILP (it->string) && !it->s);
7823 xassert (!it->bidi_p
7824 || (EQ (it->bidi_it.string.lstring, Qnil)
7825 && it->bidi_it.string.s == NULL));
7826
7827 /* With bidi reordering, the character to display might not be the
7828 character at IT_CHARPOS. BIDI_IT.FIRST_ELT non-zero means that
7829 we were reseat()ed to a new buffer position, which is potentially
7830 a different paragraph. */
7831 if (it->bidi_p && it->bidi_it.first_elt)
7832 {
7833 get_visually_first_element (it);
7834 SET_TEXT_POS (it->position, IT_CHARPOS (*it), IT_BYTEPOS (*it));
7835 }
7836
7837 if (IT_CHARPOS (*it) >= it->stop_charpos)
7838 {
7839 if (IT_CHARPOS (*it) >= it->end_charpos)
7840 {
7841 int overlay_strings_follow_p;
7842
7843 /* End of the game, except when overlay strings follow that
7844 haven't been returned yet. */
7845 if (it->overlay_strings_at_end_processed_p)
7846 overlay_strings_follow_p = 0;
7847 else
7848 {
7849 it->overlay_strings_at_end_processed_p = 1;
7850 overlay_strings_follow_p = get_overlay_strings (it, 0);
7851 }
7852
7853 if (overlay_strings_follow_p)
7854 success_p = GET_NEXT_DISPLAY_ELEMENT (it);
7855 else
7856 {
7857 it->what = IT_EOB;
7858 it->position = it->current.pos;
7859 success_p = 0;
7860 }
7861 }
7862 else if (!(!it->bidi_p
7863 || BIDI_AT_BASE_LEVEL (it->bidi_it)
7864 || IT_CHARPOS (*it) == it->stop_charpos))
7865 {
7866 /* With bidi non-linear iteration, we could find ourselves
7867 far beyond the last computed stop_charpos, with several
7868 other stop positions in between that we missed. Scan
7869 them all now, in buffer's logical order, until we find
7870 and handle the last stop_charpos that precedes our
7871 current position. */
7872 handle_stop_backwards (it, it->stop_charpos);
7873 return GET_NEXT_DISPLAY_ELEMENT (it);
7874 }
7875 else
7876 {
7877 if (it->bidi_p)
7878 {
7879 /* Take note of the stop position we just moved across,
7880 for when we will move back across it. */
7881 it->prev_stop = it->stop_charpos;
7882 /* If we are at base paragraph embedding level, take
7883 note of the last stop position seen at this
7884 level. */
7885 if (BIDI_AT_BASE_LEVEL (it->bidi_it))
7886 it->base_level_stop = it->stop_charpos;
7887 }
7888 handle_stop (it);
7889 return GET_NEXT_DISPLAY_ELEMENT (it);
7890 }
7891 }
7892 else if (it->bidi_p
7893 /* If we are before prev_stop, we may have overstepped on
7894 our way backwards a stop_pos, and if so, we need to
7895 handle that stop_pos. */
7896 && IT_CHARPOS (*it) < it->prev_stop
7897 /* We can sometimes back up for reasons that have nothing
7898 to do with bidi reordering. E.g., compositions. The
7899 code below is only needed when we are above the base
7900 embedding level, so test for that explicitly. */
7901 && !BIDI_AT_BASE_LEVEL (it->bidi_it))
7902 {
7903 if (it->base_level_stop <= 0
7904 || IT_CHARPOS (*it) < it->base_level_stop)
7905 {
7906 /* If we lost track of base_level_stop, we need to find
7907 prev_stop by looking backwards. This happens, e.g., when
7908 we were reseated to the previous screenful of text by
7909 vertical-motion. */
7910 it->base_level_stop = BEGV;
7911 compute_stop_pos_backwards (it);
7912 handle_stop_backwards (it, it->prev_stop);
7913 }
7914 else
7915 handle_stop_backwards (it, it->base_level_stop);
7916 return GET_NEXT_DISPLAY_ELEMENT (it);
7917 }
7918 else
7919 {
7920 /* No face changes, overlays etc. in sight, so just return a
7921 character from current_buffer. */
7922 unsigned char *p;
7923 ptrdiff_t stop;
7924
7925 /* Maybe run the redisplay end trigger hook. Performance note:
7926 This doesn't seem to cost measurable time. */
7927 if (it->redisplay_end_trigger_charpos
7928 && it->glyph_row
7929 && IT_CHARPOS (*it) >= it->redisplay_end_trigger_charpos)
7930 run_redisplay_end_trigger_hook (it);
7931
7932 stop = it->bidi_it.scan_dir < 0 ? -1 : it->end_charpos;
7933 if (CHAR_COMPOSED_P (it, IT_CHARPOS (*it), IT_BYTEPOS (*it),
7934 stop)
7935 && next_element_from_composition (it))
7936 {
7937 return 1;
7938 }
7939
7940 /* Get the next character, maybe multibyte. */
7941 p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
7942 if (it->multibyte_p && !ASCII_BYTE_P (*p))
7943 it->c = STRING_CHAR_AND_LENGTH (p, it->len);
7944 else
7945 it->c = *p, it->len = 1;
7946
7947 /* Record what we have and where it came from. */
7948 it->what = IT_CHARACTER;
7949 it->object = it->w->buffer;
7950 it->position = it->current.pos;
7951
7952 /* Normally we return the character found above, except when we
7953 really want to return an ellipsis for selective display. */
7954 if (it->selective)
7955 {
7956 if (it->c == '\n')
7957 {
7958 /* A value of selective > 0 means hide lines indented more
7959 than that number of columns. */
7960 if (it->selective > 0
7961 && IT_CHARPOS (*it) + 1 < ZV
7962 && indented_beyond_p (IT_CHARPOS (*it) + 1,
7963 IT_BYTEPOS (*it) + 1,
7964 it->selective))
7965 {
7966 success_p = next_element_from_ellipsis (it);
7967 it->dpvec_char_len = -1;
7968 }
7969 }
7970 else if (it->c == '\r' && it->selective == -1)
7971 {
7972 /* A value of selective == -1 means that everything from the
7973 CR to the end of the line is invisible, with maybe an
7974 ellipsis displayed for it. */
7975 success_p = next_element_from_ellipsis (it);
7976 it->dpvec_char_len = -1;
7977 }
7978 }
7979 }
7980
7981 /* Value is zero if end of buffer reached. */
7982 xassert (!success_p || it->what != IT_CHARACTER || it->len > 0);
7983 return success_p;
7984 }
7985
7986
7987 /* Run the redisplay end trigger hook for IT. */
7988
7989 static void
7990 run_redisplay_end_trigger_hook (struct it *it)
7991 {
7992 Lisp_Object args[3];
7993
7994 /* IT->glyph_row should be non-null, i.e. we should be actually
7995 displaying something, or otherwise we should not run the hook. */
7996 xassert (it->glyph_row);
7997
7998 /* Set up hook arguments. */
7999 args[0] = Qredisplay_end_trigger_functions;
8000 args[1] = it->window;
8001 XSETINT (args[2], it->redisplay_end_trigger_charpos);
8002 it->redisplay_end_trigger_charpos = 0;
8003
8004 /* Since we are *trying* to run these functions, don't try to run
8005 them again, even if they get an error. */
8006 it->w->redisplay_end_trigger = Qnil;
8007 Frun_hook_with_args (3, args);
8008
8009 /* Notice if it changed the face of the character we are on. */
8010 handle_face_prop (it);
8011 }
8012
8013
8014 /* Deliver a composition display element. Unlike the other
8015 next_element_from_XXX, this function is not registered in the array
8016 get_next_element[]. It is called from next_element_from_buffer and
8017 next_element_from_string when necessary. */
8018
8019 static int
8020 next_element_from_composition (struct it *it)
8021 {
8022 it->what = IT_COMPOSITION;
8023 it->len = it->cmp_it.nbytes;
8024 if (STRINGP (it->string))
8025 {
8026 if (it->c < 0)
8027 {
8028 IT_STRING_CHARPOS (*it) += it->cmp_it.nchars;
8029 IT_STRING_BYTEPOS (*it) += it->cmp_it.nbytes;
8030 return 0;
8031 }
8032 it->position = it->current.string_pos;
8033 it->object = it->string;
8034 it->c = composition_update_it (&it->cmp_it, IT_STRING_CHARPOS (*it),
8035 IT_STRING_BYTEPOS (*it), it->string);
8036 }
8037 else
8038 {
8039 if (it->c < 0)
8040 {
8041 IT_CHARPOS (*it) += it->cmp_it.nchars;
8042 IT_BYTEPOS (*it) += it->cmp_it.nbytes;
8043 if (it->bidi_p)
8044 {
8045 if (it->bidi_it.new_paragraph)
8046 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 0);
8047 /* Resync the bidi iterator with IT's new position.
8048 FIXME: this doesn't support bidirectional text. */
8049 while (it->bidi_it.charpos < IT_CHARPOS (*it))
8050 bidi_move_to_visually_next (&it->bidi_it);
8051 }
8052 return 0;
8053 }
8054 it->position = it->current.pos;
8055 it->object = it->w->buffer;
8056 it->c = composition_update_it (&it->cmp_it, IT_CHARPOS (*it),
8057 IT_BYTEPOS (*it), Qnil);
8058 }
8059 return 1;
8060 }
8061
8062
8063 \f
8064 /***********************************************************************
8065 Moving an iterator without producing glyphs
8066 ***********************************************************************/
8067
8068 /* Check if iterator is at a position corresponding to a valid buffer
8069 position after some move_it_ call. */
8070
8071 #define IT_POS_VALID_AFTER_MOVE_P(it) \
8072 ((it)->method == GET_FROM_STRING \
8073 ? IT_STRING_CHARPOS (*it) == 0 \
8074 : 1)
8075
8076
8077 /* Move iterator IT to a specified buffer or X position within one
8078 line on the display without producing glyphs.
8079
8080 OP should be a bit mask including some or all of these bits:
8081 MOVE_TO_X: Stop upon reaching x-position TO_X.
8082 MOVE_TO_POS: Stop upon reaching buffer or string position TO_CHARPOS.
8083 Regardless of OP's value, stop upon reaching the end of the display line.
8084
8085 TO_X is normally a value 0 <= TO_X <= IT->last_visible_x.
8086 This means, in particular, that TO_X includes window's horizontal
8087 scroll amount.
8088
8089 The return value has several possible values that
8090 say what condition caused the scan to stop:
8091
8092 MOVE_POS_MATCH_OR_ZV
8093 - when TO_POS or ZV was reached.
8094
8095 MOVE_X_REACHED
8096 -when TO_X was reached before TO_POS or ZV were reached.
8097
8098 MOVE_LINE_CONTINUED
8099 - when we reached the end of the display area and the line must
8100 be continued.
8101
8102 MOVE_LINE_TRUNCATED
8103 - when we reached the end of the display area and the line is
8104 truncated.
8105
8106 MOVE_NEWLINE_OR_CR
8107 - when we stopped at a line end, i.e. a newline or a CR and selective
8108 display is on. */
8109
8110 static enum move_it_result
8111 move_it_in_display_line_to (struct it *it,
8112 ptrdiff_t to_charpos, int to_x,
8113 enum move_operation_enum op)
8114 {
8115 enum move_it_result result = MOVE_UNDEFINED;
8116 struct glyph_row *saved_glyph_row;
8117 struct it wrap_it, atpos_it, atx_it, ppos_it;
8118 void *wrap_data = NULL, *atpos_data = NULL, *atx_data = NULL;
8119 void *ppos_data = NULL;
8120 int may_wrap = 0;
8121 enum it_method prev_method = it->method;
8122 ptrdiff_t prev_pos = IT_CHARPOS (*it);
8123 int saw_smaller_pos = prev_pos < to_charpos;
8124
8125 /* Don't produce glyphs in produce_glyphs. */
8126 saved_glyph_row = it->glyph_row;
8127 it->glyph_row = NULL;
8128
8129 /* Use wrap_it to save a copy of IT wherever a word wrap could
8130 occur. Use atpos_it to save a copy of IT at the desired buffer
8131 position, if found, so that we can scan ahead and check if the
8132 word later overshoots the window edge. Use atx_it similarly, for
8133 pixel positions. */
8134 wrap_it.sp = -1;
8135 atpos_it.sp = -1;
8136 atx_it.sp = -1;
8137
8138 /* Use ppos_it under bidi reordering to save a copy of IT for the
8139 position > CHARPOS that is the closest to CHARPOS. We restore
8140 that position in IT when we have scanned the entire display line
8141 without finding a match for CHARPOS and all the character
8142 positions are greater than CHARPOS. */
8143 if (it->bidi_p)
8144 {
8145 SAVE_IT (ppos_it, *it, ppos_data);
8146 SET_TEXT_POS (ppos_it.current.pos, ZV, ZV_BYTE);
8147 if ((op & MOVE_TO_POS) && IT_CHARPOS (*it) >= to_charpos)
8148 SAVE_IT (ppos_it, *it, ppos_data);
8149 }
8150
8151 #define BUFFER_POS_REACHED_P() \
8152 ((op & MOVE_TO_POS) != 0 \
8153 && BUFFERP (it->object) \
8154 && (IT_CHARPOS (*it) == to_charpos \
8155 || ((!it->bidi_p \
8156 || BIDI_AT_BASE_LEVEL (it->bidi_it)) \
8157 && IT_CHARPOS (*it) > to_charpos) \
8158 || (it->what == IT_COMPOSITION \
8159 && ((IT_CHARPOS (*it) > to_charpos \
8160 && to_charpos >= it->cmp_it.charpos) \
8161 || (IT_CHARPOS (*it) < to_charpos \
8162 && to_charpos <= it->cmp_it.charpos)))) \
8163 && (it->method == GET_FROM_BUFFER \
8164 || (it->method == GET_FROM_DISPLAY_VECTOR \
8165 && it->dpvec + it->current.dpvec_index + 1 >= it->dpend)))
8166
8167 /* If there's a line-/wrap-prefix, handle it. */
8168 if (it->hpos == 0 && it->method == GET_FROM_BUFFER
8169 && it->current_y < it->last_visible_y)
8170 handle_line_prefix (it);
8171
8172 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
8173 SET_TEXT_POS (this_line_min_pos, IT_CHARPOS (*it), IT_BYTEPOS (*it));
8174
8175 while (1)
8176 {
8177 int x, i, ascent = 0, descent = 0;
8178
8179 /* Utility macro to reset an iterator with x, ascent, and descent. */
8180 #define IT_RESET_X_ASCENT_DESCENT(IT) \
8181 ((IT)->current_x = x, (IT)->max_ascent = ascent, \
8182 (IT)->max_descent = descent)
8183
8184 /* Stop if we move beyond TO_CHARPOS (after an image or a
8185 display string or stretch glyph). */
8186 if ((op & MOVE_TO_POS) != 0
8187 && BUFFERP (it->object)
8188 && it->method == GET_FROM_BUFFER
8189 && (((!it->bidi_p
8190 /* When the iterator is at base embedding level, we
8191 are guaranteed that characters are delivered for
8192 display in strictly increasing order of their
8193 buffer positions. */
8194 || BIDI_AT_BASE_LEVEL (it->bidi_it))
8195 && IT_CHARPOS (*it) > to_charpos)
8196 || (it->bidi_p
8197 && (prev_method == GET_FROM_IMAGE
8198 || prev_method == GET_FROM_STRETCH
8199 || prev_method == GET_FROM_STRING)
8200 /* Passed TO_CHARPOS from left to right. */
8201 && ((prev_pos < to_charpos
8202 && IT_CHARPOS (*it) > to_charpos)
8203 /* Passed TO_CHARPOS from right to left. */
8204 || (prev_pos > to_charpos
8205 && IT_CHARPOS (*it) < to_charpos)))))
8206 {
8207 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
8208 {
8209 result = MOVE_POS_MATCH_OR_ZV;
8210 break;
8211 }
8212 else if (it->line_wrap == WORD_WRAP && atpos_it.sp < 0)
8213 /* If wrap_it is valid, the current position might be in a
8214 word that is wrapped. So, save the iterator in
8215 atpos_it and continue to see if wrapping happens. */
8216 SAVE_IT (atpos_it, *it, atpos_data);
8217 }
8218
8219 /* Stop when ZV reached.
8220 We used to stop here when TO_CHARPOS reached as well, but that is
8221 too soon if this glyph does not fit on this line. So we handle it
8222 explicitly below. */
8223 if (!get_next_display_element (it))
8224 {
8225 result = MOVE_POS_MATCH_OR_ZV;
8226 break;
8227 }
8228
8229 if (it->line_wrap == TRUNCATE)
8230 {
8231 if (BUFFER_POS_REACHED_P ())
8232 {
8233 result = MOVE_POS_MATCH_OR_ZV;
8234 break;
8235 }
8236 }
8237 else
8238 {
8239 if (it->line_wrap == WORD_WRAP)
8240 {
8241 if (IT_DISPLAYING_WHITESPACE (it))
8242 may_wrap = 1;
8243 else if (may_wrap)
8244 {
8245 /* We have reached a glyph that follows one or more
8246 whitespace characters. If the position is
8247 already found, we are done. */
8248 if (atpos_it.sp >= 0)
8249 {
8250 RESTORE_IT (it, &atpos_it, atpos_data);
8251 result = MOVE_POS_MATCH_OR_ZV;
8252 goto done;
8253 }
8254 if (atx_it.sp >= 0)
8255 {
8256 RESTORE_IT (it, &atx_it, atx_data);
8257 result = MOVE_X_REACHED;
8258 goto done;
8259 }
8260 /* Otherwise, we can wrap here. */
8261 SAVE_IT (wrap_it, *it, wrap_data);
8262 may_wrap = 0;
8263 }
8264 }
8265 }
8266
8267 /* Remember the line height for the current line, in case
8268 the next element doesn't fit on the line. */
8269 ascent = it->max_ascent;
8270 descent = it->max_descent;
8271
8272 /* The call to produce_glyphs will get the metrics of the
8273 display element IT is loaded with. Record the x-position
8274 before this display element, in case it doesn't fit on the
8275 line. */
8276 x = it->current_x;
8277
8278 PRODUCE_GLYPHS (it);
8279
8280 if (it->area != TEXT_AREA)
8281 {
8282 prev_method = it->method;
8283 if (it->method == GET_FROM_BUFFER)
8284 prev_pos = IT_CHARPOS (*it);
8285 set_iterator_to_next (it, 1);
8286 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
8287 SET_TEXT_POS (this_line_min_pos,
8288 IT_CHARPOS (*it), IT_BYTEPOS (*it));
8289 if (it->bidi_p
8290 && (op & MOVE_TO_POS)
8291 && IT_CHARPOS (*it) > to_charpos
8292 && IT_CHARPOS (*it) < IT_CHARPOS (ppos_it))
8293 SAVE_IT (ppos_it, *it, ppos_data);
8294 continue;
8295 }
8296
8297 /* The number of glyphs we get back in IT->nglyphs will normally
8298 be 1 except when IT->c is (i) a TAB, or (ii) a multi-glyph
8299 character on a terminal frame, or (iii) a line end. For the
8300 second case, IT->nglyphs - 1 padding glyphs will be present.
8301 (On X frames, there is only one glyph produced for a
8302 composite character.)
8303
8304 The behavior implemented below means, for continuation lines,
8305 that as many spaces of a TAB as fit on the current line are
8306 displayed there. For terminal frames, as many glyphs of a
8307 multi-glyph character are displayed in the current line, too.
8308 This is what the old redisplay code did, and we keep it that
8309 way. Under X, the whole shape of a complex character must
8310 fit on the line or it will be completely displayed in the
8311 next line.
8312
8313 Note that both for tabs and padding glyphs, all glyphs have
8314 the same width. */
8315 if (it->nglyphs)
8316 {
8317 /* More than one glyph or glyph doesn't fit on line. All
8318 glyphs have the same width. */
8319 int single_glyph_width = it->pixel_width / it->nglyphs;
8320 int new_x;
8321 int x_before_this_char = x;
8322 int hpos_before_this_char = it->hpos;
8323
8324 for (i = 0; i < it->nglyphs; ++i, x = new_x)
8325 {
8326 new_x = x + single_glyph_width;
8327
8328 /* We want to leave anything reaching TO_X to the caller. */
8329 if ((op & MOVE_TO_X) && new_x > to_x)
8330 {
8331 if (BUFFER_POS_REACHED_P ())
8332 {
8333 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
8334 goto buffer_pos_reached;
8335 if (atpos_it.sp < 0)
8336 {
8337 SAVE_IT (atpos_it, *it, atpos_data);
8338 IT_RESET_X_ASCENT_DESCENT (&atpos_it);
8339 }
8340 }
8341 else
8342 {
8343 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
8344 {
8345 it->current_x = x;
8346 result = MOVE_X_REACHED;
8347 break;
8348 }
8349 if (atx_it.sp < 0)
8350 {
8351 SAVE_IT (atx_it, *it, atx_data);
8352 IT_RESET_X_ASCENT_DESCENT (&atx_it);
8353 }
8354 }
8355 }
8356
8357 if (/* Lines are continued. */
8358 it->line_wrap != TRUNCATE
8359 && (/* And glyph doesn't fit on the line. */
8360 new_x > it->last_visible_x
8361 /* Or it fits exactly and we're on a window
8362 system frame. */
8363 || (new_x == it->last_visible_x
8364 && FRAME_WINDOW_P (it->f))))
8365 {
8366 if (/* IT->hpos == 0 means the very first glyph
8367 doesn't fit on the line, e.g. a wide image. */
8368 it->hpos == 0
8369 || (new_x == it->last_visible_x
8370 && FRAME_WINDOW_P (it->f)))
8371 {
8372 ++it->hpos;
8373 it->current_x = new_x;
8374
8375 /* The character's last glyph just barely fits
8376 in this row. */
8377 if (i == it->nglyphs - 1)
8378 {
8379 /* If this is the destination position,
8380 return a position *before* it in this row,
8381 now that we know it fits in this row. */
8382 if (BUFFER_POS_REACHED_P ())
8383 {
8384 if (it->line_wrap != WORD_WRAP
8385 || wrap_it.sp < 0)
8386 {
8387 it->hpos = hpos_before_this_char;
8388 it->current_x = x_before_this_char;
8389 result = MOVE_POS_MATCH_OR_ZV;
8390 break;
8391 }
8392 if (it->line_wrap == WORD_WRAP
8393 && atpos_it.sp < 0)
8394 {
8395 SAVE_IT (atpos_it, *it, atpos_data);
8396 atpos_it.current_x = x_before_this_char;
8397 atpos_it.hpos = hpos_before_this_char;
8398 }
8399 }
8400
8401 prev_method = it->method;
8402 if (it->method == GET_FROM_BUFFER)
8403 prev_pos = IT_CHARPOS (*it);
8404 set_iterator_to_next (it, 1);
8405 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
8406 SET_TEXT_POS (this_line_min_pos,
8407 IT_CHARPOS (*it), IT_BYTEPOS (*it));
8408 /* On graphical terminals, newlines may
8409 "overflow" into the fringe if
8410 overflow-newline-into-fringe is non-nil.
8411 On text-only terminals, newlines may
8412 overflow into the last glyph on the
8413 display line.*/
8414 if (!FRAME_WINDOW_P (it->f)
8415 || IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
8416 {
8417 if (!get_next_display_element (it))
8418 {
8419 result = MOVE_POS_MATCH_OR_ZV;
8420 break;
8421 }
8422 if (BUFFER_POS_REACHED_P ())
8423 {
8424 if (ITERATOR_AT_END_OF_LINE_P (it))
8425 result = MOVE_POS_MATCH_OR_ZV;
8426 else
8427 result = MOVE_LINE_CONTINUED;
8428 break;
8429 }
8430 if (ITERATOR_AT_END_OF_LINE_P (it))
8431 {
8432 result = MOVE_NEWLINE_OR_CR;
8433 break;
8434 }
8435 }
8436 }
8437 }
8438 else
8439 IT_RESET_X_ASCENT_DESCENT (it);
8440
8441 if (wrap_it.sp >= 0)
8442 {
8443 RESTORE_IT (it, &wrap_it, wrap_data);
8444 atpos_it.sp = -1;
8445 atx_it.sp = -1;
8446 }
8447
8448 TRACE_MOVE ((stderr, "move_it_in: continued at %d\n",
8449 IT_CHARPOS (*it)));
8450 result = MOVE_LINE_CONTINUED;
8451 break;
8452 }
8453
8454 if (BUFFER_POS_REACHED_P ())
8455 {
8456 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
8457 goto buffer_pos_reached;
8458 if (it->line_wrap == WORD_WRAP && atpos_it.sp < 0)
8459 {
8460 SAVE_IT (atpos_it, *it, atpos_data);
8461 IT_RESET_X_ASCENT_DESCENT (&atpos_it);
8462 }
8463 }
8464
8465 if (new_x > it->first_visible_x)
8466 {
8467 /* Glyph is visible. Increment number of glyphs that
8468 would be displayed. */
8469 ++it->hpos;
8470 }
8471 }
8472
8473 if (result != MOVE_UNDEFINED)
8474 break;
8475 }
8476 else if (BUFFER_POS_REACHED_P ())
8477 {
8478 buffer_pos_reached:
8479 IT_RESET_X_ASCENT_DESCENT (it);
8480 result = MOVE_POS_MATCH_OR_ZV;
8481 break;
8482 }
8483 else if ((op & MOVE_TO_X) && it->current_x >= to_x)
8484 {
8485 /* Stop when TO_X specified and reached. This check is
8486 necessary here because of lines consisting of a line end,
8487 only. The line end will not produce any glyphs and we
8488 would never get MOVE_X_REACHED. */
8489 xassert (it->nglyphs == 0);
8490 result = MOVE_X_REACHED;
8491 break;
8492 }
8493
8494 /* Is this a line end? If yes, we're done. */
8495 if (ITERATOR_AT_END_OF_LINE_P (it))
8496 {
8497 /* If we are past TO_CHARPOS, but never saw any character
8498 positions smaller than TO_CHARPOS, return
8499 MOVE_POS_MATCH_OR_ZV, like the unidirectional display
8500 did. */
8501 if (it->bidi_p && (op & MOVE_TO_POS) != 0)
8502 {
8503 if (!saw_smaller_pos && IT_CHARPOS (*it) > to_charpos)
8504 {
8505 if (IT_CHARPOS (ppos_it) < ZV)
8506 {
8507 RESTORE_IT (it, &ppos_it, ppos_data);
8508 result = MOVE_POS_MATCH_OR_ZV;
8509 }
8510 else
8511 goto buffer_pos_reached;
8512 }
8513 else if (it->line_wrap == WORD_WRAP && atpos_it.sp >= 0
8514 && IT_CHARPOS (*it) > to_charpos)
8515 goto buffer_pos_reached;
8516 else
8517 result = MOVE_NEWLINE_OR_CR;
8518 }
8519 else
8520 result = MOVE_NEWLINE_OR_CR;
8521 break;
8522 }
8523
8524 prev_method = it->method;
8525 if (it->method == GET_FROM_BUFFER)
8526 prev_pos = IT_CHARPOS (*it);
8527 /* The current display element has been consumed. Advance
8528 to the next. */
8529 set_iterator_to_next (it, 1);
8530 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
8531 SET_TEXT_POS (this_line_min_pos, IT_CHARPOS (*it), IT_BYTEPOS (*it));
8532 if (IT_CHARPOS (*it) < to_charpos)
8533 saw_smaller_pos = 1;
8534 if (it->bidi_p
8535 && (op & MOVE_TO_POS)
8536 && IT_CHARPOS (*it) >= to_charpos
8537 && IT_CHARPOS (*it) < IT_CHARPOS (ppos_it))
8538 SAVE_IT (ppos_it, *it, ppos_data);
8539
8540 /* Stop if lines are truncated and IT's current x-position is
8541 past the right edge of the window now. */
8542 if (it->line_wrap == TRUNCATE
8543 && it->current_x >= it->last_visible_x)
8544 {
8545 if (!FRAME_WINDOW_P (it->f)
8546 || IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
8547 {
8548 int at_eob_p = 0;
8549
8550 if ((at_eob_p = !get_next_display_element (it))
8551 || BUFFER_POS_REACHED_P ()
8552 /* If we are past TO_CHARPOS, but never saw any
8553 character positions smaller than TO_CHARPOS,
8554 return MOVE_POS_MATCH_OR_ZV, like the
8555 unidirectional display did. */
8556 || (it->bidi_p && (op & MOVE_TO_POS) != 0
8557 && !saw_smaller_pos
8558 && IT_CHARPOS (*it) > to_charpos))
8559 {
8560 if (it->bidi_p
8561 && !at_eob_p && IT_CHARPOS (ppos_it) < ZV)
8562 RESTORE_IT (it, &ppos_it, ppos_data);
8563 result = MOVE_POS_MATCH_OR_ZV;
8564 break;
8565 }
8566 if (ITERATOR_AT_END_OF_LINE_P (it))
8567 {
8568 result = MOVE_NEWLINE_OR_CR;
8569 break;
8570 }
8571 }
8572 else if (it->bidi_p && (op & MOVE_TO_POS) != 0
8573 && !saw_smaller_pos
8574 && IT_CHARPOS (*it) > to_charpos)
8575 {
8576 if (IT_CHARPOS (ppos_it) < ZV)
8577 RESTORE_IT (it, &ppos_it, ppos_data);
8578 result = MOVE_POS_MATCH_OR_ZV;
8579 break;
8580 }
8581 result = MOVE_LINE_TRUNCATED;
8582 break;
8583 }
8584 #undef IT_RESET_X_ASCENT_DESCENT
8585 }
8586
8587 #undef BUFFER_POS_REACHED_P
8588
8589 /* If we scanned beyond to_pos and didn't find a point to wrap at,
8590 restore the saved iterator. */
8591 if (atpos_it.sp >= 0)
8592 RESTORE_IT (it, &atpos_it, atpos_data);
8593 else if (atx_it.sp >= 0)
8594 RESTORE_IT (it, &atx_it, atx_data);
8595
8596 done:
8597
8598 if (atpos_data)
8599 bidi_unshelve_cache (atpos_data, 1);
8600 if (atx_data)
8601 bidi_unshelve_cache (atx_data, 1);
8602 if (wrap_data)
8603 bidi_unshelve_cache (wrap_data, 1);
8604 if (ppos_data)
8605 bidi_unshelve_cache (ppos_data, 1);
8606
8607 /* Restore the iterator settings altered at the beginning of this
8608 function. */
8609 it->glyph_row = saved_glyph_row;
8610 return result;
8611 }
8612
8613 /* For external use. */
8614 void
8615 move_it_in_display_line (struct it *it,
8616 ptrdiff_t to_charpos, int to_x,
8617 enum move_operation_enum op)
8618 {
8619 if (it->line_wrap == WORD_WRAP
8620 && (op & MOVE_TO_X))
8621 {
8622 struct it save_it;
8623 void *save_data = NULL;
8624 int skip;
8625
8626 SAVE_IT (save_it, *it, save_data);
8627 skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
8628 /* When word-wrap is on, TO_X may lie past the end
8629 of a wrapped line. Then it->current is the
8630 character on the next line, so backtrack to the
8631 space before the wrap point. */
8632 if (skip == MOVE_LINE_CONTINUED)
8633 {
8634 int prev_x = max (it->current_x - 1, 0);
8635 RESTORE_IT (it, &save_it, save_data);
8636 move_it_in_display_line_to
8637 (it, -1, prev_x, MOVE_TO_X);
8638 }
8639 else
8640 bidi_unshelve_cache (save_data, 1);
8641 }
8642 else
8643 move_it_in_display_line_to (it, to_charpos, to_x, op);
8644 }
8645
8646
8647 /* Move IT forward until it satisfies one or more of the criteria in
8648 TO_CHARPOS, TO_X, TO_Y, and TO_VPOS.
8649
8650 OP is a bit-mask that specifies where to stop, and in particular,
8651 which of those four position arguments makes a difference. See the
8652 description of enum move_operation_enum.
8653
8654 If TO_CHARPOS is in invisible text, e.g. a truncated part of a
8655 screen line, this function will set IT to the next position that is
8656 displayed to the right of TO_CHARPOS on the screen. */
8657
8658 void
8659 move_it_to (struct it *it, ptrdiff_t to_charpos, int to_x, int to_y, int to_vpos, int op)
8660 {
8661 enum move_it_result skip, skip2 = MOVE_X_REACHED;
8662 int line_height, line_start_x = 0, reached = 0;
8663 void *backup_data = NULL;
8664
8665 for (;;)
8666 {
8667 if (op & MOVE_TO_VPOS)
8668 {
8669 /* If no TO_CHARPOS and no TO_X specified, stop at the
8670 start of the line TO_VPOS. */
8671 if ((op & (MOVE_TO_X | MOVE_TO_POS)) == 0)
8672 {
8673 if (it->vpos == to_vpos)
8674 {
8675 reached = 1;
8676 break;
8677 }
8678 else
8679 skip = move_it_in_display_line_to (it, -1, -1, 0);
8680 }
8681 else
8682 {
8683 /* TO_VPOS >= 0 means stop at TO_X in the line at
8684 TO_VPOS, or at TO_POS, whichever comes first. */
8685 if (it->vpos == to_vpos)
8686 {
8687 reached = 2;
8688 break;
8689 }
8690
8691 skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
8692
8693 if (skip == MOVE_POS_MATCH_OR_ZV || it->vpos == to_vpos)
8694 {
8695 reached = 3;
8696 break;
8697 }
8698 else if (skip == MOVE_X_REACHED && it->vpos != to_vpos)
8699 {
8700 /* We have reached TO_X but not in the line we want. */
8701 skip = move_it_in_display_line_to (it, to_charpos,
8702 -1, MOVE_TO_POS);
8703 if (skip == MOVE_POS_MATCH_OR_ZV)
8704 {
8705 reached = 4;
8706 break;
8707 }
8708 }
8709 }
8710 }
8711 else if (op & MOVE_TO_Y)
8712 {
8713 struct it it_backup;
8714
8715 if (it->line_wrap == WORD_WRAP)
8716 SAVE_IT (it_backup, *it, backup_data);
8717
8718 /* TO_Y specified means stop at TO_X in the line containing
8719 TO_Y---or at TO_CHARPOS if this is reached first. The
8720 problem is that we can't really tell whether the line
8721 contains TO_Y before we have completely scanned it, and
8722 this may skip past TO_X. What we do is to first scan to
8723 TO_X.
8724
8725 If TO_X is not specified, use a TO_X of zero. The reason
8726 is to make the outcome of this function more predictable.
8727 If we didn't use TO_X == 0, we would stop at the end of
8728 the line which is probably not what a caller would expect
8729 to happen. */
8730 skip = move_it_in_display_line_to
8731 (it, to_charpos, ((op & MOVE_TO_X) ? to_x : 0),
8732 (MOVE_TO_X | (op & MOVE_TO_POS)));
8733
8734 /* If TO_CHARPOS is reached or ZV, we don't have to do more. */
8735 if (skip == MOVE_POS_MATCH_OR_ZV)
8736 reached = 5;
8737 else if (skip == MOVE_X_REACHED)
8738 {
8739 /* If TO_X was reached, we want to know whether TO_Y is
8740 in the line. We know this is the case if the already
8741 scanned glyphs make the line tall enough. Otherwise,
8742 we must check by scanning the rest of the line. */
8743 line_height = it->max_ascent + it->max_descent;
8744 if (to_y >= it->current_y
8745 && to_y < it->current_y + line_height)
8746 {
8747 reached = 6;
8748 break;
8749 }
8750 SAVE_IT (it_backup, *it, backup_data);
8751 TRACE_MOVE ((stderr, "move_it: from %d\n", IT_CHARPOS (*it)));
8752 skip2 = move_it_in_display_line_to (it, to_charpos, -1,
8753 op & MOVE_TO_POS);
8754 TRACE_MOVE ((stderr, "move_it: to %d\n", IT_CHARPOS (*it)));
8755 line_height = it->max_ascent + it->max_descent;
8756 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
8757
8758 if (to_y >= it->current_y
8759 && to_y < it->current_y + line_height)
8760 {
8761 /* If TO_Y is in this line and TO_X was reached
8762 above, we scanned too far. We have to restore
8763 IT's settings to the ones before skipping. But
8764 keep the more accurate values of max_ascent and
8765 max_descent we've found while skipping the rest
8766 of the line, for the sake of callers, such as
8767 pos_visible_p, that need to know the line
8768 height. */
8769 int max_ascent = it->max_ascent;
8770 int max_descent = it->max_descent;
8771
8772 RESTORE_IT (it, &it_backup, backup_data);
8773 it->max_ascent = max_ascent;
8774 it->max_descent = max_descent;
8775 reached = 6;
8776 }
8777 else
8778 {
8779 skip = skip2;
8780 if (skip == MOVE_POS_MATCH_OR_ZV)
8781 reached = 7;
8782 }
8783 }
8784 else
8785 {
8786 /* Check whether TO_Y is in this line. */
8787 line_height = it->max_ascent + it->max_descent;
8788 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
8789
8790 if (to_y >= it->current_y
8791 && to_y < it->current_y + line_height)
8792 {
8793 /* When word-wrap is on, TO_X may lie past the end
8794 of a wrapped line. Then it->current is the
8795 character on the next line, so backtrack to the
8796 space before the wrap point. */
8797 if (skip == MOVE_LINE_CONTINUED
8798 && it->line_wrap == WORD_WRAP)
8799 {
8800 int prev_x = max (it->current_x - 1, 0);
8801 RESTORE_IT (it, &it_backup, backup_data);
8802 skip = move_it_in_display_line_to
8803 (it, -1, prev_x, MOVE_TO_X);
8804 }
8805 reached = 6;
8806 }
8807 }
8808
8809 if (reached)
8810 break;
8811 }
8812 else if (BUFFERP (it->object)
8813 && (it->method == GET_FROM_BUFFER
8814 || it->method == GET_FROM_STRETCH)
8815 && IT_CHARPOS (*it) >= to_charpos
8816 /* Under bidi iteration, a call to set_iterator_to_next
8817 can scan far beyond to_charpos if the initial
8818 portion of the next line needs to be reordered. In
8819 that case, give move_it_in_display_line_to another
8820 chance below. */
8821 && !(it->bidi_p
8822 && it->bidi_it.scan_dir == -1))
8823 skip = MOVE_POS_MATCH_OR_ZV;
8824 else
8825 skip = move_it_in_display_line_to (it, to_charpos, -1, MOVE_TO_POS);
8826
8827 switch (skip)
8828 {
8829 case MOVE_POS_MATCH_OR_ZV:
8830 reached = 8;
8831 goto out;
8832
8833 case MOVE_NEWLINE_OR_CR:
8834 set_iterator_to_next (it, 1);
8835 it->continuation_lines_width = 0;
8836 break;
8837
8838 case MOVE_LINE_TRUNCATED:
8839 it->continuation_lines_width = 0;
8840 reseat_at_next_visible_line_start (it, 0);
8841 if ((op & MOVE_TO_POS) != 0
8842 && IT_CHARPOS (*it) > to_charpos)
8843 {
8844 reached = 9;
8845 goto out;
8846 }
8847 break;
8848
8849 case MOVE_LINE_CONTINUED:
8850 /* For continued lines ending in a tab, some of the glyphs
8851 associated with the tab are displayed on the current
8852 line. Since it->current_x does not include these glyphs,
8853 we use it->last_visible_x instead. */
8854 if (it->c == '\t')
8855 {
8856 it->continuation_lines_width += it->last_visible_x;
8857 /* When moving by vpos, ensure that the iterator really
8858 advances to the next line (bug#847, bug#969). Fixme:
8859 do we need to do this in other circumstances? */
8860 if (it->current_x != it->last_visible_x
8861 && (op & MOVE_TO_VPOS)
8862 && !(op & (MOVE_TO_X | MOVE_TO_POS)))
8863 {
8864 line_start_x = it->current_x + it->pixel_width
8865 - it->last_visible_x;
8866 set_iterator_to_next (it, 0);
8867 }
8868 }
8869 else
8870 it->continuation_lines_width += it->current_x;
8871 break;
8872
8873 default:
8874 abort ();
8875 }
8876
8877 /* Reset/increment for the next run. */
8878 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
8879 it->current_x = line_start_x;
8880 line_start_x = 0;
8881 it->hpos = 0;
8882 it->current_y += it->max_ascent + it->max_descent;
8883 ++it->vpos;
8884 last_height = it->max_ascent + it->max_descent;
8885 last_max_ascent = it->max_ascent;
8886 it->max_ascent = it->max_descent = 0;
8887 }
8888
8889 out:
8890
8891 /* On text terminals, we may stop at the end of a line in the middle
8892 of a multi-character glyph. If the glyph itself is continued,
8893 i.e. it is actually displayed on the next line, don't treat this
8894 stopping point as valid; move to the next line instead (unless
8895 that brings us offscreen). */
8896 if (!FRAME_WINDOW_P (it->f)
8897 && op & MOVE_TO_POS
8898 && IT_CHARPOS (*it) == to_charpos
8899 && it->what == IT_CHARACTER
8900 && it->nglyphs > 1
8901 && it->line_wrap == WINDOW_WRAP
8902 && it->current_x == it->last_visible_x - 1
8903 && it->c != '\n'
8904 && it->c != '\t'
8905 && it->vpos < XFASTINT (it->w->window_end_vpos))
8906 {
8907 it->continuation_lines_width += it->current_x;
8908 it->current_x = it->hpos = it->max_ascent = it->max_descent = 0;
8909 it->current_y += it->max_ascent + it->max_descent;
8910 ++it->vpos;
8911 last_height = it->max_ascent + it->max_descent;
8912 last_max_ascent = it->max_ascent;
8913 }
8914
8915 if (backup_data)
8916 bidi_unshelve_cache (backup_data, 1);
8917
8918 TRACE_MOVE ((stderr, "move_it_to: reached %d\n", reached));
8919 }
8920
8921
8922 /* Move iterator IT backward by a specified y-distance DY, DY >= 0.
8923
8924 If DY > 0, move IT backward at least that many pixels. DY = 0
8925 means move IT backward to the preceding line start or BEGV. This
8926 function may move over more than DY pixels if IT->current_y - DY
8927 ends up in the middle of a line; in this case IT->current_y will be
8928 set to the top of the line moved to. */
8929
8930 void
8931 move_it_vertically_backward (struct it *it, int dy)
8932 {
8933 int nlines, h;
8934 struct it it2, it3;
8935 void *it2data = NULL, *it3data = NULL;
8936 ptrdiff_t start_pos;
8937
8938 move_further_back:
8939 xassert (dy >= 0);
8940
8941 start_pos = IT_CHARPOS (*it);
8942
8943 /* Estimate how many newlines we must move back. */
8944 nlines = max (1, dy / FRAME_LINE_HEIGHT (it->f));
8945
8946 /* Set the iterator's position that many lines back. */
8947 while (nlines-- && IT_CHARPOS (*it) > BEGV)
8948 back_to_previous_visible_line_start (it);
8949
8950 /* Reseat the iterator here. When moving backward, we don't want
8951 reseat to skip forward over invisible text, set up the iterator
8952 to deliver from overlay strings at the new position etc. So,
8953 use reseat_1 here. */
8954 reseat_1 (it, it->current.pos, 1);
8955
8956 /* We are now surely at a line start. */
8957 it->current_x = it->hpos = 0; /* FIXME: this is incorrect when bidi
8958 reordering is in effect. */
8959 it->continuation_lines_width = 0;
8960
8961 /* Move forward and see what y-distance we moved. First move to the
8962 start of the next line so that we get its height. We need this
8963 height to be able to tell whether we reached the specified
8964 y-distance. */
8965 SAVE_IT (it2, *it, it2data);
8966 it2.max_ascent = it2.max_descent = 0;
8967 do
8968 {
8969 move_it_to (&it2, start_pos, -1, -1, it2.vpos + 1,
8970 MOVE_TO_POS | MOVE_TO_VPOS);
8971 }
8972 while (!(IT_POS_VALID_AFTER_MOVE_P (&it2)
8973 /* If we are in a display string which starts at START_POS,
8974 and that display string includes a newline, and we are
8975 right after that newline (i.e. at the beginning of a
8976 display line), exit the loop, because otherwise we will
8977 infloop, since move_it_to will see that it is already at
8978 START_POS and will not move. */
8979 || (it2.method == GET_FROM_STRING
8980 && IT_CHARPOS (it2) == start_pos
8981 && SREF (it2.string, IT_STRING_BYTEPOS (it2) - 1) == '\n')));
8982 xassert (IT_CHARPOS (*it) >= BEGV);
8983 SAVE_IT (it3, it2, it3data);
8984
8985 move_it_to (&it2, start_pos, -1, -1, -1, MOVE_TO_POS);
8986 xassert (IT_CHARPOS (*it) >= BEGV);
8987 /* H is the actual vertical distance from the position in *IT
8988 and the starting position. */
8989 h = it2.current_y - it->current_y;
8990 /* NLINES is the distance in number of lines. */
8991 nlines = it2.vpos - it->vpos;
8992
8993 /* Correct IT's y and vpos position
8994 so that they are relative to the starting point. */
8995 it->vpos -= nlines;
8996 it->current_y -= h;
8997
8998 if (dy == 0)
8999 {
9000 /* DY == 0 means move to the start of the screen line. The
9001 value of nlines is > 0 if continuation lines were involved,
9002 or if the original IT position was at start of a line. */
9003 RESTORE_IT (it, it, it2data);
9004 if (nlines > 0)
9005 move_it_by_lines (it, nlines);
9006 /* The above code moves us to some position NLINES down,
9007 usually to its first glyph (leftmost in an L2R line), but
9008 that's not necessarily the start of the line, under bidi
9009 reordering. We want to get to the character position
9010 that is immediately after the newline of the previous
9011 line. */
9012 if (it->bidi_p
9013 && !it->continuation_lines_width
9014 && !STRINGP (it->string)
9015 && IT_CHARPOS (*it) > BEGV
9016 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
9017 {
9018 ptrdiff_t nl_pos =
9019 find_next_newline_no_quit (IT_CHARPOS (*it) - 1, -1);
9020
9021 move_it_to (it, nl_pos, -1, -1, -1, MOVE_TO_POS);
9022 }
9023 bidi_unshelve_cache (it3data, 1);
9024 }
9025 else
9026 {
9027 /* The y-position we try to reach, relative to *IT.
9028 Note that H has been subtracted in front of the if-statement. */
9029 int target_y = it->current_y + h - dy;
9030 int y0 = it3.current_y;
9031 int y1;
9032 int line_height;
9033
9034 RESTORE_IT (&it3, &it3, it3data);
9035 y1 = line_bottom_y (&it3);
9036 line_height = y1 - y0;
9037 RESTORE_IT (it, it, it2data);
9038 /* If we did not reach target_y, try to move further backward if
9039 we can. If we moved too far backward, try to move forward. */
9040 if (target_y < it->current_y
9041 /* This is heuristic. In a window that's 3 lines high, with
9042 a line height of 13 pixels each, recentering with point
9043 on the bottom line will try to move -39/2 = 19 pixels
9044 backward. Try to avoid moving into the first line. */
9045 && (it->current_y - target_y
9046 > min (window_box_height (it->w), line_height * 2 / 3))
9047 && IT_CHARPOS (*it) > BEGV)
9048 {
9049 TRACE_MOVE ((stderr, " not far enough -> move_vert %d\n",
9050 target_y - it->current_y));
9051 dy = it->current_y - target_y;
9052 goto move_further_back;
9053 }
9054 else if (target_y >= it->current_y + line_height
9055 && IT_CHARPOS (*it) < ZV)
9056 {
9057 /* Should move forward by at least one line, maybe more.
9058
9059 Note: Calling move_it_by_lines can be expensive on
9060 terminal frames, where compute_motion is used (via
9061 vmotion) to do the job, when there are very long lines
9062 and truncate-lines is nil. That's the reason for
9063 treating terminal frames specially here. */
9064
9065 if (!FRAME_WINDOW_P (it->f))
9066 move_it_vertically (it, target_y - (it->current_y + line_height));
9067 else
9068 {
9069 do
9070 {
9071 move_it_by_lines (it, 1);
9072 }
9073 while (target_y >= line_bottom_y (it) && IT_CHARPOS (*it) < ZV);
9074 }
9075 }
9076 }
9077 }
9078
9079
9080 /* Move IT by a specified amount of pixel lines DY. DY negative means
9081 move backwards. DY = 0 means move to start of screen line. At the
9082 end, IT will be on the start of a screen line. */
9083
9084 void
9085 move_it_vertically (struct it *it, int dy)
9086 {
9087 if (dy <= 0)
9088 move_it_vertically_backward (it, -dy);
9089 else
9090 {
9091 TRACE_MOVE ((stderr, "move_it_v: from %d, %d\n", IT_CHARPOS (*it), dy));
9092 move_it_to (it, ZV, -1, it->current_y + dy, -1,
9093 MOVE_TO_POS | MOVE_TO_Y);
9094 TRACE_MOVE ((stderr, "move_it_v: to %d\n", IT_CHARPOS (*it)));
9095
9096 /* If buffer ends in ZV without a newline, move to the start of
9097 the line to satisfy the post-condition. */
9098 if (IT_CHARPOS (*it) == ZV
9099 && ZV > BEGV
9100 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
9101 move_it_by_lines (it, 0);
9102 }
9103 }
9104
9105
9106 /* Move iterator IT past the end of the text line it is in. */
9107
9108 void
9109 move_it_past_eol (struct it *it)
9110 {
9111 enum move_it_result rc;
9112
9113 rc = move_it_in_display_line_to (it, Z, 0, MOVE_TO_POS);
9114 if (rc == MOVE_NEWLINE_OR_CR)
9115 set_iterator_to_next (it, 0);
9116 }
9117
9118
9119 /* Move IT by a specified number DVPOS of screen lines down. DVPOS
9120 negative means move up. DVPOS == 0 means move to the start of the
9121 screen line.
9122
9123 Optimization idea: If we would know that IT->f doesn't use
9124 a face with proportional font, we could be faster for
9125 truncate-lines nil. */
9126
9127 void
9128 move_it_by_lines (struct it *it, ptrdiff_t dvpos)
9129 {
9130
9131 /* The commented-out optimization uses vmotion on terminals. This
9132 gives bad results, because elements like it->what, on which
9133 callers such as pos_visible_p rely, aren't updated. */
9134 /* struct position pos;
9135 if (!FRAME_WINDOW_P (it->f))
9136 {
9137 struct text_pos textpos;
9138
9139 pos = *vmotion (IT_CHARPOS (*it), dvpos, it->w);
9140 SET_TEXT_POS (textpos, pos.bufpos, pos.bytepos);
9141 reseat (it, textpos, 1);
9142 it->vpos += pos.vpos;
9143 it->current_y += pos.vpos;
9144 }
9145 else */
9146
9147 if (dvpos == 0)
9148 {
9149 /* DVPOS == 0 means move to the start of the screen line. */
9150 move_it_vertically_backward (it, 0);
9151 /* Let next call to line_bottom_y calculate real line height */
9152 last_height = 0;
9153 }
9154 else if (dvpos > 0)
9155 {
9156 move_it_to (it, -1, -1, -1, it->vpos + dvpos, MOVE_TO_VPOS);
9157 if (!IT_POS_VALID_AFTER_MOVE_P (it))
9158 {
9159 /* Only move to the next buffer position if we ended up in a
9160 string from display property, not in an overlay string
9161 (before-string or after-string). That is because the
9162 latter don't conceal the underlying buffer position, so
9163 we can ask to move the iterator to the exact position we
9164 are interested in. Note that, even if we are already at
9165 IT_CHARPOS (*it), the call below is not a no-op, as it
9166 will detect that we are at the end of the string, pop the
9167 iterator, and compute it->current_x and it->hpos
9168 correctly. */
9169 move_it_to (it, IT_CHARPOS (*it) + it->string_from_display_prop_p,
9170 -1, -1, -1, MOVE_TO_POS);
9171 }
9172 }
9173 else
9174 {
9175 struct it it2;
9176 void *it2data = NULL;
9177 ptrdiff_t start_charpos, i;
9178
9179 /* Start at the beginning of the screen line containing IT's
9180 position. This may actually move vertically backwards,
9181 in case of overlays, so adjust dvpos accordingly. */
9182 dvpos += it->vpos;
9183 move_it_vertically_backward (it, 0);
9184 dvpos -= it->vpos;
9185
9186 /* Go back -DVPOS visible lines and reseat the iterator there. */
9187 start_charpos = IT_CHARPOS (*it);
9188 for (i = -dvpos; i > 0 && IT_CHARPOS (*it) > BEGV; --i)
9189 back_to_previous_visible_line_start (it);
9190 reseat (it, it->current.pos, 1);
9191
9192 /* Move further back if we end up in a string or an image. */
9193 while (!IT_POS_VALID_AFTER_MOVE_P (it))
9194 {
9195 /* First try to move to start of display line. */
9196 dvpos += it->vpos;
9197 move_it_vertically_backward (it, 0);
9198 dvpos -= it->vpos;
9199 if (IT_POS_VALID_AFTER_MOVE_P (it))
9200 break;
9201 /* If start of line is still in string or image,
9202 move further back. */
9203 back_to_previous_visible_line_start (it);
9204 reseat (it, it->current.pos, 1);
9205 dvpos--;
9206 }
9207
9208 it->current_x = it->hpos = 0;
9209
9210 /* Above call may have moved too far if continuation lines
9211 are involved. Scan forward and see if it did. */
9212 SAVE_IT (it2, *it, it2data);
9213 it2.vpos = it2.current_y = 0;
9214 move_it_to (&it2, start_charpos, -1, -1, -1, MOVE_TO_POS);
9215 it->vpos -= it2.vpos;
9216 it->current_y -= it2.current_y;
9217 it->current_x = it->hpos = 0;
9218
9219 /* If we moved too far back, move IT some lines forward. */
9220 if (it2.vpos > -dvpos)
9221 {
9222 int delta = it2.vpos + dvpos;
9223
9224 RESTORE_IT (&it2, &it2, it2data);
9225 SAVE_IT (it2, *it, it2data);
9226 move_it_to (it, -1, -1, -1, it->vpos + delta, MOVE_TO_VPOS);
9227 /* Move back again if we got too far ahead. */
9228 if (IT_CHARPOS (*it) >= start_charpos)
9229 RESTORE_IT (it, &it2, it2data);
9230 else
9231 bidi_unshelve_cache (it2data, 1);
9232 }
9233 else
9234 RESTORE_IT (it, it, it2data);
9235 }
9236 }
9237
9238 /* Return 1 if IT points into the middle of a display vector. */
9239
9240 int
9241 in_display_vector_p (struct it *it)
9242 {
9243 return (it->method == GET_FROM_DISPLAY_VECTOR
9244 && it->current.dpvec_index > 0
9245 && it->dpvec + it->current.dpvec_index != it->dpend);
9246 }
9247
9248 \f
9249 /***********************************************************************
9250 Messages
9251 ***********************************************************************/
9252
9253
9254 /* Add a message with format string FORMAT and arguments ARG1 and ARG2
9255 to *Messages*. */
9256
9257 void
9258 add_to_log (const char *format, Lisp_Object arg1, Lisp_Object arg2)
9259 {
9260 Lisp_Object args[3];
9261 Lisp_Object msg, fmt;
9262 char *buffer;
9263 ptrdiff_t len;
9264 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
9265 USE_SAFE_ALLOCA;
9266
9267 /* Do nothing if called asynchronously. Inserting text into
9268 a buffer may call after-change-functions and alike and
9269 that would means running Lisp asynchronously. */
9270 if (handling_signal)
9271 return;
9272
9273 fmt = msg = Qnil;
9274 GCPRO4 (fmt, msg, arg1, arg2);
9275
9276 args[0] = fmt = build_string (format);
9277 args[1] = arg1;
9278 args[2] = arg2;
9279 msg = Fformat (3, args);
9280
9281 len = SBYTES (msg) + 1;
9282 SAFE_ALLOCA (buffer, char *, len);
9283 memcpy (buffer, SDATA (msg), len);
9284
9285 message_dolog (buffer, len - 1, 1, 0);
9286 SAFE_FREE ();
9287
9288 UNGCPRO;
9289 }
9290
9291
9292 /* Output a newline in the *Messages* buffer if "needs" one. */
9293
9294 void
9295 message_log_maybe_newline (void)
9296 {
9297 if (message_log_need_newline)
9298 message_dolog ("", 0, 1, 0);
9299 }
9300
9301
9302 /* Add a string M of length NBYTES to the message log, optionally
9303 terminated with a newline when NLFLAG is non-zero. MULTIBYTE, if
9304 nonzero, means interpret the contents of M as multibyte. This
9305 function calls low-level routines in order to bypass text property
9306 hooks, etc. which might not be safe to run.
9307
9308 This may GC (insert may run before/after change hooks),
9309 so the buffer M must NOT point to a Lisp string. */
9310
9311 void
9312 message_dolog (const char *m, ptrdiff_t nbytes, int nlflag, int multibyte)
9313 {
9314 const unsigned char *msg = (const unsigned char *) m;
9315
9316 if (!NILP (Vmemory_full))
9317 return;
9318
9319 if (!NILP (Vmessage_log_max))
9320 {
9321 struct buffer *oldbuf;
9322 Lisp_Object oldpoint, oldbegv, oldzv;
9323 int old_windows_or_buffers_changed = windows_or_buffers_changed;
9324 ptrdiff_t point_at_end = 0;
9325 ptrdiff_t zv_at_end = 0;
9326 Lisp_Object old_deactivate_mark, tem;
9327 struct gcpro gcpro1;
9328
9329 old_deactivate_mark = Vdeactivate_mark;
9330 oldbuf = current_buffer;
9331 Fset_buffer (Fget_buffer_create (Vmessages_buffer_name));
9332 BVAR (current_buffer, undo_list) = Qt;
9333
9334 oldpoint = message_dolog_marker1;
9335 set_marker_restricted (oldpoint, make_number (PT), Qnil);
9336 oldbegv = message_dolog_marker2;
9337 set_marker_restricted (oldbegv, make_number (BEGV), Qnil);
9338 oldzv = message_dolog_marker3;
9339 set_marker_restricted (oldzv, make_number (ZV), Qnil);
9340 GCPRO1 (old_deactivate_mark);
9341
9342 if (PT == Z)
9343 point_at_end = 1;
9344 if (ZV == Z)
9345 zv_at_end = 1;
9346
9347 BEGV = BEG;
9348 BEGV_BYTE = BEG_BYTE;
9349 ZV = Z;
9350 ZV_BYTE = Z_BYTE;
9351 TEMP_SET_PT_BOTH (Z, Z_BYTE);
9352
9353 /* Insert the string--maybe converting multibyte to single byte
9354 or vice versa, so that all the text fits the buffer. */
9355 if (multibyte
9356 && NILP (BVAR (current_buffer, enable_multibyte_characters)))
9357 {
9358 ptrdiff_t i;
9359 int c, char_bytes;
9360 char work[1];
9361
9362 /* Convert a multibyte string to single-byte
9363 for the *Message* buffer. */
9364 for (i = 0; i < nbytes; i += char_bytes)
9365 {
9366 c = string_char_and_length (msg + i, &char_bytes);
9367 work[0] = (ASCII_CHAR_P (c)
9368 ? c
9369 : multibyte_char_to_unibyte (c));
9370 insert_1_both (work, 1, 1, 1, 0, 0);
9371 }
9372 }
9373 else if (! multibyte
9374 && ! NILP (BVAR (current_buffer, enable_multibyte_characters)))
9375 {
9376 ptrdiff_t i;
9377 int c, char_bytes;
9378 unsigned char str[MAX_MULTIBYTE_LENGTH];
9379 /* Convert a single-byte string to multibyte
9380 for the *Message* buffer. */
9381 for (i = 0; i < nbytes; i++)
9382 {
9383 c = msg[i];
9384 MAKE_CHAR_MULTIBYTE (c);
9385 char_bytes = CHAR_STRING (c, str);
9386 insert_1_both ((char *) str, 1, char_bytes, 1, 0, 0);
9387 }
9388 }
9389 else if (nbytes)
9390 insert_1 (m, nbytes, 1, 0, 0);
9391
9392 if (nlflag)
9393 {
9394 ptrdiff_t this_bol, this_bol_byte, prev_bol, prev_bol_byte;
9395 printmax_t dups;
9396 insert_1 ("\n", 1, 1, 0, 0);
9397
9398 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE, -2, 0);
9399 this_bol = PT;
9400 this_bol_byte = PT_BYTE;
9401
9402 /* See if this line duplicates the previous one.
9403 If so, combine duplicates. */
9404 if (this_bol > BEG)
9405 {
9406 scan_newline (PT, PT_BYTE, BEG, BEG_BYTE, -2, 0);
9407 prev_bol = PT;
9408 prev_bol_byte = PT_BYTE;
9409
9410 dups = message_log_check_duplicate (prev_bol_byte,
9411 this_bol_byte);
9412 if (dups)
9413 {
9414 del_range_both (prev_bol, prev_bol_byte,
9415 this_bol, this_bol_byte, 0);
9416 if (dups > 1)
9417 {
9418 char dupstr[sizeof " [ times]"
9419 + INT_STRLEN_BOUND (printmax_t)];
9420 int duplen;
9421
9422 /* If you change this format, don't forget to also
9423 change message_log_check_duplicate. */
9424 sprintf (dupstr, " [%"pMd" times]", dups);
9425 duplen = strlen (dupstr);
9426 TEMP_SET_PT_BOTH (Z - 1, Z_BYTE - 1);
9427 insert_1 (dupstr, duplen, 1, 0, 1);
9428 }
9429 }
9430 }
9431
9432 /* If we have more than the desired maximum number of lines
9433 in the *Messages* buffer now, delete the oldest ones.
9434 This is safe because we don't have undo in this buffer. */
9435
9436 if (NATNUMP (Vmessage_log_max))
9437 {
9438 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE,
9439 -XFASTINT (Vmessage_log_max) - 1, 0);
9440 del_range_both (BEG, BEG_BYTE, PT, PT_BYTE, 0);
9441 }
9442 }
9443 BEGV = XMARKER (oldbegv)->charpos;
9444 BEGV_BYTE = marker_byte_position (oldbegv);
9445
9446 if (zv_at_end)
9447 {
9448 ZV = Z;
9449 ZV_BYTE = Z_BYTE;
9450 }
9451 else
9452 {
9453 ZV = XMARKER (oldzv)->charpos;
9454 ZV_BYTE = marker_byte_position (oldzv);
9455 }
9456
9457 if (point_at_end)
9458 TEMP_SET_PT_BOTH (Z, Z_BYTE);
9459 else
9460 /* We can't do Fgoto_char (oldpoint) because it will run some
9461 Lisp code. */
9462 TEMP_SET_PT_BOTH (XMARKER (oldpoint)->charpos,
9463 XMARKER (oldpoint)->bytepos);
9464
9465 UNGCPRO;
9466 unchain_marker (XMARKER (oldpoint));
9467 unchain_marker (XMARKER (oldbegv));
9468 unchain_marker (XMARKER (oldzv));
9469
9470 tem = Fget_buffer_window (Fcurrent_buffer (), Qt);
9471 set_buffer_internal (oldbuf);
9472 if (NILP (tem))
9473 windows_or_buffers_changed = old_windows_or_buffers_changed;
9474 message_log_need_newline = !nlflag;
9475 Vdeactivate_mark = old_deactivate_mark;
9476 }
9477 }
9478
9479
9480 /* We are at the end of the buffer after just having inserted a newline.
9481 (Note: We depend on the fact we won't be crossing the gap.)
9482 Check to see if the most recent message looks a lot like the previous one.
9483 Return 0 if different, 1 if the new one should just replace it, or a
9484 value N > 1 if we should also append " [N times]". */
9485
9486 static intmax_t
9487 message_log_check_duplicate (ptrdiff_t prev_bol_byte, ptrdiff_t this_bol_byte)
9488 {
9489 ptrdiff_t i;
9490 ptrdiff_t len = Z_BYTE - 1 - this_bol_byte;
9491 int seen_dots = 0;
9492 unsigned char *p1 = BUF_BYTE_ADDRESS (current_buffer, prev_bol_byte);
9493 unsigned char *p2 = BUF_BYTE_ADDRESS (current_buffer, this_bol_byte);
9494
9495 for (i = 0; i < len; i++)
9496 {
9497 if (i >= 3 && p1[i-3] == '.' && p1[i-2] == '.' && p1[i-1] == '.')
9498 seen_dots = 1;
9499 if (p1[i] != p2[i])
9500 return seen_dots;
9501 }
9502 p1 += len;
9503 if (*p1 == '\n')
9504 return 2;
9505 if (*p1++ == ' ' && *p1++ == '[')
9506 {
9507 char *pend;
9508 intmax_t n = strtoimax ((char *) p1, &pend, 10);
9509 if (0 < n && n < INTMAX_MAX && strncmp (pend, " times]\n", 8) == 0)
9510 return n+1;
9511 }
9512 return 0;
9513 }
9514 \f
9515
9516 /* Display an echo area message M with a specified length of NBYTES
9517 bytes. The string may include null characters. If M is 0, clear
9518 out any existing message, and let the mini-buffer text show
9519 through.
9520
9521 This may GC, so the buffer M must NOT point to a Lisp string. */
9522
9523 void
9524 message2 (const char *m, ptrdiff_t nbytes, int multibyte)
9525 {
9526 /* First flush out any partial line written with print. */
9527 message_log_maybe_newline ();
9528 if (m)
9529 message_dolog (m, nbytes, 1, multibyte);
9530 message2_nolog (m, nbytes, multibyte);
9531 }
9532
9533
9534 /* The non-logging counterpart of message2. */
9535
9536 void
9537 message2_nolog (const char *m, ptrdiff_t nbytes, int multibyte)
9538 {
9539 struct frame *sf = SELECTED_FRAME ();
9540 message_enable_multibyte = multibyte;
9541
9542 if (FRAME_INITIAL_P (sf))
9543 {
9544 if (noninteractive_need_newline)
9545 putc ('\n', stderr);
9546 noninteractive_need_newline = 0;
9547 if (m)
9548 fwrite (m, nbytes, 1, stderr);
9549 if (cursor_in_echo_area == 0)
9550 fprintf (stderr, "\n");
9551 fflush (stderr);
9552 }
9553 /* A null message buffer means that the frame hasn't really been
9554 initialized yet. Error messages get reported properly by
9555 cmd_error, so this must be just an informative message; toss it. */
9556 else if (INTERACTIVE
9557 && sf->glyphs_initialized_p
9558 && FRAME_MESSAGE_BUF (sf))
9559 {
9560 Lisp_Object mini_window;
9561 struct frame *f;
9562
9563 /* Get the frame containing the mini-buffer
9564 that the selected frame is using. */
9565 mini_window = FRAME_MINIBUF_WINDOW (sf);
9566 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
9567
9568 FRAME_SAMPLE_VISIBILITY (f);
9569 if (FRAME_VISIBLE_P (sf)
9570 && ! FRAME_VISIBLE_P (f))
9571 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (mini_window)));
9572
9573 if (m)
9574 {
9575 set_message (m, Qnil, nbytes, multibyte);
9576 if (minibuffer_auto_raise)
9577 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
9578 }
9579 else
9580 clear_message (1, 1);
9581
9582 do_pending_window_change (0);
9583 echo_area_display (1);
9584 do_pending_window_change (0);
9585 if (FRAME_TERMINAL (f)->frame_up_to_date_hook != 0 && ! gc_in_progress)
9586 (*FRAME_TERMINAL (f)->frame_up_to_date_hook) (f);
9587 }
9588 }
9589
9590
9591 /* Display an echo area message M with a specified length of NBYTES
9592 bytes. The string may include null characters. If M is not a
9593 string, clear out any existing message, and let the mini-buffer
9594 text show through.
9595
9596 This function cancels echoing. */
9597
9598 void
9599 message3 (Lisp_Object m, ptrdiff_t nbytes, int multibyte)
9600 {
9601 struct gcpro gcpro1;
9602
9603 GCPRO1 (m);
9604 clear_message (1,1);
9605 cancel_echoing ();
9606
9607 /* First flush out any partial line written with print. */
9608 message_log_maybe_newline ();
9609 if (STRINGP (m))
9610 {
9611 char *buffer;
9612 USE_SAFE_ALLOCA;
9613
9614 SAFE_ALLOCA (buffer, char *, nbytes);
9615 memcpy (buffer, SDATA (m), nbytes);
9616 message_dolog (buffer, nbytes, 1, multibyte);
9617 SAFE_FREE ();
9618 }
9619 message3_nolog (m, nbytes, multibyte);
9620
9621 UNGCPRO;
9622 }
9623
9624
9625 /* The non-logging version of message3.
9626 This does not cancel echoing, because it is used for echoing.
9627 Perhaps we need to make a separate function for echoing
9628 and make this cancel echoing. */
9629
9630 void
9631 message3_nolog (Lisp_Object m, ptrdiff_t nbytes, int multibyte)
9632 {
9633 struct frame *sf = SELECTED_FRAME ();
9634 message_enable_multibyte = multibyte;
9635
9636 if (FRAME_INITIAL_P (sf))
9637 {
9638 if (noninteractive_need_newline)
9639 putc ('\n', stderr);
9640 noninteractive_need_newline = 0;
9641 if (STRINGP (m))
9642 fwrite (SDATA (m), nbytes, 1, stderr);
9643 if (cursor_in_echo_area == 0)
9644 fprintf (stderr, "\n");
9645 fflush (stderr);
9646 }
9647 /* A null message buffer means that the frame hasn't really been
9648 initialized yet. Error messages get reported properly by
9649 cmd_error, so this must be just an informative message; toss it. */
9650 else if (INTERACTIVE
9651 && sf->glyphs_initialized_p
9652 && FRAME_MESSAGE_BUF (sf))
9653 {
9654 Lisp_Object mini_window;
9655 Lisp_Object frame;
9656 struct frame *f;
9657
9658 /* Get the frame containing the mini-buffer
9659 that the selected frame is using. */
9660 mini_window = FRAME_MINIBUF_WINDOW (sf);
9661 frame = XWINDOW (mini_window)->frame;
9662 f = XFRAME (frame);
9663
9664 FRAME_SAMPLE_VISIBILITY (f);
9665 if (FRAME_VISIBLE_P (sf)
9666 && !FRAME_VISIBLE_P (f))
9667 Fmake_frame_visible (frame);
9668
9669 if (STRINGP (m) && SCHARS (m) > 0)
9670 {
9671 set_message (NULL, m, nbytes, multibyte);
9672 if (minibuffer_auto_raise)
9673 Fraise_frame (frame);
9674 /* Assume we are not echoing.
9675 (If we are, echo_now will override this.) */
9676 echo_message_buffer = Qnil;
9677 }
9678 else
9679 clear_message (1, 1);
9680
9681 do_pending_window_change (0);
9682 echo_area_display (1);
9683 do_pending_window_change (0);
9684 if (FRAME_TERMINAL (f)->frame_up_to_date_hook != 0 && ! gc_in_progress)
9685 (*FRAME_TERMINAL (f)->frame_up_to_date_hook) (f);
9686 }
9687 }
9688
9689
9690 /* Display a null-terminated echo area message M. If M is 0, clear
9691 out any existing message, and let the mini-buffer text show through.
9692
9693 The buffer M must continue to exist until after the echo area gets
9694 cleared or some other message gets displayed there. Do not pass
9695 text that is stored in a Lisp string. Do not pass text in a buffer
9696 that was alloca'd. */
9697
9698 void
9699 message1 (const char *m)
9700 {
9701 message2 (m, (m ? strlen (m) : 0), 0);
9702 }
9703
9704
9705 /* The non-logging counterpart of message1. */
9706
9707 void
9708 message1_nolog (const char *m)
9709 {
9710 message2_nolog (m, (m ? strlen (m) : 0), 0);
9711 }
9712
9713 /* Display a message M which contains a single %s
9714 which gets replaced with STRING. */
9715
9716 void
9717 message_with_string (const char *m, Lisp_Object string, int log)
9718 {
9719 CHECK_STRING (string);
9720
9721 if (noninteractive)
9722 {
9723 if (m)
9724 {
9725 if (noninteractive_need_newline)
9726 putc ('\n', stderr);
9727 noninteractive_need_newline = 0;
9728 fprintf (stderr, m, SDATA (string));
9729 if (!cursor_in_echo_area)
9730 fprintf (stderr, "\n");
9731 fflush (stderr);
9732 }
9733 }
9734 else if (INTERACTIVE)
9735 {
9736 /* The frame whose minibuffer we're going to display the message on.
9737 It may be larger than the selected frame, so we need
9738 to use its buffer, not the selected frame's buffer. */
9739 Lisp_Object mini_window;
9740 struct frame *f, *sf = SELECTED_FRAME ();
9741
9742 /* Get the frame containing the minibuffer
9743 that the selected frame is using. */
9744 mini_window = FRAME_MINIBUF_WINDOW (sf);
9745 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
9746
9747 /* A null message buffer means that the frame hasn't really been
9748 initialized yet. Error messages get reported properly by
9749 cmd_error, so this must be just an informative message; toss it. */
9750 if (FRAME_MESSAGE_BUF (f))
9751 {
9752 Lisp_Object args[2], msg;
9753 struct gcpro gcpro1, gcpro2;
9754
9755 args[0] = build_string (m);
9756 args[1] = msg = string;
9757 GCPRO2 (args[0], msg);
9758 gcpro1.nvars = 2;
9759
9760 msg = Fformat (2, args);
9761
9762 if (log)
9763 message3 (msg, SBYTES (msg), STRING_MULTIBYTE (msg));
9764 else
9765 message3_nolog (msg, SBYTES (msg), STRING_MULTIBYTE (msg));
9766
9767 UNGCPRO;
9768
9769 /* Print should start at the beginning of the message
9770 buffer next time. */
9771 message_buf_print = 0;
9772 }
9773 }
9774 }
9775
9776
9777 /* Dump an informative message to the minibuf. If M is 0, clear out
9778 any existing message, and let the mini-buffer text show through. */
9779
9780 static void
9781 vmessage (const char *m, va_list ap)
9782 {
9783 if (noninteractive)
9784 {
9785 if (m)
9786 {
9787 if (noninteractive_need_newline)
9788 putc ('\n', stderr);
9789 noninteractive_need_newline = 0;
9790 vfprintf (stderr, m, ap);
9791 if (cursor_in_echo_area == 0)
9792 fprintf (stderr, "\n");
9793 fflush (stderr);
9794 }
9795 }
9796 else if (INTERACTIVE)
9797 {
9798 /* The frame whose mini-buffer we're going to display the message
9799 on. It may be larger than the selected frame, so we need to
9800 use its buffer, not the selected frame's buffer. */
9801 Lisp_Object mini_window;
9802 struct frame *f, *sf = SELECTED_FRAME ();
9803
9804 /* Get the frame containing the mini-buffer
9805 that the selected frame is using. */
9806 mini_window = FRAME_MINIBUF_WINDOW (sf);
9807 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
9808
9809 /* A null message buffer means that the frame hasn't really been
9810 initialized yet. Error messages get reported properly by
9811 cmd_error, so this must be just an informative message; toss
9812 it. */
9813 if (FRAME_MESSAGE_BUF (f))
9814 {
9815 if (m)
9816 {
9817 ptrdiff_t len;
9818
9819 len = doprnt (FRAME_MESSAGE_BUF (f),
9820 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, ap);
9821
9822 message2 (FRAME_MESSAGE_BUF (f), len, 1);
9823 }
9824 else
9825 message1 (0);
9826
9827 /* Print should start at the beginning of the message
9828 buffer next time. */
9829 message_buf_print = 0;
9830 }
9831 }
9832 }
9833
9834 void
9835 message (const char *m, ...)
9836 {
9837 va_list ap;
9838 va_start (ap, m);
9839 vmessage (m, ap);
9840 va_end (ap);
9841 }
9842
9843
9844 #if 0
9845 /* The non-logging version of message. */
9846
9847 void
9848 message_nolog (const char *m, ...)
9849 {
9850 Lisp_Object old_log_max;
9851 va_list ap;
9852 va_start (ap, m);
9853 old_log_max = Vmessage_log_max;
9854 Vmessage_log_max = Qnil;
9855 vmessage (m, ap);
9856 Vmessage_log_max = old_log_max;
9857 va_end (ap);
9858 }
9859 #endif
9860
9861
9862 /* Display the current message in the current mini-buffer. This is
9863 only called from error handlers in process.c, and is not time
9864 critical. */
9865
9866 void
9867 update_echo_area (void)
9868 {
9869 if (!NILP (echo_area_buffer[0]))
9870 {
9871 Lisp_Object string;
9872 string = Fcurrent_message ();
9873 message3 (string, SBYTES (string),
9874 !NILP (BVAR (current_buffer, enable_multibyte_characters)));
9875 }
9876 }
9877
9878
9879 /* Make sure echo area buffers in `echo_buffers' are live.
9880 If they aren't, make new ones. */
9881
9882 static void
9883 ensure_echo_area_buffers (void)
9884 {
9885 int i;
9886
9887 for (i = 0; i < 2; ++i)
9888 if (!BUFFERP (echo_buffer[i])
9889 || NILP (BVAR (XBUFFER (echo_buffer[i]), name)))
9890 {
9891 char name[30];
9892 Lisp_Object old_buffer;
9893 int j;
9894
9895 old_buffer = echo_buffer[i];
9896 sprintf (name, " *Echo Area %d*", i);
9897 echo_buffer[i] = Fget_buffer_create (build_string (name));
9898 BVAR (XBUFFER (echo_buffer[i]), truncate_lines) = Qnil;
9899 /* to force word wrap in echo area -
9900 it was decided to postpone this*/
9901 /* XBUFFER (echo_buffer[i])->word_wrap = Qt; */
9902
9903 for (j = 0; j < 2; ++j)
9904 if (EQ (old_buffer, echo_area_buffer[j]))
9905 echo_area_buffer[j] = echo_buffer[i];
9906 }
9907 }
9908
9909
9910 /* Call FN with args A1..A4 with either the current or last displayed
9911 echo_area_buffer as current buffer.
9912
9913 WHICH zero means use the current message buffer
9914 echo_area_buffer[0]. If that is nil, choose a suitable buffer
9915 from echo_buffer[] and clear it.
9916
9917 WHICH > 0 means use echo_area_buffer[1]. If that is nil, choose a
9918 suitable buffer from echo_buffer[] and clear it.
9919
9920 If WHICH < 0, set echo_area_buffer[1] to echo_area_buffer[0], so
9921 that the current message becomes the last displayed one, make
9922 choose a suitable buffer for echo_area_buffer[0], and clear it.
9923
9924 Value is what FN returns. */
9925
9926 static int
9927 with_echo_area_buffer (struct window *w, int which,
9928 int (*fn) (ptrdiff_t, Lisp_Object, ptrdiff_t, ptrdiff_t),
9929 ptrdiff_t a1, Lisp_Object a2, ptrdiff_t a3, ptrdiff_t a4)
9930 {
9931 Lisp_Object buffer;
9932 int this_one, the_other, clear_buffer_p, rc;
9933 ptrdiff_t count = SPECPDL_INDEX ();
9934
9935 /* If buffers aren't live, make new ones. */
9936 ensure_echo_area_buffers ();
9937
9938 clear_buffer_p = 0;
9939
9940 if (which == 0)
9941 this_one = 0, the_other = 1;
9942 else if (which > 0)
9943 this_one = 1, the_other = 0;
9944 else
9945 {
9946 this_one = 0, the_other = 1;
9947 clear_buffer_p = 1;
9948
9949 /* We need a fresh one in case the current echo buffer equals
9950 the one containing the last displayed echo area message. */
9951 if (!NILP (echo_area_buffer[this_one])
9952 && EQ (echo_area_buffer[this_one], echo_area_buffer[the_other]))
9953 echo_area_buffer[this_one] = Qnil;
9954 }
9955
9956 /* Choose a suitable buffer from echo_buffer[] is we don't
9957 have one. */
9958 if (NILP (echo_area_buffer[this_one]))
9959 {
9960 echo_area_buffer[this_one]
9961 = (EQ (echo_area_buffer[the_other], echo_buffer[this_one])
9962 ? echo_buffer[the_other]
9963 : echo_buffer[this_one]);
9964 clear_buffer_p = 1;
9965 }
9966
9967 buffer = echo_area_buffer[this_one];
9968
9969 /* Don't get confused by reusing the buffer used for echoing
9970 for a different purpose. */
9971 if (echo_kboard == NULL && EQ (buffer, echo_message_buffer))
9972 cancel_echoing ();
9973
9974 record_unwind_protect (unwind_with_echo_area_buffer,
9975 with_echo_area_buffer_unwind_data (w));
9976
9977 /* Make the echo area buffer current. Note that for display
9978 purposes, it is not necessary that the displayed window's buffer
9979 == current_buffer, except for text property lookup. So, let's
9980 only set that buffer temporarily here without doing a full
9981 Fset_window_buffer. We must also change w->pointm, though,
9982 because otherwise an assertions in unshow_buffer fails, and Emacs
9983 aborts. */
9984 set_buffer_internal_1 (XBUFFER (buffer));
9985 if (w)
9986 {
9987 w->buffer = buffer;
9988 set_marker_both (w->pointm, buffer, BEG, BEG_BYTE);
9989 }
9990
9991 BVAR (current_buffer, undo_list) = Qt;
9992 BVAR (current_buffer, read_only) = Qnil;
9993 specbind (Qinhibit_read_only, Qt);
9994 specbind (Qinhibit_modification_hooks, Qt);
9995
9996 if (clear_buffer_p && Z > BEG)
9997 del_range (BEG, Z);
9998
9999 xassert (BEGV >= BEG);
10000 xassert (ZV <= Z && ZV >= BEGV);
10001
10002 rc = fn (a1, a2, a3, a4);
10003
10004 xassert (BEGV >= BEG);
10005 xassert (ZV <= Z && ZV >= BEGV);
10006
10007 unbind_to (count, Qnil);
10008 return rc;
10009 }
10010
10011
10012 /* Save state that should be preserved around the call to the function
10013 FN called in with_echo_area_buffer. */
10014
10015 static Lisp_Object
10016 with_echo_area_buffer_unwind_data (struct window *w)
10017 {
10018 int i = 0;
10019 Lisp_Object vector, tmp;
10020
10021 /* Reduce consing by keeping one vector in
10022 Vwith_echo_area_save_vector. */
10023 vector = Vwith_echo_area_save_vector;
10024 Vwith_echo_area_save_vector = Qnil;
10025
10026 if (NILP (vector))
10027 vector = Fmake_vector (make_number (7), Qnil);
10028
10029 XSETBUFFER (tmp, current_buffer); ASET (vector, i, tmp); ++i;
10030 ASET (vector, i, Vdeactivate_mark); ++i;
10031 ASET (vector, i, make_number (windows_or_buffers_changed)); ++i;
10032
10033 if (w)
10034 {
10035 XSETWINDOW (tmp, w); ASET (vector, i, tmp); ++i;
10036 ASET (vector, i, w->buffer); ++i;
10037 ASET (vector, i, make_number (XMARKER (w->pointm)->charpos)); ++i;
10038 ASET (vector, i, make_number (XMARKER (w->pointm)->bytepos)); ++i;
10039 }
10040 else
10041 {
10042 int end = i + 4;
10043 for (; i < end; ++i)
10044 ASET (vector, i, Qnil);
10045 }
10046
10047 xassert (i == ASIZE (vector));
10048 return vector;
10049 }
10050
10051
10052 /* Restore global state from VECTOR which was created by
10053 with_echo_area_buffer_unwind_data. */
10054
10055 static Lisp_Object
10056 unwind_with_echo_area_buffer (Lisp_Object vector)
10057 {
10058 set_buffer_internal_1 (XBUFFER (AREF (vector, 0)));
10059 Vdeactivate_mark = AREF (vector, 1);
10060 windows_or_buffers_changed = XFASTINT (AREF (vector, 2));
10061
10062 if (WINDOWP (AREF (vector, 3)))
10063 {
10064 struct window *w;
10065 Lisp_Object buffer, charpos, bytepos;
10066
10067 w = XWINDOW (AREF (vector, 3));
10068 buffer = AREF (vector, 4);
10069 charpos = AREF (vector, 5);
10070 bytepos = AREF (vector, 6);
10071
10072 w->buffer = buffer;
10073 set_marker_both (w->pointm, buffer,
10074 XFASTINT (charpos), XFASTINT (bytepos));
10075 }
10076
10077 Vwith_echo_area_save_vector = vector;
10078 return Qnil;
10079 }
10080
10081
10082 /* Set up the echo area for use by print functions. MULTIBYTE_P
10083 non-zero means we will print multibyte. */
10084
10085 void
10086 setup_echo_area_for_printing (int multibyte_p)
10087 {
10088 /* If we can't find an echo area any more, exit. */
10089 if (! FRAME_LIVE_P (XFRAME (selected_frame)))
10090 Fkill_emacs (Qnil);
10091
10092 ensure_echo_area_buffers ();
10093
10094 if (!message_buf_print)
10095 {
10096 /* A message has been output since the last time we printed.
10097 Choose a fresh echo area buffer. */
10098 if (EQ (echo_area_buffer[1], echo_buffer[0]))
10099 echo_area_buffer[0] = echo_buffer[1];
10100 else
10101 echo_area_buffer[0] = echo_buffer[0];
10102
10103 /* Switch to that buffer and clear it. */
10104 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
10105 BVAR (current_buffer, truncate_lines) = Qnil;
10106
10107 if (Z > BEG)
10108 {
10109 ptrdiff_t count = SPECPDL_INDEX ();
10110 specbind (Qinhibit_read_only, Qt);
10111 /* Note that undo recording is always disabled. */
10112 del_range (BEG, Z);
10113 unbind_to (count, Qnil);
10114 }
10115 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
10116
10117 /* Set up the buffer for the multibyteness we need. */
10118 if (multibyte_p
10119 != !NILP (BVAR (current_buffer, enable_multibyte_characters)))
10120 Fset_buffer_multibyte (multibyte_p ? Qt : Qnil);
10121
10122 /* Raise the frame containing the echo area. */
10123 if (minibuffer_auto_raise)
10124 {
10125 struct frame *sf = SELECTED_FRAME ();
10126 Lisp_Object mini_window;
10127 mini_window = FRAME_MINIBUF_WINDOW (sf);
10128 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
10129 }
10130
10131 message_log_maybe_newline ();
10132 message_buf_print = 1;
10133 }
10134 else
10135 {
10136 if (NILP (echo_area_buffer[0]))
10137 {
10138 if (EQ (echo_area_buffer[1], echo_buffer[0]))
10139 echo_area_buffer[0] = echo_buffer[1];
10140 else
10141 echo_area_buffer[0] = echo_buffer[0];
10142 }
10143
10144 if (current_buffer != XBUFFER (echo_area_buffer[0]))
10145 {
10146 /* Someone switched buffers between print requests. */
10147 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
10148 BVAR (current_buffer, truncate_lines) = Qnil;
10149 }
10150 }
10151 }
10152
10153
10154 /* Display an echo area message in window W. Value is non-zero if W's
10155 height is changed. If display_last_displayed_message_p is
10156 non-zero, display the message that was last displayed, otherwise
10157 display the current message. */
10158
10159 static int
10160 display_echo_area (struct window *w)
10161 {
10162 int i, no_message_p, window_height_changed_p;
10163
10164 /* Temporarily disable garbage collections while displaying the echo
10165 area. This is done because a GC can print a message itself.
10166 That message would modify the echo area buffer's contents while a
10167 redisplay of the buffer is going on, and seriously confuse
10168 redisplay. */
10169 ptrdiff_t count = inhibit_garbage_collection ();
10170
10171 /* If there is no message, we must call display_echo_area_1
10172 nevertheless because it resizes the window. But we will have to
10173 reset the echo_area_buffer in question to nil at the end because
10174 with_echo_area_buffer will sets it to an empty buffer. */
10175 i = display_last_displayed_message_p ? 1 : 0;
10176 no_message_p = NILP (echo_area_buffer[i]);
10177
10178 window_height_changed_p
10179 = with_echo_area_buffer (w, display_last_displayed_message_p,
10180 display_echo_area_1,
10181 (intptr_t) w, Qnil, 0, 0);
10182
10183 if (no_message_p)
10184 echo_area_buffer[i] = Qnil;
10185
10186 unbind_to (count, Qnil);
10187 return window_height_changed_p;
10188 }
10189
10190
10191 /* Helper for display_echo_area. Display the current buffer which
10192 contains the current echo area message in window W, a mini-window,
10193 a pointer to which is passed in A1. A2..A4 are currently not used.
10194 Change the height of W so that all of the message is displayed.
10195 Value is non-zero if height of W was changed. */
10196
10197 static int
10198 display_echo_area_1 (ptrdiff_t a1, Lisp_Object a2, ptrdiff_t a3, ptrdiff_t a4)
10199 {
10200 intptr_t i1 = a1;
10201 struct window *w = (struct window *) i1;
10202 Lisp_Object window;
10203 struct text_pos start;
10204 int window_height_changed_p = 0;
10205
10206 /* Do this before displaying, so that we have a large enough glyph
10207 matrix for the display. If we can't get enough space for the
10208 whole text, display the last N lines. That works by setting w->start. */
10209 window_height_changed_p = resize_mini_window (w, 0);
10210
10211 /* Use the starting position chosen by resize_mini_window. */
10212 SET_TEXT_POS_FROM_MARKER (start, w->start);
10213
10214 /* Display. */
10215 clear_glyph_matrix (w->desired_matrix);
10216 XSETWINDOW (window, w);
10217 try_window (window, start, 0);
10218
10219 return window_height_changed_p;
10220 }
10221
10222
10223 /* Resize the echo area window to exactly the size needed for the
10224 currently displayed message, if there is one. If a mini-buffer
10225 is active, don't shrink it. */
10226
10227 void
10228 resize_echo_area_exactly (void)
10229 {
10230 if (BUFFERP (echo_area_buffer[0])
10231 && WINDOWP (echo_area_window))
10232 {
10233 struct window *w = XWINDOW (echo_area_window);
10234 int resized_p;
10235 Lisp_Object resize_exactly;
10236
10237 if (minibuf_level == 0)
10238 resize_exactly = Qt;
10239 else
10240 resize_exactly = Qnil;
10241
10242 resized_p = with_echo_area_buffer (w, 0, resize_mini_window_1,
10243 (intptr_t) w, resize_exactly,
10244 0, 0);
10245 if (resized_p)
10246 {
10247 ++windows_or_buffers_changed;
10248 ++update_mode_lines;
10249 redisplay_internal ();
10250 }
10251 }
10252 }
10253
10254
10255 /* Callback function for with_echo_area_buffer, when used from
10256 resize_echo_area_exactly. A1 contains a pointer to the window to
10257 resize, EXACTLY non-nil means resize the mini-window exactly to the
10258 size of the text displayed. A3 and A4 are not used. Value is what
10259 resize_mini_window returns. */
10260
10261 static int
10262 resize_mini_window_1 (ptrdiff_t a1, Lisp_Object exactly, ptrdiff_t a3, ptrdiff_t a4)
10263 {
10264 intptr_t i1 = a1;
10265 return resize_mini_window ((struct window *) i1, !NILP (exactly));
10266 }
10267
10268
10269 /* Resize mini-window W to fit the size of its contents. EXACT_P
10270 means size the window exactly to the size needed. Otherwise, it's
10271 only enlarged until W's buffer is empty.
10272
10273 Set W->start to the right place to begin display. If the whole
10274 contents fit, start at the beginning. Otherwise, start so as
10275 to make the end of the contents appear. This is particularly
10276 important for y-or-n-p, but seems desirable generally.
10277
10278 Value is non-zero if the window height has been changed. */
10279
10280 int
10281 resize_mini_window (struct window *w, int exact_p)
10282 {
10283 struct frame *f = XFRAME (w->frame);
10284 int window_height_changed_p = 0;
10285
10286 xassert (MINI_WINDOW_P (w));
10287
10288 /* By default, start display at the beginning. */
10289 set_marker_both (w->start, w->buffer,
10290 BUF_BEGV (XBUFFER (w->buffer)),
10291 BUF_BEGV_BYTE (XBUFFER (w->buffer)));
10292
10293 /* Don't resize windows while redisplaying a window; it would
10294 confuse redisplay functions when the size of the window they are
10295 displaying changes from under them. Such a resizing can happen,
10296 for instance, when which-func prints a long message while
10297 we are running fontification-functions. We're running these
10298 functions with safe_call which binds inhibit-redisplay to t. */
10299 if (!NILP (Vinhibit_redisplay))
10300 return 0;
10301
10302 /* Nil means don't try to resize. */
10303 if (NILP (Vresize_mini_windows)
10304 || (FRAME_X_P (f) && FRAME_X_OUTPUT (f) == NULL))
10305 return 0;
10306
10307 if (!FRAME_MINIBUF_ONLY_P (f))
10308 {
10309 struct it it;
10310 struct window *root = XWINDOW (FRAME_ROOT_WINDOW (f));
10311 int total_height = WINDOW_TOTAL_LINES (root) + WINDOW_TOTAL_LINES (w);
10312 int height;
10313 EMACS_INT max_height;
10314 int unit = FRAME_LINE_HEIGHT (f);
10315 struct text_pos start;
10316 struct buffer *old_current_buffer = NULL;
10317
10318 if (current_buffer != XBUFFER (w->buffer))
10319 {
10320 old_current_buffer = current_buffer;
10321 set_buffer_internal (XBUFFER (w->buffer));
10322 }
10323
10324 init_iterator (&it, w, BEGV, BEGV_BYTE, NULL, DEFAULT_FACE_ID);
10325
10326 /* Compute the max. number of lines specified by the user. */
10327 if (FLOATP (Vmax_mini_window_height))
10328 max_height = XFLOATINT (Vmax_mini_window_height) * FRAME_LINES (f);
10329 else if (INTEGERP (Vmax_mini_window_height))
10330 max_height = XINT (Vmax_mini_window_height);
10331 else
10332 max_height = total_height / 4;
10333
10334 /* Correct that max. height if it's bogus. */
10335 max_height = max (1, max_height);
10336 max_height = min (total_height, max_height);
10337
10338 /* Find out the height of the text in the window. */
10339 if (it.line_wrap == TRUNCATE)
10340 height = 1;
10341 else
10342 {
10343 last_height = 0;
10344 move_it_to (&it, ZV, -1, -1, -1, MOVE_TO_POS);
10345 if (it.max_ascent == 0 && it.max_descent == 0)
10346 height = it.current_y + last_height;
10347 else
10348 height = it.current_y + it.max_ascent + it.max_descent;
10349 height -= min (it.extra_line_spacing, it.max_extra_line_spacing);
10350 height = (height + unit - 1) / unit;
10351 }
10352
10353 /* Compute a suitable window start. */
10354 if (height > max_height)
10355 {
10356 height = max_height;
10357 init_iterator (&it, w, ZV, ZV_BYTE, NULL, DEFAULT_FACE_ID);
10358 move_it_vertically_backward (&it, (height - 1) * unit);
10359 start = it.current.pos;
10360 }
10361 else
10362 SET_TEXT_POS (start, BEGV, BEGV_BYTE);
10363 SET_MARKER_FROM_TEXT_POS (w->start, start);
10364
10365 if (EQ (Vresize_mini_windows, Qgrow_only))
10366 {
10367 /* Let it grow only, until we display an empty message, in which
10368 case the window shrinks again. */
10369 if (height > WINDOW_TOTAL_LINES (w))
10370 {
10371 int old_height = WINDOW_TOTAL_LINES (w);
10372 freeze_window_starts (f, 1);
10373 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
10374 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
10375 }
10376 else if (height < WINDOW_TOTAL_LINES (w)
10377 && (exact_p || BEGV == ZV))
10378 {
10379 int old_height = WINDOW_TOTAL_LINES (w);
10380 freeze_window_starts (f, 0);
10381 shrink_mini_window (w);
10382 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
10383 }
10384 }
10385 else
10386 {
10387 /* Always resize to exact size needed. */
10388 if (height > WINDOW_TOTAL_LINES (w))
10389 {
10390 int old_height = WINDOW_TOTAL_LINES (w);
10391 freeze_window_starts (f, 1);
10392 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
10393 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
10394 }
10395 else if (height < WINDOW_TOTAL_LINES (w))
10396 {
10397 int old_height = WINDOW_TOTAL_LINES (w);
10398 freeze_window_starts (f, 0);
10399 shrink_mini_window (w);
10400
10401 if (height)
10402 {
10403 freeze_window_starts (f, 1);
10404 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
10405 }
10406
10407 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
10408 }
10409 }
10410
10411 if (old_current_buffer)
10412 set_buffer_internal (old_current_buffer);
10413 }
10414
10415 return window_height_changed_p;
10416 }
10417
10418
10419 /* Value is the current message, a string, or nil if there is no
10420 current message. */
10421
10422 Lisp_Object
10423 current_message (void)
10424 {
10425 Lisp_Object msg;
10426
10427 if (!BUFFERP (echo_area_buffer[0]))
10428 msg = Qnil;
10429 else
10430 {
10431 with_echo_area_buffer (0, 0, current_message_1,
10432 (intptr_t) &msg, Qnil, 0, 0);
10433 if (NILP (msg))
10434 echo_area_buffer[0] = Qnil;
10435 }
10436
10437 return msg;
10438 }
10439
10440
10441 static int
10442 current_message_1 (ptrdiff_t a1, Lisp_Object a2, ptrdiff_t a3, ptrdiff_t a4)
10443 {
10444 intptr_t i1 = a1;
10445 Lisp_Object *msg = (Lisp_Object *) i1;
10446
10447 if (Z > BEG)
10448 *msg = make_buffer_string (BEG, Z, 1);
10449 else
10450 *msg = Qnil;
10451 return 0;
10452 }
10453
10454
10455 /* Push the current message on Vmessage_stack for later restoration
10456 by restore_message. Value is non-zero if the current message isn't
10457 empty. This is a relatively infrequent operation, so it's not
10458 worth optimizing. */
10459
10460 int
10461 push_message (void)
10462 {
10463 Lisp_Object msg;
10464 msg = current_message ();
10465 Vmessage_stack = Fcons (msg, Vmessage_stack);
10466 return STRINGP (msg);
10467 }
10468
10469
10470 /* Restore message display from the top of Vmessage_stack. */
10471
10472 void
10473 restore_message (void)
10474 {
10475 Lisp_Object msg;
10476
10477 xassert (CONSP (Vmessage_stack));
10478 msg = XCAR (Vmessage_stack);
10479 if (STRINGP (msg))
10480 message3_nolog (msg, SBYTES (msg), STRING_MULTIBYTE (msg));
10481 else
10482 message3_nolog (msg, 0, 0);
10483 }
10484
10485
10486 /* Handler for record_unwind_protect calling pop_message. */
10487
10488 Lisp_Object
10489 pop_message_unwind (Lisp_Object dummy)
10490 {
10491 pop_message ();
10492 return Qnil;
10493 }
10494
10495 /* Pop the top-most entry off Vmessage_stack. */
10496
10497 static void
10498 pop_message (void)
10499 {
10500 xassert (CONSP (Vmessage_stack));
10501 Vmessage_stack = XCDR (Vmessage_stack);
10502 }
10503
10504
10505 /* Check that Vmessage_stack is nil. Called from emacs.c when Emacs
10506 exits. If the stack is not empty, we have a missing pop_message
10507 somewhere. */
10508
10509 void
10510 check_message_stack (void)
10511 {
10512 if (!NILP (Vmessage_stack))
10513 abort ();
10514 }
10515
10516
10517 /* Truncate to NCHARS what will be displayed in the echo area the next
10518 time we display it---but don't redisplay it now. */
10519
10520 void
10521 truncate_echo_area (ptrdiff_t nchars)
10522 {
10523 if (nchars == 0)
10524 echo_area_buffer[0] = Qnil;
10525 /* A null message buffer means that the frame hasn't really been
10526 initialized yet. Error messages get reported properly by
10527 cmd_error, so this must be just an informative message; toss it. */
10528 else if (!noninteractive
10529 && INTERACTIVE
10530 && !NILP (echo_area_buffer[0]))
10531 {
10532 struct frame *sf = SELECTED_FRAME ();
10533 if (FRAME_MESSAGE_BUF (sf))
10534 with_echo_area_buffer (0, 0, truncate_message_1, nchars, Qnil, 0, 0);
10535 }
10536 }
10537
10538
10539 /* Helper function for truncate_echo_area. Truncate the current
10540 message to at most NCHARS characters. */
10541
10542 static int
10543 truncate_message_1 (ptrdiff_t nchars, Lisp_Object a2, ptrdiff_t a3, ptrdiff_t a4)
10544 {
10545 if (BEG + nchars < Z)
10546 del_range (BEG + nchars, Z);
10547 if (Z == BEG)
10548 echo_area_buffer[0] = Qnil;
10549 return 0;
10550 }
10551
10552
10553 /* Set the current message to a substring of S or STRING.
10554
10555 If STRING is a Lisp string, set the message to the first NBYTES
10556 bytes from STRING. NBYTES zero means use the whole string. If
10557 STRING is multibyte, the message will be displayed multibyte.
10558
10559 If S is not null, set the message to the first LEN bytes of S. LEN
10560 zero means use the whole string. MULTIBYTE_P non-zero means S is
10561 multibyte. Display the message multibyte in that case.
10562
10563 Doesn't GC, as with_echo_area_buffer binds Qinhibit_modification_hooks
10564 to t before calling set_message_1 (which calls insert).
10565 */
10566
10567 static void
10568 set_message (const char *s, Lisp_Object string,
10569 ptrdiff_t nbytes, int multibyte_p)
10570 {
10571 message_enable_multibyte
10572 = ((s && multibyte_p)
10573 || (STRINGP (string) && STRING_MULTIBYTE (string)));
10574
10575 with_echo_area_buffer (0, -1, set_message_1,
10576 (intptr_t) s, string, nbytes, multibyte_p);
10577 message_buf_print = 0;
10578 help_echo_showing_p = 0;
10579 }
10580
10581
10582 /* Helper function for set_message. Arguments have the same meaning
10583 as there, with A1 corresponding to S and A2 corresponding to STRING
10584 This function is called with the echo area buffer being
10585 current. */
10586
10587 static int
10588 set_message_1 (ptrdiff_t a1, Lisp_Object a2, ptrdiff_t nbytes, ptrdiff_t multibyte_p)
10589 {
10590 intptr_t i1 = a1;
10591 const char *s = (const char *) i1;
10592 const unsigned char *msg = (const unsigned char *) s;
10593 Lisp_Object string = a2;
10594
10595 /* Change multibyteness of the echo buffer appropriately. */
10596 if (message_enable_multibyte
10597 != !NILP (BVAR (current_buffer, enable_multibyte_characters)))
10598 Fset_buffer_multibyte (message_enable_multibyte ? Qt : Qnil);
10599
10600 BVAR (current_buffer, truncate_lines) = message_truncate_lines ? Qt : Qnil;
10601 if (!NILP (BVAR (current_buffer, bidi_display_reordering)))
10602 BVAR (current_buffer, bidi_paragraph_direction) = Qleft_to_right;
10603
10604 /* Insert new message at BEG. */
10605 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
10606
10607 if (STRINGP (string))
10608 {
10609 ptrdiff_t nchars;
10610
10611 if (nbytes == 0)
10612 nbytes = SBYTES (string);
10613 nchars = string_byte_to_char (string, nbytes);
10614
10615 /* This function takes care of single/multibyte conversion. We
10616 just have to ensure that the echo area buffer has the right
10617 setting of enable_multibyte_characters. */
10618 insert_from_string (string, 0, 0, nchars, nbytes, 1);
10619 }
10620 else if (s)
10621 {
10622 if (nbytes == 0)
10623 nbytes = strlen (s);
10624
10625 if (multibyte_p && NILP (BVAR (current_buffer, enable_multibyte_characters)))
10626 {
10627 /* Convert from multi-byte to single-byte. */
10628 ptrdiff_t i;
10629 int c, n;
10630 char work[1];
10631
10632 /* Convert a multibyte string to single-byte. */
10633 for (i = 0; i < nbytes; i += n)
10634 {
10635 c = string_char_and_length (msg + i, &n);
10636 work[0] = (ASCII_CHAR_P (c)
10637 ? c
10638 : multibyte_char_to_unibyte (c));
10639 insert_1_both (work, 1, 1, 1, 0, 0);
10640 }
10641 }
10642 else if (!multibyte_p
10643 && !NILP (BVAR (current_buffer, enable_multibyte_characters)))
10644 {
10645 /* Convert from single-byte to multi-byte. */
10646 ptrdiff_t i;
10647 int c, n;
10648 unsigned char str[MAX_MULTIBYTE_LENGTH];
10649
10650 /* Convert a single-byte string to multibyte. */
10651 for (i = 0; i < nbytes; i++)
10652 {
10653 c = msg[i];
10654 MAKE_CHAR_MULTIBYTE (c);
10655 n = CHAR_STRING (c, str);
10656 insert_1_both ((char *) str, 1, n, 1, 0, 0);
10657 }
10658 }
10659 else
10660 insert_1 (s, nbytes, 1, 0, 0);
10661 }
10662
10663 return 0;
10664 }
10665
10666
10667 /* Clear messages. CURRENT_P non-zero means clear the current
10668 message. LAST_DISPLAYED_P non-zero means clear the message
10669 last displayed. */
10670
10671 void
10672 clear_message (int current_p, int last_displayed_p)
10673 {
10674 if (current_p)
10675 {
10676 echo_area_buffer[0] = Qnil;
10677 message_cleared_p = 1;
10678 }
10679
10680 if (last_displayed_p)
10681 echo_area_buffer[1] = Qnil;
10682
10683 message_buf_print = 0;
10684 }
10685
10686 /* Clear garbaged frames.
10687
10688 This function is used where the old redisplay called
10689 redraw_garbaged_frames which in turn called redraw_frame which in
10690 turn called clear_frame. The call to clear_frame was a source of
10691 flickering. I believe a clear_frame is not necessary. It should
10692 suffice in the new redisplay to invalidate all current matrices,
10693 and ensure a complete redisplay of all windows. */
10694
10695 static void
10696 clear_garbaged_frames (void)
10697 {
10698 if (frame_garbaged)
10699 {
10700 Lisp_Object tail, frame;
10701 int changed_count = 0;
10702
10703 FOR_EACH_FRAME (tail, frame)
10704 {
10705 struct frame *f = XFRAME (frame);
10706
10707 if (FRAME_VISIBLE_P (f) && FRAME_GARBAGED_P (f))
10708 {
10709 if (f->resized_p)
10710 {
10711 Fredraw_frame (frame);
10712 f->force_flush_display_p = 1;
10713 }
10714 clear_current_matrices (f);
10715 changed_count++;
10716 f->garbaged = 0;
10717 f->resized_p = 0;
10718 }
10719 }
10720
10721 frame_garbaged = 0;
10722 if (changed_count)
10723 ++windows_or_buffers_changed;
10724 }
10725 }
10726
10727
10728 /* Redisplay the echo area of the selected frame. If UPDATE_FRAME_P
10729 is non-zero update selected_frame. Value is non-zero if the
10730 mini-windows height has been changed. */
10731
10732 static int
10733 echo_area_display (int update_frame_p)
10734 {
10735 Lisp_Object mini_window;
10736 struct window *w;
10737 struct frame *f;
10738 int window_height_changed_p = 0;
10739 struct frame *sf = SELECTED_FRAME ();
10740
10741 mini_window = FRAME_MINIBUF_WINDOW (sf);
10742 w = XWINDOW (mini_window);
10743 f = XFRAME (WINDOW_FRAME (w));
10744
10745 /* Don't display if frame is invisible or not yet initialized. */
10746 if (!FRAME_VISIBLE_P (f) || !f->glyphs_initialized_p)
10747 return 0;
10748
10749 #ifdef HAVE_WINDOW_SYSTEM
10750 /* When Emacs starts, selected_frame may be the initial terminal
10751 frame. If we let this through, a message would be displayed on
10752 the terminal. */
10753 if (FRAME_INITIAL_P (XFRAME (selected_frame)))
10754 return 0;
10755 #endif /* HAVE_WINDOW_SYSTEM */
10756
10757 /* Redraw garbaged frames. */
10758 if (frame_garbaged)
10759 clear_garbaged_frames ();
10760
10761 if (!NILP (echo_area_buffer[0]) || minibuf_level == 0)
10762 {
10763 echo_area_window = mini_window;
10764 window_height_changed_p = display_echo_area (w);
10765 w->must_be_updated_p = 1;
10766
10767 /* Update the display, unless called from redisplay_internal.
10768 Also don't update the screen during redisplay itself. The
10769 update will happen at the end of redisplay, and an update
10770 here could cause confusion. */
10771 if (update_frame_p && !redisplaying_p)
10772 {
10773 int n = 0;
10774
10775 /* If the display update has been interrupted by pending
10776 input, update mode lines in the frame. Due to the
10777 pending input, it might have been that redisplay hasn't
10778 been called, so that mode lines above the echo area are
10779 garbaged. This looks odd, so we prevent it here. */
10780 if (!display_completed)
10781 n = redisplay_mode_lines (FRAME_ROOT_WINDOW (f), 0);
10782
10783 if (window_height_changed_p
10784 /* Don't do this if Emacs is shutting down. Redisplay
10785 needs to run hooks. */
10786 && !NILP (Vrun_hooks))
10787 {
10788 /* Must update other windows. Likewise as in other
10789 cases, don't let this update be interrupted by
10790 pending input. */
10791 ptrdiff_t count = SPECPDL_INDEX ();
10792 specbind (Qredisplay_dont_pause, Qt);
10793 windows_or_buffers_changed = 1;
10794 redisplay_internal ();
10795 unbind_to (count, Qnil);
10796 }
10797 else if (FRAME_WINDOW_P (f) && n == 0)
10798 {
10799 /* Window configuration is the same as before.
10800 Can do with a display update of the echo area,
10801 unless we displayed some mode lines. */
10802 update_single_window (w, 1);
10803 FRAME_RIF (f)->flush_display (f);
10804 }
10805 else
10806 update_frame (f, 1, 1);
10807
10808 /* If cursor is in the echo area, make sure that the next
10809 redisplay displays the minibuffer, so that the cursor will
10810 be replaced with what the minibuffer wants. */
10811 if (cursor_in_echo_area)
10812 ++windows_or_buffers_changed;
10813 }
10814 }
10815 else if (!EQ (mini_window, selected_window))
10816 windows_or_buffers_changed++;
10817
10818 /* Last displayed message is now the current message. */
10819 echo_area_buffer[1] = echo_area_buffer[0];
10820 /* Inform read_char that we're not echoing. */
10821 echo_message_buffer = Qnil;
10822
10823 /* Prevent redisplay optimization in redisplay_internal by resetting
10824 this_line_start_pos. This is done because the mini-buffer now
10825 displays the message instead of its buffer text. */
10826 if (EQ (mini_window, selected_window))
10827 CHARPOS (this_line_start_pos) = 0;
10828
10829 return window_height_changed_p;
10830 }
10831
10832
10833 \f
10834 /***********************************************************************
10835 Mode Lines and Frame Titles
10836 ***********************************************************************/
10837
10838 /* A buffer for constructing non-propertized mode-line strings and
10839 frame titles in it; allocated from the heap in init_xdisp and
10840 resized as needed in store_mode_line_noprop_char. */
10841
10842 static char *mode_line_noprop_buf;
10843
10844 /* The buffer's end, and a current output position in it. */
10845
10846 static char *mode_line_noprop_buf_end;
10847 static char *mode_line_noprop_ptr;
10848
10849 #define MODE_LINE_NOPROP_LEN(start) \
10850 ((mode_line_noprop_ptr - mode_line_noprop_buf) - start)
10851
10852 static enum {
10853 MODE_LINE_DISPLAY = 0,
10854 MODE_LINE_TITLE,
10855 MODE_LINE_NOPROP,
10856 MODE_LINE_STRING
10857 } mode_line_target;
10858
10859 /* Alist that caches the results of :propertize.
10860 Each element is (PROPERTIZED-STRING . PROPERTY-LIST). */
10861 static Lisp_Object mode_line_proptrans_alist;
10862
10863 /* List of strings making up the mode-line. */
10864 static Lisp_Object mode_line_string_list;
10865
10866 /* Base face property when building propertized mode line string. */
10867 static Lisp_Object mode_line_string_face;
10868 static Lisp_Object mode_line_string_face_prop;
10869
10870
10871 /* Unwind data for mode line strings */
10872
10873 static Lisp_Object Vmode_line_unwind_vector;
10874
10875 static Lisp_Object
10876 format_mode_line_unwind_data (struct buffer *obuf,
10877 Lisp_Object owin,
10878 int save_proptrans)
10879 {
10880 Lisp_Object vector, tmp;
10881
10882 /* Reduce consing by keeping one vector in
10883 Vwith_echo_area_save_vector. */
10884 vector = Vmode_line_unwind_vector;
10885 Vmode_line_unwind_vector = Qnil;
10886
10887 if (NILP (vector))
10888 vector = Fmake_vector (make_number (8), Qnil);
10889
10890 ASET (vector, 0, make_number (mode_line_target));
10891 ASET (vector, 1, make_number (MODE_LINE_NOPROP_LEN (0)));
10892 ASET (vector, 2, mode_line_string_list);
10893 ASET (vector, 3, save_proptrans ? mode_line_proptrans_alist : Qt);
10894 ASET (vector, 4, mode_line_string_face);
10895 ASET (vector, 5, mode_line_string_face_prop);
10896
10897 if (obuf)
10898 XSETBUFFER (tmp, obuf);
10899 else
10900 tmp = Qnil;
10901 ASET (vector, 6, tmp);
10902 ASET (vector, 7, owin);
10903
10904 return vector;
10905 }
10906
10907 static Lisp_Object
10908 unwind_format_mode_line (Lisp_Object vector)
10909 {
10910 mode_line_target = XINT (AREF (vector, 0));
10911 mode_line_noprop_ptr = mode_line_noprop_buf + XINT (AREF (vector, 1));
10912 mode_line_string_list = AREF (vector, 2);
10913 if (! EQ (AREF (vector, 3), Qt))
10914 mode_line_proptrans_alist = AREF (vector, 3);
10915 mode_line_string_face = AREF (vector, 4);
10916 mode_line_string_face_prop = AREF (vector, 5);
10917
10918 if (!NILP (AREF (vector, 7)))
10919 /* Select window before buffer, since it may change the buffer. */
10920 Fselect_window (AREF (vector, 7), Qt);
10921
10922 if (!NILP (AREF (vector, 6)))
10923 {
10924 set_buffer_internal_1 (XBUFFER (AREF (vector, 6)));
10925 ASET (vector, 6, Qnil);
10926 }
10927
10928 Vmode_line_unwind_vector = vector;
10929 return Qnil;
10930 }
10931
10932
10933 /* Store a single character C for the frame title in mode_line_noprop_buf.
10934 Re-allocate mode_line_noprop_buf if necessary. */
10935
10936 static void
10937 store_mode_line_noprop_char (char c)
10938 {
10939 /* If output position has reached the end of the allocated buffer,
10940 increase the buffer's size. */
10941 if (mode_line_noprop_ptr == mode_line_noprop_buf_end)
10942 {
10943 ptrdiff_t len = MODE_LINE_NOPROP_LEN (0);
10944 ptrdiff_t size = len;
10945 mode_line_noprop_buf =
10946 xpalloc (mode_line_noprop_buf, &size, 1, STRING_BYTES_BOUND, 1);
10947 mode_line_noprop_buf_end = mode_line_noprop_buf + size;
10948 mode_line_noprop_ptr = mode_line_noprop_buf + len;
10949 }
10950
10951 *mode_line_noprop_ptr++ = c;
10952 }
10953
10954
10955 /* Store part of a frame title in mode_line_noprop_buf, beginning at
10956 mode_line_noprop_ptr. STRING is the string to store. Do not copy
10957 characters that yield more columns than PRECISION; PRECISION <= 0
10958 means copy the whole string. Pad with spaces until FIELD_WIDTH
10959 number of characters have been copied; FIELD_WIDTH <= 0 means don't
10960 pad. Called from display_mode_element when it is used to build a
10961 frame title. */
10962
10963 static int
10964 store_mode_line_noprop (const char *string, int field_width, int precision)
10965 {
10966 const unsigned char *str = (const unsigned char *) string;
10967 int n = 0;
10968 ptrdiff_t dummy, nbytes;
10969
10970 /* Copy at most PRECISION chars from STR. */
10971 nbytes = strlen (string);
10972 n += c_string_width (str, nbytes, precision, &dummy, &nbytes);
10973 while (nbytes--)
10974 store_mode_line_noprop_char (*str++);
10975
10976 /* Fill up with spaces until FIELD_WIDTH reached. */
10977 while (field_width > 0
10978 && n < field_width)
10979 {
10980 store_mode_line_noprop_char (' ');
10981 ++n;
10982 }
10983
10984 return n;
10985 }
10986
10987 /***********************************************************************
10988 Frame Titles
10989 ***********************************************************************/
10990
10991 #ifdef HAVE_WINDOW_SYSTEM
10992
10993 /* Set the title of FRAME, if it has changed. The title format is
10994 Vicon_title_format if FRAME is iconified, otherwise it is
10995 frame_title_format. */
10996
10997 static void
10998 x_consider_frame_title (Lisp_Object frame)
10999 {
11000 struct frame *f = XFRAME (frame);
11001
11002 if (FRAME_WINDOW_P (f)
11003 || FRAME_MINIBUF_ONLY_P (f)
11004 || f->explicit_name)
11005 {
11006 /* Do we have more than one visible frame on this X display? */
11007 Lisp_Object tail;
11008 Lisp_Object fmt;
11009 ptrdiff_t title_start;
11010 char *title;
11011 ptrdiff_t len;
11012 struct it it;
11013 ptrdiff_t count = SPECPDL_INDEX ();
11014
11015 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
11016 {
11017 Lisp_Object other_frame = XCAR (tail);
11018 struct frame *tf = XFRAME (other_frame);
11019
11020 if (tf != f
11021 && FRAME_KBOARD (tf) == FRAME_KBOARD (f)
11022 && !FRAME_MINIBUF_ONLY_P (tf)
11023 && !EQ (other_frame, tip_frame)
11024 && (FRAME_VISIBLE_P (tf) || FRAME_ICONIFIED_P (tf)))
11025 break;
11026 }
11027
11028 /* Set global variable indicating that multiple frames exist. */
11029 multiple_frames = CONSP (tail);
11030
11031 /* Switch to the buffer of selected window of the frame. Set up
11032 mode_line_target so that display_mode_element will output into
11033 mode_line_noprop_buf; then display the title. */
11034 record_unwind_protect (unwind_format_mode_line,
11035 format_mode_line_unwind_data
11036 (current_buffer, selected_window, 0));
11037
11038 Fselect_window (f->selected_window, Qt);
11039 set_buffer_internal_1 (XBUFFER (XWINDOW (f->selected_window)->buffer));
11040 fmt = FRAME_ICONIFIED_P (f) ? Vicon_title_format : Vframe_title_format;
11041
11042 mode_line_target = MODE_LINE_TITLE;
11043 title_start = MODE_LINE_NOPROP_LEN (0);
11044 init_iterator (&it, XWINDOW (f->selected_window), -1, -1,
11045 NULL, DEFAULT_FACE_ID);
11046 display_mode_element (&it, 0, -1, -1, fmt, Qnil, 0);
11047 len = MODE_LINE_NOPROP_LEN (title_start);
11048 title = mode_line_noprop_buf + title_start;
11049 unbind_to (count, Qnil);
11050
11051 /* Set the title only if it's changed. This avoids consing in
11052 the common case where it hasn't. (If it turns out that we've
11053 already wasted too much time by walking through the list with
11054 display_mode_element, then we might need to optimize at a
11055 higher level than this.) */
11056 if (! STRINGP (f->name)
11057 || SBYTES (f->name) != len
11058 || memcmp (title, SDATA (f->name), len) != 0)
11059 x_implicitly_set_name (f, make_string (title, len), Qnil);
11060 }
11061 }
11062
11063 #endif /* not HAVE_WINDOW_SYSTEM */
11064
11065
11066
11067 \f
11068 /***********************************************************************
11069 Menu Bars
11070 ***********************************************************************/
11071
11072
11073 /* Prepare for redisplay by updating menu-bar item lists when
11074 appropriate. This can call eval. */
11075
11076 void
11077 prepare_menu_bars (void)
11078 {
11079 int all_windows;
11080 struct gcpro gcpro1, gcpro2;
11081 struct frame *f;
11082 Lisp_Object tooltip_frame;
11083
11084 #ifdef HAVE_WINDOW_SYSTEM
11085 tooltip_frame = tip_frame;
11086 #else
11087 tooltip_frame = Qnil;
11088 #endif
11089
11090 /* Update all frame titles based on their buffer names, etc. We do
11091 this before the menu bars so that the buffer-menu will show the
11092 up-to-date frame titles. */
11093 #ifdef HAVE_WINDOW_SYSTEM
11094 if (windows_or_buffers_changed || update_mode_lines)
11095 {
11096 Lisp_Object tail, frame;
11097
11098 FOR_EACH_FRAME (tail, frame)
11099 {
11100 f = XFRAME (frame);
11101 if (!EQ (frame, tooltip_frame)
11102 && (FRAME_VISIBLE_P (f) || FRAME_ICONIFIED_P (f)))
11103 x_consider_frame_title (frame);
11104 }
11105 }
11106 #endif /* HAVE_WINDOW_SYSTEM */
11107
11108 /* Update the menu bar item lists, if appropriate. This has to be
11109 done before any actual redisplay or generation of display lines. */
11110 all_windows = (update_mode_lines
11111 || buffer_shared > 1
11112 || windows_or_buffers_changed);
11113 if (all_windows)
11114 {
11115 Lisp_Object tail, frame;
11116 ptrdiff_t count = SPECPDL_INDEX ();
11117 /* 1 means that update_menu_bar has run its hooks
11118 so any further calls to update_menu_bar shouldn't do so again. */
11119 int menu_bar_hooks_run = 0;
11120
11121 record_unwind_save_match_data ();
11122
11123 FOR_EACH_FRAME (tail, frame)
11124 {
11125 f = XFRAME (frame);
11126
11127 /* Ignore tooltip frame. */
11128 if (EQ (frame, tooltip_frame))
11129 continue;
11130
11131 /* If a window on this frame changed size, report that to
11132 the user and clear the size-change flag. */
11133 if (FRAME_WINDOW_SIZES_CHANGED (f))
11134 {
11135 Lisp_Object functions;
11136
11137 /* Clear flag first in case we get an error below. */
11138 FRAME_WINDOW_SIZES_CHANGED (f) = 0;
11139 functions = Vwindow_size_change_functions;
11140 GCPRO2 (tail, functions);
11141
11142 while (CONSP (functions))
11143 {
11144 if (!EQ (XCAR (functions), Qt))
11145 call1 (XCAR (functions), frame);
11146 functions = XCDR (functions);
11147 }
11148 UNGCPRO;
11149 }
11150
11151 GCPRO1 (tail);
11152 menu_bar_hooks_run = update_menu_bar (f, 0, menu_bar_hooks_run);
11153 #ifdef HAVE_WINDOW_SYSTEM
11154 update_tool_bar (f, 0);
11155 #endif
11156 #ifdef HAVE_NS
11157 if (windows_or_buffers_changed
11158 && FRAME_NS_P (f))
11159 ns_set_doc_edited (f, Fbuffer_modified_p
11160 (XWINDOW (f->selected_window)->buffer));
11161 #endif
11162 UNGCPRO;
11163 }
11164
11165 unbind_to (count, Qnil);
11166 }
11167 else
11168 {
11169 struct frame *sf = SELECTED_FRAME ();
11170 update_menu_bar (sf, 1, 0);
11171 #ifdef HAVE_WINDOW_SYSTEM
11172 update_tool_bar (sf, 1);
11173 #endif
11174 }
11175 }
11176
11177
11178 /* Update the menu bar item list for frame F. This has to be done
11179 before we start to fill in any display lines, because it can call
11180 eval.
11181
11182 If SAVE_MATCH_DATA is non-zero, we must save and restore it here.
11183
11184 If HOOKS_RUN is 1, that means a previous call to update_menu_bar
11185 already ran the menu bar hooks for this redisplay, so there
11186 is no need to run them again. The return value is the
11187 updated value of this flag, to pass to the next call. */
11188
11189 static int
11190 update_menu_bar (struct frame *f, int save_match_data, int hooks_run)
11191 {
11192 Lisp_Object window;
11193 register struct window *w;
11194
11195 /* If called recursively during a menu update, do nothing. This can
11196 happen when, for instance, an activate-menubar-hook causes a
11197 redisplay. */
11198 if (inhibit_menubar_update)
11199 return hooks_run;
11200
11201 window = FRAME_SELECTED_WINDOW (f);
11202 w = XWINDOW (window);
11203
11204 if (FRAME_WINDOW_P (f)
11205 ?
11206 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
11207 || defined (HAVE_NS) || defined (USE_GTK)
11208 FRAME_EXTERNAL_MENU_BAR (f)
11209 #else
11210 FRAME_MENU_BAR_LINES (f) > 0
11211 #endif
11212 : FRAME_MENU_BAR_LINES (f) > 0)
11213 {
11214 /* If the user has switched buffers or windows, we need to
11215 recompute to reflect the new bindings. But we'll
11216 recompute when update_mode_lines is set too; that means
11217 that people can use force-mode-line-update to request
11218 that the menu bar be recomputed. The adverse effect on
11219 the rest of the redisplay algorithm is about the same as
11220 windows_or_buffers_changed anyway. */
11221 if (windows_or_buffers_changed
11222 /* This used to test w->update_mode_line, but we believe
11223 there is no need to recompute the menu in that case. */
11224 || update_mode_lines
11225 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
11226 < BUF_MODIFF (XBUFFER (w->buffer)))
11227 != w->last_had_star)
11228 || ((!NILP (Vtransient_mark_mode)
11229 && !NILP (BVAR (XBUFFER (w->buffer), mark_active)))
11230 != !NILP (w->region_showing)))
11231 {
11232 struct buffer *prev = current_buffer;
11233 ptrdiff_t count = SPECPDL_INDEX ();
11234
11235 specbind (Qinhibit_menubar_update, Qt);
11236
11237 set_buffer_internal_1 (XBUFFER (w->buffer));
11238 if (save_match_data)
11239 record_unwind_save_match_data ();
11240 if (NILP (Voverriding_local_map_menu_flag))
11241 {
11242 specbind (Qoverriding_terminal_local_map, Qnil);
11243 specbind (Qoverriding_local_map, Qnil);
11244 }
11245
11246 if (!hooks_run)
11247 {
11248 /* Run the Lucid hook. */
11249 safe_run_hooks (Qactivate_menubar_hook);
11250
11251 /* If it has changed current-menubar from previous value,
11252 really recompute the menu-bar from the value. */
11253 if (! NILP (Vlucid_menu_bar_dirty_flag))
11254 call0 (Qrecompute_lucid_menubar);
11255
11256 safe_run_hooks (Qmenu_bar_update_hook);
11257
11258 hooks_run = 1;
11259 }
11260
11261 XSETFRAME (Vmenu_updating_frame, f);
11262 FRAME_MENU_BAR_ITEMS (f) = menu_bar_items (FRAME_MENU_BAR_ITEMS (f));
11263
11264 /* Redisplay the menu bar in case we changed it. */
11265 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
11266 || defined (HAVE_NS) || defined (USE_GTK)
11267 if (FRAME_WINDOW_P (f))
11268 {
11269 #if defined (HAVE_NS)
11270 /* All frames on Mac OS share the same menubar. So only
11271 the selected frame should be allowed to set it. */
11272 if (f == SELECTED_FRAME ())
11273 #endif
11274 set_frame_menubar (f, 0, 0);
11275 }
11276 else
11277 /* On a terminal screen, the menu bar is an ordinary screen
11278 line, and this makes it get updated. */
11279 w->update_mode_line = 1;
11280 #else /* ! (USE_X_TOOLKIT || HAVE_NTGUI || HAVE_NS || USE_GTK) */
11281 /* In the non-toolkit version, the menu bar is an ordinary screen
11282 line, and this makes it get updated. */
11283 w->update_mode_line = 1;
11284 #endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI || HAVE_NS || USE_GTK) */
11285
11286 unbind_to (count, Qnil);
11287 set_buffer_internal_1 (prev);
11288 }
11289 }
11290
11291 return hooks_run;
11292 }
11293
11294
11295 \f
11296 /***********************************************************************
11297 Output Cursor
11298 ***********************************************************************/
11299
11300 #ifdef HAVE_WINDOW_SYSTEM
11301
11302 /* EXPORT:
11303 Nominal cursor position -- where to draw output.
11304 HPOS and VPOS are window relative glyph matrix coordinates.
11305 X and Y are window relative pixel coordinates. */
11306
11307 struct cursor_pos output_cursor;
11308
11309
11310 /* EXPORT:
11311 Set the global variable output_cursor to CURSOR. All cursor
11312 positions are relative to updated_window. */
11313
11314 void
11315 set_output_cursor (struct cursor_pos *cursor)
11316 {
11317 output_cursor.hpos = cursor->hpos;
11318 output_cursor.vpos = cursor->vpos;
11319 output_cursor.x = cursor->x;
11320 output_cursor.y = cursor->y;
11321 }
11322
11323
11324 /* EXPORT for RIF:
11325 Set a nominal cursor position.
11326
11327 HPOS and VPOS are column/row positions in a window glyph matrix. X
11328 and Y are window text area relative pixel positions.
11329
11330 If this is done during an update, updated_window will contain the
11331 window that is being updated and the position is the future output
11332 cursor position for that window. If updated_window is null, use
11333 selected_window and display the cursor at the given position. */
11334
11335 void
11336 x_cursor_to (int vpos, int hpos, int y, int x)
11337 {
11338 struct window *w;
11339
11340 /* If updated_window is not set, work on selected_window. */
11341 if (updated_window)
11342 w = updated_window;
11343 else
11344 w = XWINDOW (selected_window);
11345
11346 /* Set the output cursor. */
11347 output_cursor.hpos = hpos;
11348 output_cursor.vpos = vpos;
11349 output_cursor.x = x;
11350 output_cursor.y = y;
11351
11352 /* If not called as part of an update, really display the cursor.
11353 This will also set the cursor position of W. */
11354 if (updated_window == NULL)
11355 {
11356 BLOCK_INPUT;
11357 display_and_set_cursor (w, 1, hpos, vpos, x, y);
11358 if (FRAME_RIF (SELECTED_FRAME ())->flush_display_optional)
11359 FRAME_RIF (SELECTED_FRAME ())->flush_display_optional (SELECTED_FRAME ());
11360 UNBLOCK_INPUT;
11361 }
11362 }
11363
11364 #endif /* HAVE_WINDOW_SYSTEM */
11365
11366 \f
11367 /***********************************************************************
11368 Tool-bars
11369 ***********************************************************************/
11370
11371 #ifdef HAVE_WINDOW_SYSTEM
11372
11373 /* Where the mouse was last time we reported a mouse event. */
11374
11375 FRAME_PTR last_mouse_frame;
11376
11377 /* Tool-bar item index of the item on which a mouse button was pressed
11378 or -1. */
11379
11380 int last_tool_bar_item;
11381
11382
11383 static Lisp_Object
11384 update_tool_bar_unwind (Lisp_Object frame)
11385 {
11386 selected_frame = frame;
11387 return Qnil;
11388 }
11389
11390 /* Update the tool-bar item list for frame F. This has to be done
11391 before we start to fill in any display lines. Called from
11392 prepare_menu_bars. If SAVE_MATCH_DATA is non-zero, we must save
11393 and restore it here. */
11394
11395 static void
11396 update_tool_bar (struct frame *f, int save_match_data)
11397 {
11398 #if defined (USE_GTK) || defined (HAVE_NS)
11399 int do_update = FRAME_EXTERNAL_TOOL_BAR (f);
11400 #else
11401 int do_update = WINDOWP (f->tool_bar_window)
11402 && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)) > 0;
11403 #endif
11404
11405 if (do_update)
11406 {
11407 Lisp_Object window;
11408 struct window *w;
11409
11410 window = FRAME_SELECTED_WINDOW (f);
11411 w = XWINDOW (window);
11412
11413 /* If the user has switched buffers or windows, we need to
11414 recompute to reflect the new bindings. But we'll
11415 recompute when update_mode_lines is set too; that means
11416 that people can use force-mode-line-update to request
11417 that the menu bar be recomputed. The adverse effect on
11418 the rest of the redisplay algorithm is about the same as
11419 windows_or_buffers_changed anyway. */
11420 if (windows_or_buffers_changed
11421 || w->update_mode_line
11422 || update_mode_lines
11423 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
11424 < BUF_MODIFF (XBUFFER (w->buffer)))
11425 != w->last_had_star)
11426 || ((!NILP (Vtransient_mark_mode)
11427 && !NILP (BVAR (XBUFFER (w->buffer), mark_active)))
11428 != !NILP (w->region_showing)))
11429 {
11430 struct buffer *prev = current_buffer;
11431 ptrdiff_t count = SPECPDL_INDEX ();
11432 Lisp_Object frame, new_tool_bar;
11433 int new_n_tool_bar;
11434 struct gcpro gcpro1;
11435
11436 /* Set current_buffer to the buffer of the selected
11437 window of the frame, so that we get the right local
11438 keymaps. */
11439 set_buffer_internal_1 (XBUFFER (w->buffer));
11440
11441 /* Save match data, if we must. */
11442 if (save_match_data)
11443 record_unwind_save_match_data ();
11444
11445 /* Make sure that we don't accidentally use bogus keymaps. */
11446 if (NILP (Voverriding_local_map_menu_flag))
11447 {
11448 specbind (Qoverriding_terminal_local_map, Qnil);
11449 specbind (Qoverriding_local_map, Qnil);
11450 }
11451
11452 GCPRO1 (new_tool_bar);
11453
11454 /* We must temporarily set the selected frame to this frame
11455 before calling tool_bar_items, because the calculation of
11456 the tool-bar keymap uses the selected frame (see
11457 `tool-bar-make-keymap' in tool-bar.el). */
11458 record_unwind_protect (update_tool_bar_unwind, selected_frame);
11459 XSETFRAME (frame, f);
11460 selected_frame = frame;
11461
11462 /* Build desired tool-bar items from keymaps. */
11463 new_tool_bar = tool_bar_items (Fcopy_sequence (f->tool_bar_items),
11464 &new_n_tool_bar);
11465
11466 /* Redisplay the tool-bar if we changed it. */
11467 if (new_n_tool_bar != f->n_tool_bar_items
11468 || NILP (Fequal (new_tool_bar, f->tool_bar_items)))
11469 {
11470 /* Redisplay that happens asynchronously due to an expose event
11471 may access f->tool_bar_items. Make sure we update both
11472 variables within BLOCK_INPUT so no such event interrupts. */
11473 BLOCK_INPUT;
11474 f->tool_bar_items = new_tool_bar;
11475 f->n_tool_bar_items = new_n_tool_bar;
11476 w->update_mode_line = 1;
11477 UNBLOCK_INPUT;
11478 }
11479
11480 UNGCPRO;
11481
11482 unbind_to (count, Qnil);
11483 set_buffer_internal_1 (prev);
11484 }
11485 }
11486 }
11487
11488
11489 /* Set F->desired_tool_bar_string to a Lisp string representing frame
11490 F's desired tool-bar contents. F->tool_bar_items must have
11491 been set up previously by calling prepare_menu_bars. */
11492
11493 static void
11494 build_desired_tool_bar_string (struct frame *f)
11495 {
11496 int i, size, size_needed;
11497 struct gcpro gcpro1, gcpro2, gcpro3;
11498 Lisp_Object image, plist, props;
11499
11500 image = plist = props = Qnil;
11501 GCPRO3 (image, plist, props);
11502
11503 /* Prepare F->desired_tool_bar_string. If we can reuse it, do so.
11504 Otherwise, make a new string. */
11505
11506 /* The size of the string we might be able to reuse. */
11507 size = (STRINGP (f->desired_tool_bar_string)
11508 ? SCHARS (f->desired_tool_bar_string)
11509 : 0);
11510
11511 /* We need one space in the string for each image. */
11512 size_needed = f->n_tool_bar_items;
11513
11514 /* Reuse f->desired_tool_bar_string, if possible. */
11515 if (size < size_needed || NILP (f->desired_tool_bar_string))
11516 f->desired_tool_bar_string = Fmake_string (make_number (size_needed),
11517 make_number (' '));
11518 else
11519 {
11520 props = list4 (Qdisplay, Qnil, Qmenu_item, Qnil);
11521 Fremove_text_properties (make_number (0), make_number (size),
11522 props, f->desired_tool_bar_string);
11523 }
11524
11525 /* Put a `display' property on the string for the images to display,
11526 put a `menu_item' property on tool-bar items with a value that
11527 is the index of the item in F's tool-bar item vector. */
11528 for (i = 0; i < f->n_tool_bar_items; ++i)
11529 {
11530 #define PROP(IDX) AREF (f->tool_bar_items, i * TOOL_BAR_ITEM_NSLOTS + (IDX))
11531
11532 int enabled_p = !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P));
11533 int selected_p = !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P));
11534 int hmargin, vmargin, relief, idx, end;
11535
11536 /* If image is a vector, choose the image according to the
11537 button state. */
11538 image = PROP (TOOL_BAR_ITEM_IMAGES);
11539 if (VECTORP (image))
11540 {
11541 if (enabled_p)
11542 idx = (selected_p
11543 ? TOOL_BAR_IMAGE_ENABLED_SELECTED
11544 : TOOL_BAR_IMAGE_ENABLED_DESELECTED);
11545 else
11546 idx = (selected_p
11547 ? TOOL_BAR_IMAGE_DISABLED_SELECTED
11548 : TOOL_BAR_IMAGE_DISABLED_DESELECTED);
11549
11550 xassert (ASIZE (image) >= idx);
11551 image = AREF (image, idx);
11552 }
11553 else
11554 idx = -1;
11555
11556 /* Ignore invalid image specifications. */
11557 if (!valid_image_p (image))
11558 continue;
11559
11560 /* Display the tool-bar button pressed, or depressed. */
11561 plist = Fcopy_sequence (XCDR (image));
11562
11563 /* Compute margin and relief to draw. */
11564 relief = (tool_bar_button_relief >= 0
11565 ? tool_bar_button_relief
11566 : DEFAULT_TOOL_BAR_BUTTON_RELIEF);
11567 hmargin = vmargin = relief;
11568
11569 if (RANGED_INTEGERP (1, Vtool_bar_button_margin,
11570 INT_MAX - max (hmargin, vmargin)))
11571 {
11572 hmargin += XFASTINT (Vtool_bar_button_margin);
11573 vmargin += XFASTINT (Vtool_bar_button_margin);
11574 }
11575 else if (CONSP (Vtool_bar_button_margin))
11576 {
11577 if (RANGED_INTEGERP (1, XCAR (Vtool_bar_button_margin),
11578 INT_MAX - hmargin))
11579 hmargin += XFASTINT (XCAR (Vtool_bar_button_margin));
11580
11581 if (RANGED_INTEGERP (1, XCDR (Vtool_bar_button_margin),
11582 INT_MAX - vmargin))
11583 vmargin += XFASTINT (XCDR (Vtool_bar_button_margin));
11584 }
11585
11586 if (auto_raise_tool_bar_buttons_p)
11587 {
11588 /* Add a `:relief' property to the image spec if the item is
11589 selected. */
11590 if (selected_p)
11591 {
11592 plist = Fplist_put (plist, QCrelief, make_number (-relief));
11593 hmargin -= relief;
11594 vmargin -= relief;
11595 }
11596 }
11597 else
11598 {
11599 /* If image is selected, display it pressed, i.e. with a
11600 negative relief. If it's not selected, display it with a
11601 raised relief. */
11602 plist = Fplist_put (plist, QCrelief,
11603 (selected_p
11604 ? make_number (-relief)
11605 : make_number (relief)));
11606 hmargin -= relief;
11607 vmargin -= relief;
11608 }
11609
11610 /* Put a margin around the image. */
11611 if (hmargin || vmargin)
11612 {
11613 if (hmargin == vmargin)
11614 plist = Fplist_put (plist, QCmargin, make_number (hmargin));
11615 else
11616 plist = Fplist_put (plist, QCmargin,
11617 Fcons (make_number (hmargin),
11618 make_number (vmargin)));
11619 }
11620
11621 /* If button is not enabled, and we don't have special images
11622 for the disabled state, make the image appear disabled by
11623 applying an appropriate algorithm to it. */
11624 if (!enabled_p && idx < 0)
11625 plist = Fplist_put (plist, QCconversion, Qdisabled);
11626
11627 /* Put a `display' text property on the string for the image to
11628 display. Put a `menu-item' property on the string that gives
11629 the start of this item's properties in the tool-bar items
11630 vector. */
11631 image = Fcons (Qimage, plist);
11632 props = list4 (Qdisplay, image,
11633 Qmenu_item, make_number (i * TOOL_BAR_ITEM_NSLOTS));
11634
11635 /* Let the last image hide all remaining spaces in the tool bar
11636 string. The string can be longer than needed when we reuse a
11637 previous string. */
11638 if (i + 1 == f->n_tool_bar_items)
11639 end = SCHARS (f->desired_tool_bar_string);
11640 else
11641 end = i + 1;
11642 Fadd_text_properties (make_number (i), make_number (end),
11643 props, f->desired_tool_bar_string);
11644 #undef PROP
11645 }
11646
11647 UNGCPRO;
11648 }
11649
11650
11651 /* Display one line of the tool-bar of frame IT->f.
11652
11653 HEIGHT specifies the desired height of the tool-bar line.
11654 If the actual height of the glyph row is less than HEIGHT, the
11655 row's height is increased to HEIGHT, and the icons are centered
11656 vertically in the new height.
11657
11658 If HEIGHT is -1, we are counting needed tool-bar lines, so don't
11659 count a final empty row in case the tool-bar width exactly matches
11660 the window width.
11661 */
11662
11663 static void
11664 display_tool_bar_line (struct it *it, int height)
11665 {
11666 struct glyph_row *row = it->glyph_row;
11667 int max_x = it->last_visible_x;
11668 struct glyph *last;
11669
11670 prepare_desired_row (row);
11671 row->y = it->current_y;
11672
11673 /* Note that this isn't made use of if the face hasn't a box,
11674 so there's no need to check the face here. */
11675 it->start_of_box_run_p = 1;
11676
11677 while (it->current_x < max_x)
11678 {
11679 int x, n_glyphs_before, i, nglyphs;
11680 struct it it_before;
11681
11682 /* Get the next display element. */
11683 if (!get_next_display_element (it))
11684 {
11685 /* Don't count empty row if we are counting needed tool-bar lines. */
11686 if (height < 0 && !it->hpos)
11687 return;
11688 break;
11689 }
11690
11691 /* Produce glyphs. */
11692 n_glyphs_before = row->used[TEXT_AREA];
11693 it_before = *it;
11694
11695 PRODUCE_GLYPHS (it);
11696
11697 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
11698 i = 0;
11699 x = it_before.current_x;
11700 while (i < nglyphs)
11701 {
11702 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
11703
11704 if (x + glyph->pixel_width > max_x)
11705 {
11706 /* Glyph doesn't fit on line. Backtrack. */
11707 row->used[TEXT_AREA] = n_glyphs_before;
11708 *it = it_before;
11709 /* If this is the only glyph on this line, it will never fit on the
11710 tool-bar, so skip it. But ensure there is at least one glyph,
11711 so we don't accidentally disable the tool-bar. */
11712 if (n_glyphs_before == 0
11713 && (it->vpos > 0 || IT_STRING_CHARPOS (*it) < it->end_charpos-1))
11714 break;
11715 goto out;
11716 }
11717
11718 ++it->hpos;
11719 x += glyph->pixel_width;
11720 ++i;
11721 }
11722
11723 /* Stop at line end. */
11724 if (ITERATOR_AT_END_OF_LINE_P (it))
11725 break;
11726
11727 set_iterator_to_next (it, 1);
11728 }
11729
11730 out:;
11731
11732 row->displays_text_p = row->used[TEXT_AREA] != 0;
11733
11734 /* Use default face for the border below the tool bar.
11735
11736 FIXME: When auto-resize-tool-bars is grow-only, there is
11737 no additional border below the possibly empty tool-bar lines.
11738 So to make the extra empty lines look "normal", we have to
11739 use the tool-bar face for the border too. */
11740 if (!row->displays_text_p && !EQ (Vauto_resize_tool_bars, Qgrow_only))
11741 it->face_id = DEFAULT_FACE_ID;
11742
11743 extend_face_to_end_of_line (it);
11744 last = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
11745 last->right_box_line_p = 1;
11746 if (last == row->glyphs[TEXT_AREA])
11747 last->left_box_line_p = 1;
11748
11749 /* Make line the desired height and center it vertically. */
11750 if ((height -= it->max_ascent + it->max_descent) > 0)
11751 {
11752 /* Don't add more than one line height. */
11753 height %= FRAME_LINE_HEIGHT (it->f);
11754 it->max_ascent += height / 2;
11755 it->max_descent += (height + 1) / 2;
11756 }
11757
11758 compute_line_metrics (it);
11759
11760 /* If line is empty, make it occupy the rest of the tool-bar. */
11761 if (!row->displays_text_p)
11762 {
11763 row->height = row->phys_height = it->last_visible_y - row->y;
11764 row->visible_height = row->height;
11765 row->ascent = row->phys_ascent = 0;
11766 row->extra_line_spacing = 0;
11767 }
11768
11769 row->full_width_p = 1;
11770 row->continued_p = 0;
11771 row->truncated_on_left_p = 0;
11772 row->truncated_on_right_p = 0;
11773
11774 it->current_x = it->hpos = 0;
11775 it->current_y += row->height;
11776 ++it->vpos;
11777 ++it->glyph_row;
11778 }
11779
11780
11781 /* Max tool-bar height. */
11782
11783 #define MAX_FRAME_TOOL_BAR_HEIGHT(f) \
11784 ((FRAME_LINE_HEIGHT (f) * FRAME_LINES (f)))
11785
11786 /* Value is the number of screen lines needed to make all tool-bar
11787 items of frame F visible. The number of actual rows needed is
11788 returned in *N_ROWS if non-NULL. */
11789
11790 static int
11791 tool_bar_lines_needed (struct frame *f, int *n_rows)
11792 {
11793 struct window *w = XWINDOW (f->tool_bar_window);
11794 struct it it;
11795 /* tool_bar_lines_needed is called from redisplay_tool_bar after building
11796 the desired matrix, so use (unused) mode-line row as temporary row to
11797 avoid destroying the first tool-bar row. */
11798 struct glyph_row *temp_row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
11799
11800 /* Initialize an iterator for iteration over
11801 F->desired_tool_bar_string in the tool-bar window of frame F. */
11802 init_iterator (&it, w, -1, -1, temp_row, TOOL_BAR_FACE_ID);
11803 it.first_visible_x = 0;
11804 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
11805 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
11806 it.paragraph_embedding = L2R;
11807
11808 while (!ITERATOR_AT_END_P (&it))
11809 {
11810 clear_glyph_row (temp_row);
11811 it.glyph_row = temp_row;
11812 display_tool_bar_line (&it, -1);
11813 }
11814 clear_glyph_row (temp_row);
11815
11816 /* f->n_tool_bar_rows == 0 means "unknown"; -1 means no tool-bar. */
11817 if (n_rows)
11818 *n_rows = it.vpos > 0 ? it.vpos : -1;
11819
11820 return (it.current_y + FRAME_LINE_HEIGHT (f) - 1) / FRAME_LINE_HEIGHT (f);
11821 }
11822
11823
11824 DEFUN ("tool-bar-lines-needed", Ftool_bar_lines_needed, Stool_bar_lines_needed,
11825 0, 1, 0,
11826 doc: /* Return the number of lines occupied by the tool bar of FRAME. */)
11827 (Lisp_Object frame)
11828 {
11829 struct frame *f;
11830 struct window *w;
11831 int nlines = 0;
11832
11833 if (NILP (frame))
11834 frame = selected_frame;
11835 else
11836 CHECK_FRAME (frame);
11837 f = XFRAME (frame);
11838
11839 if (WINDOWP (f->tool_bar_window)
11840 && (w = XWINDOW (f->tool_bar_window),
11841 WINDOW_TOTAL_LINES (w) > 0))
11842 {
11843 update_tool_bar (f, 1);
11844 if (f->n_tool_bar_items)
11845 {
11846 build_desired_tool_bar_string (f);
11847 nlines = tool_bar_lines_needed (f, NULL);
11848 }
11849 }
11850
11851 return make_number (nlines);
11852 }
11853
11854
11855 /* Display the tool-bar of frame F. Value is non-zero if tool-bar's
11856 height should be changed. */
11857
11858 static int
11859 redisplay_tool_bar (struct frame *f)
11860 {
11861 struct window *w;
11862 struct it it;
11863 struct glyph_row *row;
11864
11865 #if defined (USE_GTK) || defined (HAVE_NS)
11866 if (FRAME_EXTERNAL_TOOL_BAR (f))
11867 update_frame_tool_bar (f);
11868 return 0;
11869 #endif
11870
11871 /* If frame hasn't a tool-bar window or if it is zero-height, don't
11872 do anything. This means you must start with tool-bar-lines
11873 non-zero to get the auto-sizing effect. Or in other words, you
11874 can turn off tool-bars by specifying tool-bar-lines zero. */
11875 if (!WINDOWP (f->tool_bar_window)
11876 || (w = XWINDOW (f->tool_bar_window),
11877 WINDOW_TOTAL_LINES (w) == 0))
11878 return 0;
11879
11880 /* Set up an iterator for the tool-bar window. */
11881 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
11882 it.first_visible_x = 0;
11883 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
11884 row = it.glyph_row;
11885
11886 /* Build a string that represents the contents of the tool-bar. */
11887 build_desired_tool_bar_string (f);
11888 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
11889 /* FIXME: This should be controlled by a user option. But it
11890 doesn't make sense to have an R2L tool bar if the menu bar cannot
11891 be drawn also R2L, and making the menu bar R2L is tricky due
11892 toolkit-specific code that implements it. If an R2L tool bar is
11893 ever supported, display_tool_bar_line should also be augmented to
11894 call unproduce_glyphs like display_line and display_string
11895 do. */
11896 it.paragraph_embedding = L2R;
11897
11898 if (f->n_tool_bar_rows == 0)
11899 {
11900 int nlines;
11901
11902 if ((nlines = tool_bar_lines_needed (f, &f->n_tool_bar_rows),
11903 nlines != WINDOW_TOTAL_LINES (w)))
11904 {
11905 Lisp_Object frame;
11906 int old_height = WINDOW_TOTAL_LINES (w);
11907
11908 XSETFRAME (frame, f);
11909 Fmodify_frame_parameters (frame,
11910 Fcons (Fcons (Qtool_bar_lines,
11911 make_number (nlines)),
11912 Qnil));
11913 if (WINDOW_TOTAL_LINES (w) != old_height)
11914 {
11915 clear_glyph_matrix (w->desired_matrix);
11916 fonts_changed_p = 1;
11917 return 1;
11918 }
11919 }
11920 }
11921
11922 /* Display as many lines as needed to display all tool-bar items. */
11923
11924 if (f->n_tool_bar_rows > 0)
11925 {
11926 int border, rows, height, extra;
11927
11928 if (TYPE_RANGED_INTEGERP (int, Vtool_bar_border))
11929 border = XINT (Vtool_bar_border);
11930 else if (EQ (Vtool_bar_border, Qinternal_border_width))
11931 border = FRAME_INTERNAL_BORDER_WIDTH (f);
11932 else if (EQ (Vtool_bar_border, Qborder_width))
11933 border = f->border_width;
11934 else
11935 border = 0;
11936 if (border < 0)
11937 border = 0;
11938
11939 rows = f->n_tool_bar_rows;
11940 height = max (1, (it.last_visible_y - border) / rows);
11941 extra = it.last_visible_y - border - height * rows;
11942
11943 while (it.current_y < it.last_visible_y)
11944 {
11945 int h = 0;
11946 if (extra > 0 && rows-- > 0)
11947 {
11948 h = (extra + rows - 1) / rows;
11949 extra -= h;
11950 }
11951 display_tool_bar_line (&it, height + h);
11952 }
11953 }
11954 else
11955 {
11956 while (it.current_y < it.last_visible_y)
11957 display_tool_bar_line (&it, 0);
11958 }
11959
11960 /* It doesn't make much sense to try scrolling in the tool-bar
11961 window, so don't do it. */
11962 w->desired_matrix->no_scrolling_p = 1;
11963 w->must_be_updated_p = 1;
11964
11965 if (!NILP (Vauto_resize_tool_bars))
11966 {
11967 int max_tool_bar_height = MAX_FRAME_TOOL_BAR_HEIGHT (f);
11968 int change_height_p = 0;
11969
11970 /* If we couldn't display everything, change the tool-bar's
11971 height if there is room for more. */
11972 if (IT_STRING_CHARPOS (it) < it.end_charpos
11973 && it.current_y < max_tool_bar_height)
11974 change_height_p = 1;
11975
11976 row = it.glyph_row - 1;
11977
11978 /* If there are blank lines at the end, except for a partially
11979 visible blank line at the end that is smaller than
11980 FRAME_LINE_HEIGHT, change the tool-bar's height. */
11981 if (!row->displays_text_p
11982 && row->height >= FRAME_LINE_HEIGHT (f))
11983 change_height_p = 1;
11984
11985 /* If row displays tool-bar items, but is partially visible,
11986 change the tool-bar's height. */
11987 if (row->displays_text_p
11988 && MATRIX_ROW_BOTTOM_Y (row) > it.last_visible_y
11989 && MATRIX_ROW_BOTTOM_Y (row) < max_tool_bar_height)
11990 change_height_p = 1;
11991
11992 /* Resize windows as needed by changing the `tool-bar-lines'
11993 frame parameter. */
11994 if (change_height_p)
11995 {
11996 Lisp_Object frame;
11997 int old_height = WINDOW_TOTAL_LINES (w);
11998 int nrows;
11999 int nlines = tool_bar_lines_needed (f, &nrows);
12000
12001 change_height_p = ((EQ (Vauto_resize_tool_bars, Qgrow_only)
12002 && !f->minimize_tool_bar_window_p)
12003 ? (nlines > old_height)
12004 : (nlines != old_height));
12005 f->minimize_tool_bar_window_p = 0;
12006
12007 if (change_height_p)
12008 {
12009 XSETFRAME (frame, f);
12010 Fmodify_frame_parameters (frame,
12011 Fcons (Fcons (Qtool_bar_lines,
12012 make_number (nlines)),
12013 Qnil));
12014 if (WINDOW_TOTAL_LINES (w) != old_height)
12015 {
12016 clear_glyph_matrix (w->desired_matrix);
12017 f->n_tool_bar_rows = nrows;
12018 fonts_changed_p = 1;
12019 return 1;
12020 }
12021 }
12022 }
12023 }
12024
12025 f->minimize_tool_bar_window_p = 0;
12026 return 0;
12027 }
12028
12029
12030 /* Get information about the tool-bar item which is displayed in GLYPH
12031 on frame F. Return in *PROP_IDX the index where tool-bar item
12032 properties start in F->tool_bar_items. Value is zero if
12033 GLYPH doesn't display a tool-bar item. */
12034
12035 static int
12036 tool_bar_item_info (struct frame *f, struct glyph *glyph, int *prop_idx)
12037 {
12038 Lisp_Object prop;
12039 int success_p;
12040 int charpos;
12041
12042 /* This function can be called asynchronously, which means we must
12043 exclude any possibility that Fget_text_property signals an
12044 error. */
12045 charpos = min (SCHARS (f->current_tool_bar_string), glyph->charpos);
12046 charpos = max (0, charpos);
12047
12048 /* Get the text property `menu-item' at pos. The value of that
12049 property is the start index of this item's properties in
12050 F->tool_bar_items. */
12051 prop = Fget_text_property (make_number (charpos),
12052 Qmenu_item, f->current_tool_bar_string);
12053 if (INTEGERP (prop))
12054 {
12055 *prop_idx = XINT (prop);
12056 success_p = 1;
12057 }
12058 else
12059 success_p = 0;
12060
12061 return success_p;
12062 }
12063
12064 \f
12065 /* Get information about the tool-bar item at position X/Y on frame F.
12066 Return in *GLYPH a pointer to the glyph of the tool-bar item in
12067 the current matrix of the tool-bar window of F, or NULL if not
12068 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
12069 item in F->tool_bar_items. Value is
12070
12071 -1 if X/Y is not on a tool-bar item
12072 0 if X/Y is on the same item that was highlighted before.
12073 1 otherwise. */
12074
12075 static int
12076 get_tool_bar_item (struct frame *f, int x, int y, struct glyph **glyph,
12077 int *hpos, int *vpos, int *prop_idx)
12078 {
12079 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
12080 struct window *w = XWINDOW (f->tool_bar_window);
12081 int area;
12082
12083 /* Find the glyph under X/Y. */
12084 *glyph = x_y_to_hpos_vpos (w, x, y, hpos, vpos, 0, 0, &area);
12085 if (*glyph == NULL)
12086 return -1;
12087
12088 /* Get the start of this tool-bar item's properties in
12089 f->tool_bar_items. */
12090 if (!tool_bar_item_info (f, *glyph, prop_idx))
12091 return -1;
12092
12093 /* Is mouse on the highlighted item? */
12094 if (EQ (f->tool_bar_window, hlinfo->mouse_face_window)
12095 && *vpos >= hlinfo->mouse_face_beg_row
12096 && *vpos <= hlinfo->mouse_face_end_row
12097 && (*vpos > hlinfo->mouse_face_beg_row
12098 || *hpos >= hlinfo->mouse_face_beg_col)
12099 && (*vpos < hlinfo->mouse_face_end_row
12100 || *hpos < hlinfo->mouse_face_end_col
12101 || hlinfo->mouse_face_past_end))
12102 return 0;
12103
12104 return 1;
12105 }
12106
12107
12108 /* EXPORT:
12109 Handle mouse button event on the tool-bar of frame F, at
12110 frame-relative coordinates X/Y. DOWN_P is 1 for a button press,
12111 0 for button release. MODIFIERS is event modifiers for button
12112 release. */
12113
12114 void
12115 handle_tool_bar_click (struct frame *f, int x, int y, int down_p,
12116 int modifiers)
12117 {
12118 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
12119 struct window *w = XWINDOW (f->tool_bar_window);
12120 int hpos, vpos, prop_idx;
12121 struct glyph *glyph;
12122 Lisp_Object enabled_p;
12123
12124 /* If not on the highlighted tool-bar item, return. */
12125 frame_to_window_pixel_xy (w, &x, &y);
12126 if (get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx) != 0)
12127 return;
12128
12129 /* If item is disabled, do nothing. */
12130 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
12131 if (NILP (enabled_p))
12132 return;
12133
12134 if (down_p)
12135 {
12136 /* Show item in pressed state. */
12137 show_mouse_face (hlinfo, DRAW_IMAGE_SUNKEN);
12138 hlinfo->mouse_face_image_state = DRAW_IMAGE_SUNKEN;
12139 last_tool_bar_item = prop_idx;
12140 }
12141 else
12142 {
12143 Lisp_Object key, frame;
12144 struct input_event event;
12145 EVENT_INIT (event);
12146
12147 /* Show item in released state. */
12148 show_mouse_face (hlinfo, DRAW_IMAGE_RAISED);
12149 hlinfo->mouse_face_image_state = DRAW_IMAGE_RAISED;
12150
12151 key = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_KEY);
12152
12153 XSETFRAME (frame, f);
12154 event.kind = TOOL_BAR_EVENT;
12155 event.frame_or_window = frame;
12156 event.arg = frame;
12157 kbd_buffer_store_event (&event);
12158
12159 event.kind = TOOL_BAR_EVENT;
12160 event.frame_or_window = frame;
12161 event.arg = key;
12162 event.modifiers = modifiers;
12163 kbd_buffer_store_event (&event);
12164 last_tool_bar_item = -1;
12165 }
12166 }
12167
12168
12169 /* Possibly highlight a tool-bar item on frame F when mouse moves to
12170 tool-bar window-relative coordinates X/Y. Called from
12171 note_mouse_highlight. */
12172
12173 static void
12174 note_tool_bar_highlight (struct frame *f, int x, int y)
12175 {
12176 Lisp_Object window = f->tool_bar_window;
12177 struct window *w = XWINDOW (window);
12178 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
12179 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
12180 int hpos, vpos;
12181 struct glyph *glyph;
12182 struct glyph_row *row;
12183 int i;
12184 Lisp_Object enabled_p;
12185 int prop_idx;
12186 enum draw_glyphs_face draw = DRAW_IMAGE_RAISED;
12187 int mouse_down_p, rc;
12188
12189 /* Function note_mouse_highlight is called with negative X/Y
12190 values when mouse moves outside of the frame. */
12191 if (x <= 0 || y <= 0)
12192 {
12193 clear_mouse_face (hlinfo);
12194 return;
12195 }
12196
12197 rc = get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx);
12198 if (rc < 0)
12199 {
12200 /* Not on tool-bar item. */
12201 clear_mouse_face (hlinfo);
12202 return;
12203 }
12204 else if (rc == 0)
12205 /* On same tool-bar item as before. */
12206 goto set_help_echo;
12207
12208 clear_mouse_face (hlinfo);
12209
12210 /* Mouse is down, but on different tool-bar item? */
12211 mouse_down_p = (dpyinfo->grabbed
12212 && f == last_mouse_frame
12213 && FRAME_LIVE_P (f));
12214 if (mouse_down_p
12215 && last_tool_bar_item != prop_idx)
12216 return;
12217
12218 hlinfo->mouse_face_image_state = DRAW_NORMAL_TEXT;
12219 draw = mouse_down_p ? DRAW_IMAGE_SUNKEN : DRAW_IMAGE_RAISED;
12220
12221 /* If tool-bar item is not enabled, don't highlight it. */
12222 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
12223 if (!NILP (enabled_p))
12224 {
12225 /* Compute the x-position of the glyph. In front and past the
12226 image is a space. We include this in the highlighted area. */
12227 row = MATRIX_ROW (w->current_matrix, vpos);
12228 for (i = x = 0; i < hpos; ++i)
12229 x += row->glyphs[TEXT_AREA][i].pixel_width;
12230
12231 /* Record this as the current active region. */
12232 hlinfo->mouse_face_beg_col = hpos;
12233 hlinfo->mouse_face_beg_row = vpos;
12234 hlinfo->mouse_face_beg_x = x;
12235 hlinfo->mouse_face_beg_y = row->y;
12236 hlinfo->mouse_face_past_end = 0;
12237
12238 hlinfo->mouse_face_end_col = hpos + 1;
12239 hlinfo->mouse_face_end_row = vpos;
12240 hlinfo->mouse_face_end_x = x + glyph->pixel_width;
12241 hlinfo->mouse_face_end_y = row->y;
12242 hlinfo->mouse_face_window = window;
12243 hlinfo->mouse_face_face_id = TOOL_BAR_FACE_ID;
12244
12245 /* Display it as active. */
12246 show_mouse_face (hlinfo, draw);
12247 hlinfo->mouse_face_image_state = draw;
12248 }
12249
12250 set_help_echo:
12251
12252 /* Set help_echo_string to a help string to display for this tool-bar item.
12253 XTread_socket does the rest. */
12254 help_echo_object = help_echo_window = Qnil;
12255 help_echo_pos = -1;
12256 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_HELP);
12257 if (NILP (help_echo_string))
12258 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_CAPTION);
12259 }
12260
12261 #endif /* HAVE_WINDOW_SYSTEM */
12262
12263
12264 \f
12265 /************************************************************************
12266 Horizontal scrolling
12267 ************************************************************************/
12268
12269 static int hscroll_window_tree (Lisp_Object);
12270 static int hscroll_windows (Lisp_Object);
12271
12272 /* For all leaf windows in the window tree rooted at WINDOW, set their
12273 hscroll value so that PT is (i) visible in the window, and (ii) so
12274 that it is not within a certain margin at the window's left and
12275 right border. Value is non-zero if any window's hscroll has been
12276 changed. */
12277
12278 static int
12279 hscroll_window_tree (Lisp_Object window)
12280 {
12281 int hscrolled_p = 0;
12282 int hscroll_relative_p = FLOATP (Vhscroll_step);
12283 int hscroll_step_abs = 0;
12284 double hscroll_step_rel = 0;
12285
12286 if (hscroll_relative_p)
12287 {
12288 hscroll_step_rel = XFLOAT_DATA (Vhscroll_step);
12289 if (hscroll_step_rel < 0)
12290 {
12291 hscroll_relative_p = 0;
12292 hscroll_step_abs = 0;
12293 }
12294 }
12295 else if (TYPE_RANGED_INTEGERP (int, Vhscroll_step))
12296 {
12297 hscroll_step_abs = XINT (Vhscroll_step);
12298 if (hscroll_step_abs < 0)
12299 hscroll_step_abs = 0;
12300 }
12301 else
12302 hscroll_step_abs = 0;
12303
12304 while (WINDOWP (window))
12305 {
12306 struct window *w = XWINDOW (window);
12307
12308 if (WINDOWP (w->hchild))
12309 hscrolled_p |= hscroll_window_tree (w->hchild);
12310 else if (WINDOWP (w->vchild))
12311 hscrolled_p |= hscroll_window_tree (w->vchild);
12312 else if (w->cursor.vpos >= 0)
12313 {
12314 int h_margin;
12315 int text_area_width;
12316 struct glyph_row *current_cursor_row
12317 = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
12318 struct glyph_row *desired_cursor_row
12319 = MATRIX_ROW (w->desired_matrix, w->cursor.vpos);
12320 struct glyph_row *cursor_row
12321 = (desired_cursor_row->enabled_p
12322 ? desired_cursor_row
12323 : current_cursor_row);
12324 int row_r2l_p = cursor_row->reversed_p;
12325
12326 text_area_width = window_box_width (w, TEXT_AREA);
12327
12328 /* Scroll when cursor is inside this scroll margin. */
12329 h_margin = hscroll_margin * WINDOW_FRAME_COLUMN_WIDTH (w);
12330
12331 if (!NILP (Fbuffer_local_value (Qauto_hscroll_mode, w->buffer))
12332 /* For left-to-right rows, hscroll when cursor is either
12333 (i) inside the right hscroll margin, or (ii) if it is
12334 inside the left margin and the window is already
12335 hscrolled. */
12336 && ((!row_r2l_p
12337 && ((XFASTINT (w->hscroll)
12338 && w->cursor.x <= h_margin)
12339 || (cursor_row->enabled_p
12340 && cursor_row->truncated_on_right_p
12341 && (w->cursor.x >= text_area_width - h_margin))))
12342 /* For right-to-left rows, the logic is similar,
12343 except that rules for scrolling to left and right
12344 are reversed. E.g., if cursor.x <= h_margin, we
12345 need to hscroll "to the right" unconditionally,
12346 and that will scroll the screen to the left so as
12347 to reveal the next portion of the row. */
12348 || (row_r2l_p
12349 && ((cursor_row->enabled_p
12350 /* FIXME: It is confusing to set the
12351 truncated_on_right_p flag when R2L rows
12352 are actually truncated on the left. */
12353 && cursor_row->truncated_on_right_p
12354 && w->cursor.x <= h_margin)
12355 || (XFASTINT (w->hscroll)
12356 && (w->cursor.x >= text_area_width - h_margin))))))
12357 {
12358 struct it it;
12359 ptrdiff_t hscroll;
12360 struct buffer *saved_current_buffer;
12361 ptrdiff_t pt;
12362 int wanted_x;
12363
12364 /* Find point in a display of infinite width. */
12365 saved_current_buffer = current_buffer;
12366 current_buffer = XBUFFER (w->buffer);
12367
12368 if (w == XWINDOW (selected_window))
12369 pt = PT;
12370 else
12371 {
12372 pt = marker_position (w->pointm);
12373 pt = max (BEGV, pt);
12374 pt = min (ZV, pt);
12375 }
12376
12377 /* Move iterator to pt starting at cursor_row->start in
12378 a line with infinite width. */
12379 init_to_row_start (&it, w, cursor_row);
12380 it.last_visible_x = INFINITY;
12381 move_it_in_display_line_to (&it, pt, -1, MOVE_TO_POS);
12382 current_buffer = saved_current_buffer;
12383
12384 /* Position cursor in window. */
12385 if (!hscroll_relative_p && hscroll_step_abs == 0)
12386 hscroll = max (0, (it.current_x
12387 - (ITERATOR_AT_END_OF_LINE_P (&it)
12388 ? (text_area_width - 4 * FRAME_COLUMN_WIDTH (it.f))
12389 : (text_area_width / 2))))
12390 / FRAME_COLUMN_WIDTH (it.f);
12391 else if ((!row_r2l_p
12392 && w->cursor.x >= text_area_width - h_margin)
12393 || (row_r2l_p && w->cursor.x <= h_margin))
12394 {
12395 if (hscroll_relative_p)
12396 wanted_x = text_area_width * (1 - hscroll_step_rel)
12397 - h_margin;
12398 else
12399 wanted_x = text_area_width
12400 - hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
12401 - h_margin;
12402 hscroll
12403 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
12404 }
12405 else
12406 {
12407 if (hscroll_relative_p)
12408 wanted_x = text_area_width * hscroll_step_rel
12409 + h_margin;
12410 else
12411 wanted_x = hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
12412 + h_margin;
12413 hscroll
12414 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
12415 }
12416 hscroll = max (hscroll, XFASTINT (w->min_hscroll));
12417
12418 /* Don't prevent redisplay optimizations if hscroll
12419 hasn't changed, as it will unnecessarily slow down
12420 redisplay. */
12421 if (XFASTINT (w->hscroll) != hscroll)
12422 {
12423 XBUFFER (w->buffer)->prevent_redisplay_optimizations_p = 1;
12424 w->hscroll = make_number (hscroll);
12425 hscrolled_p = 1;
12426 }
12427 }
12428 }
12429
12430 window = w->next;
12431 }
12432
12433 /* Value is non-zero if hscroll of any leaf window has been changed. */
12434 return hscrolled_p;
12435 }
12436
12437
12438 /* Set hscroll so that cursor is visible and not inside horizontal
12439 scroll margins for all windows in the tree rooted at WINDOW. See
12440 also hscroll_window_tree above. Value is non-zero if any window's
12441 hscroll has been changed. If it has, desired matrices on the frame
12442 of WINDOW are cleared. */
12443
12444 static int
12445 hscroll_windows (Lisp_Object window)
12446 {
12447 int hscrolled_p = hscroll_window_tree (window);
12448 if (hscrolled_p)
12449 clear_desired_matrices (XFRAME (WINDOW_FRAME (XWINDOW (window))));
12450 return hscrolled_p;
12451 }
12452
12453
12454 \f
12455 /************************************************************************
12456 Redisplay
12457 ************************************************************************/
12458
12459 /* Variables holding some state of redisplay if GLYPH_DEBUG is defined
12460 to a non-zero value. This is sometimes handy to have in a debugger
12461 session. */
12462
12463 #if GLYPH_DEBUG
12464
12465 /* First and last unchanged row for try_window_id. */
12466
12467 static int debug_first_unchanged_at_end_vpos;
12468 static int debug_last_unchanged_at_beg_vpos;
12469
12470 /* Delta vpos and y. */
12471
12472 static int debug_dvpos, debug_dy;
12473
12474 /* Delta in characters and bytes for try_window_id. */
12475
12476 static ptrdiff_t debug_delta, debug_delta_bytes;
12477
12478 /* Values of window_end_pos and window_end_vpos at the end of
12479 try_window_id. */
12480
12481 static ptrdiff_t debug_end_vpos;
12482
12483 /* Append a string to W->desired_matrix->method. FMT is a printf
12484 format string. If trace_redisplay_p is non-zero also printf the
12485 resulting string to stderr. */
12486
12487 static void debug_method_add (struct window *, char const *, ...)
12488 ATTRIBUTE_FORMAT_PRINTF (2, 3);
12489
12490 static void
12491 debug_method_add (struct window *w, char const *fmt, ...)
12492 {
12493 char buffer[512];
12494 char *method = w->desired_matrix->method;
12495 int len = strlen (method);
12496 int size = sizeof w->desired_matrix->method;
12497 int remaining = size - len - 1;
12498 va_list ap;
12499
12500 va_start (ap, fmt);
12501 vsprintf (buffer, fmt, ap);
12502 va_end (ap);
12503 if (len && remaining)
12504 {
12505 method[len] = '|';
12506 --remaining, ++len;
12507 }
12508
12509 strncpy (method + len, buffer, remaining);
12510
12511 if (trace_redisplay_p)
12512 fprintf (stderr, "%p (%s): %s\n",
12513 w,
12514 ((BUFFERP (w->buffer)
12515 && STRINGP (BVAR (XBUFFER (w->buffer), name)))
12516 ? SSDATA (BVAR (XBUFFER (w->buffer), name))
12517 : "no buffer"),
12518 buffer);
12519 }
12520
12521 #endif /* GLYPH_DEBUG */
12522
12523
12524 /* Value is non-zero if all changes in window W, which displays
12525 current_buffer, are in the text between START and END. START is a
12526 buffer position, END is given as a distance from Z. Used in
12527 redisplay_internal for display optimization. */
12528
12529 static inline int
12530 text_outside_line_unchanged_p (struct window *w,
12531 ptrdiff_t start, ptrdiff_t end)
12532 {
12533 int unchanged_p = 1;
12534
12535 /* If text or overlays have changed, see where. */
12536 if (XFASTINT (w->last_modified) < MODIFF
12537 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
12538 {
12539 /* Gap in the line? */
12540 if (GPT < start || Z - GPT < end)
12541 unchanged_p = 0;
12542
12543 /* Changes start in front of the line, or end after it? */
12544 if (unchanged_p
12545 && (BEG_UNCHANGED < start - 1
12546 || END_UNCHANGED < end))
12547 unchanged_p = 0;
12548
12549 /* If selective display, can't optimize if changes start at the
12550 beginning of the line. */
12551 if (unchanged_p
12552 && INTEGERP (BVAR (current_buffer, selective_display))
12553 && XINT (BVAR (current_buffer, selective_display)) > 0
12554 && (BEG_UNCHANGED < start || GPT <= start))
12555 unchanged_p = 0;
12556
12557 /* If there are overlays at the start or end of the line, these
12558 may have overlay strings with newlines in them. A change at
12559 START, for instance, may actually concern the display of such
12560 overlay strings as well, and they are displayed on different
12561 lines. So, quickly rule out this case. (For the future, it
12562 might be desirable to implement something more telling than
12563 just BEG/END_UNCHANGED.) */
12564 if (unchanged_p)
12565 {
12566 if (BEG + BEG_UNCHANGED == start
12567 && overlay_touches_p (start))
12568 unchanged_p = 0;
12569 if (END_UNCHANGED == end
12570 && overlay_touches_p (Z - end))
12571 unchanged_p = 0;
12572 }
12573
12574 /* Under bidi reordering, adding or deleting a character in the
12575 beginning of a paragraph, before the first strong directional
12576 character, can change the base direction of the paragraph (unless
12577 the buffer specifies a fixed paragraph direction), which will
12578 require to redisplay the whole paragraph. It might be worthwhile
12579 to find the paragraph limits and widen the range of redisplayed
12580 lines to that, but for now just give up this optimization. */
12581 if (!NILP (BVAR (XBUFFER (w->buffer), bidi_display_reordering))
12582 && NILP (BVAR (XBUFFER (w->buffer), bidi_paragraph_direction)))
12583 unchanged_p = 0;
12584 }
12585
12586 return unchanged_p;
12587 }
12588
12589
12590 /* Do a frame update, taking possible shortcuts into account. This is
12591 the main external entry point for redisplay.
12592
12593 If the last redisplay displayed an echo area message and that message
12594 is no longer requested, we clear the echo area or bring back the
12595 mini-buffer if that is in use. */
12596
12597 void
12598 redisplay (void)
12599 {
12600 redisplay_internal ();
12601 }
12602
12603
12604 static Lisp_Object
12605 overlay_arrow_string_or_property (Lisp_Object var)
12606 {
12607 Lisp_Object val;
12608
12609 if (val = Fget (var, Qoverlay_arrow_string), STRINGP (val))
12610 return val;
12611
12612 return Voverlay_arrow_string;
12613 }
12614
12615 /* Return 1 if there are any overlay-arrows in current_buffer. */
12616 static int
12617 overlay_arrow_in_current_buffer_p (void)
12618 {
12619 Lisp_Object vlist;
12620
12621 for (vlist = Voverlay_arrow_variable_list;
12622 CONSP (vlist);
12623 vlist = XCDR (vlist))
12624 {
12625 Lisp_Object var = XCAR (vlist);
12626 Lisp_Object val;
12627
12628 if (!SYMBOLP (var))
12629 continue;
12630 val = find_symbol_value (var);
12631 if (MARKERP (val)
12632 && current_buffer == XMARKER (val)->buffer)
12633 return 1;
12634 }
12635 return 0;
12636 }
12637
12638
12639 /* Return 1 if any overlay_arrows have moved or overlay-arrow-string
12640 has changed. */
12641
12642 static int
12643 overlay_arrows_changed_p (void)
12644 {
12645 Lisp_Object vlist;
12646
12647 for (vlist = Voverlay_arrow_variable_list;
12648 CONSP (vlist);
12649 vlist = XCDR (vlist))
12650 {
12651 Lisp_Object var = XCAR (vlist);
12652 Lisp_Object val, pstr;
12653
12654 if (!SYMBOLP (var))
12655 continue;
12656 val = find_symbol_value (var);
12657 if (!MARKERP (val))
12658 continue;
12659 if (! EQ (COERCE_MARKER (val),
12660 Fget (var, Qlast_arrow_position))
12661 || ! (pstr = overlay_arrow_string_or_property (var),
12662 EQ (pstr, Fget (var, Qlast_arrow_string))))
12663 return 1;
12664 }
12665 return 0;
12666 }
12667
12668 /* Mark overlay arrows to be updated on next redisplay. */
12669
12670 static void
12671 update_overlay_arrows (int up_to_date)
12672 {
12673 Lisp_Object vlist;
12674
12675 for (vlist = Voverlay_arrow_variable_list;
12676 CONSP (vlist);
12677 vlist = XCDR (vlist))
12678 {
12679 Lisp_Object var = XCAR (vlist);
12680
12681 if (!SYMBOLP (var))
12682 continue;
12683
12684 if (up_to_date > 0)
12685 {
12686 Lisp_Object val = find_symbol_value (var);
12687 Fput (var, Qlast_arrow_position,
12688 COERCE_MARKER (val));
12689 Fput (var, Qlast_arrow_string,
12690 overlay_arrow_string_or_property (var));
12691 }
12692 else if (up_to_date < 0
12693 || !NILP (Fget (var, Qlast_arrow_position)))
12694 {
12695 Fput (var, Qlast_arrow_position, Qt);
12696 Fput (var, Qlast_arrow_string, Qt);
12697 }
12698 }
12699 }
12700
12701
12702 /* Return overlay arrow string to display at row.
12703 Return integer (bitmap number) for arrow bitmap in left fringe.
12704 Return nil if no overlay arrow. */
12705
12706 static Lisp_Object
12707 overlay_arrow_at_row (struct it *it, struct glyph_row *row)
12708 {
12709 Lisp_Object vlist;
12710
12711 for (vlist = Voverlay_arrow_variable_list;
12712 CONSP (vlist);
12713 vlist = XCDR (vlist))
12714 {
12715 Lisp_Object var = XCAR (vlist);
12716 Lisp_Object val;
12717
12718 if (!SYMBOLP (var))
12719 continue;
12720
12721 val = find_symbol_value (var);
12722
12723 if (MARKERP (val)
12724 && current_buffer == XMARKER (val)->buffer
12725 && (MATRIX_ROW_START_CHARPOS (row) == marker_position (val)))
12726 {
12727 if (FRAME_WINDOW_P (it->f)
12728 /* FIXME: if ROW->reversed_p is set, this should test
12729 the right fringe, not the left one. */
12730 && WINDOW_LEFT_FRINGE_WIDTH (it->w) > 0)
12731 {
12732 #ifdef HAVE_WINDOW_SYSTEM
12733 if (val = Fget (var, Qoverlay_arrow_bitmap), SYMBOLP (val))
12734 {
12735 int fringe_bitmap;
12736 if ((fringe_bitmap = lookup_fringe_bitmap (val)) != 0)
12737 return make_number (fringe_bitmap);
12738 }
12739 #endif
12740 return make_number (-1); /* Use default arrow bitmap */
12741 }
12742 return overlay_arrow_string_or_property (var);
12743 }
12744 }
12745
12746 return Qnil;
12747 }
12748
12749 /* Return 1 if point moved out of or into a composition. Otherwise
12750 return 0. PREV_BUF and PREV_PT are the last point buffer and
12751 position. BUF and PT are the current point buffer and position. */
12752
12753 static int
12754 check_point_in_composition (struct buffer *prev_buf, ptrdiff_t prev_pt,
12755 struct buffer *buf, ptrdiff_t pt)
12756 {
12757 ptrdiff_t start, end;
12758 Lisp_Object prop;
12759 Lisp_Object buffer;
12760
12761 XSETBUFFER (buffer, buf);
12762 /* Check a composition at the last point if point moved within the
12763 same buffer. */
12764 if (prev_buf == buf)
12765 {
12766 if (prev_pt == pt)
12767 /* Point didn't move. */
12768 return 0;
12769
12770 if (prev_pt > BUF_BEGV (buf) && prev_pt < BUF_ZV (buf)
12771 && find_composition (prev_pt, -1, &start, &end, &prop, buffer)
12772 && COMPOSITION_VALID_P (start, end, prop)
12773 && start < prev_pt && end > prev_pt)
12774 /* The last point was within the composition. Return 1 iff
12775 point moved out of the composition. */
12776 return (pt <= start || pt >= end);
12777 }
12778
12779 /* Check a composition at the current point. */
12780 return (pt > BUF_BEGV (buf) && pt < BUF_ZV (buf)
12781 && find_composition (pt, -1, &start, &end, &prop, buffer)
12782 && COMPOSITION_VALID_P (start, end, prop)
12783 && start < pt && end > pt);
12784 }
12785
12786
12787 /* Reconsider the setting of B->clip_changed which is displayed
12788 in window W. */
12789
12790 static inline void
12791 reconsider_clip_changes (struct window *w, struct buffer *b)
12792 {
12793 if (b->clip_changed
12794 && !NILP (w->window_end_valid)
12795 && w->current_matrix->buffer == b
12796 && w->current_matrix->zv == BUF_ZV (b)
12797 && w->current_matrix->begv == BUF_BEGV (b))
12798 b->clip_changed = 0;
12799
12800 /* If display wasn't paused, and W is not a tool bar window, see if
12801 point has been moved into or out of a composition. In that case,
12802 we set b->clip_changed to 1 to force updating the screen. If
12803 b->clip_changed has already been set to 1, we can skip this
12804 check. */
12805 if (!b->clip_changed
12806 && BUFFERP (w->buffer) && !NILP (w->window_end_valid))
12807 {
12808 ptrdiff_t pt;
12809
12810 if (w == XWINDOW (selected_window))
12811 pt = PT;
12812 else
12813 pt = marker_position (w->pointm);
12814
12815 if ((w->current_matrix->buffer != XBUFFER (w->buffer)
12816 || pt != XINT (w->last_point))
12817 && check_point_in_composition (w->current_matrix->buffer,
12818 XINT (w->last_point),
12819 XBUFFER (w->buffer), pt))
12820 b->clip_changed = 1;
12821 }
12822 }
12823 \f
12824
12825 /* Select FRAME to forward the values of frame-local variables into C
12826 variables so that the redisplay routines can access those values
12827 directly. */
12828
12829 static void
12830 select_frame_for_redisplay (Lisp_Object frame)
12831 {
12832 Lisp_Object tail, tem;
12833 Lisp_Object old = selected_frame;
12834 struct Lisp_Symbol *sym;
12835
12836 xassert (FRAMEP (frame) && FRAME_LIVE_P (XFRAME (frame)));
12837
12838 selected_frame = frame;
12839
12840 do {
12841 for (tail = XFRAME (frame)->param_alist; CONSP (tail); tail = XCDR (tail))
12842 if (CONSP (XCAR (tail))
12843 && (tem = XCAR (XCAR (tail)),
12844 SYMBOLP (tem))
12845 && (sym = indirect_variable (XSYMBOL (tem)),
12846 sym->redirect == SYMBOL_LOCALIZED)
12847 && sym->val.blv->frame_local)
12848 /* Use find_symbol_value rather than Fsymbol_value
12849 to avoid an error if it is void. */
12850 find_symbol_value (tem);
12851 } while (!EQ (frame, old) && (frame = old, 1));
12852 }
12853
12854
12855 #define STOP_POLLING \
12856 do { if (! polling_stopped_here) stop_polling (); \
12857 polling_stopped_here = 1; } while (0)
12858
12859 #define RESUME_POLLING \
12860 do { if (polling_stopped_here) start_polling (); \
12861 polling_stopped_here = 0; } while (0)
12862
12863
12864 /* Perhaps in the future avoid recentering windows if it
12865 is not necessary; currently that causes some problems. */
12866
12867 static void
12868 redisplay_internal (void)
12869 {
12870 struct window *w = XWINDOW (selected_window);
12871 struct window *sw;
12872 struct frame *fr;
12873 int pending;
12874 int must_finish = 0;
12875 struct text_pos tlbufpos, tlendpos;
12876 int number_of_visible_frames;
12877 ptrdiff_t count, count1;
12878 struct frame *sf;
12879 int polling_stopped_here = 0;
12880 Lisp_Object old_frame = selected_frame;
12881
12882 /* Non-zero means redisplay has to consider all windows on all
12883 frames. Zero means, only selected_window is considered. */
12884 int consider_all_windows_p;
12885
12886 /* Non-zero means redisplay has to redisplay the miniwindow */
12887 int update_miniwindow_p = 0;
12888
12889 TRACE ((stderr, "redisplay_internal %d\n", redisplaying_p));
12890
12891 /* No redisplay if running in batch mode or frame is not yet fully
12892 initialized, or redisplay is explicitly turned off by setting
12893 Vinhibit_redisplay. */
12894 if (FRAME_INITIAL_P (SELECTED_FRAME ())
12895 || !NILP (Vinhibit_redisplay))
12896 return;
12897
12898 /* Don't examine these until after testing Vinhibit_redisplay.
12899 When Emacs is shutting down, perhaps because its connection to
12900 X has dropped, we should not look at them at all. */
12901 fr = XFRAME (w->frame);
12902 sf = SELECTED_FRAME ();
12903
12904 if (!fr->glyphs_initialized_p)
12905 return;
12906
12907 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS)
12908 if (popup_activated ())
12909 return;
12910 #endif
12911
12912 /* I don't think this happens but let's be paranoid. */
12913 if (redisplaying_p)
12914 return;
12915
12916 /* Record a function that resets redisplaying_p to its old value
12917 when we leave this function. */
12918 count = SPECPDL_INDEX ();
12919 record_unwind_protect (unwind_redisplay,
12920 Fcons (make_number (redisplaying_p), selected_frame));
12921 ++redisplaying_p;
12922 specbind (Qinhibit_free_realized_faces, Qnil);
12923
12924 {
12925 Lisp_Object tail, frame;
12926
12927 FOR_EACH_FRAME (tail, frame)
12928 {
12929 struct frame *f = XFRAME (frame);
12930 f->already_hscrolled_p = 0;
12931 }
12932 }
12933
12934 retry:
12935 /* Remember the currently selected window. */
12936 sw = w;
12937
12938 if (!EQ (old_frame, selected_frame)
12939 && FRAME_LIVE_P (XFRAME (old_frame)))
12940 /* When running redisplay, we play a bit fast-and-loose and allow e.g.
12941 selected_frame and selected_window to be temporarily out-of-sync so
12942 when we come back here via `goto retry', we need to resync because we
12943 may need to run Elisp code (via prepare_menu_bars). */
12944 select_frame_for_redisplay (old_frame);
12945
12946 pending = 0;
12947 reconsider_clip_changes (w, current_buffer);
12948 last_escape_glyph_frame = NULL;
12949 last_escape_glyph_face_id = (1 << FACE_ID_BITS);
12950 last_glyphless_glyph_frame = NULL;
12951 last_glyphless_glyph_face_id = (1 << FACE_ID_BITS);
12952
12953 /* If new fonts have been loaded that make a glyph matrix adjustment
12954 necessary, do it. */
12955 if (fonts_changed_p)
12956 {
12957 adjust_glyphs (NULL);
12958 ++windows_or_buffers_changed;
12959 fonts_changed_p = 0;
12960 }
12961
12962 /* If face_change_count is non-zero, init_iterator will free all
12963 realized faces, which includes the faces referenced from current
12964 matrices. So, we can't reuse current matrices in this case. */
12965 if (face_change_count)
12966 ++windows_or_buffers_changed;
12967
12968 if ((FRAME_TERMCAP_P (sf) || FRAME_MSDOS_P (sf))
12969 && FRAME_TTY (sf)->previous_frame != sf)
12970 {
12971 /* Since frames on a single ASCII terminal share the same
12972 display area, displaying a different frame means redisplay
12973 the whole thing. */
12974 windows_or_buffers_changed++;
12975 SET_FRAME_GARBAGED (sf);
12976 #ifndef DOS_NT
12977 set_tty_color_mode (FRAME_TTY (sf), sf);
12978 #endif
12979 FRAME_TTY (sf)->previous_frame = sf;
12980 }
12981
12982 /* Set the visible flags for all frames. Do this before checking
12983 for resized or garbaged frames; they want to know if their frames
12984 are visible. See the comment in frame.h for
12985 FRAME_SAMPLE_VISIBILITY. */
12986 {
12987 Lisp_Object tail, frame;
12988
12989 number_of_visible_frames = 0;
12990
12991 FOR_EACH_FRAME (tail, frame)
12992 {
12993 struct frame *f = XFRAME (frame);
12994
12995 FRAME_SAMPLE_VISIBILITY (f);
12996 if (FRAME_VISIBLE_P (f))
12997 ++number_of_visible_frames;
12998 clear_desired_matrices (f);
12999 }
13000 }
13001
13002 /* Notice any pending interrupt request to change frame size. */
13003 do_pending_window_change (1);
13004
13005 /* do_pending_window_change could change the selected_window due to
13006 frame resizing which makes the selected window too small. */
13007 if (WINDOWP (selected_window) && (w = XWINDOW (selected_window)) != sw)
13008 {
13009 sw = w;
13010 reconsider_clip_changes (w, current_buffer);
13011 }
13012
13013 /* Clear frames marked as garbaged. */
13014 if (frame_garbaged)
13015 clear_garbaged_frames ();
13016
13017 /* Build menubar and tool-bar items. */
13018 if (NILP (Vmemory_full))
13019 prepare_menu_bars ();
13020
13021 if (windows_or_buffers_changed)
13022 update_mode_lines++;
13023
13024 /* Detect case that we need to write or remove a star in the mode line. */
13025 if ((SAVE_MODIFF < MODIFF) != w->last_had_star)
13026 {
13027 w->update_mode_line = 1;
13028 if (buffer_shared > 1)
13029 update_mode_lines++;
13030 }
13031
13032 /* Avoid invocation of point motion hooks by `current_column' below. */
13033 count1 = SPECPDL_INDEX ();
13034 specbind (Qinhibit_point_motion_hooks, Qt);
13035
13036 /* If %c is in the mode line, update it if needed. */
13037 if (!NILP (w->column_number_displayed)
13038 /* This alternative quickly identifies a common case
13039 where no change is needed. */
13040 && !(PT == XFASTINT (w->last_point)
13041 && XFASTINT (w->last_modified) >= MODIFF
13042 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
13043 && (XFASTINT (w->column_number_displayed) != current_column ()))
13044 w->update_mode_line = 1;
13045
13046 unbind_to (count1, Qnil);
13047
13048 FRAME_SCROLL_BOTTOM_VPOS (XFRAME (w->frame)) = -1;
13049
13050 /* The variable buffer_shared is set in redisplay_window and
13051 indicates that we redisplay a buffer in different windows. See
13052 there. */
13053 consider_all_windows_p = (update_mode_lines || buffer_shared > 1
13054 || cursor_type_changed);
13055
13056 /* If specs for an arrow have changed, do thorough redisplay
13057 to ensure we remove any arrow that should no longer exist. */
13058 if (overlay_arrows_changed_p ())
13059 consider_all_windows_p = windows_or_buffers_changed = 1;
13060
13061 /* Normally the message* functions will have already displayed and
13062 updated the echo area, but the frame may have been trashed, or
13063 the update may have been preempted, so display the echo area
13064 again here. Checking message_cleared_p captures the case that
13065 the echo area should be cleared. */
13066 if ((!NILP (echo_area_buffer[0]) && !display_last_displayed_message_p)
13067 || (!NILP (echo_area_buffer[1]) && display_last_displayed_message_p)
13068 || (message_cleared_p
13069 && minibuf_level == 0
13070 /* If the mini-window is currently selected, this means the
13071 echo-area doesn't show through. */
13072 && !MINI_WINDOW_P (XWINDOW (selected_window))))
13073 {
13074 int window_height_changed_p = echo_area_display (0);
13075
13076 if (message_cleared_p)
13077 update_miniwindow_p = 1;
13078
13079 must_finish = 1;
13080
13081 /* If we don't display the current message, don't clear the
13082 message_cleared_p flag, because, if we did, we wouldn't clear
13083 the echo area in the next redisplay which doesn't preserve
13084 the echo area. */
13085 if (!display_last_displayed_message_p)
13086 message_cleared_p = 0;
13087
13088 if (fonts_changed_p)
13089 goto retry;
13090 else if (window_height_changed_p)
13091 {
13092 consider_all_windows_p = 1;
13093 ++update_mode_lines;
13094 ++windows_or_buffers_changed;
13095
13096 /* If window configuration was changed, frames may have been
13097 marked garbaged. Clear them or we will experience
13098 surprises wrt scrolling. */
13099 if (frame_garbaged)
13100 clear_garbaged_frames ();
13101 }
13102 }
13103 else if (EQ (selected_window, minibuf_window)
13104 && (current_buffer->clip_changed
13105 || XFASTINT (w->last_modified) < MODIFF
13106 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
13107 && resize_mini_window (w, 0))
13108 {
13109 /* Resized active mini-window to fit the size of what it is
13110 showing if its contents might have changed. */
13111 must_finish = 1;
13112 /* FIXME: this causes all frames to be updated, which seems unnecessary
13113 since only the current frame needs to be considered. This function needs
13114 to be rewritten with two variables, consider_all_windows and
13115 consider_all_frames. */
13116 consider_all_windows_p = 1;
13117 ++windows_or_buffers_changed;
13118 ++update_mode_lines;
13119
13120 /* If window configuration was changed, frames may have been
13121 marked garbaged. Clear them or we will experience
13122 surprises wrt scrolling. */
13123 if (frame_garbaged)
13124 clear_garbaged_frames ();
13125 }
13126
13127
13128 /* If showing the region, and mark has changed, we must redisplay
13129 the whole window. The assignment to this_line_start_pos prevents
13130 the optimization directly below this if-statement. */
13131 if (((!NILP (Vtransient_mark_mode)
13132 && !NILP (BVAR (XBUFFER (w->buffer), mark_active)))
13133 != !NILP (w->region_showing))
13134 || (!NILP (w->region_showing)
13135 && !EQ (w->region_showing,
13136 Fmarker_position (BVAR (XBUFFER (w->buffer), mark)))))
13137 CHARPOS (this_line_start_pos) = 0;
13138
13139 /* Optimize the case that only the line containing the cursor in the
13140 selected window has changed. Variables starting with this_ are
13141 set in display_line and record information about the line
13142 containing the cursor. */
13143 tlbufpos = this_line_start_pos;
13144 tlendpos = this_line_end_pos;
13145 if (!consider_all_windows_p
13146 && CHARPOS (tlbufpos) > 0
13147 && !w->update_mode_line
13148 && !current_buffer->clip_changed
13149 && !current_buffer->prevent_redisplay_optimizations_p
13150 && FRAME_VISIBLE_P (XFRAME (w->frame))
13151 && !FRAME_OBSCURED_P (XFRAME (w->frame))
13152 /* Make sure recorded data applies to current buffer, etc. */
13153 && this_line_buffer == current_buffer
13154 && current_buffer == XBUFFER (w->buffer)
13155 && !w->force_start
13156 && !w->optional_new_start
13157 /* Point must be on the line that we have info recorded about. */
13158 && PT >= CHARPOS (tlbufpos)
13159 && PT <= Z - CHARPOS (tlendpos)
13160 /* All text outside that line, including its final newline,
13161 must be unchanged. */
13162 && text_outside_line_unchanged_p (w, CHARPOS (tlbufpos),
13163 CHARPOS (tlendpos)))
13164 {
13165 if (CHARPOS (tlbufpos) > BEGV
13166 && FETCH_BYTE (BYTEPOS (tlbufpos) - 1) != '\n'
13167 && (CHARPOS (tlbufpos) == ZV
13168 || FETCH_BYTE (BYTEPOS (tlbufpos)) == '\n'))
13169 /* Former continuation line has disappeared by becoming empty. */
13170 goto cancel;
13171 else if (XFASTINT (w->last_modified) < MODIFF
13172 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF
13173 || MINI_WINDOW_P (w))
13174 {
13175 /* We have to handle the case of continuation around a
13176 wide-column character (see the comment in indent.c around
13177 line 1340).
13178
13179 For instance, in the following case:
13180
13181 -------- Insert --------
13182 K_A_N_\\ `a' K_A_N_a\ `X_' are wide-column chars.
13183 J_I_ ==> J_I_ `^^' are cursors.
13184 ^^ ^^
13185 -------- --------
13186
13187 As we have to redraw the line above, we cannot use this
13188 optimization. */
13189
13190 struct it it;
13191 int line_height_before = this_line_pixel_height;
13192
13193 /* Note that start_display will handle the case that the
13194 line starting at tlbufpos is a continuation line. */
13195 start_display (&it, w, tlbufpos);
13196
13197 /* Implementation note: It this still necessary? */
13198 if (it.current_x != this_line_start_x)
13199 goto cancel;
13200
13201 TRACE ((stderr, "trying display optimization 1\n"));
13202 w->cursor.vpos = -1;
13203 overlay_arrow_seen = 0;
13204 it.vpos = this_line_vpos;
13205 it.current_y = this_line_y;
13206 it.glyph_row = MATRIX_ROW (w->desired_matrix, this_line_vpos);
13207 display_line (&it);
13208
13209 /* If line contains point, is not continued,
13210 and ends at same distance from eob as before, we win. */
13211 if (w->cursor.vpos >= 0
13212 /* Line is not continued, otherwise this_line_start_pos
13213 would have been set to 0 in display_line. */
13214 && CHARPOS (this_line_start_pos)
13215 /* Line ends as before. */
13216 && CHARPOS (this_line_end_pos) == CHARPOS (tlendpos)
13217 /* Line has same height as before. Otherwise other lines
13218 would have to be shifted up or down. */
13219 && this_line_pixel_height == line_height_before)
13220 {
13221 /* If this is not the window's last line, we must adjust
13222 the charstarts of the lines below. */
13223 if (it.current_y < it.last_visible_y)
13224 {
13225 struct glyph_row *row
13226 = MATRIX_ROW (w->current_matrix, this_line_vpos + 1);
13227 ptrdiff_t delta, delta_bytes;
13228
13229 /* We used to distinguish between two cases here,
13230 conditioned by Z - CHARPOS (tlendpos) == ZV, for
13231 when the line ends in a newline or the end of the
13232 buffer's accessible portion. But both cases did
13233 the same, so they were collapsed. */
13234 delta = (Z
13235 - CHARPOS (tlendpos)
13236 - MATRIX_ROW_START_CHARPOS (row));
13237 delta_bytes = (Z_BYTE
13238 - BYTEPOS (tlendpos)
13239 - MATRIX_ROW_START_BYTEPOS (row));
13240
13241 increment_matrix_positions (w->current_matrix,
13242 this_line_vpos + 1,
13243 w->current_matrix->nrows,
13244 delta, delta_bytes);
13245 }
13246
13247 /* If this row displays text now but previously didn't,
13248 or vice versa, w->window_end_vpos may have to be
13249 adjusted. */
13250 if ((it.glyph_row - 1)->displays_text_p)
13251 {
13252 if (XFASTINT (w->window_end_vpos) < this_line_vpos)
13253 XSETINT (w->window_end_vpos, this_line_vpos);
13254 }
13255 else if (XFASTINT (w->window_end_vpos) == this_line_vpos
13256 && this_line_vpos > 0)
13257 XSETINT (w->window_end_vpos, this_line_vpos - 1);
13258 w->window_end_valid = Qnil;
13259
13260 /* Update hint: No need to try to scroll in update_window. */
13261 w->desired_matrix->no_scrolling_p = 1;
13262
13263 #if GLYPH_DEBUG
13264 *w->desired_matrix->method = 0;
13265 debug_method_add (w, "optimization 1");
13266 #endif
13267 #if HAVE_XWIDGETS
13268 //debug optimization movement issue
13269 //w->desired_matrix->no_scrolling_p = 1;
13270 //*w->desired_matrix->method = 0;
13271 //debug_method_add (w, "optimization 1");
13272 #endif
13273
13274 #ifdef HAVE_WINDOW_SYSTEM
13275 update_window_fringes (w, 0);
13276 #endif
13277 goto update;
13278 }
13279 else
13280 goto cancel;
13281 }
13282 else if (/* Cursor position hasn't changed. */
13283 PT == XFASTINT (w->last_point)
13284 /* Make sure the cursor was last displayed
13285 in this window. Otherwise we have to reposition it. */
13286 && 0 <= w->cursor.vpos
13287 && WINDOW_TOTAL_LINES (w) > w->cursor.vpos)
13288 {
13289 if (!must_finish)
13290 {
13291 do_pending_window_change (1);
13292 /* If selected_window changed, redisplay again. */
13293 if (WINDOWP (selected_window)
13294 && (w = XWINDOW (selected_window)) != sw)
13295 goto retry;
13296
13297 /* We used to always goto end_of_redisplay here, but this
13298 isn't enough if we have a blinking cursor. */
13299 if (w->cursor_off_p == w->last_cursor_off_p)
13300 goto end_of_redisplay;
13301 }
13302 goto update;
13303 }
13304 /* If highlighting the region, or if the cursor is in the echo area,
13305 then we can't just move the cursor. */
13306 else if (! (!NILP (Vtransient_mark_mode)
13307 && !NILP (BVAR (current_buffer, mark_active)))
13308 && (EQ (selected_window,
13309 BVAR (current_buffer, last_selected_window))
13310 || highlight_nonselected_windows)
13311 && NILP (w->region_showing)
13312 && NILP (Vshow_trailing_whitespace)
13313 && !cursor_in_echo_area)
13314 {
13315 struct it it;
13316 struct glyph_row *row;
13317
13318 /* Skip from tlbufpos to PT and see where it is. Note that
13319 PT may be in invisible text. If so, we will end at the
13320 next visible position. */
13321 init_iterator (&it, w, CHARPOS (tlbufpos), BYTEPOS (tlbufpos),
13322 NULL, DEFAULT_FACE_ID);
13323 it.current_x = this_line_start_x;
13324 it.current_y = this_line_y;
13325 it.vpos = this_line_vpos;
13326
13327 /* The call to move_it_to stops in front of PT, but
13328 moves over before-strings. */
13329 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
13330
13331 if (it.vpos == this_line_vpos
13332 && (row = MATRIX_ROW (w->current_matrix, this_line_vpos),
13333 row->enabled_p))
13334 {
13335 xassert (this_line_vpos == it.vpos);
13336 xassert (this_line_y == it.current_y);
13337 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
13338 #if GLYPH_DEBUG
13339 *w->desired_matrix->method = 0;
13340 debug_method_add (w, "optimization 3");
13341 #endif
13342 goto update;
13343 }
13344 else
13345 goto cancel;
13346 }
13347
13348 cancel:
13349 /* Text changed drastically or point moved off of line. */
13350 SET_MATRIX_ROW_ENABLED_P (w->desired_matrix, this_line_vpos, 0);
13351 }
13352
13353 CHARPOS (this_line_start_pos) = 0;
13354 consider_all_windows_p |= buffer_shared > 1;
13355 ++clear_face_cache_count;
13356 #ifdef HAVE_WINDOW_SYSTEM
13357 ++clear_image_cache_count;
13358 #endif
13359
13360 /* Build desired matrices, and update the display. If
13361 consider_all_windows_p is non-zero, do it for all windows on all
13362 frames. Otherwise do it for selected_window, only. */
13363
13364 if (consider_all_windows_p)
13365 {
13366 Lisp_Object tail, frame;
13367
13368 FOR_EACH_FRAME (tail, frame)
13369 XFRAME (frame)->updated_p = 0;
13370
13371 /* Recompute # windows showing selected buffer. This will be
13372 incremented each time such a window is displayed. */
13373 buffer_shared = 0;
13374
13375 FOR_EACH_FRAME (tail, frame)
13376 {
13377 struct frame *f = XFRAME (frame);
13378
13379 if (FRAME_WINDOW_P (f) || FRAME_TERMCAP_P (f) || f == sf)
13380 {
13381 if (! EQ (frame, selected_frame))
13382 /* Select the frame, for the sake of frame-local
13383 variables. */
13384 select_frame_for_redisplay (frame);
13385
13386 /* Mark all the scroll bars to be removed; we'll redeem
13387 the ones we want when we redisplay their windows. */
13388 if (FRAME_TERMINAL (f)->condemn_scroll_bars_hook)
13389 FRAME_TERMINAL (f)->condemn_scroll_bars_hook (f);
13390
13391 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
13392 redisplay_windows (FRAME_ROOT_WINDOW (f));
13393
13394 /* The X error handler may have deleted that frame. */
13395 if (!FRAME_LIVE_P (f))
13396 continue;
13397
13398 /* Any scroll bars which redisplay_windows should have
13399 nuked should now go away. */
13400 if (FRAME_TERMINAL (f)->judge_scroll_bars_hook)
13401 FRAME_TERMINAL (f)->judge_scroll_bars_hook (f);
13402
13403 /* If fonts changed, display again. */
13404 /* ??? rms: I suspect it is a mistake to jump all the way
13405 back to retry here. It should just retry this frame. */
13406 if (fonts_changed_p)
13407 goto retry;
13408
13409 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
13410 {
13411 /* See if we have to hscroll. */
13412 if (!f->already_hscrolled_p)
13413 {
13414 f->already_hscrolled_p = 1;
13415 if (hscroll_windows (f->root_window))
13416 goto retry;
13417 }
13418
13419 /* Prevent various kinds of signals during display
13420 update. stdio is not robust about handling
13421 signals, which can cause an apparent I/O
13422 error. */
13423 if (interrupt_input)
13424 unrequest_sigio ();
13425 STOP_POLLING;
13426
13427 /* Update the display. */
13428 set_window_update_flags (XWINDOW (f->root_window), 1);
13429 pending |= update_frame (f, 0, 0);
13430 f->updated_p = 1;
13431 }
13432 }
13433 }
13434
13435 if (!EQ (old_frame, selected_frame)
13436 && FRAME_LIVE_P (XFRAME (old_frame)))
13437 /* We played a bit fast-and-loose above and allowed selected_frame
13438 and selected_window to be temporarily out-of-sync but let's make
13439 sure this stays contained. */
13440 select_frame_for_redisplay (old_frame);
13441 eassert (EQ (XFRAME (selected_frame)->selected_window, selected_window));
13442
13443 if (!pending)
13444 {
13445 /* Do the mark_window_display_accurate after all windows have
13446 been redisplayed because this call resets flags in buffers
13447 which are needed for proper redisplay. */
13448 FOR_EACH_FRAME (tail, frame)
13449 {
13450 struct frame *f = XFRAME (frame);
13451 if (f->updated_p)
13452 {
13453 mark_window_display_accurate (f->root_window, 1);
13454 if (FRAME_TERMINAL (f)->frame_up_to_date_hook)
13455 FRAME_TERMINAL (f)->frame_up_to_date_hook (f);
13456 }
13457 }
13458 }
13459 }
13460 else if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
13461 {
13462 Lisp_Object mini_window = FRAME_MINIBUF_WINDOW (sf);
13463 struct frame *mini_frame;
13464
13465 displayed_buffer = XBUFFER (XWINDOW (selected_window)->buffer);
13466 /* Use list_of_error, not Qerror, so that
13467 we catch only errors and don't run the debugger. */
13468 internal_condition_case_1 (redisplay_window_1, selected_window,
13469 list_of_error,
13470 redisplay_window_error);
13471 if (update_miniwindow_p)
13472 internal_condition_case_1 (redisplay_window_1, mini_window,
13473 list_of_error,
13474 redisplay_window_error);
13475
13476 /* Compare desired and current matrices, perform output. */
13477
13478 update:
13479 /* If fonts changed, display again. */
13480 if (fonts_changed_p)
13481 goto retry;
13482
13483 /* Prevent various kinds of signals during display update.
13484 stdio is not robust about handling signals,
13485 which can cause an apparent I/O error. */
13486 if (interrupt_input)
13487 unrequest_sigio ();
13488 STOP_POLLING;
13489
13490 if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
13491 {
13492 if (hscroll_windows (selected_window))
13493 goto retry;
13494
13495 XWINDOW (selected_window)->must_be_updated_p = 1;
13496 pending = update_frame (sf, 0, 0);
13497 }
13498
13499 /* We may have called echo_area_display at the top of this
13500 function. If the echo area is on another frame, that may
13501 have put text on a frame other than the selected one, so the
13502 above call to update_frame would not have caught it. Catch
13503 it here. */
13504 mini_window = FRAME_MINIBUF_WINDOW (sf);
13505 mini_frame = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
13506
13507 if (mini_frame != sf && FRAME_WINDOW_P (mini_frame))
13508 {
13509 XWINDOW (mini_window)->must_be_updated_p = 1;
13510 pending |= update_frame (mini_frame, 0, 0);
13511 if (!pending && hscroll_windows (mini_window))
13512 goto retry;
13513 }
13514 }
13515
13516 /* If display was paused because of pending input, make sure we do a
13517 thorough update the next time. */
13518 if (pending)
13519 {
13520 /* Prevent the optimization at the beginning of
13521 redisplay_internal that tries a single-line update of the
13522 line containing the cursor in the selected window. */
13523 CHARPOS (this_line_start_pos) = 0;
13524
13525 /* Let the overlay arrow be updated the next time. */
13526 update_overlay_arrows (0);
13527
13528 /* If we pause after scrolling, some rows in the current
13529 matrices of some windows are not valid. */
13530 if (!WINDOW_FULL_WIDTH_P (w)
13531 && !FRAME_WINDOW_P (XFRAME (w->frame)))
13532 update_mode_lines = 1;
13533 }
13534 else
13535 {
13536 if (!consider_all_windows_p)
13537 {
13538 /* This has already been done above if
13539 consider_all_windows_p is set. */
13540 mark_window_display_accurate_1 (w, 1);
13541
13542 /* Say overlay arrows are up to date. */
13543 update_overlay_arrows (1);
13544
13545 if (FRAME_TERMINAL (sf)->frame_up_to_date_hook != 0)
13546 FRAME_TERMINAL (sf)->frame_up_to_date_hook (sf);
13547 }
13548
13549 update_mode_lines = 0;
13550 windows_or_buffers_changed = 0;
13551 cursor_type_changed = 0;
13552 }
13553
13554 /* Start SIGIO interrupts coming again. Having them off during the
13555 code above makes it less likely one will discard output, but not
13556 impossible, since there might be stuff in the system buffer here.
13557 But it is much hairier to try to do anything about that. */
13558 if (interrupt_input)
13559 request_sigio ();
13560 RESUME_POLLING;
13561
13562 /* If a frame has become visible which was not before, redisplay
13563 again, so that we display it. Expose events for such a frame
13564 (which it gets when becoming visible) don't call the parts of
13565 redisplay constructing glyphs, so simply exposing a frame won't
13566 display anything in this case. So, we have to display these
13567 frames here explicitly. */
13568 if (!pending)
13569 {
13570 Lisp_Object tail, frame;
13571 int new_count = 0;
13572
13573 FOR_EACH_FRAME (tail, frame)
13574 {
13575 int this_is_visible = 0;
13576
13577 if (XFRAME (frame)->visible)
13578 this_is_visible = 1;
13579 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
13580 if (XFRAME (frame)->visible)
13581 this_is_visible = 1;
13582
13583 if (this_is_visible)
13584 new_count++;
13585 }
13586
13587 if (new_count != number_of_visible_frames)
13588 windows_or_buffers_changed++;
13589 }
13590
13591 /* Change frame size now if a change is pending. */
13592 do_pending_window_change (1);
13593
13594 /* If we just did a pending size change, or have additional
13595 visible frames, or selected_window changed, redisplay again. */
13596 if ((windows_or_buffers_changed && !pending)
13597 || (WINDOWP (selected_window) && (w = XWINDOW (selected_window)) != sw))
13598 goto retry;
13599
13600 /* Clear the face and image caches.
13601
13602 We used to do this only if consider_all_windows_p. But the cache
13603 needs to be cleared if a timer creates images in the current
13604 buffer (e.g. the test case in Bug#6230). */
13605
13606 if (clear_face_cache_count > CLEAR_FACE_CACHE_COUNT)
13607 {
13608 clear_face_cache (0);
13609 clear_face_cache_count = 0;
13610 }
13611
13612 #ifdef HAVE_WINDOW_SYSTEM
13613 if (clear_image_cache_count > CLEAR_IMAGE_CACHE_COUNT)
13614 {
13615 clear_image_caches (Qnil);
13616 clear_image_cache_count = 0;
13617 }
13618 #endif /* HAVE_WINDOW_SYSTEM */
13619
13620 end_of_redisplay:
13621 unbind_to (count, Qnil);
13622 RESUME_POLLING;
13623 }
13624
13625
13626 /* Redisplay, but leave alone any recent echo area message unless
13627 another message has been requested in its place.
13628
13629 This is useful in situations where you need to redisplay but no
13630 user action has occurred, making it inappropriate for the message
13631 area to be cleared. See tracking_off and
13632 wait_reading_process_output for examples of these situations.
13633
13634 FROM_WHERE is an integer saying from where this function was
13635 called. This is useful for debugging. */
13636
13637 void
13638 redisplay_preserve_echo_area (int from_where)
13639 {
13640 TRACE ((stderr, "redisplay_preserve_echo_area (%d)\n", from_where));
13641
13642 if (!NILP (echo_area_buffer[1]))
13643 {
13644 /* We have a previously displayed message, but no current
13645 message. Redisplay the previous message. */
13646 display_last_displayed_message_p = 1;
13647 redisplay_internal ();
13648 display_last_displayed_message_p = 0;
13649 }
13650 else
13651 redisplay_internal ();
13652
13653 if (FRAME_RIF (SELECTED_FRAME ()) != NULL
13654 && FRAME_RIF (SELECTED_FRAME ())->flush_display_optional)
13655 FRAME_RIF (SELECTED_FRAME ())->flush_display_optional (NULL);
13656 }
13657
13658
13659 /* Function registered with record_unwind_protect in
13660 redisplay_internal. Reset redisplaying_p to the value it had
13661 before redisplay_internal was called, and clear
13662 prevent_freeing_realized_faces_p. It also selects the previously
13663 selected frame, unless it has been deleted (by an X connection
13664 failure during redisplay, for example). */
13665
13666 static Lisp_Object
13667 unwind_redisplay (Lisp_Object val)
13668 {
13669 Lisp_Object old_redisplaying_p, old_frame;
13670
13671 old_redisplaying_p = XCAR (val);
13672 redisplaying_p = XFASTINT (old_redisplaying_p);
13673 old_frame = XCDR (val);
13674 if (! EQ (old_frame, selected_frame)
13675 && FRAME_LIVE_P (XFRAME (old_frame)))
13676 select_frame_for_redisplay (old_frame);
13677 return Qnil;
13678 }
13679
13680
13681 /* Mark the display of window W as accurate or inaccurate. If
13682 ACCURATE_P is non-zero mark display of W as accurate. If
13683 ACCURATE_P is zero, arrange for W to be redisplayed the next time
13684 redisplay_internal is called. */
13685
13686 static void
13687 mark_window_display_accurate_1 (struct window *w, int accurate_p)
13688 {
13689 if (BUFFERP (w->buffer))
13690 {
13691 struct buffer *b = XBUFFER (w->buffer);
13692
13693 w->last_modified
13694 = make_number (accurate_p ? BUF_MODIFF (b) : 0);
13695 w->last_overlay_modified
13696 = make_number (accurate_p ? BUF_OVERLAY_MODIFF (b) : 0);
13697 w->last_had_star
13698 = BUF_MODIFF (b) > BUF_SAVE_MODIFF (b);
13699
13700 if (accurate_p)
13701 {
13702 b->clip_changed = 0;
13703 b->prevent_redisplay_optimizations_p = 0;
13704
13705 BUF_UNCHANGED_MODIFIED (b) = BUF_MODIFF (b);
13706 BUF_OVERLAY_UNCHANGED_MODIFIED (b) = BUF_OVERLAY_MODIFF (b);
13707 BUF_BEG_UNCHANGED (b) = BUF_GPT (b) - BUF_BEG (b);
13708 BUF_END_UNCHANGED (b) = BUF_Z (b) - BUF_GPT (b);
13709
13710 w->current_matrix->buffer = b;
13711 w->current_matrix->begv = BUF_BEGV (b);
13712 w->current_matrix->zv = BUF_ZV (b);
13713
13714 w->last_cursor = w->cursor;
13715 w->last_cursor_off_p = w->cursor_off_p;
13716
13717 if (w == XWINDOW (selected_window))
13718 w->last_point = make_number (BUF_PT (b));
13719 else
13720 w->last_point = make_number (XMARKER (w->pointm)->charpos);
13721 }
13722 }
13723
13724 if (accurate_p)
13725 {
13726 w->window_end_valid = w->buffer;
13727 w->update_mode_line = 0;
13728 }
13729 }
13730
13731
13732 /* Mark the display of windows in the window tree rooted at WINDOW as
13733 accurate or inaccurate. If ACCURATE_P is non-zero mark display of
13734 windows as accurate. If ACCURATE_P is zero, arrange for windows to
13735 be redisplayed the next time redisplay_internal is called. */
13736
13737 void
13738 mark_window_display_accurate (Lisp_Object window, int accurate_p)
13739 {
13740 struct window *w;
13741
13742 for (; !NILP (window); window = w->next)
13743 {
13744 w = XWINDOW (window);
13745 mark_window_display_accurate_1 (w, accurate_p);
13746
13747 if (!NILP (w->vchild))
13748 mark_window_display_accurate (w->vchild, accurate_p);
13749 if (!NILP (w->hchild))
13750 mark_window_display_accurate (w->hchild, accurate_p);
13751 }
13752
13753 if (accurate_p)
13754 {
13755 update_overlay_arrows (1);
13756 }
13757 else
13758 {
13759 /* Force a thorough redisplay the next time by setting
13760 last_arrow_position and last_arrow_string to t, which is
13761 unequal to any useful value of Voverlay_arrow_... */
13762 update_overlay_arrows (-1);
13763 }
13764 }
13765
13766
13767 /* Return value in display table DP (Lisp_Char_Table *) for character
13768 C. Since a display table doesn't have any parent, we don't have to
13769 follow parent. Do not call this function directly but use the
13770 macro DISP_CHAR_VECTOR. */
13771
13772 Lisp_Object
13773 disp_char_vector (struct Lisp_Char_Table *dp, int c)
13774 {
13775 Lisp_Object val;
13776
13777 if (ASCII_CHAR_P (c))
13778 {
13779 val = dp->ascii;
13780 if (SUB_CHAR_TABLE_P (val))
13781 val = XSUB_CHAR_TABLE (val)->contents[c];
13782 }
13783 else
13784 {
13785 Lisp_Object table;
13786
13787 XSETCHAR_TABLE (table, dp);
13788 val = char_table_ref (table, c);
13789 }
13790 if (NILP (val))
13791 val = dp->defalt;
13792 return val;
13793 }
13794
13795
13796 \f
13797 /***********************************************************************
13798 Window Redisplay
13799 ***********************************************************************/
13800
13801 /* Redisplay all leaf windows in the window tree rooted at WINDOW. */
13802
13803 static void
13804 redisplay_windows (Lisp_Object window)
13805 {
13806 while (!NILP (window))
13807 {
13808 struct window *w = XWINDOW (window);
13809
13810 if (!NILP (w->hchild))
13811 redisplay_windows (w->hchild);
13812 else if (!NILP (w->vchild))
13813 redisplay_windows (w->vchild);
13814 else if (!NILP (w->buffer))
13815 {
13816 displayed_buffer = XBUFFER (w->buffer);
13817 /* Use list_of_error, not Qerror, so that
13818 we catch only errors and don't run the debugger. */
13819 internal_condition_case_1 (redisplay_window_0, window,
13820 list_of_error,
13821 redisplay_window_error);
13822 }
13823
13824 window = w->next;
13825 }
13826 }
13827
13828 static Lisp_Object
13829 redisplay_window_error (Lisp_Object ignore)
13830 {
13831 displayed_buffer->display_error_modiff = BUF_MODIFF (displayed_buffer);
13832 return Qnil;
13833 }
13834
13835 static Lisp_Object
13836 redisplay_window_0 (Lisp_Object window)
13837 {
13838 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
13839 redisplay_window (window, 0);
13840 return Qnil;
13841 }
13842
13843 static Lisp_Object
13844 redisplay_window_1 (Lisp_Object window)
13845 {
13846 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
13847 redisplay_window (window, 1);
13848 return Qnil;
13849 }
13850 \f
13851
13852 /* Set cursor position of W. PT is assumed to be displayed in ROW.
13853 DELTA and DELTA_BYTES are the numbers of characters and bytes by
13854 which positions recorded in ROW differ from current buffer
13855 positions.
13856
13857 Return 0 if cursor is not on this row, 1 otherwise. */
13858
13859 static int
13860 set_cursor_from_row (struct window *w, struct glyph_row *row,
13861 struct glyph_matrix *matrix,
13862 ptrdiff_t delta, ptrdiff_t delta_bytes,
13863 int dy, int dvpos)
13864 {
13865 struct glyph *glyph = row->glyphs[TEXT_AREA];
13866 struct glyph *end = glyph + row->used[TEXT_AREA];
13867 struct glyph *cursor = NULL;
13868 /* The last known character position in row. */
13869 ptrdiff_t last_pos = MATRIX_ROW_START_CHARPOS (row) + delta;
13870 int x = row->x;
13871 ptrdiff_t pt_old = PT - delta;
13872 ptrdiff_t pos_before = MATRIX_ROW_START_CHARPOS (row) + delta;
13873 ptrdiff_t pos_after = MATRIX_ROW_END_CHARPOS (row) + delta;
13874 struct glyph *glyph_before = glyph - 1, *glyph_after = end;
13875 /* A glyph beyond the edge of TEXT_AREA which we should never
13876 touch. */
13877 struct glyph *glyphs_end = end;
13878 /* Non-zero means we've found a match for cursor position, but that
13879 glyph has the avoid_cursor_p flag set. */
13880 int match_with_avoid_cursor = 0;
13881 /* Non-zero means we've seen at least one glyph that came from a
13882 display string. */
13883 int string_seen = 0;
13884 /* Largest and smallest buffer positions seen so far during scan of
13885 glyph row. */
13886 ptrdiff_t bpos_max = pos_before;
13887 ptrdiff_t bpos_min = pos_after;
13888 /* Last buffer position covered by an overlay string with an integer
13889 `cursor' property. */
13890 ptrdiff_t bpos_covered = 0;
13891 /* Non-zero means the display string on which to display the cursor
13892 comes from a text property, not from an overlay. */
13893 int string_from_text_prop = 0;
13894
13895 /* Don't even try doing anything if called for a mode-line or
13896 header-line row, since the rest of the code isn't prepared to
13897 deal with such calamities. */
13898 xassert (!row->mode_line_p);
13899 if (row->mode_line_p)
13900 return 0;
13901
13902 /* Skip over glyphs not having an object at the start and the end of
13903 the row. These are special glyphs like truncation marks on
13904 terminal frames. */
13905 if (row->displays_text_p)
13906 {
13907 if (!row->reversed_p)
13908 {
13909 while (glyph < end
13910 && INTEGERP (glyph->object)
13911 && glyph->charpos < 0)
13912 {
13913 x += glyph->pixel_width;
13914 ++glyph;
13915 }
13916 while (end > glyph
13917 && INTEGERP ((end - 1)->object)
13918 /* CHARPOS is zero for blanks and stretch glyphs
13919 inserted by extend_face_to_end_of_line. */
13920 && (end - 1)->charpos <= 0)
13921 --end;
13922 glyph_before = glyph - 1;
13923 glyph_after = end;
13924 }
13925 else
13926 {
13927 struct glyph *g;
13928
13929 /* If the glyph row is reversed, we need to process it from back
13930 to front, so swap the edge pointers. */
13931 glyphs_end = end = glyph - 1;
13932 glyph += row->used[TEXT_AREA] - 1;
13933
13934 while (glyph > end + 1
13935 && INTEGERP (glyph->object)
13936 && glyph->charpos < 0)
13937 {
13938 --glyph;
13939 x -= glyph->pixel_width;
13940 }
13941 if (INTEGERP (glyph->object) && glyph->charpos < 0)
13942 --glyph;
13943 /* By default, in reversed rows we put the cursor on the
13944 rightmost (first in the reading order) glyph. */
13945 for (g = end + 1; g < glyph; g++)
13946 x += g->pixel_width;
13947 while (end < glyph
13948 && INTEGERP ((end + 1)->object)
13949 && (end + 1)->charpos <= 0)
13950 ++end;
13951 glyph_before = glyph + 1;
13952 glyph_after = end;
13953 }
13954 }
13955 else if (row->reversed_p)
13956 {
13957 /* In R2L rows that don't display text, put the cursor on the
13958 rightmost glyph. Case in point: an empty last line that is
13959 part of an R2L paragraph. */
13960 cursor = end - 1;
13961 /* Avoid placing the cursor on the last glyph of the row, where
13962 on terminal frames we hold the vertical border between
13963 adjacent windows. */
13964 if (!FRAME_WINDOW_P (WINDOW_XFRAME (w))
13965 && !WINDOW_RIGHTMOST_P (w)
13966 && cursor == row->glyphs[LAST_AREA] - 1)
13967 cursor--;
13968 x = -1; /* will be computed below, at label compute_x */
13969 }
13970
13971 /* Step 1: Try to find the glyph whose character position
13972 corresponds to point. If that's not possible, find 2 glyphs
13973 whose character positions are the closest to point, one before
13974 point, the other after it. */
13975 if (!row->reversed_p)
13976 while (/* not marched to end of glyph row */
13977 glyph < end
13978 /* glyph was not inserted by redisplay for internal purposes */
13979 && !INTEGERP (glyph->object))
13980 {
13981 if (BUFFERP (glyph->object))
13982 {
13983 ptrdiff_t dpos = glyph->charpos - pt_old;
13984
13985 if (glyph->charpos > bpos_max)
13986 bpos_max = glyph->charpos;
13987 if (glyph->charpos < bpos_min)
13988 bpos_min = glyph->charpos;
13989 if (!glyph->avoid_cursor_p)
13990 {
13991 /* If we hit point, we've found the glyph on which to
13992 display the cursor. */
13993 if (dpos == 0)
13994 {
13995 match_with_avoid_cursor = 0;
13996 break;
13997 }
13998 /* See if we've found a better approximation to
13999 POS_BEFORE or to POS_AFTER. Note that we want the
14000 first (leftmost) glyph of all those that are the
14001 closest from below, and the last (rightmost) of all
14002 those from above. */
14003 if (0 > dpos && dpos > pos_before - pt_old)
14004 {
14005 pos_before = glyph->charpos;
14006 glyph_before = glyph;
14007 }
14008 else if (0 < dpos && dpos <= pos_after - pt_old)
14009 {
14010 pos_after = glyph->charpos;
14011 glyph_after = glyph;
14012 }
14013 }
14014 else if (dpos == 0)
14015 match_with_avoid_cursor = 1;
14016 }
14017 else if (STRINGP (glyph->object))
14018 {
14019 Lisp_Object chprop;
14020 ptrdiff_t glyph_pos = glyph->charpos;
14021
14022 chprop = Fget_char_property (make_number (glyph_pos), Qcursor,
14023 glyph->object);
14024 if (!NILP (chprop))
14025 {
14026 /* If the string came from a `display' text property,
14027 look up the buffer position of that property and
14028 use that position to update bpos_max, as if we
14029 actually saw such a position in one of the row's
14030 glyphs. This helps with supporting integer values
14031 of `cursor' property on the display string in
14032 situations where most or all of the row's buffer
14033 text is completely covered by display properties,
14034 so that no glyph with valid buffer positions is
14035 ever seen in the row. */
14036 ptrdiff_t prop_pos =
14037 string_buffer_position_lim (glyph->object, pos_before,
14038 pos_after, 0);
14039
14040 if (prop_pos >= pos_before)
14041 bpos_max = prop_pos - 1;
14042 }
14043 if (INTEGERP (chprop))
14044 {
14045 bpos_covered = bpos_max + XINT (chprop);
14046 /* If the `cursor' property covers buffer positions up
14047 to and including point, we should display cursor on
14048 this glyph. Note that, if a `cursor' property on one
14049 of the string's characters has an integer value, we
14050 will break out of the loop below _before_ we get to
14051 the position match above. IOW, integer values of
14052 the `cursor' property override the "exact match for
14053 point" strategy of positioning the cursor. */
14054 /* Implementation note: bpos_max == pt_old when, e.g.,
14055 we are in an empty line, where bpos_max is set to
14056 MATRIX_ROW_START_CHARPOS, see above. */
14057 if (bpos_max <= pt_old && bpos_covered >= pt_old)
14058 {
14059 cursor = glyph;
14060 break;
14061 }
14062 }
14063
14064 string_seen = 1;
14065 }
14066 x += glyph->pixel_width;
14067 ++glyph;
14068 }
14069 else if (glyph > end) /* row is reversed */
14070 while (!INTEGERP (glyph->object))
14071 {
14072 if (BUFFERP (glyph->object))
14073 {
14074 ptrdiff_t dpos = glyph->charpos - pt_old;
14075
14076 if (glyph->charpos > bpos_max)
14077 bpos_max = glyph->charpos;
14078 if (glyph->charpos < bpos_min)
14079 bpos_min = glyph->charpos;
14080 if (!glyph->avoid_cursor_p)
14081 {
14082 if (dpos == 0)
14083 {
14084 match_with_avoid_cursor = 0;
14085 break;
14086 }
14087 if (0 > dpos && dpos > pos_before - pt_old)
14088 {
14089 pos_before = glyph->charpos;
14090 glyph_before = glyph;
14091 }
14092 else if (0 < dpos && dpos <= pos_after - pt_old)
14093 {
14094 pos_after = glyph->charpos;
14095 glyph_after = glyph;
14096 }
14097 }
14098 else if (dpos == 0)
14099 match_with_avoid_cursor = 1;
14100 }
14101 else if (STRINGP (glyph->object))
14102 {
14103 Lisp_Object chprop;
14104 ptrdiff_t glyph_pos = glyph->charpos;
14105
14106 chprop = Fget_char_property (make_number (glyph_pos), Qcursor,
14107 glyph->object);
14108 if (!NILP (chprop))
14109 {
14110 ptrdiff_t prop_pos =
14111 string_buffer_position_lim (glyph->object, pos_before,
14112 pos_after, 0);
14113
14114 if (prop_pos >= pos_before)
14115 bpos_max = prop_pos - 1;
14116 }
14117 if (INTEGERP (chprop))
14118 {
14119 bpos_covered = bpos_max + XINT (chprop);
14120 /* If the `cursor' property covers buffer positions up
14121 to and including point, we should display cursor on
14122 this glyph. */
14123 if (bpos_max <= pt_old && bpos_covered >= pt_old)
14124 {
14125 cursor = glyph;
14126 break;
14127 }
14128 }
14129 string_seen = 1;
14130 }
14131 --glyph;
14132 if (glyph == glyphs_end) /* don't dereference outside TEXT_AREA */
14133 {
14134 x--; /* can't use any pixel_width */
14135 break;
14136 }
14137 x -= glyph->pixel_width;
14138 }
14139
14140 /* Step 2: If we didn't find an exact match for point, we need to
14141 look for a proper place to put the cursor among glyphs between
14142 GLYPH_BEFORE and GLYPH_AFTER. */
14143 if (!((row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end)
14144 && BUFFERP (glyph->object) && glyph->charpos == pt_old)
14145 && bpos_covered < pt_old)
14146 {
14147 /* An empty line has a single glyph whose OBJECT is zero and
14148 whose CHARPOS is the position of a newline on that line.
14149 Note that on a TTY, there are more glyphs after that, which
14150 were produced by extend_face_to_end_of_line, but their
14151 CHARPOS is zero or negative. */
14152 int empty_line_p =
14153 (row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end)
14154 && INTEGERP (glyph->object) && glyph->charpos > 0;
14155
14156 if (row->ends_in_ellipsis_p && pos_after == last_pos)
14157 {
14158 ptrdiff_t ellipsis_pos;
14159
14160 /* Scan back over the ellipsis glyphs. */
14161 if (!row->reversed_p)
14162 {
14163 ellipsis_pos = (glyph - 1)->charpos;
14164 while (glyph > row->glyphs[TEXT_AREA]
14165 && (glyph - 1)->charpos == ellipsis_pos)
14166 glyph--, x -= glyph->pixel_width;
14167 /* That loop always goes one position too far, including
14168 the glyph before the ellipsis. So scan forward over
14169 that one. */
14170 x += glyph->pixel_width;
14171 glyph++;
14172 }
14173 else /* row is reversed */
14174 {
14175 ellipsis_pos = (glyph + 1)->charpos;
14176 while (glyph < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1
14177 && (glyph + 1)->charpos == ellipsis_pos)
14178 glyph++, x += glyph->pixel_width;
14179 x -= glyph->pixel_width;
14180 glyph--;
14181 }
14182 }
14183 else if (match_with_avoid_cursor)
14184 {
14185 cursor = glyph_after;
14186 x = -1;
14187 }
14188 else if (string_seen)
14189 {
14190 int incr = row->reversed_p ? -1 : +1;
14191
14192 /* Need to find the glyph that came out of a string which is
14193 present at point. That glyph is somewhere between
14194 GLYPH_BEFORE and GLYPH_AFTER, and it came from a string
14195 positioned between POS_BEFORE and POS_AFTER in the
14196 buffer. */
14197 struct glyph *start, *stop;
14198 ptrdiff_t pos = pos_before;
14199
14200 x = -1;
14201
14202 /* If the row ends in a newline from a display string,
14203 reordering could have moved the glyphs belonging to the
14204 string out of the [GLYPH_BEFORE..GLYPH_AFTER] range. So
14205 in this case we extend the search to the last glyph in
14206 the row that was not inserted by redisplay. */
14207 if (row->ends_in_newline_from_string_p)
14208 {
14209 glyph_after = end;
14210 pos_after = MATRIX_ROW_END_CHARPOS (row) + delta;
14211 }
14212
14213 /* GLYPH_BEFORE and GLYPH_AFTER are the glyphs that
14214 correspond to POS_BEFORE and POS_AFTER, respectively. We
14215 need START and STOP in the order that corresponds to the
14216 row's direction as given by its reversed_p flag. If the
14217 directionality of characters between POS_BEFORE and
14218 POS_AFTER is the opposite of the row's base direction,
14219 these characters will have been reordered for display,
14220 and we need to reverse START and STOP. */
14221 if (!row->reversed_p)
14222 {
14223 start = min (glyph_before, glyph_after);
14224 stop = max (glyph_before, glyph_after);
14225 }
14226 else
14227 {
14228 start = max (glyph_before, glyph_after);
14229 stop = min (glyph_before, glyph_after);
14230 }
14231 for (glyph = start + incr;
14232 row->reversed_p ? glyph > stop : glyph < stop; )
14233 {
14234
14235 /* Any glyphs that come from the buffer are here because
14236 of bidi reordering. Skip them, and only pay
14237 attention to glyphs that came from some string. */
14238 if (STRINGP (glyph->object))
14239 {
14240 Lisp_Object str;
14241 ptrdiff_t tem;
14242 /* If the display property covers the newline, we
14243 need to search for it one position farther. */
14244 ptrdiff_t lim = pos_after
14245 + (pos_after == MATRIX_ROW_END_CHARPOS (row) + delta);
14246
14247 string_from_text_prop = 0;
14248 str = glyph->object;
14249 tem = string_buffer_position_lim (str, pos, lim, 0);
14250 if (tem == 0 /* from overlay */
14251 || pos <= tem)
14252 {
14253 /* If the string from which this glyph came is
14254 found in the buffer at point, or at position
14255 that is closer to point than pos_after, then
14256 we've found the glyph we've been looking for.
14257 If it comes from an overlay (tem == 0), and
14258 it has the `cursor' property on one of its
14259 glyphs, record that glyph as a candidate for
14260 displaying the cursor. (As in the
14261 unidirectional version, we will display the
14262 cursor on the last candidate we find.) */
14263 if (tem == 0
14264 || tem == pt_old
14265 || (tem - pt_old > 0 && tem < pos_after))
14266 {
14267 /* The glyphs from this string could have
14268 been reordered. Find the one with the
14269 smallest string position. Or there could
14270 be a character in the string with the
14271 `cursor' property, which means display
14272 cursor on that character's glyph. */
14273 ptrdiff_t strpos = glyph->charpos;
14274
14275 if (tem)
14276 {
14277 cursor = glyph;
14278 string_from_text_prop = 1;
14279 }
14280 for ( ;
14281 (row->reversed_p ? glyph > stop : glyph < stop)
14282 && EQ (glyph->object, str);
14283 glyph += incr)
14284 {
14285 Lisp_Object cprop;
14286 ptrdiff_t gpos = glyph->charpos;
14287
14288 cprop = Fget_char_property (make_number (gpos),
14289 Qcursor,
14290 glyph->object);
14291 if (!NILP (cprop))
14292 {
14293 cursor = glyph;
14294 break;
14295 }
14296 if (tem && glyph->charpos < strpos)
14297 {
14298 strpos = glyph->charpos;
14299 cursor = glyph;
14300 }
14301 }
14302
14303 if (tem == pt_old
14304 || (tem - pt_old > 0 && tem < pos_after))
14305 goto compute_x;
14306 }
14307 if (tem)
14308 pos = tem + 1; /* don't find previous instances */
14309 }
14310 /* This string is not what we want; skip all of the
14311 glyphs that came from it. */
14312 while ((row->reversed_p ? glyph > stop : glyph < stop)
14313 && EQ (glyph->object, str))
14314 glyph += incr;
14315 }
14316 else
14317 glyph += incr;
14318 }
14319
14320 /* If we reached the end of the line, and END was from a string,
14321 the cursor is not on this line. */
14322 if (cursor == NULL
14323 && (row->reversed_p ? glyph <= end : glyph >= end)
14324 && STRINGP (end->object)
14325 && row->continued_p)
14326 return 0;
14327 }
14328 /* A truncated row may not include PT among its character positions.
14329 Setting the cursor inside the scroll margin will trigger
14330 recalculation of hscroll in hscroll_window_tree. But if a
14331 display string covers point, defer to the string-handling
14332 code below to figure this out. */
14333 else if (row->truncated_on_left_p && pt_old < bpos_min)
14334 {
14335 cursor = glyph_before;
14336 x = -1;
14337 }
14338 else if ((row->truncated_on_right_p && pt_old > bpos_max)
14339 /* Zero-width characters produce no glyphs. */
14340 || (!empty_line_p
14341 && (row->reversed_p
14342 ? glyph_after > glyphs_end
14343 : glyph_after < glyphs_end)))
14344 {
14345 cursor = glyph_after;
14346 x = -1;
14347 }
14348 }
14349
14350 compute_x:
14351 if (cursor != NULL)
14352 glyph = cursor;
14353 if (x < 0)
14354 {
14355 struct glyph *g;
14356
14357 /* Need to compute x that corresponds to GLYPH. */
14358 for (g = row->glyphs[TEXT_AREA], x = row->x; g < glyph; g++)
14359 {
14360 if (g >= row->glyphs[TEXT_AREA] + row->used[TEXT_AREA])
14361 abort ();
14362 x += g->pixel_width;
14363 }
14364 }
14365
14366 /* ROW could be part of a continued line, which, under bidi
14367 reordering, might have other rows whose start and end charpos
14368 occlude point. Only set w->cursor if we found a better
14369 approximation to the cursor position than we have from previously
14370 examined candidate rows belonging to the same continued line. */
14371 if (/* we already have a candidate row */
14372 w->cursor.vpos >= 0
14373 /* that candidate is not the row we are processing */
14374 && MATRIX_ROW (matrix, w->cursor.vpos) != row
14375 /* Make sure cursor.vpos specifies a row whose start and end
14376 charpos occlude point, and it is valid candidate for being a
14377 cursor-row. This is because some callers of this function
14378 leave cursor.vpos at the row where the cursor was displayed
14379 during the last redisplay cycle. */
14380 && MATRIX_ROW_START_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos)) <= pt_old
14381 && pt_old <= MATRIX_ROW_END_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))
14382 && cursor_row_p (MATRIX_ROW (matrix, w->cursor.vpos)))
14383 {
14384 struct glyph *g1 =
14385 MATRIX_ROW_GLYPH_START (matrix, w->cursor.vpos) + w->cursor.hpos;
14386
14387 /* Don't consider glyphs that are outside TEXT_AREA. */
14388 if (!(row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end))
14389 return 0;
14390 /* Keep the candidate whose buffer position is the closest to
14391 point or has the `cursor' property. */
14392 if (/* previous candidate is a glyph in TEXT_AREA of that row */
14393 w->cursor.hpos >= 0
14394 && w->cursor.hpos < MATRIX_ROW_USED (matrix, w->cursor.vpos)
14395 && ((BUFFERP (g1->object)
14396 && (g1->charpos == pt_old /* an exact match always wins */
14397 || (BUFFERP (glyph->object)
14398 && eabs (g1->charpos - pt_old)
14399 < eabs (glyph->charpos - pt_old))))
14400 /* previous candidate is a glyph from a string that has
14401 a non-nil `cursor' property */
14402 || (STRINGP (g1->object)
14403 && (!NILP (Fget_char_property (make_number (g1->charpos),
14404 Qcursor, g1->object))
14405 /* previous candidate is from the same display
14406 string as this one, and the display string
14407 came from a text property */
14408 || (EQ (g1->object, glyph->object)
14409 && string_from_text_prop)
14410 /* this candidate is from newline and its
14411 position is not an exact match */
14412 || (INTEGERP (glyph->object)
14413 && glyph->charpos != pt_old)))))
14414 return 0;
14415 /* If this candidate gives an exact match, use that. */
14416 if (!((BUFFERP (glyph->object) && glyph->charpos == pt_old)
14417 /* If this candidate is a glyph created for the
14418 terminating newline of a line, and point is on that
14419 newline, it wins because it's an exact match. */
14420 || (!row->continued_p
14421 && INTEGERP (glyph->object)
14422 && glyph->charpos == 0
14423 && pt_old == MATRIX_ROW_END_CHARPOS (row) - 1))
14424 /* Otherwise, keep the candidate that comes from a row
14425 spanning less buffer positions. This may win when one or
14426 both candidate positions are on glyphs that came from
14427 display strings, for which we cannot compare buffer
14428 positions. */
14429 && MATRIX_ROW_END_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))
14430 - MATRIX_ROW_START_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))
14431 < MATRIX_ROW_END_CHARPOS (row) - MATRIX_ROW_START_CHARPOS (row))
14432 return 0;
14433 }
14434 w->cursor.hpos = glyph - row->glyphs[TEXT_AREA];
14435 w->cursor.x = x;
14436 w->cursor.vpos = MATRIX_ROW_VPOS (row, matrix) + dvpos;
14437 w->cursor.y = row->y + dy;
14438
14439 if (w == XWINDOW (selected_window))
14440 {
14441 if (!row->continued_p
14442 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
14443 && row->x == 0)
14444 {
14445 this_line_buffer = XBUFFER (w->buffer);
14446
14447 CHARPOS (this_line_start_pos)
14448 = MATRIX_ROW_START_CHARPOS (row) + delta;
14449 BYTEPOS (this_line_start_pos)
14450 = MATRIX_ROW_START_BYTEPOS (row) + delta_bytes;
14451
14452 CHARPOS (this_line_end_pos)
14453 = Z - (MATRIX_ROW_END_CHARPOS (row) + delta);
14454 BYTEPOS (this_line_end_pos)
14455 = Z_BYTE - (MATRIX_ROW_END_BYTEPOS (row) + delta_bytes);
14456
14457 this_line_y = w->cursor.y;
14458 this_line_pixel_height = row->height;
14459 this_line_vpos = w->cursor.vpos;
14460 this_line_start_x = row->x;
14461 }
14462 else
14463 CHARPOS (this_line_start_pos) = 0;
14464 }
14465
14466 return 1;
14467 }
14468
14469
14470 /* Run window scroll functions, if any, for WINDOW with new window
14471 start STARTP. Sets the window start of WINDOW to that position.
14472
14473 We assume that the window's buffer is really current. */
14474
14475 static inline struct text_pos
14476 run_window_scroll_functions (Lisp_Object window, struct text_pos startp)
14477 {
14478 struct window *w = XWINDOW (window);
14479 SET_MARKER_FROM_TEXT_POS (w->start, startp);
14480
14481 if (current_buffer != XBUFFER (w->buffer))
14482 abort ();
14483
14484 if (!NILP (Vwindow_scroll_functions))
14485 {
14486 run_hook_with_args_2 (Qwindow_scroll_functions, window,
14487 make_number (CHARPOS (startp)));
14488 SET_TEXT_POS_FROM_MARKER (startp, w->start);
14489 /* In case the hook functions switch buffers. */
14490 if (current_buffer != XBUFFER (w->buffer))
14491 set_buffer_internal_1 (XBUFFER (w->buffer));
14492 }
14493
14494 return startp;
14495 }
14496
14497
14498 /* Make sure the line containing the cursor is fully visible.
14499 A value of 1 means there is nothing to be done.
14500 (Either the line is fully visible, or it cannot be made so,
14501 or we cannot tell.)
14502
14503 If FORCE_P is non-zero, return 0 even if partial visible cursor row
14504 is higher than window.
14505
14506 A value of 0 means the caller should do scrolling
14507 as if point had gone off the screen. */
14508
14509 static int
14510 cursor_row_fully_visible_p (struct window *w, int force_p, int current_matrix_p)
14511 {
14512 struct glyph_matrix *matrix;
14513 struct glyph_row *row;
14514 int window_height;
14515
14516 if (!make_cursor_line_fully_visible_p)
14517 return 1;
14518
14519 /* It's not always possible to find the cursor, e.g, when a window
14520 is full of overlay strings. Don't do anything in that case. */
14521 if (w->cursor.vpos < 0)
14522 return 1;
14523
14524 matrix = current_matrix_p ? w->current_matrix : w->desired_matrix;
14525 row = MATRIX_ROW (matrix, w->cursor.vpos);
14526
14527 /* If the cursor row is not partially visible, there's nothing to do. */
14528 if (!MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row))
14529 return 1;
14530
14531 /* If the row the cursor is in is taller than the window's height,
14532 it's not clear what to do, so do nothing. */
14533 window_height = window_box_height (w);
14534 if (row->height >= window_height)
14535 {
14536 if (!force_p || MINI_WINDOW_P (w)
14537 || w->vscroll || w->cursor.vpos == 0)
14538 return 1;
14539 }
14540 return 0;
14541 }
14542
14543
14544 /* Try scrolling PT into view in window WINDOW. JUST_THIS_ONE_P
14545 non-zero means only WINDOW is redisplayed in redisplay_internal.
14546 TEMP_SCROLL_STEP has the same meaning as emacs_scroll_step, and is used
14547 in redisplay_window to bring a partially visible line into view in
14548 the case that only the cursor has moved.
14549
14550 LAST_LINE_MISFIT should be nonzero if we're scrolling because the
14551 last screen line's vertical height extends past the end of the screen.
14552
14553 Value is
14554
14555 1 if scrolling succeeded
14556
14557 0 if scrolling didn't find point.
14558
14559 -1 if new fonts have been loaded so that we must interrupt
14560 redisplay, adjust glyph matrices, and try again. */
14561
14562 enum
14563 {
14564 SCROLLING_SUCCESS,
14565 SCROLLING_FAILED,
14566 SCROLLING_NEED_LARGER_MATRICES
14567 };
14568
14569 /* If scroll-conservatively is more than this, never recenter.
14570
14571 If you change this, don't forget to update the doc string of
14572 `scroll-conservatively' and the Emacs manual. */
14573 #define SCROLL_LIMIT 100
14574
14575 static int
14576 try_scrolling (Lisp_Object window, int just_this_one_p,
14577 ptrdiff_t arg_scroll_conservatively, ptrdiff_t scroll_step,
14578 int temp_scroll_step, int last_line_misfit)
14579 {
14580 struct window *w = XWINDOW (window);
14581 struct frame *f = XFRAME (w->frame);
14582 struct text_pos pos, startp;
14583 struct it it;
14584 int this_scroll_margin, scroll_max, rc, height;
14585 int dy = 0, amount_to_scroll = 0, scroll_down_p = 0;
14586 int extra_scroll_margin_lines = last_line_misfit ? 1 : 0;
14587 Lisp_Object aggressive;
14588 /* We will never try scrolling more than this number of lines. */
14589 int scroll_limit = SCROLL_LIMIT;
14590
14591 #if GLYPH_DEBUG
14592 debug_method_add (w, "try_scrolling");
14593 #endif
14594
14595 SET_TEXT_POS_FROM_MARKER (startp, w->start);
14596
14597 /* Compute scroll margin height in pixels. We scroll when point is
14598 within this distance from the top or bottom of the window. */
14599 if (scroll_margin > 0)
14600 this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4)
14601 * FRAME_LINE_HEIGHT (f);
14602 else
14603 this_scroll_margin = 0;
14604
14605 /* Force arg_scroll_conservatively to have a reasonable value, to
14606 avoid scrolling too far away with slow move_it_* functions. Note
14607 that the user can supply scroll-conservatively equal to
14608 `most-positive-fixnum', which can be larger than INT_MAX. */
14609 if (arg_scroll_conservatively > scroll_limit)
14610 {
14611 arg_scroll_conservatively = scroll_limit + 1;
14612 scroll_max = scroll_limit * FRAME_LINE_HEIGHT (f);
14613 }
14614 else if (scroll_step || arg_scroll_conservatively || temp_scroll_step)
14615 /* Compute how much we should try to scroll maximally to bring
14616 point into view. */
14617 scroll_max = (max (scroll_step,
14618 max (arg_scroll_conservatively, temp_scroll_step))
14619 * FRAME_LINE_HEIGHT (f));
14620 else if (NUMBERP (BVAR (current_buffer, scroll_down_aggressively))
14621 || NUMBERP (BVAR (current_buffer, scroll_up_aggressively)))
14622 /* We're trying to scroll because of aggressive scrolling but no
14623 scroll_step is set. Choose an arbitrary one. */
14624 scroll_max = 10 * FRAME_LINE_HEIGHT (f);
14625 else
14626 scroll_max = 0;
14627
14628 too_near_end:
14629
14630 /* Decide whether to scroll down. */
14631 if (PT > CHARPOS (startp))
14632 {
14633 int scroll_margin_y;
14634
14635 /* Compute the pixel ypos of the scroll margin, then move IT to
14636 either that ypos or PT, whichever comes first. */
14637 start_display (&it, w, startp);
14638 scroll_margin_y = it.last_visible_y - this_scroll_margin
14639 - FRAME_LINE_HEIGHT (f) * extra_scroll_margin_lines;
14640 move_it_to (&it, PT, -1, scroll_margin_y - 1, -1,
14641 (MOVE_TO_POS | MOVE_TO_Y));
14642
14643 if (PT > CHARPOS (it.current.pos))
14644 {
14645 int y0 = line_bottom_y (&it);
14646 /* Compute how many pixels below window bottom to stop searching
14647 for PT. This avoids costly search for PT that is far away if
14648 the user limited scrolling by a small number of lines, but
14649 always finds PT if scroll_conservatively is set to a large
14650 number, such as most-positive-fixnum. */
14651 int slack = max (scroll_max, 10 * FRAME_LINE_HEIGHT (f));
14652 int y_to_move = it.last_visible_y + slack;
14653
14654 /* Compute the distance from the scroll margin to PT or to
14655 the scroll limit, whichever comes first. This should
14656 include the height of the cursor line, to make that line
14657 fully visible. */
14658 move_it_to (&it, PT, -1, y_to_move,
14659 -1, MOVE_TO_POS | MOVE_TO_Y);
14660 dy = line_bottom_y (&it) - y0;
14661
14662 if (dy > scroll_max)
14663 return SCROLLING_FAILED;
14664
14665 if (dy > 0)
14666 scroll_down_p = 1;
14667 }
14668 }
14669
14670 if (scroll_down_p)
14671 {
14672 /* Point is in or below the bottom scroll margin, so move the
14673 window start down. If scrolling conservatively, move it just
14674 enough down to make point visible. If scroll_step is set,
14675 move it down by scroll_step. */
14676 if (arg_scroll_conservatively)
14677 amount_to_scroll
14678 = min (max (dy, FRAME_LINE_HEIGHT (f)),
14679 FRAME_LINE_HEIGHT (f) * arg_scroll_conservatively);
14680 else if (scroll_step || temp_scroll_step)
14681 amount_to_scroll = scroll_max;
14682 else
14683 {
14684 aggressive = BVAR (current_buffer, scroll_up_aggressively);
14685 height = WINDOW_BOX_TEXT_HEIGHT (w);
14686 if (NUMBERP (aggressive))
14687 {
14688 double float_amount = XFLOATINT (aggressive) * height;
14689 amount_to_scroll = float_amount;
14690 if (amount_to_scroll == 0 && float_amount > 0)
14691 amount_to_scroll = 1;
14692 /* Don't let point enter the scroll margin near top of
14693 the window. */
14694 if (amount_to_scroll > height - 2*this_scroll_margin + dy)
14695 amount_to_scroll = height - 2*this_scroll_margin + dy;
14696 }
14697 }
14698
14699 if (amount_to_scroll <= 0)
14700 return SCROLLING_FAILED;
14701
14702 start_display (&it, w, startp);
14703 if (arg_scroll_conservatively <= scroll_limit)
14704 move_it_vertically (&it, amount_to_scroll);
14705 else
14706 {
14707 /* Extra precision for users who set scroll-conservatively
14708 to a large number: make sure the amount we scroll
14709 the window start is never less than amount_to_scroll,
14710 which was computed as distance from window bottom to
14711 point. This matters when lines at window top and lines
14712 below window bottom have different height. */
14713 struct it it1;
14714 void *it1data = NULL;
14715 /* We use a temporary it1 because line_bottom_y can modify
14716 its argument, if it moves one line down; see there. */
14717 int start_y;
14718
14719 SAVE_IT (it1, it, it1data);
14720 start_y = line_bottom_y (&it1);
14721 do {
14722 RESTORE_IT (&it, &it, it1data);
14723 move_it_by_lines (&it, 1);
14724 SAVE_IT (it1, it, it1data);
14725 } while (line_bottom_y (&it1) - start_y < amount_to_scroll);
14726 }
14727
14728 /* If STARTP is unchanged, move it down another screen line. */
14729 if (CHARPOS (it.current.pos) == CHARPOS (startp))
14730 move_it_by_lines (&it, 1);
14731 startp = it.current.pos;
14732 }
14733 else
14734 {
14735 struct text_pos scroll_margin_pos = startp;
14736
14737 /* See if point is inside the scroll margin at the top of the
14738 window. */
14739 if (this_scroll_margin)
14740 {
14741 start_display (&it, w, startp);
14742 move_it_vertically (&it, this_scroll_margin);
14743 scroll_margin_pos = it.current.pos;
14744 }
14745
14746 if (PT < CHARPOS (scroll_margin_pos))
14747 {
14748 /* Point is in the scroll margin at the top of the window or
14749 above what is displayed in the window. */
14750 int y0, y_to_move;
14751
14752 /* Compute the vertical distance from PT to the scroll
14753 margin position. Move as far as scroll_max allows, or
14754 one screenful, or 10 screen lines, whichever is largest.
14755 Give up if distance is greater than scroll_max. */
14756 SET_TEXT_POS (pos, PT, PT_BYTE);
14757 start_display (&it, w, pos);
14758 y0 = it.current_y;
14759 y_to_move = max (it.last_visible_y,
14760 max (scroll_max, 10 * FRAME_LINE_HEIGHT (f)));
14761 move_it_to (&it, CHARPOS (scroll_margin_pos), 0,
14762 y_to_move, -1,
14763 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
14764 dy = it.current_y - y0;
14765 if (dy > scroll_max)
14766 return SCROLLING_FAILED;
14767
14768 /* Compute new window start. */
14769 start_display (&it, w, startp);
14770
14771 if (arg_scroll_conservatively)
14772 amount_to_scroll = max (dy, FRAME_LINE_HEIGHT (f) *
14773 max (scroll_step, temp_scroll_step));
14774 else if (scroll_step || temp_scroll_step)
14775 amount_to_scroll = scroll_max;
14776 else
14777 {
14778 aggressive = BVAR (current_buffer, scroll_down_aggressively);
14779 height = WINDOW_BOX_TEXT_HEIGHT (w);
14780 if (NUMBERP (aggressive))
14781 {
14782 double float_amount = XFLOATINT (aggressive) * height;
14783 amount_to_scroll = float_amount;
14784 if (amount_to_scroll == 0 && float_amount > 0)
14785 amount_to_scroll = 1;
14786 amount_to_scroll -=
14787 this_scroll_margin - dy - FRAME_LINE_HEIGHT (f);
14788 /* Don't let point enter the scroll margin near
14789 bottom of the window. */
14790 if (amount_to_scroll > height - 2*this_scroll_margin + dy)
14791 amount_to_scroll = height - 2*this_scroll_margin + dy;
14792 }
14793 }
14794
14795 if (amount_to_scroll <= 0)
14796 return SCROLLING_FAILED;
14797
14798 move_it_vertically_backward (&it, amount_to_scroll);
14799 startp = it.current.pos;
14800 }
14801 }
14802
14803 /* Run window scroll functions. */
14804 startp = run_window_scroll_functions (window, startp);
14805
14806 /* Display the window. Give up if new fonts are loaded, or if point
14807 doesn't appear. */
14808 if (!try_window (window, startp, 0))
14809 rc = SCROLLING_NEED_LARGER_MATRICES;
14810 else if (w->cursor.vpos < 0)
14811 {
14812 clear_glyph_matrix (w->desired_matrix);
14813 rc = SCROLLING_FAILED;
14814 }
14815 else
14816 {
14817 /* Maybe forget recorded base line for line number display. */
14818 if (!just_this_one_p
14819 || current_buffer->clip_changed
14820 || BEG_UNCHANGED < CHARPOS (startp))
14821 w->base_line_number = Qnil;
14822
14823 /* If cursor ends up on a partially visible line,
14824 treat that as being off the bottom of the screen. */
14825 if (! cursor_row_fully_visible_p (w, extra_scroll_margin_lines <= 1, 0)
14826 /* It's possible that the cursor is on the first line of the
14827 buffer, which is partially obscured due to a vscroll
14828 (Bug#7537). In that case, avoid looping forever . */
14829 && extra_scroll_margin_lines < w->desired_matrix->nrows - 1)
14830 {
14831 clear_glyph_matrix (w->desired_matrix);
14832 ++extra_scroll_margin_lines;
14833 goto too_near_end;
14834 }
14835 rc = SCROLLING_SUCCESS;
14836 }
14837
14838 return rc;
14839 }
14840
14841
14842 /* Compute a suitable window start for window W if display of W starts
14843 on a continuation line. Value is non-zero if a new window start
14844 was computed.
14845
14846 The new window start will be computed, based on W's width, starting
14847 from the start of the continued line. It is the start of the
14848 screen line with the minimum distance from the old start W->start. */
14849
14850 static int
14851 compute_window_start_on_continuation_line (struct window *w)
14852 {
14853 struct text_pos pos, start_pos;
14854 int window_start_changed_p = 0;
14855
14856 SET_TEXT_POS_FROM_MARKER (start_pos, w->start);
14857
14858 /* If window start is on a continuation line... Window start may be
14859 < BEGV in case there's invisible text at the start of the
14860 buffer (M-x rmail, for example). */
14861 if (CHARPOS (start_pos) > BEGV
14862 && FETCH_BYTE (BYTEPOS (start_pos) - 1) != '\n')
14863 {
14864 struct it it;
14865 struct glyph_row *row;
14866
14867 /* Handle the case that the window start is out of range. */
14868 if (CHARPOS (start_pos) < BEGV)
14869 SET_TEXT_POS (start_pos, BEGV, BEGV_BYTE);
14870 else if (CHARPOS (start_pos) > ZV)
14871 SET_TEXT_POS (start_pos, ZV, ZV_BYTE);
14872
14873 /* Find the start of the continued line. This should be fast
14874 because scan_buffer is fast (newline cache). */
14875 row = w->desired_matrix->rows + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0);
14876 init_iterator (&it, w, CHARPOS (start_pos), BYTEPOS (start_pos),
14877 row, DEFAULT_FACE_ID);
14878 reseat_at_previous_visible_line_start (&it);
14879
14880 /* If the line start is "too far" away from the window start,
14881 say it takes too much time to compute a new window start. */
14882 if (CHARPOS (start_pos) - IT_CHARPOS (it)
14883 < WINDOW_TOTAL_LINES (w) * WINDOW_TOTAL_COLS (w))
14884 {
14885 int min_distance, distance;
14886
14887 /* Move forward by display lines to find the new window
14888 start. If window width was enlarged, the new start can
14889 be expected to be > the old start. If window width was
14890 decreased, the new window start will be < the old start.
14891 So, we're looking for the display line start with the
14892 minimum distance from the old window start. */
14893 pos = it.current.pos;
14894 min_distance = INFINITY;
14895 while ((distance = eabs (CHARPOS (start_pos) - IT_CHARPOS (it))),
14896 distance < min_distance)
14897 {
14898 min_distance = distance;
14899 pos = it.current.pos;
14900 move_it_by_lines (&it, 1);
14901 }
14902
14903 /* Set the window start there. */
14904 SET_MARKER_FROM_TEXT_POS (w->start, pos);
14905 window_start_changed_p = 1;
14906 }
14907 }
14908
14909 return window_start_changed_p;
14910 }
14911
14912
14913 /* Try cursor movement in case text has not changed in window WINDOW,
14914 with window start STARTP. Value is
14915
14916 CURSOR_MOVEMENT_SUCCESS if successful
14917
14918 CURSOR_MOVEMENT_CANNOT_BE_USED if this method cannot be used
14919
14920 CURSOR_MOVEMENT_MUST_SCROLL if we know we have to scroll the
14921 display. *SCROLL_STEP is set to 1, under certain circumstances, if
14922 we want to scroll as if scroll-step were set to 1. See the code.
14923
14924 CURSOR_MOVEMENT_NEED_LARGER_MATRICES if we need larger matrices, in
14925 which case we have to abort this redisplay, and adjust matrices
14926 first. */
14927
14928 enum
14929 {
14930 CURSOR_MOVEMENT_SUCCESS,
14931 CURSOR_MOVEMENT_CANNOT_BE_USED,
14932 CURSOR_MOVEMENT_MUST_SCROLL,
14933 CURSOR_MOVEMENT_NEED_LARGER_MATRICES
14934 };
14935
14936 static int
14937 try_cursor_movement (Lisp_Object window, struct text_pos startp, int *scroll_step)
14938 {
14939 struct window *w = XWINDOW (window);
14940 struct frame *f = XFRAME (w->frame);
14941 int rc = CURSOR_MOVEMENT_CANNOT_BE_USED;
14942
14943 #if GLYPH_DEBUG
14944 if (inhibit_try_cursor_movement)
14945 return rc;
14946 #endif
14947
14948 /* Handle case where text has not changed, only point, and it has
14949 not moved off the frame. */
14950 if (/* Point may be in this window. */
14951 PT >= CHARPOS (startp)
14952 /* Selective display hasn't changed. */
14953 && !current_buffer->clip_changed
14954 /* Function force-mode-line-update is used to force a thorough
14955 redisplay. It sets either windows_or_buffers_changed or
14956 update_mode_lines. So don't take a shortcut here for these
14957 cases. */
14958 && !update_mode_lines
14959 && !windows_or_buffers_changed
14960 && !cursor_type_changed
14961 /* Can't use this case if highlighting a region. When a
14962 region exists, cursor movement has to do more than just
14963 set the cursor. */
14964 && !(!NILP (Vtransient_mark_mode)
14965 && !NILP (BVAR (current_buffer, mark_active)))
14966 && NILP (w->region_showing)
14967 && NILP (Vshow_trailing_whitespace)
14968 /* Right after splitting windows, last_point may be nil. */
14969 && INTEGERP (w->last_point)
14970 /* This code is not used for mini-buffer for the sake of the case
14971 of redisplaying to replace an echo area message; since in
14972 that case the mini-buffer contents per se are usually
14973 unchanged. This code is of no real use in the mini-buffer
14974 since the handling of this_line_start_pos, etc., in redisplay
14975 handles the same cases. */
14976 && !EQ (window, minibuf_window)
14977 /* When splitting windows or for new windows, it happens that
14978 redisplay is called with a nil window_end_vpos or one being
14979 larger than the window. This should really be fixed in
14980 window.c. I don't have this on my list, now, so we do
14981 approximately the same as the old redisplay code. --gerd. */
14982 && INTEGERP (w->window_end_vpos)
14983 && XFASTINT (w->window_end_vpos) < w->current_matrix->nrows
14984 && (FRAME_WINDOW_P (f)
14985 || !overlay_arrow_in_current_buffer_p ()))
14986 {
14987 int this_scroll_margin, top_scroll_margin;
14988 struct glyph_row *row = NULL;
14989
14990 #if GLYPH_DEBUG
14991 debug_method_add (w, "cursor movement");
14992 #endif
14993
14994 /* Scroll if point within this distance from the top or bottom
14995 of the window. This is a pixel value. */
14996 if (scroll_margin > 0)
14997 {
14998 this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
14999 this_scroll_margin *= FRAME_LINE_HEIGHT (f);
15000 }
15001 else
15002 this_scroll_margin = 0;
15003
15004 top_scroll_margin = this_scroll_margin;
15005 if (WINDOW_WANTS_HEADER_LINE_P (w))
15006 top_scroll_margin += CURRENT_HEADER_LINE_HEIGHT (w);
15007
15008 /* Start with the row the cursor was displayed during the last
15009 not paused redisplay. Give up if that row is not valid. */
15010 if (w->last_cursor.vpos < 0
15011 || w->last_cursor.vpos >= w->current_matrix->nrows)
15012 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15013 else
15014 {
15015 row = MATRIX_ROW (w->current_matrix, w->last_cursor.vpos);
15016 if (row->mode_line_p)
15017 ++row;
15018 if (!row->enabled_p)
15019 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15020 }
15021
15022 if (rc == CURSOR_MOVEMENT_CANNOT_BE_USED)
15023 {
15024 int scroll_p = 0, must_scroll = 0;
15025 int last_y = window_text_bottom_y (w) - this_scroll_margin;
15026
15027 if (PT > XFASTINT (w->last_point))
15028 {
15029 /* Point has moved forward. */
15030 while (MATRIX_ROW_END_CHARPOS (row) < PT
15031 && MATRIX_ROW_BOTTOM_Y (row) < last_y)
15032 {
15033 xassert (row->enabled_p);
15034 ++row;
15035 }
15036
15037 /* If the end position of a row equals the start
15038 position of the next row, and PT is at that position,
15039 we would rather display cursor in the next line. */
15040 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
15041 && MATRIX_ROW_END_CHARPOS (row) == PT
15042 && row < w->current_matrix->rows
15043 + w->current_matrix->nrows - 1
15044 && MATRIX_ROW_START_CHARPOS (row+1) == PT
15045 && !cursor_row_p (row))
15046 ++row;
15047
15048 /* If within the scroll margin, scroll. Note that
15049 MATRIX_ROW_BOTTOM_Y gives the pixel position at which
15050 the next line would be drawn, and that
15051 this_scroll_margin can be zero. */
15052 if (MATRIX_ROW_BOTTOM_Y (row) > last_y
15053 || PT > MATRIX_ROW_END_CHARPOS (row)
15054 /* Line is completely visible last line in window
15055 and PT is to be set in the next line. */
15056 || (MATRIX_ROW_BOTTOM_Y (row) == last_y
15057 && PT == MATRIX_ROW_END_CHARPOS (row)
15058 && !row->ends_at_zv_p
15059 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
15060 scroll_p = 1;
15061 }
15062 else if (PT < XFASTINT (w->last_point))
15063 {
15064 /* Cursor has to be moved backward. Note that PT >=
15065 CHARPOS (startp) because of the outer if-statement. */
15066 while (!row->mode_line_p
15067 && (MATRIX_ROW_START_CHARPOS (row) > PT
15068 || (MATRIX_ROW_START_CHARPOS (row) == PT
15069 && (MATRIX_ROW_STARTS_IN_MIDDLE_OF_CHAR_P (row)
15070 || (/* STARTS_IN_MIDDLE_OF_STRING_P (row) */
15071 row > w->current_matrix->rows
15072 && (row-1)->ends_in_newline_from_string_p))))
15073 && (row->y > top_scroll_margin
15074 || CHARPOS (startp) == BEGV))
15075 {
15076 xassert (row->enabled_p);
15077 --row;
15078 }
15079
15080 /* Consider the following case: Window starts at BEGV,
15081 there is invisible, intangible text at BEGV, so that
15082 display starts at some point START > BEGV. It can
15083 happen that we are called with PT somewhere between
15084 BEGV and START. Try to handle that case. */
15085 if (row < w->current_matrix->rows
15086 || row->mode_line_p)
15087 {
15088 row = w->current_matrix->rows;
15089 if (row->mode_line_p)
15090 ++row;
15091 }
15092
15093 /* Due to newlines in overlay strings, we may have to
15094 skip forward over overlay strings. */
15095 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
15096 && MATRIX_ROW_END_CHARPOS (row) == PT
15097 && !cursor_row_p (row))
15098 ++row;
15099
15100 /* If within the scroll margin, scroll. */
15101 if (row->y < top_scroll_margin
15102 && CHARPOS (startp) != BEGV)
15103 scroll_p = 1;
15104 }
15105 else
15106 {
15107 /* Cursor did not move. So don't scroll even if cursor line
15108 is partially visible, as it was so before. */
15109 rc = CURSOR_MOVEMENT_SUCCESS;
15110 }
15111
15112 if (PT < MATRIX_ROW_START_CHARPOS (row)
15113 || PT > MATRIX_ROW_END_CHARPOS (row))
15114 {
15115 /* if PT is not in the glyph row, give up. */
15116 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15117 must_scroll = 1;
15118 }
15119 else if (rc != CURSOR_MOVEMENT_SUCCESS
15120 && !NILP (BVAR (XBUFFER (w->buffer), bidi_display_reordering)))
15121 {
15122 struct glyph_row *row1;
15123
15124 /* If rows are bidi-reordered and point moved, back up
15125 until we find a row that does not belong to a
15126 continuation line. This is because we must consider
15127 all rows of a continued line as candidates for the
15128 new cursor positioning, since row start and end
15129 positions change non-linearly with vertical position
15130 in such rows. */
15131 /* FIXME: Revisit this when glyph ``spilling'' in
15132 continuation lines' rows is implemented for
15133 bidi-reordered rows. */
15134 for (row1 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
15135 MATRIX_ROW_CONTINUATION_LINE_P (row);
15136 --row)
15137 {
15138 /* If we hit the beginning of the displayed portion
15139 without finding the first row of a continued
15140 line, give up. */
15141 if (row <= row1)
15142 {
15143 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15144 break;
15145 }
15146 xassert (row->enabled_p);
15147 }
15148 }
15149 if (must_scroll)
15150 ;
15151 else if (rc != CURSOR_MOVEMENT_SUCCESS
15152 && MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row)
15153 /* Make sure this isn't a header line by any chance, since
15154 then MATRIX_ROW_PARTIALLY_VISIBLE_P might yield non-zero. */
15155 && !row->mode_line_p
15156 && make_cursor_line_fully_visible_p)
15157 {
15158 if (PT == MATRIX_ROW_END_CHARPOS (row)
15159 && !row->ends_at_zv_p
15160 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
15161 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15162 else if (row->height > window_box_height (w))
15163 {
15164 /* If we end up in a partially visible line, let's
15165 make it fully visible, except when it's taller
15166 than the window, in which case we can't do much
15167 about it. */
15168 *scroll_step = 1;
15169 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15170 }
15171 else
15172 {
15173 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
15174 if (!cursor_row_fully_visible_p (w, 0, 1))
15175 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15176 else
15177 rc = CURSOR_MOVEMENT_SUCCESS;
15178 }
15179 }
15180 else if (scroll_p)
15181 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15182 else if (rc != CURSOR_MOVEMENT_SUCCESS
15183 && !NILP (BVAR (XBUFFER (w->buffer), bidi_display_reordering)))
15184 {
15185 /* With bidi-reordered rows, there could be more than
15186 one candidate row whose start and end positions
15187 occlude point. We need to let set_cursor_from_row
15188 find the best candidate. */
15189 /* FIXME: Revisit this when glyph ``spilling'' in
15190 continuation lines' rows is implemented for
15191 bidi-reordered rows. */
15192 int rv = 0;
15193
15194 do
15195 {
15196 int at_zv_p = 0, exact_match_p = 0;
15197
15198 if (MATRIX_ROW_START_CHARPOS (row) <= PT
15199 && PT <= MATRIX_ROW_END_CHARPOS (row)
15200 && cursor_row_p (row))
15201 rv |= set_cursor_from_row (w, row, w->current_matrix,
15202 0, 0, 0, 0);
15203 /* As soon as we've found the exact match for point,
15204 or the first suitable row whose ends_at_zv_p flag
15205 is set, we are done. */
15206 at_zv_p =
15207 MATRIX_ROW (w->current_matrix, w->cursor.vpos)->ends_at_zv_p;
15208 if (rv && !at_zv_p
15209 && w->cursor.hpos >= 0
15210 && w->cursor.hpos < MATRIX_ROW_USED (w->current_matrix,
15211 w->cursor.vpos))
15212 {
15213 struct glyph_row *candidate =
15214 MATRIX_ROW (w->current_matrix, w->cursor.vpos);
15215 struct glyph *g =
15216 candidate->glyphs[TEXT_AREA] + w->cursor.hpos;
15217 ptrdiff_t endpos = MATRIX_ROW_END_CHARPOS (candidate);
15218
15219 exact_match_p =
15220 (BUFFERP (g->object) && g->charpos == PT)
15221 || (INTEGERP (g->object)
15222 && (g->charpos == PT
15223 || (g->charpos == 0 && endpos - 1 == PT)));
15224 }
15225 if (rv && (at_zv_p || exact_match_p))
15226 {
15227 rc = CURSOR_MOVEMENT_SUCCESS;
15228 break;
15229 }
15230 if (MATRIX_ROW_BOTTOM_Y (row) == last_y)
15231 break;
15232 ++row;
15233 }
15234 while (((MATRIX_ROW_CONTINUATION_LINE_P (row)
15235 || row->continued_p)
15236 && MATRIX_ROW_BOTTOM_Y (row) <= last_y)
15237 || (MATRIX_ROW_START_CHARPOS (row) == PT
15238 && MATRIX_ROW_BOTTOM_Y (row) < last_y));
15239 /* If we didn't find any candidate rows, or exited the
15240 loop before all the candidates were examined, signal
15241 to the caller that this method failed. */
15242 if (rc != CURSOR_MOVEMENT_SUCCESS
15243 && !(rv
15244 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
15245 && !row->continued_p))
15246 rc = CURSOR_MOVEMENT_MUST_SCROLL;
15247 else if (rv)
15248 rc = CURSOR_MOVEMENT_SUCCESS;
15249 }
15250 else
15251 {
15252 do
15253 {
15254 if (set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0))
15255 {
15256 rc = CURSOR_MOVEMENT_SUCCESS;
15257 break;
15258 }
15259 ++row;
15260 }
15261 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
15262 && MATRIX_ROW_START_CHARPOS (row) == PT
15263 && cursor_row_p (row));
15264 }
15265 }
15266 }
15267
15268 return rc;
15269 }
15270
15271 #if !defined USE_TOOLKIT_SCROLL_BARS || defined USE_GTK
15272 static
15273 #endif
15274 void
15275 set_vertical_scroll_bar (struct window *w)
15276 {
15277 ptrdiff_t start, end, whole;
15278
15279 /* Calculate the start and end positions for the current window.
15280 At some point, it would be nice to choose between scrollbars
15281 which reflect the whole buffer size, with special markers
15282 indicating narrowing, and scrollbars which reflect only the
15283 visible region.
15284
15285 Note that mini-buffers sometimes aren't displaying any text. */
15286 if (!MINI_WINDOW_P (w)
15287 || (w == XWINDOW (minibuf_window)
15288 && NILP (echo_area_buffer[0])))
15289 {
15290 struct buffer *buf = XBUFFER (w->buffer);
15291 whole = BUF_ZV (buf) - BUF_BEGV (buf);
15292 start = marker_position (w->start) - BUF_BEGV (buf);
15293 /* I don't think this is guaranteed to be right. For the
15294 moment, we'll pretend it is. */
15295 end = BUF_Z (buf) - XFASTINT (w->window_end_pos) - BUF_BEGV (buf);
15296
15297 if (end < start)
15298 end = start;
15299 if (whole < (end - start))
15300 whole = end - start;
15301 }
15302 else
15303 start = end = whole = 0;
15304
15305 /* Indicate what this scroll bar ought to be displaying now. */
15306 if (FRAME_TERMINAL (XFRAME (w->frame))->set_vertical_scroll_bar_hook)
15307 (*FRAME_TERMINAL (XFRAME (w->frame))->set_vertical_scroll_bar_hook)
15308 (w, end - start, whole, start);
15309 }
15310
15311
15312 /* Redisplay leaf window WINDOW. JUST_THIS_ONE_P non-zero means only
15313 selected_window is redisplayed.
15314
15315 We can return without actually redisplaying the window if
15316 fonts_changed_p is nonzero. In that case, redisplay_internal will
15317 retry. */
15318
15319 static void
15320 redisplay_window (Lisp_Object window, int just_this_one_p)
15321 {
15322 struct window *w = XWINDOW (window);
15323 struct frame *f = XFRAME (w->frame);
15324 struct buffer *buffer = XBUFFER (w->buffer);
15325 struct buffer *old = current_buffer;
15326 struct text_pos lpoint, opoint, startp;
15327 int update_mode_line;
15328 int tem;
15329 struct it it;
15330 /* Record it now because it's overwritten. */
15331 int current_matrix_up_to_date_p = 0;
15332 int used_current_matrix_p = 0;
15333 /* This is less strict than current_matrix_up_to_date_p.
15334 It indicates that the buffer contents and narrowing are unchanged. */
15335 int buffer_unchanged_p = 0;
15336 int temp_scroll_step = 0;
15337 ptrdiff_t count = SPECPDL_INDEX ();
15338 int rc;
15339 int centering_position = -1;
15340 int last_line_misfit = 0;
15341 ptrdiff_t beg_unchanged, end_unchanged;
15342
15343 SET_TEXT_POS (lpoint, PT, PT_BYTE);
15344 opoint = lpoint;
15345
15346 /* W must be a leaf window here. */
15347 xassert (!NILP (w->buffer));
15348 #if GLYPH_DEBUG
15349 *w->desired_matrix->method = 0;
15350 #endif
15351
15352 restart:
15353 reconsider_clip_changes (w, buffer);
15354
15355 /* Has the mode line to be updated? */
15356 update_mode_line = (w->update_mode_line
15357 || update_mode_lines
15358 || buffer->clip_changed
15359 || buffer->prevent_redisplay_optimizations_p);
15360
15361 if (MINI_WINDOW_P (w))
15362 {
15363 if (w == XWINDOW (echo_area_window)
15364 && !NILP (echo_area_buffer[0]))
15365 {
15366 if (update_mode_line)
15367 /* We may have to update a tty frame's menu bar or a
15368 tool-bar. Example `M-x C-h C-h C-g'. */
15369 goto finish_menu_bars;
15370 else
15371 /* We've already displayed the echo area glyphs in this window. */
15372 goto finish_scroll_bars;
15373 }
15374 else if ((w != XWINDOW (minibuf_window)
15375 || minibuf_level == 0)
15376 /* When buffer is nonempty, redisplay window normally. */
15377 && BUF_Z (XBUFFER (w->buffer)) == BUF_BEG (XBUFFER (w->buffer))
15378 /* Quail displays non-mini buffers in minibuffer window.
15379 In that case, redisplay the window normally. */
15380 && !NILP (Fmemq (w->buffer, Vminibuffer_list)))
15381 {
15382 /* W is a mini-buffer window, but it's not active, so clear
15383 it. */
15384 int yb = window_text_bottom_y (w);
15385 struct glyph_row *row;
15386 int y;
15387
15388 for (y = 0, row = w->desired_matrix->rows;
15389 y < yb;
15390 y += row->height, ++row)
15391 blank_row (w, row, y);
15392 goto finish_scroll_bars;
15393 }
15394
15395 clear_glyph_matrix (w->desired_matrix);
15396 }
15397
15398 /* Otherwise set up data on this window; select its buffer and point
15399 value. */
15400 /* Really select the buffer, for the sake of buffer-local
15401 variables. */
15402 set_buffer_internal_1 (XBUFFER (w->buffer));
15403
15404 current_matrix_up_to_date_p
15405 = (!NILP (w->window_end_valid)
15406 && !current_buffer->clip_changed
15407 && !current_buffer->prevent_redisplay_optimizations_p
15408 && XFASTINT (w->last_modified) >= MODIFF
15409 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
15410
15411 /* Run the window-bottom-change-functions
15412 if it is possible that the text on the screen has changed
15413 (either due to modification of the text, or any other reason). */
15414 if (!current_matrix_up_to_date_p
15415 && !NILP (Vwindow_text_change_functions))
15416 {
15417 safe_run_hooks (Qwindow_text_change_functions);
15418 goto restart;
15419 }
15420
15421 beg_unchanged = BEG_UNCHANGED;
15422 end_unchanged = END_UNCHANGED;
15423
15424 SET_TEXT_POS (opoint, PT, PT_BYTE);
15425
15426 specbind (Qinhibit_point_motion_hooks, Qt);
15427
15428 buffer_unchanged_p
15429 = (!NILP (w->window_end_valid)
15430 && !current_buffer->clip_changed
15431 && XFASTINT (w->last_modified) >= MODIFF
15432 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
15433
15434 /* When windows_or_buffers_changed is non-zero, we can't rely on
15435 the window end being valid, so set it to nil there. */
15436 if (windows_or_buffers_changed)
15437 {
15438 /* If window starts on a continuation line, maybe adjust the
15439 window start in case the window's width changed. */
15440 if (XMARKER (w->start)->buffer == current_buffer)
15441 compute_window_start_on_continuation_line (w);
15442
15443 w->window_end_valid = Qnil;
15444 }
15445
15446 /* Some sanity checks. */
15447 CHECK_WINDOW_END (w);
15448 if (Z == Z_BYTE && CHARPOS (opoint) != BYTEPOS (opoint))
15449 abort ();
15450 if (BYTEPOS (opoint) < CHARPOS (opoint))
15451 abort ();
15452
15453 /* If %c is in mode line, update it if needed. */
15454 if (!NILP (w->column_number_displayed)
15455 /* This alternative quickly identifies a common case
15456 where no change is needed. */
15457 && !(PT == XFASTINT (w->last_point)
15458 && XFASTINT (w->last_modified) >= MODIFF
15459 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
15460 && (XFASTINT (w->column_number_displayed) != current_column ()))
15461 update_mode_line = 1;
15462
15463 /* Count number of windows showing the selected buffer. An indirect
15464 buffer counts as its base buffer. */
15465 if (!just_this_one_p)
15466 {
15467 struct buffer *current_base, *window_base;
15468 current_base = current_buffer;
15469 window_base = XBUFFER (XWINDOW (selected_window)->buffer);
15470 if (current_base->base_buffer)
15471 current_base = current_base->base_buffer;
15472 if (window_base->base_buffer)
15473 window_base = window_base->base_buffer;
15474 if (current_base == window_base)
15475 buffer_shared++;
15476 }
15477
15478 /* Point refers normally to the selected window. For any other
15479 window, set up appropriate value. */
15480 if (!EQ (window, selected_window))
15481 {
15482 ptrdiff_t new_pt = XMARKER (w->pointm)->charpos;
15483 ptrdiff_t new_pt_byte = marker_byte_position (w->pointm);
15484 if (new_pt < BEGV)
15485 {
15486 new_pt = BEGV;
15487 new_pt_byte = BEGV_BYTE;
15488 set_marker_both (w->pointm, Qnil, BEGV, BEGV_BYTE);
15489 }
15490 else if (new_pt > (ZV - 1))
15491 {
15492 new_pt = ZV;
15493 new_pt_byte = ZV_BYTE;
15494 set_marker_both (w->pointm, Qnil, ZV, ZV_BYTE);
15495 }
15496
15497 /* We don't use SET_PT so that the point-motion hooks don't run. */
15498 TEMP_SET_PT_BOTH (new_pt, new_pt_byte);
15499 }
15500
15501 /* If any of the character widths specified in the display table
15502 have changed, invalidate the width run cache. It's true that
15503 this may be a bit late to catch such changes, but the rest of
15504 redisplay goes (non-fatally) haywire when the display table is
15505 changed, so why should we worry about doing any better? */
15506 if (current_buffer->width_run_cache)
15507 {
15508 struct Lisp_Char_Table *disptab = buffer_display_table ();
15509
15510 if (! disptab_matches_widthtab (disptab,
15511 XVECTOR (BVAR (current_buffer, width_table))))
15512 {
15513 invalidate_region_cache (current_buffer,
15514 current_buffer->width_run_cache,
15515 BEG, Z);
15516 recompute_width_table (current_buffer, disptab);
15517 }
15518 }
15519
15520 /* If window-start is screwed up, choose a new one. */
15521 if (XMARKER (w->start)->buffer != current_buffer)
15522 goto recenter;
15523
15524 SET_TEXT_POS_FROM_MARKER (startp, w->start);
15525
15526 /* If someone specified a new starting point but did not insist,
15527 check whether it can be used. */
15528 if (w->optional_new_start
15529 && CHARPOS (startp) >= BEGV
15530 && CHARPOS (startp) <= ZV)
15531 {
15532 w->optional_new_start = 0;
15533 start_display (&it, w, startp);
15534 move_it_to (&it, PT, 0, it.last_visible_y, -1,
15535 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
15536 if (IT_CHARPOS (it) == PT)
15537 w->force_start = 1;
15538 /* IT may overshoot PT if text at PT is invisible. */
15539 else if (IT_CHARPOS (it) > PT && CHARPOS (startp) <= PT)
15540 w->force_start = 1;
15541 }
15542
15543 force_start:
15544
15545 /* Handle case where place to start displaying has been specified,
15546 unless the specified location is outside the accessible range. */
15547 if (w->force_start || w->frozen_window_start_p)
15548 {
15549 /* We set this later on if we have to adjust point. */
15550 int new_vpos = -1;
15551
15552 w->force_start = 0;
15553 w->vscroll = 0;
15554 w->window_end_valid = Qnil;
15555
15556 /* Forget any recorded base line for line number display. */
15557 if (!buffer_unchanged_p)
15558 w->base_line_number = Qnil;
15559
15560 /* Redisplay the mode line. Select the buffer properly for that.
15561 Also, run the hook window-scroll-functions
15562 because we have scrolled. */
15563 /* Note, we do this after clearing force_start because
15564 if there's an error, it is better to forget about force_start
15565 than to get into an infinite loop calling the hook functions
15566 and having them get more errors. */
15567 if (!update_mode_line
15568 || ! NILP (Vwindow_scroll_functions))
15569 {
15570 update_mode_line = 1;
15571 w->update_mode_line = 1;
15572 startp = run_window_scroll_functions (window, startp);
15573 }
15574
15575 w->last_modified = make_number (0);
15576 w->last_overlay_modified = make_number (0);
15577 if (CHARPOS (startp) < BEGV)
15578 SET_TEXT_POS (startp, BEGV, BEGV_BYTE);
15579 else if (CHARPOS (startp) > ZV)
15580 SET_TEXT_POS (startp, ZV, ZV_BYTE);
15581
15582 /* Redisplay, then check if cursor has been set during the
15583 redisplay. Give up if new fonts were loaded. */
15584 /* We used to issue a CHECK_MARGINS argument to try_window here,
15585 but this causes scrolling to fail when point begins inside
15586 the scroll margin (bug#148) -- cyd */
15587 if (!try_window (window, startp, 0))
15588 {
15589 w->force_start = 1;
15590 clear_glyph_matrix (w->desired_matrix);
15591 goto need_larger_matrices;
15592 }
15593
15594 if (w->cursor.vpos < 0 && !w->frozen_window_start_p)
15595 {
15596 /* If point does not appear, try to move point so it does
15597 appear. The desired matrix has been built above, so we
15598 can use it here. */
15599 new_vpos = window_box_height (w) / 2;
15600 }
15601
15602 if (!cursor_row_fully_visible_p (w, 0, 0))
15603 {
15604 /* Point does appear, but on a line partly visible at end of window.
15605 Move it back to a fully-visible line. */
15606 new_vpos = window_box_height (w);
15607 }
15608
15609 /* If we need to move point for either of the above reasons,
15610 now actually do it. */
15611 if (new_vpos >= 0)
15612 {
15613 struct glyph_row *row;
15614
15615 row = MATRIX_FIRST_TEXT_ROW (w->desired_matrix);
15616 while (MATRIX_ROW_BOTTOM_Y (row) < new_vpos)
15617 ++row;
15618
15619 TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row),
15620 MATRIX_ROW_START_BYTEPOS (row));
15621
15622 if (w != XWINDOW (selected_window))
15623 set_marker_both (w->pointm, Qnil, PT, PT_BYTE);
15624 else if (current_buffer == old)
15625 SET_TEXT_POS (lpoint, PT, PT_BYTE);
15626
15627 set_cursor_from_row (w, row, w->desired_matrix, 0, 0, 0, 0);
15628
15629 /* If we are highlighting the region, then we just changed
15630 the region, so redisplay to show it. */
15631 if (!NILP (Vtransient_mark_mode)
15632 && !NILP (BVAR (current_buffer, mark_active)))
15633 {
15634 clear_glyph_matrix (w->desired_matrix);
15635 if (!try_window (window, startp, 0))
15636 goto need_larger_matrices;
15637 }
15638 }
15639
15640 #if GLYPH_DEBUG
15641 debug_method_add (w, "forced window start");
15642 #endif
15643 goto done;
15644 }
15645
15646 /* Handle case where text has not changed, only point, and it has
15647 not moved off the frame, and we are not retrying after hscroll.
15648 (current_matrix_up_to_date_p is nonzero when retrying.) */
15649 if (current_matrix_up_to_date_p
15650 && (rc = try_cursor_movement (window, startp, &temp_scroll_step),
15651 rc != CURSOR_MOVEMENT_CANNOT_BE_USED))
15652 {
15653 switch (rc)
15654 {
15655 case CURSOR_MOVEMENT_SUCCESS:
15656 used_current_matrix_p = 1;
15657 goto done;
15658
15659 case CURSOR_MOVEMENT_MUST_SCROLL:
15660 goto try_to_scroll;
15661
15662 default:
15663 abort ();
15664 }
15665 }
15666 /* If current starting point was originally the beginning of a line
15667 but no longer is, find a new starting point. */
15668 else if (w->start_at_line_beg
15669 && !(CHARPOS (startp) <= BEGV
15670 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n'))
15671 {
15672 #if GLYPH_DEBUG
15673 debug_method_add (w, "recenter 1");
15674 #endif
15675 goto recenter;
15676 }
15677
15678 /* Try scrolling with try_window_id. Value is > 0 if update has
15679 been done, it is -1 if we know that the same window start will
15680 not work. It is 0 if unsuccessful for some other reason. */
15681 else if ((tem = try_window_id (w)) != 0)
15682 {
15683 #if GLYPH_DEBUG
15684 debug_method_add (w, "try_window_id %d", tem);
15685 #endif
15686
15687 if (fonts_changed_p)
15688 goto need_larger_matrices;
15689 if (tem > 0)
15690 goto done;
15691
15692 /* Otherwise try_window_id has returned -1 which means that we
15693 don't want the alternative below this comment to execute. */
15694 }
15695 else if (CHARPOS (startp) >= BEGV
15696 && CHARPOS (startp) <= ZV
15697 && PT >= CHARPOS (startp)
15698 && (CHARPOS (startp) < ZV
15699 /* Avoid starting at end of buffer. */
15700 || CHARPOS (startp) == BEGV
15701 || (XFASTINT (w->last_modified) >= MODIFF
15702 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)))
15703 {
15704 int d1, d2, d3, d4, d5, d6;
15705
15706 /* If first window line is a continuation line, and window start
15707 is inside the modified region, but the first change is before
15708 current window start, we must select a new window start.
15709
15710 However, if this is the result of a down-mouse event (e.g. by
15711 extending the mouse-drag-overlay), we don't want to select a
15712 new window start, since that would change the position under
15713 the mouse, resulting in an unwanted mouse-movement rather
15714 than a simple mouse-click. */
15715 if (!w->start_at_line_beg
15716 && NILP (do_mouse_tracking)
15717 && CHARPOS (startp) > BEGV
15718 && CHARPOS (startp) > BEG + beg_unchanged
15719 && CHARPOS (startp) <= Z - end_unchanged
15720 /* Even if w->start_at_line_beg is nil, a new window may
15721 start at a line_beg, since that's how set_buffer_window
15722 sets it. So, we need to check the return value of
15723 compute_window_start_on_continuation_line. (See also
15724 bug#197). */
15725 && XMARKER (w->start)->buffer == current_buffer
15726 && compute_window_start_on_continuation_line (w)
15727 /* It doesn't make sense to force the window start like we
15728 do at label force_start if it is already known that point
15729 will not be visible in the resulting window, because
15730 doing so will move point from its correct position
15731 instead of scrolling the window to bring point into view.
15732 See bug#9324. */
15733 && pos_visible_p (w, PT, &d1, &d2, &d3, &d4, &d5, &d6))
15734 {
15735 w->force_start = 1;
15736 SET_TEXT_POS_FROM_MARKER (startp, w->start);
15737 goto force_start;
15738 }
15739
15740 #if GLYPH_DEBUG
15741 debug_method_add (w, "same window start");
15742 #endif
15743
15744 /* Try to redisplay starting at same place as before.
15745 If point has not moved off frame, accept the results. */
15746 if (!current_matrix_up_to_date_p
15747 /* Don't use try_window_reusing_current_matrix in this case
15748 because a window scroll function can have changed the
15749 buffer. */
15750 || !NILP (Vwindow_scroll_functions)
15751 || MINI_WINDOW_P (w)
15752 || !(used_current_matrix_p
15753 = try_window_reusing_current_matrix (w)))
15754 {
15755 IF_DEBUG (debug_method_add (w, "1"));
15756 if (try_window (window, startp, TRY_WINDOW_CHECK_MARGINS) < 0)
15757 /* -1 means we need to scroll.
15758 0 means we need new matrices, but fonts_changed_p
15759 is set in that case, so we will detect it below. */
15760 goto try_to_scroll;
15761 }
15762
15763 if (fonts_changed_p)
15764 goto need_larger_matrices;
15765
15766 if (w->cursor.vpos >= 0)
15767 {
15768 if (!just_this_one_p
15769 || current_buffer->clip_changed
15770 || BEG_UNCHANGED < CHARPOS (startp))
15771 /* Forget any recorded base line for line number display. */
15772 w->base_line_number = Qnil;
15773
15774 if (!cursor_row_fully_visible_p (w, 1, 0))
15775 {
15776 clear_glyph_matrix (w->desired_matrix);
15777 last_line_misfit = 1;
15778 }
15779 /* Drop through and scroll. */
15780 else
15781 goto done;
15782 }
15783 else
15784 clear_glyph_matrix (w->desired_matrix);
15785 }
15786
15787 try_to_scroll:
15788
15789 w->last_modified = make_number (0);
15790 w->last_overlay_modified = make_number (0);
15791
15792 /* Redisplay the mode line. Select the buffer properly for that. */
15793 if (!update_mode_line)
15794 {
15795 update_mode_line = 1;
15796 w->update_mode_line = 1;
15797 }
15798
15799 /* Try to scroll by specified few lines. */
15800 if ((scroll_conservatively
15801 || emacs_scroll_step
15802 || temp_scroll_step
15803 || NUMBERP (BVAR (current_buffer, scroll_up_aggressively))
15804 || NUMBERP (BVAR (current_buffer, scroll_down_aggressively)))
15805 && CHARPOS (startp) >= BEGV
15806 && CHARPOS (startp) <= ZV)
15807 {
15808 /* The function returns -1 if new fonts were loaded, 1 if
15809 successful, 0 if not successful. */
15810 int ss = try_scrolling (window, just_this_one_p,
15811 scroll_conservatively,
15812 emacs_scroll_step,
15813 temp_scroll_step, last_line_misfit);
15814 switch (ss)
15815 {
15816 case SCROLLING_SUCCESS:
15817 goto done;
15818
15819 case SCROLLING_NEED_LARGER_MATRICES:
15820 goto need_larger_matrices;
15821
15822 case SCROLLING_FAILED:
15823 break;
15824
15825 default:
15826 abort ();
15827 }
15828 }
15829
15830 /* Finally, just choose a place to start which positions point
15831 according to user preferences. */
15832
15833 recenter:
15834
15835 #if GLYPH_DEBUG
15836 debug_method_add (w, "recenter");
15837 #endif
15838
15839 /* w->vscroll = 0; */
15840
15841 /* Forget any previously recorded base line for line number display. */
15842 if (!buffer_unchanged_p)
15843 w->base_line_number = Qnil;
15844
15845 /* Determine the window start relative to point. */
15846 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
15847 it.current_y = it.last_visible_y;
15848 if (centering_position < 0)
15849 {
15850 int margin =
15851 scroll_margin > 0
15852 ? min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4)
15853 : 0;
15854 ptrdiff_t margin_pos = CHARPOS (startp);
15855 Lisp_Object aggressive;
15856 int scrolling_up;
15857
15858 /* If there is a scroll margin at the top of the window, find
15859 its character position. */
15860 if (margin
15861 /* Cannot call start_display if startp is not in the
15862 accessible region of the buffer. This can happen when we
15863 have just switched to a different buffer and/or changed
15864 its restriction. In that case, startp is initialized to
15865 the character position 1 (BEGV) because we did not yet
15866 have chance to display the buffer even once. */
15867 && BEGV <= CHARPOS (startp) && CHARPOS (startp) <= ZV)
15868 {
15869 struct it it1;
15870 void *it1data = NULL;
15871
15872 SAVE_IT (it1, it, it1data);
15873 start_display (&it1, w, startp);
15874 move_it_vertically (&it1, margin * FRAME_LINE_HEIGHT (f));
15875 margin_pos = IT_CHARPOS (it1);
15876 RESTORE_IT (&it, &it, it1data);
15877 }
15878 scrolling_up = PT > margin_pos;
15879 aggressive =
15880 scrolling_up
15881 ? BVAR (current_buffer, scroll_up_aggressively)
15882 : BVAR (current_buffer, scroll_down_aggressively);
15883
15884 if (!MINI_WINDOW_P (w)
15885 && (scroll_conservatively > SCROLL_LIMIT || NUMBERP (aggressive)))
15886 {
15887 int pt_offset = 0;
15888
15889 /* Setting scroll-conservatively overrides
15890 scroll-*-aggressively. */
15891 if (!scroll_conservatively && NUMBERP (aggressive))
15892 {
15893 double float_amount = XFLOATINT (aggressive);
15894
15895 pt_offset = float_amount * WINDOW_BOX_TEXT_HEIGHT (w);
15896 if (pt_offset == 0 && float_amount > 0)
15897 pt_offset = 1;
15898 if (pt_offset && margin > 0)
15899 margin -= 1;
15900 }
15901 /* Compute how much to move the window start backward from
15902 point so that point will be displayed where the user
15903 wants it. */
15904 if (scrolling_up)
15905 {
15906 centering_position = it.last_visible_y;
15907 if (pt_offset)
15908 centering_position -= pt_offset;
15909 centering_position -=
15910 FRAME_LINE_HEIGHT (f) * (1 + margin + (last_line_misfit != 0))
15911 + WINDOW_HEADER_LINE_HEIGHT (w);
15912 /* Don't let point enter the scroll margin near top of
15913 the window. */
15914 if (centering_position < margin * FRAME_LINE_HEIGHT (f))
15915 centering_position = margin * FRAME_LINE_HEIGHT (f);
15916 }
15917 else
15918 centering_position = margin * FRAME_LINE_HEIGHT (f) + pt_offset;
15919 }
15920 else
15921 /* Set the window start half the height of the window backward
15922 from point. */
15923 centering_position = window_box_height (w) / 2;
15924 }
15925 move_it_vertically_backward (&it, centering_position);
15926
15927 xassert (IT_CHARPOS (it) >= BEGV);
15928
15929 /* The function move_it_vertically_backward may move over more
15930 than the specified y-distance. If it->w is small, e.g. a
15931 mini-buffer window, we may end up in front of the window's
15932 display area. Start displaying at the start of the line
15933 containing PT in this case. */
15934 if (it.current_y <= 0)
15935 {
15936 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
15937 move_it_vertically_backward (&it, 0);
15938 it.current_y = 0;
15939 }
15940
15941 it.current_x = it.hpos = 0;
15942
15943 /* Set the window start position here explicitly, to avoid an
15944 infinite loop in case the functions in window-scroll-functions
15945 get errors. */
15946 set_marker_both (w->start, Qnil, IT_CHARPOS (it), IT_BYTEPOS (it));
15947
15948 /* Run scroll hooks. */
15949 startp = run_window_scroll_functions (window, it.current.pos);
15950
15951 /* Redisplay the window. */
15952 if (!current_matrix_up_to_date_p
15953 || windows_or_buffers_changed
15954 || cursor_type_changed
15955 /* Don't use try_window_reusing_current_matrix in this case
15956 because it can have changed the buffer. */
15957 || !NILP (Vwindow_scroll_functions)
15958 || !just_this_one_p
15959 || MINI_WINDOW_P (w)
15960 || !(used_current_matrix_p
15961 = try_window_reusing_current_matrix (w)))
15962 try_window (window, startp, 0);
15963
15964 /* If new fonts have been loaded (due to fontsets), give up. We
15965 have to start a new redisplay since we need to re-adjust glyph
15966 matrices. */
15967 if (fonts_changed_p)
15968 goto need_larger_matrices;
15969
15970 /* If cursor did not appear assume that the middle of the window is
15971 in the first line of the window. Do it again with the next line.
15972 (Imagine a window of height 100, displaying two lines of height
15973 60. Moving back 50 from it->last_visible_y will end in the first
15974 line.) */
15975 if (w->cursor.vpos < 0)
15976 {
15977 if (!NILP (w->window_end_valid)
15978 && PT >= Z - XFASTINT (w->window_end_pos))
15979 {
15980 clear_glyph_matrix (w->desired_matrix);
15981 move_it_by_lines (&it, 1);
15982 try_window (window, it.current.pos, 0);
15983 }
15984 else if (PT < IT_CHARPOS (it))
15985 {
15986 clear_glyph_matrix (w->desired_matrix);
15987 move_it_by_lines (&it, -1);
15988 try_window (window, it.current.pos, 0);
15989 }
15990 else
15991 {
15992 /* Not much we can do about it. */
15993 }
15994 }
15995
15996 /* Consider the following case: Window starts at BEGV, there is
15997 invisible, intangible text at BEGV, so that display starts at
15998 some point START > BEGV. It can happen that we are called with
15999 PT somewhere between BEGV and START. Try to handle that case. */
16000 if (w->cursor.vpos < 0)
16001 {
16002 struct glyph_row *row = w->current_matrix->rows;
16003 if (row->mode_line_p)
16004 ++row;
16005 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
16006 }
16007
16008 if (!cursor_row_fully_visible_p (w, 0, 0))
16009 {
16010 /* If vscroll is enabled, disable it and try again. */
16011 if (w->vscroll)
16012 {
16013 w->vscroll = 0;
16014 clear_glyph_matrix (w->desired_matrix);
16015 goto recenter;
16016 }
16017
16018 /* Users who set scroll-conservatively to a large number want
16019 point just above/below the scroll margin. If we ended up
16020 with point's row partially visible, move the window start to
16021 make that row fully visible and out of the margin. */
16022 if (scroll_conservatively > SCROLL_LIMIT)
16023 {
16024 int margin =
16025 scroll_margin > 0
16026 ? min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4)
16027 : 0;
16028 int move_down = w->cursor.vpos >= WINDOW_TOTAL_LINES (w) / 2;
16029
16030 move_it_by_lines (&it, move_down ? margin + 1 : -(margin + 1));
16031 clear_glyph_matrix (w->desired_matrix);
16032 if (1 == try_window (window, it.current.pos,
16033 TRY_WINDOW_CHECK_MARGINS))
16034 goto done;
16035 }
16036
16037 /* If centering point failed to make the whole line visible,
16038 put point at the top instead. That has to make the whole line
16039 visible, if it can be done. */
16040 if (centering_position == 0)
16041 goto done;
16042
16043 clear_glyph_matrix (w->desired_matrix);
16044 centering_position = 0;
16045 goto recenter;
16046 }
16047
16048 done:
16049
16050 SET_TEXT_POS_FROM_MARKER (startp, w->start);
16051 w->start_at_line_beg = (CHARPOS (startp) == BEGV
16052 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n');
16053
16054 /* Display the mode line, if we must. */
16055 if ((update_mode_line
16056 /* If window not full width, must redo its mode line
16057 if (a) the window to its side is being redone and
16058 (b) we do a frame-based redisplay. This is a consequence
16059 of how inverted lines are drawn in frame-based redisplay. */
16060 || (!just_this_one_p
16061 && !FRAME_WINDOW_P (f)
16062 && !WINDOW_FULL_WIDTH_P (w))
16063 /* Line number to display. */
16064 || INTEGERP (w->base_line_pos)
16065 /* Column number is displayed and different from the one displayed. */
16066 || (!NILP (w->column_number_displayed)
16067 && (XFASTINT (w->column_number_displayed) != current_column ())))
16068 /* This means that the window has a mode line. */
16069 && (WINDOW_WANTS_MODELINE_P (w)
16070 || WINDOW_WANTS_HEADER_LINE_P (w)))
16071 {
16072 display_mode_lines (w);
16073
16074 /* If mode line height has changed, arrange for a thorough
16075 immediate redisplay using the correct mode line height. */
16076 if (WINDOW_WANTS_MODELINE_P (w)
16077 && CURRENT_MODE_LINE_HEIGHT (w) != DESIRED_MODE_LINE_HEIGHT (w))
16078 {
16079 fonts_changed_p = 1;
16080 MATRIX_MODE_LINE_ROW (w->current_matrix)->height
16081 = DESIRED_MODE_LINE_HEIGHT (w);
16082 }
16083
16084 /* If header line height has changed, arrange for a thorough
16085 immediate redisplay using the correct header line height. */
16086 if (WINDOW_WANTS_HEADER_LINE_P (w)
16087 && CURRENT_HEADER_LINE_HEIGHT (w) != DESIRED_HEADER_LINE_HEIGHT (w))
16088 {
16089 fonts_changed_p = 1;
16090 MATRIX_HEADER_LINE_ROW (w->current_matrix)->height
16091 = DESIRED_HEADER_LINE_HEIGHT (w);
16092 }
16093
16094 if (fonts_changed_p)
16095 goto need_larger_matrices;
16096 }
16097
16098 if (!line_number_displayed
16099 && !BUFFERP (w->base_line_pos))
16100 {
16101 w->base_line_pos = Qnil;
16102 w->base_line_number = Qnil;
16103 }
16104
16105 finish_menu_bars:
16106
16107 /* When we reach a frame's selected window, redo the frame's menu bar. */
16108 if (update_mode_line
16109 && EQ (FRAME_SELECTED_WINDOW (f), window))
16110 {
16111 int redisplay_menu_p = 0;
16112
16113 if (FRAME_WINDOW_P (f))
16114 {
16115 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
16116 || defined (HAVE_NS) || defined (USE_GTK)
16117 redisplay_menu_p = FRAME_EXTERNAL_MENU_BAR (f);
16118 #else
16119 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
16120 #endif
16121 }
16122 else
16123 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
16124
16125 if (redisplay_menu_p)
16126 display_menu_bar (w);
16127
16128 #ifdef HAVE_WINDOW_SYSTEM
16129 if (FRAME_WINDOW_P (f))
16130 {
16131 #if defined (USE_GTK) || defined (HAVE_NS)
16132 if (FRAME_EXTERNAL_TOOL_BAR (f))
16133 redisplay_tool_bar (f);
16134 #else
16135 if (WINDOWP (f->tool_bar_window)
16136 && (FRAME_TOOL_BAR_LINES (f) > 0
16137 || !NILP (Vauto_resize_tool_bars))
16138 && redisplay_tool_bar (f))
16139 ignore_mouse_drag_p = 1;
16140 #endif
16141 }
16142 #endif
16143 }
16144
16145 #ifdef HAVE_WINDOW_SYSTEM
16146 if (FRAME_WINDOW_P (f)
16147 && update_window_fringes (w, (just_this_one_p
16148 || (!used_current_matrix_p && !overlay_arrow_seen)
16149 || w->pseudo_window_p)))
16150 {
16151 update_begin (f);
16152 BLOCK_INPUT;
16153 if (draw_window_fringes (w, 1))
16154 x_draw_vertical_border (w);
16155 UNBLOCK_INPUT;
16156 update_end (f);
16157 }
16158 #endif /* HAVE_WINDOW_SYSTEM */
16159
16160 /* We go to this label, with fonts_changed_p nonzero,
16161 if it is necessary to try again using larger glyph matrices.
16162 We have to redeem the scroll bar even in this case,
16163 because the loop in redisplay_internal expects that. */
16164 need_larger_matrices:
16165 ;
16166 finish_scroll_bars:
16167
16168 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
16169 {
16170 /* Set the thumb's position and size. */
16171 set_vertical_scroll_bar (w);
16172
16173 /* Note that we actually used the scroll bar attached to this
16174 window, so it shouldn't be deleted at the end of redisplay. */
16175 if (FRAME_TERMINAL (f)->redeem_scroll_bar_hook)
16176 (*FRAME_TERMINAL (f)->redeem_scroll_bar_hook) (w);
16177 }
16178
16179 /* Restore current_buffer and value of point in it. The window
16180 update may have changed the buffer, so first make sure `opoint'
16181 is still valid (Bug#6177). */
16182 if (CHARPOS (opoint) < BEGV)
16183 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
16184 else if (CHARPOS (opoint) > ZV)
16185 TEMP_SET_PT_BOTH (Z, Z_BYTE);
16186 else
16187 TEMP_SET_PT_BOTH (CHARPOS (opoint), BYTEPOS (opoint));
16188
16189 set_buffer_internal_1 (old);
16190 /* Avoid an abort in TEMP_SET_PT_BOTH if the buffer has become
16191 shorter. This can be caused by log truncation in *Messages*. */
16192 if (CHARPOS (lpoint) <= ZV)
16193 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
16194
16195 unbind_to (count, Qnil);
16196 }
16197
16198
16199 /* Build the complete desired matrix of WINDOW with a window start
16200 buffer position POS.
16201
16202 Value is 1 if successful. It is zero if fonts were loaded during
16203 redisplay which makes re-adjusting glyph matrices necessary, and -1
16204 if point would appear in the scroll margins.
16205 (We check the former only if TRY_WINDOW_IGNORE_FONTS_CHANGE is
16206 unset in FLAGS, and the latter only if TRY_WINDOW_CHECK_MARGINS is
16207 set in FLAGS.) */
16208
16209 int
16210 try_window (Lisp_Object window, struct text_pos pos, int flags)
16211 {
16212 struct window *w = XWINDOW (window);
16213 struct it it;
16214 struct glyph_row *last_text_row = NULL;
16215 struct frame *f = XFRAME (w->frame);
16216
16217 /* Make POS the new window start. */
16218 set_marker_both (w->start, Qnil, CHARPOS (pos), BYTEPOS (pos));
16219
16220 /* Mark cursor position as unknown. No overlay arrow seen. */
16221 w->cursor.vpos = -1;
16222 overlay_arrow_seen = 0;
16223
16224 /* Initialize iterator and info to start at POS. */
16225 start_display (&it, w, pos);
16226
16227
16228
16229 /* Display all lines of W. */
16230 while (it.current_y < it.last_visible_y)
16231 {
16232 if (display_line (&it))
16233 last_text_row = it.glyph_row - 1;
16234 if (fonts_changed_p && !(flags & TRY_WINDOW_IGNORE_FONTS_CHANGE))
16235 return 0;
16236 }
16237 #ifdef HAVE_XWIDGETS_xxx
16238 //currently this is needed to detect xwidget movement reliably. or probably not.
16239 printf("try_window\n");
16240 return 0;
16241 #endif
16242
16243 /* Don't let the cursor end in the scroll margins. */
16244 if ((flags & TRY_WINDOW_CHECK_MARGINS)
16245 && !MINI_WINDOW_P (w))
16246 {
16247 int this_scroll_margin;
16248
16249 if (scroll_margin > 0)
16250 {
16251 this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
16252 this_scroll_margin *= FRAME_LINE_HEIGHT (f);
16253 }
16254 else
16255 this_scroll_margin = 0;
16256
16257 if ((w->cursor.y >= 0 /* not vscrolled */
16258 && w->cursor.y < this_scroll_margin
16259 && CHARPOS (pos) > BEGV
16260 && IT_CHARPOS (it) < ZV)
16261 /* rms: considering make_cursor_line_fully_visible_p here
16262 seems to give wrong results. We don't want to recenter
16263 when the last line is partly visible, we want to allow
16264 that case to be handled in the usual way. */
16265 || w->cursor.y > it.last_visible_y - this_scroll_margin - 1)
16266 {
16267 w->cursor.vpos = -1;
16268 clear_glyph_matrix (w->desired_matrix);
16269 return -1;
16270 }
16271 }
16272
16273 /* If bottom moved off end of frame, change mode line percentage. */
16274 if (XFASTINT (w->window_end_pos) <= 0
16275 && Z != IT_CHARPOS (it))
16276 w->update_mode_line = 1;
16277
16278 /* Set window_end_pos to the offset of the last character displayed
16279 on the window from the end of current_buffer. Set
16280 window_end_vpos to its row number. */
16281 if (last_text_row)
16282 {
16283 xassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row));
16284 w->window_end_bytepos
16285 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
16286 w->window_end_pos
16287 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
16288 w->window_end_vpos
16289 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
16290 xassert (MATRIX_ROW (w->desired_matrix, XFASTINT (w->window_end_vpos))
16291 ->displays_text_p);
16292 }
16293 else
16294 {
16295 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
16296 w->window_end_pos = make_number (Z - ZV);
16297 w->window_end_vpos = make_number (0);
16298 }
16299
16300 /* But that is not valid info until redisplay finishes. */
16301 w->window_end_valid = Qnil;
16302 return 1;
16303 }
16304
16305
16306 \f
16307 /************************************************************************
16308 Window redisplay reusing current matrix when buffer has not changed
16309 ************************************************************************/
16310
16311 /* Try redisplay of window W showing an unchanged buffer with a
16312 different window start than the last time it was displayed by
16313 reusing its current matrix. Value is non-zero if successful.
16314 W->start is the new window start. */
16315
16316 static int
16317 try_window_reusing_current_matrix (struct window *w)
16318 {
16319 struct frame *f = XFRAME (w->frame);
16320 struct glyph_row *bottom_row;
16321 struct it it;
16322 struct run run;
16323 struct text_pos start, new_start;
16324 int nrows_scrolled, i;
16325 struct glyph_row *last_text_row;
16326 struct glyph_row *last_reused_text_row;
16327 struct glyph_row *start_row;
16328 int start_vpos, min_y, max_y;
16329
16330 #if GLYPH_DEBUG
16331 if (inhibit_try_window_reusing)
16332 return 0;
16333 #endif
16334
16335 #ifdef HAVE_XWIDGETS_xxx
16336 //currently this is needed to detect xwidget movement reliably. or probably not.
16337 printf("try_window_reusing_current_matrix\n");
16338 return 0;
16339 #endif
16340
16341
16342 if (/* This function doesn't handle terminal frames. */
16343 !FRAME_WINDOW_P (f)
16344 /* Don't try to reuse the display if windows have been split
16345 or such. */
16346 || windows_or_buffers_changed
16347 || cursor_type_changed)
16348 return 0;
16349
16350 /* Can't do this if region may have changed. */
16351 if ((!NILP (Vtransient_mark_mode)
16352 && !NILP (BVAR (current_buffer, mark_active)))
16353 || !NILP (w->region_showing)
16354 || !NILP (Vshow_trailing_whitespace))
16355 return 0;
16356
16357 /* If top-line visibility has changed, give up. */
16358 if (WINDOW_WANTS_HEADER_LINE_P (w)
16359 != MATRIX_HEADER_LINE_ROW (w->current_matrix)->mode_line_p)
16360 return 0;
16361
16362 /* Give up if old or new display is scrolled vertically. We could
16363 make this function handle this, but right now it doesn't. */
16364 start_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
16365 if (w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row))
16366 return 0;
16367
16368 /* The variable new_start now holds the new window start. The old
16369 start `start' can be determined from the current matrix. */
16370 SET_TEXT_POS_FROM_MARKER (new_start, w->start);
16371 start = start_row->minpos;
16372 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
16373
16374 /* Clear the desired matrix for the display below. */
16375 clear_glyph_matrix (w->desired_matrix);
16376
16377 if (CHARPOS (new_start) <= CHARPOS (start))
16378 {
16379 /* Don't use this method if the display starts with an ellipsis
16380 displayed for invisible text. It's not easy to handle that case
16381 below, and it's certainly not worth the effort since this is
16382 not a frequent case. */
16383 if (in_ellipses_for_invisible_text_p (&start_row->start, w))
16384 return 0;
16385
16386 IF_DEBUG (debug_method_add (w, "twu1"));
16387
16388 /* Display up to a row that can be reused. The variable
16389 last_text_row is set to the last row displayed that displays
16390 text. Note that it.vpos == 0 if or if not there is a
16391 header-line; it's not the same as the MATRIX_ROW_VPOS! */
16392 start_display (&it, w, new_start);
16393 w->cursor.vpos = -1;
16394 last_text_row = last_reused_text_row = NULL;
16395
16396 while (it.current_y < it.last_visible_y
16397 && !fonts_changed_p)
16398 {
16399 /* If we have reached into the characters in the START row,
16400 that means the line boundaries have changed. So we
16401 can't start copying with the row START. Maybe it will
16402 work to start copying with the following row. */
16403 while (IT_CHARPOS (it) > CHARPOS (start))
16404 {
16405 /* Advance to the next row as the "start". */
16406 start_row++;
16407 start = start_row->minpos;
16408 /* If there are no more rows to try, or just one, give up. */
16409 if (start_row == MATRIX_MODE_LINE_ROW (w->current_matrix) - 1
16410 || w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row)
16411 || CHARPOS (start) == ZV)
16412 {
16413 clear_glyph_matrix (w->desired_matrix);
16414 return 0;
16415 }
16416
16417 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
16418 }
16419 /* If we have reached alignment, we can copy the rest of the
16420 rows. */
16421 if (IT_CHARPOS (it) == CHARPOS (start)
16422 /* Don't accept "alignment" inside a display vector,
16423 since start_row could have started in the middle of
16424 that same display vector (thus their character
16425 positions match), and we have no way of telling if
16426 that is the case. */
16427 && it.current.dpvec_index < 0)
16428 break;
16429
16430 if (display_line (&it))
16431 last_text_row = it.glyph_row - 1;
16432
16433 }
16434
16435 /* A value of current_y < last_visible_y means that we stopped
16436 at the previous window start, which in turn means that we
16437 have at least one reusable row. */
16438 if (it.current_y < it.last_visible_y)
16439 {
16440 struct glyph_row *row;
16441
16442 /* IT.vpos always starts from 0; it counts text lines. */
16443 nrows_scrolled = it.vpos - (start_row - MATRIX_FIRST_TEXT_ROW (w->current_matrix));
16444
16445 /* Find PT if not already found in the lines displayed. */
16446 if (w->cursor.vpos < 0)
16447 {
16448 int dy = it.current_y - start_row->y;
16449
16450 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
16451 row = row_containing_pos (w, PT, row, NULL, dy);
16452 if (row)
16453 set_cursor_from_row (w, row, w->current_matrix, 0, 0,
16454 dy, nrows_scrolled);
16455 else
16456 {
16457 clear_glyph_matrix (w->desired_matrix);
16458 return 0;
16459 }
16460 }
16461
16462 /* Scroll the display. Do it before the current matrix is
16463 changed. The problem here is that update has not yet
16464 run, i.e. part of the current matrix is not up to date.
16465 scroll_run_hook will clear the cursor, and use the
16466 current matrix to get the height of the row the cursor is
16467 in. */
16468 run.current_y = start_row->y;
16469 run.desired_y = it.current_y;
16470 run.height = it.last_visible_y - it.current_y;
16471
16472 if (run.height > 0 && run.current_y != run.desired_y)
16473 {
16474 update_begin (f);
16475 FRAME_RIF (f)->update_window_begin_hook (w);
16476 FRAME_RIF (f)->clear_window_mouse_face (w);
16477 FRAME_RIF (f)->scroll_run_hook (w, &run);
16478 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
16479 update_end (f);
16480 }
16481
16482 /* Shift current matrix down by nrows_scrolled lines. */
16483 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
16484 rotate_matrix (w->current_matrix,
16485 start_vpos,
16486 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
16487 nrows_scrolled);
16488
16489 /* Disable lines that must be updated. */
16490 for (i = 0; i < nrows_scrolled; ++i)
16491 (start_row + i)->enabled_p = 0;
16492
16493 /* Re-compute Y positions. */
16494 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
16495 max_y = it.last_visible_y;
16496 for (row = start_row + nrows_scrolled;
16497 row < bottom_row;
16498 ++row)
16499 {
16500 row->y = it.current_y;
16501 row->visible_height = row->height;
16502
16503 if (row->y < min_y)
16504 row->visible_height -= min_y - row->y;
16505 if (row->y + row->height > max_y)
16506 row->visible_height -= row->y + row->height - max_y;
16507 if (row->fringe_bitmap_periodic_p)
16508 row->redraw_fringe_bitmaps_p = 1;
16509
16510 it.current_y += row->height;
16511
16512 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
16513 last_reused_text_row = row;
16514 if (MATRIX_ROW_BOTTOM_Y (row) >= it.last_visible_y)
16515 break;
16516 }
16517
16518 /* Disable lines in the current matrix which are now
16519 below the window. */
16520 for (++row; row < bottom_row; ++row)
16521 row->enabled_p = row->mode_line_p = 0;
16522 }
16523
16524 /* Update window_end_pos etc.; last_reused_text_row is the last
16525 reused row from the current matrix containing text, if any.
16526 The value of last_text_row is the last displayed line
16527 containing text. */
16528 if (last_reused_text_row)
16529 {
16530 w->window_end_bytepos
16531 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_reused_text_row);
16532 w->window_end_pos
16533 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_reused_text_row));
16534 w->window_end_vpos
16535 = make_number (MATRIX_ROW_VPOS (last_reused_text_row,
16536 w->current_matrix));
16537 }
16538 else if (last_text_row)
16539 {
16540 w->window_end_bytepos
16541 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
16542 w->window_end_pos
16543 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
16544 w->window_end_vpos
16545 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
16546 }
16547 else
16548 {
16549 /* This window must be completely empty. */
16550 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
16551 w->window_end_pos = make_number (Z - ZV);
16552 w->window_end_vpos = make_number (0);
16553 }
16554 w->window_end_valid = Qnil;
16555
16556 /* Update hint: don't try scrolling again in update_window. */
16557 w->desired_matrix->no_scrolling_p = 1;
16558
16559 #if GLYPH_DEBUG
16560 debug_method_add (w, "try_window_reusing_current_matrix 1");
16561 #endif
16562 return 1;
16563 }
16564 else if (CHARPOS (new_start) > CHARPOS (start))
16565 {
16566 struct glyph_row *pt_row, *row;
16567 struct glyph_row *first_reusable_row;
16568 struct glyph_row *first_row_to_display;
16569 int dy;
16570 int yb = window_text_bottom_y (w);
16571
16572 /* Find the row starting at new_start, if there is one. Don't
16573 reuse a partially visible line at the end. */
16574 first_reusable_row = start_row;
16575 while (first_reusable_row->enabled_p
16576 && MATRIX_ROW_BOTTOM_Y (first_reusable_row) < yb
16577 && (MATRIX_ROW_START_CHARPOS (first_reusable_row)
16578 < CHARPOS (new_start)))
16579 ++first_reusable_row;
16580
16581 /* Give up if there is no row to reuse. */
16582 if (MATRIX_ROW_BOTTOM_Y (first_reusable_row) >= yb
16583 || !first_reusable_row->enabled_p
16584 || (MATRIX_ROW_START_CHARPOS (first_reusable_row)
16585 != CHARPOS (new_start)))
16586 return 0;
16587
16588 /* We can reuse fully visible rows beginning with
16589 first_reusable_row to the end of the window. Set
16590 first_row_to_display to the first row that cannot be reused.
16591 Set pt_row to the row containing point, if there is any. */
16592 pt_row = NULL;
16593 for (first_row_to_display = first_reusable_row;
16594 MATRIX_ROW_BOTTOM_Y (first_row_to_display) < yb;
16595 ++first_row_to_display)
16596 {
16597 if (PT >= MATRIX_ROW_START_CHARPOS (first_row_to_display)
16598 && (PT < MATRIX_ROW_END_CHARPOS (first_row_to_display)
16599 || (PT == MATRIX_ROW_END_CHARPOS (first_row_to_display)
16600 && first_row_to_display->ends_at_zv_p
16601 && pt_row == NULL)))
16602 pt_row = first_row_to_display;
16603 }
16604
16605 /* Start displaying at the start of first_row_to_display. */
16606 xassert (first_row_to_display->y < yb);
16607 init_to_row_start (&it, w, first_row_to_display);
16608
16609 nrows_scrolled = (MATRIX_ROW_VPOS (first_reusable_row, w->current_matrix)
16610 - start_vpos);
16611 it.vpos = (MATRIX_ROW_VPOS (first_row_to_display, w->current_matrix)
16612 - nrows_scrolled);
16613 it.current_y = (first_row_to_display->y - first_reusable_row->y
16614 + WINDOW_HEADER_LINE_HEIGHT (w));
16615
16616 /* Display lines beginning with first_row_to_display in the
16617 desired matrix. Set last_text_row to the last row displayed
16618 that displays text. */
16619 it.glyph_row = MATRIX_ROW (w->desired_matrix, it.vpos);
16620 if (pt_row == NULL)
16621 w->cursor.vpos = -1;
16622 last_text_row = NULL;
16623 while (it.current_y < it.last_visible_y && !fonts_changed_p)
16624 if (display_line (&it))
16625 last_text_row = it.glyph_row - 1;
16626
16627 /* If point is in a reused row, adjust y and vpos of the cursor
16628 position. */
16629 if (pt_row)
16630 {
16631 w->cursor.vpos -= nrows_scrolled;
16632 w->cursor.y -= first_reusable_row->y - start_row->y;
16633 }
16634
16635 /* Give up if point isn't in a row displayed or reused. (This
16636 also handles the case where w->cursor.vpos < nrows_scrolled
16637 after the calls to display_line, which can happen with scroll
16638 margins. See bug#1295.) */
16639 if (w->cursor.vpos < 0)
16640 {
16641 clear_glyph_matrix (w->desired_matrix);
16642 return 0;
16643 }
16644
16645 /* Scroll the display. */
16646 run.current_y = first_reusable_row->y;
16647 run.desired_y = WINDOW_HEADER_LINE_HEIGHT (w);
16648 run.height = it.last_visible_y - run.current_y;
16649 dy = run.current_y - run.desired_y;
16650
16651 if (run.height)
16652 {
16653 update_begin (f);
16654 FRAME_RIF (f)->update_window_begin_hook (w);
16655 FRAME_RIF (f)->clear_window_mouse_face (w);
16656 FRAME_RIF (f)->scroll_run_hook (w, &run);
16657 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
16658 update_end (f);
16659 }
16660
16661 /* Adjust Y positions of reused rows. */
16662 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
16663 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
16664 max_y = it.last_visible_y;
16665 for (row = first_reusable_row; row < first_row_to_display; ++row)
16666 {
16667 row->y -= dy;
16668 row->visible_height = row->height;
16669 if (row->y < min_y)
16670 row->visible_height -= min_y - row->y;
16671 if (row->y + row->height > max_y)
16672 row->visible_height -= row->y + row->height - max_y;
16673 if (row->fringe_bitmap_periodic_p)
16674 row->redraw_fringe_bitmaps_p = 1;
16675 }
16676
16677 /* Scroll the current matrix. */
16678 xassert (nrows_scrolled > 0);
16679 rotate_matrix (w->current_matrix,
16680 start_vpos,
16681 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
16682 -nrows_scrolled);
16683
16684 /* Disable rows not reused. */
16685 for (row -= nrows_scrolled; row < bottom_row; ++row)
16686 row->enabled_p = 0;
16687
16688 /* Point may have moved to a different line, so we cannot assume that
16689 the previous cursor position is valid; locate the correct row. */
16690 if (pt_row)
16691 {
16692 for (row = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
16693 row < bottom_row
16694 && PT >= MATRIX_ROW_END_CHARPOS (row)
16695 && !row->ends_at_zv_p;
16696 row++)
16697 {
16698 w->cursor.vpos++;
16699 w->cursor.y = row->y;
16700 }
16701 if (row < bottom_row)
16702 {
16703 struct glyph *glyph = row->glyphs[TEXT_AREA] + w->cursor.hpos;
16704 struct glyph *end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
16705
16706 /* Can't use this optimization with bidi-reordered glyph
16707 rows, unless cursor is already at point. */
16708 if (!NILP (BVAR (XBUFFER (w->buffer), bidi_display_reordering)))
16709 {
16710 if (!(w->cursor.hpos >= 0
16711 && w->cursor.hpos < row->used[TEXT_AREA]
16712 && BUFFERP (glyph->object)
16713 && glyph->charpos == PT))
16714 return 0;
16715 }
16716 else
16717 for (; glyph < end
16718 && (!BUFFERP (glyph->object)
16719 || glyph->charpos < PT);
16720 glyph++)
16721 {
16722 w->cursor.hpos++;
16723 w->cursor.x += glyph->pixel_width;
16724 }
16725 }
16726 }
16727
16728 /* Adjust window end. A null value of last_text_row means that
16729 the window end is in reused rows which in turn means that
16730 only its vpos can have changed. */
16731 if (last_text_row)
16732 {
16733 w->window_end_bytepos
16734 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
16735 w->window_end_pos
16736 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
16737 w->window_end_vpos
16738 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
16739 }
16740 else
16741 {
16742 w->window_end_vpos
16743 = make_number (XFASTINT (w->window_end_vpos) - nrows_scrolled);
16744 }
16745
16746 w->window_end_valid = Qnil;
16747 w->desired_matrix->no_scrolling_p = 1;
16748
16749 #if GLYPH_DEBUG
16750 debug_method_add (w, "try_window_reusing_current_matrix 2");
16751 #endif
16752 return 1;
16753 }
16754
16755 return 0;
16756 }
16757
16758
16759 \f
16760 /************************************************************************
16761 Window redisplay reusing current matrix when buffer has changed
16762 ************************************************************************/
16763
16764 static struct glyph_row *find_last_unchanged_at_beg_row (struct window *);
16765 static struct glyph_row *find_first_unchanged_at_end_row (struct window *,
16766 ptrdiff_t *, ptrdiff_t *);
16767 static struct glyph_row *
16768 find_last_row_displaying_text (struct glyph_matrix *, struct it *,
16769 struct glyph_row *);
16770
16771
16772 /* Return the last row in MATRIX displaying text. If row START is
16773 non-null, start searching with that row. IT gives the dimensions
16774 of the display. Value is null if matrix is empty; otherwise it is
16775 a pointer to the row found. */
16776
16777 static struct glyph_row *
16778 find_last_row_displaying_text (struct glyph_matrix *matrix, struct it *it,
16779 struct glyph_row *start)
16780 {
16781 struct glyph_row *row, *row_found;
16782
16783 /* Set row_found to the last row in IT->w's current matrix
16784 displaying text. The loop looks funny but think of partially
16785 visible lines. */
16786 row_found = NULL;
16787 row = start ? start : MATRIX_FIRST_TEXT_ROW (matrix);
16788 while (MATRIX_ROW_DISPLAYS_TEXT_P (row))
16789 {
16790 xassert (row->enabled_p);
16791 row_found = row;
16792 if (MATRIX_ROW_BOTTOM_Y (row) >= it->last_visible_y)
16793 break;
16794 ++row;
16795 }
16796
16797 return row_found;
16798 }
16799
16800
16801 /* Return the last row in the current matrix of W that is not affected
16802 by changes at the start of current_buffer that occurred since W's
16803 current matrix was built. Value is null if no such row exists.
16804
16805 BEG_UNCHANGED us the number of characters unchanged at the start of
16806 current_buffer. BEG + BEG_UNCHANGED is the buffer position of the
16807 first changed character in current_buffer. Characters at positions <
16808 BEG + BEG_UNCHANGED are at the same buffer positions as they were
16809 when the current matrix was built. */
16810
16811 static struct glyph_row *
16812 find_last_unchanged_at_beg_row (struct window *w)
16813 {
16814 ptrdiff_t first_changed_pos = BEG + BEG_UNCHANGED;
16815 struct glyph_row *row;
16816 struct glyph_row *row_found = NULL;
16817 int yb = window_text_bottom_y (w);
16818
16819 /* Find the last row displaying unchanged text. */
16820 for (row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
16821 MATRIX_ROW_DISPLAYS_TEXT_P (row)
16822 && MATRIX_ROW_START_CHARPOS (row) < first_changed_pos;
16823 ++row)
16824 {
16825 if (/* If row ends before first_changed_pos, it is unchanged,
16826 except in some case. */
16827 MATRIX_ROW_END_CHARPOS (row) <= first_changed_pos
16828 /* When row ends in ZV and we write at ZV it is not
16829 unchanged. */
16830 && !row->ends_at_zv_p
16831 /* When first_changed_pos is the end of a continued line,
16832 row is not unchanged because it may be no longer
16833 continued. */
16834 && !(MATRIX_ROW_END_CHARPOS (row) == first_changed_pos
16835 && (row->continued_p
16836 || row->exact_window_width_line_p))
16837 /* If ROW->end is beyond ZV, then ROW->end is outdated and
16838 needs to be recomputed, so don't consider this row as
16839 unchanged. This happens when the last line was
16840 bidi-reordered and was killed immediately before this
16841 redisplay cycle. In that case, ROW->end stores the
16842 buffer position of the first visual-order character of
16843 the killed text, which is now beyond ZV. */
16844 && CHARPOS (row->end.pos) <= ZV)
16845 row_found = row;
16846
16847 /* Stop if last visible row. */
16848 if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
16849 break;
16850 }
16851
16852 return row_found;
16853 }
16854
16855
16856 /* Find the first glyph row in the current matrix of W that is not
16857 affected by changes at the end of current_buffer since the
16858 time W's current matrix was built.
16859
16860 Return in *DELTA the number of chars by which buffer positions in
16861 unchanged text at the end of current_buffer must be adjusted.
16862
16863 Return in *DELTA_BYTES the corresponding number of bytes.
16864
16865 Value is null if no such row exists, i.e. all rows are affected by
16866 changes. */
16867
16868 static struct glyph_row *
16869 find_first_unchanged_at_end_row (struct window *w,
16870 ptrdiff_t *delta, ptrdiff_t *delta_bytes)
16871 {
16872 struct glyph_row *row;
16873 struct glyph_row *row_found = NULL;
16874
16875 *delta = *delta_bytes = 0;
16876
16877 /* Display must not have been paused, otherwise the current matrix
16878 is not up to date. */
16879 eassert (!NILP (w->window_end_valid));
16880
16881 /* A value of window_end_pos >= END_UNCHANGED means that the window
16882 end is in the range of changed text. If so, there is no
16883 unchanged row at the end of W's current matrix. */
16884 if (XFASTINT (w->window_end_pos) >= END_UNCHANGED)
16885 return NULL;
16886
16887 /* Set row to the last row in W's current matrix displaying text. */
16888 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
16889
16890 /* If matrix is entirely empty, no unchanged row exists. */
16891 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
16892 {
16893 /* The value of row is the last glyph row in the matrix having a
16894 meaningful buffer position in it. The end position of row
16895 corresponds to window_end_pos. This allows us to translate
16896 buffer positions in the current matrix to current buffer
16897 positions for characters not in changed text. */
16898 ptrdiff_t Z_old =
16899 MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
16900 ptrdiff_t Z_BYTE_old =
16901 MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
16902 ptrdiff_t last_unchanged_pos, last_unchanged_pos_old;
16903 struct glyph_row *first_text_row
16904 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
16905
16906 *delta = Z - Z_old;
16907 *delta_bytes = Z_BYTE - Z_BYTE_old;
16908
16909 /* Set last_unchanged_pos to the buffer position of the last
16910 character in the buffer that has not been changed. Z is the
16911 index + 1 of the last character in current_buffer, i.e. by
16912 subtracting END_UNCHANGED we get the index of the last
16913 unchanged character, and we have to add BEG to get its buffer
16914 position. */
16915 last_unchanged_pos = Z - END_UNCHANGED + BEG;
16916 last_unchanged_pos_old = last_unchanged_pos - *delta;
16917
16918 /* Search backward from ROW for a row displaying a line that
16919 starts at a minimum position >= last_unchanged_pos_old. */
16920 for (; row > first_text_row; --row)
16921 {
16922 /* This used to abort, but it can happen.
16923 It is ok to just stop the search instead here. KFS. */
16924 if (!row->enabled_p || !MATRIX_ROW_DISPLAYS_TEXT_P (row))
16925 break;
16926
16927 if (MATRIX_ROW_START_CHARPOS (row) >= last_unchanged_pos_old)
16928 row_found = row;
16929 }
16930 }
16931
16932 eassert (!row_found || MATRIX_ROW_DISPLAYS_TEXT_P (row_found));
16933
16934 return row_found;
16935 }
16936
16937
16938 /* Make sure that glyph rows in the current matrix of window W
16939 reference the same glyph memory as corresponding rows in the
16940 frame's frame matrix. This function is called after scrolling W's
16941 current matrix on a terminal frame in try_window_id and
16942 try_window_reusing_current_matrix. */
16943
16944 static void
16945 sync_frame_with_window_matrix_rows (struct window *w)
16946 {
16947 struct frame *f = XFRAME (w->frame);
16948 struct glyph_row *window_row, *window_row_end, *frame_row;
16949
16950 /* Preconditions: W must be a leaf window and full-width. Its frame
16951 must have a frame matrix. */
16952 xassert (NILP (w->hchild) && NILP (w->vchild));
16953 xassert (WINDOW_FULL_WIDTH_P (w));
16954 xassert (!FRAME_WINDOW_P (f));
16955
16956 /* If W is a full-width window, glyph pointers in W's current matrix
16957 have, by definition, to be the same as glyph pointers in the
16958 corresponding frame matrix. Note that frame matrices have no
16959 marginal areas (see build_frame_matrix). */
16960 window_row = w->current_matrix->rows;
16961 window_row_end = window_row + w->current_matrix->nrows;
16962 frame_row = f->current_matrix->rows + WINDOW_TOP_EDGE_LINE (w);
16963 while (window_row < window_row_end)
16964 {
16965 struct glyph *start = window_row->glyphs[LEFT_MARGIN_AREA];
16966 struct glyph *end = window_row->glyphs[LAST_AREA];
16967
16968 frame_row->glyphs[LEFT_MARGIN_AREA] = start;
16969 frame_row->glyphs[TEXT_AREA] = start;
16970 frame_row->glyphs[RIGHT_MARGIN_AREA] = end;
16971 frame_row->glyphs[LAST_AREA] = end;
16972
16973 /* Disable frame rows whose corresponding window rows have
16974 been disabled in try_window_id. */
16975 if (!window_row->enabled_p)
16976 frame_row->enabled_p = 0;
16977
16978 ++window_row, ++frame_row;
16979 }
16980 }
16981
16982
16983 /* Find the glyph row in window W containing CHARPOS. Consider all
16984 rows between START and END (not inclusive). END null means search
16985 all rows to the end of the display area of W. Value is the row
16986 containing CHARPOS or null. */
16987
16988 struct glyph_row *
16989 row_containing_pos (struct window *w, ptrdiff_t charpos,
16990 struct glyph_row *start, struct glyph_row *end, int dy)
16991 {
16992 struct glyph_row *row = start;
16993 struct glyph_row *best_row = NULL;
16994 ptrdiff_t mindif = BUF_ZV (XBUFFER (w->buffer)) + 1;
16995 int last_y;
16996
16997 /* If we happen to start on a header-line, skip that. */
16998 if (row->mode_line_p)
16999 ++row;
17000
17001 if ((end && row >= end) || !row->enabled_p)
17002 return NULL;
17003
17004 last_y = window_text_bottom_y (w) - dy;
17005
17006 while (1)
17007 {
17008 /* Give up if we have gone too far. */
17009 if (end && row >= end)
17010 return NULL;
17011 /* This formerly returned if they were equal.
17012 I think that both quantities are of a "last plus one" type;
17013 if so, when they are equal, the row is within the screen. -- rms. */
17014 if (MATRIX_ROW_BOTTOM_Y (row) > last_y)
17015 return NULL;
17016
17017 /* If it is in this row, return this row. */
17018 if (! (MATRIX_ROW_END_CHARPOS (row) < charpos
17019 || (MATRIX_ROW_END_CHARPOS (row) == charpos
17020 /* The end position of a row equals the start
17021 position of the next row. If CHARPOS is there, we
17022 would rather display it in the next line, except
17023 when this line ends in ZV. */
17024 && !row->ends_at_zv_p
17025 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
17026 && charpos >= MATRIX_ROW_START_CHARPOS (row))
17027 {
17028 struct glyph *g;
17029
17030 if (NILP (BVAR (XBUFFER (w->buffer), bidi_display_reordering))
17031 || (!best_row && !row->continued_p))
17032 return row;
17033 /* In bidi-reordered rows, there could be several rows
17034 occluding point, all of them belonging to the same
17035 continued line. We need to find the row which fits
17036 CHARPOS the best. */
17037 for (g = row->glyphs[TEXT_AREA];
17038 g < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
17039 g++)
17040 {
17041 if (!STRINGP (g->object))
17042 {
17043 if (g->charpos > 0 && eabs (g->charpos - charpos) < mindif)
17044 {
17045 mindif = eabs (g->charpos - charpos);
17046 best_row = row;
17047 /* Exact match always wins. */
17048 if (mindif == 0)
17049 return best_row;
17050 }
17051 }
17052 }
17053 }
17054 else if (best_row && !row->continued_p)
17055 return best_row;
17056 ++row;
17057 }
17058 }
17059
17060
17061 /* Try to redisplay window W by reusing its existing display. W's
17062 current matrix must be up to date when this function is called,
17063 i.e. window_end_valid must not be nil.
17064
17065 Value is
17066
17067 1 if display has been updated
17068 0 if otherwise unsuccessful
17069 -1 if redisplay with same window start is known not to succeed
17070
17071 The following steps are performed:
17072
17073 1. Find the last row in the current matrix of W that is not
17074 affected by changes at the start of current_buffer. If no such row
17075 is found, give up.
17076
17077 2. Find the first row in W's current matrix that is not affected by
17078 changes at the end of current_buffer. Maybe there is no such row.
17079
17080 3. Display lines beginning with the row + 1 found in step 1 to the
17081 row found in step 2 or, if step 2 didn't find a row, to the end of
17082 the window.
17083
17084 4. If cursor is not known to appear on the window, give up.
17085
17086 5. If display stopped at the row found in step 2, scroll the
17087 display and current matrix as needed.
17088
17089 6. Maybe display some lines at the end of W, if we must. This can
17090 happen under various circumstances, like a partially visible line
17091 becoming fully visible, or because newly displayed lines are displayed
17092 in smaller font sizes.
17093
17094 7. Update W's window end information. */
17095
17096 static int
17097 try_window_id (struct window *w)
17098 {
17099 struct frame *f = XFRAME (w->frame);
17100 struct glyph_matrix *current_matrix = w->current_matrix;
17101 struct glyph_matrix *desired_matrix = w->desired_matrix;
17102 struct glyph_row *last_unchanged_at_beg_row;
17103 struct glyph_row *first_unchanged_at_end_row;
17104 struct glyph_row *row;
17105 struct glyph_row *bottom_row;
17106 int bottom_vpos;
17107 struct it it;
17108 ptrdiff_t delta = 0, delta_bytes = 0, stop_pos;
17109 int dvpos, dy;
17110 struct text_pos start_pos;
17111 struct run run;
17112 int first_unchanged_at_end_vpos = 0;
17113 struct glyph_row *last_text_row, *last_text_row_at_end;
17114 struct text_pos start;
17115 ptrdiff_t first_changed_charpos, last_changed_charpos;
17116
17117 #if GLYPH_DEBUG
17118 if (inhibit_try_window_id)
17119 return 0;
17120 #endif
17121
17122 #ifdef HAVE_XWIDGETS_xxx
17123 //maybe needed for proper xwidget movement
17124 printf("try_window_id\n");
17125 return -1;
17126 #endif
17127
17128
17129 /* This is handy for debugging. */
17130 #if 0
17131 #define GIVE_UP(X) \
17132 do { \
17133 fprintf (stderr, "try_window_id give up %d\n", (X)); \
17134 return 0; \
17135 } while (0)
17136 #else
17137 #define GIVE_UP(X) return 0
17138 #endif
17139
17140 SET_TEXT_POS_FROM_MARKER (start, w->start);
17141
17142 /* Don't use this for mini-windows because these can show
17143 messages and mini-buffers, and we don't handle that here. */
17144 if (MINI_WINDOW_P (w))
17145 GIVE_UP (1);
17146
17147 /* This flag is used to prevent redisplay optimizations. */
17148 if (windows_or_buffers_changed || cursor_type_changed)
17149 GIVE_UP (2);
17150
17151 /* Verify that narrowing has not changed.
17152 Also verify that we were not told to prevent redisplay optimizations.
17153 It would be nice to further
17154 reduce the number of cases where this prevents try_window_id. */
17155 if (current_buffer->clip_changed
17156 || current_buffer->prevent_redisplay_optimizations_p)
17157 GIVE_UP (3);
17158
17159 /* Window must either use window-based redisplay or be full width. */
17160 if (!FRAME_WINDOW_P (f)
17161 && (!FRAME_LINE_INS_DEL_OK (f)
17162 || !WINDOW_FULL_WIDTH_P (w)))
17163 GIVE_UP (4);
17164
17165 /* Give up if point is known NOT to appear in W. */
17166 if (PT < CHARPOS (start))
17167 GIVE_UP (5);
17168
17169 /* Another way to prevent redisplay optimizations. */
17170 if (XFASTINT (w->last_modified) == 0)
17171 GIVE_UP (6);
17172
17173 /* Verify that window is not hscrolled. */
17174 if (XFASTINT (w->hscroll) != 0)
17175 GIVE_UP (7);
17176
17177 /* Verify that display wasn't paused. */
17178 if (NILP (w->window_end_valid))
17179 GIVE_UP (8);
17180
17181 /* Can't use this if highlighting a region because a cursor movement
17182 will do more than just set the cursor. */
17183 if (!NILP (Vtransient_mark_mode)
17184 && !NILP (BVAR (current_buffer, mark_active)))
17185 GIVE_UP (9);
17186
17187 /* Likewise if highlighting trailing whitespace. */
17188 if (!NILP (Vshow_trailing_whitespace))
17189 GIVE_UP (11);
17190
17191 /* Likewise if showing a region. */
17192 if (!NILP (w->region_showing))
17193 GIVE_UP (10);
17194
17195 /* Can't use this if overlay arrow position and/or string have
17196 changed. */
17197 if (overlay_arrows_changed_p ())
17198 GIVE_UP (12);
17199
17200 /* When word-wrap is on, adding a space to the first word of a
17201 wrapped line can change the wrap position, altering the line
17202 above it. It might be worthwhile to handle this more
17203 intelligently, but for now just redisplay from scratch. */
17204 if (!NILP (BVAR (XBUFFER (w->buffer), word_wrap)))
17205 GIVE_UP (21);
17206
17207 /* Under bidi reordering, adding or deleting a character in the
17208 beginning of a paragraph, before the first strong directional
17209 character, can change the base direction of the paragraph (unless
17210 the buffer specifies a fixed paragraph direction), which will
17211 require to redisplay the whole paragraph. It might be worthwhile
17212 to find the paragraph limits and widen the range of redisplayed
17213 lines to that, but for now just give up this optimization and
17214 redisplay from scratch. */
17215 if (!NILP (BVAR (XBUFFER (w->buffer), bidi_display_reordering))
17216 && NILP (BVAR (XBUFFER (w->buffer), bidi_paragraph_direction)))
17217 GIVE_UP (22);
17218
17219 /* Make sure beg_unchanged and end_unchanged are up to date. Do it
17220 only if buffer has really changed. The reason is that the gap is
17221 initially at Z for freshly visited files. The code below would
17222 set end_unchanged to 0 in that case. */
17223 if (MODIFF > SAVE_MODIFF
17224 /* This seems to happen sometimes after saving a buffer. */
17225 || BEG_UNCHANGED + END_UNCHANGED > Z_BYTE)
17226 {
17227 if (GPT - BEG < BEG_UNCHANGED)
17228 BEG_UNCHANGED = GPT - BEG;
17229 if (Z - GPT < END_UNCHANGED)
17230 END_UNCHANGED = Z - GPT;
17231 }
17232
17233 /* The position of the first and last character that has been changed. */
17234 first_changed_charpos = BEG + BEG_UNCHANGED;
17235 last_changed_charpos = Z - END_UNCHANGED;
17236
17237 /* If window starts after a line end, and the last change is in
17238 front of that newline, then changes don't affect the display.
17239 This case happens with stealth-fontification. Note that although
17240 the display is unchanged, glyph positions in the matrix have to
17241 be adjusted, of course. */
17242 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
17243 if (MATRIX_ROW_DISPLAYS_TEXT_P (row)
17244 && ((last_changed_charpos < CHARPOS (start)
17245 && CHARPOS (start) == BEGV)
17246 || (last_changed_charpos < CHARPOS (start) - 1
17247 && FETCH_BYTE (BYTEPOS (start) - 1) == '\n')))
17248 {
17249 ptrdiff_t Z_old, Z_delta, Z_BYTE_old, Z_delta_bytes;
17250 struct glyph_row *r0;
17251
17252 /* Compute how many chars/bytes have been added to or removed
17253 from the buffer. */
17254 Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
17255 Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
17256 Z_delta = Z - Z_old;
17257 Z_delta_bytes = Z_BYTE - Z_BYTE_old;
17258
17259 /* Give up if PT is not in the window. Note that it already has
17260 been checked at the start of try_window_id that PT is not in
17261 front of the window start. */
17262 if (PT >= MATRIX_ROW_END_CHARPOS (row) + Z_delta)
17263 GIVE_UP (13);
17264
17265 /* If window start is unchanged, we can reuse the whole matrix
17266 as is, after adjusting glyph positions. No need to compute
17267 the window end again, since its offset from Z hasn't changed. */
17268 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
17269 if (CHARPOS (start) == MATRIX_ROW_START_CHARPOS (r0) + Z_delta
17270 && BYTEPOS (start) == MATRIX_ROW_START_BYTEPOS (r0) + Z_delta_bytes
17271 /* PT must not be in a partially visible line. */
17272 && !(PT >= MATRIX_ROW_START_CHARPOS (row) + Z_delta
17273 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
17274 {
17275 /* Adjust positions in the glyph matrix. */
17276 if (Z_delta || Z_delta_bytes)
17277 {
17278 struct glyph_row *r1
17279 = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
17280 increment_matrix_positions (w->current_matrix,
17281 MATRIX_ROW_VPOS (r0, current_matrix),
17282 MATRIX_ROW_VPOS (r1, current_matrix),
17283 Z_delta, Z_delta_bytes);
17284 }
17285
17286 /* Set the cursor. */
17287 row = row_containing_pos (w, PT, r0, NULL, 0);
17288 if (row)
17289 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
17290 else
17291 abort ();
17292 return 1;
17293 }
17294 }
17295
17296 /* Handle the case that changes are all below what is displayed in
17297 the window, and that PT is in the window. This shortcut cannot
17298 be taken if ZV is visible in the window, and text has been added
17299 there that is visible in the window. */
17300 if (first_changed_charpos >= MATRIX_ROW_END_CHARPOS (row)
17301 /* ZV is not visible in the window, or there are no
17302 changes at ZV, actually. */
17303 && (current_matrix->zv > MATRIX_ROW_END_CHARPOS (row)
17304 || first_changed_charpos == last_changed_charpos))
17305 {
17306 struct glyph_row *r0;
17307
17308 /* Give up if PT is not in the window. Note that it already has
17309 been checked at the start of try_window_id that PT is not in
17310 front of the window start. */
17311 if (PT >= MATRIX_ROW_END_CHARPOS (row))
17312 GIVE_UP (14);
17313
17314 /* If window start is unchanged, we can reuse the whole matrix
17315 as is, without changing glyph positions since no text has
17316 been added/removed in front of the window end. */
17317 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
17318 if (TEXT_POS_EQUAL_P (start, r0->minpos)
17319 /* PT must not be in a partially visible line. */
17320 && !(PT >= MATRIX_ROW_START_CHARPOS (row)
17321 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
17322 {
17323 /* We have to compute the window end anew since text
17324 could have been added/removed after it. */
17325 w->window_end_pos
17326 = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
17327 w->window_end_bytepos
17328 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
17329
17330 /* Set the cursor. */
17331 row = row_containing_pos (w, PT, r0, NULL, 0);
17332 if (row)
17333 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
17334 else
17335 abort ();
17336 return 2;
17337 }
17338 }
17339
17340 /* Give up if window start is in the changed area.
17341
17342 The condition used to read
17343
17344 (BEG_UNCHANGED + END_UNCHANGED != Z - BEG && ...)
17345
17346 but why that was tested escapes me at the moment. */
17347 if (CHARPOS (start) >= first_changed_charpos
17348 && CHARPOS (start) <= last_changed_charpos)
17349 GIVE_UP (15);
17350
17351 /* Check that window start agrees with the start of the first glyph
17352 row in its current matrix. Check this after we know the window
17353 start is not in changed text, otherwise positions would not be
17354 comparable. */
17355 row = MATRIX_FIRST_TEXT_ROW (current_matrix);
17356 if (!TEXT_POS_EQUAL_P (start, row->minpos))
17357 GIVE_UP (16);
17358
17359 /* Give up if the window ends in strings. Overlay strings
17360 at the end are difficult to handle, so don't try. */
17361 row = MATRIX_ROW (current_matrix, XFASTINT (w->window_end_vpos));
17362 if (MATRIX_ROW_START_CHARPOS (row) == MATRIX_ROW_END_CHARPOS (row))
17363 GIVE_UP (20);
17364
17365 /* Compute the position at which we have to start displaying new
17366 lines. Some of the lines at the top of the window might be
17367 reusable because they are not displaying changed text. Find the
17368 last row in W's current matrix not affected by changes at the
17369 start of current_buffer. Value is null if changes start in the
17370 first line of window. */
17371 last_unchanged_at_beg_row = find_last_unchanged_at_beg_row (w);
17372 if (last_unchanged_at_beg_row)
17373 {
17374 /* Avoid starting to display in the middle of a character, a TAB
17375 for instance. This is easier than to set up the iterator
17376 exactly, and it's not a frequent case, so the additional
17377 effort wouldn't really pay off. */
17378 while ((MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row)
17379 || last_unchanged_at_beg_row->ends_in_newline_from_string_p)
17380 && last_unchanged_at_beg_row > w->current_matrix->rows)
17381 --last_unchanged_at_beg_row;
17382
17383 if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row))
17384 GIVE_UP (17);
17385
17386 if (init_to_row_end (&it, w, last_unchanged_at_beg_row) == 0)
17387 GIVE_UP (18);
17388 start_pos = it.current.pos;
17389
17390 /* Start displaying new lines in the desired matrix at the same
17391 vpos we would use in the current matrix, i.e. below
17392 last_unchanged_at_beg_row. */
17393 it.vpos = 1 + MATRIX_ROW_VPOS (last_unchanged_at_beg_row,
17394 current_matrix);
17395 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
17396 it.current_y = MATRIX_ROW_BOTTOM_Y (last_unchanged_at_beg_row);
17397
17398 xassert (it.hpos == 0 && it.current_x == 0);
17399 }
17400 else
17401 {
17402 /* There are no reusable lines at the start of the window.
17403 Start displaying in the first text line. */
17404 start_display (&it, w, start);
17405 it.vpos = it.first_vpos;
17406 start_pos = it.current.pos;
17407 }
17408
17409 /* Find the first row that is not affected by changes at the end of
17410 the buffer. Value will be null if there is no unchanged row, in
17411 which case we must redisplay to the end of the window. delta
17412 will be set to the value by which buffer positions beginning with
17413 first_unchanged_at_end_row have to be adjusted due to text
17414 changes. */
17415 first_unchanged_at_end_row
17416 = find_first_unchanged_at_end_row (w, &delta, &delta_bytes);
17417 IF_DEBUG (debug_delta = delta);
17418 IF_DEBUG (debug_delta_bytes = delta_bytes);
17419
17420 /* Set stop_pos to the buffer position up to which we will have to
17421 display new lines. If first_unchanged_at_end_row != NULL, this
17422 is the buffer position of the start of the line displayed in that
17423 row. For first_unchanged_at_end_row == NULL, use 0 to indicate
17424 that we don't stop at a buffer position. */
17425 stop_pos = 0;
17426 if (first_unchanged_at_end_row)
17427 {
17428 xassert (last_unchanged_at_beg_row == NULL
17429 || first_unchanged_at_end_row >= last_unchanged_at_beg_row);
17430
17431 /* If this is a continuation line, move forward to the next one
17432 that isn't. Changes in lines above affect this line.
17433 Caution: this may move first_unchanged_at_end_row to a row
17434 not displaying text. */
17435 while (MATRIX_ROW_CONTINUATION_LINE_P (first_unchanged_at_end_row)
17436 && MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
17437 && (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
17438 < it.last_visible_y))
17439 ++first_unchanged_at_end_row;
17440
17441 if (!MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
17442 || (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
17443 >= it.last_visible_y))
17444 first_unchanged_at_end_row = NULL;
17445 else
17446 {
17447 stop_pos = (MATRIX_ROW_START_CHARPOS (first_unchanged_at_end_row)
17448 + delta);
17449 first_unchanged_at_end_vpos
17450 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, current_matrix);
17451 xassert (stop_pos >= Z - END_UNCHANGED);
17452 }
17453 }
17454 else if (last_unchanged_at_beg_row == NULL)
17455 GIVE_UP (19);
17456
17457
17458 #if GLYPH_DEBUG
17459
17460 /* Either there is no unchanged row at the end, or the one we have
17461 now displays text. This is a necessary condition for the window
17462 end pos calculation at the end of this function. */
17463 xassert (first_unchanged_at_end_row == NULL
17464 || MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
17465
17466 debug_last_unchanged_at_beg_vpos
17467 = (last_unchanged_at_beg_row
17468 ? MATRIX_ROW_VPOS (last_unchanged_at_beg_row, current_matrix)
17469 : -1);
17470 debug_first_unchanged_at_end_vpos = first_unchanged_at_end_vpos;
17471
17472 #endif /* GLYPH_DEBUG != 0 */
17473
17474
17475 /* Display new lines. Set last_text_row to the last new line
17476 displayed which has text on it, i.e. might end up as being the
17477 line where the window_end_vpos is. */
17478 w->cursor.vpos = -1;
17479 last_text_row = NULL;
17480 overlay_arrow_seen = 0;
17481 while (it.current_y < it.last_visible_y
17482 && !fonts_changed_p
17483 && (first_unchanged_at_end_row == NULL
17484 || IT_CHARPOS (it) < stop_pos))
17485 {
17486 if (display_line (&it))
17487 last_text_row = it.glyph_row - 1;
17488 }
17489
17490 if (fonts_changed_p)
17491 return -1;
17492
17493
17494 /* Compute differences in buffer positions, y-positions etc. for
17495 lines reused at the bottom of the window. Compute what we can
17496 scroll. */
17497 if (first_unchanged_at_end_row
17498 /* No lines reused because we displayed everything up to the
17499 bottom of the window. */
17500 && it.current_y < it.last_visible_y)
17501 {
17502 dvpos = (it.vpos
17503 - MATRIX_ROW_VPOS (first_unchanged_at_end_row,
17504 current_matrix));
17505 dy = it.current_y - first_unchanged_at_end_row->y;
17506 run.current_y = first_unchanged_at_end_row->y;
17507 run.desired_y = run.current_y + dy;
17508 run.height = it.last_visible_y - max (run.current_y, run.desired_y);
17509 }
17510 else
17511 {
17512 delta = delta_bytes = dvpos = dy
17513 = run.current_y = run.desired_y = run.height = 0;
17514 first_unchanged_at_end_row = NULL;
17515 }
17516 IF_DEBUG (debug_dvpos = dvpos; debug_dy = dy);
17517
17518
17519 /* Find the cursor if not already found. We have to decide whether
17520 PT will appear on this window (it sometimes doesn't, but this is
17521 not a very frequent case.) This decision has to be made before
17522 the current matrix is altered. A value of cursor.vpos < 0 means
17523 that PT is either in one of the lines beginning at
17524 first_unchanged_at_end_row or below the window. Don't care for
17525 lines that might be displayed later at the window end; as
17526 mentioned, this is not a frequent case. */
17527 if (w->cursor.vpos < 0)
17528 {
17529 /* Cursor in unchanged rows at the top? */
17530 if (PT < CHARPOS (start_pos)
17531 && last_unchanged_at_beg_row)
17532 {
17533 row = row_containing_pos (w, PT,
17534 MATRIX_FIRST_TEXT_ROW (w->current_matrix),
17535 last_unchanged_at_beg_row + 1, 0);
17536 if (row)
17537 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
17538 }
17539
17540 /* Start from first_unchanged_at_end_row looking for PT. */
17541 else if (first_unchanged_at_end_row)
17542 {
17543 row = row_containing_pos (w, PT - delta,
17544 first_unchanged_at_end_row, NULL, 0);
17545 if (row)
17546 set_cursor_from_row (w, row, w->current_matrix, delta,
17547 delta_bytes, dy, dvpos);
17548 }
17549
17550 /* Give up if cursor was not found. */
17551 if (w->cursor.vpos < 0)
17552 {
17553 clear_glyph_matrix (w->desired_matrix);
17554 return -1;
17555 }
17556 }
17557
17558 /* Don't let the cursor end in the scroll margins. */
17559 {
17560 int this_scroll_margin, cursor_height;
17561
17562 this_scroll_margin =
17563 max (0, min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4));
17564 this_scroll_margin *= FRAME_LINE_HEIGHT (it.f);
17565 cursor_height = MATRIX_ROW (w->desired_matrix, w->cursor.vpos)->height;
17566
17567 if ((w->cursor.y < this_scroll_margin
17568 && CHARPOS (start) > BEGV)
17569 /* Old redisplay didn't take scroll margin into account at the bottom,
17570 but then global-hl-line-mode doesn't scroll. KFS 2004-06-14 */
17571 || (w->cursor.y + (make_cursor_line_fully_visible_p
17572 ? cursor_height + this_scroll_margin
17573 : 1)) > it.last_visible_y)
17574 {
17575 w->cursor.vpos = -1;
17576 clear_glyph_matrix (w->desired_matrix);
17577 return -1;
17578 }
17579 }
17580
17581 /* Scroll the display. Do it before changing the current matrix so
17582 that xterm.c doesn't get confused about where the cursor glyph is
17583 found. */
17584 if (dy && run.height)
17585 {
17586 update_begin (f);
17587
17588 if (FRAME_WINDOW_P (f))
17589 {
17590 FRAME_RIF (f)->update_window_begin_hook (w);
17591 FRAME_RIF (f)->clear_window_mouse_face (w);
17592 FRAME_RIF (f)->scroll_run_hook (w, &run);
17593 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
17594 }
17595 else
17596 {
17597 /* Terminal frame. In this case, dvpos gives the number of
17598 lines to scroll by; dvpos < 0 means scroll up. */
17599 int from_vpos
17600 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, w->current_matrix);
17601 int from = WINDOW_TOP_EDGE_LINE (w) + from_vpos;
17602 int end = (WINDOW_TOP_EDGE_LINE (w)
17603 + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0)
17604 + window_internal_height (w));
17605
17606 #if defined (HAVE_GPM) || defined (MSDOS)
17607 x_clear_window_mouse_face (w);
17608 #endif
17609 /* Perform the operation on the screen. */
17610 if (dvpos > 0)
17611 {
17612 /* Scroll last_unchanged_at_beg_row to the end of the
17613 window down dvpos lines. */
17614 set_terminal_window (f, end);
17615
17616 /* On dumb terminals delete dvpos lines at the end
17617 before inserting dvpos empty lines. */
17618 if (!FRAME_SCROLL_REGION_OK (f))
17619 ins_del_lines (f, end - dvpos, -dvpos);
17620
17621 /* Insert dvpos empty lines in front of
17622 last_unchanged_at_beg_row. */
17623 ins_del_lines (f, from, dvpos);
17624 }
17625 else if (dvpos < 0)
17626 {
17627 /* Scroll up last_unchanged_at_beg_vpos to the end of
17628 the window to last_unchanged_at_beg_vpos - |dvpos|. */
17629 set_terminal_window (f, end);
17630
17631 /* Delete dvpos lines in front of
17632 last_unchanged_at_beg_vpos. ins_del_lines will set
17633 the cursor to the given vpos and emit |dvpos| delete
17634 line sequences. */
17635 ins_del_lines (f, from + dvpos, dvpos);
17636
17637 /* On a dumb terminal insert dvpos empty lines at the
17638 end. */
17639 if (!FRAME_SCROLL_REGION_OK (f))
17640 ins_del_lines (f, end + dvpos, -dvpos);
17641 }
17642
17643 set_terminal_window (f, 0);
17644 }
17645
17646 update_end (f);
17647 }
17648
17649 /* Shift reused rows of the current matrix to the right position.
17650 BOTTOM_ROW is the last + 1 row in the current matrix reserved for
17651 text. */
17652 bottom_row = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
17653 bottom_vpos = MATRIX_ROW_VPOS (bottom_row, current_matrix);
17654 if (dvpos < 0)
17655 {
17656 rotate_matrix (current_matrix, first_unchanged_at_end_vpos + dvpos,
17657 bottom_vpos, dvpos);
17658 enable_glyph_matrix_rows (current_matrix, bottom_vpos + dvpos,
17659 bottom_vpos, 0);
17660 }
17661 else if (dvpos > 0)
17662 {
17663 rotate_matrix (current_matrix, first_unchanged_at_end_vpos,
17664 bottom_vpos, dvpos);
17665 enable_glyph_matrix_rows (current_matrix, first_unchanged_at_end_vpos,
17666 first_unchanged_at_end_vpos + dvpos, 0);
17667 }
17668
17669 /* For frame-based redisplay, make sure that current frame and window
17670 matrix are in sync with respect to glyph memory. */
17671 if (!FRAME_WINDOW_P (f))
17672 sync_frame_with_window_matrix_rows (w);
17673
17674 /* Adjust buffer positions in reused rows. */
17675 if (delta || delta_bytes)
17676 increment_matrix_positions (current_matrix,
17677 first_unchanged_at_end_vpos + dvpos,
17678 bottom_vpos, delta, delta_bytes);
17679
17680 /* Adjust Y positions. */
17681 if (dy)
17682 shift_glyph_matrix (w, current_matrix,
17683 first_unchanged_at_end_vpos + dvpos,
17684 bottom_vpos, dy);
17685
17686 if (first_unchanged_at_end_row)
17687 {
17688 first_unchanged_at_end_row += dvpos;
17689 if (first_unchanged_at_end_row->y >= it.last_visible_y
17690 || !MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row))
17691 first_unchanged_at_end_row = NULL;
17692 }
17693
17694 /* If scrolling up, there may be some lines to display at the end of
17695 the window. */
17696 last_text_row_at_end = NULL;
17697 if (dy < 0)
17698 {
17699 /* Scrolling up can leave for example a partially visible line
17700 at the end of the window to be redisplayed. */
17701 /* Set last_row to the glyph row in the current matrix where the
17702 window end line is found. It has been moved up or down in
17703 the matrix by dvpos. */
17704 int last_vpos = XFASTINT (w->window_end_vpos) + dvpos;
17705 struct glyph_row *last_row = MATRIX_ROW (current_matrix, last_vpos);
17706
17707 /* If last_row is the window end line, it should display text. */
17708 xassert (last_row->displays_text_p);
17709
17710 /* If window end line was partially visible before, begin
17711 displaying at that line. Otherwise begin displaying with the
17712 line following it. */
17713 if (MATRIX_ROW_BOTTOM_Y (last_row) - dy >= it.last_visible_y)
17714 {
17715 init_to_row_start (&it, w, last_row);
17716 it.vpos = last_vpos;
17717 it.current_y = last_row->y;
17718 }
17719 else
17720 {
17721 init_to_row_end (&it, w, last_row);
17722 it.vpos = 1 + last_vpos;
17723 it.current_y = MATRIX_ROW_BOTTOM_Y (last_row);
17724 ++last_row;
17725 }
17726
17727 /* We may start in a continuation line. If so, we have to
17728 get the right continuation_lines_width and current_x. */
17729 it.continuation_lines_width = last_row->continuation_lines_width;
17730 it.hpos = it.current_x = 0;
17731
17732 /* Display the rest of the lines at the window end. */
17733 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
17734 while (it.current_y < it.last_visible_y
17735 && !fonts_changed_p)
17736 {
17737 /* Is it always sure that the display agrees with lines in
17738 the current matrix? I don't think so, so we mark rows
17739 displayed invalid in the current matrix by setting their
17740 enabled_p flag to zero. */
17741 MATRIX_ROW (w->current_matrix, it.vpos)->enabled_p = 0;
17742 if (display_line (&it))
17743 last_text_row_at_end = it.glyph_row - 1;
17744 }
17745 }
17746
17747 /* Update window_end_pos and window_end_vpos. */
17748 if (first_unchanged_at_end_row
17749 && !last_text_row_at_end)
17750 {
17751 /* Window end line if one of the preserved rows from the current
17752 matrix. Set row to the last row displaying text in current
17753 matrix starting at first_unchanged_at_end_row, after
17754 scrolling. */
17755 xassert (first_unchanged_at_end_row->displays_text_p);
17756 row = find_last_row_displaying_text (w->current_matrix, &it,
17757 first_unchanged_at_end_row);
17758 xassert (row && MATRIX_ROW_DISPLAYS_TEXT_P (row));
17759
17760 w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
17761 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
17762 w->window_end_vpos
17763 = make_number (MATRIX_ROW_VPOS (row, w->current_matrix));
17764 xassert (w->window_end_bytepos >= 0);
17765 IF_DEBUG (debug_method_add (w, "A"));
17766 }
17767 else if (last_text_row_at_end)
17768 {
17769 w->window_end_pos
17770 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row_at_end));
17771 w->window_end_bytepos
17772 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row_at_end);
17773 w->window_end_vpos
17774 = make_number (MATRIX_ROW_VPOS (last_text_row_at_end, desired_matrix));
17775 xassert (w->window_end_bytepos >= 0);
17776 IF_DEBUG (debug_method_add (w, "B"));
17777 }
17778 else if (last_text_row)
17779 {
17780 /* We have displayed either to the end of the window or at the
17781 end of the window, i.e. the last row with text is to be found
17782 in the desired matrix. */
17783 w->window_end_pos
17784 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
17785 w->window_end_bytepos
17786 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
17787 w->window_end_vpos
17788 = make_number (MATRIX_ROW_VPOS (last_text_row, desired_matrix));
17789 xassert (w->window_end_bytepos >= 0);
17790 }
17791 else if (first_unchanged_at_end_row == NULL
17792 && last_text_row == NULL
17793 && last_text_row_at_end == NULL)
17794 {
17795 /* Displayed to end of window, but no line containing text was
17796 displayed. Lines were deleted at the end of the window. */
17797 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
17798 int vpos = XFASTINT (w->window_end_vpos);
17799 struct glyph_row *current_row = current_matrix->rows + vpos;
17800 struct glyph_row *desired_row = desired_matrix->rows + vpos;
17801
17802 for (row = NULL;
17803 row == NULL && vpos >= first_vpos;
17804 --vpos, --current_row, --desired_row)
17805 {
17806 if (desired_row->enabled_p)
17807 {
17808 if (desired_row->displays_text_p)
17809 row = desired_row;
17810 }
17811 else if (current_row->displays_text_p)
17812 row = current_row;
17813 }
17814
17815 xassert (row != NULL);
17816 w->window_end_vpos = make_number (vpos + 1);
17817 w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
17818 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
17819 xassert (w->window_end_bytepos >= 0);
17820 IF_DEBUG (debug_method_add (w, "C"));
17821 }
17822 else
17823 abort ();
17824
17825 IF_DEBUG (debug_end_pos = XFASTINT (w->window_end_pos);
17826 debug_end_vpos = XFASTINT (w->window_end_vpos));
17827
17828 /* Record that display has not been completed. */
17829 w->window_end_valid = Qnil;
17830 w->desired_matrix->no_scrolling_p = 1;
17831 return 3;
17832
17833 #undef GIVE_UP
17834 }
17835
17836
17837 \f
17838 /***********************************************************************
17839 More debugging support
17840 ***********************************************************************/
17841
17842 #if GLYPH_DEBUG
17843
17844 void dump_glyph_row (struct glyph_row *, int, int) EXTERNALLY_VISIBLE;
17845 void dump_glyph_matrix (struct glyph_matrix *, int) EXTERNALLY_VISIBLE;
17846 void dump_glyph (struct glyph_row *, struct glyph *, int) EXTERNALLY_VISIBLE;
17847
17848
17849 /* Dump the contents of glyph matrix MATRIX on stderr.
17850
17851 GLYPHS 0 means don't show glyph contents.
17852 GLYPHS 1 means show glyphs in short form
17853 GLYPHS > 1 means show glyphs in long form. */
17854
17855 void
17856 dump_glyph_matrix (struct glyph_matrix *matrix, int glyphs)
17857 {
17858 int i;
17859 for (i = 0; i < matrix->nrows; ++i)
17860 dump_glyph_row (MATRIX_ROW (matrix, i), i, glyphs);
17861 }
17862
17863
17864 /* Dump contents of glyph GLYPH to stderr. ROW and AREA are
17865 the glyph row and area where the glyph comes from. */
17866
17867 void
17868 dump_glyph (struct glyph_row *row, struct glyph *glyph, int area)
17869 {
17870 if (glyph->type == CHAR_GLYPH)
17871 {
17872 fprintf (stderr,
17873 " %5td %4c %6"pI"d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
17874 glyph - row->glyphs[TEXT_AREA],
17875 'C',
17876 glyph->charpos,
17877 (BUFFERP (glyph->object)
17878 ? 'B'
17879 : (STRINGP (glyph->object)
17880 ? 'S'
17881 : '-')),
17882 glyph->pixel_width,
17883 glyph->u.ch,
17884 (glyph->u.ch < 0x80 && glyph->u.ch >= ' '
17885 ? glyph->u.ch
17886 : '.'),
17887 glyph->face_id,
17888 glyph->left_box_line_p,
17889 glyph->right_box_line_p);
17890 }
17891 else if (glyph->type == STRETCH_GLYPH)
17892 {
17893 fprintf (stderr,
17894 " %5td %4c %6"pI"d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
17895 glyph - row->glyphs[TEXT_AREA],
17896 'S',
17897 glyph->charpos,
17898 (BUFFERP (glyph->object)
17899 ? 'B'
17900 : (STRINGP (glyph->object)
17901 ? 'S'
17902 : '-')),
17903 glyph->pixel_width,
17904 0,
17905 '.',
17906 glyph->face_id,
17907 glyph->left_box_line_p,
17908 glyph->right_box_line_p);
17909 }
17910 else if (glyph->type == IMAGE_GLYPH)
17911 {
17912 fprintf (stderr,
17913 " %5td %4c %6"pI"d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
17914 glyph - row->glyphs[TEXT_AREA],
17915 'I',
17916 glyph->charpos,
17917 (BUFFERP (glyph->object)
17918 ? 'B'
17919 : (STRINGP (glyph->object)
17920 ? 'S'
17921 : '-')),
17922 glyph->pixel_width,
17923 glyph->u.img_id,
17924 '.',
17925 glyph->face_id,
17926 glyph->left_box_line_p,
17927 glyph->right_box_line_p);
17928 }
17929 else if (glyph->type == COMPOSITE_GLYPH)
17930 {
17931 fprintf (stderr,
17932 " %5td %4c %6"pI"d %c %3d 0x%05x",
17933 glyph - row->glyphs[TEXT_AREA],
17934 '+',
17935 glyph->charpos,
17936 (BUFFERP (glyph->object)
17937 ? 'B'
17938 : (STRINGP (glyph->object)
17939 ? 'S'
17940 : '-')),
17941 glyph->pixel_width,
17942 glyph->u.cmp.id);
17943 if (glyph->u.cmp.automatic)
17944 fprintf (stderr,
17945 "[%d-%d]",
17946 glyph->slice.cmp.from, glyph->slice.cmp.to);
17947 fprintf (stderr, " . %4d %1.1d%1.1d\n",
17948 glyph->face_id,
17949 glyph->left_box_line_p,
17950 glyph->right_box_line_p);
17951 }
17952 #ifdef HAVE_XWIDGETS
17953 else if (glyph->type == XWIDGET_GLYPH)
17954 {
17955 fprintf (stderr,
17956 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
17957 glyph - row->glyphs[TEXT_AREA],
17958 'X',
17959 glyph->charpos,
17960 (BUFFERP (glyph->object)
17961 ? 'B'
17962 : (STRINGP (glyph->object)
17963 ? 'S'
17964 : '-')),
17965 glyph->pixel_width,
17966 glyph->u.xwidget,
17967 '.',
17968 glyph->face_id,
17969 glyph->left_box_line_p,
17970 glyph->right_box_line_p);
17971
17972 // printf("dump xwidget glyph\n");
17973 }
17974 #endif
17975 }
17976
17977
17978 /* Dump the contents of glyph row at VPOS in MATRIX to stderr.
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_row (struct glyph_row *row, int vpos, int glyphs)
17985 {
17986 if (glyphs != 1)
17987 {
17988 fprintf (stderr, "Row Start End Used oE><\\CTZFesm X Y W H V A P\n");
17989 fprintf (stderr, "======================================================================\n");
17990
17991 fprintf (stderr, "%3d %5"pI"d %5"pI"d %4d %1.1d%1.1d%1.1d%1.1d\
17992 %1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d %4d %4d %4d %4d %4d %4d %4d\n",
17993 vpos,
17994 MATRIX_ROW_START_CHARPOS (row),
17995 MATRIX_ROW_END_CHARPOS (row),
17996 row->used[TEXT_AREA],
17997 row->contains_overlapping_glyphs_p,
17998 row->enabled_p,
17999 row->truncated_on_left_p,
18000 row->truncated_on_right_p,
18001 row->continued_p,
18002 MATRIX_ROW_CONTINUATION_LINE_P (row),
18003 row->displays_text_p,
18004 row->ends_at_zv_p,
18005 row->fill_line_p,
18006 row->ends_in_middle_of_char_p,
18007 row->starts_in_middle_of_char_p,
18008 row->mouse_face_p,
18009 row->x,
18010 row->y,
18011 row->pixel_width,
18012 row->height,
18013 row->visible_height,
18014 row->ascent,
18015 row->phys_ascent);
18016 fprintf (stderr, "%9"pD"d %5"pD"d\t%5d\n", row->start.overlay_string_index,
18017 row->end.overlay_string_index,
18018 row->continuation_lines_width);
18019 fprintf (stderr, "%9"pI"d %5"pI"d\n",
18020 CHARPOS (row->start.string_pos),
18021 CHARPOS (row->end.string_pos));
18022 fprintf (stderr, "%9d %5d\n", row->start.dpvec_index,
18023 row->end.dpvec_index);
18024 }
18025
18026 if (glyphs > 1)
18027 {
18028 int area;
18029
18030 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
18031 {
18032 struct glyph *glyph = row->glyphs[area];
18033 struct glyph *glyph_end = glyph + row->used[area];
18034
18035 /* Glyph for a line end in text. */
18036 if (area == TEXT_AREA && glyph == glyph_end && glyph->charpos > 0)
18037 ++glyph_end;
18038
18039 if (glyph < glyph_end)
18040 fprintf (stderr, " Glyph Type Pos O W Code C Face LR\n");
18041
18042 for (; glyph < glyph_end; ++glyph)
18043 dump_glyph (row, glyph, area);
18044 }
18045 }
18046 else if (glyphs == 1)
18047 {
18048 int area;
18049
18050 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
18051 {
18052 char *s = (char *) alloca (row->used[area] + 1);
18053 int i;
18054
18055 for (i = 0; i < row->used[area]; ++i)
18056 {
18057 struct glyph *glyph = row->glyphs[area] + i;
18058 if (glyph->type == CHAR_GLYPH
18059 && glyph->u.ch < 0x80
18060 && glyph->u.ch >= ' ')
18061 s[i] = glyph->u.ch;
18062 else
18063 s[i] = '.';
18064 }
18065
18066 s[i] = '\0';
18067 fprintf (stderr, "%3d: (%d) '%s'\n", vpos, row->enabled_p, s);
18068 }
18069 }
18070 }
18071
18072
18073 DEFUN ("dump-glyph-matrix", Fdump_glyph_matrix,
18074 Sdump_glyph_matrix, 0, 1, "p",
18075 doc: /* Dump the current matrix of the selected window to stderr.
18076 Shows contents of glyph row structures. With non-nil
18077 parameter GLYPHS, dump glyphs as well. If GLYPHS is 1 show
18078 glyphs in short form, otherwise show glyphs in long form. */)
18079 (Lisp_Object glyphs)
18080 {
18081 struct window *w = XWINDOW (selected_window);
18082 struct buffer *buffer = XBUFFER (w->buffer);
18083
18084 fprintf (stderr, "PT = %"pI"d, BEGV = %"pI"d. ZV = %"pI"d\n",
18085 BUF_PT (buffer), BUF_BEGV (buffer), BUF_ZV (buffer));
18086 fprintf (stderr, "Cursor x = %d, y = %d, hpos = %d, vpos = %d\n",
18087 w->cursor.x, w->cursor.y, w->cursor.hpos, w->cursor.vpos);
18088 fprintf (stderr, "=============================================\n");
18089 dump_glyph_matrix (w->current_matrix,
18090 TYPE_RANGED_INTEGERP (int, glyphs) ? XINT (glyphs) : 0);
18091 return Qnil;
18092 }
18093
18094
18095 DEFUN ("dump-frame-glyph-matrix", Fdump_frame_glyph_matrix,
18096 Sdump_frame_glyph_matrix, 0, 0, "", doc: /* */)
18097 (void)
18098 {
18099 struct frame *f = XFRAME (selected_frame);
18100 dump_glyph_matrix (f->current_matrix, 1);
18101 return Qnil;
18102 }
18103
18104
18105 DEFUN ("dump-glyph-row", Fdump_glyph_row, Sdump_glyph_row, 1, 2, "",
18106 doc: /* Dump glyph row ROW to stderr.
18107 GLYPH 0 means don't dump glyphs.
18108 GLYPH 1 means dump glyphs in short form.
18109 GLYPH > 1 or omitted means dump glyphs in long form. */)
18110 (Lisp_Object row, Lisp_Object glyphs)
18111 {
18112 struct glyph_matrix *matrix;
18113 EMACS_INT vpos;
18114
18115 CHECK_NUMBER (row);
18116 matrix = XWINDOW (selected_window)->current_matrix;
18117 vpos = XINT (row);
18118 if (vpos >= 0 && vpos < matrix->nrows)
18119 dump_glyph_row (MATRIX_ROW (matrix, vpos),
18120 vpos,
18121 TYPE_RANGED_INTEGERP (int, glyphs) ? XINT (glyphs) : 2);
18122 return Qnil;
18123 }
18124
18125
18126 DEFUN ("dump-tool-bar-row", Fdump_tool_bar_row, Sdump_tool_bar_row, 1, 2, "",
18127 doc: /* Dump glyph row ROW of the tool-bar of the current frame to stderr.
18128 GLYPH 0 means don't dump glyphs.
18129 GLYPH 1 means dump glyphs in short form.
18130 GLYPH > 1 or omitted means dump glyphs in long form. */)
18131 (Lisp_Object row, Lisp_Object glyphs)
18132 {
18133 struct frame *sf = SELECTED_FRAME ();
18134 struct glyph_matrix *m = XWINDOW (sf->tool_bar_window)->current_matrix;
18135 EMACS_INT vpos;
18136
18137 CHECK_NUMBER (row);
18138 vpos = XINT (row);
18139 if (vpos >= 0 && vpos < m->nrows)
18140 dump_glyph_row (MATRIX_ROW (m, vpos), vpos,
18141 TYPE_RANGED_INTEGERP (int, glyphs) ? XINT (glyphs) : 2);
18142 return Qnil;
18143 }
18144
18145
18146 DEFUN ("trace-redisplay", Ftrace_redisplay, Strace_redisplay, 0, 1, "P",
18147 doc: /* Toggle tracing of redisplay.
18148 With ARG, turn tracing on if and only if ARG is positive. */)
18149 (Lisp_Object arg)
18150 {
18151 if (NILP (arg))
18152 trace_redisplay_p = !trace_redisplay_p;
18153 else
18154 {
18155 arg = Fprefix_numeric_value (arg);
18156 trace_redisplay_p = XINT (arg) > 0;
18157 }
18158
18159 return Qnil;
18160 }
18161
18162
18163 DEFUN ("trace-to-stderr", Ftrace_to_stderr, Strace_to_stderr, 1, MANY, "",
18164 doc: /* Like `format', but print result to stderr.
18165 usage: (trace-to-stderr STRING &rest OBJECTS) */)
18166 (ptrdiff_t nargs, Lisp_Object *args)
18167 {
18168 Lisp_Object s = Fformat (nargs, args);
18169 fprintf (stderr, "%s", SDATA (s));
18170 return Qnil;
18171 }
18172
18173 #endif /* GLYPH_DEBUG */
18174
18175
18176 \f
18177 /***********************************************************************
18178 Building Desired Matrix Rows
18179 ***********************************************************************/
18180
18181 /* Return a temporary glyph row holding the glyphs of an overlay arrow.
18182 Used for non-window-redisplay windows, and for windows w/o left fringe. */
18183
18184 static struct glyph_row *
18185 get_overlay_arrow_glyph_row (struct window *w, Lisp_Object overlay_arrow_string)
18186 {
18187 struct frame *f = XFRAME (WINDOW_FRAME (w));
18188 struct buffer *buffer = XBUFFER (w->buffer);
18189 struct buffer *old = current_buffer;
18190 const unsigned char *arrow_string = SDATA (overlay_arrow_string);
18191 int arrow_len = SCHARS (overlay_arrow_string);
18192 const unsigned char *arrow_end = arrow_string + arrow_len;
18193 const unsigned char *p;
18194 struct it it;
18195 int multibyte_p;
18196 int n_glyphs_before;
18197
18198 set_buffer_temp (buffer);
18199 init_iterator (&it, w, -1, -1, &scratch_glyph_row, DEFAULT_FACE_ID);
18200 it.glyph_row->used[TEXT_AREA] = 0;
18201 SET_TEXT_POS (it.position, 0, 0);
18202
18203 multibyte_p = !NILP (BVAR (buffer, enable_multibyte_characters));
18204 p = arrow_string;
18205 while (p < arrow_end)
18206 {
18207 Lisp_Object face, ilisp;
18208
18209 /* Get the next character. */
18210 if (multibyte_p)
18211 it.c = it.char_to_display = string_char_and_length (p, &it.len);
18212 else
18213 {
18214 it.c = it.char_to_display = *p, it.len = 1;
18215 if (! ASCII_CHAR_P (it.c))
18216 it.char_to_display = BYTE8_TO_CHAR (it.c);
18217 }
18218 p += it.len;
18219
18220 /* Get its face. */
18221 ilisp = make_number (p - arrow_string);
18222 face = Fget_text_property (ilisp, Qface, overlay_arrow_string);
18223 it.face_id = compute_char_face (f, it.char_to_display, face);
18224
18225 /* Compute its width, get its glyphs. */
18226 n_glyphs_before = it.glyph_row->used[TEXT_AREA];
18227 SET_TEXT_POS (it.position, -1, -1);
18228 PRODUCE_GLYPHS (&it);
18229
18230 /* If this character doesn't fit any more in the line, we have
18231 to remove some glyphs. */
18232 if (it.current_x > it.last_visible_x)
18233 {
18234 it.glyph_row->used[TEXT_AREA] = n_glyphs_before;
18235 break;
18236 }
18237 }
18238
18239 set_buffer_temp (old);
18240 return it.glyph_row;
18241 }
18242
18243
18244 /* Insert truncation glyphs at the start of IT->glyph_row. Truncation
18245 glyphs are only inserted for terminal frames since we can't really
18246 win with truncation glyphs when partially visible glyphs are
18247 involved. Which glyphs to insert is determined by
18248 produce_special_glyphs. */
18249
18250 static void
18251 insert_left_trunc_glyphs (struct it *it)
18252 {
18253 struct it truncate_it;
18254 struct glyph *from, *end, *to, *toend;
18255
18256 xassert (!FRAME_WINDOW_P (it->f));
18257
18258 /* Get the truncation glyphs. */
18259 truncate_it = *it;
18260 truncate_it.current_x = 0;
18261 truncate_it.face_id = DEFAULT_FACE_ID;
18262 truncate_it.glyph_row = &scratch_glyph_row;
18263 truncate_it.glyph_row->used[TEXT_AREA] = 0;
18264 CHARPOS (truncate_it.position) = BYTEPOS (truncate_it.position) = -1;
18265 truncate_it.object = make_number (0);
18266 produce_special_glyphs (&truncate_it, IT_TRUNCATION);
18267
18268 /* Overwrite glyphs from IT with truncation glyphs. */
18269 if (!it->glyph_row->reversed_p)
18270 {
18271 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
18272 end = from + truncate_it.glyph_row->used[TEXT_AREA];
18273 to = it->glyph_row->glyphs[TEXT_AREA];
18274 toend = to + it->glyph_row->used[TEXT_AREA];
18275
18276 while (from < end)
18277 *to++ = *from++;
18278
18279 /* There may be padding glyphs left over. Overwrite them too. */
18280 while (to < toend && CHAR_GLYPH_PADDING_P (*to))
18281 {
18282 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
18283 while (from < end)
18284 *to++ = *from++;
18285 }
18286
18287 if (to > toend)
18288 it->glyph_row->used[TEXT_AREA] = to - it->glyph_row->glyphs[TEXT_AREA];
18289 }
18290 else
18291 {
18292 /* In R2L rows, overwrite the last (rightmost) glyphs, and do
18293 that back to front. */
18294 end = truncate_it.glyph_row->glyphs[TEXT_AREA];
18295 from = end + truncate_it.glyph_row->used[TEXT_AREA] - 1;
18296 toend = it->glyph_row->glyphs[TEXT_AREA];
18297 to = toend + it->glyph_row->used[TEXT_AREA] - 1;
18298
18299 while (from >= end && to >= toend)
18300 *to-- = *from--;
18301 while (to >= toend && CHAR_GLYPH_PADDING_P (*to))
18302 {
18303 from =
18304 truncate_it.glyph_row->glyphs[TEXT_AREA]
18305 + truncate_it.glyph_row->used[TEXT_AREA] - 1;
18306 while (from >= end && to >= toend)
18307 *to-- = *from--;
18308 }
18309 if (from >= end)
18310 {
18311 /* Need to free some room before prepending additional
18312 glyphs. */
18313 int move_by = from - end + 1;
18314 struct glyph *g0 = it->glyph_row->glyphs[TEXT_AREA];
18315 struct glyph *g = g0 + it->glyph_row->used[TEXT_AREA] - 1;
18316
18317 for ( ; g >= g0; g--)
18318 g[move_by] = *g;
18319 while (from >= end)
18320 *to-- = *from--;
18321 it->glyph_row->used[TEXT_AREA] += move_by;
18322 }
18323 }
18324 }
18325
18326 /* Compute the hash code for ROW. */
18327 unsigned
18328 row_hash (struct glyph_row *row)
18329 {
18330 int area, k;
18331 unsigned hashval = 0;
18332
18333 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
18334 for (k = 0; k < row->used[area]; ++k)
18335 hashval = ((((hashval << 4) + (hashval >> 24)) & 0x0fffffff)
18336 + row->glyphs[area][k].u.val
18337 + row->glyphs[area][k].face_id
18338 + row->glyphs[area][k].padding_p
18339 + (row->glyphs[area][k].type << 2));
18340
18341 return hashval;
18342 }
18343
18344 /* Compute the pixel height and width of IT->glyph_row.
18345
18346 Most of the time, ascent and height of a display line will be equal
18347 to the max_ascent and max_height values of the display iterator
18348 structure. This is not the case if
18349
18350 1. We hit ZV without displaying anything. In this case, max_ascent
18351 and max_height will be zero.
18352
18353 2. We have some glyphs that don't contribute to the line height.
18354 (The glyph row flag contributes_to_line_height_p is for future
18355 pixmap extensions).
18356
18357 The first case is easily covered by using default values because in
18358 these cases, the line height does not really matter, except that it
18359 must not be zero. */
18360
18361 static void
18362 compute_line_metrics (struct it *it)
18363 {
18364 struct glyph_row *row = it->glyph_row;
18365
18366 if (FRAME_WINDOW_P (it->f))
18367 {
18368 int i, min_y, max_y;
18369
18370 /* The line may consist of one space only, that was added to
18371 place the cursor on it. If so, the row's height hasn't been
18372 computed yet. */
18373 if (row->height == 0)
18374 {
18375 if (it->max_ascent + it->max_descent == 0)
18376 it->max_descent = it->max_phys_descent = FRAME_LINE_HEIGHT (it->f);
18377 row->ascent = it->max_ascent;
18378 row->height = it->max_ascent + it->max_descent;
18379 row->phys_ascent = it->max_phys_ascent;
18380 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
18381 row->extra_line_spacing = it->max_extra_line_spacing;
18382 }
18383
18384 /* Compute the width of this line. */
18385 row->pixel_width = row->x;
18386 for (i = 0; i < row->used[TEXT_AREA]; ++i)
18387 row->pixel_width += row->glyphs[TEXT_AREA][i].pixel_width;
18388
18389 xassert (row->pixel_width >= 0);
18390 xassert (row->ascent >= 0 && row->height > 0);
18391
18392 row->overlapping_p = (MATRIX_ROW_OVERLAPS_SUCC_P (row)
18393 || MATRIX_ROW_OVERLAPS_PRED_P (row));
18394
18395 /* If first line's physical ascent is larger than its logical
18396 ascent, use the physical ascent, and make the row taller.
18397 This makes accented characters fully visible. */
18398 if (row == MATRIX_FIRST_TEXT_ROW (it->w->desired_matrix)
18399 && row->phys_ascent > row->ascent)
18400 {
18401 row->height += row->phys_ascent - row->ascent;
18402 row->ascent = row->phys_ascent;
18403 }
18404
18405 /* Compute how much of the line is visible. */
18406 row->visible_height = row->height;
18407
18408 min_y = WINDOW_HEADER_LINE_HEIGHT (it->w);
18409 max_y = WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w);
18410
18411 if (row->y < min_y)
18412 row->visible_height -= min_y - row->y;
18413 if (row->y + row->height > max_y)
18414 row->visible_height -= row->y + row->height - max_y;
18415 }
18416 else
18417 {
18418 row->pixel_width = row->used[TEXT_AREA];
18419 if (row->continued_p)
18420 row->pixel_width -= it->continuation_pixel_width;
18421 else if (row->truncated_on_right_p)
18422 row->pixel_width -= it->truncation_pixel_width;
18423 row->ascent = row->phys_ascent = 0;
18424 row->height = row->phys_height = row->visible_height = 1;
18425 row->extra_line_spacing = 0;
18426 }
18427
18428 /* Compute a hash code for this row. */
18429 row->hash = row_hash (row);
18430
18431 it->max_ascent = it->max_descent = 0;
18432 it->max_phys_ascent = it->max_phys_descent = 0;
18433 }
18434
18435
18436 /* Append one space to the glyph row of iterator IT if doing a
18437 window-based redisplay. The space has the same face as
18438 IT->face_id. Value is non-zero if a space was added.
18439
18440 This function is called to make sure that there is always one glyph
18441 at the end of a glyph row that the cursor can be set on under
18442 window-systems. (If there weren't such a glyph we would not know
18443 how wide and tall a box cursor should be displayed).
18444
18445 At the same time this space let's a nicely handle clearing to the
18446 end of the line if the row ends in italic text. */
18447
18448 static int
18449 append_space_for_newline (struct it *it, int default_face_p)
18450 {
18451 if (FRAME_WINDOW_P (it->f))
18452 {
18453 int n = it->glyph_row->used[TEXT_AREA];
18454
18455 if (it->glyph_row->glyphs[TEXT_AREA] + n
18456 < it->glyph_row->glyphs[1 + TEXT_AREA])
18457 {
18458 /* Save some values that must not be changed.
18459 Must save IT->c and IT->len because otherwise
18460 ITERATOR_AT_END_P wouldn't work anymore after
18461 append_space_for_newline has been called. */
18462 enum display_element_type saved_what = it->what;
18463 int saved_c = it->c, saved_len = it->len;
18464 int saved_char_to_display = it->char_to_display;
18465 int saved_x = it->current_x;
18466 int saved_face_id = it->face_id;
18467 struct text_pos saved_pos;
18468 Lisp_Object saved_object;
18469 struct face *face;
18470
18471 saved_object = it->object;
18472 saved_pos = it->position;
18473
18474 it->what = IT_CHARACTER;
18475 memset (&it->position, 0, sizeof it->position);
18476 it->object = make_number (0);
18477 it->c = it->char_to_display = ' ';
18478 it->len = 1;
18479
18480 /* If the default face was remapped, be sure to use the
18481 remapped face for the appended newline. */
18482 if (default_face_p)
18483 it->face_id = lookup_basic_face (it->f, DEFAULT_FACE_ID);
18484 else if (it->face_before_selective_p)
18485 it->face_id = it->saved_face_id;
18486 face = FACE_FROM_ID (it->f, it->face_id);
18487 it->face_id = FACE_FOR_CHAR (it->f, face, 0, -1, Qnil);
18488
18489 PRODUCE_GLYPHS (it);
18490
18491 it->override_ascent = -1;
18492 it->constrain_row_ascent_descent_p = 0;
18493 it->current_x = saved_x;
18494 it->object = saved_object;
18495 it->position = saved_pos;
18496 it->what = saved_what;
18497 it->face_id = saved_face_id;
18498 it->len = saved_len;
18499 it->c = saved_c;
18500 it->char_to_display = saved_char_to_display;
18501 return 1;
18502 }
18503 }
18504
18505 return 0;
18506 }
18507
18508
18509 /* Extend the face of the last glyph in the text area of IT->glyph_row
18510 to the end of the display line. Called from display_line. If the
18511 glyph row is empty, add a space glyph to it so that we know the
18512 face to draw. Set the glyph row flag fill_line_p. If the glyph
18513 row is R2L, prepend a stretch glyph to cover the empty space to the
18514 left of the leftmost glyph. */
18515
18516 static void
18517 extend_face_to_end_of_line (struct it *it)
18518 {
18519 struct face *face, *default_face;
18520 struct frame *f = it->f;
18521
18522 /* If line is already filled, do nothing. Non window-system frames
18523 get a grace of one more ``pixel'' because their characters are
18524 1-``pixel'' wide, so they hit the equality too early. This grace
18525 is needed only for R2L rows that are not continued, to produce
18526 one extra blank where we could display the cursor. */
18527 if (it->current_x >= it->last_visible_x
18528 + (!FRAME_WINDOW_P (f)
18529 && it->glyph_row->reversed_p
18530 && !it->glyph_row->continued_p))
18531 return;
18532
18533 /* The default face, possibly remapped. */
18534 default_face = FACE_FROM_ID (f, lookup_basic_face (f, DEFAULT_FACE_ID));
18535
18536 /* Face extension extends the background and box of IT->face_id
18537 to the end of the line. If the background equals the background
18538 of the frame, we don't have to do anything. */
18539 if (it->face_before_selective_p)
18540 face = FACE_FROM_ID (f, it->saved_face_id);
18541 else
18542 face = FACE_FROM_ID (f, it->face_id);
18543
18544 if (FRAME_WINDOW_P (f)
18545 && it->glyph_row->displays_text_p
18546 && face->box == FACE_NO_BOX
18547 && face->background == FRAME_BACKGROUND_PIXEL (f)
18548 && !face->stipple
18549 && !it->glyph_row->reversed_p)
18550 return;
18551
18552 /* Set the glyph row flag indicating that the face of the last glyph
18553 in the text area has to be drawn to the end of the text area. */
18554 it->glyph_row->fill_line_p = 1;
18555
18556 /* If current character of IT is not ASCII, make sure we have the
18557 ASCII face. This will be automatically undone the next time
18558 get_next_display_element returns a multibyte character. Note
18559 that the character will always be single byte in unibyte
18560 text. */
18561 if (!ASCII_CHAR_P (it->c))
18562 {
18563 it->face_id = FACE_FOR_CHAR (f, face, 0, -1, Qnil);
18564 }
18565
18566 if (FRAME_WINDOW_P (f))
18567 {
18568 /* If the row is empty, add a space with the current face of IT,
18569 so that we know which face to draw. */
18570 if (it->glyph_row->used[TEXT_AREA] == 0)
18571 {
18572 it->glyph_row->glyphs[TEXT_AREA][0] = space_glyph;
18573 it->glyph_row->glyphs[TEXT_AREA][0].face_id = face->id;
18574 it->glyph_row->used[TEXT_AREA] = 1;
18575 }
18576 #ifdef HAVE_WINDOW_SYSTEM
18577 if (it->glyph_row->reversed_p)
18578 {
18579 /* Prepend a stretch glyph to the row, such that the
18580 rightmost glyph will be drawn flushed all the way to the
18581 right margin of the window. The stretch glyph that will
18582 occupy the empty space, if any, to the left of the
18583 glyphs. */
18584 struct font *font = face->font ? face->font : FRAME_FONT (f);
18585 struct glyph *row_start = it->glyph_row->glyphs[TEXT_AREA];
18586 struct glyph *row_end = row_start + it->glyph_row->used[TEXT_AREA];
18587 struct glyph *g;
18588 int row_width, stretch_ascent, stretch_width;
18589 struct text_pos saved_pos;
18590 int saved_face_id, saved_avoid_cursor;
18591
18592 for (row_width = 0, g = row_start; g < row_end; g++)
18593 row_width += g->pixel_width;
18594 stretch_width = window_box_width (it->w, TEXT_AREA) - row_width;
18595 if (stretch_width > 0)
18596 {
18597 stretch_ascent =
18598 (((it->ascent + it->descent)
18599 * FONT_BASE (font)) / FONT_HEIGHT (font));
18600 saved_pos = it->position;
18601 memset (&it->position, 0, sizeof it->position);
18602 saved_avoid_cursor = it->avoid_cursor_p;
18603 it->avoid_cursor_p = 1;
18604 saved_face_id = it->face_id;
18605 /* The last row's stretch glyph should get the default
18606 face, to avoid painting the rest of the window with
18607 the region face, if the region ends at ZV. */
18608 if (it->glyph_row->ends_at_zv_p)
18609 it->face_id = default_face->id;
18610 else
18611 it->face_id = face->id;
18612 append_stretch_glyph (it, make_number (0), stretch_width,
18613 it->ascent + it->descent, stretch_ascent);
18614 it->position = saved_pos;
18615 it->avoid_cursor_p = saved_avoid_cursor;
18616 it->face_id = saved_face_id;
18617 }
18618 }
18619 #endif /* HAVE_WINDOW_SYSTEM */
18620 }
18621 else
18622 {
18623 /* Save some values that must not be changed. */
18624 int saved_x = it->current_x;
18625 struct text_pos saved_pos;
18626 Lisp_Object saved_object;
18627 enum display_element_type saved_what = it->what;
18628 int saved_face_id = it->face_id;
18629
18630 saved_object = it->object;
18631 saved_pos = it->position;
18632
18633 it->what = IT_CHARACTER;
18634 memset (&it->position, 0, sizeof it->position);
18635 it->object = make_number (0);
18636 it->c = it->char_to_display = ' ';
18637 it->len = 1;
18638 /* The last row's blank glyphs should get the default face, to
18639 avoid painting the rest of the window with the region face,
18640 if the region ends at ZV. */
18641 if (it->glyph_row->ends_at_zv_p)
18642 it->face_id = default_face->id;
18643 else
18644 it->face_id = face->id;
18645
18646 PRODUCE_GLYPHS (it);
18647
18648 while (it->current_x <= it->last_visible_x)
18649 PRODUCE_GLYPHS (it);
18650
18651 /* Don't count these blanks really. It would let us insert a left
18652 truncation glyph below and make us set the cursor on them, maybe. */
18653 it->current_x = saved_x;
18654 it->object = saved_object;
18655 it->position = saved_pos;
18656 it->what = saved_what;
18657 it->face_id = saved_face_id;
18658 }
18659 }
18660
18661
18662 /* Value is non-zero if text starting at CHARPOS in current_buffer is
18663 trailing whitespace. */
18664
18665 static int
18666 trailing_whitespace_p (ptrdiff_t charpos)
18667 {
18668 ptrdiff_t bytepos = CHAR_TO_BYTE (charpos);
18669 int c = 0;
18670
18671 while (bytepos < ZV_BYTE
18672 && (c = FETCH_CHAR (bytepos),
18673 c == ' ' || c == '\t'))
18674 ++bytepos;
18675
18676 if (bytepos >= ZV_BYTE || c == '\n' || c == '\r')
18677 {
18678 if (bytepos != PT_BYTE)
18679 return 1;
18680 }
18681 return 0;
18682 }
18683
18684
18685 /* Highlight trailing whitespace, if any, in ROW. */
18686
18687 static void
18688 highlight_trailing_whitespace (struct frame *f, struct glyph_row *row)
18689 {
18690 int used = row->used[TEXT_AREA];
18691
18692 if (used)
18693 {
18694 struct glyph *start = row->glyphs[TEXT_AREA];
18695 struct glyph *glyph = start + used - 1;
18696
18697 if (row->reversed_p)
18698 {
18699 /* Right-to-left rows need to be processed in the opposite
18700 direction, so swap the edge pointers. */
18701 glyph = start;
18702 start = row->glyphs[TEXT_AREA] + used - 1;
18703 }
18704
18705 /* Skip over glyphs inserted to display the cursor at the
18706 end of a line, for extending the face of the last glyph
18707 to the end of the line on terminals, and for truncation
18708 and continuation glyphs. */
18709 if (!row->reversed_p)
18710 {
18711 while (glyph >= start
18712 && glyph->type == CHAR_GLYPH
18713 && INTEGERP (glyph->object))
18714 --glyph;
18715 }
18716 else
18717 {
18718 while (glyph <= start
18719 && glyph->type == CHAR_GLYPH
18720 && INTEGERP (glyph->object))
18721 ++glyph;
18722 }
18723
18724 /* If last glyph is a space or stretch, and it's trailing
18725 whitespace, set the face of all trailing whitespace glyphs in
18726 IT->glyph_row to `trailing-whitespace'. */
18727 if ((row->reversed_p ? glyph <= start : glyph >= start)
18728 && BUFFERP (glyph->object)
18729 && (glyph->type == STRETCH_GLYPH
18730 || (glyph->type == CHAR_GLYPH
18731 && glyph->u.ch == ' '))
18732 && trailing_whitespace_p (glyph->charpos))
18733 {
18734 int face_id = lookup_named_face (f, Qtrailing_whitespace, 0);
18735 if (face_id < 0)
18736 return;
18737
18738 if (!row->reversed_p)
18739 {
18740 while (glyph >= start
18741 && BUFFERP (glyph->object)
18742 && (glyph->type == STRETCH_GLYPH
18743 || (glyph->type == CHAR_GLYPH
18744 && glyph->u.ch == ' ')))
18745 (glyph--)->face_id = face_id;
18746 }
18747 else
18748 {
18749 while (glyph <= start
18750 && BUFFERP (glyph->object)
18751 && (glyph->type == STRETCH_GLYPH
18752 || (glyph->type == CHAR_GLYPH
18753 && glyph->u.ch == ' ')))
18754 (glyph++)->face_id = face_id;
18755 }
18756 }
18757 }
18758 }
18759
18760
18761 /* Value is non-zero if glyph row ROW should be
18762 used to hold the cursor. */
18763
18764 static int
18765 cursor_row_p (struct glyph_row *row)
18766 {
18767 int result = 1;
18768
18769 if (PT == CHARPOS (row->end.pos)
18770 || PT == MATRIX_ROW_END_CHARPOS (row))
18771 {
18772 /* Suppose the row ends on a string.
18773 Unless the row is continued, that means it ends on a newline
18774 in the string. If it's anything other than a display string
18775 (e.g., a before-string from an overlay), we don't want the
18776 cursor there. (This heuristic seems to give the optimal
18777 behavior for the various types of multi-line strings.)
18778 One exception: if the string has `cursor' property on one of
18779 its characters, we _do_ want the cursor there. */
18780 if (CHARPOS (row->end.string_pos) >= 0)
18781 {
18782 if (row->continued_p)
18783 result = 1;
18784 else
18785 {
18786 /* Check for `display' property. */
18787 struct glyph *beg = row->glyphs[TEXT_AREA];
18788 struct glyph *end = beg + row->used[TEXT_AREA] - 1;
18789 struct glyph *glyph;
18790
18791 result = 0;
18792 for (glyph = end; glyph >= beg; --glyph)
18793 if (STRINGP (glyph->object))
18794 {
18795 Lisp_Object prop
18796 = Fget_char_property (make_number (PT),
18797 Qdisplay, Qnil);
18798 result =
18799 (!NILP (prop)
18800 && display_prop_string_p (prop, glyph->object));
18801 /* If there's a `cursor' property on one of the
18802 string's characters, this row is a cursor row,
18803 even though this is not a display string. */
18804 if (!result)
18805 {
18806 Lisp_Object s = glyph->object;
18807
18808 for ( ; glyph >= beg && EQ (glyph->object, s); --glyph)
18809 {
18810 ptrdiff_t gpos = glyph->charpos;
18811
18812 if (!NILP (Fget_char_property (make_number (gpos),
18813 Qcursor, s)))
18814 {
18815 result = 1;
18816 break;
18817 }
18818 }
18819 }
18820 break;
18821 }
18822 }
18823 }
18824 else if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
18825 {
18826 /* If the row ends in middle of a real character,
18827 and the line is continued, we want the cursor here.
18828 That's because CHARPOS (ROW->end.pos) would equal
18829 PT if PT is before the character. */
18830 if (!row->ends_in_ellipsis_p)
18831 result = row->continued_p;
18832 else
18833 /* If the row ends in an ellipsis, then
18834 CHARPOS (ROW->end.pos) will equal point after the
18835 invisible text. We want that position to be displayed
18836 after the ellipsis. */
18837 result = 0;
18838 }
18839 /* If the row ends at ZV, display the cursor at the end of that
18840 row instead of at the start of the row below. */
18841 else if (row->ends_at_zv_p)
18842 result = 1;
18843 else
18844 result = 0;
18845 }
18846
18847 return result;
18848 }
18849
18850 \f
18851
18852 /* Push the property PROP so that it will be rendered at the current
18853 position in IT. Return 1 if PROP was successfully pushed, 0
18854 otherwise. Called from handle_line_prefix to handle the
18855 `line-prefix' and `wrap-prefix' properties. */
18856
18857 static int
18858 push_prefix_prop (struct it *it, Lisp_Object prop)
18859 {
18860 struct text_pos pos =
18861 STRINGP (it->string) ? it->current.string_pos : it->current.pos;
18862
18863 xassert (it->method == GET_FROM_BUFFER
18864 || it->method == GET_FROM_DISPLAY_VECTOR
18865 || it->method == GET_FROM_STRING);
18866
18867 /* We need to save the current buffer/string position, so it will be
18868 restored by pop_it, because iterate_out_of_display_property
18869 depends on that being set correctly, but some situations leave
18870 it->position not yet set when this function is called. */
18871 push_it (it, &pos);
18872
18873 if (STRINGP (prop))
18874 {
18875 if (SCHARS (prop) == 0)
18876 {
18877 pop_it (it);
18878 return 0;
18879 }
18880
18881 it->string = prop;
18882 it->string_from_prefix_prop_p = 1;
18883 it->multibyte_p = STRING_MULTIBYTE (it->string);
18884 it->current.overlay_string_index = -1;
18885 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
18886 it->end_charpos = it->string_nchars = SCHARS (it->string);
18887 it->method = GET_FROM_STRING;
18888 it->stop_charpos = 0;
18889 it->prev_stop = 0;
18890 it->base_level_stop = 0;
18891
18892 /* Force paragraph direction to be that of the parent
18893 buffer/string. */
18894 if (it->bidi_p && it->bidi_it.paragraph_dir == R2L)
18895 it->paragraph_embedding = it->bidi_it.paragraph_dir;
18896 else
18897 it->paragraph_embedding = L2R;
18898
18899 /* Set up the bidi iterator for this display string. */
18900 if (it->bidi_p)
18901 {
18902 it->bidi_it.string.lstring = it->string;
18903 it->bidi_it.string.s = NULL;
18904 it->bidi_it.string.schars = it->end_charpos;
18905 it->bidi_it.string.bufpos = IT_CHARPOS (*it);
18906 it->bidi_it.string.from_disp_str = it->string_from_display_prop_p;
18907 it->bidi_it.string.unibyte = !it->multibyte_p;
18908 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
18909 }
18910 }
18911 else if (CONSP (prop) && EQ (XCAR (prop), Qspace))
18912 {
18913 it->method = GET_FROM_STRETCH;
18914 it->object = prop;
18915 }
18916 #ifdef HAVE_WINDOW_SYSTEM
18917 else if (IMAGEP (prop))
18918 {
18919 it->what = IT_IMAGE;
18920 it->image_id = lookup_image (it->f, prop);
18921 it->method = GET_FROM_IMAGE;
18922 }
18923 #endif /* HAVE_WINDOW_SYSTEM */
18924 else
18925 {
18926 pop_it (it); /* bogus display property, give up */
18927 return 0;
18928 }
18929
18930 return 1;
18931 }
18932
18933 /* Return the character-property PROP at the current position in IT. */
18934
18935 static Lisp_Object
18936 get_it_property (struct it *it, Lisp_Object prop)
18937 {
18938 Lisp_Object position;
18939
18940 if (STRINGP (it->object))
18941 position = make_number (IT_STRING_CHARPOS (*it));
18942 else if (BUFFERP (it->object))
18943 position = make_number (IT_CHARPOS (*it));
18944 else
18945 return Qnil;
18946
18947 return Fget_char_property (position, prop, it->object);
18948 }
18949
18950 /* See if there's a line- or wrap-prefix, and if so, push it on IT. */
18951
18952 static void
18953 handle_line_prefix (struct it *it)
18954 {
18955 Lisp_Object prefix;
18956
18957 if (it->continuation_lines_width > 0)
18958 {
18959 prefix = get_it_property (it, Qwrap_prefix);
18960 if (NILP (prefix))
18961 prefix = Vwrap_prefix;
18962 }
18963 else
18964 {
18965 prefix = get_it_property (it, Qline_prefix);
18966 if (NILP (prefix))
18967 prefix = Vline_prefix;
18968 }
18969 if (! NILP (prefix) && push_prefix_prop (it, prefix))
18970 {
18971 /* If the prefix is wider than the window, and we try to wrap
18972 it, it would acquire its own wrap prefix, and so on till the
18973 iterator stack overflows. So, don't wrap the prefix. */
18974 it->line_wrap = TRUNCATE;
18975 it->avoid_cursor_p = 1;
18976 }
18977 }
18978
18979 \f
18980
18981 /* Remove N glyphs at the start of a reversed IT->glyph_row. Called
18982 only for R2L lines from display_line and display_string, when they
18983 decide that too many glyphs were produced by PRODUCE_GLYPHS, and
18984 the line/string needs to be continued on the next glyph row. */
18985 static void
18986 unproduce_glyphs (struct it *it, int n)
18987 {
18988 struct glyph *glyph, *end;
18989
18990 xassert (it->glyph_row);
18991 xassert (it->glyph_row->reversed_p);
18992 xassert (it->area == TEXT_AREA);
18993 xassert (n <= it->glyph_row->used[TEXT_AREA]);
18994
18995 if (n > it->glyph_row->used[TEXT_AREA])
18996 n = it->glyph_row->used[TEXT_AREA];
18997 glyph = it->glyph_row->glyphs[TEXT_AREA] + n;
18998 end = it->glyph_row->glyphs[TEXT_AREA] + it->glyph_row->used[TEXT_AREA];
18999 for ( ; glyph < end; glyph++)
19000 glyph[-n] = *glyph;
19001 }
19002
19003 /* Find the positions in a bidi-reordered ROW to serve as ROW->minpos
19004 and ROW->maxpos. */
19005 static void
19006 find_row_edges (struct it *it, struct glyph_row *row,
19007 ptrdiff_t min_pos, ptrdiff_t min_bpos,
19008 ptrdiff_t max_pos, ptrdiff_t max_bpos)
19009 {
19010 /* FIXME: Revisit this when glyph ``spilling'' in continuation
19011 lines' rows is implemented for bidi-reordered rows. */
19012
19013 /* ROW->minpos is the value of min_pos, the minimal buffer position
19014 we have in ROW, or ROW->start.pos if that is smaller. */
19015 if (min_pos <= ZV && min_pos < row->start.pos.charpos)
19016 SET_TEXT_POS (row->minpos, min_pos, min_bpos);
19017 else
19018 /* We didn't find buffer positions smaller than ROW->start, or
19019 didn't find _any_ valid buffer positions in any of the glyphs,
19020 so we must trust the iterator's computed positions. */
19021 row->minpos = row->start.pos;
19022 if (max_pos <= 0)
19023 {
19024 max_pos = CHARPOS (it->current.pos);
19025 max_bpos = BYTEPOS (it->current.pos);
19026 }
19027
19028 /* Here are the various use-cases for ending the row, and the
19029 corresponding values for ROW->maxpos:
19030
19031 Line ends in a newline from buffer eol_pos + 1
19032 Line is continued from buffer max_pos + 1
19033 Line is truncated on right it->current.pos
19034 Line ends in a newline from string max_pos + 1(*)
19035 (*) + 1 only when line ends in a forward scan
19036 Line is continued from string max_pos
19037 Line is continued from display vector max_pos
19038 Line is entirely from a string min_pos == max_pos
19039 Line is entirely from a display vector min_pos == max_pos
19040 Line that ends at ZV ZV
19041
19042 If you discover other use-cases, please add them here as
19043 appropriate. */
19044 if (row->ends_at_zv_p)
19045 row->maxpos = it->current.pos;
19046 else if (row->used[TEXT_AREA])
19047 {
19048 int seen_this_string = 0;
19049 struct glyph_row *r1 = row - 1;
19050
19051 /* Did we see the same display string on the previous row? */
19052 if (STRINGP (it->object)
19053 /* this is not the first row */
19054 && row > it->w->desired_matrix->rows
19055 /* previous row is not the header line */
19056 && !r1->mode_line_p
19057 /* previous row also ends in a newline from a string */
19058 && r1->ends_in_newline_from_string_p)
19059 {
19060 struct glyph *start, *end;
19061
19062 /* Search for the last glyph of the previous row that came
19063 from buffer or string. Depending on whether the row is
19064 L2R or R2L, we need to process it front to back or the
19065 other way round. */
19066 if (!r1->reversed_p)
19067 {
19068 start = r1->glyphs[TEXT_AREA];
19069 end = start + r1->used[TEXT_AREA];
19070 /* Glyphs inserted by redisplay have an integer (zero)
19071 as their object. */
19072 while (end > start
19073 && INTEGERP ((end - 1)->object)
19074 && (end - 1)->charpos <= 0)
19075 --end;
19076 if (end > start)
19077 {
19078 if (EQ ((end - 1)->object, it->object))
19079 seen_this_string = 1;
19080 }
19081 else
19082 /* If all the glyphs of the previous row were inserted
19083 by redisplay, it means the previous row was
19084 produced from a single newline, which is only
19085 possible if that newline came from the same string
19086 as the one which produced this ROW. */
19087 seen_this_string = 1;
19088 }
19089 else
19090 {
19091 end = r1->glyphs[TEXT_AREA] - 1;
19092 start = end + r1->used[TEXT_AREA];
19093 while (end < start
19094 && INTEGERP ((end + 1)->object)
19095 && (end + 1)->charpos <= 0)
19096 ++end;
19097 if (end < start)
19098 {
19099 if (EQ ((end + 1)->object, it->object))
19100 seen_this_string = 1;
19101 }
19102 else
19103 seen_this_string = 1;
19104 }
19105 }
19106 /* Take note of each display string that covers a newline only
19107 once, the first time we see it. This is for when a display
19108 string includes more than one newline in it. */
19109 if (row->ends_in_newline_from_string_p && !seen_this_string)
19110 {
19111 /* If we were scanning the buffer forward when we displayed
19112 the string, we want to account for at least one buffer
19113 position that belongs to this row (position covered by
19114 the display string), so that cursor positioning will
19115 consider this row as a candidate when point is at the end
19116 of the visual line represented by this row. This is not
19117 required when scanning back, because max_pos will already
19118 have a much larger value. */
19119 if (CHARPOS (row->end.pos) > max_pos)
19120 INC_BOTH (max_pos, max_bpos);
19121 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
19122 }
19123 else if (CHARPOS (it->eol_pos) > 0)
19124 SET_TEXT_POS (row->maxpos,
19125 CHARPOS (it->eol_pos) + 1, BYTEPOS (it->eol_pos) + 1);
19126 else if (row->continued_p)
19127 {
19128 /* If max_pos is different from IT's current position, it
19129 means IT->method does not belong to the display element
19130 at max_pos. However, it also means that the display
19131 element at max_pos was displayed in its entirety on this
19132 line, which is equivalent to saying that the next line
19133 starts at the next buffer position. */
19134 if (IT_CHARPOS (*it) == max_pos && it->method != GET_FROM_BUFFER)
19135 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
19136 else
19137 {
19138 INC_BOTH (max_pos, max_bpos);
19139 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
19140 }
19141 }
19142 else if (row->truncated_on_right_p)
19143 /* display_line already called reseat_at_next_visible_line_start,
19144 which puts the iterator at the beginning of the next line, in
19145 the logical order. */
19146 row->maxpos = it->current.pos;
19147 else if (max_pos == min_pos && it->method != GET_FROM_BUFFER)
19148 /* A line that is entirely from a string/image/stretch... */
19149 row->maxpos = row->minpos;
19150 else
19151 abort ();
19152 }
19153 else
19154 row->maxpos = it->current.pos;
19155 }
19156
19157 /* Construct the glyph row IT->glyph_row in the desired matrix of
19158 IT->w from text at the current position of IT. See dispextern.h
19159 for an overview of struct it. Value is non-zero if
19160 IT->glyph_row displays text, as opposed to a line displaying ZV
19161 only. */
19162
19163 static int
19164 display_line (struct it *it)
19165 {
19166 struct glyph_row *row = it->glyph_row;
19167 Lisp_Object overlay_arrow_string;
19168 struct it wrap_it;
19169 void *wrap_data = NULL;
19170 int may_wrap = 0, wrap_x IF_LINT (= 0);
19171 int wrap_row_used = -1;
19172 int wrap_row_ascent IF_LINT (= 0), wrap_row_height IF_LINT (= 0);
19173 int wrap_row_phys_ascent IF_LINT (= 0), wrap_row_phys_height IF_LINT (= 0);
19174 int wrap_row_extra_line_spacing IF_LINT (= 0);
19175 ptrdiff_t wrap_row_min_pos IF_LINT (= 0), wrap_row_min_bpos IF_LINT (= 0);
19176 ptrdiff_t wrap_row_max_pos IF_LINT (= 0), wrap_row_max_bpos IF_LINT (= 0);
19177 int cvpos;
19178 ptrdiff_t min_pos = ZV + 1, max_pos = 0;
19179 ptrdiff_t min_bpos IF_LINT (= 0), max_bpos IF_LINT (= 0);
19180
19181 /* We always start displaying at hpos zero even if hscrolled. */
19182 xassert (it->hpos == 0 && it->current_x == 0);
19183
19184 if (MATRIX_ROW_VPOS (row, it->w->desired_matrix)
19185 >= it->w->desired_matrix->nrows)
19186 {
19187 it->w->nrows_scale_factor++;
19188 fonts_changed_p = 1;
19189 return 0;
19190 }
19191
19192 /* Is IT->w showing the region? */
19193 it->w->region_showing = it->region_beg_charpos > 0 ? Qt : Qnil;
19194
19195 /* Clear the result glyph row and enable it. */
19196 prepare_desired_row (row);
19197
19198 row->y = it->current_y;
19199 row->start = it->start;
19200 row->continuation_lines_width = it->continuation_lines_width;
19201 row->displays_text_p = 1;
19202 row->starts_in_middle_of_char_p = it->starts_in_middle_of_char_p;
19203 it->starts_in_middle_of_char_p = 0;
19204
19205 /* Arrange the overlays nicely for our purposes. Usually, we call
19206 display_line on only one line at a time, in which case this
19207 can't really hurt too much, or we call it on lines which appear
19208 one after another in the buffer, in which case all calls to
19209 recenter_overlay_lists but the first will be pretty cheap. */
19210 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
19211
19212 /* Move over display elements that are not visible because we are
19213 hscrolled. This may stop at an x-position < IT->first_visible_x
19214 if the first glyph is partially visible or if we hit a line end. */
19215 if (it->current_x < it->first_visible_x)
19216 {
19217 this_line_min_pos = row->start.pos;
19218 move_it_in_display_line_to (it, ZV, it->first_visible_x,
19219 MOVE_TO_POS | MOVE_TO_X);
19220 /* Record the smallest positions seen while we moved over
19221 display elements that are not visible. This is needed by
19222 redisplay_internal for optimizing the case where the cursor
19223 stays inside the same line. The rest of this function only
19224 considers positions that are actually displayed, so
19225 RECORD_MAX_MIN_POS will not otherwise record positions that
19226 are hscrolled to the left of the left edge of the window. */
19227 min_pos = CHARPOS (this_line_min_pos);
19228 min_bpos = BYTEPOS (this_line_min_pos);
19229 }
19230 else
19231 {
19232 /* We only do this when not calling `move_it_in_display_line_to'
19233 above, because move_it_in_display_line_to calls
19234 handle_line_prefix itself. */
19235 handle_line_prefix (it);
19236 }
19237
19238 /* Get the initial row height. This is either the height of the
19239 text hscrolled, if there is any, or zero. */
19240 row->ascent = it->max_ascent;
19241 row->height = it->max_ascent + it->max_descent;
19242 row->phys_ascent = it->max_phys_ascent;
19243 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
19244 row->extra_line_spacing = it->max_extra_line_spacing;
19245
19246 /* Utility macro to record max and min buffer positions seen until now. */
19247 #define RECORD_MAX_MIN_POS(IT) \
19248 do \
19249 { \
19250 int composition_p = !STRINGP ((IT)->string) \
19251 && ((IT)->what == IT_COMPOSITION); \
19252 ptrdiff_t current_pos = \
19253 composition_p ? (IT)->cmp_it.charpos \
19254 : IT_CHARPOS (*(IT)); \
19255 ptrdiff_t current_bpos = \
19256 composition_p ? CHAR_TO_BYTE (current_pos) \
19257 : IT_BYTEPOS (*(IT)); \
19258 if (current_pos < min_pos) \
19259 { \
19260 min_pos = current_pos; \
19261 min_bpos = current_bpos; \
19262 } \
19263 if (IT_CHARPOS (*it) > max_pos) \
19264 { \
19265 max_pos = IT_CHARPOS (*it); \
19266 max_bpos = IT_BYTEPOS (*it); \
19267 } \
19268 } \
19269 while (0)
19270
19271 /* Loop generating characters. The loop is left with IT on the next
19272 character to display. */
19273 while (1)
19274 {
19275 int n_glyphs_before, hpos_before, x_before;
19276 int x, nglyphs;
19277 int ascent = 0, descent = 0, phys_ascent = 0, phys_descent = 0;
19278
19279 /* Retrieve the next thing to display. Value is zero if end of
19280 buffer reached. */
19281 if (!get_next_display_element (it))
19282 {
19283 /* Maybe add a space at the end of this line that is used to
19284 display the cursor there under X. Set the charpos of the
19285 first glyph of blank lines not corresponding to any text
19286 to -1. */
19287 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
19288 row->exact_window_width_line_p = 1;
19289 else if ((append_space_for_newline (it, 1) && row->used[TEXT_AREA] == 1)
19290 || row->used[TEXT_AREA] == 0)
19291 {
19292 row->glyphs[TEXT_AREA]->charpos = -1;
19293 row->displays_text_p = 0;
19294
19295 if (!NILP (BVAR (XBUFFER (it->w->buffer), indicate_empty_lines))
19296 && (!MINI_WINDOW_P (it->w)
19297 || (minibuf_level && EQ (it->window, minibuf_window))))
19298 row->indicate_empty_line_p = 1;
19299 }
19300
19301 it->continuation_lines_width = 0;
19302 row->ends_at_zv_p = 1;
19303 /* A row that displays right-to-left text must always have
19304 its last face extended all the way to the end of line,
19305 even if this row ends in ZV, because we still write to
19306 the screen left to right. We also need to extend the
19307 last face if the default face is remapped to some
19308 different face, otherwise the functions that clear
19309 portions of the screen will clear with the default face's
19310 background color. */
19311 if (row->reversed_p
19312 || lookup_basic_face (it->f, DEFAULT_FACE_ID) != DEFAULT_FACE_ID)
19313 extend_face_to_end_of_line (it);
19314 break;
19315 }
19316
19317 /* Now, get the metrics of what we want to display. This also
19318 generates glyphs in `row' (which is IT->glyph_row). */
19319 n_glyphs_before = row->used[TEXT_AREA];
19320 x = it->current_x;
19321
19322 /* Remember the line height so far in case the next element doesn't
19323 fit on the line. */
19324 if (it->line_wrap != TRUNCATE)
19325 {
19326 ascent = it->max_ascent;
19327 descent = it->max_descent;
19328 phys_ascent = it->max_phys_ascent;
19329 phys_descent = it->max_phys_descent;
19330
19331 if (it->line_wrap == WORD_WRAP && it->area == TEXT_AREA)
19332 {
19333 if (IT_DISPLAYING_WHITESPACE (it))
19334 may_wrap = 1;
19335 else if (may_wrap)
19336 {
19337 SAVE_IT (wrap_it, *it, wrap_data);
19338 wrap_x = x;
19339 wrap_row_used = row->used[TEXT_AREA];
19340 wrap_row_ascent = row->ascent;
19341 wrap_row_height = row->height;
19342 wrap_row_phys_ascent = row->phys_ascent;
19343 wrap_row_phys_height = row->phys_height;
19344 wrap_row_extra_line_spacing = row->extra_line_spacing;
19345 wrap_row_min_pos = min_pos;
19346 wrap_row_min_bpos = min_bpos;
19347 wrap_row_max_pos = max_pos;
19348 wrap_row_max_bpos = max_bpos;
19349 may_wrap = 0;
19350 }
19351 }
19352 }
19353
19354 PRODUCE_GLYPHS (it);
19355
19356 /* If this display element was in marginal areas, continue with
19357 the next one. */
19358 if (it->area != TEXT_AREA)
19359 {
19360 row->ascent = max (row->ascent, it->max_ascent);
19361 row->height = max (row->height, it->max_ascent + it->max_descent);
19362 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
19363 row->phys_height = max (row->phys_height,
19364 it->max_phys_ascent + it->max_phys_descent);
19365 row->extra_line_spacing = max (row->extra_line_spacing,
19366 it->max_extra_line_spacing);
19367 set_iterator_to_next (it, 1);
19368 continue;
19369 }
19370
19371 /* Does the display element fit on the line? If we truncate
19372 lines, we should draw past the right edge of the window. If
19373 we don't truncate, we want to stop so that we can display the
19374 continuation glyph before the right margin. If lines are
19375 continued, there are two possible strategies for characters
19376 resulting in more than 1 glyph (e.g. tabs): Display as many
19377 glyphs as possible in this line and leave the rest for the
19378 continuation line, or display the whole element in the next
19379 line. Original redisplay did the former, so we do it also. */
19380 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
19381 hpos_before = it->hpos;
19382 x_before = x;
19383
19384 if (/* Not a newline. */
19385 nglyphs > 0
19386 /* Glyphs produced fit entirely in the line. */
19387 && it->current_x < it->last_visible_x)
19388 {
19389 it->hpos += nglyphs;
19390 row->ascent = max (row->ascent, it->max_ascent);
19391 row->height = max (row->height, it->max_ascent + it->max_descent);
19392 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
19393 row->phys_height = max (row->phys_height,
19394 it->max_phys_ascent + it->max_phys_descent);
19395 row->extra_line_spacing = max (row->extra_line_spacing,
19396 it->max_extra_line_spacing);
19397 if (it->current_x - it->pixel_width < it->first_visible_x)
19398 row->x = x - it->first_visible_x;
19399 /* Record the maximum and minimum buffer positions seen so
19400 far in glyphs that will be displayed by this row. */
19401 if (it->bidi_p)
19402 RECORD_MAX_MIN_POS (it);
19403 }
19404 else
19405 {
19406 int i, new_x;
19407 struct glyph *glyph;
19408
19409 for (i = 0; i < nglyphs; ++i, x = new_x)
19410 {
19411 glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
19412 new_x = x + glyph->pixel_width;
19413
19414 if (/* Lines are continued. */
19415 it->line_wrap != TRUNCATE
19416 && (/* Glyph doesn't fit on the line. */
19417 new_x > it->last_visible_x
19418 /* Or it fits exactly on a window system frame. */
19419 || (new_x == it->last_visible_x
19420 && FRAME_WINDOW_P (it->f))))
19421 {
19422 /* End of a continued line. */
19423
19424 if (it->hpos == 0
19425 || (new_x == it->last_visible_x
19426 && FRAME_WINDOW_P (it->f)))
19427 {
19428 /* Current glyph is the only one on the line or
19429 fits exactly on the line. We must continue
19430 the line because we can't draw the cursor
19431 after the glyph. */
19432 row->continued_p = 1;
19433 it->current_x = new_x;
19434 it->continuation_lines_width += new_x;
19435 ++it->hpos;
19436 if (i == nglyphs - 1)
19437 {
19438 /* If line-wrap is on, check if a previous
19439 wrap point was found. */
19440 if (wrap_row_used > 0
19441 /* Even if there is a previous wrap
19442 point, continue the line here as
19443 usual, if (i) the previous character
19444 was a space or tab AND (ii) the
19445 current character is not. */
19446 && (!may_wrap
19447 || IT_DISPLAYING_WHITESPACE (it)))
19448 goto back_to_wrap;
19449
19450 /* Record the maximum and minimum buffer
19451 positions seen so far in glyphs that will be
19452 displayed by this row. */
19453 if (it->bidi_p)
19454 RECORD_MAX_MIN_POS (it);
19455 set_iterator_to_next (it, 1);
19456 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
19457 {
19458 if (!get_next_display_element (it))
19459 {
19460 row->exact_window_width_line_p = 1;
19461 it->continuation_lines_width = 0;
19462 row->continued_p = 0;
19463 row->ends_at_zv_p = 1;
19464 }
19465 else if (ITERATOR_AT_END_OF_LINE_P (it))
19466 {
19467 row->continued_p = 0;
19468 row->exact_window_width_line_p = 1;
19469 }
19470 }
19471 }
19472 else if (it->bidi_p)
19473 RECORD_MAX_MIN_POS (it);
19474 }
19475 else if (CHAR_GLYPH_PADDING_P (*glyph)
19476 && !FRAME_WINDOW_P (it->f))
19477 {
19478 /* A padding glyph that doesn't fit on this line.
19479 This means the whole character doesn't fit
19480 on the line. */
19481 if (row->reversed_p)
19482 unproduce_glyphs (it, row->used[TEXT_AREA]
19483 - n_glyphs_before);
19484 row->used[TEXT_AREA] = n_glyphs_before;
19485
19486 /* Fill the rest of the row with continuation
19487 glyphs like in 20.x. */
19488 while (row->glyphs[TEXT_AREA] + row->used[TEXT_AREA]
19489 < row->glyphs[1 + TEXT_AREA])
19490 produce_special_glyphs (it, IT_CONTINUATION);
19491
19492 row->continued_p = 1;
19493 it->current_x = x_before;
19494 it->continuation_lines_width += x_before;
19495
19496 /* Restore the height to what it was before the
19497 element not fitting on the line. */
19498 it->max_ascent = ascent;
19499 it->max_descent = descent;
19500 it->max_phys_ascent = phys_ascent;
19501 it->max_phys_descent = phys_descent;
19502 }
19503 else if (wrap_row_used > 0)
19504 {
19505 back_to_wrap:
19506 if (row->reversed_p)
19507 unproduce_glyphs (it,
19508 row->used[TEXT_AREA] - wrap_row_used);
19509 RESTORE_IT (it, &wrap_it, wrap_data);
19510 it->continuation_lines_width += wrap_x;
19511 row->used[TEXT_AREA] = wrap_row_used;
19512 row->ascent = wrap_row_ascent;
19513 row->height = wrap_row_height;
19514 row->phys_ascent = wrap_row_phys_ascent;
19515 row->phys_height = wrap_row_phys_height;
19516 row->extra_line_spacing = wrap_row_extra_line_spacing;
19517 min_pos = wrap_row_min_pos;
19518 min_bpos = wrap_row_min_bpos;
19519 max_pos = wrap_row_max_pos;
19520 max_bpos = wrap_row_max_bpos;
19521 row->continued_p = 1;
19522 row->ends_at_zv_p = 0;
19523 row->exact_window_width_line_p = 0;
19524 it->continuation_lines_width += x;
19525
19526 /* Make sure that a non-default face is extended
19527 up to the right margin of the window. */
19528 extend_face_to_end_of_line (it);
19529 }
19530 else if (it->c == '\t' && FRAME_WINDOW_P (it->f))
19531 {
19532 /* A TAB that extends past the right edge of the
19533 window. This produces a single glyph on
19534 window system frames. We leave the glyph in
19535 this row and let it fill the row, but don't
19536 consume the TAB. */
19537 it->continuation_lines_width += it->last_visible_x;
19538 row->ends_in_middle_of_char_p = 1;
19539 row->continued_p = 1;
19540 glyph->pixel_width = it->last_visible_x - x;
19541 it->starts_in_middle_of_char_p = 1;
19542 }
19543 else
19544 {
19545 /* Something other than a TAB that draws past
19546 the right edge of the window. Restore
19547 positions to values before the element. */
19548 if (row->reversed_p)
19549 unproduce_glyphs (it, row->used[TEXT_AREA]
19550 - (n_glyphs_before + i));
19551 row->used[TEXT_AREA] = n_glyphs_before + i;
19552
19553 /* Display continuation glyphs. */
19554 if (!FRAME_WINDOW_P (it->f))
19555 produce_special_glyphs (it, IT_CONTINUATION);
19556 row->continued_p = 1;
19557
19558 it->current_x = x_before;
19559 it->continuation_lines_width += x;
19560 extend_face_to_end_of_line (it);
19561
19562 if (nglyphs > 1 && i > 0)
19563 {
19564 row->ends_in_middle_of_char_p = 1;
19565 it->starts_in_middle_of_char_p = 1;
19566 }
19567
19568 /* Restore the height to what it was before the
19569 element not fitting on the line. */
19570 it->max_ascent = ascent;
19571 it->max_descent = descent;
19572 it->max_phys_ascent = phys_ascent;
19573 it->max_phys_descent = phys_descent;
19574 }
19575
19576 break;
19577 }
19578 else if (new_x > it->first_visible_x)
19579 {
19580 /* Increment number of glyphs actually displayed. */
19581 ++it->hpos;
19582
19583 /* Record the maximum and minimum buffer positions
19584 seen so far in glyphs that will be displayed by
19585 this row. */
19586 if (it->bidi_p)
19587 RECORD_MAX_MIN_POS (it);
19588
19589 if (x < it->first_visible_x)
19590 /* Glyph is partially visible, i.e. row starts at
19591 negative X position. */
19592 row->x = x - it->first_visible_x;
19593 }
19594 else
19595 {
19596 /* Glyph is completely off the left margin of the
19597 window. This should not happen because of the
19598 move_it_in_display_line at the start of this
19599 function, unless the text display area of the
19600 window is empty. */
19601 xassert (it->first_visible_x <= it->last_visible_x);
19602 }
19603 }
19604 /* Even if this display element produced no glyphs at all,
19605 we want to record its position. */
19606 if (it->bidi_p && nglyphs == 0)
19607 RECORD_MAX_MIN_POS (it);
19608
19609 row->ascent = max (row->ascent, it->max_ascent);
19610 row->height = max (row->height, it->max_ascent + it->max_descent);
19611 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
19612 row->phys_height = max (row->phys_height,
19613 it->max_phys_ascent + it->max_phys_descent);
19614 row->extra_line_spacing = max (row->extra_line_spacing,
19615 it->max_extra_line_spacing);
19616
19617 /* End of this display line if row is continued. */
19618 if (row->continued_p || row->ends_at_zv_p)
19619 break;
19620 }
19621
19622 at_end_of_line:
19623 /* Is this a line end? If yes, we're also done, after making
19624 sure that a non-default face is extended up to the right
19625 margin of the window. */
19626 if (ITERATOR_AT_END_OF_LINE_P (it))
19627 {
19628 int used_before = row->used[TEXT_AREA];
19629
19630 row->ends_in_newline_from_string_p = STRINGP (it->object);
19631
19632 /* Add a space at the end of the line that is used to
19633 display the cursor there. */
19634 if (!IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
19635 append_space_for_newline (it, 0);
19636
19637 /* Extend the face to the end of the line. */
19638 extend_face_to_end_of_line (it);
19639
19640 /* Make sure we have the position. */
19641 if (used_before == 0)
19642 row->glyphs[TEXT_AREA]->charpos = CHARPOS (it->position);
19643
19644 /* Record the position of the newline, for use in
19645 find_row_edges. */
19646 it->eol_pos = it->current.pos;
19647
19648 /* Consume the line end. This skips over invisible lines. */
19649 set_iterator_to_next (it, 1);
19650 it->continuation_lines_width = 0;
19651 break;
19652 }
19653
19654 /* Proceed with next display element. Note that this skips
19655 over lines invisible because of selective display. */
19656 set_iterator_to_next (it, 1);
19657
19658 /* If we truncate lines, we are done when the last displayed
19659 glyphs reach past the right margin of the window. */
19660 if (it->line_wrap == TRUNCATE
19661 && (FRAME_WINDOW_P (it->f)
19662 ? (it->current_x >= it->last_visible_x)
19663 : (it->current_x > it->last_visible_x)))
19664 {
19665 /* Maybe add truncation glyphs. */
19666 if (!FRAME_WINDOW_P (it->f))
19667 {
19668 int i, n;
19669
19670 if (!row->reversed_p)
19671 {
19672 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
19673 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
19674 break;
19675 }
19676 else
19677 {
19678 for (i = 0; i < row->used[TEXT_AREA]; i++)
19679 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
19680 break;
19681 /* Remove any padding glyphs at the front of ROW, to
19682 make room for the truncation glyphs we will be
19683 adding below. The loop below always inserts at
19684 least one truncation glyph, so also remove the
19685 last glyph added to ROW. */
19686 unproduce_glyphs (it, i + 1);
19687 /* Adjust i for the loop below. */
19688 i = row->used[TEXT_AREA] - (i + 1);
19689 }
19690
19691 for (n = row->used[TEXT_AREA]; i < n; ++i)
19692 {
19693 row->used[TEXT_AREA] = i;
19694 produce_special_glyphs (it, IT_TRUNCATION);
19695 }
19696 }
19697 else if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
19698 {
19699 /* Don't truncate if we can overflow newline into fringe. */
19700 if (!get_next_display_element (it))
19701 {
19702 it->continuation_lines_width = 0;
19703 row->ends_at_zv_p = 1;
19704 row->exact_window_width_line_p = 1;
19705 break;
19706 }
19707 if (ITERATOR_AT_END_OF_LINE_P (it))
19708 {
19709 row->exact_window_width_line_p = 1;
19710 goto at_end_of_line;
19711 }
19712 }
19713
19714 row->truncated_on_right_p = 1;
19715 it->continuation_lines_width = 0;
19716 reseat_at_next_visible_line_start (it, 0);
19717 row->ends_at_zv_p = FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n';
19718 it->hpos = hpos_before;
19719 it->current_x = x_before;
19720 break;
19721 }
19722 }
19723
19724 if (wrap_data)
19725 bidi_unshelve_cache (wrap_data, 1);
19726
19727 /* If line is not empty and hscrolled, maybe insert truncation glyphs
19728 at the left window margin. */
19729 if (it->first_visible_x
19730 && IT_CHARPOS (*it) != CHARPOS (row->start.pos))
19731 {
19732 if (!FRAME_WINDOW_P (it->f))
19733 insert_left_trunc_glyphs (it);
19734 row->truncated_on_left_p = 1;
19735 }
19736
19737 /* Remember the position at which this line ends.
19738
19739 BIDI Note: any code that needs MATRIX_ROW_START/END_CHARPOS
19740 cannot be before the call to find_row_edges below, since that is
19741 where these positions are determined. */
19742 row->end = it->current;
19743 if (!it->bidi_p)
19744 {
19745 row->minpos = row->start.pos;
19746 row->maxpos = row->end.pos;
19747 }
19748 else
19749 {
19750 /* ROW->minpos and ROW->maxpos must be the smallest and
19751 `1 + the largest' buffer positions in ROW. But if ROW was
19752 bidi-reordered, these two positions can be anywhere in the
19753 row, so we must determine them now. */
19754 find_row_edges (it, row, min_pos, min_bpos, max_pos, max_bpos);
19755 }
19756
19757 /* If the start of this line is the overlay arrow-position, then
19758 mark this glyph row as the one containing the overlay arrow.
19759 This is clearly a mess with variable size fonts. It would be
19760 better to let it be displayed like cursors under X. */
19761 if ((row->displays_text_p || !overlay_arrow_seen)
19762 && (overlay_arrow_string = overlay_arrow_at_row (it, row),
19763 !NILP (overlay_arrow_string)))
19764 {
19765 /* Overlay arrow in window redisplay is a fringe bitmap. */
19766 if (STRINGP (overlay_arrow_string))
19767 {
19768 struct glyph_row *arrow_row
19769 = get_overlay_arrow_glyph_row (it->w, overlay_arrow_string);
19770 struct glyph *glyph = arrow_row->glyphs[TEXT_AREA];
19771 struct glyph *arrow_end = glyph + arrow_row->used[TEXT_AREA];
19772 struct glyph *p = row->glyphs[TEXT_AREA];
19773 struct glyph *p2, *end;
19774
19775 /* Copy the arrow glyphs. */
19776 while (glyph < arrow_end)
19777 *p++ = *glyph++;
19778
19779 /* Throw away padding glyphs. */
19780 p2 = p;
19781 end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
19782 while (p2 < end && CHAR_GLYPH_PADDING_P (*p2))
19783 ++p2;
19784 if (p2 > p)
19785 {
19786 while (p2 < end)
19787 *p++ = *p2++;
19788 row->used[TEXT_AREA] = p2 - row->glyphs[TEXT_AREA];
19789 }
19790 }
19791 else
19792 {
19793 xassert (INTEGERP (overlay_arrow_string));
19794 row->overlay_arrow_bitmap = XINT (overlay_arrow_string);
19795 }
19796 overlay_arrow_seen = 1;
19797 }
19798
19799 /* Highlight trailing whitespace. */
19800 if (!NILP (Vshow_trailing_whitespace))
19801 highlight_trailing_whitespace (it->f, it->glyph_row);
19802
19803 /* Compute pixel dimensions of this line. */
19804 compute_line_metrics (it);
19805
19806 /* Implementation note: No changes in the glyphs of ROW or in their
19807 faces can be done past this point, because compute_line_metrics
19808 computes ROW's hash value and stores it within the glyph_row
19809 structure. */
19810
19811 /* Record whether this row ends inside an ellipsis. */
19812 row->ends_in_ellipsis_p
19813 = (it->method == GET_FROM_DISPLAY_VECTOR
19814 && it->ellipsis_p);
19815
19816 /* Save fringe bitmaps in this row. */
19817 row->left_user_fringe_bitmap = it->left_user_fringe_bitmap;
19818 row->left_user_fringe_face_id = it->left_user_fringe_face_id;
19819 row->right_user_fringe_bitmap = it->right_user_fringe_bitmap;
19820 row->right_user_fringe_face_id = it->right_user_fringe_face_id;
19821
19822 it->left_user_fringe_bitmap = 0;
19823 it->left_user_fringe_face_id = 0;
19824 it->right_user_fringe_bitmap = 0;
19825 it->right_user_fringe_face_id = 0;
19826
19827 /* Maybe set the cursor. */
19828 cvpos = it->w->cursor.vpos;
19829 if ((cvpos < 0
19830 /* In bidi-reordered rows, keep checking for proper cursor
19831 position even if one has been found already, because buffer
19832 positions in such rows change non-linearly with ROW->VPOS,
19833 when a line is continued. One exception: when we are at ZV,
19834 display cursor on the first suitable glyph row, since all
19835 the empty rows after that also have their position set to ZV. */
19836 /* FIXME: Revisit this when glyph ``spilling'' in continuation
19837 lines' rows is implemented for bidi-reordered rows. */
19838 || (it->bidi_p
19839 && !MATRIX_ROW (it->w->desired_matrix, cvpos)->ends_at_zv_p))
19840 && PT >= MATRIX_ROW_START_CHARPOS (row)
19841 && PT <= MATRIX_ROW_END_CHARPOS (row)
19842 && cursor_row_p (row))
19843 set_cursor_from_row (it->w, row, it->w->desired_matrix, 0, 0, 0, 0);
19844
19845 /* Prepare for the next line. This line starts horizontally at (X
19846 HPOS) = (0 0). Vertical positions are incremented. As a
19847 convenience for the caller, IT->glyph_row is set to the next
19848 row to be used. */
19849 it->current_x = it->hpos = 0;
19850 it->current_y += row->height;
19851 SET_TEXT_POS (it->eol_pos, 0, 0);
19852 ++it->vpos;
19853 ++it->glyph_row;
19854 /* The next row should by default use the same value of the
19855 reversed_p flag as this one. set_iterator_to_next decides when
19856 it's a new paragraph, and PRODUCE_GLYPHS recomputes the value of
19857 the flag accordingly. */
19858 if (it->glyph_row < MATRIX_BOTTOM_TEXT_ROW (it->w->desired_matrix, it->w))
19859 it->glyph_row->reversed_p = row->reversed_p;
19860 it->start = row->end;
19861 return row->displays_text_p;
19862
19863 #undef RECORD_MAX_MIN_POS
19864 }
19865
19866 DEFUN ("current-bidi-paragraph-direction", Fcurrent_bidi_paragraph_direction,
19867 Scurrent_bidi_paragraph_direction, 0, 1, 0,
19868 doc: /* Return paragraph direction at point in BUFFER.
19869 Value is either `left-to-right' or `right-to-left'.
19870 If BUFFER is omitted or nil, it defaults to the current buffer.
19871
19872 Paragraph direction determines how the text in the paragraph is displayed.
19873 In left-to-right paragraphs, text begins at the left margin of the window
19874 and the reading direction is generally left to right. In right-to-left
19875 paragraphs, text begins at the right margin and is read from right to left.
19876
19877 See also `bidi-paragraph-direction'. */)
19878 (Lisp_Object buffer)
19879 {
19880 struct buffer *buf = current_buffer;
19881 struct buffer *old = buf;
19882
19883 if (! NILP (buffer))
19884 {
19885 CHECK_BUFFER (buffer);
19886 buf = XBUFFER (buffer);
19887 }
19888
19889 if (NILP (BVAR (buf, bidi_display_reordering))
19890 || NILP (BVAR (buf, enable_multibyte_characters))
19891 /* When we are loading loadup.el, the character property tables
19892 needed for bidi iteration are not yet available. */
19893 || !NILP (Vpurify_flag))
19894 return Qleft_to_right;
19895 else if (!NILP (BVAR (buf, bidi_paragraph_direction)))
19896 return BVAR (buf, bidi_paragraph_direction);
19897 else
19898 {
19899 /* Determine the direction from buffer text. We could try to
19900 use current_matrix if it is up to date, but this seems fast
19901 enough as it is. */
19902 struct bidi_it itb;
19903 ptrdiff_t pos = BUF_PT (buf);
19904 ptrdiff_t bytepos = BUF_PT_BYTE (buf);
19905 int c;
19906 void *itb_data = bidi_shelve_cache ();
19907
19908 set_buffer_temp (buf);
19909 /* bidi_paragraph_init finds the base direction of the paragraph
19910 by searching forward from paragraph start. We need the base
19911 direction of the current or _previous_ paragraph, so we need
19912 to make sure we are within that paragraph. To that end, find
19913 the previous non-empty line. */
19914 if (pos >= ZV && pos > BEGV)
19915 {
19916 pos--;
19917 bytepos = CHAR_TO_BYTE (pos);
19918 }
19919 if (fast_looking_at (build_string ("[\f\t ]*\n"),
19920 pos, bytepos, ZV, ZV_BYTE, Qnil) > 0)
19921 {
19922 while ((c = FETCH_BYTE (bytepos)) == '\n'
19923 || c == ' ' || c == '\t' || c == '\f')
19924 {
19925 if (bytepos <= BEGV_BYTE)
19926 break;
19927 bytepos--;
19928 pos--;
19929 }
19930 while (!CHAR_HEAD_P (FETCH_BYTE (bytepos)))
19931 bytepos--;
19932 }
19933 bidi_init_it (pos, bytepos, FRAME_WINDOW_P (SELECTED_FRAME ()), &itb);
19934 itb.paragraph_dir = NEUTRAL_DIR;
19935 itb.string.s = NULL;
19936 itb.string.lstring = Qnil;
19937 itb.string.bufpos = 0;
19938 itb.string.unibyte = 0;
19939 bidi_paragraph_init (NEUTRAL_DIR, &itb, 1);
19940 bidi_unshelve_cache (itb_data, 0);
19941 set_buffer_temp (old);
19942 switch (itb.paragraph_dir)
19943 {
19944 case L2R:
19945 return Qleft_to_right;
19946 break;
19947 case R2L:
19948 return Qright_to_left;
19949 break;
19950 default:
19951 abort ();
19952 }
19953 }
19954 }
19955
19956
19957 \f
19958 /***********************************************************************
19959 Menu Bar
19960 ***********************************************************************/
19961
19962 /* Redisplay the menu bar in the frame for window W.
19963
19964 The menu bar of X frames that don't have X toolkit support is
19965 displayed in a special window W->frame->menu_bar_window.
19966
19967 The menu bar of terminal frames is treated specially as far as
19968 glyph matrices are concerned. Menu bar lines are not part of
19969 windows, so the update is done directly on the frame matrix rows
19970 for the menu bar. */
19971
19972 static void
19973 display_menu_bar (struct window *w)
19974 {
19975 struct frame *f = XFRAME (WINDOW_FRAME (w));
19976 struct it it;
19977 Lisp_Object items;
19978 int i;
19979
19980 /* Don't do all this for graphical frames. */
19981 #ifdef HAVE_NTGUI
19982 if (FRAME_W32_P (f))
19983 return;
19984 #endif
19985 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
19986 if (FRAME_X_P (f))
19987 return;
19988 #endif
19989
19990 #ifdef HAVE_NS
19991 if (FRAME_NS_P (f))
19992 return;
19993 #endif /* HAVE_NS */
19994
19995 #ifdef USE_X_TOOLKIT
19996 xassert (!FRAME_WINDOW_P (f));
19997 init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MENU_FACE_ID);
19998 it.first_visible_x = 0;
19999 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
20000 #else /* not USE_X_TOOLKIT */
20001 if (FRAME_WINDOW_P (f))
20002 {
20003 /* Menu bar lines are displayed in the desired matrix of the
20004 dummy window menu_bar_window. */
20005 struct window *menu_w;
20006 xassert (WINDOWP (f->menu_bar_window));
20007 menu_w = XWINDOW (f->menu_bar_window);
20008 init_iterator (&it, menu_w, -1, -1, menu_w->desired_matrix->rows,
20009 MENU_FACE_ID);
20010 it.first_visible_x = 0;
20011 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
20012 }
20013 else
20014 {
20015 /* This is a TTY frame, i.e. character hpos/vpos are used as
20016 pixel x/y. */
20017 init_iterator (&it, w, -1, -1, f->desired_matrix->rows,
20018 MENU_FACE_ID);
20019 it.first_visible_x = 0;
20020 it.last_visible_x = FRAME_COLS (f);
20021 }
20022 #endif /* not USE_X_TOOLKIT */
20023
20024 /* FIXME: This should be controlled by a user option. See the
20025 comments in redisplay_tool_bar and display_mode_line about
20026 this. */
20027 it.paragraph_embedding = L2R;
20028
20029 if (! mode_line_inverse_video)
20030 /* Force the menu-bar to be displayed in the default face. */
20031 it.base_face_id = it.face_id = DEFAULT_FACE_ID;
20032
20033 /* Clear all rows of the menu bar. */
20034 for (i = 0; i < FRAME_MENU_BAR_LINES (f); ++i)
20035 {
20036 struct glyph_row *row = it.glyph_row + i;
20037 clear_glyph_row (row);
20038 row->enabled_p = 1;
20039 row->full_width_p = 1;
20040 }
20041
20042 /* Display all items of the menu bar. */
20043 items = FRAME_MENU_BAR_ITEMS (it.f);
20044 for (i = 0; i < ASIZE (items); i += 4)
20045 {
20046 Lisp_Object string;
20047
20048 /* Stop at nil string. */
20049 string = AREF (items, i + 1);
20050 if (NILP (string))
20051 break;
20052
20053 /* Remember where item was displayed. */
20054 ASET (items, i + 3, make_number (it.hpos));
20055
20056 /* Display the item, pad with one space. */
20057 if (it.current_x < it.last_visible_x)
20058 display_string (NULL, string, Qnil, 0, 0, &it,
20059 SCHARS (string) + 1, 0, 0, -1);
20060 }
20061
20062 /* Fill out the line with spaces. */
20063 if (it.current_x < it.last_visible_x)
20064 display_string ("", Qnil, Qnil, 0, 0, &it, -1, 0, 0, -1);
20065
20066 /* Compute the total height of the lines. */
20067 compute_line_metrics (&it);
20068 }
20069
20070
20071 \f
20072 /***********************************************************************
20073 Mode Line
20074 ***********************************************************************/
20075
20076 /* Redisplay mode lines in the window tree whose root is WINDOW. If
20077 FORCE is non-zero, redisplay mode lines unconditionally.
20078 Otherwise, redisplay only mode lines that are garbaged. Value is
20079 the number of windows whose mode lines were redisplayed. */
20080
20081 static int
20082 redisplay_mode_lines (Lisp_Object window, int force)
20083 {
20084 int nwindows = 0;
20085
20086 while (!NILP (window))
20087 {
20088 struct window *w = XWINDOW (window);
20089
20090 if (WINDOWP (w->hchild))
20091 nwindows += redisplay_mode_lines (w->hchild, force);
20092 else if (WINDOWP (w->vchild))
20093 nwindows += redisplay_mode_lines (w->vchild, force);
20094 else if (force
20095 || FRAME_GARBAGED_P (XFRAME (w->frame))
20096 || !MATRIX_MODE_LINE_ROW (w->current_matrix)->enabled_p)
20097 {
20098 struct text_pos lpoint;
20099 struct buffer *old = current_buffer;
20100
20101 /* Set the window's buffer for the mode line display. */
20102 SET_TEXT_POS (lpoint, PT, PT_BYTE);
20103 set_buffer_internal_1 (XBUFFER (w->buffer));
20104
20105 /* Point refers normally to the selected window. For any
20106 other window, set up appropriate value. */
20107 if (!EQ (window, selected_window))
20108 {
20109 struct text_pos pt;
20110
20111 SET_TEXT_POS_FROM_MARKER (pt, w->pointm);
20112 if (CHARPOS (pt) < BEGV)
20113 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
20114 else if (CHARPOS (pt) > (ZV - 1))
20115 TEMP_SET_PT_BOTH (ZV, ZV_BYTE);
20116 else
20117 TEMP_SET_PT_BOTH (CHARPOS (pt), BYTEPOS (pt));
20118 }
20119
20120 /* Display mode lines. */
20121 clear_glyph_matrix (w->desired_matrix);
20122 if (display_mode_lines (w))
20123 {
20124 ++nwindows;
20125 w->must_be_updated_p = 1;
20126 }
20127
20128 /* Restore old settings. */
20129 set_buffer_internal_1 (old);
20130 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
20131 }
20132
20133 window = w->next;
20134 }
20135
20136 return nwindows;
20137 }
20138
20139
20140 /* Display the mode and/or header line of window W. Value is the
20141 sum number of mode lines and header lines displayed. */
20142
20143 static int
20144 display_mode_lines (struct window *w)
20145 {
20146 Lisp_Object old_selected_window, old_selected_frame;
20147 int n = 0;
20148
20149 old_selected_frame = selected_frame;
20150 selected_frame = w->frame;
20151 old_selected_window = selected_window;
20152 XSETWINDOW (selected_window, w);
20153
20154 /* These will be set while the mode line specs are processed. */
20155 line_number_displayed = 0;
20156 w->column_number_displayed = Qnil;
20157
20158 if (WINDOW_WANTS_MODELINE_P (w))
20159 {
20160 struct window *sel_w = XWINDOW (old_selected_window);
20161
20162 /* Select mode line face based on the real selected window. */
20163 display_mode_line (w, CURRENT_MODE_LINE_FACE_ID_3 (sel_w, sel_w, w),
20164 BVAR (current_buffer, mode_line_format));
20165 ++n;
20166 }
20167
20168 if (WINDOW_WANTS_HEADER_LINE_P (w))
20169 {
20170 display_mode_line (w, HEADER_LINE_FACE_ID,
20171 BVAR (current_buffer, header_line_format));
20172 ++n;
20173 }
20174
20175 selected_frame = old_selected_frame;
20176 selected_window = old_selected_window;
20177 return n;
20178 }
20179
20180
20181 /* Display mode or header line of window W. FACE_ID specifies which
20182 line to display; it is either MODE_LINE_FACE_ID or
20183 HEADER_LINE_FACE_ID. FORMAT is the mode/header line format to
20184 display. Value is the pixel height of the mode/header line
20185 displayed. */
20186
20187 static int
20188 display_mode_line (struct window *w, enum face_id face_id, Lisp_Object format)
20189 {
20190 struct it it;
20191 struct face *face;
20192 ptrdiff_t count = SPECPDL_INDEX ();
20193
20194 init_iterator (&it, w, -1, -1, NULL, face_id);
20195 /* Don't extend on a previously drawn mode-line.
20196 This may happen if called from pos_visible_p. */
20197 it.glyph_row->enabled_p = 0;
20198 prepare_desired_row (it.glyph_row);
20199
20200 it.glyph_row->mode_line_p = 1;
20201
20202 if (! mode_line_inverse_video)
20203 /* Force the mode-line to be displayed in the default face. */
20204 it.base_face_id = it.face_id = DEFAULT_FACE_ID;
20205
20206 /* FIXME: This should be controlled by a user option. But
20207 supporting such an option is not trivial, since the mode line is
20208 made up of many separate strings. */
20209 it.paragraph_embedding = L2R;
20210
20211 record_unwind_protect (unwind_format_mode_line,
20212 format_mode_line_unwind_data (NULL, Qnil, 0));
20213
20214 mode_line_target = MODE_LINE_DISPLAY;
20215
20216 /* Temporarily make frame's keyboard the current kboard so that
20217 kboard-local variables in the mode_line_format will get the right
20218 values. */
20219 push_kboard (FRAME_KBOARD (it.f));
20220 record_unwind_save_match_data ();
20221 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
20222 pop_kboard ();
20223
20224 unbind_to (count, Qnil);
20225
20226 /* Fill up with spaces. */
20227 display_string (" ", Qnil, Qnil, 0, 0, &it, 10000, -1, -1, 0);
20228
20229 compute_line_metrics (&it);
20230 it.glyph_row->full_width_p = 1;
20231 it.glyph_row->continued_p = 0;
20232 it.glyph_row->truncated_on_left_p = 0;
20233 it.glyph_row->truncated_on_right_p = 0;
20234
20235 /* Make a 3D mode-line have a shadow at its right end. */
20236 face = FACE_FROM_ID (it.f, face_id);
20237 extend_face_to_end_of_line (&it);
20238 if (face->box != FACE_NO_BOX)
20239 {
20240 struct glyph *last = (it.glyph_row->glyphs[TEXT_AREA]
20241 + it.glyph_row->used[TEXT_AREA] - 1);
20242 last->right_box_line_p = 1;
20243 }
20244
20245 return it.glyph_row->height;
20246 }
20247
20248 /* Move element ELT in LIST to the front of LIST.
20249 Return the updated list. */
20250
20251 static Lisp_Object
20252 move_elt_to_front (Lisp_Object elt, Lisp_Object list)
20253 {
20254 register Lisp_Object tail, prev;
20255 register Lisp_Object tem;
20256
20257 tail = list;
20258 prev = Qnil;
20259 while (CONSP (tail))
20260 {
20261 tem = XCAR (tail);
20262
20263 if (EQ (elt, tem))
20264 {
20265 /* Splice out the link TAIL. */
20266 if (NILP (prev))
20267 list = XCDR (tail);
20268 else
20269 Fsetcdr (prev, XCDR (tail));
20270
20271 /* Now make it the first. */
20272 Fsetcdr (tail, list);
20273 return tail;
20274 }
20275 else
20276 prev = tail;
20277 tail = XCDR (tail);
20278 QUIT;
20279 }
20280
20281 /* Not found--return unchanged LIST. */
20282 return list;
20283 }
20284
20285 /* Contribute ELT to the mode line for window IT->w. How it
20286 translates into text depends on its data type.
20287
20288 IT describes the display environment in which we display, as usual.
20289
20290 DEPTH is the depth in recursion. It is used to prevent
20291 infinite recursion here.
20292
20293 FIELD_WIDTH is the number of characters the display of ELT should
20294 occupy in the mode line, and PRECISION is the maximum number of
20295 characters to display from ELT's representation. See
20296 display_string for details.
20297
20298 Returns the hpos of the end of the text generated by ELT.
20299
20300 PROPS is a property list to add to any string we encounter.
20301
20302 If RISKY is nonzero, remove (disregard) any properties in any string
20303 we encounter, and ignore :eval and :propertize.
20304
20305 The global variable `mode_line_target' determines whether the
20306 output is passed to `store_mode_line_noprop',
20307 `store_mode_line_string', or `display_string'. */
20308
20309 static int
20310 display_mode_element (struct it *it, int depth, int field_width, int precision,
20311 Lisp_Object elt, Lisp_Object props, int risky)
20312 {
20313 int n = 0, field, prec;
20314 int literal = 0;
20315
20316 tail_recurse:
20317 if (depth > 100)
20318 elt = build_string ("*too-deep*");
20319
20320 depth++;
20321
20322 switch (SWITCH_ENUM_CAST (XTYPE (elt)))
20323 {
20324 case Lisp_String:
20325 {
20326 /* A string: output it and check for %-constructs within it. */
20327 unsigned char c;
20328 ptrdiff_t offset = 0;
20329
20330 if (SCHARS (elt) > 0
20331 && (!NILP (props) || risky))
20332 {
20333 Lisp_Object oprops, aelt;
20334 oprops = Ftext_properties_at (make_number (0), elt);
20335
20336 /* If the starting string's properties are not what
20337 we want, translate the string. Also, if the string
20338 is risky, do that anyway. */
20339
20340 if (NILP (Fequal (props, oprops)) || risky)
20341 {
20342 /* If the starting string has properties,
20343 merge the specified ones onto the existing ones. */
20344 if (! NILP (oprops) && !risky)
20345 {
20346 Lisp_Object tem;
20347
20348 oprops = Fcopy_sequence (oprops);
20349 tem = props;
20350 while (CONSP (tem))
20351 {
20352 oprops = Fplist_put (oprops, XCAR (tem),
20353 XCAR (XCDR (tem)));
20354 tem = XCDR (XCDR (tem));
20355 }
20356 props = oprops;
20357 }
20358
20359 aelt = Fassoc (elt, mode_line_proptrans_alist);
20360 if (! NILP (aelt) && !NILP (Fequal (props, XCDR (aelt))))
20361 {
20362 /* AELT is what we want. Move it to the front
20363 without consing. */
20364 elt = XCAR (aelt);
20365 mode_line_proptrans_alist
20366 = move_elt_to_front (aelt, mode_line_proptrans_alist);
20367 }
20368 else
20369 {
20370 Lisp_Object tem;
20371
20372 /* If AELT has the wrong props, it is useless.
20373 so get rid of it. */
20374 if (! NILP (aelt))
20375 mode_line_proptrans_alist
20376 = Fdelq (aelt, mode_line_proptrans_alist);
20377
20378 elt = Fcopy_sequence (elt);
20379 Fset_text_properties (make_number (0), Flength (elt),
20380 props, elt);
20381 /* Add this item to mode_line_proptrans_alist. */
20382 mode_line_proptrans_alist
20383 = Fcons (Fcons (elt, props),
20384 mode_line_proptrans_alist);
20385 /* Truncate mode_line_proptrans_alist
20386 to at most 50 elements. */
20387 tem = Fnthcdr (make_number (50),
20388 mode_line_proptrans_alist);
20389 if (! NILP (tem))
20390 XSETCDR (tem, Qnil);
20391 }
20392 }
20393 }
20394
20395 offset = 0;
20396
20397 if (literal)
20398 {
20399 prec = precision - n;
20400 switch (mode_line_target)
20401 {
20402 case MODE_LINE_NOPROP:
20403 case MODE_LINE_TITLE:
20404 n += store_mode_line_noprop (SSDATA (elt), -1, prec);
20405 break;
20406 case MODE_LINE_STRING:
20407 n += store_mode_line_string (NULL, elt, 1, 0, prec, Qnil);
20408 break;
20409 case MODE_LINE_DISPLAY:
20410 n += display_string (NULL, elt, Qnil, 0, 0, it,
20411 0, prec, 0, STRING_MULTIBYTE (elt));
20412 break;
20413 }
20414
20415 break;
20416 }
20417
20418 /* Handle the non-literal case. */
20419
20420 while ((precision <= 0 || n < precision)
20421 && SREF (elt, offset) != 0
20422 && (mode_line_target != MODE_LINE_DISPLAY
20423 || it->current_x < it->last_visible_x))
20424 {
20425 ptrdiff_t last_offset = offset;
20426
20427 /* Advance to end of string or next format specifier. */
20428 while ((c = SREF (elt, offset++)) != '\0' && c != '%')
20429 ;
20430
20431 if (offset - 1 != last_offset)
20432 {
20433 ptrdiff_t nchars, nbytes;
20434
20435 /* Output to end of string or up to '%'. Field width
20436 is length of string. Don't output more than
20437 PRECISION allows us. */
20438 offset--;
20439
20440 prec = c_string_width (SDATA (elt) + last_offset,
20441 offset - last_offset, precision - n,
20442 &nchars, &nbytes);
20443
20444 switch (mode_line_target)
20445 {
20446 case MODE_LINE_NOPROP:
20447 case MODE_LINE_TITLE:
20448 n += store_mode_line_noprop (SSDATA (elt) + last_offset, 0, prec);
20449 break;
20450 case MODE_LINE_STRING:
20451 {
20452 ptrdiff_t bytepos = last_offset;
20453 ptrdiff_t charpos = string_byte_to_char (elt, bytepos);
20454 ptrdiff_t endpos = (precision <= 0
20455 ? string_byte_to_char (elt, offset)
20456 : charpos + nchars);
20457
20458 n += store_mode_line_string (NULL,
20459 Fsubstring (elt, make_number (charpos),
20460 make_number (endpos)),
20461 0, 0, 0, Qnil);
20462 }
20463 break;
20464 case MODE_LINE_DISPLAY:
20465 {
20466 ptrdiff_t bytepos = last_offset;
20467 ptrdiff_t charpos = string_byte_to_char (elt, bytepos);
20468
20469 if (precision <= 0)
20470 nchars = string_byte_to_char (elt, offset) - charpos;
20471 n += display_string (NULL, elt, Qnil, 0, charpos,
20472 it, 0, nchars, 0,
20473 STRING_MULTIBYTE (elt));
20474 }
20475 break;
20476 }
20477 }
20478 else /* c == '%' */
20479 {
20480 ptrdiff_t percent_position = offset;
20481
20482 /* Get the specified minimum width. Zero means
20483 don't pad. */
20484 field = 0;
20485 while ((c = SREF (elt, offset++)) >= '0' && c <= '9')
20486 field = field * 10 + c - '0';
20487
20488 /* Don't pad beyond the total padding allowed. */
20489 if (field_width - n > 0 && field > field_width - n)
20490 field = field_width - n;
20491
20492 /* Note that either PRECISION <= 0 or N < PRECISION. */
20493 prec = precision - n;
20494
20495 if (c == 'M')
20496 n += display_mode_element (it, depth, field, prec,
20497 Vglobal_mode_string, props,
20498 risky);
20499 else if (c != 0)
20500 {
20501 int multibyte;
20502 ptrdiff_t bytepos, charpos;
20503 const char *spec;
20504 Lisp_Object string;
20505
20506 bytepos = percent_position;
20507 charpos = (STRING_MULTIBYTE (elt)
20508 ? string_byte_to_char (elt, bytepos)
20509 : bytepos);
20510 spec = decode_mode_spec (it->w, c, field, &string);
20511 multibyte = STRINGP (string) && STRING_MULTIBYTE (string);
20512
20513 switch (mode_line_target)
20514 {
20515 case MODE_LINE_NOPROP:
20516 case MODE_LINE_TITLE:
20517 n += store_mode_line_noprop (spec, field, prec);
20518 break;
20519 case MODE_LINE_STRING:
20520 {
20521 Lisp_Object tem = build_string (spec);
20522 props = Ftext_properties_at (make_number (charpos), elt);
20523 /* Should only keep face property in props */
20524 n += store_mode_line_string (NULL, tem, 0, field, prec, props);
20525 }
20526 break;
20527 case MODE_LINE_DISPLAY:
20528 {
20529 int nglyphs_before, nwritten;
20530
20531 nglyphs_before = it->glyph_row->used[TEXT_AREA];
20532 nwritten = display_string (spec, string, elt,
20533 charpos, 0, it,
20534 field, prec, 0,
20535 multibyte);
20536
20537 /* Assign to the glyphs written above the
20538 string where the `%x' came from, position
20539 of the `%'. */
20540 if (nwritten > 0)
20541 {
20542 struct glyph *glyph
20543 = (it->glyph_row->glyphs[TEXT_AREA]
20544 + nglyphs_before);
20545 int i;
20546
20547 for (i = 0; i < nwritten; ++i)
20548 {
20549 glyph[i].object = elt;
20550 glyph[i].charpos = charpos;
20551 }
20552
20553 n += nwritten;
20554 }
20555 }
20556 break;
20557 }
20558 }
20559 else /* c == 0 */
20560 break;
20561 }
20562 }
20563 }
20564 break;
20565
20566 case Lisp_Symbol:
20567 /* A symbol: process the value of the symbol recursively
20568 as if it appeared here directly. Avoid error if symbol void.
20569 Special case: if value of symbol is a string, output the string
20570 literally. */
20571 {
20572 register Lisp_Object tem;
20573
20574 /* If the variable is not marked as risky to set
20575 then its contents are risky to use. */
20576 if (NILP (Fget (elt, Qrisky_local_variable)))
20577 risky = 1;
20578
20579 tem = Fboundp (elt);
20580 if (!NILP (tem))
20581 {
20582 tem = Fsymbol_value (elt);
20583 /* If value is a string, output that string literally:
20584 don't check for % within it. */
20585 if (STRINGP (tem))
20586 literal = 1;
20587
20588 if (!EQ (tem, elt))
20589 {
20590 /* Give up right away for nil or t. */
20591 elt = tem;
20592 goto tail_recurse;
20593 }
20594 }
20595 }
20596 break;
20597
20598 case Lisp_Cons:
20599 {
20600 register Lisp_Object car, tem;
20601
20602 /* A cons cell: five distinct cases.
20603 If first element is :eval or :propertize, do something special.
20604 If first element is a string or a cons, process all the elements
20605 and effectively concatenate them.
20606 If first element is a negative number, truncate displaying cdr to
20607 at most that many characters. If positive, pad (with spaces)
20608 to at least that many characters.
20609 If first element is a symbol, process the cadr or caddr recursively
20610 according to whether the symbol's value is non-nil or nil. */
20611 car = XCAR (elt);
20612 if (EQ (car, QCeval))
20613 {
20614 /* An element of the form (:eval FORM) means evaluate FORM
20615 and use the result as mode line elements. */
20616
20617 if (risky)
20618 break;
20619
20620 if (CONSP (XCDR (elt)))
20621 {
20622 Lisp_Object spec;
20623 spec = safe_eval (XCAR (XCDR (elt)));
20624 n += display_mode_element (it, depth, field_width - n,
20625 precision - n, spec, props,
20626 risky);
20627 }
20628 }
20629 else if (EQ (car, QCpropertize))
20630 {
20631 /* An element of the form (:propertize ELT PROPS...)
20632 means display ELT but applying properties PROPS. */
20633
20634 if (risky)
20635 break;
20636
20637 if (CONSP (XCDR (elt)))
20638 n += display_mode_element (it, depth, field_width - n,
20639 precision - n, XCAR (XCDR (elt)),
20640 XCDR (XCDR (elt)), risky);
20641 }
20642 else if (SYMBOLP (car))
20643 {
20644 tem = Fboundp (car);
20645 elt = XCDR (elt);
20646 if (!CONSP (elt))
20647 goto invalid;
20648 /* elt is now the cdr, and we know it is a cons cell.
20649 Use its car if CAR has a non-nil value. */
20650 if (!NILP (tem))
20651 {
20652 tem = Fsymbol_value (car);
20653 if (!NILP (tem))
20654 {
20655 elt = XCAR (elt);
20656 goto tail_recurse;
20657 }
20658 }
20659 /* Symbol's value is nil (or symbol is unbound)
20660 Get the cddr of the original list
20661 and if possible find the caddr and use that. */
20662 elt = XCDR (elt);
20663 if (NILP (elt))
20664 break;
20665 else if (!CONSP (elt))
20666 goto invalid;
20667 elt = XCAR (elt);
20668 goto tail_recurse;
20669 }
20670 else if (INTEGERP (car))
20671 {
20672 register int lim = XINT (car);
20673 elt = XCDR (elt);
20674 if (lim < 0)
20675 {
20676 /* Negative int means reduce maximum width. */
20677 if (precision <= 0)
20678 precision = -lim;
20679 else
20680 precision = min (precision, -lim);
20681 }
20682 else if (lim > 0)
20683 {
20684 /* Padding specified. Don't let it be more than
20685 current maximum. */
20686 if (precision > 0)
20687 lim = min (precision, lim);
20688
20689 /* If that's more padding than already wanted, queue it.
20690 But don't reduce padding already specified even if
20691 that is beyond the current truncation point. */
20692 field_width = max (lim, field_width);
20693 }
20694 goto tail_recurse;
20695 }
20696 else if (STRINGP (car) || CONSP (car))
20697 {
20698 Lisp_Object halftail = elt;
20699 int len = 0;
20700
20701 while (CONSP (elt)
20702 && (precision <= 0 || n < precision))
20703 {
20704 n += display_mode_element (it, depth,
20705 /* Do padding only after the last
20706 element in the list. */
20707 (! CONSP (XCDR (elt))
20708 ? field_width - n
20709 : 0),
20710 precision - n, XCAR (elt),
20711 props, risky);
20712 elt = XCDR (elt);
20713 len++;
20714 if ((len & 1) == 0)
20715 halftail = XCDR (halftail);
20716 /* Check for cycle. */
20717 if (EQ (halftail, elt))
20718 break;
20719 }
20720 }
20721 }
20722 break;
20723
20724 default:
20725 invalid:
20726 elt = build_string ("*invalid*");
20727 goto tail_recurse;
20728 }
20729
20730 /* Pad to FIELD_WIDTH. */
20731 if (field_width > 0 && n < field_width)
20732 {
20733 switch (mode_line_target)
20734 {
20735 case MODE_LINE_NOPROP:
20736 case MODE_LINE_TITLE:
20737 n += store_mode_line_noprop ("", field_width - n, 0);
20738 break;
20739 case MODE_LINE_STRING:
20740 n += store_mode_line_string ("", Qnil, 0, field_width - n, 0, Qnil);
20741 break;
20742 case MODE_LINE_DISPLAY:
20743 n += display_string ("", Qnil, Qnil, 0, 0, it, field_width - n,
20744 0, 0, 0);
20745 break;
20746 }
20747 }
20748
20749 return n;
20750 }
20751
20752 /* Store a mode-line string element in mode_line_string_list.
20753
20754 If STRING is non-null, display that C string. Otherwise, the Lisp
20755 string LISP_STRING is displayed.
20756
20757 FIELD_WIDTH is the minimum number of output glyphs to produce.
20758 If STRING has fewer characters than FIELD_WIDTH, pad to the right
20759 with spaces. FIELD_WIDTH <= 0 means don't pad.
20760
20761 PRECISION is the maximum number of characters to output from
20762 STRING. PRECISION <= 0 means don't truncate the string.
20763
20764 If COPY_STRING is non-zero, make a copy of LISP_STRING before adding
20765 properties to the string.
20766
20767 PROPS are the properties to add to the string.
20768 The mode_line_string_face face property is always added to the string.
20769 */
20770
20771 static int
20772 store_mode_line_string (const char *string, Lisp_Object lisp_string, int copy_string,
20773 int field_width, int precision, Lisp_Object props)
20774 {
20775 ptrdiff_t len;
20776 int n = 0;
20777
20778 if (string != NULL)
20779 {
20780 len = strlen (string);
20781 if (precision > 0 && len > precision)
20782 len = precision;
20783 lisp_string = make_string (string, len);
20784 if (NILP (props))
20785 props = mode_line_string_face_prop;
20786 else if (!NILP (mode_line_string_face))
20787 {
20788 Lisp_Object face = Fplist_get (props, Qface);
20789 props = Fcopy_sequence (props);
20790 if (NILP (face))
20791 face = mode_line_string_face;
20792 else
20793 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
20794 props = Fplist_put (props, Qface, face);
20795 }
20796 Fadd_text_properties (make_number (0), make_number (len),
20797 props, lisp_string);
20798 }
20799 else
20800 {
20801 len = XFASTINT (Flength (lisp_string));
20802 if (precision > 0 && len > precision)
20803 {
20804 len = precision;
20805 lisp_string = Fsubstring (lisp_string, make_number (0), make_number (len));
20806 precision = -1;
20807 }
20808 if (!NILP (mode_line_string_face))
20809 {
20810 Lisp_Object face;
20811 if (NILP (props))
20812 props = Ftext_properties_at (make_number (0), lisp_string);
20813 face = Fplist_get (props, Qface);
20814 if (NILP (face))
20815 face = mode_line_string_face;
20816 else
20817 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
20818 props = Fcons (Qface, Fcons (face, Qnil));
20819 if (copy_string)
20820 lisp_string = Fcopy_sequence (lisp_string);
20821 }
20822 if (!NILP (props))
20823 Fadd_text_properties (make_number (0), make_number (len),
20824 props, lisp_string);
20825 }
20826
20827 if (len > 0)
20828 {
20829 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
20830 n += len;
20831 }
20832
20833 if (field_width > len)
20834 {
20835 field_width -= len;
20836 lisp_string = Fmake_string (make_number (field_width), make_number (' '));
20837 if (!NILP (props))
20838 Fadd_text_properties (make_number (0), make_number (field_width),
20839 props, lisp_string);
20840 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
20841 n += field_width;
20842 }
20843
20844 return n;
20845 }
20846
20847
20848 DEFUN ("format-mode-line", Fformat_mode_line, Sformat_mode_line,
20849 1, 4, 0,
20850 doc: /* Format a string out of a mode line format specification.
20851 First arg FORMAT specifies the mode line format (see `mode-line-format'
20852 for details) to use.
20853
20854 By default, the format is evaluated for the currently selected window.
20855
20856 Optional second arg FACE specifies the face property to put on all
20857 characters for which no face is specified. The value nil means the
20858 default face. The value t means whatever face the window's mode line
20859 currently uses (either `mode-line' or `mode-line-inactive',
20860 depending on whether the window is the selected window or not).
20861 An integer value means the value string has no text
20862 properties.
20863
20864 Optional third and fourth args WINDOW and BUFFER specify the window
20865 and buffer to use as the context for the formatting (defaults
20866 are the selected window and the WINDOW's buffer). */)
20867 (Lisp_Object format, Lisp_Object face,
20868 Lisp_Object window, Lisp_Object buffer)
20869 {
20870 struct it it;
20871 int len;
20872 struct window *w;
20873 struct buffer *old_buffer = NULL;
20874 int face_id;
20875 int no_props = INTEGERP (face);
20876 ptrdiff_t count = SPECPDL_INDEX ();
20877 Lisp_Object str;
20878 int string_start = 0;
20879
20880 if (NILP (window))
20881 window = selected_window;
20882 CHECK_WINDOW (window);
20883 w = XWINDOW (window);
20884
20885 if (NILP (buffer))
20886 buffer = w->buffer;
20887 CHECK_BUFFER (buffer);
20888
20889 /* Make formatting the modeline a non-op when noninteractive, otherwise
20890 there will be problems later caused by a partially initialized frame. */
20891 if (NILP (format) || noninteractive)
20892 return empty_unibyte_string;
20893
20894 if (no_props)
20895 face = Qnil;
20896
20897 face_id = (NILP (face) || EQ (face, Qdefault)) ? DEFAULT_FACE_ID
20898 : EQ (face, Qt) ? (EQ (window, selected_window)
20899 ? MODE_LINE_FACE_ID : MODE_LINE_INACTIVE_FACE_ID)
20900 : EQ (face, Qmode_line) ? MODE_LINE_FACE_ID
20901 : EQ (face, Qmode_line_inactive) ? MODE_LINE_INACTIVE_FACE_ID
20902 : EQ (face, Qheader_line) ? HEADER_LINE_FACE_ID
20903 : EQ (face, Qtool_bar) ? TOOL_BAR_FACE_ID
20904 : DEFAULT_FACE_ID;
20905
20906 if (XBUFFER (buffer) != current_buffer)
20907 old_buffer = current_buffer;
20908
20909 /* Save things including mode_line_proptrans_alist,
20910 and set that to nil so that we don't alter the outer value. */
20911 record_unwind_protect (unwind_format_mode_line,
20912 format_mode_line_unwind_data
20913 (old_buffer, selected_window, 1));
20914 mode_line_proptrans_alist = Qnil;
20915
20916 Fselect_window (window, Qt);
20917 if (old_buffer)
20918 set_buffer_internal_1 (XBUFFER (buffer));
20919
20920 init_iterator (&it, w, -1, -1, NULL, face_id);
20921
20922 if (no_props)
20923 {
20924 mode_line_target = MODE_LINE_NOPROP;
20925 mode_line_string_face_prop = Qnil;
20926 mode_line_string_list = Qnil;
20927 string_start = MODE_LINE_NOPROP_LEN (0);
20928 }
20929 else
20930 {
20931 mode_line_target = MODE_LINE_STRING;
20932 mode_line_string_list = Qnil;
20933 mode_line_string_face = face;
20934 mode_line_string_face_prop
20935 = (NILP (face) ? Qnil : Fcons (Qface, Fcons (face, Qnil)));
20936 }
20937
20938 push_kboard (FRAME_KBOARD (it.f));
20939 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
20940 pop_kboard ();
20941
20942 if (no_props)
20943 {
20944 len = MODE_LINE_NOPROP_LEN (string_start);
20945 str = make_string (mode_line_noprop_buf + string_start, len);
20946 }
20947 else
20948 {
20949 mode_line_string_list = Fnreverse (mode_line_string_list);
20950 str = Fmapconcat (intern ("identity"), mode_line_string_list,
20951 empty_unibyte_string);
20952 }
20953
20954 unbind_to (count, Qnil);
20955 return str;
20956 }
20957
20958 /* Write a null-terminated, right justified decimal representation of
20959 the positive integer D to BUF using a minimal field width WIDTH. */
20960
20961 static void
20962 pint2str (register char *buf, register int width, register ptrdiff_t d)
20963 {
20964 register char *p = buf;
20965
20966 if (d <= 0)
20967 *p++ = '0';
20968 else
20969 {
20970 while (d > 0)
20971 {
20972 *p++ = d % 10 + '0';
20973 d /= 10;
20974 }
20975 }
20976
20977 for (width -= (int) (p - buf); width > 0; --width)
20978 *p++ = ' ';
20979 *p-- = '\0';
20980 while (p > buf)
20981 {
20982 d = *buf;
20983 *buf++ = *p;
20984 *p-- = d;
20985 }
20986 }
20987
20988 /* Write a null-terminated, right justified decimal and "human
20989 readable" representation of the nonnegative integer D to BUF using
20990 a minimal field width WIDTH. D should be smaller than 999.5e24. */
20991
20992 static const char power_letter[] =
20993 {
20994 0, /* no letter */
20995 'k', /* kilo */
20996 'M', /* mega */
20997 'G', /* giga */
20998 'T', /* tera */
20999 'P', /* peta */
21000 'E', /* exa */
21001 'Z', /* zetta */
21002 'Y' /* yotta */
21003 };
21004
21005 static void
21006 pint2hrstr (char *buf, int width, ptrdiff_t d)
21007 {
21008 /* We aim to represent the nonnegative integer D as
21009 QUOTIENT.TENTHS * 10 ^ (3 * EXPONENT). */
21010 ptrdiff_t quotient = d;
21011 int remainder = 0;
21012 /* -1 means: do not use TENTHS. */
21013 int tenths = -1;
21014 int exponent = 0;
21015
21016 /* Length of QUOTIENT.TENTHS as a string. */
21017 int length;
21018
21019 char * psuffix;
21020 char * p;
21021
21022 if (1000 <= quotient)
21023 {
21024 /* Scale to the appropriate EXPONENT. */
21025 do
21026 {
21027 remainder = quotient % 1000;
21028 quotient /= 1000;
21029 exponent++;
21030 }
21031 while (1000 <= quotient);
21032
21033 /* Round to nearest and decide whether to use TENTHS or not. */
21034 if (quotient <= 9)
21035 {
21036 tenths = remainder / 100;
21037 if (50 <= remainder % 100)
21038 {
21039 if (tenths < 9)
21040 tenths++;
21041 else
21042 {
21043 quotient++;
21044 if (quotient == 10)
21045 tenths = -1;
21046 else
21047 tenths = 0;
21048 }
21049 }
21050 }
21051 else
21052 if (500 <= remainder)
21053 {
21054 if (quotient < 999)
21055 quotient++;
21056 else
21057 {
21058 quotient = 1;
21059 exponent++;
21060 tenths = 0;
21061 }
21062 }
21063 }
21064
21065 /* Calculate the LENGTH of QUOTIENT.TENTHS as a string. */
21066 if (tenths == -1 && quotient <= 99)
21067 if (quotient <= 9)
21068 length = 1;
21069 else
21070 length = 2;
21071 else
21072 length = 3;
21073 p = psuffix = buf + max (width, length);
21074
21075 /* Print EXPONENT. */
21076 *psuffix++ = power_letter[exponent];
21077 *psuffix = '\0';
21078
21079 /* Print TENTHS. */
21080 if (tenths >= 0)
21081 {
21082 *--p = '0' + tenths;
21083 *--p = '.';
21084 }
21085
21086 /* Print QUOTIENT. */
21087 do
21088 {
21089 int digit = quotient % 10;
21090 *--p = '0' + digit;
21091 }
21092 while ((quotient /= 10) != 0);
21093
21094 /* Print leading spaces. */
21095 while (buf < p)
21096 *--p = ' ';
21097 }
21098
21099 /* Set a mnemonic character for coding_system (Lisp symbol) in BUF.
21100 If EOL_FLAG is 1, set also a mnemonic character for end-of-line
21101 type of CODING_SYSTEM. Return updated pointer into BUF. */
21102
21103 static unsigned char invalid_eol_type[] = "(*invalid*)";
21104
21105 static char *
21106 decode_mode_spec_coding (Lisp_Object coding_system, register char *buf, int eol_flag)
21107 {
21108 Lisp_Object val;
21109 int multibyte = !NILP (BVAR (current_buffer, enable_multibyte_characters));
21110 const unsigned char *eol_str;
21111 int eol_str_len;
21112 /* The EOL conversion we are using. */
21113 Lisp_Object eoltype;
21114
21115 val = CODING_SYSTEM_SPEC (coding_system);
21116 eoltype = Qnil;
21117
21118 if (!VECTORP (val)) /* Not yet decided. */
21119 {
21120 *buf++ = multibyte ? '-' : ' ';
21121 if (eol_flag)
21122 eoltype = eol_mnemonic_undecided;
21123 /* Don't mention EOL conversion if it isn't decided. */
21124 }
21125 else
21126 {
21127 Lisp_Object attrs;
21128 Lisp_Object eolvalue;
21129
21130 attrs = AREF (val, 0);
21131 eolvalue = AREF (val, 2);
21132
21133 *buf++ = multibyte
21134 ? XFASTINT (CODING_ATTR_MNEMONIC (attrs))
21135 : ' ';
21136
21137 if (eol_flag)
21138 {
21139 /* The EOL conversion that is normal on this system. */
21140
21141 if (NILP (eolvalue)) /* Not yet decided. */
21142 eoltype = eol_mnemonic_undecided;
21143 else if (VECTORP (eolvalue)) /* Not yet decided. */
21144 eoltype = eol_mnemonic_undecided;
21145 else /* eolvalue is Qunix, Qdos, or Qmac. */
21146 eoltype = (EQ (eolvalue, Qunix)
21147 ? eol_mnemonic_unix
21148 : (EQ (eolvalue, Qdos) == 1
21149 ? eol_mnemonic_dos : eol_mnemonic_mac));
21150 }
21151 }
21152
21153 if (eol_flag)
21154 {
21155 /* Mention the EOL conversion if it is not the usual one. */
21156 if (STRINGP (eoltype))
21157 {
21158 eol_str = SDATA (eoltype);
21159 eol_str_len = SBYTES (eoltype);
21160 }
21161 else if (CHARACTERP (eoltype))
21162 {
21163 unsigned char *tmp = (unsigned char *) alloca (MAX_MULTIBYTE_LENGTH);
21164 int c = XFASTINT (eoltype);
21165 eol_str_len = CHAR_STRING (c, tmp);
21166 eol_str = tmp;
21167 }
21168 else
21169 {
21170 eol_str = invalid_eol_type;
21171 eol_str_len = sizeof (invalid_eol_type) - 1;
21172 }
21173 memcpy (buf, eol_str, eol_str_len);
21174 buf += eol_str_len;
21175 }
21176
21177 return buf;
21178 }
21179
21180 /* Return a string for the output of a mode line %-spec for window W,
21181 generated by character C. FIELD_WIDTH > 0 means pad the string
21182 returned with spaces to that value. Return a Lisp string in
21183 *STRING if the resulting string is taken from that Lisp string.
21184
21185 Note we operate on the current buffer for most purposes,
21186 the exception being w->base_line_pos. */
21187
21188 static char lots_of_dashes[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
21189
21190 static const char *
21191 decode_mode_spec (struct window *w, register int c, int field_width,
21192 Lisp_Object *string)
21193 {
21194 Lisp_Object obj;
21195 struct frame *f = XFRAME (WINDOW_FRAME (w));
21196 char *decode_mode_spec_buf = f->decode_mode_spec_buffer;
21197 struct buffer *b = current_buffer;
21198
21199 obj = Qnil;
21200 *string = Qnil;
21201
21202 switch (c)
21203 {
21204 case '*':
21205 if (!NILP (BVAR (b, read_only)))
21206 return "%";
21207 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
21208 return "*";
21209 return "-";
21210
21211 case '+':
21212 /* This differs from %* only for a modified read-only buffer. */
21213 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
21214 return "*";
21215 if (!NILP (BVAR (b, read_only)))
21216 return "%";
21217 return "-";
21218
21219 case '&':
21220 /* This differs from %* in ignoring read-only-ness. */
21221 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
21222 return "*";
21223 return "-";
21224
21225 case '%':
21226 return "%";
21227
21228 case '[':
21229 {
21230 int i;
21231 char *p;
21232
21233 if (command_loop_level > 5)
21234 return "[[[... ";
21235 p = decode_mode_spec_buf;
21236 for (i = 0; i < command_loop_level; i++)
21237 *p++ = '[';
21238 *p = 0;
21239 return decode_mode_spec_buf;
21240 }
21241
21242 case ']':
21243 {
21244 int i;
21245 char *p;
21246
21247 if (command_loop_level > 5)
21248 return " ...]]]";
21249 p = decode_mode_spec_buf;
21250 for (i = 0; i < command_loop_level; i++)
21251 *p++ = ']';
21252 *p = 0;
21253 return decode_mode_spec_buf;
21254 }
21255
21256 case '-':
21257 {
21258 register int i;
21259
21260 /* Let lots_of_dashes be a string of infinite length. */
21261 if (mode_line_target == MODE_LINE_NOPROP ||
21262 mode_line_target == MODE_LINE_STRING)
21263 return "--";
21264 if (field_width <= 0
21265 || field_width > sizeof (lots_of_dashes))
21266 {
21267 for (i = 0; i < FRAME_MESSAGE_BUF_SIZE (f) - 1; ++i)
21268 decode_mode_spec_buf[i] = '-';
21269 decode_mode_spec_buf[i] = '\0';
21270 return decode_mode_spec_buf;
21271 }
21272 else
21273 return lots_of_dashes;
21274 }
21275
21276 case 'b':
21277 obj = BVAR (b, name);
21278 break;
21279
21280 case 'c':
21281 /* %c and %l are ignored in `frame-title-format'.
21282 (In redisplay_internal, the frame title is drawn _before_ the
21283 windows are updated, so the stuff which depends on actual
21284 window contents (such as %l) may fail to render properly, or
21285 even crash emacs.) */
21286 if (mode_line_target == MODE_LINE_TITLE)
21287 return "";
21288 else
21289 {
21290 ptrdiff_t col = current_column ();
21291 w->column_number_displayed = make_number (col);
21292 pint2str (decode_mode_spec_buf, field_width, col);
21293 return decode_mode_spec_buf;
21294 }
21295
21296 case 'e':
21297 #ifndef SYSTEM_MALLOC
21298 {
21299 if (NILP (Vmemory_full))
21300 return "";
21301 else
21302 return "!MEM FULL! ";
21303 }
21304 #else
21305 return "";
21306 #endif
21307
21308 case 'F':
21309 /* %F displays the frame name. */
21310 if (!NILP (f->title))
21311 return SSDATA (f->title);
21312 if (f->explicit_name || ! FRAME_WINDOW_P (f))
21313 return SSDATA (f->name);
21314 return "Emacs";
21315
21316 case 'f':
21317 obj = BVAR (b, filename);
21318 break;
21319
21320 case 'i':
21321 {
21322 ptrdiff_t size = ZV - BEGV;
21323 pint2str (decode_mode_spec_buf, field_width, size);
21324 return decode_mode_spec_buf;
21325 }
21326
21327 case 'I':
21328 {
21329 ptrdiff_t size = ZV - BEGV;
21330 pint2hrstr (decode_mode_spec_buf, field_width, size);
21331 return decode_mode_spec_buf;
21332 }
21333
21334 case 'l':
21335 {
21336 ptrdiff_t startpos, startpos_byte, line, linepos, linepos_byte;
21337 ptrdiff_t topline, nlines, height;
21338 ptrdiff_t junk;
21339
21340 /* %c and %l are ignored in `frame-title-format'. */
21341 if (mode_line_target == MODE_LINE_TITLE)
21342 return "";
21343
21344 startpos = XMARKER (w->start)->charpos;
21345 startpos_byte = marker_byte_position (w->start);
21346 height = WINDOW_TOTAL_LINES (w);
21347
21348 /* If we decided that this buffer isn't suitable for line numbers,
21349 don't forget that too fast. */
21350 if (EQ (w->base_line_pos, w->buffer))
21351 goto no_value;
21352 /* But do forget it, if the window shows a different buffer now. */
21353 else if (BUFFERP (w->base_line_pos))
21354 w->base_line_pos = Qnil;
21355
21356 /* If the buffer is very big, don't waste time. */
21357 if (INTEGERP (Vline_number_display_limit)
21358 && BUF_ZV (b) - BUF_BEGV (b) > XINT (Vline_number_display_limit))
21359 {
21360 w->base_line_pos = Qnil;
21361 w->base_line_number = Qnil;
21362 goto no_value;
21363 }
21364
21365 if (INTEGERP (w->base_line_number)
21366 && INTEGERP (w->base_line_pos)
21367 && XFASTINT (w->base_line_pos) <= startpos)
21368 {
21369 line = XFASTINT (w->base_line_number);
21370 linepos = XFASTINT (w->base_line_pos);
21371 linepos_byte = buf_charpos_to_bytepos (b, linepos);
21372 }
21373 else
21374 {
21375 line = 1;
21376 linepos = BUF_BEGV (b);
21377 linepos_byte = BUF_BEGV_BYTE (b);
21378 }
21379
21380 /* Count lines from base line to window start position. */
21381 nlines = display_count_lines (linepos_byte,
21382 startpos_byte,
21383 startpos, &junk);
21384
21385 topline = nlines + line;
21386
21387 /* Determine a new base line, if the old one is too close
21388 or too far away, or if we did not have one.
21389 "Too close" means it's plausible a scroll-down would
21390 go back past it. */
21391 if (startpos == BUF_BEGV (b))
21392 {
21393 w->base_line_number = make_number (topline);
21394 w->base_line_pos = make_number (BUF_BEGV (b));
21395 }
21396 else if (nlines < height + 25 || nlines > height * 3 + 50
21397 || linepos == BUF_BEGV (b))
21398 {
21399 ptrdiff_t limit = BUF_BEGV (b);
21400 ptrdiff_t limit_byte = BUF_BEGV_BYTE (b);
21401 ptrdiff_t position;
21402 ptrdiff_t distance =
21403 (height * 2 + 30) * line_number_display_limit_width;
21404
21405 if (startpos - distance > limit)
21406 {
21407 limit = startpos - distance;
21408 limit_byte = CHAR_TO_BYTE (limit);
21409 }
21410
21411 nlines = display_count_lines (startpos_byte,
21412 limit_byte,
21413 - (height * 2 + 30),
21414 &position);
21415 /* If we couldn't find the lines we wanted within
21416 line_number_display_limit_width chars per line,
21417 give up on line numbers for this window. */
21418 if (position == limit_byte && limit == startpos - distance)
21419 {
21420 w->base_line_pos = w->buffer;
21421 w->base_line_number = Qnil;
21422 goto no_value;
21423 }
21424
21425 w->base_line_number = make_number (topline - nlines);
21426 w->base_line_pos = make_number (BYTE_TO_CHAR (position));
21427 }
21428
21429 /* Now count lines from the start pos to point. */
21430 nlines = display_count_lines (startpos_byte,
21431 PT_BYTE, PT, &junk);
21432
21433 /* Record that we did display the line number. */
21434 line_number_displayed = 1;
21435
21436 /* Make the string to show. */
21437 pint2str (decode_mode_spec_buf, field_width, topline + nlines);
21438 return decode_mode_spec_buf;
21439 no_value:
21440 {
21441 char* p = decode_mode_spec_buf;
21442 int pad = field_width - 2;
21443 while (pad-- > 0)
21444 *p++ = ' ';
21445 *p++ = '?';
21446 *p++ = '?';
21447 *p = '\0';
21448 return decode_mode_spec_buf;
21449 }
21450 }
21451 break;
21452
21453 case 'm':
21454 obj = BVAR (b, mode_name);
21455 break;
21456
21457 case 'n':
21458 if (BUF_BEGV (b) > BUF_BEG (b) || BUF_ZV (b) < BUF_Z (b))
21459 return " Narrow";
21460 break;
21461
21462 case 'p':
21463 {
21464 ptrdiff_t pos = marker_position (w->start);
21465 ptrdiff_t total = BUF_ZV (b) - BUF_BEGV (b);
21466
21467 if (XFASTINT (w->window_end_pos) <= BUF_Z (b) - BUF_ZV (b))
21468 {
21469 if (pos <= BUF_BEGV (b))
21470 return "All";
21471 else
21472 return "Bottom";
21473 }
21474 else if (pos <= BUF_BEGV (b))
21475 return "Top";
21476 else
21477 {
21478 if (total > 1000000)
21479 /* Do it differently for a large value, to avoid overflow. */
21480 total = ((pos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
21481 else
21482 total = ((pos - BUF_BEGV (b)) * 100 + total - 1) / total;
21483 /* We can't normally display a 3-digit number,
21484 so get us a 2-digit number that is close. */
21485 if (total == 100)
21486 total = 99;
21487 sprintf (decode_mode_spec_buf, "%2"pD"d%%", total);
21488 return decode_mode_spec_buf;
21489 }
21490 }
21491
21492 /* Display percentage of size above the bottom of the screen. */
21493 case 'P':
21494 {
21495 ptrdiff_t toppos = marker_position (w->start);
21496 ptrdiff_t botpos = BUF_Z (b) - XFASTINT (w->window_end_pos);
21497 ptrdiff_t total = BUF_ZV (b) - BUF_BEGV (b);
21498
21499 if (botpos >= BUF_ZV (b))
21500 {
21501 if (toppos <= BUF_BEGV (b))
21502 return "All";
21503 else
21504 return "Bottom";
21505 }
21506 else
21507 {
21508 if (total > 1000000)
21509 /* Do it differently for a large value, to avoid overflow. */
21510 total = ((botpos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
21511 else
21512 total = ((botpos - BUF_BEGV (b)) * 100 + total - 1) / total;
21513 /* We can't normally display a 3-digit number,
21514 so get us a 2-digit number that is close. */
21515 if (total == 100)
21516 total = 99;
21517 if (toppos <= BUF_BEGV (b))
21518 sprintf (decode_mode_spec_buf, "Top%2"pD"d%%", total);
21519 else
21520 sprintf (decode_mode_spec_buf, "%2"pD"d%%", total);
21521 return decode_mode_spec_buf;
21522 }
21523 }
21524
21525 case 's':
21526 /* status of process */
21527 obj = Fget_buffer_process (Fcurrent_buffer ());
21528 if (NILP (obj))
21529 return "no process";
21530 #ifndef MSDOS
21531 obj = Fsymbol_name (Fprocess_status (obj));
21532 #endif
21533 break;
21534
21535 case '@':
21536 {
21537 ptrdiff_t count = inhibit_garbage_collection ();
21538 Lisp_Object val = call1 (intern ("file-remote-p"),
21539 BVAR (current_buffer, directory));
21540 unbind_to (count, Qnil);
21541
21542 if (NILP (val))
21543 return "-";
21544 else
21545 return "@";
21546 }
21547
21548 case 't': /* indicate TEXT or BINARY */
21549 return "T";
21550
21551 case 'z':
21552 /* coding-system (not including end-of-line format) */
21553 case 'Z':
21554 /* coding-system (including end-of-line type) */
21555 {
21556 int eol_flag = (c == 'Z');
21557 char *p = decode_mode_spec_buf;
21558
21559 if (! FRAME_WINDOW_P (f))
21560 {
21561 /* No need to mention EOL here--the terminal never needs
21562 to do EOL conversion. */
21563 p = decode_mode_spec_coding (CODING_ID_NAME
21564 (FRAME_KEYBOARD_CODING (f)->id),
21565 p, 0);
21566 p = decode_mode_spec_coding (CODING_ID_NAME
21567 (FRAME_TERMINAL_CODING (f)->id),
21568 p, 0);
21569 }
21570 p = decode_mode_spec_coding (BVAR (b, buffer_file_coding_system),
21571 p, eol_flag);
21572
21573 #if 0 /* This proves to be annoying; I think we can do without. -- rms. */
21574 #ifdef subprocesses
21575 obj = Fget_buffer_process (Fcurrent_buffer ());
21576 if (PROCESSP (obj))
21577 {
21578 p = decode_mode_spec_coding (XPROCESS (obj)->decode_coding_system,
21579 p, eol_flag);
21580 p = decode_mode_spec_coding (XPROCESS (obj)->encode_coding_system,
21581 p, eol_flag);
21582 }
21583 #endif /* subprocesses */
21584 #endif /* 0 */
21585 *p = 0;
21586 return decode_mode_spec_buf;
21587 }
21588 }
21589
21590 if (STRINGP (obj))
21591 {
21592 *string = obj;
21593 return SSDATA (obj);
21594 }
21595 else
21596 return "";
21597 }
21598
21599
21600 /* Count up to COUNT lines starting from START_BYTE.
21601 But don't go beyond LIMIT_BYTE.
21602 Return the number of lines thus found (always nonnegative).
21603
21604 Set *BYTE_POS_PTR to 1 if we found COUNT lines, 0 if we hit LIMIT. */
21605
21606 static ptrdiff_t
21607 display_count_lines (ptrdiff_t start_byte,
21608 ptrdiff_t limit_byte, ptrdiff_t count,
21609 ptrdiff_t *byte_pos_ptr)
21610 {
21611 register unsigned char *cursor;
21612 unsigned char *base;
21613
21614 register ptrdiff_t ceiling;
21615 register unsigned char *ceiling_addr;
21616 ptrdiff_t orig_count = count;
21617
21618 /* If we are not in selective display mode,
21619 check only for newlines. */
21620 int selective_display = (!NILP (BVAR (current_buffer, selective_display))
21621 && !INTEGERP (BVAR (current_buffer, selective_display)));
21622
21623 if (count > 0)
21624 {
21625 while (start_byte < limit_byte)
21626 {
21627 ceiling = BUFFER_CEILING_OF (start_byte);
21628 ceiling = min (limit_byte - 1, ceiling);
21629 ceiling_addr = BYTE_POS_ADDR (ceiling) + 1;
21630 base = (cursor = BYTE_POS_ADDR (start_byte));
21631 while (1)
21632 {
21633 if (selective_display)
21634 while (*cursor != '\n' && *cursor != 015 && ++cursor != ceiling_addr)
21635 ;
21636 else
21637 while (*cursor != '\n' && ++cursor != ceiling_addr)
21638 ;
21639
21640 if (cursor != ceiling_addr)
21641 {
21642 if (--count == 0)
21643 {
21644 start_byte += cursor - base + 1;
21645 *byte_pos_ptr = start_byte;
21646 return orig_count;
21647 }
21648 else
21649 if (++cursor == ceiling_addr)
21650 break;
21651 }
21652 else
21653 break;
21654 }
21655 start_byte += cursor - base;
21656 }
21657 }
21658 else
21659 {
21660 while (start_byte > limit_byte)
21661 {
21662 ceiling = BUFFER_FLOOR_OF (start_byte - 1);
21663 ceiling = max (limit_byte, ceiling);
21664 ceiling_addr = BYTE_POS_ADDR (ceiling) - 1;
21665 base = (cursor = BYTE_POS_ADDR (start_byte - 1) + 1);
21666 while (1)
21667 {
21668 if (selective_display)
21669 while (--cursor != ceiling_addr
21670 && *cursor != '\n' && *cursor != 015)
21671 ;
21672 else
21673 while (--cursor != ceiling_addr && *cursor != '\n')
21674 ;
21675
21676 if (cursor != ceiling_addr)
21677 {
21678 if (++count == 0)
21679 {
21680 start_byte += cursor - base + 1;
21681 *byte_pos_ptr = start_byte;
21682 /* When scanning backwards, we should
21683 not count the newline posterior to which we stop. */
21684 return - orig_count - 1;
21685 }
21686 }
21687 else
21688 break;
21689 }
21690 /* Here we add 1 to compensate for the last decrement
21691 of CURSOR, which took it past the valid range. */
21692 start_byte += cursor - base + 1;
21693 }
21694 }
21695
21696 *byte_pos_ptr = limit_byte;
21697
21698 if (count < 0)
21699 return - orig_count + count;
21700 return orig_count - count;
21701
21702 }
21703
21704
21705 \f
21706 /***********************************************************************
21707 Displaying strings
21708 ***********************************************************************/
21709
21710 /* Display a NUL-terminated string, starting with index START.
21711
21712 If STRING is non-null, display that C string. Otherwise, the Lisp
21713 string LISP_STRING is displayed. There's a case that STRING is
21714 non-null and LISP_STRING is not nil. It means STRING is a string
21715 data of LISP_STRING. In that case, we display LISP_STRING while
21716 ignoring its text properties.
21717
21718 If FACE_STRING is not nil, FACE_STRING_POS is a position in
21719 FACE_STRING. Display STRING or LISP_STRING with the face at
21720 FACE_STRING_POS in FACE_STRING:
21721
21722 Display the string in the environment given by IT, but use the
21723 standard display table, temporarily.
21724
21725 FIELD_WIDTH is the minimum number of output glyphs to produce.
21726 If STRING has fewer characters than FIELD_WIDTH, pad to the right
21727 with spaces. If STRING has more characters, more than FIELD_WIDTH
21728 glyphs will be produced. FIELD_WIDTH <= 0 means don't pad.
21729
21730 PRECISION is the maximum number of characters to output from
21731 STRING. PRECISION < 0 means don't truncate the string.
21732
21733 This is roughly equivalent to printf format specifiers:
21734
21735 FIELD_WIDTH PRECISION PRINTF
21736 ----------------------------------------
21737 -1 -1 %s
21738 -1 10 %.10s
21739 10 -1 %10s
21740 20 10 %20.10s
21741
21742 MULTIBYTE zero means do not display multibyte chars, > 0 means do
21743 display them, and < 0 means obey the current buffer's value of
21744 enable_multibyte_characters.
21745
21746 Value is the number of columns displayed. */
21747
21748 static int
21749 display_string (const char *string, Lisp_Object lisp_string, Lisp_Object face_string,
21750 ptrdiff_t face_string_pos, ptrdiff_t start, struct it *it,
21751 int field_width, int precision, int max_x, int multibyte)
21752 {
21753 int hpos_at_start = it->hpos;
21754 int saved_face_id = it->face_id;
21755 struct glyph_row *row = it->glyph_row;
21756 ptrdiff_t it_charpos;
21757
21758 /* Initialize the iterator IT for iteration over STRING beginning
21759 with index START. */
21760 reseat_to_string (it, NILP (lisp_string) ? string : NULL, lisp_string, start,
21761 precision, field_width, multibyte);
21762 if (string && STRINGP (lisp_string))
21763 /* LISP_STRING is the one returned by decode_mode_spec. We should
21764 ignore its text properties. */
21765 it->stop_charpos = it->end_charpos;
21766
21767 /* If displaying STRING, set up the face of the iterator from
21768 FACE_STRING, if that's given. */
21769 if (STRINGP (face_string))
21770 {
21771 ptrdiff_t endptr;
21772 struct face *face;
21773
21774 it->face_id
21775 = face_at_string_position (it->w, face_string, face_string_pos,
21776 0, it->region_beg_charpos,
21777 it->region_end_charpos,
21778 &endptr, it->base_face_id, 0);
21779 face = FACE_FROM_ID (it->f, it->face_id);
21780 it->face_box_p = face->box != FACE_NO_BOX;
21781 }
21782
21783 /* Set max_x to the maximum allowed X position. Don't let it go
21784 beyond the right edge of the window. */
21785 if (max_x <= 0)
21786 max_x = it->last_visible_x;
21787 else
21788 max_x = min (max_x, it->last_visible_x);
21789
21790 /* Skip over display elements that are not visible. because IT->w is
21791 hscrolled. */
21792 if (it->current_x < it->first_visible_x)
21793 move_it_in_display_line_to (it, 100000, it->first_visible_x,
21794 MOVE_TO_POS | MOVE_TO_X);
21795
21796 row->ascent = it->max_ascent;
21797 row->height = it->max_ascent + it->max_descent;
21798 row->phys_ascent = it->max_phys_ascent;
21799 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
21800 row->extra_line_spacing = it->max_extra_line_spacing;
21801
21802 if (STRINGP (it->string))
21803 it_charpos = IT_STRING_CHARPOS (*it);
21804 else
21805 it_charpos = IT_CHARPOS (*it);
21806
21807 /* This condition is for the case that we are called with current_x
21808 past last_visible_x. */
21809 while (it->current_x < max_x)
21810 {
21811 int x_before, x, n_glyphs_before, i, nglyphs;
21812
21813 /* Get the next display element. */
21814 if (!get_next_display_element (it))
21815 break;
21816
21817 /* Produce glyphs. */
21818 x_before = it->current_x;
21819 n_glyphs_before = row->used[TEXT_AREA];
21820 PRODUCE_GLYPHS (it);
21821
21822 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
21823 i = 0;
21824 x = x_before;
21825 while (i < nglyphs)
21826 {
21827 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
21828
21829 if (it->line_wrap != TRUNCATE
21830 && x + glyph->pixel_width > max_x)
21831 {
21832 /* End of continued line or max_x reached. */
21833 if (CHAR_GLYPH_PADDING_P (*glyph))
21834 {
21835 /* A wide character is unbreakable. */
21836 if (row->reversed_p)
21837 unproduce_glyphs (it, row->used[TEXT_AREA]
21838 - n_glyphs_before);
21839 row->used[TEXT_AREA] = n_glyphs_before;
21840 it->current_x = x_before;
21841 }
21842 else
21843 {
21844 if (row->reversed_p)
21845 unproduce_glyphs (it, row->used[TEXT_AREA]
21846 - (n_glyphs_before + i));
21847 row->used[TEXT_AREA] = n_glyphs_before + i;
21848 it->current_x = x;
21849 }
21850 break;
21851 }
21852 else if (x + glyph->pixel_width >= it->first_visible_x)
21853 {
21854 /* Glyph is at least partially visible. */
21855 ++it->hpos;
21856 if (x < it->first_visible_x)
21857 row->x = x - it->first_visible_x;
21858 }
21859 else
21860 {
21861 /* Glyph is off the left margin of the display area.
21862 Should not happen. */
21863 abort ();
21864 }
21865
21866 row->ascent = max (row->ascent, it->max_ascent);
21867 row->height = max (row->height, it->max_ascent + it->max_descent);
21868 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
21869 row->phys_height = max (row->phys_height,
21870 it->max_phys_ascent + it->max_phys_descent);
21871 row->extra_line_spacing = max (row->extra_line_spacing,
21872 it->max_extra_line_spacing);
21873 x += glyph->pixel_width;
21874 ++i;
21875 }
21876
21877 /* Stop if max_x reached. */
21878 if (i < nglyphs)
21879 break;
21880
21881 /* Stop at line ends. */
21882 if (ITERATOR_AT_END_OF_LINE_P (it))
21883 {
21884 it->continuation_lines_width = 0;
21885 break;
21886 }
21887
21888 set_iterator_to_next (it, 1);
21889 if (STRINGP (it->string))
21890 it_charpos = IT_STRING_CHARPOS (*it);
21891 else
21892 it_charpos = IT_CHARPOS (*it);
21893
21894 /* Stop if truncating at the right edge. */
21895 if (it->line_wrap == TRUNCATE
21896 && it->current_x >= it->last_visible_x)
21897 {
21898 /* Add truncation mark, but don't do it if the line is
21899 truncated at a padding space. */
21900 if (it_charpos < it->string_nchars)
21901 {
21902 if (!FRAME_WINDOW_P (it->f))
21903 {
21904 int ii, n;
21905
21906 if (it->current_x > it->last_visible_x)
21907 {
21908 if (!row->reversed_p)
21909 {
21910 for (ii = row->used[TEXT_AREA] - 1; ii > 0; --ii)
21911 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][ii]))
21912 break;
21913 }
21914 else
21915 {
21916 for (ii = 0; ii < row->used[TEXT_AREA]; ii++)
21917 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][ii]))
21918 break;
21919 unproduce_glyphs (it, ii + 1);
21920 ii = row->used[TEXT_AREA] - (ii + 1);
21921 }
21922 for (n = row->used[TEXT_AREA]; ii < n; ++ii)
21923 {
21924 row->used[TEXT_AREA] = ii;
21925 produce_special_glyphs (it, IT_TRUNCATION);
21926 }
21927 }
21928 produce_special_glyphs (it, IT_TRUNCATION);
21929 }
21930 row->truncated_on_right_p = 1;
21931 }
21932 break;
21933 }
21934 }
21935
21936 /* Maybe insert a truncation at the left. */
21937 if (it->first_visible_x
21938 && it_charpos > 0)
21939 {
21940 if (!FRAME_WINDOW_P (it->f))
21941 insert_left_trunc_glyphs (it);
21942 row->truncated_on_left_p = 1;
21943 }
21944
21945 it->face_id = saved_face_id;
21946
21947 /* Value is number of columns displayed. */
21948 return it->hpos - hpos_at_start;
21949 }
21950
21951
21952 \f
21953 /* This is like a combination of memq and assq. Return 1/2 if PROPVAL
21954 appears as an element of LIST or as the car of an element of LIST.
21955 If PROPVAL is a list, compare each element against LIST in that
21956 way, and return 1/2 if any element of PROPVAL is found in LIST.
21957 Otherwise return 0. This function cannot quit.
21958 The return value is 2 if the text is invisible but with an ellipsis
21959 and 1 if it's invisible and without an ellipsis. */
21960
21961 int
21962 invisible_p (register Lisp_Object propval, Lisp_Object list)
21963 {
21964 register Lisp_Object tail, proptail;
21965
21966 for (tail = list; CONSP (tail); tail = XCDR (tail))
21967 {
21968 register Lisp_Object tem;
21969 tem = XCAR (tail);
21970 if (EQ (propval, tem))
21971 return 1;
21972 if (CONSP (tem) && EQ (propval, XCAR (tem)))
21973 return NILP (XCDR (tem)) ? 1 : 2;
21974 }
21975
21976 if (CONSP (propval))
21977 {
21978 for (proptail = propval; CONSP (proptail); proptail = XCDR (proptail))
21979 {
21980 Lisp_Object propelt;
21981 propelt = XCAR (proptail);
21982 for (tail = list; CONSP (tail); tail = XCDR (tail))
21983 {
21984 register Lisp_Object tem;
21985 tem = XCAR (tail);
21986 if (EQ (propelt, tem))
21987 return 1;
21988 if (CONSP (tem) && EQ (propelt, XCAR (tem)))
21989 return NILP (XCDR (tem)) ? 1 : 2;
21990 }
21991 }
21992 }
21993
21994 return 0;
21995 }
21996
21997 DEFUN ("invisible-p", Finvisible_p, Sinvisible_p, 1, 1, 0,
21998 doc: /* Non-nil if the property makes the text invisible.
21999 POS-OR-PROP can be a marker or number, in which case it is taken to be
22000 a position in the current buffer and the value of the `invisible' property
22001 is checked; or it can be some other value, which is then presumed to be the
22002 value of the `invisible' property of the text of interest.
22003 The non-nil value returned can be t for truly invisible text or something
22004 else if the text is replaced by an ellipsis. */)
22005 (Lisp_Object pos_or_prop)
22006 {
22007 Lisp_Object prop
22008 = (NATNUMP (pos_or_prop) || MARKERP (pos_or_prop)
22009 ? Fget_char_property (pos_or_prop, Qinvisible, Qnil)
22010 : pos_or_prop);
22011 int invis = TEXT_PROP_MEANS_INVISIBLE (prop);
22012 return (invis == 0 ? Qnil
22013 : invis == 1 ? Qt
22014 : make_number (invis));
22015 }
22016
22017 /* Calculate a width or height in pixels from a specification using
22018 the following elements:
22019
22020 SPEC ::=
22021 NUM - a (fractional) multiple of the default font width/height
22022 (NUM) - specifies exactly NUM pixels
22023 UNIT - a fixed number of pixels, see below.
22024 ELEMENT - size of a display element in pixels, see below.
22025 (NUM . SPEC) - equals NUM * SPEC
22026 (+ SPEC SPEC ...) - add pixel values
22027 (- SPEC SPEC ...) - subtract pixel values
22028 (- SPEC) - negate pixel value
22029
22030 NUM ::=
22031 INT or FLOAT - a number constant
22032 SYMBOL - use symbol's (buffer local) variable binding.
22033
22034 UNIT ::=
22035 in - pixels per inch *)
22036 mm - pixels per 1/1000 meter *)
22037 cm - pixels per 1/100 meter *)
22038 width - width of current font in pixels.
22039 height - height of current font in pixels.
22040
22041 *) using the ratio(s) defined in display-pixels-per-inch.
22042
22043 ELEMENT ::=
22044
22045 left-fringe - left fringe width in pixels
22046 right-fringe - right fringe width in pixels
22047
22048 left-margin - left margin width in pixels
22049 right-margin - right margin width in pixels
22050
22051 scroll-bar - scroll-bar area width in pixels
22052
22053 Examples:
22054
22055 Pixels corresponding to 5 inches:
22056 (5 . in)
22057
22058 Total width of non-text areas on left side of window (if scroll-bar is on left):
22059 '(space :width (+ left-fringe left-margin scroll-bar))
22060
22061 Align to first text column (in header line):
22062 '(space :align-to 0)
22063
22064 Align to middle of text area minus half the width of variable `my-image'
22065 containing a loaded image:
22066 '(space :align-to (0.5 . (- text my-image)))
22067
22068 Width of left margin minus width of 1 character in the default font:
22069 '(space :width (- left-margin 1))
22070
22071 Width of left margin minus width of 2 characters in the current font:
22072 '(space :width (- left-margin (2 . width)))
22073
22074 Center 1 character over left-margin (in header line):
22075 '(space :align-to (+ left-margin (0.5 . left-margin) -0.5))
22076
22077 Different ways to express width of left fringe plus left margin minus one pixel:
22078 '(space :width (- (+ left-fringe left-margin) (1)))
22079 '(space :width (+ left-fringe left-margin (- (1))))
22080 '(space :width (+ left-fringe left-margin (-1)))
22081
22082 */
22083
22084 #define NUMVAL(X) \
22085 ((INTEGERP (X) || FLOATP (X)) \
22086 ? XFLOATINT (X) \
22087 : - 1)
22088
22089 static int
22090 calc_pixel_width_or_height (double *res, struct it *it, Lisp_Object prop,
22091 struct font *font, int width_p, int *align_to)
22092 {
22093 double pixels;
22094
22095 #define OK_PIXELS(val) ((*res = (double)(val)), 1)
22096 #define OK_ALIGN_TO(val) ((*align_to = (int)(val)), 1)
22097
22098 if (NILP (prop))
22099 return OK_PIXELS (0);
22100
22101 xassert (FRAME_LIVE_P (it->f));
22102
22103 if (SYMBOLP (prop))
22104 {
22105 if (SCHARS (SYMBOL_NAME (prop)) == 2)
22106 {
22107 char *unit = SSDATA (SYMBOL_NAME (prop));
22108
22109 if (unit[0] == 'i' && unit[1] == 'n')
22110 pixels = 1.0;
22111 else if (unit[0] == 'm' && unit[1] == 'm')
22112 pixels = 25.4;
22113 else if (unit[0] == 'c' && unit[1] == 'm')
22114 pixels = 2.54;
22115 else
22116 pixels = 0;
22117 if (pixels > 0)
22118 {
22119 double ppi;
22120 #ifdef HAVE_WINDOW_SYSTEM
22121 if (FRAME_WINDOW_P (it->f)
22122 && (ppi = (width_p
22123 ? FRAME_X_DISPLAY_INFO (it->f)->resx
22124 : FRAME_X_DISPLAY_INFO (it->f)->resy),
22125 ppi > 0))
22126 return OK_PIXELS (ppi / pixels);
22127 #endif
22128
22129 if ((ppi = NUMVAL (Vdisplay_pixels_per_inch), ppi > 0)
22130 || (CONSP (Vdisplay_pixels_per_inch)
22131 && (ppi = (width_p
22132 ? NUMVAL (XCAR (Vdisplay_pixels_per_inch))
22133 : NUMVAL (XCDR (Vdisplay_pixels_per_inch))),
22134 ppi > 0)))
22135 return OK_PIXELS (ppi / pixels);
22136
22137 return 0;
22138 }
22139 }
22140
22141 #ifdef HAVE_WINDOW_SYSTEM
22142 if (EQ (prop, Qheight))
22143 return OK_PIXELS (font ? FONT_HEIGHT (font) : FRAME_LINE_HEIGHT (it->f));
22144 if (EQ (prop, Qwidth))
22145 return OK_PIXELS (font ? FONT_WIDTH (font) : FRAME_COLUMN_WIDTH (it->f));
22146 #else
22147 if (EQ (prop, Qheight) || EQ (prop, Qwidth))
22148 return OK_PIXELS (1);
22149 #endif
22150
22151 if (EQ (prop, Qtext))
22152 return OK_PIXELS (width_p
22153 ? window_box_width (it->w, TEXT_AREA)
22154 : WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w));
22155
22156 if (align_to && *align_to < 0)
22157 {
22158 *res = 0;
22159 if (EQ (prop, Qleft))
22160 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA));
22161 if (EQ (prop, Qright))
22162 return OK_ALIGN_TO (window_box_right_offset (it->w, TEXT_AREA));
22163 if (EQ (prop, Qcenter))
22164 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA)
22165 + window_box_width (it->w, TEXT_AREA) / 2);
22166 if (EQ (prop, Qleft_fringe))
22167 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
22168 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (it->w)
22169 : window_box_right_offset (it->w, LEFT_MARGIN_AREA));
22170 if (EQ (prop, Qright_fringe))
22171 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
22172 ? window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
22173 : window_box_right_offset (it->w, TEXT_AREA));
22174 if (EQ (prop, Qleft_margin))
22175 return OK_ALIGN_TO (window_box_left_offset (it->w, LEFT_MARGIN_AREA));
22176 if (EQ (prop, Qright_margin))
22177 return OK_ALIGN_TO (window_box_left_offset (it->w, RIGHT_MARGIN_AREA));
22178 if (EQ (prop, Qscroll_bar))
22179 return OK_ALIGN_TO (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (it->w)
22180 ? 0
22181 : (window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
22182 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
22183 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
22184 : 0)));
22185 }
22186 else
22187 {
22188 if (EQ (prop, Qleft_fringe))
22189 return OK_PIXELS (WINDOW_LEFT_FRINGE_WIDTH (it->w));
22190 if (EQ (prop, Qright_fringe))
22191 return OK_PIXELS (WINDOW_RIGHT_FRINGE_WIDTH (it->w));
22192 if (EQ (prop, Qleft_margin))
22193 return OK_PIXELS (WINDOW_LEFT_MARGIN_WIDTH (it->w));
22194 if (EQ (prop, Qright_margin))
22195 return OK_PIXELS (WINDOW_RIGHT_MARGIN_WIDTH (it->w));
22196 if (EQ (prop, Qscroll_bar))
22197 return OK_PIXELS (WINDOW_SCROLL_BAR_AREA_WIDTH (it->w));
22198 }
22199
22200 prop = buffer_local_value_1 (prop, it->w->buffer);
22201 if (EQ (prop, Qunbound))
22202 prop = Qnil;
22203 }
22204
22205 if (INTEGERP (prop) || FLOATP (prop))
22206 {
22207 int base_unit = (width_p
22208 ? FRAME_COLUMN_WIDTH (it->f)
22209 : FRAME_LINE_HEIGHT (it->f));
22210 return OK_PIXELS (XFLOATINT (prop) * base_unit);
22211 }
22212
22213 if (CONSP (prop))
22214 {
22215 Lisp_Object car = XCAR (prop);
22216 Lisp_Object cdr = XCDR (prop);
22217
22218 if (SYMBOLP (car))
22219 {
22220 #ifdef HAVE_WINDOW_SYSTEM
22221 if (FRAME_WINDOW_P (it->f)
22222 && valid_image_p (prop))
22223 {
22224 ptrdiff_t id = lookup_image (it->f, prop);
22225 struct image *img = IMAGE_FROM_ID (it->f, id);
22226
22227 return OK_PIXELS (width_p ? img->width : img->height);
22228 }
22229 #ifdef HAVE_XWIDGETS
22230 if (FRAME_WINDOW_P (it->f) && valid_xwidget_p (prop))
22231 {
22232 printf("calc_pixel_width_or_height: return dummy size FIXME\n");
22233 return OK_PIXELS (width_p ? 100 : 100);
22234 }
22235 #endif
22236 #endif
22237 if (EQ (car, Qplus) || EQ (car, Qminus))
22238 {
22239 int first = 1;
22240 double px;
22241
22242 pixels = 0;
22243 while (CONSP (cdr))
22244 {
22245 if (!calc_pixel_width_or_height (&px, it, XCAR (cdr),
22246 font, width_p, align_to))
22247 return 0;
22248 if (first)
22249 pixels = (EQ (car, Qplus) ? px : -px), first = 0;
22250 else
22251 pixels += px;
22252 cdr = XCDR (cdr);
22253 }
22254 if (EQ (car, Qminus))
22255 pixels = -pixels;
22256 return OK_PIXELS (pixels);
22257 }
22258
22259 car = buffer_local_value_1 (car, it->w->buffer);
22260 if (EQ (car, Qunbound))
22261 car = Qnil;
22262 }
22263
22264 if (INTEGERP (car) || FLOATP (car))
22265 {
22266 double fact;
22267 pixels = XFLOATINT (car);
22268 if (NILP (cdr))
22269 return OK_PIXELS (pixels);
22270 if (calc_pixel_width_or_height (&fact, it, cdr,
22271 font, width_p, align_to))
22272 return OK_PIXELS (pixels * fact);
22273 return 0;
22274 }
22275
22276 return 0;
22277 }
22278
22279 return 0;
22280 }
22281
22282 \f
22283 /***********************************************************************
22284 Glyph Display
22285 ***********************************************************************/
22286
22287 #ifdef HAVE_WINDOW_SYSTEM
22288
22289 #if GLYPH_DEBUG
22290
22291 void
22292 dump_glyph_string (struct glyph_string *s)
22293 {
22294 fprintf (stderr, "glyph string\n");
22295 fprintf (stderr, " x, y, w, h = %d, %d, %d, %d\n",
22296 s->x, s->y, s->width, s->height);
22297 fprintf (stderr, " ybase = %d\n", s->ybase);
22298 fprintf (stderr, " hl = %d\n", s->hl);
22299 fprintf (stderr, " left overhang = %d, right = %d\n",
22300 s->left_overhang, s->right_overhang);
22301 fprintf (stderr, " nchars = %d\n", s->nchars);
22302 fprintf (stderr, " extends to end of line = %d\n",
22303 s->extends_to_end_of_line_p);
22304 fprintf (stderr, " font height = %d\n", FONT_HEIGHT (s->font));
22305 fprintf (stderr, " bg width = %d\n", s->background_width);
22306 }
22307
22308 #endif /* GLYPH_DEBUG */
22309
22310 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
22311 of XChar2b structures for S; it can't be allocated in
22312 init_glyph_string because it must be allocated via `alloca'. W
22313 is the window on which S is drawn. ROW and AREA are the glyph row
22314 and area within the row from which S is constructed. START is the
22315 index of the first glyph structure covered by S. HL is a
22316 face-override for drawing S. */
22317
22318 #ifdef HAVE_NTGUI
22319 #define OPTIONAL_HDC(hdc) HDC hdc,
22320 #define DECLARE_HDC(hdc) HDC hdc;
22321 #define ALLOCATE_HDC(hdc, f) hdc = get_frame_dc ((f))
22322 #define RELEASE_HDC(hdc, f) release_frame_dc ((f), (hdc))
22323 #endif
22324
22325 #ifndef OPTIONAL_HDC
22326 #define OPTIONAL_HDC(hdc)
22327 #define DECLARE_HDC(hdc)
22328 #define ALLOCATE_HDC(hdc, f)
22329 #define RELEASE_HDC(hdc, f)
22330 #endif
22331
22332 static void
22333 init_glyph_string (struct glyph_string *s,
22334 OPTIONAL_HDC (hdc)
22335 XChar2b *char2b, struct window *w, struct glyph_row *row,
22336 enum glyph_row_area area, int start, enum draw_glyphs_face hl)
22337 {
22338 memset (s, 0, sizeof *s);
22339 s->w = w;
22340 s->f = XFRAME (w->frame);
22341 #ifdef HAVE_NTGUI
22342 s->hdc = hdc;
22343 #endif
22344 s->display = FRAME_X_DISPLAY (s->f);
22345 s->window = FRAME_X_WINDOW (s->f);
22346 s->char2b = char2b;
22347 s->hl = hl;
22348 s->row = row;
22349 s->area = area;
22350 s->first_glyph = row->glyphs[area] + start;
22351 s->height = row->height;
22352 s->y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
22353 s->ybase = s->y + row->ascent;
22354 }
22355
22356
22357 /* Append the list of glyph strings with head H and tail T to the list
22358 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
22359
22360 static inline void
22361 append_glyph_string_lists (struct glyph_string **head, struct glyph_string **tail,
22362 struct glyph_string *h, struct glyph_string *t)
22363 {
22364 if (h)
22365 {
22366 if (*head)
22367 (*tail)->next = h;
22368 else
22369 *head = h;
22370 h->prev = *tail;
22371 *tail = t;
22372 }
22373 }
22374
22375
22376 /* Prepend the list of glyph strings with head H and tail T to the
22377 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
22378 result. */
22379
22380 static inline void
22381 prepend_glyph_string_lists (struct glyph_string **head, struct glyph_string **tail,
22382 struct glyph_string *h, struct glyph_string *t)
22383 {
22384 if (h)
22385 {
22386 if (*head)
22387 (*head)->prev = t;
22388 else
22389 *tail = t;
22390 t->next = *head;
22391 *head = h;
22392 }
22393 }
22394
22395
22396 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
22397 Set *HEAD and *TAIL to the resulting list. */
22398
22399 static inline void
22400 append_glyph_string (struct glyph_string **head, struct glyph_string **tail,
22401 struct glyph_string *s)
22402 {
22403 s->next = s->prev = NULL;
22404 append_glyph_string_lists (head, tail, s, s);
22405 }
22406
22407
22408 /* Get face and two-byte form of character C in face FACE_ID on frame F.
22409 The encoding of C is returned in *CHAR2B. DISPLAY_P non-zero means
22410 make sure that X resources for the face returned are allocated.
22411 Value is a pointer to a realized face that is ready for display if
22412 DISPLAY_P is non-zero. */
22413
22414 static inline struct face *
22415 get_char_face_and_encoding (struct frame *f, int c, int face_id,
22416 XChar2b *char2b, int display_p)
22417 {
22418 struct face *face = FACE_FROM_ID (f, face_id);
22419
22420 if (face->font)
22421 {
22422 unsigned code = face->font->driver->encode_char (face->font, c);
22423
22424 if (code != FONT_INVALID_CODE)
22425 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
22426 else
22427 STORE_XCHAR2B (char2b, 0, 0);
22428 }
22429
22430 /* Make sure X resources of the face are allocated. */
22431 #ifdef HAVE_X_WINDOWS
22432 if (display_p)
22433 #endif
22434 {
22435 xassert (face != NULL);
22436 PREPARE_FACE_FOR_DISPLAY (f, face);
22437 }
22438
22439 return face;
22440 }
22441
22442
22443 /* Get face and two-byte form of character glyph GLYPH on frame F.
22444 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
22445 a pointer to a realized face that is ready for display. */
22446
22447 static inline struct face *
22448 get_glyph_face_and_encoding (struct frame *f, struct glyph *glyph,
22449 XChar2b *char2b, int *two_byte_p)
22450 {
22451 struct face *face;
22452
22453 xassert (glyph->type == CHAR_GLYPH);
22454 face = FACE_FROM_ID (f, glyph->face_id);
22455
22456 if (two_byte_p)
22457 *two_byte_p = 0;
22458
22459 if (face->font)
22460 {
22461 unsigned code;
22462
22463 if (CHAR_BYTE8_P (glyph->u.ch))
22464 code = CHAR_TO_BYTE8 (glyph->u.ch);
22465 else
22466 code = face->font->driver->encode_char (face->font, glyph->u.ch);
22467
22468 if (code != FONT_INVALID_CODE)
22469 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
22470 else
22471 STORE_XCHAR2B (char2b, 0, 0);
22472 }
22473
22474 /* Make sure X resources of the face are allocated. */
22475 xassert (face != NULL);
22476 PREPARE_FACE_FOR_DISPLAY (f, face);
22477 return face;
22478 }
22479
22480
22481 /* Get glyph code of character C in FONT in the two-byte form CHAR2B.
22482 Return 1 if FONT has a glyph for C, otherwise return 0. */
22483
22484 static inline int
22485 get_char_glyph_code (int c, struct font *font, XChar2b *char2b)
22486 {
22487 unsigned code;
22488
22489 if (CHAR_BYTE8_P (c))
22490 code = CHAR_TO_BYTE8 (c);
22491 else
22492 code = font->driver->encode_char (font, c);
22493
22494 if (code == FONT_INVALID_CODE)
22495 return 0;
22496 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
22497 return 1;
22498 }
22499
22500
22501 /* Fill glyph string S with composition components specified by S->cmp.
22502
22503 BASE_FACE is the base face of the composition.
22504 S->cmp_from is the index of the first component for S.
22505
22506 OVERLAPS non-zero means S should draw the foreground only, and use
22507 its physical height for clipping. See also draw_glyphs.
22508
22509 Value is the index of a component not in S. */
22510
22511 static int
22512 fill_composite_glyph_string (struct glyph_string *s, struct face *base_face,
22513 int overlaps)
22514 {
22515 int i;
22516 /* For all glyphs of this composition, starting at the offset
22517 S->cmp_from, until we reach the end of the definition or encounter a
22518 glyph that requires the different face, add it to S. */
22519 struct face *face;
22520
22521 xassert (s);
22522
22523 s->for_overlaps = overlaps;
22524 s->face = NULL;
22525 s->font = NULL;
22526 for (i = s->cmp_from; i < s->cmp->glyph_len; i++)
22527 {
22528 int c = COMPOSITION_GLYPH (s->cmp, i);
22529
22530 /* TAB in a composition means display glyphs with padding space
22531 on the left or right. */
22532 if (c != '\t')
22533 {
22534 int face_id = FACE_FOR_CHAR (s->f, base_face->ascii_face, c,
22535 -1, Qnil);
22536
22537 face = get_char_face_and_encoding (s->f, c, face_id,
22538 s->char2b + i, 1);
22539 if (face)
22540 {
22541 if (! s->face)
22542 {
22543 s->face = face;
22544 s->font = s->face->font;
22545 }
22546 else if (s->face != face)
22547 break;
22548 }
22549 }
22550 ++s->nchars;
22551 }
22552 s->cmp_to = i;
22553
22554 if (s->face == NULL)
22555 {
22556 s->face = base_face->ascii_face;
22557 s->font = s->face->font;
22558 }
22559
22560 /* All glyph strings for the same composition has the same width,
22561 i.e. the width set for the first component of the composition. */
22562 s->width = s->first_glyph->pixel_width;
22563
22564 /* If the specified font could not be loaded, use the frame's
22565 default font, but record the fact that we couldn't load it in
22566 the glyph string so that we can draw rectangles for the
22567 characters of the glyph string. */
22568 if (s->font == NULL)
22569 {
22570 s->font_not_found_p = 1;
22571 s->font = FRAME_FONT (s->f);
22572 }
22573
22574 /* Adjust base line for subscript/superscript text. */
22575 s->ybase += s->first_glyph->voffset;
22576
22577 /* This glyph string must always be drawn with 16-bit functions. */
22578 s->two_byte_p = 1;
22579
22580 return s->cmp_to;
22581 }
22582
22583 static int
22584 fill_gstring_glyph_string (struct glyph_string *s, int face_id,
22585 int start, int end, int overlaps)
22586 {
22587 struct glyph *glyph, *last;
22588 Lisp_Object lgstring;
22589 int i;
22590
22591 s->for_overlaps = overlaps;
22592 glyph = s->row->glyphs[s->area] + start;
22593 last = s->row->glyphs[s->area] + end;
22594 s->cmp_id = glyph->u.cmp.id;
22595 s->cmp_from = glyph->slice.cmp.from;
22596 s->cmp_to = glyph->slice.cmp.to + 1;
22597 s->face = FACE_FROM_ID (s->f, face_id);
22598 lgstring = composition_gstring_from_id (s->cmp_id);
22599 s->font = XFONT_OBJECT (LGSTRING_FONT (lgstring));
22600 glyph++;
22601 while (glyph < last
22602 && glyph->u.cmp.automatic
22603 && glyph->u.cmp.id == s->cmp_id
22604 && s->cmp_to == glyph->slice.cmp.from)
22605 s->cmp_to = (glyph++)->slice.cmp.to + 1;
22606
22607 for (i = s->cmp_from; i < s->cmp_to; i++)
22608 {
22609 Lisp_Object lglyph = LGSTRING_GLYPH (lgstring, i);
22610 unsigned code = LGLYPH_CODE (lglyph);
22611
22612 STORE_XCHAR2B ((s->char2b + i), code >> 8, code & 0xFF);
22613 }
22614 s->width = composition_gstring_width (lgstring, s->cmp_from, s->cmp_to, NULL);
22615 return glyph - s->row->glyphs[s->area];
22616 }
22617
22618
22619 /* Fill glyph string S from a sequence glyphs for glyphless characters.
22620 See the comment of fill_glyph_string for arguments.
22621 Value is the index of the first glyph not in S. */
22622
22623
22624 static int
22625 fill_glyphless_glyph_string (struct glyph_string *s, int face_id,
22626 int start, int end, int overlaps)
22627 {
22628 struct glyph *glyph, *last;
22629 int voffset;
22630
22631 xassert (s->first_glyph->type == GLYPHLESS_GLYPH);
22632 s->for_overlaps = overlaps;
22633 glyph = s->row->glyphs[s->area] + start;
22634 last = s->row->glyphs[s->area] + end;
22635 voffset = glyph->voffset;
22636 s->face = FACE_FROM_ID (s->f, face_id);
22637 s->font = s->face->font;
22638 s->nchars = 1;
22639 s->width = glyph->pixel_width;
22640 glyph++;
22641 while (glyph < last
22642 && glyph->type == GLYPHLESS_GLYPH
22643 && glyph->voffset == voffset
22644 && glyph->face_id == face_id)
22645 {
22646 s->nchars++;
22647 s->width += glyph->pixel_width;
22648 glyph++;
22649 }
22650 s->ybase += voffset;
22651 return glyph - s->row->glyphs[s->area];
22652 }
22653
22654
22655 /* Fill glyph string S from a sequence of character glyphs.
22656
22657 FACE_ID is the face id of the string. START is the index of the
22658 first glyph to consider, END is the index of the last + 1.
22659 OVERLAPS non-zero means S should draw the foreground only, and use
22660 its physical height for clipping. See also draw_glyphs.
22661
22662 Value is the index of the first glyph not in S. */
22663
22664 static int
22665 fill_glyph_string (struct glyph_string *s, int face_id,
22666 int start, int end, int overlaps)
22667 {
22668 struct glyph *glyph, *last;
22669 int voffset;
22670 int glyph_not_available_p;
22671
22672 xassert (s->f == XFRAME (s->w->frame));
22673 xassert (s->nchars == 0);
22674 xassert (start >= 0 && end > start);
22675
22676 s->for_overlaps = overlaps;
22677 glyph = s->row->glyphs[s->area] + start;
22678 last = s->row->glyphs[s->area] + end;
22679 voffset = glyph->voffset;
22680 s->padding_p = glyph->padding_p;
22681 glyph_not_available_p = glyph->glyph_not_available_p;
22682
22683 while (glyph < last
22684 && glyph->type == CHAR_GLYPH
22685 && glyph->voffset == voffset
22686 /* Same face id implies same font, nowadays. */
22687 && glyph->face_id == face_id
22688 && glyph->glyph_not_available_p == glyph_not_available_p)
22689 {
22690 int two_byte_p;
22691
22692 s->face = get_glyph_face_and_encoding (s->f, glyph,
22693 s->char2b + s->nchars,
22694 &two_byte_p);
22695 s->two_byte_p = two_byte_p;
22696 ++s->nchars;
22697 xassert (s->nchars <= end - start);
22698 s->width += glyph->pixel_width;
22699 if (glyph++->padding_p != s->padding_p)
22700 break;
22701 }
22702
22703 s->font = s->face->font;
22704
22705 /* If the specified font could not be loaded, use the frame's font,
22706 but record the fact that we couldn't load it in
22707 S->font_not_found_p so that we can draw rectangles for the
22708 characters of the glyph string. */
22709 if (s->font == NULL || glyph_not_available_p)
22710 {
22711 s->font_not_found_p = 1;
22712 s->font = FRAME_FONT (s->f);
22713 }
22714
22715 /* Adjust base line for subscript/superscript text. */
22716 s->ybase += voffset;
22717
22718 xassert (s->face && s->face->gc);
22719 return glyph - s->row->glyphs[s->area];
22720 }
22721
22722
22723 /* Fill glyph string S from image glyph S->first_glyph. */
22724
22725 static void
22726 fill_image_glyph_string (struct glyph_string *s)
22727 {
22728 xassert (s->first_glyph->type == IMAGE_GLYPH);
22729 s->img = IMAGE_FROM_ID (s->f, s->first_glyph->u.img_id);
22730 xassert (s->img);
22731 s->slice = s->first_glyph->slice.img;
22732 s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
22733 s->font = s->face->font;
22734 s->width = s->first_glyph->pixel_width;
22735
22736 /* Adjust base line for subscript/superscript text. */
22737 s->ybase += s->first_glyph->voffset;
22738 }
22739
22740 #ifdef HAVE_XWIDGETS
22741 static void
22742 fill_xwidget_glyph_string (struct glyph_string *s)
22743 {
22744 xassert (s->first_glyph->type == XWIDGET_GLYPH);
22745 printf("fill_xwidget_glyph_string: width:%d \n",s->first_glyph->pixel_width);
22746 s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
22747 s->font = s->face->font;
22748 s->width = s->first_glyph->pixel_width;
22749 s->ybase += s->first_glyph->voffset;
22750 s->xwidget = s->first_glyph->u.xwidget;
22751 //assert_valid_xwidget_id ( s->xwidget, "fill_xwidget_glyph_string");
22752 }
22753 #endif
22754 /* Fill glyph string S from a sequence of stretch glyphs.
22755
22756 START is the index of the first glyph to consider,
22757 END is the index of the last + 1.
22758
22759 Value is the index of the first glyph not in S. */
22760
22761 static int
22762 fill_stretch_glyph_string (struct glyph_string *s, int start, int end)
22763 {
22764 struct glyph *glyph, *last;
22765 int voffset, face_id;
22766
22767 xassert (s->first_glyph->type == STRETCH_GLYPH);
22768
22769 glyph = s->row->glyphs[s->area] + start;
22770 last = s->row->glyphs[s->area] + end;
22771 face_id = glyph->face_id;
22772 s->face = FACE_FROM_ID (s->f, face_id);
22773 s->font = s->face->font;
22774 s->width = glyph->pixel_width;
22775 s->nchars = 1;
22776 voffset = glyph->voffset;
22777
22778 for (++glyph;
22779 (glyph < last
22780 && glyph->type == STRETCH_GLYPH
22781 && glyph->voffset == voffset
22782 && glyph->face_id == face_id);
22783 ++glyph)
22784 s->width += glyph->pixel_width;
22785
22786 /* Adjust base line for subscript/superscript text. */
22787 s->ybase += voffset;
22788
22789 /* The case that face->gc == 0 is handled when drawing the glyph
22790 string by calling PREPARE_FACE_FOR_DISPLAY. */
22791 xassert (s->face);
22792 return glyph - s->row->glyphs[s->area];
22793 }
22794
22795 static struct font_metrics *
22796 get_per_char_metric (struct font *font, XChar2b *char2b)
22797 {
22798 static struct font_metrics metrics;
22799 unsigned code = (XCHAR2B_BYTE1 (char2b) << 8) | XCHAR2B_BYTE2 (char2b);
22800
22801 if (! font || code == FONT_INVALID_CODE)
22802 return NULL;
22803 font->driver->text_extents (font, &code, 1, &metrics);
22804 return &metrics;
22805 }
22806
22807 /* EXPORT for RIF:
22808 Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
22809 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
22810 assumed to be zero. */
22811
22812 void
22813 x_get_glyph_overhangs (struct glyph *glyph, struct frame *f, int *left, int *right)
22814 {
22815 *left = *right = 0;
22816
22817 if (glyph->type == CHAR_GLYPH)
22818 {
22819 struct face *face;
22820 XChar2b char2b;
22821 struct font_metrics *pcm;
22822
22823 face = get_glyph_face_and_encoding (f, glyph, &char2b, NULL);
22824 if (face->font && (pcm = get_per_char_metric (face->font, &char2b)))
22825 {
22826 if (pcm->rbearing > pcm->width)
22827 *right = pcm->rbearing - pcm->width;
22828 if (pcm->lbearing < 0)
22829 *left = -pcm->lbearing;
22830 }
22831 }
22832 else if (glyph->type == COMPOSITE_GLYPH)
22833 {
22834 if (! glyph->u.cmp.automatic)
22835 {
22836 struct composition *cmp = composition_table[glyph->u.cmp.id];
22837
22838 if (cmp->rbearing > cmp->pixel_width)
22839 *right = cmp->rbearing - cmp->pixel_width;
22840 if (cmp->lbearing < 0)
22841 *left = - cmp->lbearing;
22842 }
22843 else
22844 {
22845 Lisp_Object gstring = composition_gstring_from_id (glyph->u.cmp.id);
22846 struct font_metrics metrics;
22847
22848 composition_gstring_width (gstring, glyph->slice.cmp.from,
22849 glyph->slice.cmp.to + 1, &metrics);
22850 if (metrics.rbearing > metrics.width)
22851 *right = metrics.rbearing - metrics.width;
22852 if (metrics.lbearing < 0)
22853 *left = - metrics.lbearing;
22854 }
22855 }
22856 }
22857
22858
22859 /* Return the index of the first glyph preceding glyph string S that
22860 is overwritten by S because of S's left overhang. Value is -1
22861 if no glyphs are overwritten. */
22862
22863 static int
22864 left_overwritten (struct glyph_string *s)
22865 {
22866 int k;
22867
22868 if (s->left_overhang)
22869 {
22870 int x = 0, i;
22871 struct glyph *glyphs = s->row->glyphs[s->area];
22872 int first = s->first_glyph - glyphs;
22873
22874 for (i = first - 1; i >= 0 && x > -s->left_overhang; --i)
22875 x -= glyphs[i].pixel_width;
22876
22877 k = i + 1;
22878 }
22879 else
22880 k = -1;
22881
22882 return k;
22883 }
22884
22885
22886 /* Return the index of the first glyph preceding glyph string S that
22887 is overwriting S because of its right overhang. Value is -1 if no
22888 glyph in front of S overwrites S. */
22889
22890 static int
22891 left_overwriting (struct glyph_string *s)
22892 {
22893 int i, k, x;
22894 struct glyph *glyphs = s->row->glyphs[s->area];
22895 int first = s->first_glyph - glyphs;
22896
22897 k = -1;
22898 x = 0;
22899 for (i = first - 1; i >= 0; --i)
22900 {
22901 int left, right;
22902 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
22903 if (x + right > 0)
22904 k = i;
22905 x -= glyphs[i].pixel_width;
22906 }
22907
22908 return k;
22909 }
22910
22911
22912 /* Return the index of the last glyph following glyph string S that is
22913 overwritten by S because of S's right overhang. Value is -1 if
22914 no such glyph is found. */
22915
22916 static int
22917 right_overwritten (struct glyph_string *s)
22918 {
22919 int k = -1;
22920
22921 if (s->right_overhang)
22922 {
22923 int x = 0, i;
22924 struct glyph *glyphs = s->row->glyphs[s->area];
22925 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
22926 int end = s->row->used[s->area];
22927
22928 for (i = first; i < end && s->right_overhang > x; ++i)
22929 x += glyphs[i].pixel_width;
22930
22931 k = i;
22932 }
22933
22934 return k;
22935 }
22936
22937
22938 /* Return the index of the last glyph following glyph string S that
22939 overwrites S because of its left overhang. Value is negative
22940 if no such glyph is found. */
22941
22942 static int
22943 right_overwriting (struct glyph_string *s)
22944 {
22945 int i, k, x;
22946 int end = s->row->used[s->area];
22947 struct glyph *glyphs = s->row->glyphs[s->area];
22948 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
22949
22950 k = -1;
22951 x = 0;
22952 for (i = first; i < end; ++i)
22953 {
22954 int left, right;
22955 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
22956 if (x - left < 0)
22957 k = i;
22958 x += glyphs[i].pixel_width;
22959 }
22960
22961 return k;
22962 }
22963
22964
22965 /* Set background width of glyph string S. START is the index of the
22966 first glyph following S. LAST_X is the right-most x-position + 1
22967 in the drawing area. */
22968
22969 static inline void
22970 set_glyph_string_background_width (struct glyph_string *s, int start, int last_x)
22971 {
22972 /* If the face of this glyph string has to be drawn to the end of
22973 the drawing area, set S->extends_to_end_of_line_p. */
22974
22975 if (start == s->row->used[s->area]
22976 && s->area == TEXT_AREA
22977 && ((s->row->fill_line_p
22978 && (s->hl == DRAW_NORMAL_TEXT
22979 || s->hl == DRAW_IMAGE_RAISED
22980 || s->hl == DRAW_IMAGE_SUNKEN))
22981 || s->hl == DRAW_MOUSE_FACE))
22982 s->extends_to_end_of_line_p = 1;
22983
22984 /* If S extends its face to the end of the line, set its
22985 background_width to the distance to the right edge of the drawing
22986 area. */
22987 if (s->extends_to_end_of_line_p)
22988 s->background_width = last_x - s->x + 1;
22989 else
22990 s->background_width = s->width;
22991 }
22992
22993
22994 /* Compute overhangs and x-positions for glyph string S and its
22995 predecessors, or successors. X is the starting x-position for S.
22996 BACKWARD_P non-zero means process predecessors. */
22997
22998 static void
22999 compute_overhangs_and_x (struct glyph_string *s, int x, int backward_p)
23000 {
23001 if (backward_p)
23002 {
23003 while (s)
23004 {
23005 if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
23006 FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
23007 x -= s->width;
23008 s->x = x;
23009 s = s->prev;
23010 }
23011 }
23012 else
23013 {
23014 while (s)
23015 {
23016 if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
23017 FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
23018 s->x = x;
23019 x += s->width;
23020 s = s->next;
23021 }
23022 }
23023 }
23024
23025
23026
23027 /* The following macros are only called from draw_glyphs below.
23028 They reference the following parameters of that function directly:
23029 `w', `row', `area', and `overlap_p'
23030 as well as the following local variables:
23031 `s', `f', and `hdc' (in W32) */
23032
23033 #ifdef HAVE_NTGUI
23034 /* On W32, silently add local `hdc' variable to argument list of
23035 init_glyph_string. */
23036 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
23037 init_glyph_string (s, hdc, char2b, w, row, area, start, hl)
23038 #else
23039 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
23040 init_glyph_string (s, char2b, w, row, area, start, hl)
23041 #endif
23042
23043 /* Add a glyph string for a stretch glyph to the list of strings
23044 between HEAD and TAIL. START is the index of the stretch glyph in
23045 row area AREA of glyph row ROW. END is the index of the last glyph
23046 in that glyph row area. X is the current output position assigned
23047 to the new glyph string constructed. HL overrides that face of the
23048 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
23049 is the right-most x-position of the drawing area. */
23050
23051 /* SunOS 4 bundled cc, barfed on continuations in the arg lists here
23052 and below -- keep them on one line. */
23053 #define BUILD_STRETCH_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
23054 do \
23055 { \
23056 s = (struct glyph_string *) alloca (sizeof *s); \
23057 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
23058 START = fill_stretch_glyph_string (s, START, END); \
23059 append_glyph_string (&HEAD, &TAIL, s); \
23060 s->x = (X); \
23061 } \
23062 while (0)
23063
23064
23065 /* Add a glyph string for an image glyph to the list of strings
23066 between HEAD and TAIL. START is the index of the image glyph in
23067 row area AREA of glyph row ROW. END is the index of the last glyph
23068 in that glyph row area. X is the current output position assigned
23069 to the new glyph string constructed. HL overrides that face of the
23070 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
23071 is the right-most x-position of the drawing area. */
23072
23073 #define BUILD_IMAGE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
23074 do \
23075 { \
23076 s = (struct glyph_string *) alloca (sizeof *s); \
23077 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
23078 fill_image_glyph_string (s); \
23079 append_glyph_string (&HEAD, &TAIL, s); \
23080 ++START; \
23081 s->x = (X); \
23082 } \
23083 while (0)
23084
23085 #ifdef HAVE_XWIDGETS
23086 #define BUILD_XWIDGET_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
23087 do \
23088 { \
23089 printf("BUILD_XWIDGET_GLYPH_STRING\n"); \
23090 s = (struct glyph_string *) alloca (sizeof *s); \
23091 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
23092 fill_xwidget_glyph_string (s); \
23093 append_glyph_string (&HEAD, &TAIL, s); \
23094 ++START; \
23095 s->x = (X); \
23096 } \
23097 while (0)
23098 #endif
23099
23100
23101 /* Add a glyph string for a sequence of character glyphs to the list
23102 of strings between HEAD and TAIL. START is the index of the first
23103 glyph in row area AREA of glyph row ROW that is part of the new
23104 glyph string. END is the index of the last glyph in that glyph row
23105 area. X is the current output position assigned to the new glyph
23106 string constructed. HL overrides that face of the glyph; e.g. it
23107 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
23108 right-most x-position of the drawing area. */
23109
23110 #define BUILD_CHAR_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
23111 do \
23112 { \
23113 int face_id; \
23114 XChar2b *char2b; \
23115 \
23116 face_id = (row)->glyphs[area][START].face_id; \
23117 \
23118 s = (struct glyph_string *) alloca (sizeof *s); \
23119 char2b = (XChar2b *) alloca ((END - START) * sizeof *char2b); \
23120 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
23121 append_glyph_string (&HEAD, &TAIL, s); \
23122 s->x = (X); \
23123 START = fill_glyph_string (s, face_id, START, END, overlaps); \
23124 } \
23125 while (0)
23126
23127
23128 /* Add a glyph string for a composite sequence to the list of strings
23129 between HEAD and TAIL. START is the index of the first glyph in
23130 row area AREA of glyph row ROW that is part of the new glyph
23131 string. END is the index of the last glyph in that glyph row area.
23132 X is the current output position assigned to the new glyph string
23133 constructed. HL overrides that face of the glyph; e.g. it is
23134 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
23135 x-position of the drawing area. */
23136
23137 #define BUILD_COMPOSITE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
23138 do { \
23139 int face_id = (row)->glyphs[area][START].face_id; \
23140 struct face *base_face = FACE_FROM_ID (f, face_id); \
23141 ptrdiff_t cmp_id = (row)->glyphs[area][START].u.cmp.id; \
23142 struct composition *cmp = composition_table[cmp_id]; \
23143 XChar2b *char2b; \
23144 struct glyph_string *first_s = NULL; \
23145 int n; \
23146 \
23147 char2b = (XChar2b *) alloca ((sizeof *char2b) * cmp->glyph_len); \
23148 \
23149 /* Make glyph_strings for each glyph sequence that is drawable by \
23150 the same face, and append them to HEAD/TAIL. */ \
23151 for (n = 0; n < cmp->glyph_len;) \
23152 { \
23153 s = (struct glyph_string *) alloca (sizeof *s); \
23154 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
23155 append_glyph_string (&(HEAD), &(TAIL), s); \
23156 s->cmp = cmp; \
23157 s->cmp_from = n; \
23158 s->x = (X); \
23159 if (n == 0) \
23160 first_s = s; \
23161 n = fill_composite_glyph_string (s, base_face, overlaps); \
23162 } \
23163 \
23164 ++START; \
23165 s = first_s; \
23166 } while (0)
23167
23168
23169 /* Add a glyph string for a glyph-string sequence to the list of strings
23170 between HEAD and TAIL. */
23171
23172 #define BUILD_GSTRING_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
23173 do { \
23174 int face_id; \
23175 XChar2b *char2b; \
23176 Lisp_Object gstring; \
23177 \
23178 face_id = (row)->glyphs[area][START].face_id; \
23179 gstring = (composition_gstring_from_id \
23180 ((row)->glyphs[area][START].u.cmp.id)); \
23181 s = (struct glyph_string *) alloca (sizeof *s); \
23182 char2b = (XChar2b *) alloca ((sizeof *char2b) \
23183 * LGSTRING_GLYPH_LEN (gstring)); \
23184 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
23185 append_glyph_string (&(HEAD), &(TAIL), s); \
23186 s->x = (X); \
23187 START = fill_gstring_glyph_string (s, face_id, START, END, overlaps); \
23188 } while (0)
23189
23190
23191 /* Add a glyph string for a sequence of glyphless character's glyphs
23192 to the list of strings between HEAD and TAIL. The meanings of
23193 arguments are the same as those of BUILD_CHAR_GLYPH_STRINGS. */
23194
23195 #define BUILD_GLYPHLESS_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
23196 do \
23197 { \
23198 int face_id; \
23199 \
23200 face_id = (row)->glyphs[area][START].face_id; \
23201 \
23202 s = (struct glyph_string *) alloca (sizeof *s); \
23203 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
23204 append_glyph_string (&HEAD, &TAIL, s); \
23205 s->x = (X); \
23206 START = fill_glyphless_glyph_string (s, face_id, START, END, \
23207 overlaps); \
23208 } \
23209 while (0)
23210
23211
23212 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
23213 of AREA of glyph row ROW on window W between indices START and END.
23214 HL overrides the face for drawing glyph strings, e.g. it is
23215 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
23216 x-positions of the drawing area.
23217
23218 This is an ugly monster macro construct because we must use alloca
23219 to allocate glyph strings (because draw_glyphs can be called
23220 asynchronously). */
23221
23222 #define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
23223 do \
23224 { \
23225 HEAD = TAIL = NULL; \
23226 while (START < END) \
23227 { \
23228 struct glyph *first_glyph = (row)->glyphs[area] + START; \
23229 switch (first_glyph->type) \
23230 { \
23231 case CHAR_GLYPH: \
23232 BUILD_CHAR_GLYPH_STRINGS (START, END, HEAD, TAIL, \
23233 HL, X, LAST_X); \
23234 break; \
23235 \
23236 case COMPOSITE_GLYPH: \
23237 if (first_glyph->u.cmp.automatic) \
23238 BUILD_GSTRING_GLYPH_STRING (START, END, HEAD, TAIL, \
23239 HL, X, LAST_X); \
23240 else \
23241 BUILD_COMPOSITE_GLYPH_STRING (START, END, HEAD, TAIL, \
23242 HL, X, LAST_X); \
23243 break; \
23244 \
23245 case STRETCH_GLYPH: \
23246 BUILD_STRETCH_GLYPH_STRING (START, END, HEAD, TAIL, \
23247 HL, X, LAST_X); \
23248 break; \
23249 \
23250 case IMAGE_GLYPH: \
23251 BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL, \
23252 HL, X, LAST_X); \
23253 break; \
23254 case XWIDGET_GLYPH: \
23255 BUILD_XWIDGET_GLYPH_STRING (START, END, HEAD, TAIL, \
23256 HL, X, LAST_X); \
23257 break; \
23258 \
23259 \
23260 case GLYPHLESS_GLYPH: \
23261 BUILD_GLYPHLESS_GLYPH_STRING (START, END, HEAD, TAIL, \
23262 HL, X, LAST_X); \
23263 break; \
23264 \
23265 default: \
23266 abort (); \
23267 } \
23268 \
23269 if (s) \
23270 { \
23271 set_glyph_string_background_width (s, START, LAST_X); \
23272 (X) += s->width; \
23273 } \
23274 } \
23275 } while (0)
23276
23277
23278 /* Draw glyphs between START and END in AREA of ROW on window W,
23279 starting at x-position X. X is relative to AREA in W. HL is a
23280 face-override with the following meaning:
23281
23282 DRAW_NORMAL_TEXT draw normally
23283 DRAW_CURSOR draw in cursor face
23284 DRAW_MOUSE_FACE draw in mouse face.
23285 DRAW_INVERSE_VIDEO draw in mode line face
23286 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
23287 DRAW_IMAGE_RAISED draw an image with a raised relief around it
23288
23289 If OVERLAPS is non-zero, draw only the foreground of characters and
23290 clip to the physical height of ROW. Non-zero value also defines
23291 the overlapping part to be drawn:
23292
23293 OVERLAPS_PRED overlap with preceding rows
23294 OVERLAPS_SUCC overlap with succeeding rows
23295 OVERLAPS_BOTH overlap with both preceding/succeeding rows
23296 OVERLAPS_ERASED_CURSOR overlap with erased cursor area
23297
23298 Value is the x-position reached, relative to AREA of W. */
23299
23300 static int
23301 draw_glyphs (struct window *w, int x, struct glyph_row *row,
23302 enum glyph_row_area area, ptrdiff_t start, ptrdiff_t end,
23303 enum draw_glyphs_face hl, int overlaps)
23304 {
23305 struct glyph_string *head, *tail;
23306 struct glyph_string *s;
23307 struct glyph_string *clip_head = NULL, *clip_tail = NULL;
23308 int i, j, x_reached, last_x, area_left = 0;
23309 struct frame *f = XFRAME (WINDOW_FRAME (w));
23310 DECLARE_HDC (hdc);
23311
23312 ALLOCATE_HDC (hdc, f);
23313
23314 /* Let's rather be paranoid than getting a SEGV. */
23315 end = min (end, row->used[area]);
23316 start = max (0, start);
23317 start = min (end, start);
23318
23319 /* Translate X to frame coordinates. Set last_x to the right
23320 end of the drawing area. */
23321 if (row->full_width_p)
23322 {
23323 /* X is relative to the left edge of W, without scroll bars
23324 or fringes. */
23325 area_left = WINDOW_LEFT_EDGE_X (w);
23326 last_x = WINDOW_LEFT_EDGE_X (w) + WINDOW_TOTAL_WIDTH (w);
23327 }
23328 else
23329 {
23330 area_left = window_box_left (w, area);
23331 last_x = area_left + window_box_width (w, area);
23332 }
23333 x += area_left;
23334
23335 /* Build a doubly-linked list of glyph_string structures between
23336 head and tail from what we have to draw. Note that the macro
23337 BUILD_GLYPH_STRINGS will modify its start parameter. That's
23338 the reason we use a separate variable `i'. */
23339 i = start;
23340 BUILD_GLYPH_STRINGS (i, end, head, tail, hl, x, last_x);
23341 if (tail)
23342 x_reached = tail->x + tail->background_width;
23343 else
23344 x_reached = x;
23345
23346 /* If there are any glyphs with lbearing < 0 or rbearing > width in
23347 the row, redraw some glyphs in front or following the glyph
23348 strings built above. */
23349 if (head && !overlaps && row->contains_overlapping_glyphs_p)
23350 {
23351 struct glyph_string *h, *t;
23352 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
23353 int mouse_beg_col IF_LINT (= 0), mouse_end_col IF_LINT (= 0);
23354 int check_mouse_face = 0;
23355 int dummy_x = 0;
23356
23357 /* If mouse highlighting is on, we may need to draw adjacent
23358 glyphs using mouse-face highlighting. */
23359 if (area == TEXT_AREA && row->mouse_face_p)
23360 {
23361 struct glyph_row *mouse_beg_row, *mouse_end_row;
23362
23363 mouse_beg_row = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_beg_row);
23364 mouse_end_row = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_end_row);
23365
23366 if (row >= mouse_beg_row && row <= mouse_end_row)
23367 {
23368 check_mouse_face = 1;
23369 mouse_beg_col = (row == mouse_beg_row)
23370 ? hlinfo->mouse_face_beg_col : 0;
23371 mouse_end_col = (row == mouse_end_row)
23372 ? hlinfo->mouse_face_end_col
23373 : row->used[TEXT_AREA];
23374 }
23375 }
23376
23377 /* Compute overhangs for all glyph strings. */
23378 if (FRAME_RIF (f)->compute_glyph_string_overhangs)
23379 for (s = head; s; s = s->next)
23380 FRAME_RIF (f)->compute_glyph_string_overhangs (s);
23381
23382 /* Prepend glyph strings for glyphs in front of the first glyph
23383 string that are overwritten because of the first glyph
23384 string's left overhang. The background of all strings
23385 prepended must be drawn because the first glyph string
23386 draws over it. */
23387 i = left_overwritten (head);
23388 if (i >= 0)
23389 {
23390 enum draw_glyphs_face overlap_hl;
23391
23392 /* If this row contains mouse highlighting, attempt to draw
23393 the overlapped glyphs with the correct highlight. This
23394 code fails if the overlap encompasses more than one glyph
23395 and mouse-highlight spans only some of these glyphs.
23396 However, making it work perfectly involves a lot more
23397 code, and I don't know if the pathological case occurs in
23398 practice, so we'll stick to this for now. --- cyd */
23399 if (check_mouse_face
23400 && mouse_beg_col < start && mouse_end_col > i)
23401 overlap_hl = DRAW_MOUSE_FACE;
23402 else
23403 overlap_hl = DRAW_NORMAL_TEXT;
23404
23405 j = i;
23406 BUILD_GLYPH_STRINGS (j, start, h, t,
23407 overlap_hl, dummy_x, last_x);
23408 start = i;
23409 compute_overhangs_and_x (t, head->x, 1);
23410 prepend_glyph_string_lists (&head, &tail, h, t);
23411 clip_head = head;
23412 }
23413
23414 /* Prepend glyph strings for glyphs in front of the first glyph
23415 string that overwrite that glyph string because of their
23416 right overhang. For these strings, only the foreground must
23417 be drawn, because it draws over the glyph string at `head'.
23418 The background must not be drawn because this would overwrite
23419 right overhangs of preceding glyphs for which no glyph
23420 strings exist. */
23421 i = left_overwriting (head);
23422 if (i >= 0)
23423 {
23424 enum draw_glyphs_face overlap_hl;
23425
23426 if (check_mouse_face
23427 && mouse_beg_col < start && mouse_end_col > i)
23428 overlap_hl = DRAW_MOUSE_FACE;
23429 else
23430 overlap_hl = DRAW_NORMAL_TEXT;
23431
23432 clip_head = head;
23433 BUILD_GLYPH_STRINGS (i, start, h, t,
23434 overlap_hl, dummy_x, last_x);
23435 for (s = h; s; s = s->next)
23436 s->background_filled_p = 1;
23437 compute_overhangs_and_x (t, head->x, 1);
23438 prepend_glyph_string_lists (&head, &tail, h, t);
23439 }
23440
23441 /* Append glyphs strings for glyphs following the last glyph
23442 string tail that are overwritten by tail. The background of
23443 these strings has to be drawn because tail's foreground draws
23444 over it. */
23445 i = right_overwritten (tail);
23446 if (i >= 0)
23447 {
23448 enum draw_glyphs_face overlap_hl;
23449
23450 if (check_mouse_face
23451 && mouse_beg_col < i && mouse_end_col > end)
23452 overlap_hl = DRAW_MOUSE_FACE;
23453 else
23454 overlap_hl = DRAW_NORMAL_TEXT;
23455
23456 BUILD_GLYPH_STRINGS (end, i, h, t,
23457 overlap_hl, x, last_x);
23458 /* Because BUILD_GLYPH_STRINGS updates the first argument,
23459 we don't have `end = i;' here. */
23460 compute_overhangs_and_x (h, tail->x + tail->width, 0);
23461 append_glyph_string_lists (&head, &tail, h, t);
23462 clip_tail = tail;
23463 }
23464
23465 /* Append glyph strings for glyphs following the last glyph
23466 string tail that overwrite tail. The foreground of such
23467 glyphs has to be drawn because it writes into the background
23468 of tail. The background must not be drawn because it could
23469 paint over the foreground of following glyphs. */
23470 i = right_overwriting (tail);
23471 if (i >= 0)
23472 {
23473 enum draw_glyphs_face overlap_hl;
23474 if (check_mouse_face
23475 && mouse_beg_col < i && mouse_end_col > end)
23476 overlap_hl = DRAW_MOUSE_FACE;
23477 else
23478 overlap_hl = DRAW_NORMAL_TEXT;
23479
23480 clip_tail = tail;
23481 i++; /* We must include the Ith glyph. */
23482 BUILD_GLYPH_STRINGS (end, i, h, t,
23483 overlap_hl, x, last_x);
23484 for (s = h; s; s = s->next)
23485 s->background_filled_p = 1;
23486 compute_overhangs_and_x (h, tail->x + tail->width, 0);
23487 append_glyph_string_lists (&head, &tail, h, t);
23488 }
23489 if (clip_head || clip_tail)
23490 for (s = head; s; s = s->next)
23491 {
23492 s->clip_head = clip_head;
23493 s->clip_tail = clip_tail;
23494 }
23495 }
23496
23497 /* Draw all strings. */
23498 for (s = head; s; s = s->next)
23499 FRAME_RIF (f)->draw_glyph_string (s);
23500
23501 #ifndef HAVE_NS
23502 /* When focus a sole frame and move horizontally, this sets on_p to 0
23503 causing a failure to erase prev cursor position. */
23504 if (area == TEXT_AREA
23505 && !row->full_width_p
23506 /* When drawing overlapping rows, only the glyph strings'
23507 foreground is drawn, which doesn't erase a cursor
23508 completely. */
23509 && !overlaps)
23510 {
23511 int x0 = clip_head ? clip_head->x : (head ? head->x : x);
23512 int x1 = (clip_tail ? clip_tail->x + clip_tail->background_width
23513 : (tail ? tail->x + tail->background_width : x));
23514 x0 -= area_left;
23515 x1 -= area_left;
23516
23517 notice_overwritten_cursor (w, TEXT_AREA, x0, x1,
23518 row->y, MATRIX_ROW_BOTTOM_Y (row));
23519 }
23520 #endif
23521
23522 /* Value is the x-position up to which drawn, relative to AREA of W.
23523 This doesn't include parts drawn because of overhangs. */
23524 if (row->full_width_p)
23525 x_reached = FRAME_TO_WINDOW_PIXEL_X (w, x_reached);
23526 else
23527 x_reached -= area_left;
23528
23529 RELEASE_HDC (hdc, f);
23530
23531 return x_reached;
23532 }
23533
23534 /* Expand row matrix if too narrow. Don't expand if area
23535 is not present. */
23536
23537 #define IT_EXPAND_MATRIX_WIDTH(it, area) \
23538 { \
23539 if (!fonts_changed_p \
23540 && (it->glyph_row->glyphs[area] \
23541 < it->glyph_row->glyphs[area + 1])) \
23542 { \
23543 it->w->ncols_scale_factor++; \
23544 fonts_changed_p = 1; \
23545 } \
23546 }
23547
23548 /* Store one glyph for IT->char_to_display in IT->glyph_row.
23549 Called from x_produce_glyphs when IT->glyph_row is non-null. */
23550
23551 static inline void
23552 append_glyph (struct it *it)
23553 {
23554 struct glyph *glyph;
23555 enum glyph_row_area area = it->area;
23556
23557 xassert (it->glyph_row);
23558 xassert (it->char_to_display != '\n' && it->char_to_display != '\t');
23559
23560 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
23561 if (glyph < it->glyph_row->glyphs[area + 1])
23562 {
23563 /* If the glyph row is reversed, we need to prepend the glyph
23564 rather than append it. */
23565 if (it->glyph_row->reversed_p && area == TEXT_AREA)
23566 {
23567 struct glyph *g;
23568
23569 /* Make room for the additional glyph. */
23570 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
23571 g[1] = *g;
23572 glyph = it->glyph_row->glyphs[area];
23573 }
23574 glyph->charpos = CHARPOS (it->position);
23575 glyph->object = it->object;
23576 if (it->pixel_width > 0)
23577 {
23578 glyph->pixel_width = it->pixel_width;
23579 glyph->padding_p = 0;
23580 }
23581 else
23582 {
23583 /* Assure at least 1-pixel width. Otherwise, cursor can't
23584 be displayed correctly. */
23585 glyph->pixel_width = 1;
23586 glyph->padding_p = 1;
23587 }
23588 glyph->ascent = it->ascent;
23589 glyph->descent = it->descent;
23590 glyph->voffset = it->voffset;
23591 glyph->type = CHAR_GLYPH;
23592 glyph->avoid_cursor_p = it->avoid_cursor_p;
23593 glyph->multibyte_p = it->multibyte_p;
23594 glyph->left_box_line_p = it->start_of_box_run_p;
23595 glyph->right_box_line_p = it->end_of_box_run_p;
23596 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
23597 || it->phys_descent > it->descent);
23598 glyph->glyph_not_available_p = it->glyph_not_available_p;
23599 glyph->face_id = it->face_id;
23600 glyph->u.ch = it->char_to_display;
23601 glyph->slice.img = null_glyph_slice;
23602 glyph->font_type = FONT_TYPE_UNKNOWN;
23603 if (it->bidi_p)
23604 {
23605 glyph->resolved_level = it->bidi_it.resolved_level;
23606 if ((it->bidi_it.type & 7) != it->bidi_it.type)
23607 abort ();
23608 glyph->bidi_type = it->bidi_it.type;
23609 }
23610 else
23611 {
23612 glyph->resolved_level = 0;
23613 glyph->bidi_type = UNKNOWN_BT;
23614 }
23615 ++it->glyph_row->used[area];
23616 }
23617 else
23618 IT_EXPAND_MATRIX_WIDTH (it, area);
23619 }
23620
23621 /* Store one glyph for the composition IT->cmp_it.id in
23622 IT->glyph_row. Called from x_produce_glyphs when IT->glyph_row is
23623 non-null. */
23624
23625 static inline void
23626 append_composite_glyph (struct it *it)
23627 {
23628 struct glyph *glyph;
23629 enum glyph_row_area area = it->area;
23630
23631 xassert (it->glyph_row);
23632
23633 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
23634 if (glyph < it->glyph_row->glyphs[area + 1])
23635 {
23636 /* If the glyph row is reversed, we need to prepend the glyph
23637 rather than append it. */
23638 if (it->glyph_row->reversed_p && it->area == TEXT_AREA)
23639 {
23640 struct glyph *g;
23641
23642 /* Make room for the new glyph. */
23643 for (g = glyph - 1; g >= it->glyph_row->glyphs[it->area]; g--)
23644 g[1] = *g;
23645 glyph = it->glyph_row->glyphs[it->area];
23646 }
23647 glyph->charpos = it->cmp_it.charpos;
23648 glyph->object = it->object;
23649 glyph->pixel_width = it->pixel_width;
23650 glyph->ascent = it->ascent;
23651 glyph->descent = it->descent;
23652 glyph->voffset = it->voffset;
23653 glyph->type = COMPOSITE_GLYPH;
23654 if (it->cmp_it.ch < 0)
23655 {
23656 glyph->u.cmp.automatic = 0;
23657 glyph->u.cmp.id = it->cmp_it.id;
23658 glyph->slice.cmp.from = glyph->slice.cmp.to = 0;
23659 }
23660 else
23661 {
23662 glyph->u.cmp.automatic = 1;
23663 glyph->u.cmp.id = it->cmp_it.id;
23664 glyph->slice.cmp.from = it->cmp_it.from;
23665 glyph->slice.cmp.to = it->cmp_it.to - 1;
23666 }
23667 glyph->avoid_cursor_p = it->avoid_cursor_p;
23668 glyph->multibyte_p = it->multibyte_p;
23669 glyph->left_box_line_p = it->start_of_box_run_p;
23670 glyph->right_box_line_p = it->end_of_box_run_p;
23671 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
23672 || it->phys_descent > it->descent);
23673 glyph->padding_p = 0;
23674 glyph->glyph_not_available_p = 0;
23675 glyph->face_id = it->face_id;
23676 glyph->font_type = FONT_TYPE_UNKNOWN;
23677 if (it->bidi_p)
23678 {
23679 glyph->resolved_level = it->bidi_it.resolved_level;
23680 if ((it->bidi_it.type & 7) != it->bidi_it.type)
23681 abort ();
23682 glyph->bidi_type = it->bidi_it.type;
23683 }
23684 ++it->glyph_row->used[area];
23685 }
23686 else
23687 IT_EXPAND_MATRIX_WIDTH (it, area);
23688 }
23689
23690
23691 /* Change IT->ascent and IT->height according to the setting of
23692 IT->voffset. */
23693
23694 static inline void
23695 take_vertical_position_into_account (struct it *it)
23696 {
23697 if (it->voffset)
23698 {
23699 if (it->voffset < 0)
23700 /* Increase the ascent so that we can display the text higher
23701 in the line. */
23702 it->ascent -= it->voffset;
23703 else
23704 /* Increase the descent so that we can display the text lower
23705 in the line. */
23706 it->descent += it->voffset;
23707 }
23708 }
23709
23710
23711 /* Produce glyphs/get display metrics for the image IT is loaded with.
23712 See the description of struct display_iterator in dispextern.h for
23713 an overview of struct display_iterator. */
23714
23715 static void
23716 produce_image_glyph (struct it *it)
23717 {
23718 struct image *img;
23719 struct face *face;
23720 int glyph_ascent, crop;
23721 struct glyph_slice slice;
23722
23723 xassert (it->what == IT_IMAGE);
23724
23725 face = FACE_FROM_ID (it->f, it->face_id);
23726 xassert (face);
23727 /* Make sure X resources of the face is loaded. */
23728 PREPARE_FACE_FOR_DISPLAY (it->f, face);
23729
23730 if (it->image_id < 0)
23731 {
23732 /* Fringe bitmap. */
23733 it->ascent = it->phys_ascent = 0;
23734 it->descent = it->phys_descent = 0;
23735 it->pixel_width = 0;
23736 it->nglyphs = 0;
23737 return;
23738 }
23739
23740 img = IMAGE_FROM_ID (it->f, it->image_id);
23741 xassert (img);
23742 /* Make sure X resources of the image is loaded. */
23743 prepare_image_for_display (it->f, img);
23744
23745 slice.x = slice.y = 0;
23746 slice.width = img->width;
23747 slice.height = img->height;
23748
23749 if (INTEGERP (it->slice.x))
23750 slice.x = XINT (it->slice.x);
23751 else if (FLOATP (it->slice.x))
23752 slice.x = XFLOAT_DATA (it->slice.x) * img->width;
23753
23754 if (INTEGERP (it->slice.y))
23755 slice.y = XINT (it->slice.y);
23756 else if (FLOATP (it->slice.y))
23757 slice.y = XFLOAT_DATA (it->slice.y) * img->height;
23758
23759 if (INTEGERP (it->slice.width))
23760 slice.width = XINT (it->slice.width);
23761 else if (FLOATP (it->slice.width))
23762 slice.width = XFLOAT_DATA (it->slice.width) * img->width;
23763
23764 if (INTEGERP (it->slice.height))
23765 slice.height = XINT (it->slice.height);
23766 else if (FLOATP (it->slice.height))
23767 slice.height = XFLOAT_DATA (it->slice.height) * img->height;
23768
23769 if (slice.x >= img->width)
23770 slice.x = img->width;
23771 if (slice.y >= img->height)
23772 slice.y = img->height;
23773 if (slice.x + slice.width >= img->width)
23774 slice.width = img->width - slice.x;
23775 if (slice.y + slice.height > img->height)
23776 slice.height = img->height - slice.y;
23777
23778 if (slice.width == 0 || slice.height == 0)
23779 return;
23780
23781 it->ascent = it->phys_ascent = glyph_ascent = image_ascent (img, face, &slice);
23782
23783 it->descent = slice.height - glyph_ascent;
23784 if (slice.y == 0)
23785 it->descent += img->vmargin;
23786 if (slice.y + slice.height == img->height)
23787 it->descent += img->vmargin;
23788 it->phys_descent = it->descent;
23789
23790 it->pixel_width = slice.width;
23791 if (slice.x == 0)
23792 it->pixel_width += img->hmargin;
23793 if (slice.x + slice.width == img->width)
23794 it->pixel_width += img->hmargin;
23795
23796 /* It's quite possible for images to have an ascent greater than
23797 their height, so don't get confused in that case. */
23798 if (it->descent < 0)
23799 it->descent = 0;
23800
23801 it->nglyphs = 1;
23802
23803 if (face->box != FACE_NO_BOX)
23804 {
23805 if (face->box_line_width > 0)
23806 {
23807 if (slice.y == 0)
23808 it->ascent += face->box_line_width;
23809 if (slice.y + slice.height == img->height)
23810 it->descent += face->box_line_width;
23811 }
23812
23813 if (it->start_of_box_run_p && slice.x == 0)
23814 it->pixel_width += eabs (face->box_line_width);
23815 if (it->end_of_box_run_p && slice.x + slice.width == img->width)
23816 it->pixel_width += eabs (face->box_line_width);
23817 }
23818
23819 take_vertical_position_into_account (it);
23820
23821 /* Automatically crop wide image glyphs at right edge so we can
23822 draw the cursor on same display row. */
23823 if ((crop = it->pixel_width - (it->last_visible_x - it->current_x), crop > 0)
23824 && (it->hpos == 0 || it->pixel_width > it->last_visible_x / 4))
23825 {
23826 it->pixel_width -= crop;
23827 slice.width -= crop;
23828 }
23829
23830 if (it->glyph_row)
23831 {
23832 struct glyph *glyph;
23833 enum glyph_row_area area = it->area;
23834
23835 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
23836 if (glyph < it->glyph_row->glyphs[area + 1])
23837 {
23838 glyph->charpos = CHARPOS (it->position);
23839 glyph->object = it->object;
23840 glyph->pixel_width = it->pixel_width;
23841 glyph->ascent = glyph_ascent;
23842 glyph->descent = it->descent;
23843 glyph->voffset = it->voffset;
23844 glyph->type = IMAGE_GLYPH;
23845 glyph->avoid_cursor_p = it->avoid_cursor_p;
23846 glyph->multibyte_p = it->multibyte_p;
23847 glyph->left_box_line_p = it->start_of_box_run_p;
23848 glyph->right_box_line_p = it->end_of_box_run_p;
23849 glyph->overlaps_vertically_p = 0;
23850 glyph->padding_p = 0;
23851 glyph->glyph_not_available_p = 0;
23852 glyph->face_id = it->face_id;
23853 glyph->u.img_id = img->id;
23854 glyph->slice.img = slice;
23855 glyph->font_type = FONT_TYPE_UNKNOWN;
23856 if (it->bidi_p)
23857 {
23858 glyph->resolved_level = it->bidi_it.resolved_level;
23859 if ((it->bidi_it.type & 7) != it->bidi_it.type)
23860 abort ();
23861 glyph->bidi_type = it->bidi_it.type;
23862 }
23863 ++it->glyph_row->used[area];
23864 }
23865 else
23866 IT_EXPAND_MATRIX_WIDTH (it, area);
23867 }
23868 }
23869
23870 #ifdef HAVE_XWIDGETS
23871 static void
23872 produce_xwidget_glyph (struct it *it)
23873 {
23874 struct xwidget* xw;
23875 struct face *face;
23876 int glyph_ascent, crop;
23877 printf("produce_xwidget_glyph:\n");
23878 xassert (it->what == IT_XWIDGET);
23879
23880 face = FACE_FROM_ID (it->f, it->face_id);
23881 xassert (face);
23882 /* Make sure X resources of the face is loaded. */
23883 PREPARE_FACE_FOR_DISPLAY (it->f, face);
23884
23885 xw = it->xwidget;
23886 it->ascent = it->phys_ascent = glyph_ascent = xw->height/2;
23887 it->descent = xw->height/2;
23888 it->phys_descent = it->descent;
23889 it->pixel_width = xw->width;
23890 /* It's quite possible for images to have an ascent greater than
23891 their height, so don't get confused in that case. */
23892 if (it->descent < 0)
23893 it->descent = 0;
23894
23895 it->nglyphs = 1;
23896
23897 if (face->box != FACE_NO_BOX)
23898 {
23899 if (face->box_line_width > 0)
23900 {
23901 it->ascent += face->box_line_width;
23902 it->descent += face->box_line_width;
23903 }
23904
23905 if (it->start_of_box_run_p)
23906 it->pixel_width += eabs (face->box_line_width);
23907 it->pixel_width += eabs (face->box_line_width);
23908 }
23909
23910 take_vertical_position_into_account (it);
23911
23912 /* Automatically crop wide image glyphs at right edge so we can
23913 draw the cursor on same display row. */
23914 if ((crop = it->pixel_width - (it->last_visible_x - it->current_x), crop > 0)
23915 && (it->hpos == 0 || it->pixel_width > it->last_visible_x / 4))
23916 {
23917 it->pixel_width -= crop;
23918 }
23919
23920 if (it->glyph_row)
23921 {
23922 struct glyph *glyph;
23923 enum glyph_row_area area = it->area;
23924
23925 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
23926 if (glyph < it->glyph_row->glyphs[area + 1])
23927 {
23928 glyph->charpos = CHARPOS (it->position);
23929 glyph->object = it->object;
23930 glyph->pixel_width = it->pixel_width;
23931 glyph->ascent = glyph_ascent;
23932 glyph->descent = it->descent;
23933 glyph->voffset = it->voffset;
23934 glyph->type = XWIDGET_GLYPH;
23935
23936 glyph->multibyte_p = it->multibyte_p;
23937 glyph->left_box_line_p = it->start_of_box_run_p;
23938 glyph->right_box_line_p = it->end_of_box_run_p;
23939 glyph->overlaps_vertically_p = 0;
23940 glyph->padding_p = 0;
23941 glyph->glyph_not_available_p = 0;
23942 glyph->face_id = it->face_id;
23943 glyph->u.xwidget = it->xwidget;
23944 //assert_valid_xwidget_id(glyph->u.xwidget_id,"produce_xwidget_glyph");
23945 glyph->font_type = FONT_TYPE_UNKNOWN;
23946 ++it->glyph_row->used[area];
23947 }
23948 else
23949 IT_EXPAND_MATRIX_WIDTH (it, area);
23950 }
23951 }
23952 #endif
23953
23954 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
23955 of the glyph, WIDTH and HEIGHT are the width and height of the
23956 stretch. ASCENT is the ascent of the glyph (0 <= ASCENT <= HEIGHT). */
23957
23958 static void
23959 append_stretch_glyph (struct it *it, Lisp_Object object,
23960 int width, int height, int ascent)
23961 {
23962 struct glyph *glyph;
23963 enum glyph_row_area area = it->area;
23964
23965 xassert (ascent >= 0 && ascent <= height);
23966
23967 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
23968 if (glyph < it->glyph_row->glyphs[area + 1])
23969 {
23970 /* If the glyph row is reversed, we need to prepend the glyph
23971 rather than append it. */
23972 if (it->glyph_row->reversed_p && area == TEXT_AREA)
23973 {
23974 struct glyph *g;
23975
23976 /* Make room for the additional glyph. */
23977 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
23978 g[1] = *g;
23979 glyph = it->glyph_row->glyphs[area];
23980 }
23981 glyph->charpos = CHARPOS (it->position);
23982 glyph->object = object;
23983 glyph->pixel_width = width;
23984 glyph->ascent = ascent;
23985 glyph->descent = height - ascent;
23986 glyph->voffset = it->voffset;
23987 glyph->type = STRETCH_GLYPH;
23988 glyph->avoid_cursor_p = it->avoid_cursor_p;
23989 glyph->multibyte_p = it->multibyte_p;
23990 glyph->left_box_line_p = it->start_of_box_run_p;
23991 glyph->right_box_line_p = it->end_of_box_run_p;
23992 glyph->overlaps_vertically_p = 0;
23993 glyph->padding_p = 0;
23994 glyph->glyph_not_available_p = 0;
23995 glyph->face_id = it->face_id;
23996 glyph->u.stretch.ascent = ascent;
23997 glyph->u.stretch.height = height;
23998 glyph->slice.img = null_glyph_slice;
23999 glyph->font_type = FONT_TYPE_UNKNOWN;
24000 if (it->bidi_p)
24001 {
24002 glyph->resolved_level = it->bidi_it.resolved_level;
24003 if ((it->bidi_it.type & 7) != it->bidi_it.type)
24004 abort ();
24005 glyph->bidi_type = it->bidi_it.type;
24006 }
24007 else
24008 {
24009 glyph->resolved_level = 0;
24010 glyph->bidi_type = UNKNOWN_BT;
24011 }
24012 ++it->glyph_row->used[area];
24013 }
24014 else
24015 IT_EXPAND_MATRIX_WIDTH (it, area);
24016 }
24017
24018 #endif /* HAVE_WINDOW_SYSTEM */
24019
24020 /* Produce a stretch glyph for iterator IT. IT->object is the value
24021 of the glyph property displayed. The value must be a list
24022 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
24023 being recognized:
24024
24025 1. `:width WIDTH' specifies that the space should be WIDTH *
24026 canonical char width wide. WIDTH may be an integer or floating
24027 point number.
24028
24029 2. `:relative-width FACTOR' specifies that the width of the stretch
24030 should be computed from the width of the first character having the
24031 `glyph' property, and should be FACTOR times that width.
24032
24033 3. `:align-to HPOS' specifies that the space should be wide enough
24034 to reach HPOS, a value in canonical character units.
24035
24036 Exactly one of the above pairs must be present.
24037
24038 4. `:height HEIGHT' specifies that the height of the stretch produced
24039 should be HEIGHT, measured in canonical character units.
24040
24041 5. `:relative-height FACTOR' specifies that the height of the
24042 stretch should be FACTOR times the height of the characters having
24043 the glyph property.
24044
24045 Either none or exactly one of 4 or 5 must be present.
24046
24047 6. `:ascent ASCENT' specifies that ASCENT percent of the height
24048 of the stretch should be used for the ascent of the stretch.
24049 ASCENT must be in the range 0 <= ASCENT <= 100. */
24050
24051 void
24052 produce_stretch_glyph (struct it *it)
24053 {
24054 /* (space :width WIDTH :height HEIGHT ...) */
24055 Lisp_Object prop, plist;
24056 int width = 0, height = 0, align_to = -1;
24057 int zero_width_ok_p = 0;
24058 int ascent = 0;
24059 double tem;
24060 struct face *face = NULL;
24061 struct font *font = NULL;
24062
24063 #ifdef HAVE_WINDOW_SYSTEM
24064 int zero_height_ok_p = 0;
24065
24066 if (FRAME_WINDOW_P (it->f))
24067 {
24068 face = FACE_FROM_ID (it->f, it->face_id);
24069 font = face->font ? face->font : FRAME_FONT (it->f);
24070 PREPARE_FACE_FOR_DISPLAY (it->f, face);
24071 }
24072 #endif
24073
24074 /* List should start with `space'. */
24075 xassert (CONSP (it->object) && EQ (XCAR (it->object), Qspace));
24076 plist = XCDR (it->object);
24077
24078 /* Compute the width of the stretch. */
24079 if ((prop = Fplist_get (plist, QCwidth), !NILP (prop))
24080 && calc_pixel_width_or_height (&tem, it, prop, font, 1, 0))
24081 {
24082 /* Absolute width `:width WIDTH' specified and valid. */
24083 zero_width_ok_p = 1;
24084 width = (int)tem;
24085 }
24086 #ifdef HAVE_WINDOW_SYSTEM
24087 else if (FRAME_WINDOW_P (it->f)
24088 && (prop = Fplist_get (plist, QCrelative_width), NUMVAL (prop) > 0))
24089 {
24090 /* Relative width `:relative-width FACTOR' specified and valid.
24091 Compute the width of the characters having the `glyph'
24092 property. */
24093 struct it it2;
24094 unsigned char *p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
24095
24096 it2 = *it;
24097 if (it->multibyte_p)
24098 it2.c = it2.char_to_display = STRING_CHAR_AND_LENGTH (p, it2.len);
24099 else
24100 {
24101 it2.c = it2.char_to_display = *p, it2.len = 1;
24102 if (! ASCII_CHAR_P (it2.c))
24103 it2.char_to_display = BYTE8_TO_CHAR (it2.c);
24104 }
24105
24106 it2.glyph_row = NULL;
24107 it2.what = IT_CHARACTER;
24108 x_produce_glyphs (&it2);
24109 width = NUMVAL (prop) * it2.pixel_width;
24110 }
24111 #endif /* HAVE_WINDOW_SYSTEM */
24112 else if ((prop = Fplist_get (plist, QCalign_to), !NILP (prop))
24113 && calc_pixel_width_or_height (&tem, it, prop, font, 1, &align_to))
24114 {
24115 if (it->glyph_row == NULL || !it->glyph_row->mode_line_p)
24116 align_to = (align_to < 0
24117 ? 0
24118 : align_to - window_box_left_offset (it->w, TEXT_AREA));
24119 else if (align_to < 0)
24120 align_to = window_box_left_offset (it->w, TEXT_AREA);
24121 width = max (0, (int)tem + align_to - it->current_x);
24122 zero_width_ok_p = 1;
24123 }
24124 else
24125 /* Nothing specified -> width defaults to canonical char width. */
24126 width = FRAME_COLUMN_WIDTH (it->f);
24127
24128 if (width <= 0 && (width < 0 || !zero_width_ok_p))
24129 width = 1;
24130
24131 #ifdef HAVE_WINDOW_SYSTEM
24132 /* Compute height. */
24133 if (FRAME_WINDOW_P (it->f))
24134 {
24135 if ((prop = Fplist_get (plist, QCheight), !NILP (prop))
24136 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
24137 {
24138 height = (int)tem;
24139 zero_height_ok_p = 1;
24140 }
24141 else if (prop = Fplist_get (plist, QCrelative_height),
24142 NUMVAL (prop) > 0)
24143 height = FONT_HEIGHT (font) * NUMVAL (prop);
24144 else
24145 height = FONT_HEIGHT (font);
24146
24147 if (height <= 0 && (height < 0 || !zero_height_ok_p))
24148 height = 1;
24149
24150 /* Compute percentage of height used for ascent. If
24151 `:ascent ASCENT' is present and valid, use that. Otherwise,
24152 derive the ascent from the font in use. */
24153 if (prop = Fplist_get (plist, QCascent),
24154 NUMVAL (prop) > 0 && NUMVAL (prop) <= 100)
24155 ascent = height * NUMVAL (prop) / 100.0;
24156 else if (!NILP (prop)
24157 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
24158 ascent = min (max (0, (int)tem), height);
24159 else
24160 ascent = (height * FONT_BASE (font)) / FONT_HEIGHT (font);
24161 }
24162 else
24163 #endif /* HAVE_WINDOW_SYSTEM */
24164 height = 1;
24165
24166 if (width > 0 && it->line_wrap != TRUNCATE
24167 && it->current_x + width > it->last_visible_x)
24168 {
24169 width = it->last_visible_x - it->current_x;
24170 #ifdef HAVE_WINDOW_SYSTEM
24171 /* Subtract one more pixel from the stretch width, but only on
24172 GUI frames, since on a TTY each glyph is one "pixel" wide. */
24173 width -= FRAME_WINDOW_P (it->f);
24174 #endif
24175 }
24176
24177 if (width > 0 && height > 0 && it->glyph_row)
24178 {
24179 Lisp_Object o_object = it->object;
24180 Lisp_Object object = it->stack[it->sp - 1].string;
24181 int n = width;
24182
24183 if (!STRINGP (object))
24184 object = it->w->buffer;
24185 #ifdef HAVE_WINDOW_SYSTEM
24186 if (FRAME_WINDOW_P (it->f))
24187 append_stretch_glyph (it, object, width, height, ascent);
24188 else
24189 #endif
24190 {
24191 it->object = object;
24192 it->char_to_display = ' ';
24193 it->pixel_width = it->len = 1;
24194 while (n--)
24195 tty_append_glyph (it);
24196 it->object = o_object;
24197 }
24198 }
24199
24200 it->pixel_width = width;
24201 #ifdef HAVE_WINDOW_SYSTEM
24202 if (FRAME_WINDOW_P (it->f))
24203 {
24204 it->ascent = it->phys_ascent = ascent;
24205 it->descent = it->phys_descent = height - it->ascent;
24206 it->nglyphs = width > 0 && height > 0 ? 1 : 0;
24207 take_vertical_position_into_account (it);
24208 }
24209 else
24210 #endif
24211 it->nglyphs = width;
24212 }
24213
24214 #ifdef HAVE_WINDOW_SYSTEM
24215
24216 /* Calculate line-height and line-spacing properties.
24217 An integer value specifies explicit pixel value.
24218 A float value specifies relative value to current face height.
24219 A cons (float . face-name) specifies relative value to
24220 height of specified face font.
24221
24222 Returns height in pixels, or nil. */
24223
24224
24225 static Lisp_Object
24226 calc_line_height_property (struct it *it, Lisp_Object val, struct font *font,
24227 int boff, int override)
24228 {
24229 Lisp_Object face_name = Qnil;
24230 int ascent, descent, height;
24231
24232 if (NILP (val) || INTEGERP (val) || (override && EQ (val, Qt)))
24233 return val;
24234
24235 if (CONSP (val))
24236 {
24237 face_name = XCAR (val);
24238 val = XCDR (val);
24239 if (!NUMBERP (val))
24240 val = make_number (1);
24241 if (NILP (face_name))
24242 {
24243 height = it->ascent + it->descent;
24244 goto scale;
24245 }
24246 }
24247
24248 if (NILP (face_name))
24249 {
24250 font = FRAME_FONT (it->f);
24251 boff = FRAME_BASELINE_OFFSET (it->f);
24252 }
24253 else if (EQ (face_name, Qt))
24254 {
24255 override = 0;
24256 }
24257 else
24258 {
24259 int face_id;
24260 struct face *face;
24261
24262 face_id = lookup_named_face (it->f, face_name, 0);
24263 if (face_id < 0)
24264 return make_number (-1);
24265
24266 face = FACE_FROM_ID (it->f, face_id);
24267 font = face->font;
24268 if (font == NULL)
24269 return make_number (-1);
24270 boff = font->baseline_offset;
24271 if (font->vertical_centering)
24272 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
24273 }
24274
24275 ascent = FONT_BASE (font) + boff;
24276 descent = FONT_DESCENT (font) - boff;
24277
24278 if (override)
24279 {
24280 it->override_ascent = ascent;
24281 it->override_descent = descent;
24282 it->override_boff = boff;
24283 }
24284
24285 height = ascent + descent;
24286
24287 scale:
24288 if (FLOATP (val))
24289 height = (int)(XFLOAT_DATA (val) * height);
24290 else if (INTEGERP (val))
24291 height *= XINT (val);
24292
24293 return make_number (height);
24294 }
24295
24296
24297 /* Append a glyph for a glyphless character to IT->glyph_row. FACE_ID
24298 is a face ID to be used for the glyph. FOR_NO_FONT is nonzero if
24299 and only if this is for a character for which no font was found.
24300
24301 If the display method (it->glyphless_method) is
24302 GLYPHLESS_DISPLAY_ACRONYM or GLYPHLESS_DISPLAY_HEX_CODE, LEN is a
24303 length of the acronym or the hexadecimal string, UPPER_XOFF and
24304 UPPER_YOFF are pixel offsets for the upper part of the string,
24305 LOWER_XOFF and LOWER_YOFF are for the lower part.
24306
24307 For the other display methods, LEN through LOWER_YOFF are zero. */
24308
24309 static void
24310 append_glyphless_glyph (struct it *it, int face_id, int for_no_font, int len,
24311 short upper_xoff, short upper_yoff,
24312 short lower_xoff, short lower_yoff)
24313 {
24314 struct glyph *glyph;
24315 enum glyph_row_area area = it->area;
24316
24317 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
24318 if (glyph < it->glyph_row->glyphs[area + 1])
24319 {
24320 /* If the glyph row is reversed, we need to prepend the glyph
24321 rather than append it. */
24322 if (it->glyph_row->reversed_p && area == TEXT_AREA)
24323 {
24324 struct glyph *g;
24325
24326 /* Make room for the additional glyph. */
24327 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
24328 g[1] = *g;
24329 glyph = it->glyph_row->glyphs[area];
24330 }
24331 glyph->charpos = CHARPOS (it->position);
24332 glyph->object = it->object;
24333 glyph->pixel_width = it->pixel_width;
24334 glyph->ascent = it->ascent;
24335 glyph->descent = it->descent;
24336 glyph->voffset = it->voffset;
24337 glyph->type = GLYPHLESS_GLYPH;
24338 glyph->u.glyphless.method = it->glyphless_method;
24339 glyph->u.glyphless.for_no_font = for_no_font;
24340 glyph->u.glyphless.len = len;
24341 glyph->u.glyphless.ch = it->c;
24342 glyph->slice.glyphless.upper_xoff = upper_xoff;
24343 glyph->slice.glyphless.upper_yoff = upper_yoff;
24344 glyph->slice.glyphless.lower_xoff = lower_xoff;
24345 glyph->slice.glyphless.lower_yoff = lower_yoff;
24346 glyph->avoid_cursor_p = it->avoid_cursor_p;
24347 glyph->multibyte_p = it->multibyte_p;
24348 glyph->left_box_line_p = it->start_of_box_run_p;
24349 glyph->right_box_line_p = it->end_of_box_run_p;
24350 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
24351 || it->phys_descent > it->descent);
24352 glyph->padding_p = 0;
24353 glyph->glyph_not_available_p = 0;
24354 glyph->face_id = face_id;
24355 glyph->font_type = FONT_TYPE_UNKNOWN;
24356 if (it->bidi_p)
24357 {
24358 glyph->resolved_level = it->bidi_it.resolved_level;
24359 if ((it->bidi_it.type & 7) != it->bidi_it.type)
24360 abort ();
24361 glyph->bidi_type = it->bidi_it.type;
24362 }
24363 ++it->glyph_row->used[area];
24364 }
24365 else
24366 IT_EXPAND_MATRIX_WIDTH (it, area);
24367 }
24368
24369
24370 /* Produce a glyph for a glyphless character for iterator IT.
24371 IT->glyphless_method specifies which method to use for displaying
24372 the character. See the description of enum
24373 glyphless_display_method in dispextern.h for the detail.
24374
24375 FOR_NO_FONT is nonzero if and only if this is for a character for
24376 which no font was found. ACRONYM, if non-nil, is an acronym string
24377 for the character. */
24378
24379 static void
24380 produce_glyphless_glyph (struct it *it, int for_no_font, Lisp_Object acronym)
24381 {
24382 int face_id;
24383 struct face *face;
24384 struct font *font;
24385 int base_width, base_height, width, height;
24386 short upper_xoff, upper_yoff, lower_xoff, lower_yoff;
24387 int len;
24388
24389 /* Get the metrics of the base font. We always refer to the current
24390 ASCII face. */
24391 face = FACE_FROM_ID (it->f, it->face_id)->ascii_face;
24392 font = face->font ? face->font : FRAME_FONT (it->f);
24393 it->ascent = FONT_BASE (font) + font->baseline_offset;
24394 it->descent = FONT_DESCENT (font) - font->baseline_offset;
24395 base_height = it->ascent + it->descent;
24396 base_width = font->average_width;
24397
24398 /* Get a face ID for the glyph by utilizing a cache (the same way as
24399 done for `escape-glyph' in get_next_display_element). */
24400 if (it->f == last_glyphless_glyph_frame
24401 && it->face_id == last_glyphless_glyph_face_id)
24402 {
24403 face_id = last_glyphless_glyph_merged_face_id;
24404 }
24405 else
24406 {
24407 /* Merge the `glyphless-char' face into the current face. */
24408 face_id = merge_faces (it->f, Qglyphless_char, 0, it->face_id);
24409 last_glyphless_glyph_frame = it->f;
24410 last_glyphless_glyph_face_id = it->face_id;
24411 last_glyphless_glyph_merged_face_id = face_id;
24412 }
24413
24414 if (it->glyphless_method == GLYPHLESS_DISPLAY_THIN_SPACE)
24415 {
24416 it->pixel_width = THIN_SPACE_WIDTH;
24417 len = 0;
24418 upper_xoff = upper_yoff = lower_xoff = lower_yoff = 0;
24419 }
24420 else if (it->glyphless_method == GLYPHLESS_DISPLAY_EMPTY_BOX)
24421 {
24422 width = CHAR_WIDTH (it->c);
24423 if (width == 0)
24424 width = 1;
24425 else if (width > 4)
24426 width = 4;
24427 it->pixel_width = base_width * width;
24428 len = 0;
24429 upper_xoff = upper_yoff = lower_xoff = lower_yoff = 0;
24430 }
24431 else
24432 {
24433 char buf[7];
24434 const char *str;
24435 unsigned int code[6];
24436 int upper_len;
24437 int ascent, descent;
24438 struct font_metrics metrics_upper, metrics_lower;
24439
24440 face = FACE_FROM_ID (it->f, face_id);
24441 font = face->font ? face->font : FRAME_FONT (it->f);
24442 PREPARE_FACE_FOR_DISPLAY (it->f, face);
24443
24444 if (it->glyphless_method == GLYPHLESS_DISPLAY_ACRONYM)
24445 {
24446 if (! STRINGP (acronym) && CHAR_TABLE_P (Vglyphless_char_display))
24447 acronym = CHAR_TABLE_REF (Vglyphless_char_display, it->c);
24448 if (CONSP (acronym))
24449 acronym = XCAR (acronym);
24450 str = STRINGP (acronym) ? SSDATA (acronym) : "";
24451 }
24452 else
24453 {
24454 xassert (it->glyphless_method == GLYPHLESS_DISPLAY_HEX_CODE);
24455 sprintf (buf, "%0*X", it->c < 0x10000 ? 4 : 6, it->c);
24456 str = buf;
24457 }
24458 for (len = 0; str[len] && ASCII_BYTE_P (str[len]) && len < 6; len++)
24459 code[len] = font->driver->encode_char (font, str[len]);
24460 upper_len = (len + 1) / 2;
24461 font->driver->text_extents (font, code, upper_len,
24462 &metrics_upper);
24463 font->driver->text_extents (font, code + upper_len, len - upper_len,
24464 &metrics_lower);
24465
24466
24467
24468 /* +4 is for vertical bars of a box plus 1-pixel spaces at both side. */
24469 width = max (metrics_upper.width, metrics_lower.width) + 4;
24470 upper_xoff = upper_yoff = 2; /* the typical case */
24471 if (base_width >= width)
24472 {
24473 /* Align the upper to the left, the lower to the right. */
24474 it->pixel_width = base_width;
24475 lower_xoff = base_width - 2 - metrics_lower.width;
24476 }
24477 else
24478 {
24479 /* Center the shorter one. */
24480 it->pixel_width = width;
24481 if (metrics_upper.width >= metrics_lower.width)
24482 lower_xoff = (width - metrics_lower.width) / 2;
24483 else
24484 {
24485 /* FIXME: This code doesn't look right. It formerly was
24486 missing the "lower_xoff = 0;", which couldn't have
24487 been right since it left lower_xoff uninitialized. */
24488 lower_xoff = 0;
24489 upper_xoff = (width - metrics_upper.width) / 2;
24490 }
24491 }
24492
24493 /* +5 is for horizontal bars of a box plus 1-pixel spaces at
24494 top, bottom, and between upper and lower strings. */
24495 height = (metrics_upper.ascent + metrics_upper.descent
24496 + metrics_lower.ascent + metrics_lower.descent) + 5;
24497 /* Center vertically.
24498 H:base_height, D:base_descent
24499 h:height, ld:lower_descent, la:lower_ascent, ud:upper_descent
24500
24501 ascent = - (D - H/2 - h/2 + 1); "+ 1" for rounding up
24502 descent = D - H/2 + h/2;
24503 lower_yoff = descent - 2 - ld;
24504 upper_yoff = lower_yoff - la - 1 - ud; */
24505 ascent = - (it->descent - (base_height + height + 1) / 2);
24506 descent = it->descent - (base_height - height) / 2;
24507 lower_yoff = descent - 2 - metrics_lower.descent;
24508 upper_yoff = (lower_yoff - metrics_lower.ascent - 1
24509 - metrics_upper.descent);
24510 /* Don't make the height shorter than the base height. */
24511 if (height > base_height)
24512 {
24513 it->ascent = ascent;
24514 it->descent = descent;
24515 }
24516 }
24517
24518 it->phys_ascent = it->ascent;
24519 it->phys_descent = it->descent;
24520 if (it->glyph_row)
24521 append_glyphless_glyph (it, face_id, for_no_font, len,
24522 upper_xoff, upper_yoff,
24523 lower_xoff, lower_yoff);
24524 it->nglyphs = 1;
24525 take_vertical_position_into_account (it);
24526 }
24527
24528
24529 /* RIF:
24530 Produce glyphs/get display metrics for the display element IT is
24531 loaded with. See the description of struct it in dispextern.h
24532 for an overview of struct it. */
24533
24534 void
24535 x_produce_glyphs (struct it *it)
24536 {
24537 int extra_line_spacing = it->extra_line_spacing;
24538
24539 it->glyph_not_available_p = 0;
24540
24541 if (it->what == IT_CHARACTER)
24542 {
24543 XChar2b char2b;
24544 struct face *face = FACE_FROM_ID (it->f, it->face_id);
24545 struct font *font = face->font;
24546 struct font_metrics *pcm = NULL;
24547 int boff; /* baseline offset */
24548
24549 if (font == NULL)
24550 {
24551 /* When no suitable font is found, display this character by
24552 the method specified in the first extra slot of
24553 Vglyphless_char_display. */
24554 Lisp_Object acronym = lookup_glyphless_char_display (-1, it);
24555
24556 xassert (it->what == IT_GLYPHLESS);
24557 produce_glyphless_glyph (it, 1, STRINGP (acronym) ? acronym : Qnil);
24558 goto done;
24559 }
24560
24561 boff = font->baseline_offset;
24562 if (font->vertical_centering)
24563 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
24564
24565 if (it->char_to_display != '\n' && it->char_to_display != '\t')
24566 {
24567 int stretched_p;
24568
24569 it->nglyphs = 1;
24570
24571 if (it->override_ascent >= 0)
24572 {
24573 it->ascent = it->override_ascent;
24574 it->descent = it->override_descent;
24575 boff = it->override_boff;
24576 }
24577 else
24578 {
24579 it->ascent = FONT_BASE (font) + boff;
24580 it->descent = FONT_DESCENT (font) - boff;
24581 }
24582
24583 if (get_char_glyph_code (it->char_to_display, font, &char2b))
24584 {
24585 pcm = get_per_char_metric (font, &char2b);
24586 if (pcm->width == 0
24587 && pcm->rbearing == 0 && pcm->lbearing == 0)
24588 pcm = NULL;
24589 }
24590
24591 if (pcm)
24592 {
24593 it->phys_ascent = pcm->ascent + boff;
24594 it->phys_descent = pcm->descent - boff;
24595 it->pixel_width = pcm->width;
24596 }
24597 else
24598 {
24599 it->glyph_not_available_p = 1;
24600 it->phys_ascent = it->ascent;
24601 it->phys_descent = it->descent;
24602 it->pixel_width = font->space_width;
24603 }
24604
24605 if (it->constrain_row_ascent_descent_p)
24606 {
24607 if (it->descent > it->max_descent)
24608 {
24609 it->ascent += it->descent - it->max_descent;
24610 it->descent = it->max_descent;
24611 }
24612 if (it->ascent > it->max_ascent)
24613 {
24614 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
24615 it->ascent = it->max_ascent;
24616 }
24617 it->phys_ascent = min (it->phys_ascent, it->ascent);
24618 it->phys_descent = min (it->phys_descent, it->descent);
24619 extra_line_spacing = 0;
24620 }
24621
24622 /* If this is a space inside a region of text with
24623 `space-width' property, change its width. */
24624 stretched_p = it->char_to_display == ' ' && !NILP (it->space_width);
24625 if (stretched_p)
24626 it->pixel_width *= XFLOATINT (it->space_width);
24627
24628 /* If face has a box, add the box thickness to the character
24629 height. If character has a box line to the left and/or
24630 right, add the box line width to the character's width. */
24631 if (face->box != FACE_NO_BOX)
24632 {
24633 int thick = face->box_line_width;
24634
24635 if (thick > 0)
24636 {
24637 it->ascent += thick;
24638 it->descent += thick;
24639 }
24640 else
24641 thick = -thick;
24642
24643 if (it->start_of_box_run_p)
24644 it->pixel_width += thick;
24645 if (it->end_of_box_run_p)
24646 it->pixel_width += thick;
24647 }
24648
24649 /* If face has an overline, add the height of the overline
24650 (1 pixel) and a 1 pixel margin to the character height. */
24651 if (face->overline_p)
24652 it->ascent += overline_margin;
24653
24654 if (it->constrain_row_ascent_descent_p)
24655 {
24656 if (it->ascent > it->max_ascent)
24657 it->ascent = it->max_ascent;
24658 if (it->descent > it->max_descent)
24659 it->descent = it->max_descent;
24660 }
24661
24662 take_vertical_position_into_account (it);
24663
24664 /* If we have to actually produce glyphs, do it. */
24665 if (it->glyph_row)
24666 {
24667 if (stretched_p)
24668 {
24669 /* Translate a space with a `space-width' property
24670 into a stretch glyph. */
24671 int ascent = (((it->ascent + it->descent) * FONT_BASE (font))
24672 / FONT_HEIGHT (font));
24673 append_stretch_glyph (it, it->object, it->pixel_width,
24674 it->ascent + it->descent, ascent);
24675 }
24676 else
24677 append_glyph (it);
24678
24679 /* If characters with lbearing or rbearing are displayed
24680 in this line, record that fact in a flag of the
24681 glyph row. This is used to optimize X output code. */
24682 if (pcm && (pcm->lbearing < 0 || pcm->rbearing > pcm->width))
24683 it->glyph_row->contains_overlapping_glyphs_p = 1;
24684 }
24685 if (! stretched_p && it->pixel_width == 0)
24686 /* We assure that all visible glyphs have at least 1-pixel
24687 width. */
24688 it->pixel_width = 1;
24689 }
24690 else if (it->char_to_display == '\n')
24691 {
24692 /* A newline has no width, but we need the height of the
24693 line. But if previous part of the line sets a height,
24694 don't increase that height */
24695
24696 Lisp_Object height;
24697 Lisp_Object total_height = Qnil;
24698
24699 it->override_ascent = -1;
24700 it->pixel_width = 0;
24701 it->nglyphs = 0;
24702
24703 height = get_it_property (it, Qline_height);
24704 /* Split (line-height total-height) list */
24705 if (CONSP (height)
24706 && CONSP (XCDR (height))
24707 && NILP (XCDR (XCDR (height))))
24708 {
24709 total_height = XCAR (XCDR (height));
24710 height = XCAR (height);
24711 }
24712 height = calc_line_height_property (it, height, font, boff, 1);
24713
24714 if (it->override_ascent >= 0)
24715 {
24716 it->ascent = it->override_ascent;
24717 it->descent = it->override_descent;
24718 boff = it->override_boff;
24719 }
24720 else
24721 {
24722 it->ascent = FONT_BASE (font) + boff;
24723 it->descent = FONT_DESCENT (font) - boff;
24724 }
24725
24726 if (EQ (height, Qt))
24727 {
24728 if (it->descent > it->max_descent)
24729 {
24730 it->ascent += it->descent - it->max_descent;
24731 it->descent = it->max_descent;
24732 }
24733 if (it->ascent > it->max_ascent)
24734 {
24735 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
24736 it->ascent = it->max_ascent;
24737 }
24738 it->phys_ascent = min (it->phys_ascent, it->ascent);
24739 it->phys_descent = min (it->phys_descent, it->descent);
24740 it->constrain_row_ascent_descent_p = 1;
24741 extra_line_spacing = 0;
24742 }
24743 else
24744 {
24745 Lisp_Object spacing;
24746
24747 it->phys_ascent = it->ascent;
24748 it->phys_descent = it->descent;
24749
24750 if ((it->max_ascent > 0 || it->max_descent > 0)
24751 && face->box != FACE_NO_BOX
24752 && face->box_line_width > 0)
24753 {
24754 it->ascent += face->box_line_width;
24755 it->descent += face->box_line_width;
24756 }
24757 if (!NILP (height)
24758 && XINT (height) > it->ascent + it->descent)
24759 it->ascent = XINT (height) - it->descent;
24760
24761 if (!NILP (total_height))
24762 spacing = calc_line_height_property (it, total_height, font, boff, 0);
24763 else
24764 {
24765 spacing = get_it_property (it, Qline_spacing);
24766 spacing = calc_line_height_property (it, spacing, font, boff, 0);
24767 }
24768 if (INTEGERP (spacing))
24769 {
24770 extra_line_spacing = XINT (spacing);
24771 if (!NILP (total_height))
24772 extra_line_spacing -= (it->phys_ascent + it->phys_descent);
24773 }
24774 }
24775 }
24776 else /* i.e. (it->char_to_display == '\t') */
24777 {
24778 if (font->space_width > 0)
24779 {
24780 int tab_width = it->tab_width * font->space_width;
24781 int x = it->current_x + it->continuation_lines_width;
24782 int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width;
24783
24784 /* If the distance from the current position to the next tab
24785 stop is less than a space character width, use the
24786 tab stop after that. */
24787 if (next_tab_x - x < font->space_width)
24788 next_tab_x += tab_width;
24789
24790 it->pixel_width = next_tab_x - x;
24791 it->nglyphs = 1;
24792 it->ascent = it->phys_ascent = FONT_BASE (font) + boff;
24793 it->descent = it->phys_descent = FONT_DESCENT (font) - boff;
24794
24795 if (it->glyph_row)
24796 {
24797 append_stretch_glyph (it, it->object, it->pixel_width,
24798 it->ascent + it->descent, it->ascent);
24799 }
24800 }
24801 else
24802 {
24803 it->pixel_width = 0;
24804 it->nglyphs = 1;
24805 }
24806 }
24807 }
24808 else if (it->what == IT_COMPOSITION && it->cmp_it.ch < 0)
24809 {
24810 /* A static composition.
24811
24812 Note: A composition is represented as one glyph in the
24813 glyph matrix. There are no padding glyphs.
24814
24815 Important note: pixel_width, ascent, and descent are the
24816 values of what is drawn by draw_glyphs (i.e. the values of
24817 the overall glyphs composed). */
24818 struct face *face = FACE_FROM_ID (it->f, it->face_id);
24819 int boff; /* baseline offset */
24820 struct composition *cmp = composition_table[it->cmp_it.id];
24821 int glyph_len = cmp->glyph_len;
24822 struct font *font = face->font;
24823
24824 it->nglyphs = 1;
24825
24826 /* If we have not yet calculated pixel size data of glyphs of
24827 the composition for the current face font, calculate them
24828 now. Theoretically, we have to check all fonts for the
24829 glyphs, but that requires much time and memory space. So,
24830 here we check only the font of the first glyph. This may
24831 lead to incorrect display, but it's very rare, and C-l
24832 (recenter-top-bottom) can correct the display anyway. */
24833 if (! cmp->font || cmp->font != font)
24834 {
24835 /* Ascent and descent of the font of the first character
24836 of this composition (adjusted by baseline offset).
24837 Ascent and descent of overall glyphs should not be less
24838 than these, respectively. */
24839 int font_ascent, font_descent, font_height;
24840 /* Bounding box of the overall glyphs. */
24841 int leftmost, rightmost, lowest, highest;
24842 int lbearing, rbearing;
24843 int i, width, ascent, descent;
24844 int left_padded = 0, right_padded = 0;
24845 int c IF_LINT (= 0); /* cmp->glyph_len can't be zero; see Bug#8512 */
24846 XChar2b char2b;
24847 struct font_metrics *pcm;
24848 int font_not_found_p;
24849 ptrdiff_t pos;
24850
24851 for (glyph_len = cmp->glyph_len; glyph_len > 0; glyph_len--)
24852 if ((c = COMPOSITION_GLYPH (cmp, glyph_len - 1)) != '\t')
24853 break;
24854 if (glyph_len < cmp->glyph_len)
24855 right_padded = 1;
24856 for (i = 0; i < glyph_len; i++)
24857 {
24858 if ((c = COMPOSITION_GLYPH (cmp, i)) != '\t')
24859 break;
24860 cmp->offsets[i * 2] = cmp->offsets[i * 2 + 1] = 0;
24861 }
24862 if (i > 0)
24863 left_padded = 1;
24864
24865 pos = (STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
24866 : IT_CHARPOS (*it));
24867 /* If no suitable font is found, use the default font. */
24868 font_not_found_p = font == NULL;
24869 if (font_not_found_p)
24870 {
24871 face = face->ascii_face;
24872 font = face->font;
24873 }
24874 boff = font->baseline_offset;
24875 if (font->vertical_centering)
24876 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
24877 font_ascent = FONT_BASE (font) + boff;
24878 font_descent = FONT_DESCENT (font) - boff;
24879 font_height = FONT_HEIGHT (font);
24880
24881 cmp->font = (void *) font;
24882
24883 pcm = NULL;
24884 if (! font_not_found_p)
24885 {
24886 get_char_face_and_encoding (it->f, c, it->face_id,
24887 &char2b, 0);
24888 pcm = get_per_char_metric (font, &char2b);
24889 }
24890
24891 /* Initialize the bounding box. */
24892 if (pcm)
24893 {
24894 width = cmp->glyph_len > 0 ? pcm->width : 0;
24895 ascent = pcm->ascent;
24896 descent = pcm->descent;
24897 lbearing = pcm->lbearing;
24898 rbearing = pcm->rbearing;
24899 }
24900 else
24901 {
24902 width = cmp->glyph_len > 0 ? font->space_width : 0;
24903 ascent = FONT_BASE (font);
24904 descent = FONT_DESCENT (font);
24905 lbearing = 0;
24906 rbearing = width;
24907 }
24908
24909 rightmost = width;
24910 leftmost = 0;
24911 lowest = - descent + boff;
24912 highest = ascent + boff;
24913
24914 if (! font_not_found_p
24915 && font->default_ascent
24916 && CHAR_TABLE_P (Vuse_default_ascent)
24917 && !NILP (Faref (Vuse_default_ascent,
24918 make_number (it->char_to_display))))
24919 highest = font->default_ascent + boff;
24920
24921 /* Draw the first glyph at the normal position. It may be
24922 shifted to right later if some other glyphs are drawn
24923 at the left. */
24924 cmp->offsets[i * 2] = 0;
24925 cmp->offsets[i * 2 + 1] = boff;
24926 cmp->lbearing = lbearing;
24927 cmp->rbearing = rbearing;
24928
24929 /* Set cmp->offsets for the remaining glyphs. */
24930 for (i++; i < glyph_len; i++)
24931 {
24932 int left, right, btm, top;
24933 int ch = COMPOSITION_GLYPH (cmp, i);
24934 int face_id;
24935 struct face *this_face;
24936
24937 if (ch == '\t')
24938 ch = ' ';
24939 face_id = FACE_FOR_CHAR (it->f, face, ch, pos, it->string);
24940 this_face = FACE_FROM_ID (it->f, face_id);
24941 font = this_face->font;
24942
24943 if (font == NULL)
24944 pcm = NULL;
24945 else
24946 {
24947 get_char_face_and_encoding (it->f, ch, face_id,
24948 &char2b, 0);
24949 pcm = get_per_char_metric (font, &char2b);
24950 }
24951 if (! pcm)
24952 cmp->offsets[i * 2] = cmp->offsets[i * 2 + 1] = 0;
24953 else
24954 {
24955 width = pcm->width;
24956 ascent = pcm->ascent;
24957 descent = pcm->descent;
24958 lbearing = pcm->lbearing;
24959 rbearing = pcm->rbearing;
24960 if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS)
24961 {
24962 /* Relative composition with or without
24963 alternate chars. */
24964 left = (leftmost + rightmost - width) / 2;
24965 btm = - descent + boff;
24966 if (font->relative_compose
24967 && (! CHAR_TABLE_P (Vignore_relative_composition)
24968 || NILP (Faref (Vignore_relative_composition,
24969 make_number (ch)))))
24970 {
24971
24972 if (- descent >= font->relative_compose)
24973 /* One extra pixel between two glyphs. */
24974 btm = highest + 1;
24975 else if (ascent <= 0)
24976 /* One extra pixel between two glyphs. */
24977 btm = lowest - 1 - ascent - descent;
24978 }
24979 }
24980 else
24981 {
24982 /* A composition rule is specified by an integer
24983 value that encodes global and new reference
24984 points (GREF and NREF). GREF and NREF are
24985 specified by numbers as below:
24986
24987 0---1---2 -- ascent
24988 | |
24989 | |
24990 | |
24991 9--10--11 -- center
24992 | |
24993 ---3---4---5--- baseline
24994 | |
24995 6---7---8 -- descent
24996 */
24997 int rule = COMPOSITION_RULE (cmp, i);
24998 int gref, nref, grefx, grefy, nrefx, nrefy, xoff, yoff;
24999
25000 COMPOSITION_DECODE_RULE (rule, gref, nref, xoff, yoff);
25001 grefx = gref % 3, nrefx = nref % 3;
25002 grefy = gref / 3, nrefy = nref / 3;
25003 if (xoff)
25004 xoff = font_height * (xoff - 128) / 256;
25005 if (yoff)
25006 yoff = font_height * (yoff - 128) / 256;
25007
25008 left = (leftmost
25009 + grefx * (rightmost - leftmost) / 2
25010 - nrefx * width / 2
25011 + xoff);
25012
25013 btm = ((grefy == 0 ? highest
25014 : grefy == 1 ? 0
25015 : grefy == 2 ? lowest
25016 : (highest + lowest) / 2)
25017 - (nrefy == 0 ? ascent + descent
25018 : nrefy == 1 ? descent - boff
25019 : nrefy == 2 ? 0
25020 : (ascent + descent) / 2)
25021 + yoff);
25022 }
25023
25024 cmp->offsets[i * 2] = left;
25025 cmp->offsets[i * 2 + 1] = btm + descent;
25026
25027 /* Update the bounding box of the overall glyphs. */
25028 if (width > 0)
25029 {
25030 right = left + width;
25031 if (left < leftmost)
25032 leftmost = left;
25033 if (right > rightmost)
25034 rightmost = right;
25035 }
25036 top = btm + descent + ascent;
25037 if (top > highest)
25038 highest = top;
25039 if (btm < lowest)
25040 lowest = btm;
25041
25042 if (cmp->lbearing > left + lbearing)
25043 cmp->lbearing = left + lbearing;
25044 if (cmp->rbearing < left + rbearing)
25045 cmp->rbearing = left + rbearing;
25046 }
25047 }
25048
25049 /* If there are glyphs whose x-offsets are negative,
25050 shift all glyphs to the right and make all x-offsets
25051 non-negative. */
25052 if (leftmost < 0)
25053 {
25054 for (i = 0; i < cmp->glyph_len; i++)
25055 cmp->offsets[i * 2] -= leftmost;
25056 rightmost -= leftmost;
25057 cmp->lbearing -= leftmost;
25058 cmp->rbearing -= leftmost;
25059 }
25060
25061 if (left_padded && cmp->lbearing < 0)
25062 {
25063 for (i = 0; i < cmp->glyph_len; i++)
25064 cmp->offsets[i * 2] -= cmp->lbearing;
25065 rightmost -= cmp->lbearing;
25066 cmp->rbearing -= cmp->lbearing;
25067 cmp->lbearing = 0;
25068 }
25069 if (right_padded && rightmost < cmp->rbearing)
25070 {
25071 rightmost = cmp->rbearing;
25072 }
25073
25074 cmp->pixel_width = rightmost;
25075 cmp->ascent = highest;
25076 cmp->descent = - lowest;
25077 if (cmp->ascent < font_ascent)
25078 cmp->ascent = font_ascent;
25079 if (cmp->descent < font_descent)
25080 cmp->descent = font_descent;
25081 }
25082
25083 if (it->glyph_row
25084 && (cmp->lbearing < 0
25085 || cmp->rbearing > cmp->pixel_width))
25086 it->glyph_row->contains_overlapping_glyphs_p = 1;
25087
25088 it->pixel_width = cmp->pixel_width;
25089 it->ascent = it->phys_ascent = cmp->ascent;
25090 it->descent = it->phys_descent = cmp->descent;
25091 if (face->box != FACE_NO_BOX)
25092 {
25093 int thick = face->box_line_width;
25094
25095 if (thick > 0)
25096 {
25097 it->ascent += thick;
25098 it->descent += thick;
25099 }
25100 else
25101 thick = - thick;
25102
25103 if (it->start_of_box_run_p)
25104 it->pixel_width += thick;
25105 if (it->end_of_box_run_p)
25106 it->pixel_width += thick;
25107 }
25108
25109 /* If face has an overline, add the height of the overline
25110 (1 pixel) and a 1 pixel margin to the character height. */
25111 if (face->overline_p)
25112 it->ascent += overline_margin;
25113
25114 take_vertical_position_into_account (it);
25115 if (it->ascent < 0)
25116 it->ascent = 0;
25117 if (it->descent < 0)
25118 it->descent = 0;
25119
25120 if (it->glyph_row && cmp->glyph_len > 0)
25121 append_composite_glyph (it);
25122 }
25123 else if (it->what == IT_COMPOSITION)
25124 {
25125 /* A dynamic (automatic) composition. */
25126 struct face *face = FACE_FROM_ID (it->f, it->face_id);
25127 Lisp_Object gstring;
25128 struct font_metrics metrics;
25129
25130 it->nglyphs = 1;
25131
25132 gstring = composition_gstring_from_id (it->cmp_it.id);
25133 it->pixel_width
25134 = composition_gstring_width (gstring, it->cmp_it.from, it->cmp_it.to,
25135 &metrics);
25136 if (it->glyph_row
25137 && (metrics.lbearing < 0 || metrics.rbearing > metrics.width))
25138 it->glyph_row->contains_overlapping_glyphs_p = 1;
25139 it->ascent = it->phys_ascent = metrics.ascent;
25140 it->descent = it->phys_descent = metrics.descent;
25141 if (face->box != FACE_NO_BOX)
25142 {
25143 int thick = face->box_line_width;
25144
25145 if (thick > 0)
25146 {
25147 it->ascent += thick;
25148 it->descent += thick;
25149 }
25150 else
25151 thick = - thick;
25152
25153 if (it->start_of_box_run_p)
25154 it->pixel_width += thick;
25155 if (it->end_of_box_run_p)
25156 it->pixel_width += thick;
25157 }
25158 /* If face has an overline, add the height of the overline
25159 (1 pixel) and a 1 pixel margin to the character height. */
25160 if (face->overline_p)
25161 it->ascent += overline_margin;
25162 take_vertical_position_into_account (it);
25163 if (it->ascent < 0)
25164 it->ascent = 0;
25165 if (it->descent < 0)
25166 it->descent = 0;
25167
25168 if (it->glyph_row)
25169 append_composite_glyph (it);
25170 }
25171 else if (it->what == IT_GLYPHLESS)
25172 produce_glyphless_glyph (it, 0, Qnil);
25173 else if (it->what == IT_IMAGE)
25174 produce_image_glyph (it);
25175 else if (it->what == IT_STRETCH)
25176 produce_stretch_glyph (it);
25177 #ifdef HAVE_XWIDGETS
25178 else if (it->what == IT_XWIDGET)
25179 produce_xwidget_glyph (it);
25180 #endif
25181 done:
25182 /* Accumulate dimensions. Note: can't assume that it->descent > 0
25183 because this isn't true for images with `:ascent 100'. */
25184 xassert (it->ascent >= 0 && it->descent >= 0);
25185 if (it->area == TEXT_AREA)
25186 it->current_x += it->pixel_width;
25187
25188 if (extra_line_spacing > 0)
25189 {
25190 it->descent += extra_line_spacing;
25191 if (extra_line_spacing > it->max_extra_line_spacing)
25192 it->max_extra_line_spacing = extra_line_spacing;
25193 }
25194
25195 it->max_ascent = max (it->max_ascent, it->ascent);
25196 it->max_descent = max (it->max_descent, it->descent);
25197 it->max_phys_ascent = max (it->max_phys_ascent, it->phys_ascent);
25198 it->max_phys_descent = max (it->max_phys_descent, it->phys_descent);
25199 }
25200
25201 /* EXPORT for RIF:
25202 Output LEN glyphs starting at START at the nominal cursor position.
25203 Advance the nominal cursor over the text. The global variable
25204 updated_window contains the window being updated, updated_row is
25205 the glyph row being updated, and updated_area is the area of that
25206 row being updated. */
25207
25208 void
25209 x_write_glyphs (struct glyph *start, int len)
25210 {
25211 int x, hpos, chpos = updated_window->phys_cursor.hpos;
25212
25213 xassert (updated_window && updated_row);
25214 /* When the window is hscrolled, cursor hpos can legitimately be out
25215 of bounds, but we draw the cursor at the corresponding window
25216 margin in that case. */
25217 if (!updated_row->reversed_p && chpos < 0)
25218 chpos = 0;
25219 if (updated_row->reversed_p && chpos >= updated_row->used[TEXT_AREA])
25220 chpos = updated_row->used[TEXT_AREA] - 1;
25221
25222 BLOCK_INPUT;
25223
25224 /* Write glyphs. */
25225
25226 hpos = start - updated_row->glyphs[updated_area];
25227 x = draw_glyphs (updated_window, output_cursor.x,
25228 updated_row, updated_area,
25229 hpos, hpos + len,
25230 DRAW_NORMAL_TEXT, 0);
25231
25232 /* Invalidate old phys cursor if the glyph at its hpos is redrawn. */
25233 if (updated_area == TEXT_AREA
25234 && updated_window->phys_cursor_on_p
25235 && updated_window->phys_cursor.vpos == output_cursor.vpos
25236 && chpos >= hpos
25237 && chpos < hpos + len)
25238 updated_window->phys_cursor_on_p = 0;
25239
25240 UNBLOCK_INPUT;
25241
25242 /* Advance the output cursor. */
25243 output_cursor.hpos += len;
25244 output_cursor.x = x;
25245 }
25246
25247
25248 /* EXPORT for RIF:
25249 Insert LEN glyphs from START at the nominal cursor position. */
25250
25251 void
25252 x_insert_glyphs (struct glyph *start, int len)
25253 {
25254 struct frame *f;
25255 struct window *w;
25256 int line_height, shift_by_width, shifted_region_width;
25257 struct glyph_row *row;
25258 struct glyph *glyph;
25259 int frame_x, frame_y;
25260 ptrdiff_t hpos;
25261
25262 xassert (updated_window && updated_row);
25263 BLOCK_INPUT;
25264 w = updated_window;
25265 f = XFRAME (WINDOW_FRAME (w));
25266
25267 /* Get the height of the line we are in. */
25268 row = updated_row;
25269 line_height = row->height;
25270
25271 /* Get the width of the glyphs to insert. */
25272 shift_by_width = 0;
25273 for (glyph = start; glyph < start + len; ++glyph)
25274 shift_by_width += glyph->pixel_width;
25275
25276 /* Get the width of the region to shift right. */
25277 shifted_region_width = (window_box_width (w, updated_area)
25278 - output_cursor.x
25279 - shift_by_width);
25280
25281 /* Shift right. */
25282 frame_x = window_box_left (w, updated_area) + output_cursor.x;
25283 frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, output_cursor.y);
25284
25285 FRAME_RIF (f)->shift_glyphs_for_insert (f, frame_x, frame_y, shifted_region_width,
25286 line_height, shift_by_width);
25287
25288 /* Write the glyphs. */
25289 hpos = start - row->glyphs[updated_area];
25290 draw_glyphs (w, output_cursor.x, row, updated_area,
25291 hpos, hpos + len,
25292 DRAW_NORMAL_TEXT, 0);
25293
25294 /* Advance the output cursor. */
25295 output_cursor.hpos += len;
25296 output_cursor.x += shift_by_width;
25297 UNBLOCK_INPUT;
25298 }
25299
25300
25301 /* EXPORT for RIF:
25302 Erase the current text line from the nominal cursor position
25303 (inclusive) to pixel column TO_X (exclusive). The idea is that
25304 everything from TO_X onward is already erased.
25305
25306 TO_X is a pixel position relative to updated_area of
25307 updated_window. TO_X == -1 means clear to the end of this area. */
25308
25309 void
25310 x_clear_end_of_line (int to_x)
25311 {
25312 struct frame *f;
25313 struct window *w = updated_window;
25314 int max_x, min_y, max_y;
25315 int from_x, from_y, to_y;
25316
25317 xassert (updated_window && updated_row);
25318 f = XFRAME (w->frame);
25319
25320 if (updated_row->full_width_p)
25321 max_x = WINDOW_TOTAL_WIDTH (w);
25322 else
25323 max_x = window_box_width (w, updated_area);
25324 max_y = window_text_bottom_y (w);
25325
25326 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
25327 of window. For TO_X > 0, truncate to end of drawing area. */
25328 if (to_x == 0)
25329 return;
25330 else if (to_x < 0)
25331 to_x = max_x;
25332 else
25333 to_x = min (to_x, max_x);
25334
25335 to_y = min (max_y, output_cursor.y + updated_row->height);
25336
25337 /* Notice if the cursor will be cleared by this operation. */
25338 if (!updated_row->full_width_p)
25339 notice_overwritten_cursor (w, updated_area,
25340 output_cursor.x, -1,
25341 updated_row->y,
25342 MATRIX_ROW_BOTTOM_Y (updated_row));
25343
25344 from_x = output_cursor.x;
25345
25346 /* Translate to frame coordinates. */
25347 if (updated_row->full_width_p)
25348 {
25349 from_x = WINDOW_TO_FRAME_PIXEL_X (w, from_x);
25350 to_x = WINDOW_TO_FRAME_PIXEL_X (w, to_x);
25351 }
25352 else
25353 {
25354 int area_left = window_box_left (w, updated_area);
25355 from_x += area_left;
25356 to_x += area_left;
25357 }
25358
25359 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
25360 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, max (min_y, output_cursor.y));
25361 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, to_y);
25362
25363 /* Prevent inadvertently clearing to end of the X window. */
25364 if (to_x > from_x && to_y > from_y)
25365 {
25366 BLOCK_INPUT;
25367 FRAME_RIF (f)->clear_frame_area (f, from_x, from_y,
25368 to_x - from_x, to_y - from_y);
25369 UNBLOCK_INPUT;
25370 }
25371 }
25372
25373 #endif /* HAVE_WINDOW_SYSTEM */
25374
25375
25376 \f
25377 /***********************************************************************
25378 Cursor types
25379 ***********************************************************************/
25380
25381 /* Value is the internal representation of the specified cursor type
25382 ARG. If type is BAR_CURSOR, return in *WIDTH the specified width
25383 of the bar cursor. */
25384
25385 static enum text_cursor_kinds
25386 get_specified_cursor_type (Lisp_Object arg, int *width)
25387 {
25388 enum text_cursor_kinds type;
25389
25390 if (NILP (arg))
25391 return NO_CURSOR;
25392
25393 if (EQ (arg, Qbox))
25394 return FILLED_BOX_CURSOR;
25395
25396 if (EQ (arg, Qhollow))
25397 return HOLLOW_BOX_CURSOR;
25398
25399 if (EQ (arg, Qbar))
25400 {
25401 *width = 2;
25402 return BAR_CURSOR;
25403 }
25404
25405 if (CONSP (arg)
25406 && EQ (XCAR (arg), Qbar)
25407 && RANGED_INTEGERP (0, XCDR (arg), INT_MAX))
25408 {
25409 *width = XINT (XCDR (arg));
25410 return BAR_CURSOR;
25411 }
25412
25413 if (EQ (arg, Qhbar))
25414 {
25415 *width = 2;
25416 return HBAR_CURSOR;
25417 }
25418
25419 if (CONSP (arg)
25420 && EQ (XCAR (arg), Qhbar)
25421 && RANGED_INTEGERP (0, XCDR (arg), INT_MAX))
25422 {
25423 *width = XINT (XCDR (arg));
25424 return HBAR_CURSOR;
25425 }
25426
25427 /* Treat anything unknown as "hollow box cursor".
25428 It was bad to signal an error; people have trouble fixing
25429 .Xdefaults with Emacs, when it has something bad in it. */
25430 type = HOLLOW_BOX_CURSOR;
25431
25432 return type;
25433 }
25434
25435 /* Set the default cursor types for specified frame. */
25436 void
25437 set_frame_cursor_types (struct frame *f, Lisp_Object arg)
25438 {
25439 int width = 1;
25440 Lisp_Object tem;
25441
25442 FRAME_DESIRED_CURSOR (f) = get_specified_cursor_type (arg, &width);
25443 FRAME_CURSOR_WIDTH (f) = width;
25444
25445 /* By default, set up the blink-off state depending on the on-state. */
25446
25447 tem = Fassoc (arg, Vblink_cursor_alist);
25448 if (!NILP (tem))
25449 {
25450 FRAME_BLINK_OFF_CURSOR (f)
25451 = get_specified_cursor_type (XCDR (tem), &width);
25452 FRAME_BLINK_OFF_CURSOR_WIDTH (f) = width;
25453 }
25454 else
25455 FRAME_BLINK_OFF_CURSOR (f) = DEFAULT_CURSOR;
25456 }
25457
25458
25459 #ifdef HAVE_WINDOW_SYSTEM
25460
25461 /* Return the cursor we want to be displayed in window W. Return
25462 width of bar/hbar cursor through WIDTH arg. Return with
25463 ACTIVE_CURSOR arg set to 1 if cursor in window W is `active'
25464 (i.e. if the `system caret' should track this cursor).
25465
25466 In a mini-buffer window, we want the cursor only to appear if we
25467 are reading input from this window. For the selected window, we
25468 want the cursor type given by the frame parameter or buffer local
25469 setting of cursor-type. If explicitly marked off, draw no cursor.
25470 In all other cases, we want a hollow box cursor. */
25471
25472 static enum text_cursor_kinds
25473 get_window_cursor_type (struct window *w, struct glyph *glyph, int *width,
25474 int *active_cursor)
25475 {
25476 struct frame *f = XFRAME (w->frame);
25477 struct buffer *b = XBUFFER (w->buffer);
25478 int cursor_type = DEFAULT_CURSOR;
25479 Lisp_Object alt_cursor;
25480 int non_selected = 0;
25481
25482 *active_cursor = 1;
25483
25484 /* Echo area */
25485 if (cursor_in_echo_area
25486 && FRAME_HAS_MINIBUF_P (f)
25487 && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
25488 {
25489 if (w == XWINDOW (echo_area_window))
25490 {
25491 if (EQ (BVAR (b, cursor_type), Qt) || NILP (BVAR (b, cursor_type)))
25492 {
25493 *width = FRAME_CURSOR_WIDTH (f);
25494 return FRAME_DESIRED_CURSOR (f);
25495 }
25496 else
25497 return get_specified_cursor_type (BVAR (b, cursor_type), width);
25498 }
25499
25500 *active_cursor = 0;
25501 non_selected = 1;
25502 }
25503
25504 /* Detect a nonselected window or nonselected frame. */
25505 else if (w != XWINDOW (f->selected_window)
25506 || f != FRAME_X_DISPLAY_INFO (f)->x_highlight_frame)
25507 {
25508 *active_cursor = 0;
25509
25510 if (MINI_WINDOW_P (w) && minibuf_level == 0)
25511 return NO_CURSOR;
25512
25513 non_selected = 1;
25514 }
25515
25516 /* Never display a cursor in a window in which cursor-type is nil. */
25517 if (NILP (BVAR (b, cursor_type)))
25518 return NO_CURSOR;
25519
25520 /* Get the normal cursor type for this window. */
25521 if (EQ (BVAR (b, cursor_type), Qt))
25522 {
25523 cursor_type = FRAME_DESIRED_CURSOR (f);
25524 *width = FRAME_CURSOR_WIDTH (f);
25525 }
25526 else
25527 cursor_type = get_specified_cursor_type (BVAR (b, cursor_type), width);
25528
25529 /* Use cursor-in-non-selected-windows instead
25530 for non-selected window or frame. */
25531 if (non_selected)
25532 {
25533 alt_cursor = BVAR (b, cursor_in_non_selected_windows);
25534 if (!EQ (Qt, alt_cursor))
25535 return get_specified_cursor_type (alt_cursor, width);
25536 /* t means modify the normal cursor type. */
25537 if (cursor_type == FILLED_BOX_CURSOR)
25538 cursor_type = HOLLOW_BOX_CURSOR;
25539 else if (cursor_type == BAR_CURSOR && *width > 1)
25540 --*width;
25541 return cursor_type;
25542 }
25543
25544 /* Use normal cursor if not blinked off. */
25545 if (!w->cursor_off_p)
25546 {
25547
25548 #ifdef HAVE_XWIDGETS
25549 if (glyph != NULL && glyph->type == XWIDGET_GLYPH){
25550 //printf("attempt xwidget cursor avoidance in get_window_cursor_type\n");
25551 return NO_CURSOR;
25552 }
25553 #endif
25554 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
25555 {
25556 if (cursor_type == FILLED_BOX_CURSOR)
25557 {
25558 /* Using a block cursor on large images can be very annoying.
25559 So use a hollow cursor for "large" images.
25560 If image is not transparent (no mask), also use hollow cursor. */
25561 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
25562 if (img != NULL && IMAGEP (img->spec))
25563 {
25564 /* Arbitrarily, interpret "Large" as >32x32 and >NxN
25565 where N = size of default frame font size.
25566 This should cover most of the "tiny" icons people may use. */
25567 if (!img->mask
25568 || img->width > max (32, WINDOW_FRAME_COLUMN_WIDTH (w))
25569 || img->height > max (32, WINDOW_FRAME_LINE_HEIGHT (w)))
25570 cursor_type = HOLLOW_BOX_CURSOR;
25571 }
25572 }
25573 else if (cursor_type != NO_CURSOR)
25574 {
25575 /* Display current only supports BOX and HOLLOW cursors for images.
25576 So for now, unconditionally use a HOLLOW cursor when cursor is
25577 not a solid box cursor. */
25578 cursor_type = HOLLOW_BOX_CURSOR;
25579 }
25580 }
25581 return cursor_type;
25582 }
25583
25584 /* Cursor is blinked off, so determine how to "toggle" it. */
25585
25586 /* First look for an entry matching the buffer's cursor-type in blink-cursor-alist. */
25587 if ((alt_cursor = Fassoc (BVAR (b, cursor_type), Vblink_cursor_alist), !NILP (alt_cursor)))
25588 return get_specified_cursor_type (XCDR (alt_cursor), width);
25589
25590 /* Then see if frame has specified a specific blink off cursor type. */
25591 if (FRAME_BLINK_OFF_CURSOR (f) != DEFAULT_CURSOR)
25592 {
25593 *width = FRAME_BLINK_OFF_CURSOR_WIDTH (f);
25594 return FRAME_BLINK_OFF_CURSOR (f);
25595 }
25596
25597 #if 0
25598 /* Some people liked having a permanently visible blinking cursor,
25599 while others had very strong opinions against it. So it was
25600 decided to remove it. KFS 2003-09-03 */
25601
25602 /* Finally perform built-in cursor blinking:
25603 filled box <-> hollow box
25604 wide [h]bar <-> narrow [h]bar
25605 narrow [h]bar <-> no cursor
25606 other type <-> no cursor */
25607
25608 if (cursor_type == FILLED_BOX_CURSOR)
25609 return HOLLOW_BOX_CURSOR;
25610
25611 if ((cursor_type == BAR_CURSOR || cursor_type == HBAR_CURSOR) && *width > 1)
25612 {
25613 *width = 1;
25614 return cursor_type;
25615 }
25616 #endif
25617
25618 return NO_CURSOR;
25619 }
25620
25621
25622 /* Notice when the text cursor of window W has been completely
25623 overwritten by a drawing operation that outputs glyphs in AREA
25624 starting at X0 and ending at X1 in the line starting at Y0 and
25625 ending at Y1. X coordinates are area-relative. X1 < 0 means all
25626 the rest of the line after X0 has been written. Y coordinates
25627 are window-relative. */
25628
25629 static void
25630 notice_overwritten_cursor (struct window *w, enum glyph_row_area area,
25631 int x0, int x1, int y0, int y1)
25632 {
25633 int cx0, cx1, cy0, cy1;
25634 struct glyph_row *row;
25635
25636 if (!w->phys_cursor_on_p)
25637 return;
25638 if (area != TEXT_AREA)
25639 return;
25640
25641 if (w->phys_cursor.vpos < 0
25642 || w->phys_cursor.vpos >= w->current_matrix->nrows
25643 || (row = w->current_matrix->rows + w->phys_cursor.vpos,
25644 !(row->enabled_p && row->displays_text_p)))
25645 return;
25646
25647 if (row->cursor_in_fringe_p)
25648 {
25649 row->cursor_in_fringe_p = 0;
25650 draw_fringe_bitmap (w, row, row->reversed_p);
25651 w->phys_cursor_on_p = 0;
25652 return;
25653 }
25654
25655 cx0 = w->phys_cursor.x;
25656 cx1 = cx0 + w->phys_cursor_width;
25657 if (x0 > cx0 || (x1 >= 0 && x1 < cx1))
25658 return;
25659
25660 /* The cursor image will be completely removed from the
25661 screen if the output area intersects the cursor area in
25662 y-direction. When we draw in [y0 y1[, and some part of
25663 the cursor is at y < y0, that part must have been drawn
25664 before. When scrolling, the cursor is erased before
25665 actually scrolling, so we don't come here. When not
25666 scrolling, the rows above the old cursor row must have
25667 changed, and in this case these rows must have written
25668 over the cursor image.
25669
25670 Likewise if part of the cursor is below y1, with the
25671 exception of the cursor being in the first blank row at
25672 the buffer and window end because update_text_area
25673 doesn't draw that row. (Except when it does, but
25674 that's handled in update_text_area.) */
25675
25676 cy0 = w->phys_cursor.y;
25677 cy1 = cy0 + w->phys_cursor_height;
25678 if ((y0 < cy0 || y0 >= cy1) && (y1 <= cy0 || y1 >= cy1))
25679 return;
25680
25681 w->phys_cursor_on_p = 0;
25682 }
25683
25684 #endif /* HAVE_WINDOW_SYSTEM */
25685
25686 \f
25687 /************************************************************************
25688 Mouse Face
25689 ************************************************************************/
25690
25691 #ifdef HAVE_WINDOW_SYSTEM
25692
25693 /* EXPORT for RIF:
25694 Fix the display of area AREA of overlapping row ROW in window W
25695 with respect to the overlapping part OVERLAPS. */
25696
25697 void
25698 x_fix_overlapping_area (struct window *w, struct glyph_row *row,
25699 enum glyph_row_area area, int overlaps)
25700 {
25701 int i, x;
25702
25703 BLOCK_INPUT;
25704
25705 x = 0;
25706 for (i = 0; i < row->used[area];)
25707 {
25708 if (row->glyphs[area][i].overlaps_vertically_p)
25709 {
25710 int start = i, start_x = x;
25711
25712 do
25713 {
25714 x += row->glyphs[area][i].pixel_width;
25715 ++i;
25716 }
25717 while (i < row->used[area]
25718 && row->glyphs[area][i].overlaps_vertically_p);
25719
25720 draw_glyphs (w, start_x, row, area,
25721 start, i,
25722 DRAW_NORMAL_TEXT, overlaps);
25723 }
25724 else
25725 {
25726 x += row->glyphs[area][i].pixel_width;
25727 ++i;
25728 }
25729 }
25730
25731 UNBLOCK_INPUT;
25732 }
25733
25734
25735 /* EXPORT:
25736 Draw the cursor glyph of window W in glyph row ROW. See the
25737 comment of draw_glyphs for the meaning of HL. */
25738
25739 void
25740 draw_phys_cursor_glyph (struct window *w, struct glyph_row *row,
25741 enum draw_glyphs_face hl)
25742 {
25743 /* If cursor hpos is out of bounds, don't draw garbage. This can
25744 happen in mini-buffer windows when switching between echo area
25745 glyphs and mini-buffer. */
25746 if ((row->reversed_p
25747 ? (w->phys_cursor.hpos >= 0)
25748 : (w->phys_cursor.hpos < row->used[TEXT_AREA])))
25749 {
25750 int on_p = w->phys_cursor_on_p;
25751 int x1;
25752 int hpos = w->phys_cursor.hpos;
25753
25754 /* When the window is hscrolled, cursor hpos can legitimately be
25755 out of bounds, but we draw the cursor at the corresponding
25756 window margin in that case. */
25757 if (!row->reversed_p && hpos < 0)
25758 hpos = 0;
25759 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
25760 hpos = row->used[TEXT_AREA] - 1;
25761
25762 x1 = draw_glyphs (w, w->phys_cursor.x, row, TEXT_AREA, hpos, hpos + 1,
25763 hl, 0);
25764 w->phys_cursor_on_p = on_p;
25765
25766 if (hl == DRAW_CURSOR)
25767 w->phys_cursor_width = x1 - w->phys_cursor.x;
25768 /* When we erase the cursor, and ROW is overlapped by other
25769 rows, make sure that these overlapping parts of other rows
25770 are redrawn. */
25771 else if (hl == DRAW_NORMAL_TEXT && row->overlapped_p)
25772 {
25773 w->phys_cursor_width = x1 - w->phys_cursor.x;
25774
25775 if (row > w->current_matrix->rows
25776 && MATRIX_ROW_OVERLAPS_SUCC_P (row - 1))
25777 x_fix_overlapping_area (w, row - 1, TEXT_AREA,
25778 OVERLAPS_ERASED_CURSOR);
25779
25780 if (MATRIX_ROW_BOTTOM_Y (row) < window_text_bottom_y (w)
25781 && MATRIX_ROW_OVERLAPS_PRED_P (row + 1))
25782 x_fix_overlapping_area (w, row + 1, TEXT_AREA,
25783 OVERLAPS_ERASED_CURSOR);
25784 }
25785 }
25786 }
25787
25788
25789 /* EXPORT:
25790 Erase the image of a cursor of window W from the screen. */
25791
25792 void
25793 erase_phys_cursor (struct window *w)
25794 {
25795 struct frame *f = XFRAME (w->frame);
25796 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
25797 int hpos = w->phys_cursor.hpos;
25798 int vpos = w->phys_cursor.vpos;
25799 int mouse_face_here_p = 0;
25800 struct glyph_matrix *active_glyphs = w->current_matrix;
25801 struct glyph_row *cursor_row;
25802 struct glyph *cursor_glyph;
25803 enum draw_glyphs_face hl;
25804
25805 /* No cursor displayed or row invalidated => nothing to do on the
25806 screen. */
25807 if (w->phys_cursor_type == NO_CURSOR)
25808 goto mark_cursor_off;
25809
25810 /* VPOS >= active_glyphs->nrows means that window has been resized.
25811 Don't bother to erase the cursor. */
25812 if (vpos >= active_glyphs->nrows)
25813 goto mark_cursor_off;
25814
25815 /* If row containing cursor is marked invalid, there is nothing we
25816 can do. */
25817 cursor_row = MATRIX_ROW (active_glyphs, vpos);
25818 if (!cursor_row->enabled_p)
25819 goto mark_cursor_off;
25820
25821 /* If line spacing is > 0, old cursor may only be partially visible in
25822 window after split-window. So adjust visible height. */
25823 cursor_row->visible_height = min (cursor_row->visible_height,
25824 window_text_bottom_y (w) - cursor_row->y);
25825
25826 /* If row is completely invisible, don't attempt to delete a cursor which
25827 isn't there. This can happen if cursor is at top of a window, and
25828 we switch to a buffer with a header line in that window. */
25829 if (cursor_row->visible_height <= 0)
25830 goto mark_cursor_off;
25831
25832 /* If cursor is in the fringe, erase by drawing actual bitmap there. */
25833 if (cursor_row->cursor_in_fringe_p)
25834 {
25835 cursor_row->cursor_in_fringe_p = 0;
25836 draw_fringe_bitmap (w, cursor_row, cursor_row->reversed_p);
25837 goto mark_cursor_off;
25838 }
25839
25840 /* This can happen when the new row is shorter than the old one.
25841 In this case, either draw_glyphs or clear_end_of_line
25842 should have cleared the cursor. Note that we wouldn't be
25843 able to erase the cursor in this case because we don't have a
25844 cursor glyph at hand. */
25845 if ((cursor_row->reversed_p
25846 ? (w->phys_cursor.hpos < 0)
25847 : (w->phys_cursor.hpos >= cursor_row->used[TEXT_AREA])))
25848 goto mark_cursor_off;
25849
25850 /* When the window is hscrolled, cursor hpos can legitimately be out
25851 of bounds, but we draw the cursor at the corresponding window
25852 margin in that case. */
25853 if (!cursor_row->reversed_p && hpos < 0)
25854 hpos = 0;
25855 if (cursor_row->reversed_p && hpos >= cursor_row->used[TEXT_AREA])
25856 hpos = cursor_row->used[TEXT_AREA] - 1;
25857
25858 /* If the cursor is in the mouse face area, redisplay that when
25859 we clear the cursor. */
25860 if (! NILP (hlinfo->mouse_face_window)
25861 && coords_in_mouse_face_p (w, hpos, vpos)
25862 /* Don't redraw the cursor's spot in mouse face if it is at the
25863 end of a line (on a newline). The cursor appears there, but
25864 mouse highlighting does not. */
25865 && cursor_row->used[TEXT_AREA] > hpos && hpos >= 0)
25866 mouse_face_here_p = 1;
25867
25868 /* Maybe clear the display under the cursor. */
25869 if (w->phys_cursor_type == HOLLOW_BOX_CURSOR)
25870 {
25871 int x, y, left_x;
25872 int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
25873 int width;
25874
25875 cursor_glyph = get_phys_cursor_glyph (w);
25876 if (cursor_glyph == NULL)
25877 goto mark_cursor_off;
25878
25879 width = cursor_glyph->pixel_width;
25880 left_x = window_box_left_offset (w, TEXT_AREA);
25881 x = w->phys_cursor.x;
25882 if (x < left_x)
25883 width -= left_x - x;
25884 width = min (width, window_box_width (w, TEXT_AREA) - x);
25885 y = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, cursor_row->y));
25886 x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, max (x, left_x));
25887
25888 if (width > 0)
25889 FRAME_RIF (f)->clear_frame_area (f, x, y, width, cursor_row->visible_height);
25890 }
25891
25892 /* Erase the cursor by redrawing the character underneath it. */
25893 if (mouse_face_here_p)
25894 hl = DRAW_MOUSE_FACE;
25895 else
25896 hl = DRAW_NORMAL_TEXT;
25897 draw_phys_cursor_glyph (w, cursor_row, hl);
25898
25899 mark_cursor_off:
25900 w->phys_cursor_on_p = 0;
25901 w->phys_cursor_type = NO_CURSOR;
25902 }
25903
25904
25905 /* EXPORT:
25906 Display or clear cursor of window W. If ON is zero, clear the
25907 cursor. If it is non-zero, display the cursor. If ON is nonzero,
25908 where to put the cursor is specified by HPOS, VPOS, X and Y. */
25909
25910 void
25911 display_and_set_cursor (struct window *w, int on,
25912 int hpos, int vpos, int x, int y)
25913 {
25914 struct frame *f = XFRAME (w->frame);
25915 int new_cursor_type;
25916 int new_cursor_width;
25917 int active_cursor;
25918 struct glyph_row *glyph_row;
25919 struct glyph *glyph;
25920
25921 /* This is pointless on invisible frames, and dangerous on garbaged
25922 windows and frames; in the latter case, the frame or window may
25923 be in the midst of changing its size, and x and y may be off the
25924 window. */
25925 if (! FRAME_VISIBLE_P (f)
25926 || FRAME_GARBAGED_P (f)
25927 || vpos >= w->current_matrix->nrows
25928 || hpos >= w->current_matrix->matrix_w)
25929 return;
25930
25931 /* If cursor is off and we want it off, return quickly. */
25932 if (!on && !w->phys_cursor_on_p)
25933 return;
25934
25935 glyph_row = MATRIX_ROW (w->current_matrix, vpos);
25936 /* If cursor row is not enabled, we don't really know where to
25937 display the cursor. */
25938 if (!glyph_row->enabled_p)
25939 {
25940 w->phys_cursor_on_p = 0;
25941 return;
25942 }
25943
25944 glyph = NULL;
25945 if (!glyph_row->exact_window_width_line_p
25946 || (0 <= hpos && hpos < glyph_row->used[TEXT_AREA]))
25947 glyph = glyph_row->glyphs[TEXT_AREA] + hpos;
25948
25949 xassert (interrupt_input_blocked);
25950
25951 /* Set new_cursor_type to the cursor we want to be displayed. */
25952 new_cursor_type = get_window_cursor_type (w, glyph,
25953 &new_cursor_width, &active_cursor);
25954
25955 /* If cursor is currently being shown and we don't want it to be or
25956 it is in the wrong place, or the cursor type is not what we want,
25957 erase it. */
25958 if (w->phys_cursor_on_p
25959 && (!on
25960 || w->phys_cursor.x != x
25961 || w->phys_cursor.y != y
25962 || new_cursor_type != w->phys_cursor_type
25963 || ((new_cursor_type == BAR_CURSOR || new_cursor_type == HBAR_CURSOR)
25964 && new_cursor_width != w->phys_cursor_width)))
25965 erase_phys_cursor (w);
25966
25967 /* Don't check phys_cursor_on_p here because that flag is only set
25968 to zero in some cases where we know that the cursor has been
25969 completely erased, to avoid the extra work of erasing the cursor
25970 twice. In other words, phys_cursor_on_p can be 1 and the cursor
25971 still not be visible, or it has only been partly erased. */
25972 if (on)
25973 {
25974 w->phys_cursor_ascent = glyph_row->ascent;
25975 w->phys_cursor_height = glyph_row->height;
25976
25977 /* Set phys_cursor_.* before x_draw_.* is called because some
25978 of them may need the information. */
25979 w->phys_cursor.x = x;
25980 w->phys_cursor.y = glyph_row->y;
25981 w->phys_cursor.hpos = hpos;
25982 w->phys_cursor.vpos = vpos;
25983 }
25984
25985 FRAME_RIF (f)->draw_window_cursor (w, glyph_row, x, y,
25986 new_cursor_type, new_cursor_width,
25987 on, active_cursor);
25988 }
25989
25990
25991 /* Switch the display of W's cursor on or off, according to the value
25992 of ON. */
25993
25994 static void
25995 update_window_cursor (struct window *w, int on)
25996 {
25997 /* Don't update cursor in windows whose frame is in the process
25998 of being deleted. */
25999 if (w->current_matrix)
26000 {
26001 int hpos = w->phys_cursor.hpos;
26002 int vpos = w->phys_cursor.vpos;
26003 struct glyph_row *row;
26004
26005 if (vpos >= w->current_matrix->nrows
26006 || hpos >= w->current_matrix->matrix_w)
26007 return;
26008
26009 row = MATRIX_ROW (w->current_matrix, vpos);
26010
26011 /* When the window is hscrolled, cursor hpos can legitimately be
26012 out of bounds, but we draw the cursor at the corresponding
26013 window margin in that case. */
26014 if (!row->reversed_p && hpos < 0)
26015 hpos = 0;
26016 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
26017 hpos = row->used[TEXT_AREA] - 1;
26018
26019 BLOCK_INPUT;
26020 display_and_set_cursor (w, on, hpos, vpos,
26021 w->phys_cursor.x, w->phys_cursor.y);
26022 UNBLOCK_INPUT;
26023 }
26024 }
26025
26026
26027 /* Call update_window_cursor with parameter ON_P on all leaf windows
26028 in the window tree rooted at W. */
26029
26030 static void
26031 update_cursor_in_window_tree (struct window *w, int on_p)
26032 {
26033 while (w)
26034 {
26035 if (!NILP (w->hchild))
26036 update_cursor_in_window_tree (XWINDOW (w->hchild), on_p);
26037 else if (!NILP (w->vchild))
26038 update_cursor_in_window_tree (XWINDOW (w->vchild), on_p);
26039 else
26040 update_window_cursor (w, on_p);
26041
26042 w = NILP (w->next) ? 0 : XWINDOW (w->next);
26043 }
26044 }
26045
26046
26047 /* EXPORT:
26048 Display the cursor on window W, or clear it, according to ON_P.
26049 Don't change the cursor's position. */
26050
26051 void
26052 x_update_cursor (struct frame *f, int on_p)
26053 {
26054 update_cursor_in_window_tree (XWINDOW (f->root_window), on_p);
26055 }
26056
26057
26058 /* EXPORT:
26059 Clear the cursor of window W to background color, and mark the
26060 cursor as not shown. This is used when the text where the cursor
26061 is about to be rewritten. */
26062
26063 void
26064 x_clear_cursor (struct window *w)
26065 {
26066 if (FRAME_VISIBLE_P (XFRAME (w->frame)) && w->phys_cursor_on_p)
26067 update_window_cursor (w, 0);
26068 }
26069
26070 #endif /* HAVE_WINDOW_SYSTEM */
26071
26072 /* Implementation of draw_row_with_mouse_face for GUI sessions, GPM,
26073 and MSDOS. */
26074 static void
26075 draw_row_with_mouse_face (struct window *w, int start_x, struct glyph_row *row,
26076 int start_hpos, int end_hpos,
26077 enum draw_glyphs_face draw)
26078 {
26079 #ifdef HAVE_WINDOW_SYSTEM
26080 if (FRAME_WINDOW_P (XFRAME (w->frame)))
26081 {
26082 draw_glyphs (w, start_x, row, TEXT_AREA, start_hpos, end_hpos, draw, 0);
26083 return;
26084 }
26085 #endif
26086 #if defined (HAVE_GPM) || defined (MSDOS) || defined (WINDOWSNT)
26087 tty_draw_row_with_mouse_face (w, row, start_hpos, end_hpos, draw);
26088 #endif
26089 }
26090
26091 /* Display the active region described by mouse_face_* according to DRAW. */
26092
26093 static void
26094 show_mouse_face (Mouse_HLInfo *hlinfo, enum draw_glyphs_face draw)
26095 {
26096 struct window *w = XWINDOW (hlinfo->mouse_face_window);
26097 struct frame *f = XFRAME (WINDOW_FRAME (w));
26098
26099 if (/* If window is in the process of being destroyed, don't bother
26100 to do anything. */
26101 w->current_matrix != NULL
26102 /* Don't update mouse highlight if hidden */
26103 && (draw != DRAW_MOUSE_FACE || !hlinfo->mouse_face_hidden)
26104 /* Recognize when we are called to operate on rows that don't exist
26105 anymore. This can happen when a window is split. */
26106 && hlinfo->mouse_face_end_row < w->current_matrix->nrows)
26107 {
26108 int phys_cursor_on_p = w->phys_cursor_on_p;
26109 struct glyph_row *row, *first, *last;
26110
26111 first = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_beg_row);
26112 last = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_end_row);
26113
26114 for (row = first; row <= last && row->enabled_p; ++row)
26115 {
26116 int start_hpos, end_hpos, start_x;
26117
26118 /* For all but the first row, the highlight starts at column 0. */
26119 if (row == first)
26120 {
26121 /* R2L rows have BEG and END in reversed order, but the
26122 screen drawing geometry is always left to right. So
26123 we need to mirror the beginning and end of the
26124 highlighted area in R2L rows. */
26125 if (!row->reversed_p)
26126 {
26127 start_hpos = hlinfo->mouse_face_beg_col;
26128 start_x = hlinfo->mouse_face_beg_x;
26129 }
26130 else if (row == last)
26131 {
26132 start_hpos = hlinfo->mouse_face_end_col;
26133 start_x = hlinfo->mouse_face_end_x;
26134 }
26135 else
26136 {
26137 start_hpos = 0;
26138 start_x = 0;
26139 }
26140 }
26141 else if (row->reversed_p && row == last)
26142 {
26143 start_hpos = hlinfo->mouse_face_end_col;
26144 start_x = hlinfo->mouse_face_end_x;
26145 }
26146 else
26147 {
26148 start_hpos = 0;
26149 start_x = 0;
26150 }
26151
26152 if (row == last)
26153 {
26154 if (!row->reversed_p)
26155 end_hpos = hlinfo->mouse_face_end_col;
26156 else if (row == first)
26157 end_hpos = hlinfo->mouse_face_beg_col;
26158 else
26159 {
26160 end_hpos = row->used[TEXT_AREA];
26161 if (draw == DRAW_NORMAL_TEXT)
26162 row->fill_line_p = 1; /* Clear to end of line */
26163 }
26164 }
26165 else if (row->reversed_p && row == first)
26166 end_hpos = hlinfo->mouse_face_beg_col;
26167 else
26168 {
26169 end_hpos = row->used[TEXT_AREA];
26170 if (draw == DRAW_NORMAL_TEXT)
26171 row->fill_line_p = 1; /* Clear to end of line */
26172 }
26173
26174 if (end_hpos > start_hpos)
26175 {
26176 draw_row_with_mouse_face (w, start_x, row,
26177 start_hpos, end_hpos, draw);
26178
26179 row->mouse_face_p
26180 = draw == DRAW_MOUSE_FACE || draw == DRAW_IMAGE_RAISED;
26181 }
26182 }
26183
26184 #ifdef HAVE_WINDOW_SYSTEM
26185 /* When we've written over the cursor, arrange for it to
26186 be displayed again. */
26187 if (FRAME_WINDOW_P (f)
26188 && phys_cursor_on_p && !w->phys_cursor_on_p)
26189 {
26190 int hpos = w->phys_cursor.hpos;
26191
26192 /* When the window is hscrolled, cursor hpos can legitimately be
26193 out of bounds, but we draw the cursor at the corresponding
26194 window margin in that case. */
26195 if (!row->reversed_p && hpos < 0)
26196 hpos = 0;
26197 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
26198 hpos = row->used[TEXT_AREA] - 1;
26199
26200 BLOCK_INPUT;
26201 display_and_set_cursor (w, 1, hpos, w->phys_cursor.vpos,
26202 w->phys_cursor.x, w->phys_cursor.y);
26203 UNBLOCK_INPUT;
26204 }
26205 #endif /* HAVE_WINDOW_SYSTEM */
26206 }
26207
26208 #ifdef HAVE_WINDOW_SYSTEM
26209 /* Change the mouse cursor. */
26210 if (FRAME_WINDOW_P (f))
26211 {
26212 if (draw == DRAW_NORMAL_TEXT
26213 && !EQ (hlinfo->mouse_face_window, f->tool_bar_window))
26214 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->text_cursor);
26215 else if (draw == DRAW_MOUSE_FACE)
26216 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->hand_cursor);
26217 else
26218 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->nontext_cursor);
26219 }
26220 #endif /* HAVE_WINDOW_SYSTEM */
26221 }
26222
26223 /* EXPORT:
26224 Clear out the mouse-highlighted active region.
26225 Redraw it un-highlighted first. Value is non-zero if mouse
26226 face was actually drawn unhighlighted. */
26227
26228 int
26229 clear_mouse_face (Mouse_HLInfo *hlinfo)
26230 {
26231 int cleared = 0;
26232
26233 if (!hlinfo->mouse_face_hidden && !NILP (hlinfo->mouse_face_window))
26234 {
26235 show_mouse_face (hlinfo, DRAW_NORMAL_TEXT);
26236 cleared = 1;
26237 }
26238
26239 hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
26240 hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
26241 hlinfo->mouse_face_window = Qnil;
26242 hlinfo->mouse_face_overlay = Qnil;
26243 return cleared;
26244 }
26245
26246 /* Return non-zero if the coordinates HPOS and VPOS on windows W are
26247 within the mouse face on that window. */
26248 static int
26249 coords_in_mouse_face_p (struct window *w, int hpos, int vpos)
26250 {
26251 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame));
26252
26253 /* Quickly resolve the easy cases. */
26254 if (!(WINDOWP (hlinfo->mouse_face_window)
26255 && XWINDOW (hlinfo->mouse_face_window) == w))
26256 return 0;
26257 if (vpos < hlinfo->mouse_face_beg_row
26258 || vpos > hlinfo->mouse_face_end_row)
26259 return 0;
26260 if (vpos > hlinfo->mouse_face_beg_row
26261 && vpos < hlinfo->mouse_face_end_row)
26262 return 1;
26263
26264 if (!MATRIX_ROW (w->current_matrix, vpos)->reversed_p)
26265 {
26266 if (hlinfo->mouse_face_beg_row == hlinfo->mouse_face_end_row)
26267 {
26268 if (hlinfo->mouse_face_beg_col <= hpos && hpos < hlinfo->mouse_face_end_col)
26269 return 1;
26270 }
26271 else if ((vpos == hlinfo->mouse_face_beg_row
26272 && hpos >= hlinfo->mouse_face_beg_col)
26273 || (vpos == hlinfo->mouse_face_end_row
26274 && hpos < hlinfo->mouse_face_end_col))
26275 return 1;
26276 }
26277 else
26278 {
26279 if (hlinfo->mouse_face_beg_row == hlinfo->mouse_face_end_row)
26280 {
26281 if (hlinfo->mouse_face_end_col < hpos && hpos <= hlinfo->mouse_face_beg_col)
26282 return 1;
26283 }
26284 else if ((vpos == hlinfo->mouse_face_beg_row
26285 && hpos <= hlinfo->mouse_face_beg_col)
26286 || (vpos == hlinfo->mouse_face_end_row
26287 && hpos > hlinfo->mouse_face_end_col))
26288 return 1;
26289 }
26290 return 0;
26291 }
26292
26293
26294 /* EXPORT:
26295 Non-zero if physical cursor of window W is within mouse face. */
26296
26297 int
26298 cursor_in_mouse_face_p (struct window *w)
26299 {
26300 int hpos = w->phys_cursor.hpos;
26301 int vpos = w->phys_cursor.vpos;
26302 struct glyph_row *row = MATRIX_ROW (w->current_matrix, vpos);
26303
26304 /* When the window is hscrolled, cursor hpos can legitimately be out
26305 of bounds, but we draw the cursor at the corresponding window
26306 margin in that case. */
26307 if (!row->reversed_p && hpos < 0)
26308 hpos = 0;
26309 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
26310 hpos = row->used[TEXT_AREA] - 1;
26311
26312 return coords_in_mouse_face_p (w, hpos, vpos);
26313 }
26314
26315
26316 \f
26317 /* Find the glyph rows START_ROW and END_ROW of window W that display
26318 characters between buffer positions START_CHARPOS and END_CHARPOS
26319 (excluding END_CHARPOS). DISP_STRING is a display string that
26320 covers these buffer positions. This is similar to
26321 row_containing_pos, but is more accurate when bidi reordering makes
26322 buffer positions change non-linearly with glyph rows. */
26323 static void
26324 rows_from_pos_range (struct window *w,
26325 ptrdiff_t start_charpos, ptrdiff_t end_charpos,
26326 Lisp_Object disp_string,
26327 struct glyph_row **start, struct glyph_row **end)
26328 {
26329 struct glyph_row *first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
26330 int last_y = window_text_bottom_y (w);
26331 struct glyph_row *row;
26332
26333 *start = NULL;
26334 *end = NULL;
26335
26336 while (!first->enabled_p
26337 && first < MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w))
26338 first++;
26339
26340 /* Find the START row. */
26341 for (row = first;
26342 row->enabled_p && MATRIX_ROW_BOTTOM_Y (row) <= last_y;
26343 row++)
26344 {
26345 /* A row can potentially be the START row if the range of the
26346 characters it displays intersects the range
26347 [START_CHARPOS..END_CHARPOS). */
26348 if (! ((start_charpos < MATRIX_ROW_START_CHARPOS (row)
26349 && end_charpos < MATRIX_ROW_START_CHARPOS (row))
26350 /* See the commentary in row_containing_pos, for the
26351 explanation of the complicated way to check whether
26352 some position is beyond the end of the characters
26353 displayed by a row. */
26354 || ((start_charpos > MATRIX_ROW_END_CHARPOS (row)
26355 || (start_charpos == MATRIX_ROW_END_CHARPOS (row)
26356 && !row->ends_at_zv_p
26357 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
26358 && (end_charpos > MATRIX_ROW_END_CHARPOS (row)
26359 || (end_charpos == MATRIX_ROW_END_CHARPOS (row)
26360 && !row->ends_at_zv_p
26361 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))))))
26362 {
26363 /* Found a candidate row. Now make sure at least one of the
26364 glyphs it displays has a charpos from the range
26365 [START_CHARPOS..END_CHARPOS).
26366
26367 This is not obvious because bidi reordering could make
26368 buffer positions of a row be 1,2,3,102,101,100, and if we
26369 want to highlight characters in [50..60), we don't want
26370 this row, even though [50..60) does intersect [1..103),
26371 the range of character positions given by the row's start
26372 and end positions. */
26373 struct glyph *g = row->glyphs[TEXT_AREA];
26374 struct glyph *e = g + row->used[TEXT_AREA];
26375
26376 while (g < e)
26377 {
26378 if (((BUFFERP (g->object) || INTEGERP (g->object))
26379 && start_charpos <= g->charpos && g->charpos < end_charpos)
26380 /* A glyph that comes from DISP_STRING is by
26381 definition to be highlighted. */
26382 || EQ (g->object, disp_string))
26383 *start = row;
26384 g++;
26385 }
26386 if (*start)
26387 break;
26388 }
26389 }
26390
26391 /* Find the END row. */
26392 if (!*start
26393 /* If the last row is partially visible, start looking for END
26394 from that row, instead of starting from FIRST. */
26395 && !(row->enabled_p
26396 && row->y < last_y && MATRIX_ROW_BOTTOM_Y (row) > last_y))
26397 row = first;
26398 for ( ; row->enabled_p && MATRIX_ROW_BOTTOM_Y (row) <= last_y; row++)
26399 {
26400 struct glyph_row *next = row + 1;
26401 ptrdiff_t next_start = MATRIX_ROW_START_CHARPOS (next);
26402
26403 if (!next->enabled_p
26404 || next >= MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w)
26405 /* The first row >= START whose range of displayed characters
26406 does NOT intersect the range [START_CHARPOS..END_CHARPOS]
26407 is the row END + 1. */
26408 || (start_charpos < next_start
26409 && end_charpos < next_start)
26410 || ((start_charpos > MATRIX_ROW_END_CHARPOS (next)
26411 || (start_charpos == MATRIX_ROW_END_CHARPOS (next)
26412 && !next->ends_at_zv_p
26413 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (next)))
26414 && (end_charpos > MATRIX_ROW_END_CHARPOS (next)
26415 || (end_charpos == MATRIX_ROW_END_CHARPOS (next)
26416 && !next->ends_at_zv_p
26417 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (next)))))
26418 {
26419 *end = row;
26420 break;
26421 }
26422 else
26423 {
26424 /* If the next row's edges intersect [START_CHARPOS..END_CHARPOS],
26425 but none of the characters it displays are in the range, it is
26426 also END + 1. */
26427 struct glyph *g = next->glyphs[TEXT_AREA];
26428 struct glyph *s = g;
26429 struct glyph *e = g + next->used[TEXT_AREA];
26430
26431 while (g < e)
26432 {
26433 if (((BUFFERP (g->object) || INTEGERP (g->object))
26434 && ((start_charpos <= g->charpos && g->charpos < end_charpos)
26435 /* If the buffer position of the first glyph in
26436 the row is equal to END_CHARPOS, it means
26437 the last character to be highlighted is the
26438 newline of ROW, and we must consider NEXT as
26439 END, not END+1. */
26440 || (((!next->reversed_p && g == s)
26441 || (next->reversed_p && g == e - 1))
26442 && (g->charpos == end_charpos
26443 /* Special case for when NEXT is an
26444 empty line at ZV. */
26445 || (g->charpos == -1
26446 && !row->ends_at_zv_p
26447 && next_start == end_charpos)))))
26448 /* A glyph that comes from DISP_STRING is by
26449 definition to be highlighted. */
26450 || EQ (g->object, disp_string))
26451 break;
26452 g++;
26453 }
26454 if (g == e)
26455 {
26456 *end = row;
26457 break;
26458 }
26459 /* The first row that ends at ZV must be the last to be
26460 highlighted. */
26461 else if (next->ends_at_zv_p)
26462 {
26463 *end = next;
26464 break;
26465 }
26466 }
26467 }
26468 }
26469
26470 /* This function sets the mouse_face_* elements of HLINFO, assuming
26471 the mouse cursor is on a glyph with buffer charpos MOUSE_CHARPOS in
26472 window WINDOW. START_CHARPOS and END_CHARPOS are buffer positions
26473 for the overlay or run of text properties specifying the mouse
26474 face. BEFORE_STRING and AFTER_STRING, if non-nil, are a
26475 before-string and after-string that must also be highlighted.
26476 DISP_STRING, if non-nil, is a display string that may cover some
26477 or all of the highlighted text. */
26478
26479 static void
26480 mouse_face_from_buffer_pos (Lisp_Object window,
26481 Mouse_HLInfo *hlinfo,
26482 ptrdiff_t mouse_charpos,
26483 ptrdiff_t start_charpos,
26484 ptrdiff_t end_charpos,
26485 Lisp_Object before_string,
26486 Lisp_Object after_string,
26487 Lisp_Object disp_string)
26488 {
26489 struct window *w = XWINDOW (window);
26490 struct glyph_row *first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
26491 struct glyph_row *r1, *r2;
26492 struct glyph *glyph, *end;
26493 ptrdiff_t ignore, pos;
26494 int x;
26495
26496 xassert (NILP (disp_string) || STRINGP (disp_string));
26497 xassert (NILP (before_string) || STRINGP (before_string));
26498 xassert (NILP (after_string) || STRINGP (after_string));
26499
26500 /* Find the rows corresponding to START_CHARPOS and END_CHARPOS. */
26501 rows_from_pos_range (w, start_charpos, end_charpos, disp_string, &r1, &r2);
26502 if (r1 == NULL)
26503 r1 = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
26504 /* If the before-string or display-string contains newlines,
26505 rows_from_pos_range skips to its last row. Move back. */
26506 if (!NILP (before_string) || !NILP (disp_string))
26507 {
26508 struct glyph_row *prev;
26509 while ((prev = r1 - 1, prev >= first)
26510 && MATRIX_ROW_END_CHARPOS (prev) == start_charpos
26511 && prev->used[TEXT_AREA] > 0)
26512 {
26513 struct glyph *beg = prev->glyphs[TEXT_AREA];
26514 glyph = beg + prev->used[TEXT_AREA];
26515 while (--glyph >= beg && INTEGERP (glyph->object));
26516 if (glyph < beg
26517 || !(EQ (glyph->object, before_string)
26518 || EQ (glyph->object, disp_string)))
26519 break;
26520 r1 = prev;
26521 }
26522 }
26523 if (r2 == NULL)
26524 {
26525 r2 = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
26526 hlinfo->mouse_face_past_end = 1;
26527 }
26528 else if (!NILP (after_string))
26529 {
26530 /* If the after-string has newlines, advance to its last row. */
26531 struct glyph_row *next;
26532 struct glyph_row *last
26533 = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
26534
26535 for (next = r2 + 1;
26536 next <= last
26537 && next->used[TEXT_AREA] > 0
26538 && EQ (next->glyphs[TEXT_AREA]->object, after_string);
26539 ++next)
26540 r2 = next;
26541 }
26542 /* The rest of the display engine assumes that mouse_face_beg_row is
26543 either above mouse_face_end_row or identical to it. But with
26544 bidi-reordered continued lines, the row for START_CHARPOS could
26545 be below the row for END_CHARPOS. If so, swap the rows and store
26546 them in correct order. */
26547 if (r1->y > r2->y)
26548 {
26549 struct glyph_row *tem = r2;
26550
26551 r2 = r1;
26552 r1 = tem;
26553 }
26554
26555 hlinfo->mouse_face_beg_y = r1->y;
26556 hlinfo->mouse_face_beg_row = MATRIX_ROW_VPOS (r1, w->current_matrix);
26557 hlinfo->mouse_face_end_y = r2->y;
26558 hlinfo->mouse_face_end_row = MATRIX_ROW_VPOS (r2, w->current_matrix);
26559
26560 /* For a bidi-reordered row, the positions of BEFORE_STRING,
26561 AFTER_STRING, DISP_STRING, START_CHARPOS, and END_CHARPOS
26562 could be anywhere in the row and in any order. The strategy
26563 below is to find the leftmost and the rightmost glyph that
26564 belongs to either of these 3 strings, or whose position is
26565 between START_CHARPOS and END_CHARPOS, and highlight all the
26566 glyphs between those two. This may cover more than just the text
26567 between START_CHARPOS and END_CHARPOS if the range of characters
26568 strides the bidi level boundary, e.g. if the beginning is in R2L
26569 text while the end is in L2R text or vice versa. */
26570 if (!r1->reversed_p)
26571 {
26572 /* This row is in a left to right paragraph. Scan it left to
26573 right. */
26574 glyph = r1->glyphs[TEXT_AREA];
26575 end = glyph + r1->used[TEXT_AREA];
26576 x = r1->x;
26577
26578 /* Skip truncation glyphs at the start of the glyph row. */
26579 if (r1->displays_text_p)
26580 for (; glyph < end
26581 && INTEGERP (glyph->object)
26582 && glyph->charpos < 0;
26583 ++glyph)
26584 x += glyph->pixel_width;
26585
26586 /* Scan the glyph row, looking for BEFORE_STRING, AFTER_STRING,
26587 or DISP_STRING, and the first glyph from buffer whose
26588 position is between START_CHARPOS and END_CHARPOS. */
26589 for (; glyph < end
26590 && !INTEGERP (glyph->object)
26591 && !EQ (glyph->object, disp_string)
26592 && !(BUFFERP (glyph->object)
26593 && (glyph->charpos >= start_charpos
26594 && glyph->charpos < end_charpos));
26595 ++glyph)
26596 {
26597 /* BEFORE_STRING or AFTER_STRING are only relevant if they
26598 are present at buffer positions between START_CHARPOS and
26599 END_CHARPOS, or if they come from an overlay. */
26600 if (EQ (glyph->object, before_string))
26601 {
26602 pos = string_buffer_position (before_string,
26603 start_charpos);
26604 /* If pos == 0, it means before_string came from an
26605 overlay, not from a buffer position. */
26606 if (!pos || (pos >= start_charpos && pos < end_charpos))
26607 break;
26608 }
26609 else if (EQ (glyph->object, after_string))
26610 {
26611 pos = string_buffer_position (after_string, end_charpos);
26612 if (!pos || (pos >= start_charpos && pos < end_charpos))
26613 break;
26614 }
26615 x += glyph->pixel_width;
26616 }
26617 hlinfo->mouse_face_beg_x = x;
26618 hlinfo->mouse_face_beg_col = glyph - r1->glyphs[TEXT_AREA];
26619 }
26620 else
26621 {
26622 /* This row is in a right to left paragraph. Scan it right to
26623 left. */
26624 struct glyph *g;
26625
26626 end = r1->glyphs[TEXT_AREA] - 1;
26627 glyph = end + r1->used[TEXT_AREA];
26628
26629 /* Skip truncation glyphs at the start of the glyph row. */
26630 if (r1->displays_text_p)
26631 for (; glyph > end
26632 && INTEGERP (glyph->object)
26633 && glyph->charpos < 0;
26634 --glyph)
26635 ;
26636
26637 /* Scan the glyph row, looking for BEFORE_STRING, AFTER_STRING,
26638 or DISP_STRING, and the first glyph from buffer whose
26639 position is between START_CHARPOS and END_CHARPOS. */
26640 for (; glyph > end
26641 && !INTEGERP (glyph->object)
26642 && !EQ (glyph->object, disp_string)
26643 && !(BUFFERP (glyph->object)
26644 && (glyph->charpos >= start_charpos
26645 && glyph->charpos < end_charpos));
26646 --glyph)
26647 {
26648 /* BEFORE_STRING or AFTER_STRING are only relevant if they
26649 are present at buffer positions between START_CHARPOS and
26650 END_CHARPOS, or if they come from an overlay. */
26651 if (EQ (glyph->object, before_string))
26652 {
26653 pos = string_buffer_position (before_string, start_charpos);
26654 /* If pos == 0, it means before_string came from an
26655 overlay, not from a buffer position. */
26656 if (!pos || (pos >= start_charpos && pos < end_charpos))
26657 break;
26658 }
26659 else if (EQ (glyph->object, after_string))
26660 {
26661 pos = string_buffer_position (after_string, end_charpos);
26662 if (!pos || (pos >= start_charpos && pos < end_charpos))
26663 break;
26664 }
26665 }
26666
26667 glyph++; /* first glyph to the right of the highlighted area */
26668 for (g = r1->glyphs[TEXT_AREA], x = r1->x; g < glyph; g++)
26669 x += g->pixel_width;
26670 hlinfo->mouse_face_beg_x = x;
26671 hlinfo->mouse_face_beg_col = glyph - r1->glyphs[TEXT_AREA];
26672 }
26673
26674 /* If the highlight ends in a different row, compute GLYPH and END
26675 for the end row. Otherwise, reuse the values computed above for
26676 the row where the highlight begins. */
26677 if (r2 != r1)
26678 {
26679 if (!r2->reversed_p)
26680 {
26681 glyph = r2->glyphs[TEXT_AREA];
26682 end = glyph + r2->used[TEXT_AREA];
26683 x = r2->x;
26684 }
26685 else
26686 {
26687 end = r2->glyphs[TEXT_AREA] - 1;
26688 glyph = end + r2->used[TEXT_AREA];
26689 }
26690 }
26691
26692 if (!r2->reversed_p)
26693 {
26694 /* Skip truncation and continuation glyphs near the end of the
26695 row, and also blanks and stretch glyphs inserted by
26696 extend_face_to_end_of_line. */
26697 while (end > glyph
26698 && INTEGERP ((end - 1)->object))
26699 --end;
26700 /* Scan the rest of the glyph row from the end, looking for the
26701 first glyph that comes from BEFORE_STRING, AFTER_STRING, or
26702 DISP_STRING, or whose position is between START_CHARPOS
26703 and END_CHARPOS */
26704 for (--end;
26705 end > glyph
26706 && !INTEGERP (end->object)
26707 && !EQ (end->object, disp_string)
26708 && !(BUFFERP (end->object)
26709 && (end->charpos >= start_charpos
26710 && end->charpos < end_charpos));
26711 --end)
26712 {
26713 /* BEFORE_STRING or AFTER_STRING are only relevant if they
26714 are present at buffer positions between START_CHARPOS and
26715 END_CHARPOS, or if they come from an overlay. */
26716 if (EQ (end->object, before_string))
26717 {
26718 pos = string_buffer_position (before_string, start_charpos);
26719 if (!pos || (pos >= start_charpos && pos < end_charpos))
26720 break;
26721 }
26722 else if (EQ (end->object, after_string))
26723 {
26724 pos = string_buffer_position (after_string, end_charpos);
26725 if (!pos || (pos >= start_charpos && pos < end_charpos))
26726 break;
26727 }
26728 }
26729 /* Find the X coordinate of the last glyph to be highlighted. */
26730 for (; glyph <= end; ++glyph)
26731 x += glyph->pixel_width;
26732
26733 hlinfo->mouse_face_end_x = x;
26734 hlinfo->mouse_face_end_col = glyph - r2->glyphs[TEXT_AREA];
26735 }
26736 else
26737 {
26738 /* Skip truncation and continuation glyphs near the end of the
26739 row, and also blanks and stretch glyphs inserted by
26740 extend_face_to_end_of_line. */
26741 x = r2->x;
26742 end++;
26743 while (end < glyph
26744 && INTEGERP (end->object))
26745 {
26746 x += end->pixel_width;
26747 ++end;
26748 }
26749 /* Scan the rest of the glyph row from the end, looking for the
26750 first glyph that comes from BEFORE_STRING, AFTER_STRING, or
26751 DISP_STRING, or whose position is between START_CHARPOS
26752 and END_CHARPOS */
26753 for ( ;
26754 end < glyph
26755 && !INTEGERP (end->object)
26756 && !EQ (end->object, disp_string)
26757 && !(BUFFERP (end->object)
26758 && (end->charpos >= start_charpos
26759 && end->charpos < end_charpos));
26760 ++end)
26761 {
26762 /* BEFORE_STRING or AFTER_STRING are only relevant if they
26763 are present at buffer positions between START_CHARPOS and
26764 END_CHARPOS, or if they come from an overlay. */
26765 if (EQ (end->object, before_string))
26766 {
26767 pos = string_buffer_position (before_string, start_charpos);
26768 if (!pos || (pos >= start_charpos && pos < end_charpos))
26769 break;
26770 }
26771 else if (EQ (end->object, after_string))
26772 {
26773 pos = string_buffer_position (after_string, end_charpos);
26774 if (!pos || (pos >= start_charpos && pos < end_charpos))
26775 break;
26776 }
26777 x += end->pixel_width;
26778 }
26779 /* If we exited the above loop because we arrived at the last
26780 glyph of the row, and its buffer position is still not in
26781 range, it means the last character in range is the preceding
26782 newline. Bump the end column and x values to get past the
26783 last glyph. */
26784 if (end == glyph
26785 && BUFFERP (end->object)
26786 && (end->charpos < start_charpos
26787 || end->charpos >= end_charpos))
26788 {
26789 x += end->pixel_width;
26790 ++end;
26791 }
26792 hlinfo->mouse_face_end_x = x;
26793 hlinfo->mouse_face_end_col = end - r2->glyphs[TEXT_AREA];
26794 }
26795
26796 hlinfo->mouse_face_window = window;
26797 hlinfo->mouse_face_face_id
26798 = face_at_buffer_position (w, mouse_charpos, 0, 0, &ignore,
26799 mouse_charpos + 1,
26800 !hlinfo->mouse_face_hidden, -1);
26801 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
26802 }
26803
26804 /* The following function is not used anymore (replaced with
26805 mouse_face_from_string_pos), but I leave it here for the time
26806 being, in case someone would. */
26807
26808 #if 0 /* not used */
26809
26810 /* Find the position of the glyph for position POS in OBJECT in
26811 window W's current matrix, and return in *X, *Y the pixel
26812 coordinates, and return in *HPOS, *VPOS the column/row of the glyph.
26813
26814 RIGHT_P non-zero means return the position of the right edge of the
26815 glyph, RIGHT_P zero means return the left edge position.
26816
26817 If no glyph for POS exists in the matrix, return the position of
26818 the glyph with the next smaller position that is in the matrix, if
26819 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS
26820 exists in the matrix, return the position of the glyph with the
26821 next larger position in OBJECT.
26822
26823 Value is non-zero if a glyph was found. */
26824
26825 static int
26826 fast_find_string_pos (struct window *w, ptrdiff_t pos, Lisp_Object object,
26827 int *hpos, int *vpos, int *x, int *y, int right_p)
26828 {
26829 int yb = window_text_bottom_y (w);
26830 struct glyph_row *r;
26831 struct glyph *best_glyph = NULL;
26832 struct glyph_row *best_row = NULL;
26833 int best_x = 0;
26834
26835 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
26836 r->enabled_p && r->y < yb;
26837 ++r)
26838 {
26839 struct glyph *g = r->glyphs[TEXT_AREA];
26840 struct glyph *e = g + r->used[TEXT_AREA];
26841 int gx;
26842
26843 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
26844 if (EQ (g->object, object))
26845 {
26846 if (g->charpos == pos)
26847 {
26848 best_glyph = g;
26849 best_x = gx;
26850 best_row = r;
26851 goto found;
26852 }
26853 else if (best_glyph == NULL
26854 || ((eabs (g->charpos - pos)
26855 < eabs (best_glyph->charpos - pos))
26856 && (right_p
26857 ? g->charpos < pos
26858 : g->charpos > pos)))
26859 {
26860 best_glyph = g;
26861 best_x = gx;
26862 best_row = r;
26863 }
26864 }
26865 }
26866
26867 found:
26868
26869 if (best_glyph)
26870 {
26871 *x = best_x;
26872 *hpos = best_glyph - best_row->glyphs[TEXT_AREA];
26873
26874 if (right_p)
26875 {
26876 *x += best_glyph->pixel_width;
26877 ++*hpos;
26878 }
26879
26880 *y = best_row->y;
26881 *vpos = best_row - w->current_matrix->rows;
26882 }
26883
26884 return best_glyph != NULL;
26885 }
26886 #endif /* not used */
26887
26888 /* Find the positions of the first and the last glyphs in window W's
26889 current matrix that occlude positions [STARTPOS..ENDPOS] in OBJECT
26890 (assumed to be a string), and return in HLINFO's mouse_face_*
26891 members the pixel and column/row coordinates of those glyphs. */
26892
26893 static void
26894 mouse_face_from_string_pos (struct window *w, Mouse_HLInfo *hlinfo,
26895 Lisp_Object object,
26896 ptrdiff_t startpos, ptrdiff_t endpos)
26897 {
26898 int yb = window_text_bottom_y (w);
26899 struct glyph_row *r;
26900 struct glyph *g, *e;
26901 int gx;
26902 int found = 0;
26903
26904 /* Find the glyph row with at least one position in the range
26905 [STARTPOS..ENDPOS], and the first glyph in that row whose
26906 position belongs to that range. */
26907 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
26908 r->enabled_p && r->y < yb;
26909 ++r)
26910 {
26911 if (!r->reversed_p)
26912 {
26913 g = r->glyphs[TEXT_AREA];
26914 e = g + r->used[TEXT_AREA];
26915 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
26916 if (EQ (g->object, object)
26917 && startpos <= g->charpos && g->charpos <= endpos)
26918 {
26919 hlinfo->mouse_face_beg_row = r - w->current_matrix->rows;
26920 hlinfo->mouse_face_beg_y = r->y;
26921 hlinfo->mouse_face_beg_col = g - r->glyphs[TEXT_AREA];
26922 hlinfo->mouse_face_beg_x = gx;
26923 found = 1;
26924 break;
26925 }
26926 }
26927 else
26928 {
26929 struct glyph *g1;
26930
26931 e = r->glyphs[TEXT_AREA];
26932 g = e + r->used[TEXT_AREA];
26933 for ( ; g > e; --g)
26934 if (EQ ((g-1)->object, object)
26935 && startpos <= (g-1)->charpos && (g-1)->charpos <= endpos)
26936 {
26937 hlinfo->mouse_face_beg_row = r - w->current_matrix->rows;
26938 hlinfo->mouse_face_beg_y = r->y;
26939 hlinfo->mouse_face_beg_col = g - r->glyphs[TEXT_AREA];
26940 for (gx = r->x, g1 = r->glyphs[TEXT_AREA]; g1 < g; ++g1)
26941 gx += g1->pixel_width;
26942 hlinfo->mouse_face_beg_x = gx;
26943 found = 1;
26944 break;
26945 }
26946 }
26947 if (found)
26948 break;
26949 }
26950
26951 if (!found)
26952 return;
26953
26954 /* Starting with the next row, look for the first row which does NOT
26955 include any glyphs whose positions are in the range. */
26956 for (++r; r->enabled_p && r->y < yb; ++r)
26957 {
26958 g = r->glyphs[TEXT_AREA];
26959 e = g + r->used[TEXT_AREA];
26960 found = 0;
26961 for ( ; g < e; ++g)
26962 if (EQ (g->object, object)
26963 && startpos <= g->charpos && g->charpos <= endpos)
26964 {
26965 found = 1;
26966 break;
26967 }
26968 if (!found)
26969 break;
26970 }
26971
26972 /* The highlighted region ends on the previous row. */
26973 r--;
26974
26975 /* Set the end row and its vertical pixel coordinate. */
26976 hlinfo->mouse_face_end_row = r - w->current_matrix->rows;
26977 hlinfo->mouse_face_end_y = r->y;
26978
26979 /* Compute and set the end column and the end column's horizontal
26980 pixel coordinate. */
26981 if (!r->reversed_p)
26982 {
26983 g = r->glyphs[TEXT_AREA];
26984 e = g + r->used[TEXT_AREA];
26985 for ( ; e > g; --e)
26986 if (EQ ((e-1)->object, object)
26987 && startpos <= (e-1)->charpos && (e-1)->charpos <= endpos)
26988 break;
26989 hlinfo->mouse_face_end_col = e - g;
26990
26991 for (gx = r->x; g < e; ++g)
26992 gx += g->pixel_width;
26993 hlinfo->mouse_face_end_x = gx;
26994 }
26995 else
26996 {
26997 e = r->glyphs[TEXT_AREA];
26998 g = e + r->used[TEXT_AREA];
26999 for (gx = r->x ; e < g; ++e)
27000 {
27001 if (EQ (e->object, object)
27002 && startpos <= e->charpos && e->charpos <= endpos)
27003 break;
27004 gx += e->pixel_width;
27005 }
27006 hlinfo->mouse_face_end_col = e - r->glyphs[TEXT_AREA];
27007 hlinfo->mouse_face_end_x = gx;
27008 }
27009 }
27010
27011 #ifdef HAVE_WINDOW_SYSTEM
27012
27013 /* See if position X, Y is within a hot-spot of an image. */
27014
27015 static int
27016 on_hot_spot_p (Lisp_Object hot_spot, int x, int y)
27017 {
27018 if (!CONSP (hot_spot))
27019 return 0;
27020
27021 if (EQ (XCAR (hot_spot), Qrect))
27022 {
27023 /* CDR is (Top-Left . Bottom-Right) = ((x0 . y0) . (x1 . y1)) */
27024 Lisp_Object rect = XCDR (hot_spot);
27025 Lisp_Object tem;
27026 if (!CONSP (rect))
27027 return 0;
27028 if (!CONSP (XCAR (rect)))
27029 return 0;
27030 if (!CONSP (XCDR (rect)))
27031 return 0;
27032 if (!(tem = XCAR (XCAR (rect)), INTEGERP (tem) && x >= XINT (tem)))
27033 return 0;
27034 if (!(tem = XCDR (XCAR (rect)), INTEGERP (tem) && y >= XINT (tem)))
27035 return 0;
27036 if (!(tem = XCAR (XCDR (rect)), INTEGERP (tem) && x <= XINT (tem)))
27037 return 0;
27038 if (!(tem = XCDR (XCDR (rect)), INTEGERP (tem) && y <= XINT (tem)))
27039 return 0;
27040 return 1;
27041 }
27042 else if (EQ (XCAR (hot_spot), Qcircle))
27043 {
27044 /* CDR is (Center . Radius) = ((x0 . y0) . r) */
27045 Lisp_Object circ = XCDR (hot_spot);
27046 Lisp_Object lr, lx0, ly0;
27047 if (CONSP (circ)
27048 && CONSP (XCAR (circ))
27049 && (lr = XCDR (circ), INTEGERP (lr) || FLOATP (lr))
27050 && (lx0 = XCAR (XCAR (circ)), INTEGERP (lx0))
27051 && (ly0 = XCDR (XCAR (circ)), INTEGERP (ly0)))
27052 {
27053 double r = XFLOATINT (lr);
27054 double dx = XINT (lx0) - x;
27055 double dy = XINT (ly0) - y;
27056 return (dx * dx + dy * dy <= r * r);
27057 }
27058 }
27059 else if (EQ (XCAR (hot_spot), Qpoly))
27060 {
27061 /* CDR is [x0 y0 x1 y1 x2 y2 ...x(n-1) y(n-1)] */
27062 if (VECTORP (XCDR (hot_spot)))
27063 {
27064 struct Lisp_Vector *v = XVECTOR (XCDR (hot_spot));
27065 Lisp_Object *poly = v->contents;
27066 ptrdiff_t n = v->header.size;
27067 ptrdiff_t i;
27068 int inside = 0;
27069 Lisp_Object lx, ly;
27070 int x0, y0;
27071
27072 /* Need an even number of coordinates, and at least 3 edges. */
27073 if (n < 6 || n & 1)
27074 return 0;
27075
27076 /* Count edge segments intersecting line from (X,Y) to (X,infinity).
27077 If count is odd, we are inside polygon. Pixels on edges
27078 may or may not be included depending on actual geometry of the
27079 polygon. */
27080 if ((lx = poly[n-2], !INTEGERP (lx))
27081 || (ly = poly[n-1], !INTEGERP (lx)))
27082 return 0;
27083 x0 = XINT (lx), y0 = XINT (ly);
27084 for (i = 0; i < n; i += 2)
27085 {
27086 int x1 = x0, y1 = y0;
27087 if ((lx = poly[i], !INTEGERP (lx))
27088 || (ly = poly[i+1], !INTEGERP (ly)))
27089 return 0;
27090 x0 = XINT (lx), y0 = XINT (ly);
27091
27092 /* Does this segment cross the X line? */
27093 if (x0 >= x)
27094 {
27095 if (x1 >= x)
27096 continue;
27097 }
27098 else if (x1 < x)
27099 continue;
27100 if (y > y0 && y > y1)
27101 continue;
27102 if (y < y0 + ((y1 - y0) * (x - x0)) / (x1 - x0))
27103 inside = !inside;
27104 }
27105 return inside;
27106 }
27107 }
27108 return 0;
27109 }
27110
27111 Lisp_Object
27112 find_hot_spot (Lisp_Object map, int x, int y)
27113 {
27114 while (CONSP (map))
27115 {
27116 if (CONSP (XCAR (map))
27117 && on_hot_spot_p (XCAR (XCAR (map)), x, y))
27118 return XCAR (map);
27119 map = XCDR (map);
27120 }
27121
27122 return Qnil;
27123 }
27124
27125 DEFUN ("lookup-image-map", Flookup_image_map, Slookup_image_map,
27126 3, 3, 0,
27127 doc: /* Lookup in image map MAP coordinates X and Y.
27128 An image map is an alist where each element has the format (AREA ID PLIST).
27129 An AREA is specified as either a rectangle, a circle, or a polygon:
27130 A rectangle is a cons (rect . ((x0 . y0) . (x1 . y1))) specifying the
27131 pixel coordinates of the upper left and bottom right corners.
27132 A circle is a cons (circle . ((x0 . y0) . r)) specifying the center
27133 and the radius of the circle; r may be a float or integer.
27134 A polygon is a cons (poly . [x0 y0 x1 y1 ...]) where each pair in the
27135 vector describes one corner in the polygon.
27136 Returns the alist element for the first matching AREA in MAP. */)
27137 (Lisp_Object map, Lisp_Object x, Lisp_Object y)
27138 {
27139 if (NILP (map))
27140 return Qnil;
27141
27142 CHECK_NUMBER (x);
27143 CHECK_NUMBER (y);
27144
27145 return find_hot_spot (map,
27146 clip_to_bounds (INT_MIN, XINT (x), INT_MAX),
27147 clip_to_bounds (INT_MIN, XINT (y), INT_MAX));
27148 }
27149
27150
27151 /* Display frame CURSOR, optionally using shape defined by POINTER. */
27152 static void
27153 define_frame_cursor1 (struct frame *f, Cursor cursor, Lisp_Object pointer)
27154 {
27155 /* Do not change cursor shape while dragging mouse. */
27156 if (!NILP (do_mouse_tracking))
27157 return;
27158
27159 if (!NILP (pointer))
27160 {
27161 if (EQ (pointer, Qarrow))
27162 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
27163 else if (EQ (pointer, Qhand))
27164 cursor = FRAME_X_OUTPUT (f)->hand_cursor;
27165 else if (EQ (pointer, Qtext))
27166 cursor = FRAME_X_OUTPUT (f)->text_cursor;
27167 else if (EQ (pointer, intern ("hdrag")))
27168 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
27169 #ifdef HAVE_X_WINDOWS
27170 else if (EQ (pointer, intern ("vdrag")))
27171 cursor = FRAME_X_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
27172 #endif
27173 else if (EQ (pointer, intern ("hourglass")))
27174 cursor = FRAME_X_OUTPUT (f)->hourglass_cursor;
27175 else if (EQ (pointer, Qmodeline))
27176 cursor = FRAME_X_OUTPUT (f)->modeline_cursor;
27177 else
27178 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
27179 }
27180
27181 if (cursor != No_Cursor)
27182 FRAME_RIF (f)->define_frame_cursor (f, cursor);
27183 }
27184
27185 #endif /* HAVE_WINDOW_SYSTEM */
27186
27187 /* Take proper action when mouse has moved to the mode or header line
27188 or marginal area AREA of window W, x-position X and y-position Y.
27189 X is relative to the start of the text display area of W, so the
27190 width of bitmap areas and scroll bars must be subtracted to get a
27191 position relative to the start of the mode line. */
27192
27193 static void
27194 note_mode_line_or_margin_highlight (Lisp_Object window, int x, int y,
27195 enum window_part area)
27196 {
27197 struct window *w = XWINDOW (window);
27198 struct frame *f = XFRAME (w->frame);
27199 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
27200 #ifdef HAVE_WINDOW_SYSTEM
27201 Display_Info *dpyinfo;
27202 #endif
27203 Cursor cursor = No_Cursor;
27204 Lisp_Object pointer = Qnil;
27205 int dx, dy, width, height;
27206 ptrdiff_t charpos;
27207 Lisp_Object string, object = Qnil;
27208 Lisp_Object pos IF_LINT (= Qnil), help;
27209
27210 Lisp_Object mouse_face;
27211 int original_x_pixel = x;
27212 struct glyph * glyph = NULL, * row_start_glyph = NULL;
27213 struct glyph_row *row IF_LINT (= 0);
27214
27215 if (area == ON_MODE_LINE || area == ON_HEADER_LINE)
27216 {
27217 int x0;
27218 struct glyph *end;
27219
27220 /* Kludge alert: mode_line_string takes X/Y in pixels, but
27221 returns them in row/column units! */
27222 string = mode_line_string (w, area, &x, &y, &charpos,
27223 &object, &dx, &dy, &width, &height);
27224
27225 row = (area == ON_MODE_LINE
27226 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
27227 : MATRIX_HEADER_LINE_ROW (w->current_matrix));
27228
27229 /* Find the glyph under the mouse pointer. */
27230 if (row->mode_line_p && row->enabled_p)
27231 {
27232 glyph = row_start_glyph = row->glyphs[TEXT_AREA];
27233 end = glyph + row->used[TEXT_AREA];
27234
27235 for (x0 = original_x_pixel;
27236 glyph < end && x0 >= glyph->pixel_width;
27237 ++glyph)
27238 x0 -= glyph->pixel_width;
27239
27240 if (glyph >= end)
27241 glyph = NULL;
27242 }
27243 }
27244 else
27245 {
27246 x -= WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
27247 /* Kludge alert: marginal_area_string takes X/Y in pixels, but
27248 returns them in row/column units! */
27249 string = marginal_area_string (w, area, &x, &y, &charpos,
27250 &object, &dx, &dy, &width, &height);
27251 }
27252
27253 help = Qnil;
27254
27255 #ifdef HAVE_WINDOW_SYSTEM
27256 if (IMAGEP (object))
27257 {
27258 Lisp_Object image_map, hotspot;
27259 if ((image_map = Fplist_get (XCDR (object), QCmap),
27260 !NILP (image_map))
27261 && (hotspot = find_hot_spot (image_map, dx, dy),
27262 CONSP (hotspot))
27263 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
27264 {
27265 Lisp_Object plist;
27266
27267 /* Could check XCAR (hotspot) to see if we enter/leave this hot-spot.
27268 If so, we could look for mouse-enter, mouse-leave
27269 properties in PLIST (and do something...). */
27270 hotspot = XCDR (hotspot);
27271 if (CONSP (hotspot)
27272 && (plist = XCAR (hotspot), CONSP (plist)))
27273 {
27274 pointer = Fplist_get (plist, Qpointer);
27275 if (NILP (pointer))
27276 pointer = Qhand;
27277 help = Fplist_get (plist, Qhelp_echo);
27278 if (!NILP (help))
27279 {
27280 help_echo_string = help;
27281 XSETWINDOW (help_echo_window, w);
27282 help_echo_object = w->buffer;
27283 help_echo_pos = charpos;
27284 }
27285 }
27286 }
27287 if (NILP (pointer))
27288 pointer = Fplist_get (XCDR (object), QCpointer);
27289 }
27290 #endif /* HAVE_WINDOW_SYSTEM */
27291
27292 if (STRINGP (string))
27293 pos = make_number (charpos);
27294
27295 /* Set the help text and mouse pointer. If the mouse is on a part
27296 of the mode line without any text (e.g. past the right edge of
27297 the mode line text), use the default help text and pointer. */
27298 if (STRINGP (string) || area == ON_MODE_LINE)
27299 {
27300 /* Arrange to display the help by setting the global variables
27301 help_echo_string, help_echo_object, and help_echo_pos. */
27302 if (NILP (help))
27303 {
27304 if (STRINGP (string))
27305 help = Fget_text_property (pos, Qhelp_echo, string);
27306
27307 if (!NILP (help))
27308 {
27309 help_echo_string = help;
27310 XSETWINDOW (help_echo_window, w);
27311 help_echo_object = string;
27312 help_echo_pos = charpos;
27313 }
27314 else if (area == ON_MODE_LINE)
27315 {
27316 Lisp_Object default_help
27317 = buffer_local_value_1 (Qmode_line_default_help_echo,
27318 w->buffer);
27319
27320 if (STRINGP (default_help))
27321 {
27322 help_echo_string = default_help;
27323 XSETWINDOW (help_echo_window, w);
27324 help_echo_object = Qnil;
27325 help_echo_pos = -1;
27326 }
27327 }
27328 }
27329
27330 #ifdef HAVE_WINDOW_SYSTEM
27331 /* Change the mouse pointer according to what is under it. */
27332 if (FRAME_WINDOW_P (f))
27333 {
27334 dpyinfo = FRAME_X_DISPLAY_INFO (f);
27335 if (STRINGP (string))
27336 {
27337 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
27338
27339 if (NILP (pointer))
27340 pointer = Fget_text_property (pos, Qpointer, string);
27341
27342 /* Change the mouse pointer according to what is under X/Y. */
27343 if (NILP (pointer)
27344 && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE)))
27345 {
27346 Lisp_Object map;
27347 map = Fget_text_property (pos, Qlocal_map, string);
27348 if (!KEYMAPP (map))
27349 map = Fget_text_property (pos, Qkeymap, string);
27350 if (!KEYMAPP (map))
27351 cursor = dpyinfo->vertical_scroll_bar_cursor;
27352 }
27353 }
27354 else
27355 /* Default mode-line pointer. */
27356 cursor = FRAME_X_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
27357 }
27358 #endif
27359 }
27360
27361 /* Change the mouse face according to what is under X/Y. */
27362 if (STRINGP (string))
27363 {
27364 mouse_face = Fget_text_property (pos, Qmouse_face, string);
27365 if (!NILP (mouse_face)
27366 && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE))
27367 && glyph)
27368 {
27369 Lisp_Object b, e;
27370
27371 struct glyph * tmp_glyph;
27372
27373 int gpos;
27374 int gseq_length;
27375 int total_pixel_width;
27376 ptrdiff_t begpos, endpos, ignore;
27377
27378 int vpos, hpos;
27379
27380 b = Fprevious_single_property_change (make_number (charpos + 1),
27381 Qmouse_face, string, Qnil);
27382 if (NILP (b))
27383 begpos = 0;
27384 else
27385 begpos = XINT (b);
27386
27387 e = Fnext_single_property_change (pos, Qmouse_face, string, Qnil);
27388 if (NILP (e))
27389 endpos = SCHARS (string);
27390 else
27391 endpos = XINT (e);
27392
27393 /* Calculate the glyph position GPOS of GLYPH in the
27394 displayed string, relative to the beginning of the
27395 highlighted part of the string.
27396
27397 Note: GPOS is different from CHARPOS. CHARPOS is the
27398 position of GLYPH in the internal string object. A mode
27399 line string format has structures which are converted to
27400 a flattened string by the Emacs Lisp interpreter. The
27401 internal string is an element of those structures. The
27402 displayed string is the flattened string. */
27403 tmp_glyph = row_start_glyph;
27404 while (tmp_glyph < glyph
27405 && (!(EQ (tmp_glyph->object, glyph->object)
27406 && begpos <= tmp_glyph->charpos
27407 && tmp_glyph->charpos < endpos)))
27408 tmp_glyph++;
27409 gpos = glyph - tmp_glyph;
27410
27411 /* Calculate the length GSEQ_LENGTH of the glyph sequence of
27412 the highlighted part of the displayed string to which
27413 GLYPH belongs. Note: GSEQ_LENGTH is different from
27414 SCHARS (STRING), because the latter returns the length of
27415 the internal string. */
27416 for (tmp_glyph = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
27417 tmp_glyph > glyph
27418 && (!(EQ (tmp_glyph->object, glyph->object)
27419 && begpos <= tmp_glyph->charpos
27420 && tmp_glyph->charpos < endpos));
27421 tmp_glyph--)
27422 ;
27423 gseq_length = gpos + (tmp_glyph - glyph) + 1;
27424
27425 /* Calculate the total pixel width of all the glyphs between
27426 the beginning of the highlighted area and GLYPH. */
27427 total_pixel_width = 0;
27428 for (tmp_glyph = glyph - gpos; tmp_glyph != glyph; tmp_glyph++)
27429 total_pixel_width += tmp_glyph->pixel_width;
27430
27431 /* Pre calculation of re-rendering position. Note: X is in
27432 column units here, after the call to mode_line_string or
27433 marginal_area_string. */
27434 hpos = x - gpos;
27435 vpos = (area == ON_MODE_LINE
27436 ? (w->current_matrix)->nrows - 1
27437 : 0);
27438
27439 /* If GLYPH's position is included in the region that is
27440 already drawn in mouse face, we have nothing to do. */
27441 if ( EQ (window, hlinfo->mouse_face_window)
27442 && (!row->reversed_p
27443 ? (hlinfo->mouse_face_beg_col <= hpos
27444 && hpos < hlinfo->mouse_face_end_col)
27445 /* In R2L rows we swap BEG and END, see below. */
27446 : (hlinfo->mouse_face_end_col <= hpos
27447 && hpos < hlinfo->mouse_face_beg_col))
27448 && hlinfo->mouse_face_beg_row == vpos )
27449 return;
27450
27451 if (clear_mouse_face (hlinfo))
27452 cursor = No_Cursor;
27453
27454 if (!row->reversed_p)
27455 {
27456 hlinfo->mouse_face_beg_col = hpos;
27457 hlinfo->mouse_face_beg_x = original_x_pixel
27458 - (total_pixel_width + dx);
27459 hlinfo->mouse_face_end_col = hpos + gseq_length;
27460 hlinfo->mouse_face_end_x = 0;
27461 }
27462 else
27463 {
27464 /* In R2L rows, show_mouse_face expects BEG and END
27465 coordinates to be swapped. */
27466 hlinfo->mouse_face_end_col = hpos;
27467 hlinfo->mouse_face_end_x = original_x_pixel
27468 - (total_pixel_width + dx);
27469 hlinfo->mouse_face_beg_col = hpos + gseq_length;
27470 hlinfo->mouse_face_beg_x = 0;
27471 }
27472
27473 hlinfo->mouse_face_beg_row = vpos;
27474 hlinfo->mouse_face_end_row = hlinfo->mouse_face_beg_row;
27475 hlinfo->mouse_face_beg_y = 0;
27476 hlinfo->mouse_face_end_y = 0;
27477 hlinfo->mouse_face_past_end = 0;
27478 hlinfo->mouse_face_window = window;
27479
27480 hlinfo->mouse_face_face_id = face_at_string_position (w, string,
27481 charpos,
27482 0, 0, 0,
27483 &ignore,
27484 glyph->face_id,
27485 1);
27486 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
27487
27488 if (NILP (pointer))
27489 pointer = Qhand;
27490 }
27491 else if ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE))
27492 clear_mouse_face (hlinfo);
27493 }
27494 #ifdef HAVE_WINDOW_SYSTEM
27495 if (FRAME_WINDOW_P (f))
27496 define_frame_cursor1 (f, cursor, pointer);
27497 #endif
27498 }
27499
27500
27501 /* EXPORT:
27502 Take proper action when the mouse has moved to position X, Y on
27503 frame F as regards highlighting characters that have mouse-face
27504 properties. Also de-highlighting chars where the mouse was before.
27505 X and Y can be negative or out of range. */
27506
27507 void
27508 note_mouse_highlight (struct frame *f, int x, int y)
27509 {
27510 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
27511 enum window_part part = ON_NOTHING;
27512 Lisp_Object window;
27513 struct window *w;
27514 Cursor cursor = No_Cursor;
27515 Lisp_Object pointer = Qnil; /* Takes precedence over cursor! */
27516 struct buffer *b;
27517
27518 /* When a menu is active, don't highlight because this looks odd. */
27519 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS) || defined (MSDOS)
27520 if (popup_activated ())
27521 return;
27522 #endif
27523
27524 if (NILP (Vmouse_highlight)
27525 || !f->glyphs_initialized_p
27526 || f->pointer_invisible)
27527 return;
27528
27529 hlinfo->mouse_face_mouse_x = x;
27530 hlinfo->mouse_face_mouse_y = y;
27531 hlinfo->mouse_face_mouse_frame = f;
27532
27533 if (hlinfo->mouse_face_defer)
27534 return;
27535
27536 if (gc_in_progress)
27537 {
27538 hlinfo->mouse_face_deferred_gc = 1;
27539 return;
27540 }
27541
27542 /* Which window is that in? */
27543 window = window_from_coordinates (f, x, y, &part, 1);
27544
27545 /* If displaying active text in another window, clear that. */
27546 if (! EQ (window, hlinfo->mouse_face_window)
27547 /* Also clear if we move out of text area in same window. */
27548 || (!NILP (hlinfo->mouse_face_window)
27549 && !NILP (window)
27550 && part != ON_TEXT
27551 && part != ON_MODE_LINE
27552 && part != ON_HEADER_LINE))
27553 clear_mouse_face (hlinfo);
27554
27555 /* Not on a window -> return. */
27556 if (!WINDOWP (window))
27557 return;
27558
27559 /* Reset help_echo_string. It will get recomputed below. */
27560 help_echo_string = Qnil;
27561
27562 /* Convert to window-relative pixel coordinates. */
27563 w = XWINDOW (window);
27564 frame_to_window_pixel_xy (w, &x, &y);
27565
27566 #ifdef HAVE_WINDOW_SYSTEM
27567 /* Handle tool-bar window differently since it doesn't display a
27568 buffer. */
27569 if (EQ (window, f->tool_bar_window))
27570 {
27571 note_tool_bar_highlight (f, x, y);
27572 return;
27573 }
27574 #endif
27575
27576 /* Mouse is on the mode, header line or margin? */
27577 if (part == ON_MODE_LINE || part == ON_HEADER_LINE
27578 || part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
27579 {
27580 note_mode_line_or_margin_highlight (window, x, y, part);
27581 return;
27582 }
27583
27584 #ifdef HAVE_WINDOW_SYSTEM
27585 if (part == ON_VERTICAL_BORDER)
27586 {
27587 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
27588 help_echo_string = build_string ("drag-mouse-1: resize");
27589 }
27590 else if (part == ON_LEFT_FRINGE || part == ON_RIGHT_FRINGE
27591 || part == ON_SCROLL_BAR)
27592 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
27593 else
27594 cursor = FRAME_X_OUTPUT (f)->text_cursor;
27595 #endif
27596
27597 /* Are we in a window whose display is up to date?
27598 And verify the buffer's text has not changed. */
27599 b = XBUFFER (w->buffer);
27600 if (part == ON_TEXT
27601 && EQ (w->window_end_valid, w->buffer)
27602 && XFASTINT (w->last_modified) == BUF_MODIFF (b)
27603 && XFASTINT (w->last_overlay_modified) == BUF_OVERLAY_MODIFF (b))
27604 {
27605 int hpos, vpos, dx, dy, area = LAST_AREA;
27606 ptrdiff_t pos;
27607 struct glyph *glyph;
27608 Lisp_Object object;
27609 Lisp_Object mouse_face = Qnil, position;
27610 Lisp_Object *overlay_vec = NULL;
27611 ptrdiff_t i, noverlays;
27612 struct buffer *obuf;
27613 ptrdiff_t obegv, ozv;
27614 int same_region;
27615
27616 /* Find the glyph under X/Y. */
27617 glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, &dx, &dy, &area);
27618
27619 #ifdef HAVE_WINDOW_SYSTEM
27620 /* Look for :pointer property on image. */
27621 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
27622 {
27623 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
27624 if (img != NULL && IMAGEP (img->spec))
27625 {
27626 Lisp_Object image_map, hotspot;
27627 if ((image_map = Fplist_get (XCDR (img->spec), QCmap),
27628 !NILP (image_map))
27629 && (hotspot = find_hot_spot (image_map,
27630 glyph->slice.img.x + dx,
27631 glyph->slice.img.y + dy),
27632 CONSP (hotspot))
27633 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
27634 {
27635 Lisp_Object plist;
27636
27637 /* Could check XCAR (hotspot) to see if we enter/leave
27638 this hot-spot.
27639 If so, we could look for mouse-enter, mouse-leave
27640 properties in PLIST (and do something...). */
27641 hotspot = XCDR (hotspot);
27642 if (CONSP (hotspot)
27643 && (plist = XCAR (hotspot), CONSP (plist)))
27644 {
27645 pointer = Fplist_get (plist, Qpointer);
27646 if (NILP (pointer))
27647 pointer = Qhand;
27648 help_echo_string = Fplist_get (plist, Qhelp_echo);
27649 if (!NILP (help_echo_string))
27650 {
27651 help_echo_window = window;
27652 help_echo_object = glyph->object;
27653 help_echo_pos = glyph->charpos;
27654 }
27655 }
27656 }
27657 if (NILP (pointer))
27658 pointer = Fplist_get (XCDR (img->spec), QCpointer);
27659 }
27660 }
27661 #endif /* HAVE_WINDOW_SYSTEM */
27662
27663 /* Clear mouse face if X/Y not over text. */
27664 if (glyph == NULL
27665 || area != TEXT_AREA
27666 || !MATRIX_ROW (w->current_matrix, vpos)->displays_text_p
27667 /* Glyph's OBJECT is an integer for glyphs inserted by the
27668 display engine for its internal purposes, like truncation
27669 and continuation glyphs and blanks beyond the end of
27670 line's text on text terminals. If we are over such a
27671 glyph, we are not over any text. */
27672 || INTEGERP (glyph->object)
27673 /* R2L rows have a stretch glyph at their front, which
27674 stands for no text, whereas L2R rows have no glyphs at
27675 all beyond the end of text. Treat such stretch glyphs
27676 like we do with NULL glyphs in L2R rows. */
27677 || (MATRIX_ROW (w->current_matrix, vpos)->reversed_p
27678 && glyph == MATRIX_ROW (w->current_matrix, vpos)->glyphs[TEXT_AREA]
27679 && glyph->type == STRETCH_GLYPH
27680 && glyph->avoid_cursor_p))
27681 {
27682 if (clear_mouse_face (hlinfo))
27683 cursor = No_Cursor;
27684 #ifdef HAVE_WINDOW_SYSTEM
27685 if (FRAME_WINDOW_P (f) && NILP (pointer))
27686 {
27687 if (area != TEXT_AREA)
27688 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
27689 else
27690 pointer = Vvoid_text_area_pointer;
27691 }
27692 #endif
27693 goto set_cursor;
27694 }
27695
27696 pos = glyph->charpos;
27697 object = glyph->object;
27698 if (!STRINGP (object) && !BUFFERP (object))
27699 goto set_cursor;
27700
27701 /* If we get an out-of-range value, return now; avoid an error. */
27702 if (BUFFERP (object) && pos > BUF_Z (b))
27703 goto set_cursor;
27704
27705 /* Make the window's buffer temporarily current for
27706 overlays_at and compute_char_face. */
27707 obuf = current_buffer;
27708 current_buffer = b;
27709 obegv = BEGV;
27710 ozv = ZV;
27711 BEGV = BEG;
27712 ZV = Z;
27713
27714 /* Is this char mouse-active or does it have help-echo? */
27715 position = make_number (pos);
27716
27717 if (BUFFERP (object))
27718 {
27719 /* Put all the overlays we want in a vector in overlay_vec. */
27720 GET_OVERLAYS_AT (pos, overlay_vec, noverlays, NULL, 0);
27721 /* Sort overlays into increasing priority order. */
27722 noverlays = sort_overlays (overlay_vec, noverlays, w);
27723 }
27724 else
27725 noverlays = 0;
27726
27727 same_region = coords_in_mouse_face_p (w, hpos, vpos);
27728
27729 if (same_region)
27730 cursor = No_Cursor;
27731
27732 /* Check mouse-face highlighting. */
27733 if (! same_region
27734 /* If there exists an overlay with mouse-face overlapping
27735 the one we are currently highlighting, we have to
27736 check if we enter the overlapping overlay, and then
27737 highlight only that. */
27738 || (OVERLAYP (hlinfo->mouse_face_overlay)
27739 && mouse_face_overlay_overlaps (hlinfo->mouse_face_overlay)))
27740 {
27741 /* Find the highest priority overlay with a mouse-face. */
27742 Lisp_Object overlay = Qnil;
27743 for (i = noverlays - 1; i >= 0 && NILP (overlay); --i)
27744 {
27745 mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face);
27746 if (!NILP (mouse_face))
27747 overlay = overlay_vec[i];
27748 }
27749
27750 /* If we're highlighting the same overlay as before, there's
27751 no need to do that again. */
27752 if (!NILP (overlay) && EQ (overlay, hlinfo->mouse_face_overlay))
27753 goto check_help_echo;
27754 hlinfo->mouse_face_overlay = overlay;
27755
27756 /* Clear the display of the old active region, if any. */
27757 if (clear_mouse_face (hlinfo))
27758 cursor = No_Cursor;
27759
27760 /* If no overlay applies, get a text property. */
27761 if (NILP (overlay))
27762 mouse_face = Fget_text_property (position, Qmouse_face, object);
27763
27764 /* Next, compute the bounds of the mouse highlighting and
27765 display it. */
27766 if (!NILP (mouse_face) && STRINGP (object))
27767 {
27768 /* The mouse-highlighting comes from a display string
27769 with a mouse-face. */
27770 Lisp_Object s, e;
27771 ptrdiff_t ignore;
27772
27773 s = Fprevious_single_property_change
27774 (make_number (pos + 1), Qmouse_face, object, Qnil);
27775 e = Fnext_single_property_change
27776 (position, Qmouse_face, object, Qnil);
27777 if (NILP (s))
27778 s = make_number (0);
27779 if (NILP (e))
27780 e = make_number (SCHARS (object) - 1);
27781 mouse_face_from_string_pos (w, hlinfo, object,
27782 XINT (s), XINT (e));
27783 hlinfo->mouse_face_past_end = 0;
27784 hlinfo->mouse_face_window = window;
27785 hlinfo->mouse_face_face_id
27786 = face_at_string_position (w, object, pos, 0, 0, 0, &ignore,
27787 glyph->face_id, 1);
27788 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
27789 cursor = No_Cursor;
27790 }
27791 else
27792 {
27793 /* The mouse-highlighting, if any, comes from an overlay
27794 or text property in the buffer. */
27795 Lisp_Object buffer IF_LINT (= Qnil);
27796 Lisp_Object disp_string IF_LINT (= Qnil);
27797
27798 if (STRINGP (object))
27799 {
27800 /* If we are on a display string with no mouse-face,
27801 check if the text under it has one. */
27802 struct glyph_row *r = MATRIX_ROW (w->current_matrix, vpos);
27803 ptrdiff_t start = MATRIX_ROW_START_CHARPOS (r);
27804 pos = string_buffer_position (object, start);
27805 if (pos > 0)
27806 {
27807 mouse_face = get_char_property_and_overlay
27808 (make_number (pos), Qmouse_face, w->buffer, &overlay);
27809 buffer = w->buffer;
27810 disp_string = object;
27811 }
27812 }
27813 else
27814 {
27815 buffer = object;
27816 disp_string = Qnil;
27817 }
27818
27819 if (!NILP (mouse_face))
27820 {
27821 Lisp_Object before, after;
27822 Lisp_Object before_string, after_string;
27823 /* To correctly find the limits of mouse highlight
27824 in a bidi-reordered buffer, we must not use the
27825 optimization of limiting the search in
27826 previous-single-property-change and
27827 next-single-property-change, because
27828 rows_from_pos_range needs the real start and end
27829 positions to DTRT in this case. That's because
27830 the first row visible in a window does not
27831 necessarily display the character whose position
27832 is the smallest. */
27833 Lisp_Object lim1 =
27834 NILP (BVAR (XBUFFER (buffer), bidi_display_reordering))
27835 ? Fmarker_position (w->start)
27836 : Qnil;
27837 Lisp_Object lim2 =
27838 NILP (BVAR (XBUFFER (buffer), bidi_display_reordering))
27839 ? make_number (BUF_Z (XBUFFER (buffer))
27840 - XFASTINT (w->window_end_pos))
27841 : Qnil;
27842
27843 if (NILP (overlay))
27844 {
27845 /* Handle the text property case. */
27846 before = Fprevious_single_property_change
27847 (make_number (pos + 1), Qmouse_face, buffer, lim1);
27848 after = Fnext_single_property_change
27849 (make_number (pos), Qmouse_face, buffer, lim2);
27850 before_string = after_string = Qnil;
27851 }
27852 else
27853 {
27854 /* Handle the overlay case. */
27855 before = Foverlay_start (overlay);
27856 after = Foverlay_end (overlay);
27857 before_string = Foverlay_get (overlay, Qbefore_string);
27858 after_string = Foverlay_get (overlay, Qafter_string);
27859
27860 if (!STRINGP (before_string)) before_string = Qnil;
27861 if (!STRINGP (after_string)) after_string = Qnil;
27862 }
27863
27864 mouse_face_from_buffer_pos (window, hlinfo, pos,
27865 NILP (before)
27866 ? 1
27867 : XFASTINT (before),
27868 NILP (after)
27869 ? BUF_Z (XBUFFER (buffer))
27870 : XFASTINT (after),
27871 before_string, after_string,
27872 disp_string);
27873 cursor = No_Cursor;
27874 }
27875 }
27876 }
27877
27878 check_help_echo:
27879
27880 /* Look for a `help-echo' property. */
27881 if (NILP (help_echo_string)) {
27882 Lisp_Object help, overlay;
27883
27884 /* Check overlays first. */
27885 help = overlay = Qnil;
27886 for (i = noverlays - 1; i >= 0 && NILP (help); --i)
27887 {
27888 overlay = overlay_vec[i];
27889 help = Foverlay_get (overlay, Qhelp_echo);
27890 }
27891
27892 if (!NILP (help))
27893 {
27894 help_echo_string = help;
27895 help_echo_window = window;
27896 help_echo_object = overlay;
27897 help_echo_pos = pos;
27898 }
27899 else
27900 {
27901 Lisp_Object obj = glyph->object;
27902 ptrdiff_t charpos = glyph->charpos;
27903
27904 /* Try text properties. */
27905 if (STRINGP (obj)
27906 && charpos >= 0
27907 && charpos < SCHARS (obj))
27908 {
27909 help = Fget_text_property (make_number (charpos),
27910 Qhelp_echo, obj);
27911 if (NILP (help))
27912 {
27913 /* If the string itself doesn't specify a help-echo,
27914 see if the buffer text ``under'' it does. */
27915 struct glyph_row *r
27916 = MATRIX_ROW (w->current_matrix, vpos);
27917 ptrdiff_t start = MATRIX_ROW_START_CHARPOS (r);
27918 ptrdiff_t p = string_buffer_position (obj, start);
27919 if (p > 0)
27920 {
27921 help = Fget_char_property (make_number (p),
27922 Qhelp_echo, w->buffer);
27923 if (!NILP (help))
27924 {
27925 charpos = p;
27926 obj = w->buffer;
27927 }
27928 }
27929 }
27930 }
27931 else if (BUFFERP (obj)
27932 && charpos >= BEGV
27933 && charpos < ZV)
27934 help = Fget_text_property (make_number (charpos), Qhelp_echo,
27935 obj);
27936
27937 if (!NILP (help))
27938 {
27939 help_echo_string = help;
27940 help_echo_window = window;
27941 help_echo_object = obj;
27942 help_echo_pos = charpos;
27943 }
27944 }
27945 }
27946
27947 #ifdef HAVE_WINDOW_SYSTEM
27948 /* Look for a `pointer' property. */
27949 if (FRAME_WINDOW_P (f) && NILP (pointer))
27950 {
27951 /* Check overlays first. */
27952 for (i = noverlays - 1; i >= 0 && NILP (pointer); --i)
27953 pointer = Foverlay_get (overlay_vec[i], Qpointer);
27954
27955 if (NILP (pointer))
27956 {
27957 Lisp_Object obj = glyph->object;
27958 ptrdiff_t charpos = glyph->charpos;
27959
27960 /* Try text properties. */
27961 if (STRINGP (obj)
27962 && charpos >= 0
27963 && charpos < SCHARS (obj))
27964 {
27965 pointer = Fget_text_property (make_number (charpos),
27966 Qpointer, obj);
27967 if (NILP (pointer))
27968 {
27969 /* If the string itself doesn't specify a pointer,
27970 see if the buffer text ``under'' it does. */
27971 struct glyph_row *r
27972 = MATRIX_ROW (w->current_matrix, vpos);
27973 ptrdiff_t start = MATRIX_ROW_START_CHARPOS (r);
27974 ptrdiff_t p = string_buffer_position (obj, start);
27975 if (p > 0)
27976 pointer = Fget_char_property (make_number (p),
27977 Qpointer, w->buffer);
27978 }
27979 }
27980 else if (BUFFERP (obj)
27981 && charpos >= BEGV
27982 && charpos < ZV)
27983 pointer = Fget_text_property (make_number (charpos),
27984 Qpointer, obj);
27985 }
27986 }
27987 #endif /* HAVE_WINDOW_SYSTEM */
27988
27989 BEGV = obegv;
27990 ZV = ozv;
27991 current_buffer = obuf;
27992 }
27993
27994 set_cursor:
27995
27996 #ifdef HAVE_WINDOW_SYSTEM
27997 if (FRAME_WINDOW_P (f))
27998 define_frame_cursor1 (f, cursor, pointer);
27999 #else
28000 /* This is here to prevent a compiler error, about "label at end of
28001 compound statement". */
28002 return;
28003 #endif
28004 }
28005
28006
28007 /* EXPORT for RIF:
28008 Clear any mouse-face on window W. This function is part of the
28009 redisplay interface, and is called from try_window_id and similar
28010 functions to ensure the mouse-highlight is off. */
28011
28012 void
28013 x_clear_window_mouse_face (struct window *w)
28014 {
28015 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame));
28016 Lisp_Object window;
28017
28018 BLOCK_INPUT;
28019 XSETWINDOW (window, w);
28020 if (EQ (window, hlinfo->mouse_face_window))
28021 clear_mouse_face (hlinfo);
28022 UNBLOCK_INPUT;
28023 }
28024
28025
28026 /* EXPORT:
28027 Just discard the mouse face information for frame F, if any.
28028 This is used when the size of F is changed. */
28029
28030 void
28031 cancel_mouse_face (struct frame *f)
28032 {
28033 Lisp_Object window;
28034 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
28035
28036 window = hlinfo->mouse_face_window;
28037 if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f)
28038 {
28039 hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
28040 hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
28041 hlinfo->mouse_face_window = Qnil;
28042 }
28043 }
28044
28045
28046 \f
28047 /***********************************************************************
28048 Exposure Events
28049 ***********************************************************************/
28050
28051 #ifdef HAVE_WINDOW_SYSTEM
28052
28053 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
28054 which intersects rectangle R. R is in window-relative coordinates. */
28055
28056 static void
28057 expose_area (struct window *w, struct glyph_row *row, XRectangle *r,
28058 enum glyph_row_area area)
28059 {
28060 struct glyph *first = row->glyphs[area];
28061 struct glyph *end = row->glyphs[area] + row->used[area];
28062 struct glyph *last;
28063 int first_x, start_x, x;
28064
28065 if (area == TEXT_AREA && row->fill_line_p)
28066 /* If row extends face to end of line write the whole line. */
28067 draw_glyphs (w, 0, row, area,
28068 0, row->used[area],
28069 DRAW_NORMAL_TEXT, 0);
28070 else
28071 {
28072 /* Set START_X to the window-relative start position for drawing glyphs of
28073 AREA. The first glyph of the text area can be partially visible.
28074 The first glyphs of other areas cannot. */
28075 start_x = window_box_left_offset (w, area);
28076 x = start_x;
28077 if (area == TEXT_AREA)
28078 x += row->x;
28079
28080 /* Find the first glyph that must be redrawn. */
28081 while (first < end
28082 && x + first->pixel_width < r->x)
28083 {
28084 x += first->pixel_width;
28085 ++first;
28086 }
28087
28088 /* Find the last one. */
28089 last = first;
28090 first_x = x;
28091 while (last < end
28092 && x < r->x + r->width)
28093 {
28094 x += last->pixel_width;
28095 ++last;
28096 }
28097
28098 /* Repaint. */
28099 if (last > first)
28100 draw_glyphs (w, first_x - start_x, row, area,
28101 first - row->glyphs[area], last - row->glyphs[area],
28102 DRAW_NORMAL_TEXT, 0);
28103 }
28104 }
28105
28106
28107 /* Redraw the parts of the glyph row ROW on window W intersecting
28108 rectangle R. R is in window-relative coordinates. Value is
28109 non-zero if mouse-face was overwritten. */
28110
28111 static int
28112 expose_line (struct window *w, struct glyph_row *row, XRectangle *r)
28113 {
28114 xassert (row->enabled_p);
28115
28116 if (row->mode_line_p || w->pseudo_window_p)
28117 draw_glyphs (w, 0, row, TEXT_AREA,
28118 0, row->used[TEXT_AREA],
28119 DRAW_NORMAL_TEXT, 0);
28120 else
28121 {
28122 if (row->used[LEFT_MARGIN_AREA])
28123 expose_area (w, row, r, LEFT_MARGIN_AREA);
28124 if (row->used[TEXT_AREA])
28125 expose_area (w, row, r, TEXT_AREA);
28126 if (row->used[RIGHT_MARGIN_AREA])
28127 expose_area (w, row, r, RIGHT_MARGIN_AREA);
28128 draw_row_fringe_bitmaps (w, row);
28129 }
28130
28131 return row->mouse_face_p;
28132 }
28133
28134
28135 /* Redraw those parts of glyphs rows during expose event handling that
28136 overlap other rows. Redrawing of an exposed line writes over parts
28137 of lines overlapping that exposed line; this function fixes that.
28138
28139 W is the window being exposed. FIRST_OVERLAPPING_ROW is the first
28140 row in W's current matrix that is exposed and overlaps other rows.
28141 LAST_OVERLAPPING_ROW is the last such row. */
28142
28143 static void
28144 expose_overlaps (struct window *w,
28145 struct glyph_row *first_overlapping_row,
28146 struct glyph_row *last_overlapping_row,
28147 XRectangle *r)
28148 {
28149 struct glyph_row *row;
28150
28151 for (row = first_overlapping_row; row <= last_overlapping_row; ++row)
28152 if (row->overlapping_p)
28153 {
28154 xassert (row->enabled_p && !row->mode_line_p);
28155
28156 row->clip = r;
28157 if (row->used[LEFT_MARGIN_AREA])
28158 x_fix_overlapping_area (w, row, LEFT_MARGIN_AREA, OVERLAPS_BOTH);
28159
28160 if (row->used[TEXT_AREA])
28161 x_fix_overlapping_area (w, row, TEXT_AREA, OVERLAPS_BOTH);
28162
28163 if (row->used[RIGHT_MARGIN_AREA])
28164 x_fix_overlapping_area (w, row, RIGHT_MARGIN_AREA, OVERLAPS_BOTH);
28165 row->clip = NULL;
28166 }
28167 }
28168
28169
28170 /* Return non-zero if W's cursor intersects rectangle R. */
28171
28172 static int
28173 phys_cursor_in_rect_p (struct window *w, XRectangle *r)
28174 {
28175 XRectangle cr, result;
28176 struct glyph *cursor_glyph;
28177 struct glyph_row *row;
28178
28179 if (w->phys_cursor.vpos >= 0
28180 && w->phys_cursor.vpos < w->current_matrix->nrows
28181 && (row = MATRIX_ROW (w->current_matrix, w->phys_cursor.vpos),
28182 row->enabled_p)
28183 && row->cursor_in_fringe_p)
28184 {
28185 /* Cursor is in the fringe. */
28186 cr.x = window_box_right_offset (w,
28187 (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
28188 ? RIGHT_MARGIN_AREA
28189 : TEXT_AREA));
28190 cr.y = row->y;
28191 cr.width = WINDOW_RIGHT_FRINGE_WIDTH (w);
28192 cr.height = row->height;
28193 return x_intersect_rectangles (&cr, r, &result);
28194 }
28195
28196 cursor_glyph = get_phys_cursor_glyph (w);
28197 if (cursor_glyph)
28198 {
28199 /* r is relative to W's box, but w->phys_cursor.x is relative
28200 to left edge of W's TEXT area. Adjust it. */
28201 cr.x = window_box_left_offset (w, TEXT_AREA) + w->phys_cursor.x;
28202 cr.y = w->phys_cursor.y;
28203 cr.width = cursor_glyph->pixel_width;
28204 cr.height = w->phys_cursor_height;
28205 /* ++KFS: W32 version used W32-specific IntersectRect here, but
28206 I assume the effect is the same -- and this is portable. */
28207 return x_intersect_rectangles (&cr, r, &result);
28208 }
28209 /* If we don't understand the format, pretend we're not in the hot-spot. */
28210 return 0;
28211 }
28212
28213
28214 /* EXPORT:
28215 Draw a vertical window border to the right of window W if W doesn't
28216 have vertical scroll bars. */
28217
28218 void
28219 x_draw_vertical_border (struct window *w)
28220 {
28221 struct frame *f = XFRAME (WINDOW_FRAME (w));
28222
28223 /* We could do better, if we knew what type of scroll-bar the adjacent
28224 windows (on either side) have... But we don't :-(
28225 However, I think this works ok. ++KFS 2003-04-25 */
28226
28227 /* Redraw borders between horizontally adjacent windows. Don't
28228 do it for frames with vertical scroll bars because either the
28229 right scroll bar of a window, or the left scroll bar of its
28230 neighbor will suffice as a border. */
28231 if (FRAME_HAS_VERTICAL_SCROLL_BARS (XFRAME (w->frame)))
28232 return;
28233
28234 if (!WINDOW_RIGHTMOST_P (w)
28235 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w))
28236 {
28237 int x0, x1, y0, y1;
28238
28239 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
28240 y1 -= 1;
28241
28242 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
28243 x1 -= 1;
28244
28245 FRAME_RIF (f)->draw_vertical_window_border (w, x1, y0, y1);
28246 }
28247 else if (!WINDOW_LEFTMOST_P (w)
28248 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
28249 {
28250 int x0, x1, y0, y1;
28251
28252 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
28253 y1 -= 1;
28254
28255 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
28256 x0 -= 1;
28257
28258 FRAME_RIF (f)->draw_vertical_window_border (w, x0, y0, y1);
28259 }
28260 }
28261
28262
28263 /* Redraw the part of window W intersection rectangle FR. Pixel
28264 coordinates in FR are frame-relative. Call this function with
28265 input blocked. Value is non-zero if the exposure overwrites
28266 mouse-face. */
28267
28268 static int
28269 expose_window (struct window *w, XRectangle *fr)
28270 {
28271 struct frame *f = XFRAME (w->frame);
28272 XRectangle wr, r;
28273 int mouse_face_overwritten_p = 0;
28274
28275 /* If window is not yet fully initialized, do nothing. This can
28276 happen when toolkit scroll bars are used and a window is split.
28277 Reconfiguring the scroll bar will generate an expose for a newly
28278 created window. */
28279 if (w->current_matrix == NULL)
28280 return 0;
28281
28282 /* When we're currently updating the window, display and current
28283 matrix usually don't agree. Arrange for a thorough display
28284 later. */
28285 if (w == updated_window)
28286 {
28287 SET_FRAME_GARBAGED (f);
28288 return 0;
28289 }
28290
28291 /* Frame-relative pixel rectangle of W. */
28292 wr.x = WINDOW_LEFT_EDGE_X (w);
28293 wr.y = WINDOW_TOP_EDGE_Y (w);
28294 wr.width = WINDOW_TOTAL_WIDTH (w);
28295 wr.height = WINDOW_TOTAL_HEIGHT (w);
28296
28297 if (x_intersect_rectangles (fr, &wr, &r))
28298 {
28299 int yb = window_text_bottom_y (w);
28300 struct glyph_row *row;
28301 int cursor_cleared_p, phys_cursor_on_p;
28302 struct glyph_row *first_overlapping_row, *last_overlapping_row;
28303
28304 TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n",
28305 r.x, r.y, r.width, r.height));
28306
28307 /* Convert to window coordinates. */
28308 r.x -= WINDOW_LEFT_EDGE_X (w);
28309 r.y -= WINDOW_TOP_EDGE_Y (w);
28310
28311 /* Turn off the cursor. */
28312 if (!w->pseudo_window_p
28313 && phys_cursor_in_rect_p (w, &r))
28314 {
28315 x_clear_cursor (w);
28316 cursor_cleared_p = 1;
28317 }
28318 else
28319 cursor_cleared_p = 0;
28320
28321 /* If the row containing the cursor extends face to end of line,
28322 then expose_area might overwrite the cursor outside the
28323 rectangle and thus notice_overwritten_cursor might clear
28324 w->phys_cursor_on_p. We remember the original value and
28325 check later if it is changed. */
28326 phys_cursor_on_p = w->phys_cursor_on_p;
28327
28328 /* Update lines intersecting rectangle R. */
28329 first_overlapping_row = last_overlapping_row = NULL;
28330 for (row = w->current_matrix->rows;
28331 row->enabled_p;
28332 ++row)
28333 {
28334 int y0 = row->y;
28335 int y1 = MATRIX_ROW_BOTTOM_Y (row);
28336
28337 if ((y0 >= r.y && y0 < r.y + r.height)
28338 || (y1 > r.y && y1 < r.y + r.height)
28339 || (r.y >= y0 && r.y < y1)
28340 || (r.y + r.height > y0 && r.y + r.height < y1))
28341 {
28342 /* A header line may be overlapping, but there is no need
28343 to fix overlapping areas for them. KFS 2005-02-12 */
28344 if (row->overlapping_p && !row->mode_line_p)
28345 {
28346 if (first_overlapping_row == NULL)
28347 first_overlapping_row = row;
28348 last_overlapping_row = row;
28349 }
28350
28351 row->clip = fr;
28352 if (expose_line (w, row, &r))
28353 mouse_face_overwritten_p = 1;
28354 row->clip = NULL;
28355 }
28356 else if (row->overlapping_p)
28357 {
28358 /* We must redraw a row overlapping the exposed area. */
28359 if (y0 < r.y
28360 ? y0 + row->phys_height > r.y
28361 : y0 + row->ascent - row->phys_ascent < r.y +r.height)
28362 {
28363 if (first_overlapping_row == NULL)
28364 first_overlapping_row = row;
28365 last_overlapping_row = row;
28366 }
28367 }
28368
28369 if (y1 >= yb)
28370 break;
28371 }
28372
28373 /* Display the mode line if there is one. */
28374 if (WINDOW_WANTS_MODELINE_P (w)
28375 && (row = MATRIX_MODE_LINE_ROW (w->current_matrix),
28376 row->enabled_p)
28377 && row->y < r.y + r.height)
28378 {
28379 if (expose_line (w, row, &r))
28380 mouse_face_overwritten_p = 1;
28381 }
28382
28383 if (!w->pseudo_window_p)
28384 {
28385 /* Fix the display of overlapping rows. */
28386 if (first_overlapping_row)
28387 expose_overlaps (w, first_overlapping_row, last_overlapping_row,
28388 fr);
28389
28390 /* Draw border between windows. */
28391 x_draw_vertical_border (w);
28392
28393 /* Turn the cursor on again. */
28394 if (cursor_cleared_p
28395 || (phys_cursor_on_p && !w->phys_cursor_on_p))
28396 update_window_cursor (w, 1);
28397 }
28398 }
28399
28400 return mouse_face_overwritten_p;
28401 }
28402
28403
28404
28405 /* Redraw (parts) of all windows in the window tree rooted at W that
28406 intersect R. R contains frame pixel coordinates. Value is
28407 non-zero if the exposure overwrites mouse-face. */
28408
28409 static int
28410 expose_window_tree (struct window *w, XRectangle *r)
28411 {
28412 struct frame *f = XFRAME (w->frame);
28413 int mouse_face_overwritten_p = 0;
28414
28415 while (w && !FRAME_GARBAGED_P (f))
28416 {
28417 if (!NILP (w->hchild))
28418 mouse_face_overwritten_p
28419 |= expose_window_tree (XWINDOW (w->hchild), r);
28420 else if (!NILP (w->vchild))
28421 mouse_face_overwritten_p
28422 |= expose_window_tree (XWINDOW (w->vchild), r);
28423 else
28424 mouse_face_overwritten_p |= expose_window (w, r);
28425
28426 w = NILP (w->next) ? NULL : XWINDOW (w->next);
28427 }
28428
28429 return mouse_face_overwritten_p;
28430 }
28431
28432
28433 /* EXPORT:
28434 Redisplay an exposed area of frame F. X and Y are the upper-left
28435 corner of the exposed rectangle. W and H are width and height of
28436 the exposed area. All are pixel values. W or H zero means redraw
28437 the entire frame. */
28438
28439 void
28440 expose_frame (struct frame *f, int x, int y, int w, int h)
28441 {
28442 XRectangle r;
28443 int mouse_face_overwritten_p = 0;
28444
28445 TRACE ((stderr, "expose_frame "));
28446
28447 /* No need to redraw if frame will be redrawn soon. */
28448 if (FRAME_GARBAGED_P (f))
28449 {
28450 TRACE ((stderr, " garbaged\n"));
28451 return;
28452 }
28453
28454 /* If basic faces haven't been realized yet, there is no point in
28455 trying to redraw anything. This can happen when we get an expose
28456 event while Emacs is starting, e.g. by moving another window. */
28457 if (FRAME_FACE_CACHE (f) == NULL
28458 || FRAME_FACE_CACHE (f)->used < BASIC_FACE_ID_SENTINEL)
28459 {
28460 TRACE ((stderr, " no faces\n"));
28461 return;
28462 }
28463
28464 if (w == 0 || h == 0)
28465 {
28466 r.x = r.y = 0;
28467 r.width = FRAME_COLUMN_WIDTH (f) * FRAME_COLS (f);
28468 r.height = FRAME_LINE_HEIGHT (f) * FRAME_LINES (f);
28469 }
28470 else
28471 {
28472 r.x = x;
28473 r.y = y;
28474 r.width = w;
28475 r.height = h;
28476 }
28477
28478 TRACE ((stderr, "(%d, %d, %d, %d)\n", r.x, r.y, r.width, r.height));
28479 mouse_face_overwritten_p = expose_window_tree (XWINDOW (f->root_window), &r);
28480
28481 if (WINDOWP (f->tool_bar_window))
28482 mouse_face_overwritten_p
28483 |= expose_window (XWINDOW (f->tool_bar_window), &r);
28484
28485 #ifdef HAVE_X_WINDOWS
28486 #ifndef MSDOS
28487 #ifndef USE_X_TOOLKIT
28488 if (WINDOWP (f->menu_bar_window))
28489 mouse_face_overwritten_p
28490 |= expose_window (XWINDOW (f->menu_bar_window), &r);
28491 #endif /* not USE_X_TOOLKIT */
28492 #endif
28493 #endif
28494
28495 /* Some window managers support a focus-follows-mouse style with
28496 delayed raising of frames. Imagine a partially obscured frame,
28497 and moving the mouse into partially obscured mouse-face on that
28498 frame. The visible part of the mouse-face will be highlighted,
28499 then the WM raises the obscured frame. With at least one WM, KDE
28500 2.1, Emacs is not getting any event for the raising of the frame
28501 (even tried with SubstructureRedirectMask), only Expose events.
28502 These expose events will draw text normally, i.e. not
28503 highlighted. Which means we must redo the highlight here.
28504 Subsume it under ``we love X''. --gerd 2001-08-15 */
28505 /* Included in Windows version because Windows most likely does not
28506 do the right thing if any third party tool offers
28507 focus-follows-mouse with delayed raise. --jason 2001-10-12 */
28508 if (mouse_face_overwritten_p && !FRAME_GARBAGED_P (f))
28509 {
28510 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
28511 if (f == hlinfo->mouse_face_mouse_frame)
28512 {
28513 int mouse_x = hlinfo->mouse_face_mouse_x;
28514 int mouse_y = hlinfo->mouse_face_mouse_y;
28515 clear_mouse_face (hlinfo);
28516 note_mouse_highlight (f, mouse_x, mouse_y);
28517 }
28518 }
28519 }
28520
28521
28522 /* EXPORT:
28523 Determine the intersection of two rectangles R1 and R2. Return
28524 the intersection in *RESULT. Value is non-zero if RESULT is not
28525 empty. */
28526
28527 int
28528 x_intersect_rectangles (XRectangle *r1, XRectangle *r2, XRectangle *result)
28529 {
28530 XRectangle *left, *right;
28531 XRectangle *upper, *lower;
28532 int intersection_p = 0;
28533
28534 /* Rearrange so that R1 is the left-most rectangle. */
28535 if (r1->x < r2->x)
28536 left = r1, right = r2;
28537 else
28538 left = r2, right = r1;
28539
28540 /* X0 of the intersection is right.x0, if this is inside R1,
28541 otherwise there is no intersection. */
28542 if (right->x <= left->x + left->width)
28543 {
28544 result->x = right->x;
28545
28546 /* The right end of the intersection is the minimum of
28547 the right ends of left and right. */
28548 result->width = (min (left->x + left->width, right->x + right->width)
28549 - result->x);
28550
28551 /* Same game for Y. */
28552 if (r1->y < r2->y)
28553 upper = r1, lower = r2;
28554 else
28555 upper = r2, lower = r1;
28556
28557 /* The upper end of the intersection is lower.y0, if this is inside
28558 of upper. Otherwise, there is no intersection. */
28559 if (lower->y <= upper->y + upper->height)
28560 {
28561 result->y = lower->y;
28562
28563 /* The lower end of the intersection is the minimum of the lower
28564 ends of upper and lower. */
28565 result->height = (min (lower->y + lower->height,
28566 upper->y + upper->height)
28567 - result->y);
28568 intersection_p = 1;
28569 }
28570 }
28571
28572 return intersection_p;
28573 }
28574
28575 #endif /* HAVE_WINDOW_SYSTEM */
28576
28577 \f
28578 /***********************************************************************
28579 Initialization
28580 ***********************************************************************/
28581
28582 void
28583 syms_of_xdisp (void)
28584 {
28585 Vwith_echo_area_save_vector = Qnil;
28586 staticpro (&Vwith_echo_area_save_vector);
28587
28588 Vmessage_stack = Qnil;
28589 staticpro (&Vmessage_stack);
28590
28591 DEFSYM (Qinhibit_redisplay, "inhibit-redisplay");
28592
28593 message_dolog_marker1 = Fmake_marker ();
28594 staticpro (&message_dolog_marker1);
28595 message_dolog_marker2 = Fmake_marker ();
28596 staticpro (&message_dolog_marker2);
28597 message_dolog_marker3 = Fmake_marker ();
28598 staticpro (&message_dolog_marker3);
28599
28600 #if GLYPH_DEBUG
28601 defsubr (&Sdump_frame_glyph_matrix);
28602 defsubr (&Sdump_glyph_matrix);
28603 defsubr (&Sdump_glyph_row);
28604 defsubr (&Sdump_tool_bar_row);
28605 defsubr (&Strace_redisplay);
28606 defsubr (&Strace_to_stderr);
28607 #endif
28608 #ifdef HAVE_WINDOW_SYSTEM
28609 defsubr (&Stool_bar_lines_needed);
28610 defsubr (&Slookup_image_map);
28611 #endif
28612 defsubr (&Sformat_mode_line);
28613 defsubr (&Sinvisible_p);
28614 defsubr (&Scurrent_bidi_paragraph_direction);
28615
28616 DEFSYM (Qmenu_bar_update_hook, "menu-bar-update-hook");
28617 DEFSYM (Qoverriding_terminal_local_map, "overriding-terminal-local-map");
28618 DEFSYM (Qoverriding_local_map, "overriding-local-map");
28619 DEFSYM (Qwindow_scroll_functions, "window-scroll-functions");
28620 DEFSYM (Qwindow_text_change_functions, "window-text-change-functions");
28621 DEFSYM (Qredisplay_end_trigger_functions, "redisplay-end-trigger-functions");
28622 DEFSYM (Qinhibit_point_motion_hooks, "inhibit-point-motion-hooks");
28623 DEFSYM (Qeval, "eval");
28624 DEFSYM (QCdata, ":data");
28625 DEFSYM (Qdisplay, "display");
28626 DEFSYM (Qspace_width, "space-width");
28627 DEFSYM (Qraise, "raise");
28628 DEFSYM (Qslice, "slice");
28629 DEFSYM (Qspace, "space");
28630 DEFSYM (Qmargin, "margin");
28631 DEFSYM (Qpointer, "pointer");
28632 DEFSYM (Qleft_margin, "left-margin");
28633 DEFSYM (Qright_margin, "right-margin");
28634 DEFSYM (Qcenter, "center");
28635 DEFSYM (Qline_height, "line-height");
28636 DEFSYM (QCalign_to, ":align-to");
28637 DEFSYM (QCrelative_width, ":relative-width");
28638 DEFSYM (QCrelative_height, ":relative-height");
28639 DEFSYM (QCeval, ":eval");
28640 DEFSYM (QCpropertize, ":propertize");
28641 DEFSYM (QCfile, ":file");
28642 DEFSYM (Qfontified, "fontified");
28643 DEFSYM (Qfontification_functions, "fontification-functions");
28644 DEFSYM (Qtrailing_whitespace, "trailing-whitespace");
28645 DEFSYM (Qescape_glyph, "escape-glyph");
28646 DEFSYM (Qnobreak_space, "nobreak-space");
28647 DEFSYM (Qimage, "image");
28648 DEFSYM (Qtext, "text");
28649 DEFSYM (Qboth, "both");
28650 DEFSYM (Qboth_horiz, "both-horiz");
28651 DEFSYM (Qtext_image_horiz, "text-image-horiz");
28652 DEFSYM (QCmap, ":map");
28653 DEFSYM (QCpointer, ":pointer");
28654 DEFSYM (Qrect, "rect");
28655 DEFSYM (Qcircle, "circle");
28656 DEFSYM (Qpoly, "poly");
28657 DEFSYM (Qmessage_truncate_lines, "message-truncate-lines");
28658 DEFSYM (Qgrow_only, "grow-only");
28659 DEFSYM (Qinhibit_menubar_update, "inhibit-menubar-update");
28660 DEFSYM (Qinhibit_eval_during_redisplay, "inhibit-eval-during-redisplay");
28661 DEFSYM (Qposition, "position");
28662 DEFSYM (Qbuffer_position, "buffer-position");
28663 DEFSYM (Qobject, "object");
28664 DEFSYM (Qbar, "bar");
28665 DEFSYM (Qhbar, "hbar");
28666 DEFSYM (Qbox, "box");
28667 DEFSYM (Qhollow, "hollow");
28668 DEFSYM (Qhand, "hand");
28669 DEFSYM (Qarrow, "arrow");
28670 DEFSYM (Qinhibit_free_realized_faces, "inhibit-free-realized-faces");
28671
28672 list_of_error = Fcons (Fcons (intern_c_string ("error"),
28673 Fcons (intern_c_string ("void-variable"), Qnil)),
28674 Qnil);
28675 staticpro (&list_of_error);
28676
28677 DEFSYM (Qlast_arrow_position, "last-arrow-position");
28678 DEFSYM (Qlast_arrow_string, "last-arrow-string");
28679 DEFSYM (Qoverlay_arrow_string, "overlay-arrow-string");
28680 DEFSYM (Qoverlay_arrow_bitmap, "overlay-arrow-bitmap");
28681
28682 echo_buffer[0] = echo_buffer[1] = Qnil;
28683 staticpro (&echo_buffer[0]);
28684 staticpro (&echo_buffer[1]);
28685
28686 echo_area_buffer[0] = echo_area_buffer[1] = Qnil;
28687 staticpro (&echo_area_buffer[0]);
28688 staticpro (&echo_area_buffer[1]);
28689
28690 Vmessages_buffer_name = make_pure_c_string ("*Messages*");
28691 staticpro (&Vmessages_buffer_name);
28692
28693 mode_line_proptrans_alist = Qnil;
28694 staticpro (&mode_line_proptrans_alist);
28695 mode_line_string_list = Qnil;
28696 staticpro (&mode_line_string_list);
28697 mode_line_string_face = Qnil;
28698 staticpro (&mode_line_string_face);
28699 mode_line_string_face_prop = Qnil;
28700 staticpro (&mode_line_string_face_prop);
28701 Vmode_line_unwind_vector = Qnil;
28702 staticpro (&Vmode_line_unwind_vector);
28703
28704 DEFSYM (Qmode_line_default_help_echo, "mode-line-default-help-echo");
28705
28706 help_echo_string = Qnil;
28707 staticpro (&help_echo_string);
28708 help_echo_object = Qnil;
28709 staticpro (&help_echo_object);
28710 help_echo_window = Qnil;
28711 staticpro (&help_echo_window);
28712 previous_help_echo_string = Qnil;
28713 staticpro (&previous_help_echo_string);
28714 help_echo_pos = -1;
28715
28716 DEFSYM (Qright_to_left, "right-to-left");
28717 DEFSYM (Qleft_to_right, "left-to-right");
28718
28719 #ifdef HAVE_WINDOW_SYSTEM
28720 DEFVAR_BOOL ("x-stretch-cursor", x_stretch_cursor_p,
28721 doc: /* Non-nil means draw block cursor as wide as the glyph under it.
28722 For example, if a block cursor is over a tab, it will be drawn as
28723 wide as that tab on the display. */);
28724 x_stretch_cursor_p = 0;
28725 #endif
28726
28727 DEFVAR_LISP ("show-trailing-whitespace", Vshow_trailing_whitespace,
28728 doc: /* Non-nil means highlight trailing whitespace.
28729 The face used for trailing whitespace is `trailing-whitespace'. */);
28730 Vshow_trailing_whitespace = Qnil;
28731
28732 DEFVAR_LISP ("nobreak-char-display", Vnobreak_char_display,
28733 doc: /* Control highlighting of non-ASCII space and hyphen chars.
28734 If the value is t, Emacs highlights non-ASCII chars which have the
28735 same appearance as an ASCII space or hyphen, using the `nobreak-space'
28736 or `escape-glyph' face respectively.
28737
28738 U+00A0 (no-break space), U+00AD (soft hyphen), U+2010 (hyphen), and
28739 U+2011 (non-breaking hyphen) are affected.
28740
28741 Any other non-nil value means to display these characters as a escape
28742 glyph followed by an ordinary space or hyphen.
28743
28744 A value of nil means no special handling of these characters. */);
28745 Vnobreak_char_display = Qt;
28746
28747 DEFVAR_LISP ("void-text-area-pointer", Vvoid_text_area_pointer,
28748 doc: /* The pointer shape to show in void text areas.
28749 A value of nil means to show the text pointer. Other options are `arrow',
28750 `text', `hand', `vdrag', `hdrag', `modeline', and `hourglass'. */);
28751 Vvoid_text_area_pointer = Qarrow;
28752
28753 DEFVAR_LISP ("inhibit-redisplay", Vinhibit_redisplay,
28754 doc: /* Non-nil means don't actually do any redisplay.
28755 This is used for internal purposes. */);
28756 Vinhibit_redisplay = Qnil;
28757
28758 DEFVAR_LISP ("global-mode-string", Vglobal_mode_string,
28759 doc: /* String (or mode line construct) included (normally) in `mode-line-format'. */);
28760 Vglobal_mode_string = Qnil;
28761
28762 DEFVAR_LISP ("overlay-arrow-position", Voverlay_arrow_position,
28763 doc: /* Marker for where to display an arrow on top of the buffer text.
28764 This must be the beginning of a line in order to work.
28765 See also `overlay-arrow-string'. */);
28766 Voverlay_arrow_position = Qnil;
28767
28768 DEFVAR_LISP ("overlay-arrow-string", Voverlay_arrow_string,
28769 doc: /* String to display as an arrow in non-window frames.
28770 See also `overlay-arrow-position'. */);
28771 Voverlay_arrow_string = make_pure_c_string ("=>");
28772
28773 DEFVAR_LISP ("overlay-arrow-variable-list", Voverlay_arrow_variable_list,
28774 doc: /* List of variables (symbols) which hold markers for overlay arrows.
28775 The symbols on this list are examined during redisplay to determine
28776 where to display overlay arrows. */);
28777 Voverlay_arrow_variable_list
28778 = Fcons (intern_c_string ("overlay-arrow-position"), Qnil);
28779
28780 DEFVAR_INT ("scroll-step", emacs_scroll_step,
28781 doc: /* The number of lines to try scrolling a window by when point moves out.
28782 If that fails to bring point back on frame, point is centered instead.
28783 If this is zero, point is always centered after it moves off frame.
28784 If you want scrolling to always be a line at a time, you should set
28785 `scroll-conservatively' to a large value rather than set this to 1. */);
28786
28787 DEFVAR_INT ("scroll-conservatively", scroll_conservatively,
28788 doc: /* Scroll up to this many lines, to bring point back on screen.
28789 If point moves off-screen, redisplay will scroll by up to
28790 `scroll-conservatively' lines in order to bring point just barely
28791 onto the screen again. If that cannot be done, then redisplay
28792 recenters point as usual.
28793
28794 If the value is greater than 100, redisplay will never recenter point,
28795 but will always scroll just enough text to bring point into view, even
28796 if you move far away.
28797
28798 A value of zero means always recenter point if it moves off screen. */);
28799 scroll_conservatively = 0;
28800
28801 DEFVAR_INT ("scroll-margin", scroll_margin,
28802 doc: /* Number of lines of margin at the top and bottom of a window.
28803 Recenter the window whenever point gets within this many lines
28804 of the top or bottom of the window. */);
28805 scroll_margin = 0;
28806
28807 DEFVAR_LISP ("display-pixels-per-inch", Vdisplay_pixels_per_inch,
28808 doc: /* Pixels per inch value for non-window system displays.
28809 Value is a number or a cons (WIDTH-DPI . HEIGHT-DPI). */);
28810 Vdisplay_pixels_per_inch = make_float (72.0);
28811
28812 #if GLYPH_DEBUG
28813 DEFVAR_INT ("debug-end-pos", debug_end_pos, doc: /* Don't ask. */);
28814 #endif
28815
28816 DEFVAR_LISP ("truncate-partial-width-windows",
28817 Vtruncate_partial_width_windows,
28818 doc: /* Non-nil means truncate lines in windows narrower than the frame.
28819 For an integer value, truncate lines in each window narrower than the
28820 full frame width, provided the window width is less than that integer;
28821 otherwise, respect the value of `truncate-lines'.
28822
28823 For any other non-nil value, truncate lines in all windows that do
28824 not span the full frame width.
28825
28826 A value of nil means to respect the value of `truncate-lines'.
28827
28828 If `word-wrap' is enabled, you might want to reduce this. */);
28829 Vtruncate_partial_width_windows = make_number (50);
28830
28831 DEFVAR_BOOL ("mode-line-inverse-video", mode_line_inverse_video,
28832 doc: /* When nil, display the mode-line/header-line/menu-bar in the default face.
28833 Any other value means to use the appropriate face, `mode-line',
28834 `header-line', or `menu' respectively. */);
28835 mode_line_inverse_video = 1;
28836
28837 DEFVAR_LISP ("line-number-display-limit", Vline_number_display_limit,
28838 doc: /* Maximum buffer size for which line number should be displayed.
28839 If the buffer is bigger than this, the line number does not appear
28840 in the mode line. A value of nil means no limit. */);
28841 Vline_number_display_limit = Qnil;
28842
28843 DEFVAR_INT ("line-number-display-limit-width",
28844 line_number_display_limit_width,
28845 doc: /* Maximum line width (in characters) for line number display.
28846 If the average length of the lines near point is bigger than this, then the
28847 line number may be omitted from the mode line. */);
28848 line_number_display_limit_width = 200;
28849
28850 DEFVAR_BOOL ("highlight-nonselected-windows", highlight_nonselected_windows,
28851 doc: /* Non-nil means highlight region even in nonselected windows. */);
28852 highlight_nonselected_windows = 0;
28853
28854 DEFVAR_BOOL ("multiple-frames", multiple_frames,
28855 doc: /* Non-nil if more than one frame is visible on this display.
28856 Minibuffer-only frames don't count, but iconified frames do.
28857 This variable is not guaranteed to be accurate except while processing
28858 `frame-title-format' and `icon-title-format'. */);
28859
28860 DEFVAR_LISP ("frame-title-format", Vframe_title_format,
28861 doc: /* Template for displaying the title bar of visible frames.
28862 \(Assuming the window manager supports this feature.)
28863
28864 This variable has the same structure as `mode-line-format', except that
28865 the %c and %l constructs are ignored. It is used only on frames for
28866 which no explicit name has been set \(see `modify-frame-parameters'). */);
28867
28868 DEFVAR_LISP ("icon-title-format", Vicon_title_format,
28869 doc: /* Template for displaying the title bar of an iconified frame.
28870 \(Assuming the window manager supports this feature.)
28871 This variable has the same structure as `mode-line-format' (which see),
28872 and is used only on frames for which no explicit name has been set
28873 \(see `modify-frame-parameters'). */);
28874 Vicon_title_format
28875 = Vframe_title_format
28876 = pure_cons (intern_c_string ("multiple-frames"),
28877 pure_cons (make_pure_c_string ("%b"),
28878 pure_cons (pure_cons (empty_unibyte_string,
28879 pure_cons (intern_c_string ("invocation-name"),
28880 pure_cons (make_pure_c_string ("@"),
28881 pure_cons (intern_c_string ("system-name"),
28882 Qnil)))),
28883 Qnil)));
28884
28885 DEFVAR_LISP ("message-log-max", Vmessage_log_max,
28886 doc: /* Maximum number of lines to keep in the message log buffer.
28887 If nil, disable message logging. If t, log messages but don't truncate
28888 the buffer when it becomes large. */);
28889 Vmessage_log_max = make_number (100);
28890
28891 DEFVAR_LISP ("window-size-change-functions", Vwindow_size_change_functions,
28892 doc: /* Functions called before redisplay, if window sizes have changed.
28893 The value should be a list of functions that take one argument.
28894 Just before redisplay, for each frame, if any of its windows have changed
28895 size since the last redisplay, or have been split or deleted,
28896 all the functions in the list are called, with the frame as argument. */);
28897 Vwindow_size_change_functions = Qnil;
28898
28899 DEFVAR_LISP ("window-scroll-functions", Vwindow_scroll_functions,
28900 doc: /* List of functions to call before redisplaying a window with scrolling.
28901 Each function is called with two arguments, the window and its new
28902 display-start position. Note that these functions are also called by
28903 `set-window-buffer'. Also note that the value of `window-end' is not
28904 valid when these functions are called.
28905
28906 Warning: Do not use this feature to alter the way the window
28907 is scrolled. It is not designed for that, and such use probably won't
28908 work. */);
28909 Vwindow_scroll_functions = Qnil;
28910
28911 DEFVAR_LISP ("window-text-change-functions",
28912 Vwindow_text_change_functions,
28913 doc: /* Functions to call in redisplay when text in the window might change. */);
28914 Vwindow_text_change_functions = Qnil;
28915
28916 DEFVAR_LISP ("redisplay-end-trigger-functions", Vredisplay_end_trigger_functions,
28917 doc: /* Functions called when redisplay of a window reaches the end trigger.
28918 Each function is called with two arguments, the window and the end trigger value.
28919 See `set-window-redisplay-end-trigger'. */);
28920 Vredisplay_end_trigger_functions = Qnil;
28921
28922 DEFVAR_LISP ("mouse-autoselect-window", Vmouse_autoselect_window,
28923 doc: /* Non-nil means autoselect window with mouse pointer.
28924 If nil, do not autoselect windows.
28925 A positive number means delay autoselection by that many seconds: a
28926 window is autoselected only after the mouse has remained in that
28927 window for the duration of the delay.
28928 A negative number has a similar effect, but causes windows to be
28929 autoselected only after the mouse has stopped moving. \(Because of
28930 the way Emacs compares mouse events, you will occasionally wait twice
28931 that time before the window gets selected.\)
28932 Any other value means to autoselect window instantaneously when the
28933 mouse pointer enters it.
28934
28935 Autoselection selects the minibuffer only if it is active, and never
28936 unselects the minibuffer if it is active.
28937
28938 When customizing this variable make sure that the actual value of
28939 `focus-follows-mouse' matches the behavior of your window manager. */);
28940 Vmouse_autoselect_window = Qnil;
28941
28942 DEFVAR_LISP ("auto-resize-tool-bars", Vauto_resize_tool_bars,
28943 doc: /* Non-nil means automatically resize tool-bars.
28944 This dynamically changes the tool-bar's height to the minimum height
28945 that is needed to make all tool-bar items visible.
28946 If value is `grow-only', the tool-bar's height is only increased
28947 automatically; to decrease the tool-bar height, use \\[recenter]. */);
28948 Vauto_resize_tool_bars = Qt;
28949
28950 DEFVAR_BOOL ("auto-raise-tool-bar-buttons", auto_raise_tool_bar_buttons_p,
28951 doc: /* Non-nil means raise tool-bar buttons when the mouse moves over them. */);
28952 auto_raise_tool_bar_buttons_p = 1;
28953
28954 DEFVAR_BOOL ("make-cursor-line-fully-visible", make_cursor_line_fully_visible_p,
28955 doc: /* Non-nil means to scroll (recenter) cursor line if it is not fully visible. */);
28956 make_cursor_line_fully_visible_p = 1;
28957
28958 DEFVAR_LISP ("tool-bar-border", Vtool_bar_border,
28959 doc: /* Border below tool-bar in pixels.
28960 If an integer, use it as the height of the border.
28961 If it is one of `internal-border-width' or `border-width', use the
28962 value of the corresponding frame parameter.
28963 Otherwise, no border is added below the tool-bar. */);
28964 Vtool_bar_border = Qinternal_border_width;
28965
28966 DEFVAR_LISP ("tool-bar-button-margin", Vtool_bar_button_margin,
28967 doc: /* Margin around tool-bar buttons in pixels.
28968 If an integer, use that for both horizontal and vertical margins.
28969 Otherwise, value should be a pair of integers `(HORZ . VERT)' with
28970 HORZ specifying the horizontal margin, and VERT specifying the
28971 vertical margin. */);
28972 Vtool_bar_button_margin = make_number (DEFAULT_TOOL_BAR_BUTTON_MARGIN);
28973
28974 DEFVAR_INT ("tool-bar-button-relief", tool_bar_button_relief,
28975 doc: /* Relief thickness of tool-bar buttons. */);
28976 tool_bar_button_relief = DEFAULT_TOOL_BAR_BUTTON_RELIEF;
28977
28978 DEFVAR_LISP ("tool-bar-style", Vtool_bar_style,
28979 doc: /* Tool bar style to use.
28980 It can be one of
28981 image - show images only
28982 text - show text only
28983 both - show both, text below image
28984 both-horiz - show text to the right of the image
28985 text-image-horiz - show text to the left of the image
28986 any other - use system default or image if no system default.
28987
28988 This variable only affects the GTK+ toolkit version of Emacs. */);
28989 Vtool_bar_style = Qnil;
28990
28991 DEFVAR_INT ("tool-bar-max-label-size", tool_bar_max_label_size,
28992 doc: /* Maximum number of characters a label can have to be shown.
28993 The tool bar style must also show labels for this to have any effect, see
28994 `tool-bar-style'. */);
28995 tool_bar_max_label_size = DEFAULT_TOOL_BAR_LABEL_SIZE;
28996
28997 DEFVAR_LISP ("fontification-functions", Vfontification_functions,
28998 doc: /* List of functions to call to fontify regions of text.
28999 Each function is called with one argument POS. Functions must
29000 fontify a region starting at POS in the current buffer, and give
29001 fontified regions the property `fontified'. */);
29002 Vfontification_functions = Qnil;
29003 Fmake_variable_buffer_local (Qfontification_functions);
29004
29005 DEFVAR_BOOL ("unibyte-display-via-language-environment",
29006 unibyte_display_via_language_environment,
29007 doc: /* Non-nil means display unibyte text according to language environment.
29008 Specifically, this means that raw bytes in the range 160-255 decimal
29009 are displayed by converting them to the equivalent multibyte characters
29010 according to the current language environment. As a result, they are
29011 displayed according to the current fontset.
29012
29013 Note that this variable affects only how these bytes are displayed,
29014 but does not change the fact they are interpreted as raw bytes. */);
29015 unibyte_display_via_language_environment = 0;
29016
29017 DEFVAR_LISP ("max-mini-window-height", Vmax_mini_window_height,
29018 doc: /* Maximum height for resizing mini-windows (the minibuffer and the echo area).
29019 If a float, it specifies a fraction of the mini-window frame's height.
29020 If an integer, it specifies a number of lines. */);
29021 Vmax_mini_window_height = make_float (0.25);
29022
29023 DEFVAR_LISP ("resize-mini-windows", Vresize_mini_windows,
29024 doc: /* How to resize mini-windows (the minibuffer and the echo area).
29025 A value of nil means don't automatically resize mini-windows.
29026 A value of t means resize them to fit the text displayed in them.
29027 A value of `grow-only', the default, means let mini-windows grow only;
29028 they return to their normal size when the minibuffer is closed, or the
29029 echo area becomes empty. */);
29030 Vresize_mini_windows = Qgrow_only;
29031
29032 DEFVAR_LISP ("blink-cursor-alist", Vblink_cursor_alist,
29033 doc: /* Alist specifying how to blink the cursor off.
29034 Each element has the form (ON-STATE . OFF-STATE). Whenever the
29035 `cursor-type' frame-parameter or variable equals ON-STATE,
29036 comparing using `equal', Emacs uses OFF-STATE to specify
29037 how to blink it off. ON-STATE and OFF-STATE are values for
29038 the `cursor-type' frame parameter.
29039
29040 If a frame's ON-STATE has no entry in this list,
29041 the frame's other specifications determine how to blink the cursor off. */);
29042 Vblink_cursor_alist = Qnil;
29043
29044 DEFVAR_BOOL ("auto-hscroll-mode", automatic_hscrolling_p,
29045 doc: /* Allow or disallow automatic horizontal scrolling of windows.
29046 If non-nil, windows are automatically scrolled horizontally to make
29047 point visible. */);
29048 automatic_hscrolling_p = 1;
29049 DEFSYM (Qauto_hscroll_mode, "auto-hscroll-mode");
29050
29051 DEFVAR_INT ("hscroll-margin", hscroll_margin,
29052 doc: /* How many columns away from the window edge point is allowed to get
29053 before automatic hscrolling will horizontally scroll the window. */);
29054 hscroll_margin = 5;
29055
29056 DEFVAR_LISP ("hscroll-step", Vhscroll_step,
29057 doc: /* How many columns to scroll the window when point gets too close to the edge.
29058 When point is less than `hscroll-margin' columns from the window
29059 edge, automatic hscrolling will scroll the window by the amount of columns
29060 determined by this variable. If its value is a positive integer, scroll that
29061 many columns. If it's a positive floating-point number, it specifies the
29062 fraction of the window's width to scroll. If it's nil or zero, point will be
29063 centered horizontally after the scroll. Any other value, including negative
29064 numbers, are treated as if the value were zero.
29065
29066 Automatic hscrolling always moves point outside the scroll margin, so if
29067 point was more than scroll step columns inside the margin, the window will
29068 scroll more than the value given by the scroll step.
29069
29070 Note that the lower bound for automatic hscrolling specified by `scroll-left'
29071 and `scroll-right' overrides this variable's effect. */);
29072 Vhscroll_step = make_number (0);
29073
29074 DEFVAR_BOOL ("message-truncate-lines", message_truncate_lines,
29075 doc: /* If non-nil, messages are truncated instead of resizing the echo area.
29076 Bind this around calls to `message' to let it take effect. */);
29077 message_truncate_lines = 0;
29078
29079 DEFVAR_LISP ("menu-bar-update-hook", Vmenu_bar_update_hook,
29080 doc: /* Normal hook run to update the menu bar definitions.
29081 Redisplay runs this hook before it redisplays the menu bar.
29082 This is used to update submenus such as Buffers,
29083 whose contents depend on various data. */);
29084 Vmenu_bar_update_hook = Qnil;
29085
29086 DEFVAR_LISP ("menu-updating-frame", Vmenu_updating_frame,
29087 doc: /* Frame for which we are updating a menu.
29088 The enable predicate for a menu binding should check this variable. */);
29089 Vmenu_updating_frame = Qnil;
29090
29091 DEFVAR_BOOL ("inhibit-menubar-update", inhibit_menubar_update,
29092 doc: /* Non-nil means don't update menu bars. Internal use only. */);
29093 inhibit_menubar_update = 0;
29094
29095 DEFVAR_LISP ("wrap-prefix", Vwrap_prefix,
29096 doc: /* Prefix prepended to all continuation lines at display time.
29097 The value may be a string, an image, or a stretch-glyph; it is
29098 interpreted in the same way as the value of a `display' text property.
29099
29100 This variable is overridden by any `wrap-prefix' text or overlay
29101 property.
29102
29103 To add a prefix to non-continuation lines, use `line-prefix'. */);
29104 Vwrap_prefix = Qnil;
29105 DEFSYM (Qwrap_prefix, "wrap-prefix");
29106 Fmake_variable_buffer_local (Qwrap_prefix);
29107
29108 DEFVAR_LISP ("line-prefix", Vline_prefix,
29109 doc: /* Prefix prepended to all non-continuation lines at display time.
29110 The value may be a string, an image, or a stretch-glyph; it is
29111 interpreted in the same way as the value of a `display' text property.
29112
29113 This variable is overridden by any `line-prefix' text or overlay
29114 property.
29115
29116 To add a prefix to continuation lines, use `wrap-prefix'. */);
29117 Vline_prefix = Qnil;
29118 DEFSYM (Qline_prefix, "line-prefix");
29119 Fmake_variable_buffer_local (Qline_prefix);
29120
29121 DEFVAR_BOOL ("inhibit-eval-during-redisplay", inhibit_eval_during_redisplay,
29122 doc: /* Non-nil means don't eval Lisp during redisplay. */);
29123 inhibit_eval_during_redisplay = 0;
29124
29125 DEFVAR_BOOL ("inhibit-free-realized-faces", inhibit_free_realized_faces,
29126 doc: /* Non-nil means don't free realized faces. Internal use only. */);
29127 inhibit_free_realized_faces = 0;
29128
29129 #if GLYPH_DEBUG
29130 DEFVAR_BOOL ("inhibit-try-window-id", inhibit_try_window_id,
29131 doc: /* Inhibit try_window_id display optimization. */);
29132 inhibit_try_window_id = 0;
29133
29134 DEFVAR_BOOL ("inhibit-try-window-reusing", inhibit_try_window_reusing,
29135 doc: /* Inhibit try_window_reusing display optimization. */);
29136 inhibit_try_window_reusing = 0;
29137
29138 DEFVAR_BOOL ("inhibit-try-cursor-movement", inhibit_try_cursor_movement,
29139 doc: /* Inhibit try_cursor_movement display optimization. */);
29140 inhibit_try_cursor_movement = 0;
29141 #endif /* GLYPH_DEBUG */
29142
29143 DEFVAR_INT ("overline-margin", overline_margin,
29144 doc: /* Space between overline and text, in pixels.
29145 The default value is 2: the height of the overline (1 pixel) plus 1 pixel
29146 margin to the character height. */);
29147 overline_margin = 2;
29148
29149 DEFVAR_INT ("underline-minimum-offset",
29150 underline_minimum_offset,
29151 doc: /* Minimum distance between baseline and underline.
29152 This can improve legibility of underlined text at small font sizes,
29153 particularly when using variable `x-use-underline-position-properties'
29154 with fonts that specify an UNDERLINE_POSITION relatively close to the
29155 baseline. The default value is 1. */);
29156 underline_minimum_offset = 1;
29157
29158 DEFVAR_BOOL ("display-hourglass", display_hourglass_p,
29159 doc: /* Non-nil means show an hourglass pointer, when Emacs is busy.
29160 This feature only works when on a window system that can change
29161 cursor shapes. */);
29162 display_hourglass_p = 1;
29163
29164 DEFVAR_LISP ("hourglass-delay", Vhourglass_delay,
29165 doc: /* Seconds to wait before displaying an hourglass pointer when Emacs is busy. */);
29166 Vhourglass_delay = make_number (DEFAULT_HOURGLASS_DELAY);
29167
29168 hourglass_atimer = NULL;
29169 hourglass_shown_p = 0;
29170
29171 DEFSYM (Qglyphless_char, "glyphless-char");
29172 DEFSYM (Qhex_code, "hex-code");
29173 DEFSYM (Qempty_box, "empty-box");
29174 DEFSYM (Qthin_space, "thin-space");
29175 DEFSYM (Qzero_width, "zero-width");
29176
29177 DEFSYM (Qglyphless_char_display, "glyphless-char-display");
29178 /* Intern this now in case it isn't already done.
29179 Setting this variable twice is harmless.
29180 But don't staticpro it here--that is done in alloc.c. */
29181 Qchar_table_extra_slots = intern_c_string ("char-table-extra-slots");
29182 Fput (Qglyphless_char_display, Qchar_table_extra_slots, make_number (1));
29183
29184 DEFVAR_LISP ("glyphless-char-display", Vglyphless_char_display,
29185 doc: /* Char-table defining glyphless characters.
29186 Each element, if non-nil, should be one of the following:
29187 an ASCII acronym string: display this string in a box
29188 `hex-code': display the hexadecimal code of a character in a box
29189 `empty-box': display as an empty box
29190 `thin-space': display as 1-pixel width space
29191 `zero-width': don't display
29192 An element may also be a cons cell (GRAPHICAL . TEXT), which specifies the
29193 display method for graphical terminals and text terminals respectively.
29194 GRAPHICAL and TEXT should each have one of the values listed above.
29195
29196 The char-table has one extra slot to control the display of a character for
29197 which no font is found. This slot only takes effect on graphical terminals.
29198 Its value should be an ASCII acronym string, `hex-code', `empty-box', or
29199 `thin-space'. The default is `empty-box'. */);
29200 Vglyphless_char_display = Fmake_char_table (Qglyphless_char_display, Qnil);
29201 Fset_char_table_extra_slot (Vglyphless_char_display, make_number (0),
29202 Qempty_box);
29203 }
29204
29205
29206 /* Initialize this module when Emacs starts. */
29207
29208 void
29209 init_xdisp (void)
29210 {
29211 current_header_line_height = current_mode_line_height = -1;
29212
29213 CHARPOS (this_line_start_pos) = 0;
29214
29215 if (!noninteractive)
29216 {
29217 struct window *m = XWINDOW (minibuf_window);
29218 Lisp_Object frame = m->frame;
29219 struct frame *f = XFRAME (frame);
29220 Lisp_Object root = FRAME_ROOT_WINDOW (f);
29221 struct window *r = XWINDOW (root);
29222 int i;
29223
29224 echo_area_window = minibuf_window;
29225
29226 XSETFASTINT (r->top_line, FRAME_TOP_MARGIN (f));
29227 XSETFASTINT (r->total_lines, FRAME_LINES (f) - 1 - FRAME_TOP_MARGIN (f));
29228 XSETFASTINT (r->total_cols, FRAME_COLS (f));
29229 XSETFASTINT (m->top_line, FRAME_LINES (f) - 1);
29230 XSETFASTINT (m->total_lines, 1);
29231 XSETFASTINT (m->total_cols, FRAME_COLS (f));
29232
29233 scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs;
29234 scratch_glyph_row.glyphs[TEXT_AREA + 1]
29235 = scratch_glyphs + MAX_SCRATCH_GLYPHS;
29236
29237 /* The default ellipsis glyphs `...'. */
29238 for (i = 0; i < 3; ++i)
29239 default_invis_vector[i] = make_number ('.');
29240 }
29241
29242 {
29243 /* Allocate the buffer for frame titles.
29244 Also used for `format-mode-line'. */
29245 int size = 100;
29246 mode_line_noprop_buf = (char *) xmalloc (size);
29247 mode_line_noprop_buf_end = mode_line_noprop_buf + size;
29248 mode_line_noprop_ptr = mode_line_noprop_buf;
29249 mode_line_target = MODE_LINE_DISPLAY;
29250 }
29251
29252 help_echo_showing_p = 0;
29253 }
29254
29255 /* Since w32 does not support atimers, it defines its own implementation of
29256 the following three functions in w32fns.c. */
29257 #ifndef WINDOWSNT
29258
29259 /* Platform-independent portion of hourglass implementation. */
29260
29261 /* Cancel a currently active hourglass timer, and start a new one. */
29262 void
29263 start_hourglass (void)
29264 {
29265 #if defined (HAVE_WINDOW_SYSTEM)
29266 EMACS_TIME delay;
29267 int secs = DEFAULT_HOURGLASS_DELAY, usecs = 0;
29268
29269 cancel_hourglass ();
29270
29271 if (NUMBERP (Vhourglass_delay))
29272 {
29273 double duration = extract_float (Vhourglass_delay);
29274 if (0 < duration)
29275 duration_to_sec_usec (duration, &secs, &usecs);
29276 }
29277
29278 EMACS_SET_SECS_USECS (delay, secs, usecs);
29279 hourglass_atimer = start_atimer (ATIMER_RELATIVE, delay,
29280 show_hourglass, NULL);
29281 #endif
29282 }
29283
29284
29285 /* Cancel the hourglass cursor timer if active, hide a busy cursor if
29286 shown. */
29287 void
29288 cancel_hourglass (void)
29289 {
29290 #if defined (HAVE_WINDOW_SYSTEM)
29291 if (hourglass_atimer)
29292 {
29293 cancel_atimer (hourglass_atimer);
29294 hourglass_atimer = NULL;
29295 }
29296
29297 if (hourglass_shown_p)
29298 hide_hourglass ();
29299 #endif
29300 }
29301 #endif /* ! WINDOWSNT */