src/xdisp.c: Remove some unused parameters.
[bpt/emacs.git] / src / xdisp.c
1 /* Display generation from window structure and buffer text.
2
3 Copyright (C) 1985-1988, 1993-1995, 1997-2011 Free Software Foundation, Inc.
4
5 This file is part of GNU Emacs.
6
7 GNU Emacs is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
11
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
19
20 /* New redisplay written by Gerd Moellmann <gerd@gnu.org>.
21
22 Redisplay.
23
24 Emacs separates the task of updating the display from code
25 modifying global state, e.g. buffer text. This way functions
26 operating on buffers don't also have to be concerned with updating
27 the display.
28
29 Updating the display is triggered by the Lisp interpreter when it
30 decides it's time to do it. This is done either automatically for
31 you as part of the interpreter's command loop or as the result of
32 calling Lisp functions like `sit-for'. The C function `redisplay'
33 in xdisp.c is the only entry into the inner redisplay code.
34
35 The following diagram shows how redisplay code is invoked. As you
36 can see, Lisp calls redisplay and vice versa. Under window systems
37 like X, some portions of the redisplay code are also called
38 asynchronously during mouse movement or expose events. It is very
39 important that these code parts do NOT use the C library (malloc,
40 free) because many C libraries under Unix are not reentrant. They
41 may also NOT call functions of the Lisp interpreter which could
42 change the interpreter's state. If you don't follow these rules,
43 you will encounter bugs which are very hard to explain.
44
45 +--------------+ redisplay +----------------+
46 | Lisp machine |---------------->| Redisplay code |<--+
47 +--------------+ (xdisp.c) +----------------+ |
48 ^ | |
49 +----------------------------------+ |
50 Don't use this path when called |
51 asynchronously! |
52 |
53 expose_window (asynchronous) |
54 |
55 X expose events -----+
56
57 What does redisplay do? Obviously, it has to figure out somehow what
58 has been changed since the last time the display has been updated,
59 and to make these changes visible. Preferably it would do that in
60 a moderately intelligent way, i.e. fast.
61
62 Changes in buffer text can be deduced from window and buffer
63 structures, and from some global variables like `beg_unchanged' and
64 `end_unchanged'. The contents of the display are additionally
65 recorded in a `glyph matrix', a two-dimensional matrix of glyph
66 structures. Each row in such a matrix corresponds to a line on the
67 display, and each glyph in a row corresponds to a column displaying
68 a character, an image, or what else. This matrix is called the
69 `current glyph matrix' or `current matrix' in redisplay
70 terminology.
71
72 For buffer parts that have been changed since the last update, a
73 second glyph matrix is constructed, the so called `desired glyph
74 matrix' or short `desired matrix'. Current and desired matrix are
75 then compared to find a cheap way to update the display, e.g. by
76 reusing part of the display by scrolling lines.
77
78 You will find a lot of redisplay optimizations when you start
79 looking at the innards of redisplay. The overall goal of all these
80 optimizations is to make redisplay fast because it is done
81 frequently. Some of these optimizations are implemented by the
82 following functions:
83
84 . try_cursor_movement
85
86 This function tries to update the display if the text in the
87 window did not change and did not scroll, only point moved, and
88 it did not move off the displayed portion of the text.
89
90 . try_window_reusing_current_matrix
91
92 This function reuses the current matrix of a window when text
93 has not changed, but the window start changed (e.g., due to
94 scrolling).
95
96 . try_window_id
97
98 This function attempts to redisplay a window by reusing parts of
99 its existing display. It finds and reuses the part that was not
100 changed, and redraws the rest.
101
102 . try_window
103
104 This function performs the full redisplay of a single window
105 assuming that its fonts were not changed and that the cursor
106 will not end up in the scroll margins. (Loading fonts requires
107 re-adjustment of dimensions of glyph matrices, which makes this
108 method impossible to use.)
109
110 These optimizations are tried in sequence (some can be skipped if
111 it is known that they are not applicable). If none of the
112 optimizations were successful, redisplay calls redisplay_windows,
113 which performs a full redisplay of all windows.
114
115 Desired matrices.
116
117 Desired matrices are always built per Emacs window. The function
118 `display_line' is the central function to look at if you are
119 interested. It constructs one row in a desired matrix given an
120 iterator structure containing both a buffer position and a
121 description of the environment in which the text is to be
122 displayed. But this is too early, read on.
123
124 Characters and pixmaps displayed for a range of buffer text depend
125 on various settings of buffers and windows, on overlays and text
126 properties, on display tables, on selective display. The good news
127 is that all this hairy stuff is hidden behind a small set of
128 interface functions taking an iterator structure (struct it)
129 argument.
130
131 Iteration over things to be displayed is then simple. It is
132 started by initializing an iterator with a call to init_iterator.
133 Calls to get_next_display_element fill the iterator structure with
134 relevant information about the next thing to display. Calls to
135 set_iterator_to_next move the iterator to the next thing.
136
137 Besides this, an iterator also contains information about the
138 display environment in which glyphs for display elements are to be
139 produced. It has fields for the width and height of the display,
140 the information whether long lines are truncated or continued, a
141 current X and Y position, and lots of other stuff you can better
142 see in dispextern.h.
143
144 Glyphs in a desired matrix are normally constructed in a loop
145 calling get_next_display_element and then PRODUCE_GLYPHS. The call
146 to PRODUCE_GLYPHS will fill the iterator structure with pixel
147 information about the element being displayed and at the same time
148 produce glyphs for it. If the display element fits on the line
149 being displayed, set_iterator_to_next is called next, otherwise the
150 glyphs produced are discarded. The function display_line is the
151 workhorse of filling glyph rows in the desired matrix with glyphs.
152 In addition to producing glyphs, it also handles line truncation
153 and continuation, word wrap, and cursor positioning (for the
154 latter, see also set_cursor_from_row).
155
156 Frame matrices.
157
158 That just couldn't be all, could it? What about terminal types not
159 supporting operations on sub-windows of the screen? To update the
160 display on such a terminal, window-based glyph matrices are not
161 well suited. To be able to reuse part of the display (scrolling
162 lines up and down), we must instead have a view of the whole
163 screen. This is what `frame matrices' are for. They are a trick.
164
165 Frames on terminals like above have a glyph pool. Windows on such
166 a frame sub-allocate their glyph memory from their frame's glyph
167 pool. The frame itself is given its own glyph matrices. By
168 coincidence---or maybe something else---rows in window glyph
169 matrices are slices of corresponding rows in frame matrices. Thus
170 writing to window matrices implicitly updates a frame matrix which
171 provides us with the view of the whole screen that we originally
172 wanted to have without having to move many bytes around. To be
173 honest, there is a little bit more done, but not much more. If you
174 plan to extend that code, take a look at dispnew.c. The function
175 build_frame_matrix is a good starting point.
176
177 Bidirectional display.
178
179 Bidirectional display adds quite some hair to this already complex
180 design. The good news are that a large portion of that hairy stuff
181 is hidden in bidi.c behind only 3 interfaces. bidi.c implements a
182 reordering engine which is called by set_iterator_to_next and
183 returns the next character to display in the visual order. See
184 commentary on bidi.c for more details. As far as redisplay is
185 concerned, the effect of calling bidi_move_to_visually_next, the
186 main interface of the reordering engine, is that the iterator gets
187 magically placed on the buffer or string position that is to be
188 displayed next. In other words, a linear iteration through the
189 buffer/string is replaced with a non-linear one. All the rest of
190 the redisplay is oblivious to the bidi reordering.
191
192 Well, almost oblivious---there are still complications, most of
193 them due to the fact that buffer and string positions no longer
194 change monotonously with glyph indices in a glyph row. Moreover,
195 for continued lines, the buffer positions may not even be
196 monotonously changing with vertical positions. Also, accounting
197 for face changes, overlays, etc. becomes more complex because
198 non-linear iteration could potentially skip many positions with
199 changes, and then cross them again on the way back...
200
201 One other prominent effect of bidirectional display is that some
202 paragraphs of text need to be displayed starting at the right
203 margin of the window---the so-called right-to-left, or R2L
204 paragraphs. R2L paragraphs are displayed with R2L glyph rows,
205 which have their reversed_p flag set. The bidi reordering engine
206 produces characters in such rows starting from the character which
207 should be the rightmost on display. PRODUCE_GLYPHS then reverses
208 the order, when it fills up the glyph row whose reversed_p flag is
209 set, by prepending each new glyph to what is already there, instead
210 of appending it. When the glyph row is complete, the function
211 extend_face_to_end_of_line fills the empty space to the left of the
212 leftmost character with special glyphs, which will display as,
213 well, empty. On text terminals, these special glyphs are simply
214 blank characters. On graphics terminals, there's a single stretch
215 glyph of a suitably computed width. Both the blanks and the
216 stretch glyph are given the face of the background of the line.
217 This way, the terminal-specific back-end can still draw the glyphs
218 left to right, even for R2L lines.
219
220 Bidirectional display and character compositions
221
222 Some scripts cannot be displayed by drawing each character
223 individually, because adjacent characters change each other's shape
224 on display. For example, Arabic and Indic scripts belong to this
225 category.
226
227 Emacs display supports this by providing "character compositions",
228 most of which is implemented in composite.c. During the buffer
229 scan that delivers characters to PRODUCE_GLYPHS, if the next
230 character to be delivered is a composed character, the iteration
231 calls composition_reseat_it and next_element_from_composition. If
232 they succeed to compose the character with one or more of the
233 following characters, the whole sequence of characters that where
234 composed is recorded in the `struct composition_it' object that is
235 part of the buffer iterator. The composed sequence could produce
236 one or more font glyphs (called "grapheme clusters") on the screen.
237 Each of these grapheme clusters is then delivered to PRODUCE_GLYPHS
238 in the direction corresponding to the current bidi scan direction
239 (recorded in the scan_dir member of the `struct bidi_it' object
240 that is part of the buffer iterator). In particular, if the bidi
241 iterator currently scans the buffer backwards, the grapheme
242 clusters are delivered back to front. This reorders the grapheme
243 clusters as appropriate for the current bidi context. Note that
244 this means that the grapheme clusters are always stored in the
245 LGSTRING object (see composite.c) in the logical order.
246
247 Moving an iterator in bidirectional text
248 without producing glyphs
249
250 Note one important detail mentioned above: that the bidi reordering
251 engine, driven by the iterator, produces characters in R2L rows
252 starting at the character that will be the rightmost on display.
253 As far as the iterator is concerned, the geometry of such rows is
254 still left to right, i.e. the iterator "thinks" the first character
255 is at the leftmost pixel position. The iterator does not know that
256 PRODUCE_GLYPHS reverses the order of the glyphs that the iterator
257 delivers. This is important when functions from the the move_it_*
258 family are used to get to certain screen position or to match
259 screen coordinates with buffer coordinates: these functions use the
260 iterator geometry, which is left to right even in R2L paragraphs.
261 This works well with most callers of move_it_*, because they need
262 to get to a specific column, and columns are still numbered in the
263 reading order, i.e. the rightmost character in a R2L paragraph is
264 still column zero. But some callers do not get well with this; a
265 notable example is mouse clicks that need to find the character
266 that corresponds to certain pixel coordinates. See
267 buffer_posn_from_coords in dispnew.c for how this is handled. */
268
269 #include <config.h>
270 #include <stdio.h>
271 #include <limits.h>
272 #include <setjmp.h>
273
274 #include "lisp.h"
275 #include "keyboard.h"
276 #include "frame.h"
277 #include "window.h"
278 #include "termchar.h"
279 #include "dispextern.h"
280 #include "buffer.h"
281 #include "character.h"
282 #include "charset.h"
283 #include "indent.h"
284 #include "commands.h"
285 #include "keymap.h"
286 #include "macros.h"
287 #include "disptab.h"
288 #include "termhooks.h"
289 #include "termopts.h"
290 #include "intervals.h"
291 #include "coding.h"
292 #include "process.h"
293 #include "region-cache.h"
294 #include "font.h"
295 #include "fontset.h"
296 #include "blockinput.h"
297
298 #ifdef HAVE_X_WINDOWS
299 #include "xterm.h"
300 #endif
301 #ifdef WINDOWSNT
302 #include "w32term.h"
303 #endif
304 #ifdef HAVE_NS
305 #include "nsterm.h"
306 #endif
307 #ifdef USE_GTK
308 #include "gtkutil.h"
309 #endif
310
311 #include "font.h"
312
313 #ifndef FRAME_X_OUTPUT
314 #define FRAME_X_OUTPUT(f) ((f)->output_data.x)
315 #endif
316
317 #define INFINITY 10000000
318
319 Lisp_Object Qoverriding_local_map, Qoverriding_terminal_local_map;
320 Lisp_Object Qwindow_scroll_functions;
321 Lisp_Object Qwindow_text_change_functions;
322 Lisp_Object Qredisplay_end_trigger_functions;
323 Lisp_Object Qinhibit_point_motion_hooks;
324 Lisp_Object QCeval, QCfile, QCdata, QCpropertize;
325 Lisp_Object Qfontified;
326 Lisp_Object Qgrow_only;
327 Lisp_Object Qinhibit_eval_during_redisplay;
328 Lisp_Object Qbuffer_position, Qposition, Qobject;
329 Lisp_Object Qright_to_left, Qleft_to_right;
330
331 /* Cursor shapes */
332 Lisp_Object Qbar, Qhbar, Qbox, Qhollow;
333
334 /* Pointer shapes */
335 Lisp_Object Qarrow, Qhand, Qtext;
336
337 /* Holds the list (error). */
338 Lisp_Object list_of_error;
339
340 Lisp_Object Qfontification_functions;
341
342 Lisp_Object Qwrap_prefix;
343 Lisp_Object Qline_prefix;
344
345 /* Non-nil means don't actually do any redisplay. */
346
347 Lisp_Object Qinhibit_redisplay;
348
349 /* Names of text properties relevant for redisplay. */
350
351 Lisp_Object Qdisplay;
352
353 Lisp_Object Qspace, QCalign_to, QCrelative_width, QCrelative_height;
354 Lisp_Object Qleft_margin, Qright_margin, Qspace_width, Qraise;
355 Lisp_Object Qslice;
356 Lisp_Object Qcenter;
357 Lisp_Object Qmargin, Qpointer;
358 Lisp_Object Qline_height;
359
360 #ifdef HAVE_WINDOW_SYSTEM
361
362 /* Test if overflow newline into fringe. Called with iterator IT
363 at or past right window margin, and with IT->current_x set. */
364
365 #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(IT) \
366 (!NILP (Voverflow_newline_into_fringe) \
367 && FRAME_WINDOW_P ((IT)->f) \
368 && ((IT)->bidi_it.paragraph_dir == R2L \
369 ? (WINDOW_LEFT_FRINGE_WIDTH ((IT)->w) > 0) \
370 : (WINDOW_RIGHT_FRINGE_WIDTH ((IT)->w) > 0)) \
371 && (IT)->current_x == (IT)->last_visible_x \
372 && (IT)->line_wrap != WORD_WRAP)
373
374 #else /* !HAVE_WINDOW_SYSTEM */
375 #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(it) 0
376 #endif /* HAVE_WINDOW_SYSTEM */
377
378 /* Test if the display element loaded in IT is a space or tab
379 character. This is used to determine word wrapping. */
380
381 #define IT_DISPLAYING_WHITESPACE(it) \
382 (it->what == IT_CHARACTER && (it->c == ' ' || it->c == '\t'))
383
384 /* Name of the face used to highlight trailing whitespace. */
385
386 Lisp_Object Qtrailing_whitespace;
387
388 /* Name and number of the face used to highlight escape glyphs. */
389
390 Lisp_Object Qescape_glyph;
391
392 /* Name and number of the face used to highlight non-breaking spaces. */
393
394 Lisp_Object Qnobreak_space;
395
396 /* The symbol `image' which is the car of the lists used to represent
397 images in Lisp. Also a tool bar style. */
398
399 Lisp_Object Qimage;
400
401 /* The image map types. */
402 Lisp_Object QCmap, QCpointer;
403 Lisp_Object Qrect, Qcircle, Qpoly;
404
405 /* Tool bar styles */
406 Lisp_Object Qboth, Qboth_horiz, Qtext_image_horiz;
407
408 /* Non-zero means print newline to stdout before next mini-buffer
409 message. */
410
411 int noninteractive_need_newline;
412
413 /* Non-zero means print newline to message log before next message. */
414
415 static int message_log_need_newline;
416
417 /* Three markers that message_dolog uses.
418 It could allocate them itself, but that causes trouble
419 in handling memory-full errors. */
420 static Lisp_Object message_dolog_marker1;
421 static Lisp_Object message_dolog_marker2;
422 static Lisp_Object message_dolog_marker3;
423 \f
424 /* The buffer position of the first character appearing entirely or
425 partially on the line of the selected window which contains the
426 cursor; <= 0 if not known. Set by set_cursor_from_row, used for
427 redisplay optimization in redisplay_internal. */
428
429 static struct text_pos this_line_start_pos;
430
431 /* Number of characters past the end of the line above, including the
432 terminating newline. */
433
434 static struct text_pos this_line_end_pos;
435
436 /* The vertical positions and the height of this line. */
437
438 static int this_line_vpos;
439 static int this_line_y;
440 static int this_line_pixel_height;
441
442 /* X position at which this display line starts. Usually zero;
443 negative if first character is partially visible. */
444
445 static int this_line_start_x;
446
447 /* The smallest character position seen by move_it_* functions as they
448 move across display lines. Used to set MATRIX_ROW_START_CHARPOS of
449 hscrolled lines, see display_line. */
450
451 static struct text_pos this_line_min_pos;
452
453 /* Buffer that this_line_.* variables are referring to. */
454
455 static struct buffer *this_line_buffer;
456
457
458 /* Values of those variables at last redisplay are stored as
459 properties on `overlay-arrow-position' symbol. However, if
460 Voverlay_arrow_position is a marker, last-arrow-position is its
461 numerical position. */
462
463 Lisp_Object Qlast_arrow_position, Qlast_arrow_string;
464
465 /* Alternative overlay-arrow-string and overlay-arrow-bitmap
466 properties on a symbol in overlay-arrow-variable-list. */
467
468 Lisp_Object Qoverlay_arrow_string, Qoverlay_arrow_bitmap;
469
470 Lisp_Object Qmenu_bar_update_hook;
471
472 /* Nonzero if an overlay arrow has been displayed in this window. */
473
474 static int overlay_arrow_seen;
475
476 /* Number of windows showing the buffer of the selected window (or
477 another buffer with the same base buffer). keyboard.c refers to
478 this. */
479
480 int buffer_shared;
481
482 /* Vector containing glyphs for an ellipsis `...'. */
483
484 static Lisp_Object default_invis_vector[3];
485
486 /* This is the window where the echo area message was displayed. It
487 is always a mini-buffer window, but it may not be the same window
488 currently active as a mini-buffer. */
489
490 Lisp_Object echo_area_window;
491
492 /* List of pairs (MESSAGE . MULTIBYTE). The function save_message
493 pushes the current message and the value of
494 message_enable_multibyte on the stack, the function restore_message
495 pops the stack and displays MESSAGE again. */
496
497 Lisp_Object Vmessage_stack;
498
499 /* Nonzero means multibyte characters were enabled when the echo area
500 message was specified. */
501
502 int message_enable_multibyte;
503
504 /* Nonzero if we should redraw the mode lines on the next redisplay. */
505
506 int update_mode_lines;
507
508 /* Nonzero if window sizes or contents have changed since last
509 redisplay that finished. */
510
511 int windows_or_buffers_changed;
512
513 /* Nonzero means a frame's cursor type has been changed. */
514
515 int cursor_type_changed;
516
517 /* Nonzero after display_mode_line if %l was used and it displayed a
518 line number. */
519
520 int line_number_displayed;
521
522 /* The name of the *Messages* buffer, a string. */
523
524 static Lisp_Object Vmessages_buffer_name;
525
526 /* Current, index 0, and last displayed echo area message. Either
527 buffers from echo_buffers, or nil to indicate no message. */
528
529 Lisp_Object echo_area_buffer[2];
530
531 /* The buffers referenced from echo_area_buffer. */
532
533 static Lisp_Object echo_buffer[2];
534
535 /* A vector saved used in with_area_buffer to reduce consing. */
536
537 static Lisp_Object Vwith_echo_area_save_vector;
538
539 /* Non-zero means display_echo_area should display the last echo area
540 message again. Set by redisplay_preserve_echo_area. */
541
542 static int display_last_displayed_message_p;
543
544 /* Nonzero if echo area is being used by print; zero if being used by
545 message. */
546
547 int message_buf_print;
548
549 /* The symbol `inhibit-menubar-update' and its DEFVAR_BOOL variable. */
550
551 Lisp_Object Qinhibit_menubar_update;
552 Lisp_Object Qmessage_truncate_lines;
553
554 /* Set to 1 in clear_message to make redisplay_internal aware
555 of an emptied echo area. */
556
557 static int message_cleared_p;
558
559 /* A scratch glyph row with contents used for generating truncation
560 glyphs. Also used in direct_output_for_insert. */
561
562 #define MAX_SCRATCH_GLYPHS 100
563 struct glyph_row scratch_glyph_row;
564 static struct glyph scratch_glyphs[MAX_SCRATCH_GLYPHS];
565
566 /* Ascent and height of the last line processed by move_it_to. */
567
568 static int last_max_ascent, last_height;
569
570 /* Non-zero if there's a help-echo in the echo area. */
571
572 int help_echo_showing_p;
573
574 /* If >= 0, computed, exact values of mode-line and header-line height
575 to use in the macros CURRENT_MODE_LINE_HEIGHT and
576 CURRENT_HEADER_LINE_HEIGHT. */
577
578 int current_mode_line_height, current_header_line_height;
579
580 /* The maximum distance to look ahead for text properties. Values
581 that are too small let us call compute_char_face and similar
582 functions too often which is expensive. Values that are too large
583 let us call compute_char_face and alike too often because we
584 might not be interested in text properties that far away. */
585
586 #define TEXT_PROP_DISTANCE_LIMIT 100
587
588 #if GLYPH_DEBUG
589
590 /* Non-zero means print traces of redisplay if compiled with
591 GLYPH_DEBUG != 0. */
592
593 int trace_redisplay_p;
594
595 #endif /* GLYPH_DEBUG */
596
597 #ifdef DEBUG_TRACE_MOVE
598 /* Non-zero means trace with TRACE_MOVE to stderr. */
599 int trace_move;
600
601 #define TRACE_MOVE(x) if (trace_move) fprintf x; else (void) 0
602 #else
603 #define TRACE_MOVE(x) (void) 0
604 #endif
605
606 Lisp_Object Qauto_hscroll_mode;
607
608 /* Buffer being redisplayed -- for redisplay_window_error. */
609
610 struct buffer *displayed_buffer;
611
612 /* Value returned from text property handlers (see below). */
613
614 enum prop_handled
615 {
616 HANDLED_NORMALLY,
617 HANDLED_RECOMPUTE_PROPS,
618 HANDLED_OVERLAY_STRING_CONSUMED,
619 HANDLED_RETURN
620 };
621
622 /* A description of text properties that redisplay is interested
623 in. */
624
625 struct props
626 {
627 /* The name of the property. */
628 Lisp_Object *name;
629
630 /* A unique index for the property. */
631 enum prop_idx idx;
632
633 /* A handler function called to set up iterator IT from the property
634 at IT's current position. Value is used to steer handle_stop. */
635 enum prop_handled (*handler) (struct it *it);
636 };
637
638 static enum prop_handled handle_face_prop (struct it *);
639 static enum prop_handled handle_invisible_prop (struct it *);
640 static enum prop_handled handle_display_prop (struct it *);
641 static enum prop_handled handle_composition_prop (struct it *);
642 static enum prop_handled handle_overlay_change (struct it *);
643 static enum prop_handled handle_fontified_prop (struct it *);
644
645 /* Properties handled by iterators. */
646
647 static struct props it_props[] =
648 {
649 {&Qfontified, FONTIFIED_PROP_IDX, handle_fontified_prop},
650 /* Handle `face' before `display' because some sub-properties of
651 `display' need to know the face. */
652 {&Qface, FACE_PROP_IDX, handle_face_prop},
653 {&Qdisplay, DISPLAY_PROP_IDX, handle_display_prop},
654 {&Qinvisible, INVISIBLE_PROP_IDX, handle_invisible_prop},
655 {&Qcomposition, COMPOSITION_PROP_IDX, handle_composition_prop},
656 {NULL, 0, NULL}
657 };
658
659 /* Value is the position described by X. If X is a marker, value is
660 the marker_position of X. Otherwise, value is X. */
661
662 #define COERCE_MARKER(X) (MARKERP ((X)) ? Fmarker_position (X) : (X))
663
664 /* Enumeration returned by some move_it_.* functions internally. */
665
666 enum move_it_result
667 {
668 /* Not used. Undefined value. */
669 MOVE_UNDEFINED,
670
671 /* Move ended at the requested buffer position or ZV. */
672 MOVE_POS_MATCH_OR_ZV,
673
674 /* Move ended at the requested X pixel position. */
675 MOVE_X_REACHED,
676
677 /* Move within a line ended at the end of a line that must be
678 continued. */
679 MOVE_LINE_CONTINUED,
680
681 /* Move within a line ended at the end of a line that would
682 be displayed truncated. */
683 MOVE_LINE_TRUNCATED,
684
685 /* Move within a line ended at a line end. */
686 MOVE_NEWLINE_OR_CR
687 };
688
689 /* This counter is used to clear the face cache every once in a while
690 in redisplay_internal. It is incremented for each redisplay.
691 Every CLEAR_FACE_CACHE_COUNT full redisplays, the face cache is
692 cleared. */
693
694 #define CLEAR_FACE_CACHE_COUNT 500
695 static int clear_face_cache_count;
696
697 /* Similarly for the image cache. */
698
699 #ifdef HAVE_WINDOW_SYSTEM
700 #define CLEAR_IMAGE_CACHE_COUNT 101
701 static int clear_image_cache_count;
702
703 /* Null glyph slice */
704 static struct glyph_slice null_glyph_slice = { 0, 0, 0, 0 };
705 #endif
706
707 /* Non-zero while redisplay_internal is in progress. */
708
709 int redisplaying_p;
710
711 Lisp_Object Qinhibit_free_realized_faces;
712
713 /* If a string, XTread_socket generates an event to display that string.
714 (The display is done in read_char.) */
715
716 Lisp_Object help_echo_string;
717 Lisp_Object help_echo_window;
718 Lisp_Object help_echo_object;
719 EMACS_INT help_echo_pos;
720
721 /* Temporary variable for XTread_socket. */
722
723 Lisp_Object previous_help_echo_string;
724
725 /* Platform-independent portion of hourglass implementation. */
726
727 /* Non-zero means an hourglass cursor is currently shown. */
728 int hourglass_shown_p;
729
730 /* If non-null, an asynchronous timer that, when it expires, displays
731 an hourglass cursor on all frames. */
732 struct atimer *hourglass_atimer;
733
734 /* Name of the face used to display glyphless characters. */
735 Lisp_Object Qglyphless_char;
736
737 /* Symbol for the purpose of Vglyphless_char_display. */
738 Lisp_Object Qglyphless_char_display;
739
740 /* Method symbols for Vglyphless_char_display. */
741 static Lisp_Object Qhex_code, Qempty_box, Qthin_space, Qzero_width;
742
743 /* Default pixel width of `thin-space' display method. */
744 #define THIN_SPACE_WIDTH 1
745
746 /* Default number of seconds to wait before displaying an hourglass
747 cursor. */
748 #define DEFAULT_HOURGLASS_DELAY 1
749
750 \f
751 /* Function prototypes. */
752
753 static void setup_for_ellipsis (struct it *, int);
754 static void mark_window_display_accurate_1 (struct window *, int);
755 static int single_display_spec_string_p (Lisp_Object, Lisp_Object);
756 static int display_prop_string_p (Lisp_Object, Lisp_Object);
757 static int cursor_row_p (struct glyph_row *);
758 static int redisplay_mode_lines (Lisp_Object, int);
759 static char *decode_mode_spec_coding (Lisp_Object, char *, int);
760
761 static Lisp_Object get_it_property (struct it *it, Lisp_Object prop);
762
763 static void handle_line_prefix (struct it *);
764
765 static void pint2str (char *, int, EMACS_INT);
766 static void pint2hrstr (char *, int, int);
767 static struct text_pos run_window_scroll_functions (Lisp_Object,
768 struct text_pos);
769 static void reconsider_clip_changes (struct window *, struct buffer *);
770 static int text_outside_line_unchanged_p (struct window *,
771 EMACS_INT, EMACS_INT);
772 static void store_mode_line_noprop_char (char);
773 static int store_mode_line_noprop (const char *, int, int);
774 static void handle_stop (struct it *);
775 static void handle_stop_backwards (struct it *, EMACS_INT);
776 static int single_display_spec_intangible_p (Lisp_Object);
777 static void ensure_echo_area_buffers (void);
778 static Lisp_Object unwind_with_echo_area_buffer (Lisp_Object);
779 static Lisp_Object with_echo_area_buffer_unwind_data (struct window *);
780 static int with_echo_area_buffer (struct window *, int,
781 int (*) (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT),
782 EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT);
783 static void clear_garbaged_frames (void);
784 static int current_message_1 (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT);
785 static int truncate_message_1 (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT);
786 static int set_message_1 (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT);
787 static int display_echo_area (struct window *);
788 static int display_echo_area_1 (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT);
789 static int resize_mini_window_1 (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT);
790 static Lisp_Object unwind_redisplay (Lisp_Object);
791 static int string_char_and_length (const unsigned char *, int *);
792 static struct text_pos display_prop_end (struct it *, Lisp_Object,
793 struct text_pos);
794 static int compute_window_start_on_continuation_line (struct window *);
795 static Lisp_Object safe_eval_handler (Lisp_Object);
796 static void insert_left_trunc_glyphs (struct it *);
797 static struct glyph_row *get_overlay_arrow_glyph_row (struct window *,
798 Lisp_Object);
799 static void extend_face_to_end_of_line (struct it *);
800 static int append_space_for_newline (struct it *, int);
801 static int cursor_row_fully_visible_p (struct window *, int, int);
802 static int try_scrolling (Lisp_Object, int, EMACS_INT, EMACS_INT, int, int);
803 static int try_cursor_movement (Lisp_Object, struct text_pos, int *);
804 static int trailing_whitespace_p (EMACS_INT);
805 static unsigned long int message_log_check_duplicate (EMACS_INT, EMACS_INT);
806 static void push_it (struct it *);
807 static void pop_it (struct it *);
808 static void sync_frame_with_window_matrix_rows (struct window *);
809 static void select_frame_for_redisplay (Lisp_Object);
810 static void redisplay_internal (void);
811 static int echo_area_display (int);
812 static void redisplay_windows (Lisp_Object);
813 static void redisplay_window (Lisp_Object, int);
814 static Lisp_Object redisplay_window_error (Lisp_Object);
815 static Lisp_Object redisplay_window_0 (Lisp_Object);
816 static Lisp_Object redisplay_window_1 (Lisp_Object);
817 static int update_menu_bar (struct frame *, int, int);
818 static int try_window_reusing_current_matrix (struct window *);
819 static int try_window_id (struct window *);
820 static int display_line (struct it *);
821 static int display_mode_lines (struct window *);
822 static int display_mode_line (struct window *, enum face_id, Lisp_Object);
823 static int display_mode_element (struct it *, int, int, int, Lisp_Object, Lisp_Object, int);
824 static int store_mode_line_string (const char *, Lisp_Object, int, int, int, Lisp_Object);
825 static const char *decode_mode_spec (struct window *, int, int, Lisp_Object *);
826 static void display_menu_bar (struct window *);
827 static int display_count_lines (EMACS_INT, EMACS_INT, int, EMACS_INT *);
828 static int display_string (const char *, Lisp_Object, Lisp_Object,
829 EMACS_INT, EMACS_INT, struct it *, int, int, int, int);
830 static void compute_line_metrics (struct it *);
831 static void run_redisplay_end_trigger_hook (struct it *);
832 static int get_overlay_strings (struct it *, EMACS_INT);
833 static int get_overlay_strings_1 (struct it *, EMACS_INT, int);
834 static void next_overlay_string (struct it *);
835 static void reseat (struct it *, struct text_pos, int);
836 static void reseat_1 (struct it *, struct text_pos, int);
837 static void back_to_previous_visible_line_start (struct it *);
838 void reseat_at_previous_visible_line_start (struct it *);
839 static void reseat_at_next_visible_line_start (struct it *, int);
840 static int next_element_from_ellipsis (struct it *);
841 static int next_element_from_display_vector (struct it *);
842 static int next_element_from_string (struct it *);
843 static int next_element_from_c_string (struct it *);
844 static int next_element_from_buffer (struct it *);
845 static int next_element_from_composition (struct it *);
846 static int next_element_from_image (struct it *);
847 static int next_element_from_stretch (struct it *);
848 static void load_overlay_strings (struct it *, EMACS_INT);
849 static int init_from_display_pos (struct it *, struct window *,
850 struct display_pos *);
851 static void reseat_to_string (struct it *, const char *,
852 Lisp_Object, EMACS_INT, EMACS_INT, int, int);
853 static enum move_it_result
854 move_it_in_display_line_to (struct it *, EMACS_INT, int,
855 enum move_operation_enum);
856 void move_it_vertically_backward (struct it *, int);
857 static void init_to_row_start (struct it *, struct window *,
858 struct glyph_row *);
859 static int init_to_row_end (struct it *, struct window *,
860 struct glyph_row *);
861 static void back_to_previous_line_start (struct it *);
862 static int forward_to_next_line_start (struct it *, int *);
863 static struct text_pos string_pos_nchars_ahead (struct text_pos,
864 Lisp_Object, EMACS_INT);
865 static struct text_pos string_pos (EMACS_INT, Lisp_Object);
866 static struct text_pos c_string_pos (EMACS_INT, const char *, int);
867 static EMACS_INT number_of_chars (const char *, int);
868 static void compute_stop_pos (struct it *);
869 static void compute_string_pos (struct text_pos *, struct text_pos,
870 Lisp_Object);
871 static int face_before_or_after_it_pos (struct it *, int);
872 static EMACS_INT next_overlay_change (EMACS_INT);
873 static int handle_single_display_spec (struct it *, Lisp_Object,
874 Lisp_Object, Lisp_Object,
875 struct text_pos *, int);
876 static int underlying_face_id (struct it *);
877 static int in_ellipses_for_invisible_text_p (struct display_pos *,
878 struct window *);
879
880 #define face_before_it_pos(IT) face_before_or_after_it_pos ((IT), 1)
881 #define face_after_it_pos(IT) face_before_or_after_it_pos ((IT), 0)
882
883 #ifdef HAVE_WINDOW_SYSTEM
884
885 static void x_consider_frame_title (Lisp_Object);
886 static int tool_bar_lines_needed (struct frame *, int *);
887 static void update_tool_bar (struct frame *, int);
888 static void build_desired_tool_bar_string (struct frame *f);
889 static int redisplay_tool_bar (struct frame *);
890 static void display_tool_bar_line (struct it *, int);
891 static void notice_overwritten_cursor (struct window *,
892 enum glyph_row_area,
893 int, int, int, int);
894 static void append_stretch_glyph (struct it *, Lisp_Object,
895 int, int, int);
896
897
898 #endif /* HAVE_WINDOW_SYSTEM */
899
900 static int coords_in_mouse_face_p (struct window *, int, int);
901
902
903 \f
904 /***********************************************************************
905 Window display dimensions
906 ***********************************************************************/
907
908 /* Return the bottom boundary y-position for text lines in window W.
909 This is the first y position at which a line cannot start.
910 It is relative to the top of the window.
911
912 This is the height of W minus the height of a mode line, if any. */
913
914 INLINE int
915 window_text_bottom_y (struct window *w)
916 {
917 int height = WINDOW_TOTAL_HEIGHT (w);
918
919 if (WINDOW_WANTS_MODELINE_P (w))
920 height -= CURRENT_MODE_LINE_HEIGHT (w);
921 return height;
922 }
923
924 /* Return the pixel width of display area AREA of window W. AREA < 0
925 means return the total width of W, not including fringes to
926 the left and right of the window. */
927
928 INLINE int
929 window_box_width (struct window *w, int area)
930 {
931 int cols = XFASTINT (w->total_cols);
932 int pixels = 0;
933
934 if (!w->pseudo_window_p)
935 {
936 cols -= WINDOW_SCROLL_BAR_COLS (w);
937
938 if (area == TEXT_AREA)
939 {
940 if (INTEGERP (w->left_margin_cols))
941 cols -= XFASTINT (w->left_margin_cols);
942 if (INTEGERP (w->right_margin_cols))
943 cols -= XFASTINT (w->right_margin_cols);
944 pixels = -WINDOW_TOTAL_FRINGE_WIDTH (w);
945 }
946 else if (area == LEFT_MARGIN_AREA)
947 {
948 cols = (INTEGERP (w->left_margin_cols)
949 ? XFASTINT (w->left_margin_cols) : 0);
950 pixels = 0;
951 }
952 else if (area == RIGHT_MARGIN_AREA)
953 {
954 cols = (INTEGERP (w->right_margin_cols)
955 ? XFASTINT (w->right_margin_cols) : 0);
956 pixels = 0;
957 }
958 }
959
960 return cols * WINDOW_FRAME_COLUMN_WIDTH (w) + pixels;
961 }
962
963
964 /* Return the pixel height of the display area of window W, not
965 including mode lines of W, if any. */
966
967 INLINE int
968 window_box_height (struct window *w)
969 {
970 struct frame *f = XFRAME (w->frame);
971 int height = WINDOW_TOTAL_HEIGHT (w);
972
973 xassert (height >= 0);
974
975 /* Note: the code below that determines the mode-line/header-line
976 height is essentially the same as that contained in the macro
977 CURRENT_{MODE,HEADER}_LINE_HEIGHT, except that it checks whether
978 the appropriate glyph row has its `mode_line_p' flag set,
979 and if it doesn't, uses estimate_mode_line_height instead. */
980
981 if (WINDOW_WANTS_MODELINE_P (w))
982 {
983 struct glyph_row *ml_row
984 = (w->current_matrix && w->current_matrix->rows
985 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
986 : 0);
987 if (ml_row && ml_row->mode_line_p)
988 height -= ml_row->height;
989 else
990 height -= estimate_mode_line_height (f, CURRENT_MODE_LINE_FACE_ID (w));
991 }
992
993 if (WINDOW_WANTS_HEADER_LINE_P (w))
994 {
995 struct glyph_row *hl_row
996 = (w->current_matrix && w->current_matrix->rows
997 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
998 : 0);
999 if (hl_row && hl_row->mode_line_p)
1000 height -= hl_row->height;
1001 else
1002 height -= estimate_mode_line_height (f, HEADER_LINE_FACE_ID);
1003 }
1004
1005 /* With a very small font and a mode-line that's taller than
1006 default, we might end up with a negative height. */
1007 return max (0, height);
1008 }
1009
1010 /* Return the window-relative coordinate of the left edge of display
1011 area AREA of window W. AREA < 0 means return the left edge of the
1012 whole window, to the right of the left fringe of W. */
1013
1014 INLINE int
1015 window_box_left_offset (struct window *w, int area)
1016 {
1017 int x;
1018
1019 if (w->pseudo_window_p)
1020 return 0;
1021
1022 x = WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
1023
1024 if (area == TEXT_AREA)
1025 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1026 + window_box_width (w, LEFT_MARGIN_AREA));
1027 else if (area == RIGHT_MARGIN_AREA)
1028 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1029 + window_box_width (w, LEFT_MARGIN_AREA)
1030 + window_box_width (w, TEXT_AREA)
1031 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
1032 ? 0
1033 : WINDOW_RIGHT_FRINGE_WIDTH (w)));
1034 else if (area == LEFT_MARGIN_AREA
1035 && WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w))
1036 x += WINDOW_LEFT_FRINGE_WIDTH (w);
1037
1038 return x;
1039 }
1040
1041
1042 /* Return the window-relative coordinate of the right edge of display
1043 area AREA of window W. AREA < 0 means return the right edge of the
1044 whole window, to the left of the right fringe of W. */
1045
1046 INLINE int
1047 window_box_right_offset (struct window *w, int area)
1048 {
1049 return window_box_left_offset (w, area) + window_box_width (w, area);
1050 }
1051
1052 /* Return the frame-relative coordinate of the left edge of display
1053 area AREA of window W. AREA < 0 means return the left edge of the
1054 whole window, to the right of the left fringe of W. */
1055
1056 INLINE int
1057 window_box_left (struct window *w, int area)
1058 {
1059 struct frame *f = XFRAME (w->frame);
1060 int x;
1061
1062 if (w->pseudo_window_p)
1063 return FRAME_INTERNAL_BORDER_WIDTH (f);
1064
1065 x = (WINDOW_LEFT_EDGE_X (w)
1066 + window_box_left_offset (w, area));
1067
1068 return x;
1069 }
1070
1071
1072 /* Return the frame-relative coordinate of the right edge of display
1073 area AREA of window W. AREA < 0 means return the right edge of the
1074 whole window, to the left of the right fringe of W. */
1075
1076 INLINE int
1077 window_box_right (struct window *w, int area)
1078 {
1079 return window_box_left (w, area) + window_box_width (w, area);
1080 }
1081
1082 /* Get the bounding box of the display area AREA of window W, without
1083 mode lines, in frame-relative coordinates. AREA < 0 means the
1084 whole window, not including the left and right fringes of
1085 the window. Return in *BOX_X and *BOX_Y the frame-relative pixel
1086 coordinates of the upper-left corner of the box. Return in
1087 *BOX_WIDTH, and *BOX_HEIGHT the pixel width and height of the box. */
1088
1089 INLINE void
1090 window_box (struct window *w, int area, int *box_x, int *box_y,
1091 int *box_width, int *box_height)
1092 {
1093 if (box_width)
1094 *box_width = window_box_width (w, area);
1095 if (box_height)
1096 *box_height = window_box_height (w);
1097 if (box_x)
1098 *box_x = window_box_left (w, area);
1099 if (box_y)
1100 {
1101 *box_y = WINDOW_TOP_EDGE_Y (w);
1102 if (WINDOW_WANTS_HEADER_LINE_P (w))
1103 *box_y += CURRENT_HEADER_LINE_HEIGHT (w);
1104 }
1105 }
1106
1107
1108 /* Get the bounding box of the display area AREA of window W, without
1109 mode lines. AREA < 0 means the whole window, not including the
1110 left and right fringe of the window. Return in *TOP_LEFT_X
1111 and TOP_LEFT_Y the frame-relative pixel coordinates of the
1112 upper-left corner of the box. Return in *BOTTOM_RIGHT_X, and
1113 *BOTTOM_RIGHT_Y the coordinates of the bottom-right corner of the
1114 box. */
1115
1116 INLINE void
1117 window_box_edges (struct window *w, int area, int *top_left_x, int *top_left_y,
1118 int *bottom_right_x, int *bottom_right_y)
1119 {
1120 window_box (w, area, top_left_x, top_left_y, bottom_right_x,
1121 bottom_right_y);
1122 *bottom_right_x += *top_left_x;
1123 *bottom_right_y += *top_left_y;
1124 }
1125
1126
1127 \f
1128 /***********************************************************************
1129 Utilities
1130 ***********************************************************************/
1131
1132 /* Return the bottom y-position of the line the iterator IT is in.
1133 This can modify IT's settings. */
1134
1135 int
1136 line_bottom_y (struct it *it)
1137 {
1138 int line_height = it->max_ascent + it->max_descent;
1139 int line_top_y = it->current_y;
1140
1141 if (line_height == 0)
1142 {
1143 if (last_height)
1144 line_height = last_height;
1145 else if (IT_CHARPOS (*it) < ZV)
1146 {
1147 move_it_by_lines (it, 1);
1148 line_height = (it->max_ascent || it->max_descent
1149 ? it->max_ascent + it->max_descent
1150 : last_height);
1151 }
1152 else
1153 {
1154 struct glyph_row *row = it->glyph_row;
1155
1156 /* Use the default character height. */
1157 it->glyph_row = NULL;
1158 it->what = IT_CHARACTER;
1159 it->c = ' ';
1160 it->len = 1;
1161 PRODUCE_GLYPHS (it);
1162 line_height = it->ascent + it->descent;
1163 it->glyph_row = row;
1164 }
1165 }
1166
1167 return line_top_y + line_height;
1168 }
1169
1170
1171 /* Return 1 if position CHARPOS is visible in window W.
1172 CHARPOS < 0 means return info about WINDOW_END position.
1173 If visible, set *X and *Y to pixel coordinates of top left corner.
1174 Set *RTOP and *RBOT to pixel height of an invisible area of glyph at POS.
1175 Set *ROWH and *VPOS to row's visible height and VPOS (row number). */
1176
1177 int
1178 pos_visible_p (struct window *w, EMACS_INT charpos, int *x, int *y,
1179 int *rtop, int *rbot, int *rowh, int *vpos)
1180 {
1181 struct it it;
1182 struct text_pos top;
1183 int visible_p = 0;
1184 struct buffer *old_buffer = NULL;
1185
1186 if (FRAME_INITIAL_P (XFRAME (WINDOW_FRAME (w))))
1187 return visible_p;
1188
1189 if (XBUFFER (w->buffer) != current_buffer)
1190 {
1191 old_buffer = current_buffer;
1192 set_buffer_internal_1 (XBUFFER (w->buffer));
1193 }
1194
1195 SET_TEXT_POS_FROM_MARKER (top, w->start);
1196
1197 /* Compute exact mode line heights. */
1198 if (WINDOW_WANTS_MODELINE_P (w))
1199 current_mode_line_height
1200 = display_mode_line (w, CURRENT_MODE_LINE_FACE_ID (w),
1201 BVAR (current_buffer, mode_line_format));
1202
1203 if (WINDOW_WANTS_HEADER_LINE_P (w))
1204 current_header_line_height
1205 = display_mode_line (w, HEADER_LINE_FACE_ID,
1206 BVAR (current_buffer, header_line_format));
1207
1208 start_display (&it, w, top);
1209 move_it_to (&it, charpos, -1, it.last_visible_y-1, -1,
1210 (charpos >= 0 ? MOVE_TO_POS : 0) | MOVE_TO_Y);
1211
1212 if (charpos >= 0 && IT_CHARPOS (it) >= charpos)
1213 {
1214 /* We have reached CHARPOS, or passed it. How the call to
1215 move_it_to can overshoot: (i) If CHARPOS is on invisible
1216 text, move_it_to stops at the end of the invisible text,
1217 after CHARPOS. (ii) If CHARPOS is in a display vector,
1218 move_it_to stops on its last glyph. */
1219 int top_x = it.current_x;
1220 int top_y = it.current_y;
1221 enum it_method it_method = it.method;
1222 /* Calling line_bottom_y may change it.method, it.position, etc. */
1223 int bottom_y = (last_height = 0, line_bottom_y (&it));
1224 int window_top_y = WINDOW_HEADER_LINE_HEIGHT (w);
1225
1226 if (top_y < window_top_y)
1227 visible_p = bottom_y > window_top_y;
1228 else if (top_y < it.last_visible_y)
1229 visible_p = 1;
1230 if (visible_p)
1231 {
1232 if (it_method == GET_FROM_DISPLAY_VECTOR)
1233 {
1234 /* We stopped on the last glyph of a display vector.
1235 Try and recompute. Hack alert! */
1236 if (charpos < 2 || top.charpos >= charpos)
1237 top_x = it.glyph_row->x;
1238 else
1239 {
1240 struct it it2;
1241 start_display (&it2, w, top);
1242 move_it_to (&it2, charpos - 1, -1, -1, -1, MOVE_TO_POS);
1243 get_next_display_element (&it2);
1244 PRODUCE_GLYPHS (&it2);
1245 if (ITERATOR_AT_END_OF_LINE_P (&it2)
1246 || it2.current_x > it2.last_visible_x)
1247 top_x = it.glyph_row->x;
1248 else
1249 {
1250 top_x = it2.current_x;
1251 top_y = it2.current_y;
1252 }
1253 }
1254 }
1255
1256 *x = top_x;
1257 *y = max (top_y + max (0, it.max_ascent - it.ascent), window_top_y);
1258 *rtop = max (0, window_top_y - top_y);
1259 *rbot = max (0, bottom_y - it.last_visible_y);
1260 *rowh = max (0, (min (bottom_y, it.last_visible_y)
1261 - max (top_y, window_top_y)));
1262 *vpos = it.vpos;
1263 }
1264 }
1265 else
1266 {
1267 struct it it2;
1268
1269 it2 = it;
1270 if (IT_CHARPOS (it) < ZV && FETCH_BYTE (IT_BYTEPOS (it)) != '\n')
1271 move_it_by_lines (&it, 1);
1272 if (charpos < IT_CHARPOS (it)
1273 || (it.what == IT_EOB && charpos == IT_CHARPOS (it)))
1274 {
1275 visible_p = 1;
1276 move_it_to (&it2, charpos, -1, -1, -1, MOVE_TO_POS);
1277 *x = it2.current_x;
1278 *y = it2.current_y + it2.max_ascent - it2.ascent;
1279 *rtop = max (0, -it2.current_y);
1280 *rbot = max (0, ((it2.current_y + it2.max_ascent + it2.max_descent)
1281 - it.last_visible_y));
1282 *rowh = max (0, (min (it2.current_y + it2.max_ascent + it2.max_descent,
1283 it.last_visible_y)
1284 - max (it2.current_y,
1285 WINDOW_HEADER_LINE_HEIGHT (w))));
1286 *vpos = it2.vpos;
1287 }
1288 }
1289
1290 if (old_buffer)
1291 set_buffer_internal_1 (old_buffer);
1292
1293 current_header_line_height = current_mode_line_height = -1;
1294
1295 if (visible_p && XFASTINT (w->hscroll) > 0)
1296 *x -= XFASTINT (w->hscroll) * WINDOW_FRAME_COLUMN_WIDTH (w);
1297
1298 #if 0
1299 /* Debugging code. */
1300 if (visible_p)
1301 fprintf (stderr, "+pv pt=%d vs=%d --> x=%d y=%d rt=%d rb=%d rh=%d vp=%d\n",
1302 charpos, w->vscroll, *x, *y, *rtop, *rbot, *rowh, *vpos);
1303 else
1304 fprintf (stderr, "-pv pt=%d vs=%d\n", charpos, w->vscroll);
1305 #endif
1306
1307 return visible_p;
1308 }
1309
1310
1311 /* Return the next character from STR. Return in *LEN the length of
1312 the character. This is like STRING_CHAR_AND_LENGTH but never
1313 returns an invalid character. If we find one, we return a `?', but
1314 with the length of the invalid character. */
1315
1316 static INLINE int
1317 string_char_and_length (const unsigned char *str, int *len)
1318 {
1319 int c;
1320
1321 c = STRING_CHAR_AND_LENGTH (str, *len);
1322 if (!CHAR_VALID_P (c, 1))
1323 /* We may not change the length here because other places in Emacs
1324 don't use this function, i.e. they silently accept invalid
1325 characters. */
1326 c = '?';
1327
1328 return c;
1329 }
1330
1331
1332
1333 /* Given a position POS containing a valid character and byte position
1334 in STRING, return the position NCHARS ahead (NCHARS >= 0). */
1335
1336 static struct text_pos
1337 string_pos_nchars_ahead (struct text_pos pos, Lisp_Object string, EMACS_INT nchars)
1338 {
1339 xassert (STRINGP (string) && nchars >= 0);
1340
1341 if (STRING_MULTIBYTE (string))
1342 {
1343 const unsigned char *p = SDATA (string) + BYTEPOS (pos);
1344 int len;
1345
1346 while (nchars--)
1347 {
1348 string_char_and_length (p, &len);
1349 p += len;
1350 CHARPOS (pos) += 1;
1351 BYTEPOS (pos) += len;
1352 }
1353 }
1354 else
1355 SET_TEXT_POS (pos, CHARPOS (pos) + nchars, BYTEPOS (pos) + nchars);
1356
1357 return pos;
1358 }
1359
1360
1361 /* Value is the text position, i.e. character and byte position,
1362 for character position CHARPOS in STRING. */
1363
1364 static INLINE struct text_pos
1365 string_pos (EMACS_INT charpos, Lisp_Object string)
1366 {
1367 struct text_pos pos;
1368 xassert (STRINGP (string));
1369 xassert (charpos >= 0);
1370 SET_TEXT_POS (pos, charpos, string_char_to_byte (string, charpos));
1371 return pos;
1372 }
1373
1374
1375 /* Value is a text position, i.e. character and byte position, for
1376 character position CHARPOS in C string S. MULTIBYTE_P non-zero
1377 means recognize multibyte characters. */
1378
1379 static struct text_pos
1380 c_string_pos (EMACS_INT charpos, const char *s, int multibyte_p)
1381 {
1382 struct text_pos pos;
1383
1384 xassert (s != NULL);
1385 xassert (charpos >= 0);
1386
1387 if (multibyte_p)
1388 {
1389 int len;
1390
1391 SET_TEXT_POS (pos, 0, 0);
1392 while (charpos--)
1393 {
1394 string_char_and_length ((const unsigned char *) s, &len);
1395 s += len;
1396 CHARPOS (pos) += 1;
1397 BYTEPOS (pos) += len;
1398 }
1399 }
1400 else
1401 SET_TEXT_POS (pos, charpos, charpos);
1402
1403 return pos;
1404 }
1405
1406
1407 /* Value is the number of characters in C string S. MULTIBYTE_P
1408 non-zero means recognize multibyte characters. */
1409
1410 static EMACS_INT
1411 number_of_chars (const char *s, int multibyte_p)
1412 {
1413 EMACS_INT nchars;
1414
1415 if (multibyte_p)
1416 {
1417 EMACS_INT rest = strlen (s);
1418 int len;
1419 const unsigned char *p = (const unsigned char *) s;
1420
1421 for (nchars = 0; rest > 0; ++nchars)
1422 {
1423 string_char_and_length (p, &len);
1424 rest -= len, p += len;
1425 }
1426 }
1427 else
1428 nchars = strlen (s);
1429
1430 return nchars;
1431 }
1432
1433
1434 /* Compute byte position NEWPOS->bytepos corresponding to
1435 NEWPOS->charpos. POS is a known position in string STRING.
1436 NEWPOS->charpos must be >= POS.charpos. */
1437
1438 static void
1439 compute_string_pos (struct text_pos *newpos, struct text_pos pos, Lisp_Object string)
1440 {
1441 xassert (STRINGP (string));
1442 xassert (CHARPOS (*newpos) >= CHARPOS (pos));
1443
1444 if (STRING_MULTIBYTE (string))
1445 *newpos = string_pos_nchars_ahead (pos, string,
1446 CHARPOS (*newpos) - CHARPOS (pos));
1447 else
1448 BYTEPOS (*newpos) = CHARPOS (*newpos);
1449 }
1450
1451 /* EXPORT:
1452 Return an estimation of the pixel height of mode or header lines on
1453 frame F. FACE_ID specifies what line's height to estimate. */
1454
1455 int
1456 estimate_mode_line_height (struct frame *f, enum face_id face_id)
1457 {
1458 #ifdef HAVE_WINDOW_SYSTEM
1459 if (FRAME_WINDOW_P (f))
1460 {
1461 int height = FONT_HEIGHT (FRAME_FONT (f));
1462
1463 /* This function is called so early when Emacs starts that the face
1464 cache and mode line face are not yet initialized. */
1465 if (FRAME_FACE_CACHE (f))
1466 {
1467 struct face *face = FACE_FROM_ID (f, face_id);
1468 if (face)
1469 {
1470 if (face->font)
1471 height = FONT_HEIGHT (face->font);
1472 if (face->box_line_width > 0)
1473 height += 2 * face->box_line_width;
1474 }
1475 }
1476
1477 return height;
1478 }
1479 #endif
1480
1481 return 1;
1482 }
1483
1484 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
1485 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
1486 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
1487 not force the value into range. */
1488
1489 void
1490 pixel_to_glyph_coords (FRAME_PTR f, register int pix_x, register int pix_y,
1491 int *x, int *y, NativeRectangle *bounds, int noclip)
1492 {
1493
1494 #ifdef HAVE_WINDOW_SYSTEM
1495 if (FRAME_WINDOW_P (f))
1496 {
1497 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to round down
1498 even for negative values. */
1499 if (pix_x < 0)
1500 pix_x -= FRAME_COLUMN_WIDTH (f) - 1;
1501 if (pix_y < 0)
1502 pix_y -= FRAME_LINE_HEIGHT (f) - 1;
1503
1504 pix_x = FRAME_PIXEL_X_TO_COL (f, pix_x);
1505 pix_y = FRAME_PIXEL_Y_TO_LINE (f, pix_y);
1506
1507 if (bounds)
1508 STORE_NATIVE_RECT (*bounds,
1509 FRAME_COL_TO_PIXEL_X (f, pix_x),
1510 FRAME_LINE_TO_PIXEL_Y (f, pix_y),
1511 FRAME_COLUMN_WIDTH (f) - 1,
1512 FRAME_LINE_HEIGHT (f) - 1);
1513
1514 if (!noclip)
1515 {
1516 if (pix_x < 0)
1517 pix_x = 0;
1518 else if (pix_x > FRAME_TOTAL_COLS (f))
1519 pix_x = FRAME_TOTAL_COLS (f);
1520
1521 if (pix_y < 0)
1522 pix_y = 0;
1523 else if (pix_y > FRAME_LINES (f))
1524 pix_y = FRAME_LINES (f);
1525 }
1526 }
1527 #endif
1528
1529 *x = pix_x;
1530 *y = pix_y;
1531 }
1532
1533
1534 /* Given HPOS/VPOS in the current matrix of W, return corresponding
1535 frame-relative pixel positions in *FRAME_X and *FRAME_Y. If we
1536 can't tell the positions because W's display is not up to date,
1537 return 0. */
1538
1539 int
1540 glyph_to_pixel_coords (struct window *w, int hpos, int vpos,
1541 int *frame_x, int *frame_y)
1542 {
1543 #ifdef HAVE_WINDOW_SYSTEM
1544 if (FRAME_WINDOW_P (XFRAME (WINDOW_FRAME (w))))
1545 {
1546 int success_p;
1547
1548 xassert (hpos >= 0 && hpos < w->current_matrix->matrix_w);
1549 xassert (vpos >= 0 && vpos < w->current_matrix->matrix_h);
1550
1551 if (display_completed)
1552 {
1553 struct glyph_row *row = MATRIX_ROW (w->current_matrix, vpos);
1554 struct glyph *glyph = row->glyphs[TEXT_AREA];
1555 struct glyph *end = glyph + min (hpos, row->used[TEXT_AREA]);
1556
1557 hpos = row->x;
1558 vpos = row->y;
1559 while (glyph < end)
1560 {
1561 hpos += glyph->pixel_width;
1562 ++glyph;
1563 }
1564
1565 /* If first glyph is partially visible, its first visible position is still 0. */
1566 if (hpos < 0)
1567 hpos = 0;
1568
1569 success_p = 1;
1570 }
1571 else
1572 {
1573 hpos = vpos = 0;
1574 success_p = 0;
1575 }
1576
1577 *frame_x = WINDOW_TO_FRAME_PIXEL_X (w, hpos);
1578 *frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, vpos);
1579 return success_p;
1580 }
1581 #endif
1582
1583 *frame_x = hpos;
1584 *frame_y = vpos;
1585 return 1;
1586 }
1587
1588
1589 /* Find the glyph under window-relative coordinates X/Y in window W.
1590 Consider only glyphs from buffer text, i.e. no glyphs from overlay
1591 strings. Return in *HPOS and *VPOS the row and column number of
1592 the glyph found. Return in *AREA the glyph area containing X.
1593 Value is a pointer to the glyph found or null if X/Y is not on
1594 text, or we can't tell because W's current matrix is not up to
1595 date. */
1596
1597 static
1598 struct glyph *
1599 x_y_to_hpos_vpos (struct window *w, int x, int y, int *hpos, int *vpos,
1600 int *dx, int *dy, int *area)
1601 {
1602 struct glyph *glyph, *end;
1603 struct glyph_row *row = NULL;
1604 int x0, i;
1605
1606 /* Find row containing Y. Give up if some row is not enabled. */
1607 for (i = 0; i < w->current_matrix->nrows; ++i)
1608 {
1609 row = MATRIX_ROW (w->current_matrix, i);
1610 if (!row->enabled_p)
1611 return NULL;
1612 if (y >= row->y && y < MATRIX_ROW_BOTTOM_Y (row))
1613 break;
1614 }
1615
1616 *vpos = i;
1617 *hpos = 0;
1618
1619 /* Give up if Y is not in the window. */
1620 if (i == w->current_matrix->nrows)
1621 return NULL;
1622
1623 /* Get the glyph area containing X. */
1624 if (w->pseudo_window_p)
1625 {
1626 *area = TEXT_AREA;
1627 x0 = 0;
1628 }
1629 else
1630 {
1631 if (x < window_box_left_offset (w, TEXT_AREA))
1632 {
1633 *area = LEFT_MARGIN_AREA;
1634 x0 = window_box_left_offset (w, LEFT_MARGIN_AREA);
1635 }
1636 else if (x < window_box_right_offset (w, TEXT_AREA))
1637 {
1638 *area = TEXT_AREA;
1639 x0 = window_box_left_offset (w, TEXT_AREA) + min (row->x, 0);
1640 }
1641 else
1642 {
1643 *area = RIGHT_MARGIN_AREA;
1644 x0 = window_box_left_offset (w, RIGHT_MARGIN_AREA);
1645 }
1646 }
1647
1648 /* Find glyph containing X. */
1649 glyph = row->glyphs[*area];
1650 end = glyph + row->used[*area];
1651 x -= x0;
1652 while (glyph < end && x >= glyph->pixel_width)
1653 {
1654 x -= glyph->pixel_width;
1655 ++glyph;
1656 }
1657
1658 if (glyph == end)
1659 return NULL;
1660
1661 if (dx)
1662 {
1663 *dx = x;
1664 *dy = y - (row->y + row->ascent - glyph->ascent);
1665 }
1666
1667 *hpos = glyph - row->glyphs[*area];
1668 return glyph;
1669 }
1670
1671 /* EXPORT:
1672 Convert frame-relative x/y to coordinates relative to window W.
1673 Takes pseudo-windows into account. */
1674
1675 void
1676 frame_to_window_pixel_xy (struct window *w, int *x, int *y)
1677 {
1678 if (w->pseudo_window_p)
1679 {
1680 /* A pseudo-window is always full-width, and starts at the
1681 left edge of the frame, plus a frame border. */
1682 struct frame *f = XFRAME (w->frame);
1683 *x -= FRAME_INTERNAL_BORDER_WIDTH (f);
1684 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1685 }
1686 else
1687 {
1688 *x -= WINDOW_LEFT_EDGE_X (w);
1689 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1690 }
1691 }
1692
1693 #ifdef HAVE_WINDOW_SYSTEM
1694
1695 /* EXPORT:
1696 Return in RECTS[] at most N clipping rectangles for glyph string S.
1697 Return the number of stored rectangles. */
1698
1699 int
1700 get_glyph_string_clip_rects (struct glyph_string *s, NativeRectangle *rects, int n)
1701 {
1702 XRectangle r;
1703
1704 if (n <= 0)
1705 return 0;
1706
1707 if (s->row->full_width_p)
1708 {
1709 /* Draw full-width. X coordinates are relative to S->w->left_col. */
1710 r.x = WINDOW_LEFT_EDGE_X (s->w);
1711 r.width = WINDOW_TOTAL_WIDTH (s->w);
1712
1713 /* Unless displaying a mode or menu bar line, which are always
1714 fully visible, clip to the visible part of the row. */
1715 if (s->w->pseudo_window_p)
1716 r.height = s->row->visible_height;
1717 else
1718 r.height = s->height;
1719 }
1720 else
1721 {
1722 /* This is a text line that may be partially visible. */
1723 r.x = window_box_left (s->w, s->area);
1724 r.width = window_box_width (s->w, s->area);
1725 r.height = s->row->visible_height;
1726 }
1727
1728 if (s->clip_head)
1729 if (r.x < s->clip_head->x)
1730 {
1731 if (r.width >= s->clip_head->x - r.x)
1732 r.width -= s->clip_head->x - r.x;
1733 else
1734 r.width = 0;
1735 r.x = s->clip_head->x;
1736 }
1737 if (s->clip_tail)
1738 if (r.x + r.width > s->clip_tail->x + s->clip_tail->background_width)
1739 {
1740 if (s->clip_tail->x + s->clip_tail->background_width >= r.x)
1741 r.width = s->clip_tail->x + s->clip_tail->background_width - r.x;
1742 else
1743 r.width = 0;
1744 }
1745
1746 /* If S draws overlapping rows, it's sufficient to use the top and
1747 bottom of the window for clipping because this glyph string
1748 intentionally draws over other lines. */
1749 if (s->for_overlaps)
1750 {
1751 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
1752 r.height = window_text_bottom_y (s->w) - r.y;
1753
1754 /* Alas, the above simple strategy does not work for the
1755 environments with anti-aliased text: if the same text is
1756 drawn onto the same place multiple times, it gets thicker.
1757 If the overlap we are processing is for the erased cursor, we
1758 take the intersection with the rectagle of the cursor. */
1759 if (s->for_overlaps & OVERLAPS_ERASED_CURSOR)
1760 {
1761 XRectangle rc, r_save = r;
1762
1763 rc.x = WINDOW_TEXT_TO_FRAME_PIXEL_X (s->w, s->w->phys_cursor.x);
1764 rc.y = s->w->phys_cursor.y;
1765 rc.width = s->w->phys_cursor_width;
1766 rc.height = s->w->phys_cursor_height;
1767
1768 x_intersect_rectangles (&r_save, &rc, &r);
1769 }
1770 }
1771 else
1772 {
1773 /* Don't use S->y for clipping because it doesn't take partially
1774 visible lines into account. For example, it can be negative for
1775 partially visible lines at the top of a window. */
1776 if (!s->row->full_width_p
1777 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s->w, s->row))
1778 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
1779 else
1780 r.y = max (0, s->row->y);
1781 }
1782
1783 r.y = WINDOW_TO_FRAME_PIXEL_Y (s->w, r.y);
1784
1785 /* If drawing the cursor, don't let glyph draw outside its
1786 advertised boundaries. Cleartype does this under some circumstances. */
1787 if (s->hl == DRAW_CURSOR)
1788 {
1789 struct glyph *glyph = s->first_glyph;
1790 int height, max_y;
1791
1792 if (s->x > r.x)
1793 {
1794 r.width -= s->x - r.x;
1795 r.x = s->x;
1796 }
1797 r.width = min (r.width, glyph->pixel_width);
1798
1799 /* If r.y is below window bottom, ensure that we still see a cursor. */
1800 height = min (glyph->ascent + glyph->descent,
1801 min (FRAME_LINE_HEIGHT (s->f), s->row->visible_height));
1802 max_y = window_text_bottom_y (s->w) - height;
1803 max_y = WINDOW_TO_FRAME_PIXEL_Y (s->w, max_y);
1804 if (s->ybase - glyph->ascent > max_y)
1805 {
1806 r.y = max_y;
1807 r.height = height;
1808 }
1809 else
1810 {
1811 /* Don't draw cursor glyph taller than our actual glyph. */
1812 height = max (FRAME_LINE_HEIGHT (s->f), glyph->ascent + glyph->descent);
1813 if (height < r.height)
1814 {
1815 max_y = r.y + r.height;
1816 r.y = min (max_y, max (r.y, s->ybase + glyph->descent - height));
1817 r.height = min (max_y - r.y, height);
1818 }
1819 }
1820 }
1821
1822 if (s->row->clip)
1823 {
1824 XRectangle r_save = r;
1825
1826 if (! x_intersect_rectangles (&r_save, s->row->clip, &r))
1827 r.width = 0;
1828 }
1829
1830 if ((s->for_overlaps & OVERLAPS_BOTH) == 0
1831 || ((s->for_overlaps & OVERLAPS_BOTH) == OVERLAPS_BOTH && n == 1))
1832 {
1833 #ifdef CONVERT_FROM_XRECT
1834 CONVERT_FROM_XRECT (r, *rects);
1835 #else
1836 *rects = r;
1837 #endif
1838 return 1;
1839 }
1840 else
1841 {
1842 /* If we are processing overlapping and allowed to return
1843 multiple clipping rectangles, we exclude the row of the glyph
1844 string from the clipping rectangle. This is to avoid drawing
1845 the same text on the environment with anti-aliasing. */
1846 #ifdef CONVERT_FROM_XRECT
1847 XRectangle rs[2];
1848 #else
1849 XRectangle *rs = rects;
1850 #endif
1851 int i = 0, row_y = WINDOW_TO_FRAME_PIXEL_Y (s->w, s->row->y);
1852
1853 if (s->for_overlaps & OVERLAPS_PRED)
1854 {
1855 rs[i] = r;
1856 if (r.y + r.height > row_y)
1857 {
1858 if (r.y < row_y)
1859 rs[i].height = row_y - r.y;
1860 else
1861 rs[i].height = 0;
1862 }
1863 i++;
1864 }
1865 if (s->for_overlaps & OVERLAPS_SUCC)
1866 {
1867 rs[i] = r;
1868 if (r.y < row_y + s->row->visible_height)
1869 {
1870 if (r.y + r.height > row_y + s->row->visible_height)
1871 {
1872 rs[i].y = row_y + s->row->visible_height;
1873 rs[i].height = r.y + r.height - rs[i].y;
1874 }
1875 else
1876 rs[i].height = 0;
1877 }
1878 i++;
1879 }
1880
1881 n = i;
1882 #ifdef CONVERT_FROM_XRECT
1883 for (i = 0; i < n; i++)
1884 CONVERT_FROM_XRECT (rs[i], rects[i]);
1885 #endif
1886 return n;
1887 }
1888 }
1889
1890 /* EXPORT:
1891 Return in *NR the clipping rectangle for glyph string S. */
1892
1893 void
1894 get_glyph_string_clip_rect (struct glyph_string *s, NativeRectangle *nr)
1895 {
1896 get_glyph_string_clip_rects (s, nr, 1);
1897 }
1898
1899
1900 /* EXPORT:
1901 Return the position and height of the phys cursor in window W.
1902 Set w->phys_cursor_width to width of phys cursor.
1903 */
1904
1905 void
1906 get_phys_cursor_geometry (struct window *w, struct glyph_row *row,
1907 struct glyph *glyph, int *xp, int *yp, int *heightp)
1908 {
1909 struct frame *f = XFRAME (WINDOW_FRAME (w));
1910 int x, y, wd, h, h0, y0;
1911
1912 /* Compute the width of the rectangle to draw. If on a stretch
1913 glyph, and `x-stretch-block-cursor' is nil, don't draw a
1914 rectangle as wide as the glyph, but use a canonical character
1915 width instead. */
1916 wd = glyph->pixel_width - 1;
1917 #if defined(HAVE_NTGUI) || defined(HAVE_NS)
1918 wd++; /* Why? */
1919 #endif
1920
1921 x = w->phys_cursor.x;
1922 if (x < 0)
1923 {
1924 wd += x;
1925 x = 0;
1926 }
1927
1928 if (glyph->type == STRETCH_GLYPH
1929 && !x_stretch_cursor_p)
1930 wd = min (FRAME_COLUMN_WIDTH (f), wd);
1931 w->phys_cursor_width = wd;
1932
1933 y = w->phys_cursor.y + row->ascent - glyph->ascent;
1934
1935 /* If y is below window bottom, ensure that we still see a cursor. */
1936 h0 = min (FRAME_LINE_HEIGHT (f), row->visible_height);
1937
1938 h = max (h0, glyph->ascent + glyph->descent);
1939 h0 = min (h0, glyph->ascent + glyph->descent);
1940
1941 y0 = WINDOW_HEADER_LINE_HEIGHT (w);
1942 if (y < y0)
1943 {
1944 h = max (h - (y0 - y) + 1, h0);
1945 y = y0 - 1;
1946 }
1947 else
1948 {
1949 y0 = window_text_bottom_y (w) - h0;
1950 if (y > y0)
1951 {
1952 h += y - y0;
1953 y = y0;
1954 }
1955 }
1956
1957 *xp = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, x);
1958 *yp = WINDOW_TO_FRAME_PIXEL_Y (w, y);
1959 *heightp = h;
1960 }
1961
1962 /*
1963 * Remember which glyph the mouse is over.
1964 */
1965
1966 void
1967 remember_mouse_glyph (struct frame *f, int gx, int gy, NativeRectangle *rect)
1968 {
1969 Lisp_Object window;
1970 struct window *w;
1971 struct glyph_row *r, *gr, *end_row;
1972 enum window_part part;
1973 enum glyph_row_area area;
1974 int x, y, width, height;
1975
1976 /* Try to determine frame pixel position and size of the glyph under
1977 frame pixel coordinates X/Y on frame F. */
1978
1979 if (!f->glyphs_initialized_p
1980 || (window = window_from_coordinates (f, gx, gy, &part, 0),
1981 NILP (window)))
1982 {
1983 width = FRAME_SMALLEST_CHAR_WIDTH (f);
1984 height = FRAME_SMALLEST_FONT_HEIGHT (f);
1985 goto virtual_glyph;
1986 }
1987
1988 w = XWINDOW (window);
1989 width = WINDOW_FRAME_COLUMN_WIDTH (w);
1990 height = WINDOW_FRAME_LINE_HEIGHT (w);
1991
1992 x = window_relative_x_coord (w, part, gx);
1993 y = gy - WINDOW_TOP_EDGE_Y (w);
1994
1995 r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
1996 end_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
1997
1998 if (w->pseudo_window_p)
1999 {
2000 area = TEXT_AREA;
2001 part = ON_MODE_LINE; /* Don't adjust margin. */
2002 goto text_glyph;
2003 }
2004
2005 switch (part)
2006 {
2007 case ON_LEFT_MARGIN:
2008 area = LEFT_MARGIN_AREA;
2009 goto text_glyph;
2010
2011 case ON_RIGHT_MARGIN:
2012 area = RIGHT_MARGIN_AREA;
2013 goto text_glyph;
2014
2015 case ON_HEADER_LINE:
2016 case ON_MODE_LINE:
2017 gr = (part == ON_HEADER_LINE
2018 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
2019 : MATRIX_MODE_LINE_ROW (w->current_matrix));
2020 gy = gr->y;
2021 area = TEXT_AREA;
2022 goto text_glyph_row_found;
2023
2024 case ON_TEXT:
2025 area = TEXT_AREA;
2026
2027 text_glyph:
2028 gr = 0; gy = 0;
2029 for (; r <= end_row && r->enabled_p; ++r)
2030 if (r->y + r->height > y)
2031 {
2032 gr = r; gy = r->y;
2033 break;
2034 }
2035
2036 text_glyph_row_found:
2037 if (gr && gy <= y)
2038 {
2039 struct glyph *g = gr->glyphs[area];
2040 struct glyph *end = g + gr->used[area];
2041
2042 height = gr->height;
2043 for (gx = gr->x; g < end; gx += g->pixel_width, ++g)
2044 if (gx + g->pixel_width > x)
2045 break;
2046
2047 if (g < end)
2048 {
2049 if (g->type == IMAGE_GLYPH)
2050 {
2051 /* Don't remember when mouse is over image, as
2052 image may have hot-spots. */
2053 STORE_NATIVE_RECT (*rect, 0, 0, 0, 0);
2054 return;
2055 }
2056 width = g->pixel_width;
2057 }
2058 else
2059 {
2060 /* Use nominal char spacing at end of line. */
2061 x -= gx;
2062 gx += (x / width) * width;
2063 }
2064
2065 if (part != ON_MODE_LINE && part != ON_HEADER_LINE)
2066 gx += window_box_left_offset (w, area);
2067 }
2068 else
2069 {
2070 /* Use nominal line height at end of window. */
2071 gx = (x / width) * width;
2072 y -= gy;
2073 gy += (y / height) * height;
2074 }
2075 break;
2076
2077 case ON_LEFT_FRINGE:
2078 gx = (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2079 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w)
2080 : window_box_right_offset (w, LEFT_MARGIN_AREA));
2081 width = WINDOW_LEFT_FRINGE_WIDTH (w);
2082 goto row_glyph;
2083
2084 case ON_RIGHT_FRINGE:
2085 gx = (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2086 ? window_box_right_offset (w, RIGHT_MARGIN_AREA)
2087 : window_box_right_offset (w, TEXT_AREA));
2088 width = WINDOW_RIGHT_FRINGE_WIDTH (w);
2089 goto row_glyph;
2090
2091 case ON_SCROLL_BAR:
2092 gx = (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w)
2093 ? 0
2094 : (window_box_right_offset (w, RIGHT_MARGIN_AREA)
2095 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2096 ? WINDOW_RIGHT_FRINGE_WIDTH (w)
2097 : 0)));
2098 width = WINDOW_SCROLL_BAR_AREA_WIDTH (w);
2099
2100 row_glyph:
2101 gr = 0, gy = 0;
2102 for (; r <= end_row && r->enabled_p; ++r)
2103 if (r->y + r->height > y)
2104 {
2105 gr = r; gy = r->y;
2106 break;
2107 }
2108
2109 if (gr && gy <= y)
2110 height = gr->height;
2111 else
2112 {
2113 /* Use nominal line height at end of window. */
2114 y -= gy;
2115 gy += (y / height) * height;
2116 }
2117 break;
2118
2119 default:
2120 ;
2121 virtual_glyph:
2122 /* If there is no glyph under the mouse, then we divide the screen
2123 into a grid of the smallest glyph in the frame, and use that
2124 as our "glyph". */
2125
2126 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to
2127 round down even for negative values. */
2128 if (gx < 0)
2129 gx -= width - 1;
2130 if (gy < 0)
2131 gy -= height - 1;
2132
2133 gx = (gx / width) * width;
2134 gy = (gy / height) * height;
2135
2136 goto store_rect;
2137 }
2138
2139 gx += WINDOW_LEFT_EDGE_X (w);
2140 gy += WINDOW_TOP_EDGE_Y (w);
2141
2142 store_rect:
2143 STORE_NATIVE_RECT (*rect, gx, gy, width, height);
2144
2145 /* Visible feedback for debugging. */
2146 #if 0
2147 #if HAVE_X_WINDOWS
2148 XDrawRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2149 f->output_data.x->normal_gc,
2150 gx, gy, width, height);
2151 #endif
2152 #endif
2153 }
2154
2155
2156 #endif /* HAVE_WINDOW_SYSTEM */
2157
2158 \f
2159 /***********************************************************************
2160 Lisp form evaluation
2161 ***********************************************************************/
2162
2163 /* Error handler for safe_eval and safe_call. */
2164
2165 static Lisp_Object
2166 safe_eval_handler (Lisp_Object arg)
2167 {
2168 add_to_log ("Error during redisplay: %S", arg, Qnil);
2169 return Qnil;
2170 }
2171
2172
2173 /* Evaluate SEXPR and return the result, or nil if something went
2174 wrong. Prevent redisplay during the evaluation. */
2175
2176 /* Call function ARGS[0] with arguments ARGS[1] to ARGS[NARGS - 1].
2177 Return the result, or nil if something went wrong. Prevent
2178 redisplay during the evaluation. */
2179
2180 Lisp_Object
2181 safe_call (size_t nargs, Lisp_Object *args)
2182 {
2183 Lisp_Object val;
2184
2185 if (inhibit_eval_during_redisplay)
2186 val = Qnil;
2187 else
2188 {
2189 int count = SPECPDL_INDEX ();
2190 struct gcpro gcpro1;
2191
2192 GCPRO1 (args[0]);
2193 gcpro1.nvars = nargs;
2194 specbind (Qinhibit_redisplay, Qt);
2195 /* Use Qt to ensure debugger does not run,
2196 so there is no possibility of wanting to redisplay. */
2197 val = internal_condition_case_n (Ffuncall, nargs, args, Qt,
2198 safe_eval_handler);
2199 UNGCPRO;
2200 val = unbind_to (count, val);
2201 }
2202
2203 return val;
2204 }
2205
2206
2207 /* Call function FN with one argument ARG.
2208 Return the result, or nil if something went wrong. */
2209
2210 Lisp_Object
2211 safe_call1 (Lisp_Object fn, Lisp_Object arg)
2212 {
2213 Lisp_Object args[2];
2214 args[0] = fn;
2215 args[1] = arg;
2216 return safe_call (2, args);
2217 }
2218
2219 static Lisp_Object Qeval;
2220
2221 Lisp_Object
2222 safe_eval (Lisp_Object sexpr)
2223 {
2224 return safe_call1 (Qeval, sexpr);
2225 }
2226
2227 /* Call function FN with one argument ARG.
2228 Return the result, or nil if something went wrong. */
2229
2230 Lisp_Object
2231 safe_call2 (Lisp_Object fn, Lisp_Object arg1, Lisp_Object arg2)
2232 {
2233 Lisp_Object args[3];
2234 args[0] = fn;
2235 args[1] = arg1;
2236 args[2] = arg2;
2237 return safe_call (3, args);
2238 }
2239
2240
2241 \f
2242 /***********************************************************************
2243 Debugging
2244 ***********************************************************************/
2245
2246 #if 0
2247
2248 /* Define CHECK_IT to perform sanity checks on iterators.
2249 This is for debugging. It is too slow to do unconditionally. */
2250
2251 static void
2252 check_it (it)
2253 struct it *it;
2254 {
2255 if (it->method == GET_FROM_STRING)
2256 {
2257 xassert (STRINGP (it->string));
2258 xassert (IT_STRING_CHARPOS (*it) >= 0);
2259 }
2260 else
2261 {
2262 xassert (IT_STRING_CHARPOS (*it) < 0);
2263 if (it->method == GET_FROM_BUFFER)
2264 {
2265 /* Check that character and byte positions agree. */
2266 xassert (IT_CHARPOS (*it) == BYTE_TO_CHAR (IT_BYTEPOS (*it)));
2267 }
2268 }
2269
2270 if (it->dpvec)
2271 xassert (it->current.dpvec_index >= 0);
2272 else
2273 xassert (it->current.dpvec_index < 0);
2274 }
2275
2276 #define CHECK_IT(IT) check_it ((IT))
2277
2278 #else /* not 0 */
2279
2280 #define CHECK_IT(IT) (void) 0
2281
2282 #endif /* not 0 */
2283
2284
2285 #if GLYPH_DEBUG
2286
2287 /* Check that the window end of window W is what we expect it
2288 to be---the last row in the current matrix displaying text. */
2289
2290 static void
2291 check_window_end (w)
2292 struct window *w;
2293 {
2294 if (!MINI_WINDOW_P (w)
2295 && !NILP (w->window_end_valid))
2296 {
2297 struct glyph_row *row;
2298 xassert ((row = MATRIX_ROW (w->current_matrix,
2299 XFASTINT (w->window_end_vpos)),
2300 !row->enabled_p
2301 || MATRIX_ROW_DISPLAYS_TEXT_P (row)
2302 || MATRIX_ROW_VPOS (row, w->current_matrix) == 0));
2303 }
2304 }
2305
2306 #define CHECK_WINDOW_END(W) check_window_end ((W))
2307
2308 #else /* not GLYPH_DEBUG */
2309
2310 #define CHECK_WINDOW_END(W) (void) 0
2311
2312 #endif /* not GLYPH_DEBUG */
2313
2314
2315 \f
2316 /***********************************************************************
2317 Iterator initialization
2318 ***********************************************************************/
2319
2320 /* Initialize IT for displaying current_buffer in window W, starting
2321 at character position CHARPOS. CHARPOS < 0 means that no buffer
2322 position is specified which is useful when the iterator is assigned
2323 a position later. BYTEPOS is the byte position corresponding to
2324 CHARPOS. BYTEPOS < 0 means compute it from CHARPOS.
2325
2326 If ROW is not null, calls to produce_glyphs with IT as parameter
2327 will produce glyphs in that row.
2328
2329 BASE_FACE_ID is the id of a base face to use. It must be one of
2330 DEFAULT_FACE_ID for normal text, MODE_LINE_FACE_ID,
2331 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID for displaying
2332 mode lines, or TOOL_BAR_FACE_ID for displaying the tool-bar.
2333
2334 If ROW is null and BASE_FACE_ID is equal to MODE_LINE_FACE_ID,
2335 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID, the iterator
2336 will be initialized to use the corresponding mode line glyph row of
2337 the desired matrix of W. */
2338
2339 void
2340 init_iterator (struct it *it, struct window *w,
2341 EMACS_INT charpos, EMACS_INT bytepos,
2342 struct glyph_row *row, enum face_id base_face_id)
2343 {
2344 int highlight_region_p;
2345 enum face_id remapped_base_face_id = base_face_id;
2346
2347 /* Some precondition checks. */
2348 xassert (w != NULL && it != NULL);
2349 xassert (charpos < 0 || (charpos >= BUF_BEG (current_buffer)
2350 && charpos <= ZV));
2351
2352 /* If face attributes have been changed since the last redisplay,
2353 free realized faces now because they depend on face definitions
2354 that might have changed. Don't free faces while there might be
2355 desired matrices pending which reference these faces. */
2356 if (face_change_count && !inhibit_free_realized_faces)
2357 {
2358 face_change_count = 0;
2359 free_all_realized_faces (Qnil);
2360 }
2361
2362 /* Perhaps remap BASE_FACE_ID to a user-specified alternative. */
2363 if (! NILP (Vface_remapping_alist))
2364 remapped_base_face_id = lookup_basic_face (XFRAME (w->frame), base_face_id);
2365
2366 /* Use one of the mode line rows of W's desired matrix if
2367 appropriate. */
2368 if (row == NULL)
2369 {
2370 if (base_face_id == MODE_LINE_FACE_ID
2371 || base_face_id == MODE_LINE_INACTIVE_FACE_ID)
2372 row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
2373 else if (base_face_id == HEADER_LINE_FACE_ID)
2374 row = MATRIX_HEADER_LINE_ROW (w->desired_matrix);
2375 }
2376
2377 /* Clear IT. */
2378 memset (it, 0, sizeof *it);
2379 it->current.overlay_string_index = -1;
2380 it->current.dpvec_index = -1;
2381 it->base_face_id = remapped_base_face_id;
2382 it->string = Qnil;
2383 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
2384
2385 /* The window in which we iterate over current_buffer: */
2386 XSETWINDOW (it->window, w);
2387 it->w = w;
2388 it->f = XFRAME (w->frame);
2389
2390 it->cmp_it.id = -1;
2391
2392 /* Extra space between lines (on window systems only). */
2393 if (base_face_id == DEFAULT_FACE_ID
2394 && FRAME_WINDOW_P (it->f))
2395 {
2396 if (NATNUMP (BVAR (current_buffer, extra_line_spacing)))
2397 it->extra_line_spacing = XFASTINT (BVAR (current_buffer, extra_line_spacing));
2398 else if (FLOATP (BVAR (current_buffer, extra_line_spacing)))
2399 it->extra_line_spacing = (XFLOAT_DATA (BVAR (current_buffer, extra_line_spacing))
2400 * FRAME_LINE_HEIGHT (it->f));
2401 else if (it->f->extra_line_spacing > 0)
2402 it->extra_line_spacing = it->f->extra_line_spacing;
2403 it->max_extra_line_spacing = 0;
2404 }
2405
2406 /* If realized faces have been removed, e.g. because of face
2407 attribute changes of named faces, recompute them. When running
2408 in batch mode, the face cache of the initial frame is null. If
2409 we happen to get called, make a dummy face cache. */
2410 if (FRAME_FACE_CACHE (it->f) == NULL)
2411 init_frame_faces (it->f);
2412 if (FRAME_FACE_CACHE (it->f)->used == 0)
2413 recompute_basic_faces (it->f);
2414
2415 /* Current value of the `slice', `space-width', and 'height' properties. */
2416 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
2417 it->space_width = Qnil;
2418 it->font_height = Qnil;
2419 it->override_ascent = -1;
2420
2421 /* Are control characters displayed as `^C'? */
2422 it->ctl_arrow_p = !NILP (BVAR (current_buffer, ctl_arrow));
2423
2424 /* -1 means everything between a CR and the following line end
2425 is invisible. >0 means lines indented more than this value are
2426 invisible. */
2427 it->selective = (INTEGERP (BVAR (current_buffer, selective_display))
2428 ? XFASTINT (BVAR (current_buffer, selective_display))
2429 : (!NILP (BVAR (current_buffer, selective_display))
2430 ? -1 : 0));
2431 it->selective_display_ellipsis_p
2432 = !NILP (BVAR (current_buffer, selective_display_ellipses));
2433
2434 /* Display table to use. */
2435 it->dp = window_display_table (w);
2436
2437 /* Are multibyte characters enabled in current_buffer? */
2438 it->multibyte_p = !NILP (BVAR (current_buffer, enable_multibyte_characters));
2439
2440 /* Do we need to reorder bidirectional text? Not if this is a
2441 unibyte buffer: by definition, none of the single-byte characters
2442 are strong R2L, so no reordering is needed. And bidi.c doesn't
2443 support unibyte buffers anyway. */
2444 it->bidi_p
2445 = !NILP (BVAR (current_buffer, bidi_display_reordering)) && it->multibyte_p;
2446
2447 /* Non-zero if we should highlight the region. */
2448 highlight_region_p
2449 = (!NILP (Vtransient_mark_mode)
2450 && !NILP (BVAR (current_buffer, mark_active))
2451 && XMARKER (BVAR (current_buffer, mark))->buffer != 0);
2452
2453 /* Set IT->region_beg_charpos and IT->region_end_charpos to the
2454 start and end of a visible region in window IT->w. Set both to
2455 -1 to indicate no region. */
2456 if (highlight_region_p
2457 /* Maybe highlight only in selected window. */
2458 && (/* Either show region everywhere. */
2459 highlight_nonselected_windows
2460 /* Or show region in the selected window. */
2461 || w == XWINDOW (selected_window)
2462 /* Or show the region if we are in the mini-buffer and W is
2463 the window the mini-buffer refers to. */
2464 || (MINI_WINDOW_P (XWINDOW (selected_window))
2465 && WINDOWP (minibuf_selected_window)
2466 && w == XWINDOW (minibuf_selected_window))))
2467 {
2468 EMACS_INT markpos = marker_position (BVAR (current_buffer, mark));
2469 it->region_beg_charpos = min (PT, markpos);
2470 it->region_end_charpos = max (PT, markpos);
2471 }
2472 else
2473 it->region_beg_charpos = it->region_end_charpos = -1;
2474
2475 /* Get the position at which the redisplay_end_trigger hook should
2476 be run, if it is to be run at all. */
2477 if (MARKERP (w->redisplay_end_trigger)
2478 && XMARKER (w->redisplay_end_trigger)->buffer != 0)
2479 it->redisplay_end_trigger_charpos
2480 = marker_position (w->redisplay_end_trigger);
2481 else if (INTEGERP (w->redisplay_end_trigger))
2482 it->redisplay_end_trigger_charpos = XINT (w->redisplay_end_trigger);
2483
2484 /* Correct bogus values of tab_width. */
2485 it->tab_width = XINT (BVAR (current_buffer, tab_width));
2486 if (it->tab_width <= 0 || it->tab_width > 1000)
2487 it->tab_width = 8;
2488
2489 /* Are lines in the display truncated? */
2490 if (base_face_id != DEFAULT_FACE_ID
2491 || XINT (it->w->hscroll)
2492 || (! WINDOW_FULL_WIDTH_P (it->w)
2493 && ((!NILP (Vtruncate_partial_width_windows)
2494 && !INTEGERP (Vtruncate_partial_width_windows))
2495 || (INTEGERP (Vtruncate_partial_width_windows)
2496 && (WINDOW_TOTAL_COLS (it->w)
2497 < XINT (Vtruncate_partial_width_windows))))))
2498 it->line_wrap = TRUNCATE;
2499 else if (NILP (BVAR (current_buffer, truncate_lines)))
2500 it->line_wrap = NILP (BVAR (current_buffer, word_wrap))
2501 ? WINDOW_WRAP : WORD_WRAP;
2502 else
2503 it->line_wrap = TRUNCATE;
2504
2505 /* Get dimensions of truncation and continuation glyphs. These are
2506 displayed as fringe bitmaps under X, so we don't need them for such
2507 frames. */
2508 if (!FRAME_WINDOW_P (it->f))
2509 {
2510 if (it->line_wrap == TRUNCATE)
2511 {
2512 /* We will need the truncation glyph. */
2513 xassert (it->glyph_row == NULL);
2514 produce_special_glyphs (it, IT_TRUNCATION);
2515 it->truncation_pixel_width = it->pixel_width;
2516 }
2517 else
2518 {
2519 /* We will need the continuation glyph. */
2520 xassert (it->glyph_row == NULL);
2521 produce_special_glyphs (it, IT_CONTINUATION);
2522 it->continuation_pixel_width = it->pixel_width;
2523 }
2524
2525 /* Reset these values to zero because the produce_special_glyphs
2526 above has changed them. */
2527 it->pixel_width = it->ascent = it->descent = 0;
2528 it->phys_ascent = it->phys_descent = 0;
2529 }
2530
2531 /* Set this after getting the dimensions of truncation and
2532 continuation glyphs, so that we don't produce glyphs when calling
2533 produce_special_glyphs, above. */
2534 it->glyph_row = row;
2535 it->area = TEXT_AREA;
2536
2537 /* Forget any previous info about this row being reversed. */
2538 if (it->glyph_row)
2539 it->glyph_row->reversed_p = 0;
2540
2541 /* Get the dimensions of the display area. The display area
2542 consists of the visible window area plus a horizontally scrolled
2543 part to the left of the window. All x-values are relative to the
2544 start of this total display area. */
2545 if (base_face_id != DEFAULT_FACE_ID)
2546 {
2547 /* Mode lines, menu bar in terminal frames. */
2548 it->first_visible_x = 0;
2549 it->last_visible_x = WINDOW_TOTAL_WIDTH (w);
2550 }
2551 else
2552 {
2553 it->first_visible_x
2554 = XFASTINT (it->w->hscroll) * FRAME_COLUMN_WIDTH (it->f);
2555 it->last_visible_x = (it->first_visible_x
2556 + window_box_width (w, TEXT_AREA));
2557
2558 /* If we truncate lines, leave room for the truncator glyph(s) at
2559 the right margin. Otherwise, leave room for the continuation
2560 glyph(s). Truncation and continuation glyphs are not inserted
2561 for window-based redisplay. */
2562 if (!FRAME_WINDOW_P (it->f))
2563 {
2564 if (it->line_wrap == TRUNCATE)
2565 it->last_visible_x -= it->truncation_pixel_width;
2566 else
2567 it->last_visible_x -= it->continuation_pixel_width;
2568 }
2569
2570 it->header_line_p = WINDOW_WANTS_HEADER_LINE_P (w);
2571 it->current_y = WINDOW_HEADER_LINE_HEIGHT (w) + w->vscroll;
2572 }
2573
2574 /* Leave room for a border glyph. */
2575 if (!FRAME_WINDOW_P (it->f)
2576 && !WINDOW_RIGHTMOST_P (it->w))
2577 it->last_visible_x -= 1;
2578
2579 it->last_visible_y = window_text_bottom_y (w);
2580
2581 /* For mode lines and alike, arrange for the first glyph having a
2582 left box line if the face specifies a box. */
2583 if (base_face_id != DEFAULT_FACE_ID)
2584 {
2585 struct face *face;
2586
2587 it->face_id = remapped_base_face_id;
2588
2589 /* If we have a boxed mode line, make the first character appear
2590 with a left box line. */
2591 face = FACE_FROM_ID (it->f, remapped_base_face_id);
2592 if (face->box != FACE_NO_BOX)
2593 it->start_of_box_run_p = 1;
2594 }
2595
2596 /* If we are to reorder bidirectional text, init the bidi
2597 iterator. */
2598 if (it->bidi_p)
2599 {
2600 /* Note the paragraph direction that this buffer wants to
2601 use. */
2602 if (EQ (BVAR (current_buffer, bidi_paragraph_direction), Qleft_to_right))
2603 it->paragraph_embedding = L2R;
2604 else if (EQ (BVAR (current_buffer, bidi_paragraph_direction), Qright_to_left))
2605 it->paragraph_embedding = R2L;
2606 else
2607 it->paragraph_embedding = NEUTRAL_DIR;
2608 bidi_init_it (charpos, bytepos, &it->bidi_it);
2609 }
2610
2611 /* If a buffer position was specified, set the iterator there,
2612 getting overlays and face properties from that position. */
2613 if (charpos >= BUF_BEG (current_buffer))
2614 {
2615 it->end_charpos = ZV;
2616 it->face_id = -1;
2617 IT_CHARPOS (*it) = charpos;
2618
2619 /* Compute byte position if not specified. */
2620 if (bytepos < charpos)
2621 IT_BYTEPOS (*it) = CHAR_TO_BYTE (charpos);
2622 else
2623 IT_BYTEPOS (*it) = bytepos;
2624
2625 it->start = it->current;
2626
2627 /* Compute faces etc. */
2628 reseat (it, it->current.pos, 1);
2629 }
2630
2631 CHECK_IT (it);
2632 }
2633
2634
2635 /* Initialize IT for the display of window W with window start POS. */
2636
2637 void
2638 start_display (struct it *it, struct window *w, struct text_pos pos)
2639 {
2640 struct glyph_row *row;
2641 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
2642
2643 row = w->desired_matrix->rows + first_vpos;
2644 init_iterator (it, w, CHARPOS (pos), BYTEPOS (pos), row, DEFAULT_FACE_ID);
2645 it->first_vpos = first_vpos;
2646
2647 /* Don't reseat to previous visible line start if current start
2648 position is in a string or image. */
2649 if (it->method == GET_FROM_BUFFER && it->line_wrap != TRUNCATE)
2650 {
2651 int start_at_line_beg_p;
2652 int first_y = it->current_y;
2653
2654 /* If window start is not at a line start, skip forward to POS to
2655 get the correct continuation lines width. */
2656 start_at_line_beg_p = (CHARPOS (pos) == BEGV
2657 || FETCH_BYTE (BYTEPOS (pos) - 1) == '\n');
2658 if (!start_at_line_beg_p)
2659 {
2660 int new_x;
2661
2662 reseat_at_previous_visible_line_start (it);
2663 move_it_to (it, CHARPOS (pos), -1, -1, -1, MOVE_TO_POS);
2664
2665 new_x = it->current_x + it->pixel_width;
2666
2667 /* If lines are continued, this line may end in the middle
2668 of a multi-glyph character (e.g. a control character
2669 displayed as \003, or in the middle of an overlay
2670 string). In this case move_it_to above will not have
2671 taken us to the start of the continuation line but to the
2672 end of the continued line. */
2673 if (it->current_x > 0
2674 && it->line_wrap != TRUNCATE /* Lines are continued. */
2675 && (/* And glyph doesn't fit on the line. */
2676 new_x > it->last_visible_x
2677 /* Or it fits exactly and we're on a window
2678 system frame. */
2679 || (new_x == it->last_visible_x
2680 && FRAME_WINDOW_P (it->f))))
2681 {
2682 if (it->current.dpvec_index >= 0
2683 || it->current.overlay_string_index >= 0)
2684 {
2685 set_iterator_to_next (it, 1);
2686 move_it_in_display_line_to (it, -1, -1, 0);
2687 }
2688
2689 it->continuation_lines_width += it->current_x;
2690 }
2691
2692 /* We're starting a new display line, not affected by the
2693 height of the continued line, so clear the appropriate
2694 fields in the iterator structure. */
2695 it->max_ascent = it->max_descent = 0;
2696 it->max_phys_ascent = it->max_phys_descent = 0;
2697
2698 it->current_y = first_y;
2699 it->vpos = 0;
2700 it->current_x = it->hpos = 0;
2701 }
2702 }
2703 }
2704
2705
2706 /* Return 1 if POS is a position in ellipses displayed for invisible
2707 text. W is the window we display, for text property lookup. */
2708
2709 static int
2710 in_ellipses_for_invisible_text_p (struct display_pos *pos, struct window *w)
2711 {
2712 Lisp_Object prop, window;
2713 int ellipses_p = 0;
2714 EMACS_INT charpos = CHARPOS (pos->pos);
2715
2716 /* If POS specifies a position in a display vector, this might
2717 be for an ellipsis displayed for invisible text. We won't
2718 get the iterator set up for delivering that ellipsis unless
2719 we make sure that it gets aware of the invisible text. */
2720 if (pos->dpvec_index >= 0
2721 && pos->overlay_string_index < 0
2722 && CHARPOS (pos->string_pos) < 0
2723 && charpos > BEGV
2724 && (XSETWINDOW (window, w),
2725 prop = Fget_char_property (make_number (charpos),
2726 Qinvisible, window),
2727 !TEXT_PROP_MEANS_INVISIBLE (prop)))
2728 {
2729 prop = Fget_char_property (make_number (charpos - 1), Qinvisible,
2730 window);
2731 ellipses_p = 2 == TEXT_PROP_MEANS_INVISIBLE (prop);
2732 }
2733
2734 return ellipses_p;
2735 }
2736
2737
2738 /* Initialize IT for stepping through current_buffer in window W,
2739 starting at position POS that includes overlay string and display
2740 vector/ control character translation position information. Value
2741 is zero if there are overlay strings with newlines at POS. */
2742
2743 static int
2744 init_from_display_pos (struct it *it, struct window *w, struct display_pos *pos)
2745 {
2746 EMACS_INT charpos = CHARPOS (pos->pos), bytepos = BYTEPOS (pos->pos);
2747 int i, overlay_strings_with_newlines = 0;
2748
2749 /* If POS specifies a position in a display vector, this might
2750 be for an ellipsis displayed for invisible text. We won't
2751 get the iterator set up for delivering that ellipsis unless
2752 we make sure that it gets aware of the invisible text. */
2753 if (in_ellipses_for_invisible_text_p (pos, w))
2754 {
2755 --charpos;
2756 bytepos = 0;
2757 }
2758
2759 /* Keep in mind: the call to reseat in init_iterator skips invisible
2760 text, so we might end up at a position different from POS. This
2761 is only a problem when POS is a row start after a newline and an
2762 overlay starts there with an after-string, and the overlay has an
2763 invisible property. Since we don't skip invisible text in
2764 display_line and elsewhere immediately after consuming the
2765 newline before the row start, such a POS will not be in a string,
2766 but the call to init_iterator below will move us to the
2767 after-string. */
2768 init_iterator (it, w, charpos, bytepos, NULL, DEFAULT_FACE_ID);
2769
2770 /* This only scans the current chunk -- it should scan all chunks.
2771 However, OVERLAY_STRING_CHUNK_SIZE has been increased from 3 in 21.1
2772 to 16 in 22.1 to make this a lesser problem. */
2773 for (i = 0; i < it->n_overlay_strings && i < OVERLAY_STRING_CHUNK_SIZE; ++i)
2774 {
2775 const char *s = SSDATA (it->overlay_strings[i]);
2776 const char *e = s + SBYTES (it->overlay_strings[i]);
2777
2778 while (s < e && *s != '\n')
2779 ++s;
2780
2781 if (s < e)
2782 {
2783 overlay_strings_with_newlines = 1;
2784 break;
2785 }
2786 }
2787
2788 /* If position is within an overlay string, set up IT to the right
2789 overlay string. */
2790 if (pos->overlay_string_index >= 0)
2791 {
2792 int relative_index;
2793
2794 /* If the first overlay string happens to have a `display'
2795 property for an image, the iterator will be set up for that
2796 image, and we have to undo that setup first before we can
2797 correct the overlay string index. */
2798 if (it->method == GET_FROM_IMAGE)
2799 pop_it (it);
2800
2801 /* We already have the first chunk of overlay strings in
2802 IT->overlay_strings. Load more until the one for
2803 pos->overlay_string_index is in IT->overlay_strings. */
2804 if (pos->overlay_string_index >= OVERLAY_STRING_CHUNK_SIZE)
2805 {
2806 int n = pos->overlay_string_index / OVERLAY_STRING_CHUNK_SIZE;
2807 it->current.overlay_string_index = 0;
2808 while (n--)
2809 {
2810 load_overlay_strings (it, 0);
2811 it->current.overlay_string_index += OVERLAY_STRING_CHUNK_SIZE;
2812 }
2813 }
2814
2815 it->current.overlay_string_index = pos->overlay_string_index;
2816 relative_index = (it->current.overlay_string_index
2817 % OVERLAY_STRING_CHUNK_SIZE);
2818 it->string = it->overlay_strings[relative_index];
2819 xassert (STRINGP (it->string));
2820 it->current.string_pos = pos->string_pos;
2821 it->method = GET_FROM_STRING;
2822 }
2823
2824 if (CHARPOS (pos->string_pos) >= 0)
2825 {
2826 /* Recorded position is not in an overlay string, but in another
2827 string. This can only be a string from a `display' property.
2828 IT should already be filled with that string. */
2829 it->current.string_pos = pos->string_pos;
2830 xassert (STRINGP (it->string));
2831 }
2832
2833 /* Restore position in display vector translations, control
2834 character translations or ellipses. */
2835 if (pos->dpvec_index >= 0)
2836 {
2837 if (it->dpvec == NULL)
2838 get_next_display_element (it);
2839 xassert (it->dpvec && it->current.dpvec_index == 0);
2840 it->current.dpvec_index = pos->dpvec_index;
2841 }
2842
2843 CHECK_IT (it);
2844 return !overlay_strings_with_newlines;
2845 }
2846
2847
2848 /* Initialize IT for stepping through current_buffer in window W
2849 starting at ROW->start. */
2850
2851 static void
2852 init_to_row_start (struct it *it, struct window *w, struct glyph_row *row)
2853 {
2854 init_from_display_pos (it, w, &row->start);
2855 it->start = row->start;
2856 it->continuation_lines_width = row->continuation_lines_width;
2857 CHECK_IT (it);
2858 }
2859
2860
2861 /* Initialize IT for stepping through current_buffer in window W
2862 starting in the line following ROW, i.e. starting at ROW->end.
2863 Value is zero if there are overlay strings with newlines at ROW's
2864 end position. */
2865
2866 static int
2867 init_to_row_end (struct it *it, struct window *w, struct glyph_row *row)
2868 {
2869 int success = 0;
2870
2871 if (init_from_display_pos (it, w, &row->end))
2872 {
2873 if (row->continued_p)
2874 it->continuation_lines_width
2875 = row->continuation_lines_width + row->pixel_width;
2876 CHECK_IT (it);
2877 success = 1;
2878 }
2879
2880 return success;
2881 }
2882
2883
2884
2885 \f
2886 /***********************************************************************
2887 Text properties
2888 ***********************************************************************/
2889
2890 /* Called when IT reaches IT->stop_charpos. Handle text property and
2891 overlay changes. Set IT->stop_charpos to the next position where
2892 to stop. */
2893
2894 static void
2895 handle_stop (struct it *it)
2896 {
2897 enum prop_handled handled;
2898 int handle_overlay_change_p;
2899 struct props *p;
2900
2901 it->dpvec = NULL;
2902 it->current.dpvec_index = -1;
2903 handle_overlay_change_p = !it->ignore_overlay_strings_at_pos_p;
2904 it->ignore_overlay_strings_at_pos_p = 0;
2905 it->ellipsis_p = 0;
2906
2907 /* Use face of preceding text for ellipsis (if invisible) */
2908 if (it->selective_display_ellipsis_p)
2909 it->saved_face_id = it->face_id;
2910
2911 do
2912 {
2913 handled = HANDLED_NORMALLY;
2914
2915 /* Call text property handlers. */
2916 for (p = it_props; p->handler; ++p)
2917 {
2918 handled = p->handler (it);
2919
2920 if (handled == HANDLED_RECOMPUTE_PROPS)
2921 break;
2922 else if (handled == HANDLED_RETURN)
2923 {
2924 /* We still want to show before and after strings from
2925 overlays even if the actual buffer text is replaced. */
2926 if (!handle_overlay_change_p
2927 || it->sp > 1
2928 || !get_overlay_strings_1 (it, 0, 0))
2929 {
2930 if (it->ellipsis_p)
2931 setup_for_ellipsis (it, 0);
2932 /* When handling a display spec, we might load an
2933 empty string. In that case, discard it here. We
2934 used to discard it in handle_single_display_spec,
2935 but that causes get_overlay_strings_1, above, to
2936 ignore overlay strings that we must check. */
2937 if (STRINGP (it->string) && !SCHARS (it->string))
2938 pop_it (it);
2939 return;
2940 }
2941 else if (STRINGP (it->string) && !SCHARS (it->string))
2942 pop_it (it);
2943 else
2944 {
2945 it->ignore_overlay_strings_at_pos_p = 1;
2946 it->string_from_display_prop_p = 0;
2947 handle_overlay_change_p = 0;
2948 }
2949 handled = HANDLED_RECOMPUTE_PROPS;
2950 break;
2951 }
2952 else if (handled == HANDLED_OVERLAY_STRING_CONSUMED)
2953 handle_overlay_change_p = 0;
2954 }
2955
2956 if (handled != HANDLED_RECOMPUTE_PROPS)
2957 {
2958 /* Don't check for overlay strings below when set to deliver
2959 characters from a display vector. */
2960 if (it->method == GET_FROM_DISPLAY_VECTOR)
2961 handle_overlay_change_p = 0;
2962
2963 /* Handle overlay changes.
2964 This sets HANDLED to HANDLED_RECOMPUTE_PROPS
2965 if it finds overlays. */
2966 if (handle_overlay_change_p)
2967 handled = handle_overlay_change (it);
2968 }
2969
2970 if (it->ellipsis_p)
2971 {
2972 setup_for_ellipsis (it, 0);
2973 break;
2974 }
2975 }
2976 while (handled == HANDLED_RECOMPUTE_PROPS);
2977
2978 /* Determine where to stop next. */
2979 if (handled == HANDLED_NORMALLY)
2980 compute_stop_pos (it);
2981 }
2982
2983
2984 /* Compute IT->stop_charpos from text property and overlay change
2985 information for IT's current position. */
2986
2987 static void
2988 compute_stop_pos (struct it *it)
2989 {
2990 register INTERVAL iv, next_iv;
2991 Lisp_Object object, limit, position;
2992 EMACS_INT charpos, bytepos;
2993
2994 /* If nowhere else, stop at the end. */
2995 it->stop_charpos = it->end_charpos;
2996
2997 if (STRINGP (it->string))
2998 {
2999 /* Strings are usually short, so don't limit the search for
3000 properties. */
3001 object = it->string;
3002 limit = Qnil;
3003 charpos = IT_STRING_CHARPOS (*it);
3004 bytepos = IT_STRING_BYTEPOS (*it);
3005 }
3006 else
3007 {
3008 EMACS_INT pos;
3009
3010 /* If next overlay change is in front of the current stop pos
3011 (which is IT->end_charpos), stop there. Note: value of
3012 next_overlay_change is point-max if no overlay change
3013 follows. */
3014 charpos = IT_CHARPOS (*it);
3015 bytepos = IT_BYTEPOS (*it);
3016 pos = next_overlay_change (charpos);
3017 if (pos < it->stop_charpos)
3018 it->stop_charpos = pos;
3019
3020 /* If showing the region, we have to stop at the region
3021 start or end because the face might change there. */
3022 if (it->region_beg_charpos > 0)
3023 {
3024 if (IT_CHARPOS (*it) < it->region_beg_charpos)
3025 it->stop_charpos = min (it->stop_charpos, it->region_beg_charpos);
3026 else if (IT_CHARPOS (*it) < it->region_end_charpos)
3027 it->stop_charpos = min (it->stop_charpos, it->region_end_charpos);
3028 }
3029
3030 /* Set up variables for computing the stop position from text
3031 property changes. */
3032 XSETBUFFER (object, current_buffer);
3033 limit = make_number (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT);
3034 }
3035
3036 /* Get the interval containing IT's position. Value is a null
3037 interval if there isn't such an interval. */
3038 position = make_number (charpos);
3039 iv = validate_interval_range (object, &position, &position, 0);
3040 if (!NULL_INTERVAL_P (iv))
3041 {
3042 Lisp_Object values_here[LAST_PROP_IDX];
3043 struct props *p;
3044
3045 /* Get properties here. */
3046 for (p = it_props; p->handler; ++p)
3047 values_here[p->idx] = textget (iv->plist, *p->name);
3048
3049 /* Look for an interval following iv that has different
3050 properties. */
3051 for (next_iv = next_interval (iv);
3052 (!NULL_INTERVAL_P (next_iv)
3053 && (NILP (limit)
3054 || XFASTINT (limit) > next_iv->position));
3055 next_iv = next_interval (next_iv))
3056 {
3057 for (p = it_props; p->handler; ++p)
3058 {
3059 Lisp_Object new_value;
3060
3061 new_value = textget (next_iv->plist, *p->name);
3062 if (!EQ (values_here[p->idx], new_value))
3063 break;
3064 }
3065
3066 if (p->handler)
3067 break;
3068 }
3069
3070 if (!NULL_INTERVAL_P (next_iv))
3071 {
3072 if (INTEGERP (limit)
3073 && next_iv->position >= XFASTINT (limit))
3074 /* No text property change up to limit. */
3075 it->stop_charpos = min (XFASTINT (limit), it->stop_charpos);
3076 else
3077 /* Text properties change in next_iv. */
3078 it->stop_charpos = min (it->stop_charpos, next_iv->position);
3079 }
3080 }
3081
3082 if (it->cmp_it.id < 0)
3083 {
3084 EMACS_INT stoppos = it->end_charpos;
3085
3086 if (it->bidi_p && it->bidi_it.scan_dir < 0)
3087 stoppos = -1;
3088 composition_compute_stop_pos (&it->cmp_it, charpos, bytepos,
3089 stoppos, it->string);
3090 }
3091
3092 xassert (STRINGP (it->string)
3093 || (it->stop_charpos >= BEGV
3094 && it->stop_charpos >= IT_CHARPOS (*it)));
3095 }
3096
3097
3098 /* Return the position of the next overlay change after POS in
3099 current_buffer. Value is point-max if no overlay change
3100 follows. This is like `next-overlay-change' but doesn't use
3101 xmalloc. */
3102
3103 static EMACS_INT
3104 next_overlay_change (EMACS_INT pos)
3105 {
3106 int noverlays;
3107 EMACS_INT endpos;
3108 Lisp_Object *overlays;
3109 int i;
3110
3111 /* Get all overlays at the given position. */
3112 GET_OVERLAYS_AT (pos, overlays, noverlays, &endpos, 1);
3113
3114 /* If any of these overlays ends before endpos,
3115 use its ending point instead. */
3116 for (i = 0; i < noverlays; ++i)
3117 {
3118 Lisp_Object oend;
3119 EMACS_INT oendpos;
3120
3121 oend = OVERLAY_END (overlays[i]);
3122 oendpos = OVERLAY_POSITION (oend);
3123 endpos = min (endpos, oendpos);
3124 }
3125
3126 return endpos;
3127 }
3128
3129
3130 \f
3131 /***********************************************************************
3132 Fontification
3133 ***********************************************************************/
3134
3135 /* Handle changes in the `fontified' property of the current buffer by
3136 calling hook functions from Qfontification_functions to fontify
3137 regions of text. */
3138
3139 static enum prop_handled
3140 handle_fontified_prop (struct it *it)
3141 {
3142 Lisp_Object prop, pos;
3143 enum prop_handled handled = HANDLED_NORMALLY;
3144
3145 if (!NILP (Vmemory_full))
3146 return handled;
3147
3148 /* Get the value of the `fontified' property at IT's current buffer
3149 position. (The `fontified' property doesn't have a special
3150 meaning in strings.) If the value is nil, call functions from
3151 Qfontification_functions. */
3152 if (!STRINGP (it->string)
3153 && it->s == NULL
3154 && !NILP (Vfontification_functions)
3155 && !NILP (Vrun_hooks)
3156 && (pos = make_number (IT_CHARPOS (*it)),
3157 prop = Fget_char_property (pos, Qfontified, Qnil),
3158 /* Ignore the special cased nil value always present at EOB since
3159 no amount of fontifying will be able to change it. */
3160 NILP (prop) && IT_CHARPOS (*it) < Z))
3161 {
3162 int count = SPECPDL_INDEX ();
3163 Lisp_Object val;
3164 struct buffer *obuf = current_buffer;
3165 int begv = BEGV, zv = ZV;
3166 int old_clip_changed = current_buffer->clip_changed;
3167
3168 val = Vfontification_functions;
3169 specbind (Qfontification_functions, Qnil);
3170
3171 xassert (it->end_charpos == ZV);
3172
3173 if (!CONSP (val) || EQ (XCAR (val), Qlambda))
3174 safe_call1 (val, pos);
3175 else
3176 {
3177 Lisp_Object fns, fn;
3178 struct gcpro gcpro1, gcpro2;
3179
3180 fns = Qnil;
3181 GCPRO2 (val, fns);
3182
3183 for (; CONSP (val); val = XCDR (val))
3184 {
3185 fn = XCAR (val);
3186
3187 if (EQ (fn, Qt))
3188 {
3189 /* A value of t indicates this hook has a local
3190 binding; it means to run the global binding too.
3191 In a global value, t should not occur. If it
3192 does, we must ignore it to avoid an endless
3193 loop. */
3194 for (fns = Fdefault_value (Qfontification_functions);
3195 CONSP (fns);
3196 fns = XCDR (fns))
3197 {
3198 fn = XCAR (fns);
3199 if (!EQ (fn, Qt))
3200 safe_call1 (fn, pos);
3201 }
3202 }
3203 else
3204 safe_call1 (fn, pos);
3205 }
3206
3207 UNGCPRO;
3208 }
3209
3210 unbind_to (count, Qnil);
3211
3212 /* Fontification functions routinely call `save-restriction'.
3213 Normally, this tags clip_changed, which can confuse redisplay
3214 (see discussion in Bug#6671). Since we don't perform any
3215 special handling of fontification changes in the case where
3216 `save-restriction' isn't called, there's no point doing so in
3217 this case either. So, if the buffer's restrictions are
3218 actually left unchanged, reset clip_changed. */
3219 if (obuf == current_buffer)
3220 {
3221 if (begv == BEGV && zv == ZV)
3222 current_buffer->clip_changed = old_clip_changed;
3223 }
3224 /* There isn't much we can reasonably do to protect against
3225 misbehaving fontification, but here's a fig leaf. */
3226 else if (!NILP (BVAR (obuf, name)))
3227 set_buffer_internal_1 (obuf);
3228
3229 /* The fontification code may have added/removed text.
3230 It could do even a lot worse, but let's at least protect against
3231 the most obvious case where only the text past `pos' gets changed',
3232 as is/was done in grep.el where some escapes sequences are turned
3233 into face properties (bug#7876). */
3234 it->end_charpos = ZV;
3235
3236 /* Return HANDLED_RECOMPUTE_PROPS only if function fontified
3237 something. This avoids an endless loop if they failed to
3238 fontify the text for which reason ever. */
3239 if (!NILP (Fget_char_property (pos, Qfontified, Qnil)))
3240 handled = HANDLED_RECOMPUTE_PROPS;
3241 }
3242
3243 return handled;
3244 }
3245
3246
3247 \f
3248 /***********************************************************************
3249 Faces
3250 ***********************************************************************/
3251
3252 /* Set up iterator IT from face properties at its current position.
3253 Called from handle_stop. */
3254
3255 static enum prop_handled
3256 handle_face_prop (struct it *it)
3257 {
3258 int new_face_id;
3259 EMACS_INT next_stop;
3260
3261 if (!STRINGP (it->string))
3262 {
3263 new_face_id
3264 = face_at_buffer_position (it->w,
3265 IT_CHARPOS (*it),
3266 it->region_beg_charpos,
3267 it->region_end_charpos,
3268 &next_stop,
3269 (IT_CHARPOS (*it)
3270 + TEXT_PROP_DISTANCE_LIMIT),
3271 0, it->base_face_id);
3272
3273 /* Is this a start of a run of characters with box face?
3274 Caveat: this can be called for a freshly initialized
3275 iterator; face_id is -1 in this case. We know that the new
3276 face will not change until limit, i.e. if the new face has a
3277 box, all characters up to limit will have one. But, as
3278 usual, we don't know whether limit is really the end. */
3279 if (new_face_id != it->face_id)
3280 {
3281 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
3282
3283 /* If new face has a box but old face has not, this is
3284 the start of a run of characters with box, i.e. it has
3285 a shadow on the left side. The value of face_id of the
3286 iterator will be -1 if this is the initial call that gets
3287 the face. In this case, we have to look in front of IT's
3288 position and see whether there is a face != new_face_id. */
3289 it->start_of_box_run_p
3290 = (new_face->box != FACE_NO_BOX
3291 && (it->face_id >= 0
3292 || IT_CHARPOS (*it) == BEG
3293 || new_face_id != face_before_it_pos (it)));
3294 it->face_box_p = new_face->box != FACE_NO_BOX;
3295 }
3296 }
3297 else
3298 {
3299 int base_face_id;
3300 EMACS_INT bufpos;
3301 int i;
3302 Lisp_Object from_overlay
3303 = (it->current.overlay_string_index >= 0
3304 ? it->string_overlays[it->current.overlay_string_index]
3305 : Qnil);
3306
3307 /* See if we got to this string directly or indirectly from
3308 an overlay property. That includes the before-string or
3309 after-string of an overlay, strings in display properties
3310 provided by an overlay, their text properties, etc.
3311
3312 FROM_OVERLAY is the overlay that brought us here, or nil if none. */
3313 if (! NILP (from_overlay))
3314 for (i = it->sp - 1; i >= 0; i--)
3315 {
3316 if (it->stack[i].current.overlay_string_index >= 0)
3317 from_overlay
3318 = it->string_overlays[it->stack[i].current.overlay_string_index];
3319 else if (! NILP (it->stack[i].from_overlay))
3320 from_overlay = it->stack[i].from_overlay;
3321
3322 if (!NILP (from_overlay))
3323 break;
3324 }
3325
3326 if (! NILP (from_overlay))
3327 {
3328 bufpos = IT_CHARPOS (*it);
3329 /* For a string from an overlay, the base face depends
3330 only on text properties and ignores overlays. */
3331 base_face_id
3332 = face_for_overlay_string (it->w,
3333 IT_CHARPOS (*it),
3334 it->region_beg_charpos,
3335 it->region_end_charpos,
3336 &next_stop,
3337 (IT_CHARPOS (*it)
3338 + TEXT_PROP_DISTANCE_LIMIT),
3339 0,
3340 from_overlay);
3341 }
3342 else
3343 {
3344 bufpos = 0;
3345
3346 /* For strings from a `display' property, use the face at
3347 IT's current buffer position as the base face to merge
3348 with, so that overlay strings appear in the same face as
3349 surrounding text, unless they specify their own
3350 faces. */
3351 base_face_id = underlying_face_id (it);
3352 }
3353
3354 new_face_id = face_at_string_position (it->w,
3355 it->string,
3356 IT_STRING_CHARPOS (*it),
3357 bufpos,
3358 it->region_beg_charpos,
3359 it->region_end_charpos,
3360 &next_stop,
3361 base_face_id, 0);
3362
3363 /* Is this a start of a run of characters with box? Caveat:
3364 this can be called for a freshly allocated iterator; face_id
3365 is -1 is this case. We know that the new face will not
3366 change until the next check pos, i.e. if the new face has a
3367 box, all characters up to that position will have a
3368 box. But, as usual, we don't know whether that position
3369 is really the end. */
3370 if (new_face_id != it->face_id)
3371 {
3372 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
3373 struct face *old_face = FACE_FROM_ID (it->f, it->face_id);
3374
3375 /* If new face has a box but old face hasn't, this is the
3376 start of a run of characters with box, i.e. it has a
3377 shadow on the left side. */
3378 it->start_of_box_run_p
3379 = new_face->box && (old_face == NULL || !old_face->box);
3380 it->face_box_p = new_face->box != FACE_NO_BOX;
3381 }
3382 }
3383
3384 it->face_id = new_face_id;
3385 return HANDLED_NORMALLY;
3386 }
3387
3388
3389 /* Return the ID of the face ``underlying'' IT's current position,
3390 which is in a string. If the iterator is associated with a
3391 buffer, return the face at IT's current buffer position.
3392 Otherwise, use the iterator's base_face_id. */
3393
3394 static int
3395 underlying_face_id (struct it *it)
3396 {
3397 int face_id = it->base_face_id, i;
3398
3399 xassert (STRINGP (it->string));
3400
3401 for (i = it->sp - 1; i >= 0; --i)
3402 if (NILP (it->stack[i].string))
3403 face_id = it->stack[i].face_id;
3404
3405 return face_id;
3406 }
3407
3408
3409 /* Compute the face one character before or after the current position
3410 of IT. BEFORE_P non-zero means get the face in front of IT's
3411 position. Value is the id of the face. */
3412
3413 static int
3414 face_before_or_after_it_pos (struct it *it, int before_p)
3415 {
3416 int face_id, limit;
3417 EMACS_INT next_check_charpos;
3418 struct text_pos pos;
3419
3420 xassert (it->s == NULL);
3421
3422 if (STRINGP (it->string))
3423 {
3424 EMACS_INT bufpos;
3425 int base_face_id;
3426
3427 /* No face change past the end of the string (for the case
3428 we are padding with spaces). No face change before the
3429 string start. */
3430 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string)
3431 || (IT_STRING_CHARPOS (*it) == 0 && before_p))
3432 return it->face_id;
3433
3434 /* Set pos to the position before or after IT's current position. */
3435 if (before_p)
3436 pos = string_pos (IT_STRING_CHARPOS (*it) - 1, it->string);
3437 else
3438 /* For composition, we must check the character after the
3439 composition. */
3440 pos = (it->what == IT_COMPOSITION
3441 ? string_pos (IT_STRING_CHARPOS (*it)
3442 + it->cmp_it.nchars, it->string)
3443 : string_pos (IT_STRING_CHARPOS (*it) + 1, it->string));
3444
3445 if (it->current.overlay_string_index >= 0)
3446 bufpos = IT_CHARPOS (*it);
3447 else
3448 bufpos = 0;
3449
3450 base_face_id = underlying_face_id (it);
3451
3452 /* Get the face for ASCII, or unibyte. */
3453 face_id = face_at_string_position (it->w,
3454 it->string,
3455 CHARPOS (pos),
3456 bufpos,
3457 it->region_beg_charpos,
3458 it->region_end_charpos,
3459 &next_check_charpos,
3460 base_face_id, 0);
3461
3462 /* Correct the face for charsets different from ASCII. Do it
3463 for the multibyte case only. The face returned above is
3464 suitable for unibyte text if IT->string is unibyte. */
3465 if (STRING_MULTIBYTE (it->string))
3466 {
3467 const unsigned char *p = SDATA (it->string) + BYTEPOS (pos);
3468 int c, len;
3469 struct face *face = FACE_FROM_ID (it->f, face_id);
3470
3471 c = string_char_and_length (p, &len);
3472 face_id = FACE_FOR_CHAR (it->f, face, c, CHARPOS (pos), it->string);
3473 }
3474 }
3475 else
3476 {
3477 if ((IT_CHARPOS (*it) >= ZV && !before_p)
3478 || (IT_CHARPOS (*it) <= BEGV && before_p))
3479 return it->face_id;
3480
3481 limit = IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT;
3482 pos = it->current.pos;
3483
3484 if (before_p)
3485 DEC_TEXT_POS (pos, it->multibyte_p);
3486 else
3487 {
3488 if (it->what == IT_COMPOSITION)
3489 /* For composition, we must check the position after the
3490 composition. */
3491 pos.charpos += it->cmp_it.nchars, pos.bytepos += it->len;
3492 else
3493 INC_TEXT_POS (pos, it->multibyte_p);
3494 }
3495
3496 /* Determine face for CHARSET_ASCII, or unibyte. */
3497 face_id = face_at_buffer_position (it->w,
3498 CHARPOS (pos),
3499 it->region_beg_charpos,
3500 it->region_end_charpos,
3501 &next_check_charpos,
3502 limit, 0, -1);
3503
3504 /* Correct the face for charsets different from ASCII. Do it
3505 for the multibyte case only. The face returned above is
3506 suitable for unibyte text if current_buffer is unibyte. */
3507 if (it->multibyte_p)
3508 {
3509 int c = FETCH_MULTIBYTE_CHAR (BYTEPOS (pos));
3510 struct face *face = FACE_FROM_ID (it->f, face_id);
3511 face_id = FACE_FOR_CHAR (it->f, face, c, CHARPOS (pos), Qnil);
3512 }
3513 }
3514
3515 return face_id;
3516 }
3517
3518
3519 \f
3520 /***********************************************************************
3521 Invisible text
3522 ***********************************************************************/
3523
3524 /* Set up iterator IT from invisible properties at its current
3525 position. Called from handle_stop. */
3526
3527 static enum prop_handled
3528 handle_invisible_prop (struct it *it)
3529 {
3530 enum prop_handled handled = HANDLED_NORMALLY;
3531
3532 if (STRINGP (it->string))
3533 {
3534 Lisp_Object prop, end_charpos, limit, charpos;
3535
3536 /* Get the value of the invisible text property at the
3537 current position. Value will be nil if there is no such
3538 property. */
3539 charpos = make_number (IT_STRING_CHARPOS (*it));
3540 prop = Fget_text_property (charpos, Qinvisible, it->string);
3541
3542 if (!NILP (prop)
3543 && IT_STRING_CHARPOS (*it) < it->end_charpos)
3544 {
3545 handled = HANDLED_RECOMPUTE_PROPS;
3546
3547 /* Get the position at which the next change of the
3548 invisible text property can be found in IT->string.
3549 Value will be nil if the property value is the same for
3550 all the rest of IT->string. */
3551 XSETINT (limit, SCHARS (it->string));
3552 end_charpos = Fnext_single_property_change (charpos, Qinvisible,
3553 it->string, limit);
3554
3555 /* Text at current position is invisible. The next
3556 change in the property is at position end_charpos.
3557 Move IT's current position to that position. */
3558 if (INTEGERP (end_charpos)
3559 && XFASTINT (end_charpos) < XFASTINT (limit))
3560 {
3561 struct text_pos old;
3562 old = it->current.string_pos;
3563 IT_STRING_CHARPOS (*it) = XFASTINT (end_charpos);
3564 compute_string_pos (&it->current.string_pos, old, it->string);
3565 }
3566 else
3567 {
3568 /* The rest of the string is invisible. If this is an
3569 overlay string, proceed with the next overlay string
3570 or whatever comes and return a character from there. */
3571 if (it->current.overlay_string_index >= 0)
3572 {
3573 next_overlay_string (it);
3574 /* Don't check for overlay strings when we just
3575 finished processing them. */
3576 handled = HANDLED_OVERLAY_STRING_CONSUMED;
3577 }
3578 else
3579 {
3580 IT_STRING_CHARPOS (*it) = SCHARS (it->string);
3581 IT_STRING_BYTEPOS (*it) = SBYTES (it->string);
3582 }
3583 }
3584 }
3585 }
3586 else
3587 {
3588 int invis_p;
3589 EMACS_INT newpos, next_stop, start_charpos, tem;
3590 Lisp_Object pos, prop, overlay;
3591
3592 /* First of all, is there invisible text at this position? */
3593 tem = start_charpos = IT_CHARPOS (*it);
3594 pos = make_number (tem);
3595 prop = get_char_property_and_overlay (pos, Qinvisible, it->window,
3596 &overlay);
3597 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
3598
3599 /* If we are on invisible text, skip over it. */
3600 if (invis_p && start_charpos < it->end_charpos)
3601 {
3602 /* Record whether we have to display an ellipsis for the
3603 invisible text. */
3604 int display_ellipsis_p = invis_p == 2;
3605
3606 handled = HANDLED_RECOMPUTE_PROPS;
3607
3608 /* Loop skipping over invisible text. The loop is left at
3609 ZV or with IT on the first char being visible again. */
3610 do
3611 {
3612 /* Try to skip some invisible text. Return value is the
3613 position reached which can be equal to where we start
3614 if there is nothing invisible there. This skips both
3615 over invisible text properties and overlays with
3616 invisible property. */
3617 newpos = skip_invisible (tem, &next_stop, ZV, it->window);
3618
3619 /* If we skipped nothing at all we weren't at invisible
3620 text in the first place. If everything to the end of
3621 the buffer was skipped, end the loop. */
3622 if (newpos == tem || newpos >= ZV)
3623 invis_p = 0;
3624 else
3625 {
3626 /* We skipped some characters but not necessarily
3627 all there are. Check if we ended up on visible
3628 text. Fget_char_property returns the property of
3629 the char before the given position, i.e. if we
3630 get invis_p = 0, this means that the char at
3631 newpos is visible. */
3632 pos = make_number (newpos);
3633 prop = Fget_char_property (pos, Qinvisible, it->window);
3634 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
3635 }
3636
3637 /* If we ended up on invisible text, proceed to
3638 skip starting with next_stop. */
3639 if (invis_p)
3640 tem = next_stop;
3641
3642 /* If there are adjacent invisible texts, don't lose the
3643 second one's ellipsis. */
3644 if (invis_p == 2)
3645 display_ellipsis_p = 1;
3646 }
3647 while (invis_p);
3648
3649 /* The position newpos is now either ZV or on visible text. */
3650 if (it->bidi_p && newpos < ZV)
3651 {
3652 /* With bidi iteration, the region of invisible text
3653 could start and/or end in the middle of a non-base
3654 embedding level. Therefore, we need to skip
3655 invisible text using the bidi iterator, starting at
3656 IT's current position, until we find ourselves
3657 outside the invisible text. Skipping invisible text
3658 _after_ bidi iteration avoids affecting the visual
3659 order of the displayed text when invisible properties
3660 are added or removed. */
3661 if (it->bidi_it.first_elt)
3662 {
3663 /* If we were `reseat'ed to a new paragraph,
3664 determine the paragraph base direction. We need
3665 to do it now because next_element_from_buffer may
3666 not have a chance to do it, if we are going to
3667 skip any text at the beginning, which resets the
3668 FIRST_ELT flag. */
3669 bidi_paragraph_init (it->paragraph_embedding,
3670 &it->bidi_it, 1);
3671 }
3672 do
3673 {
3674 bidi_move_to_visually_next (&it->bidi_it);
3675 }
3676 while (it->stop_charpos <= it->bidi_it.charpos
3677 && it->bidi_it.charpos < newpos);
3678 IT_CHARPOS (*it) = it->bidi_it.charpos;
3679 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
3680 /* If we overstepped NEWPOS, record its position in the
3681 iterator, so that we skip invisible text if later the
3682 bidi iteration lands us in the invisible region
3683 again. */
3684 if (IT_CHARPOS (*it) >= newpos)
3685 it->prev_stop = newpos;
3686 }
3687 else
3688 {
3689 IT_CHARPOS (*it) = newpos;
3690 IT_BYTEPOS (*it) = CHAR_TO_BYTE (newpos);
3691 }
3692
3693 /* If there are before-strings at the start of invisible
3694 text, and the text is invisible because of a text
3695 property, arrange to show before-strings because 20.x did
3696 it that way. (If the text is invisible because of an
3697 overlay property instead of a text property, this is
3698 already handled in the overlay code.) */
3699 if (NILP (overlay)
3700 && get_overlay_strings (it, it->stop_charpos))
3701 {
3702 handled = HANDLED_RECOMPUTE_PROPS;
3703 it->stack[it->sp - 1].display_ellipsis_p = display_ellipsis_p;
3704 }
3705 else if (display_ellipsis_p)
3706 {
3707 /* Make sure that the glyphs of the ellipsis will get
3708 correct `charpos' values. If we would not update
3709 it->position here, the glyphs would belong to the
3710 last visible character _before_ the invisible
3711 text, which confuses `set_cursor_from_row'.
3712
3713 We use the last invisible position instead of the
3714 first because this way the cursor is always drawn on
3715 the first "." of the ellipsis, whenever PT is inside
3716 the invisible text. Otherwise the cursor would be
3717 placed _after_ the ellipsis when the point is after the
3718 first invisible character. */
3719 if (!STRINGP (it->object))
3720 {
3721 it->position.charpos = newpos - 1;
3722 it->position.bytepos = CHAR_TO_BYTE (it->position.charpos);
3723 }
3724 it->ellipsis_p = 1;
3725 /* Let the ellipsis display before
3726 considering any properties of the following char.
3727 Fixes jasonr@gnu.org 01 Oct 07 bug. */
3728 handled = HANDLED_RETURN;
3729 }
3730 }
3731 }
3732
3733 return handled;
3734 }
3735
3736
3737 /* Make iterator IT return `...' next.
3738 Replaces LEN characters from buffer. */
3739
3740 static void
3741 setup_for_ellipsis (struct it *it, int len)
3742 {
3743 /* Use the display table definition for `...'. Invalid glyphs
3744 will be handled by the method returning elements from dpvec. */
3745 if (it->dp && VECTORP (DISP_INVIS_VECTOR (it->dp)))
3746 {
3747 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
3748 it->dpvec = v->contents;
3749 it->dpend = v->contents + v->size;
3750 }
3751 else
3752 {
3753 /* Default `...'. */
3754 it->dpvec = default_invis_vector;
3755 it->dpend = default_invis_vector + 3;
3756 }
3757
3758 it->dpvec_char_len = len;
3759 it->current.dpvec_index = 0;
3760 it->dpvec_face_id = -1;
3761
3762 /* Remember the current face id in case glyphs specify faces.
3763 IT's face is restored in set_iterator_to_next.
3764 saved_face_id was set to preceding char's face in handle_stop. */
3765 if (it->saved_face_id < 0 || it->saved_face_id != it->face_id)
3766 it->saved_face_id = it->face_id = DEFAULT_FACE_ID;
3767
3768 it->method = GET_FROM_DISPLAY_VECTOR;
3769 it->ellipsis_p = 1;
3770 }
3771
3772
3773 \f
3774 /***********************************************************************
3775 'display' property
3776 ***********************************************************************/
3777
3778 /* Set up iterator IT from `display' property at its current position.
3779 Called from handle_stop.
3780 We return HANDLED_RETURN if some part of the display property
3781 overrides the display of the buffer text itself.
3782 Otherwise we return HANDLED_NORMALLY. */
3783
3784 static enum prop_handled
3785 handle_display_prop (struct it *it)
3786 {
3787 Lisp_Object prop, object, overlay;
3788 struct text_pos *position;
3789 /* Nonzero if some property replaces the display of the text itself. */
3790 int display_replaced_p = 0;
3791
3792 if (STRINGP (it->string))
3793 {
3794 object = it->string;
3795 position = &it->current.string_pos;
3796 }
3797 else
3798 {
3799 XSETWINDOW (object, it->w);
3800 position = &it->current.pos;
3801 }
3802
3803 /* Reset those iterator values set from display property values. */
3804 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
3805 it->space_width = Qnil;
3806 it->font_height = Qnil;
3807 it->voffset = 0;
3808
3809 /* We don't support recursive `display' properties, i.e. string
3810 values that have a string `display' property, that have a string
3811 `display' property etc. */
3812 if (!it->string_from_display_prop_p)
3813 it->area = TEXT_AREA;
3814
3815 prop = get_char_property_and_overlay (make_number (position->charpos),
3816 Qdisplay, object, &overlay);
3817 if (NILP (prop))
3818 return HANDLED_NORMALLY;
3819 /* Now OVERLAY is the overlay that gave us this property, or nil
3820 if it was a text property. */
3821
3822 if (!STRINGP (it->string))
3823 object = it->w->buffer;
3824
3825 if (CONSP (prop)
3826 /* Simple properties. */
3827 && !EQ (XCAR (prop), Qimage)
3828 && !EQ (XCAR (prop), Qspace)
3829 && !EQ (XCAR (prop), Qwhen)
3830 && !EQ (XCAR (prop), Qslice)
3831 && !EQ (XCAR (prop), Qspace_width)
3832 && !EQ (XCAR (prop), Qheight)
3833 && !EQ (XCAR (prop), Qraise)
3834 /* Marginal area specifications. */
3835 && !(CONSP (XCAR (prop)) && EQ (XCAR (XCAR (prop)), Qmargin))
3836 && !EQ (XCAR (prop), Qleft_fringe)
3837 && !EQ (XCAR (prop), Qright_fringe)
3838 && !NILP (XCAR (prop)))
3839 {
3840 for (; CONSP (prop); prop = XCDR (prop))
3841 {
3842 if (handle_single_display_spec (it, XCAR (prop), object, overlay,
3843 position, display_replaced_p))
3844 {
3845 display_replaced_p = 1;
3846 /* If some text in a string is replaced, `position' no
3847 longer points to the position of `object'. */
3848 if (STRINGP (object))
3849 break;
3850 }
3851 }
3852 }
3853 else if (VECTORP (prop))
3854 {
3855 int i;
3856 for (i = 0; i < ASIZE (prop); ++i)
3857 if (handle_single_display_spec (it, AREF (prop, i), object, overlay,
3858 position, display_replaced_p))
3859 {
3860 display_replaced_p = 1;
3861 /* If some text in a string is replaced, `position' no
3862 longer points to the position of `object'. */
3863 if (STRINGP (object))
3864 break;
3865 }
3866 }
3867 else
3868 {
3869 if (handle_single_display_spec (it, prop, object, overlay,
3870 position, 0))
3871 display_replaced_p = 1;
3872 }
3873
3874 return display_replaced_p ? HANDLED_RETURN : HANDLED_NORMALLY;
3875 }
3876
3877
3878 /* Value is the position of the end of the `display' property starting
3879 at START_POS in OBJECT. */
3880
3881 static struct text_pos
3882 display_prop_end (struct it *it, Lisp_Object object, struct text_pos start_pos)
3883 {
3884 Lisp_Object end;
3885 struct text_pos end_pos;
3886
3887 end = Fnext_single_char_property_change (make_number (CHARPOS (start_pos)),
3888 Qdisplay, object, Qnil);
3889 CHARPOS (end_pos) = XFASTINT (end);
3890 if (STRINGP (object))
3891 compute_string_pos (&end_pos, start_pos, it->string);
3892 else
3893 BYTEPOS (end_pos) = CHAR_TO_BYTE (XFASTINT (end));
3894
3895 return end_pos;
3896 }
3897
3898
3899 /* Set up IT from a single `display' specification PROP. OBJECT
3900 is the object in which the `display' property was found. *POSITION
3901 is the position at which it was found. DISPLAY_REPLACED_P non-zero
3902 means that we previously saw a display specification which already
3903 replaced text display with something else, for example an image;
3904 we ignore such properties after the first one has been processed.
3905
3906 OVERLAY is the overlay this `display' property came from,
3907 or nil if it was a text property.
3908
3909 If PROP is a `space' or `image' specification, and in some other
3910 cases too, set *POSITION to the position where the `display'
3911 property ends.
3912
3913 Value is non-zero if something was found which replaces the display
3914 of buffer or string text. */
3915
3916 static int
3917 handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
3918 Lisp_Object overlay, struct text_pos *position,
3919 int display_replaced_before_p)
3920 {
3921 Lisp_Object form;
3922 Lisp_Object location, value;
3923 struct text_pos start_pos, save_pos;
3924 int valid_p;
3925
3926 /* If SPEC is a list of the form `(when FORM . VALUE)', evaluate FORM.
3927 If the result is non-nil, use VALUE instead of SPEC. */
3928 form = Qt;
3929 if (CONSP (spec) && EQ (XCAR (spec), Qwhen))
3930 {
3931 spec = XCDR (spec);
3932 if (!CONSP (spec))
3933 return 0;
3934 form = XCAR (spec);
3935 spec = XCDR (spec);
3936 }
3937
3938 if (!NILP (form) && !EQ (form, Qt))
3939 {
3940 int count = SPECPDL_INDEX ();
3941 struct gcpro gcpro1;
3942
3943 /* Bind `object' to the object having the `display' property, a
3944 buffer or string. Bind `position' to the position in the
3945 object where the property was found, and `buffer-position'
3946 to the current position in the buffer. */
3947 specbind (Qobject, object);
3948 specbind (Qposition, make_number (CHARPOS (*position)));
3949 specbind (Qbuffer_position,
3950 make_number (STRINGP (object)
3951 ? IT_CHARPOS (*it) : CHARPOS (*position)));
3952 GCPRO1 (form);
3953 form = safe_eval (form);
3954 UNGCPRO;
3955 unbind_to (count, Qnil);
3956 }
3957
3958 if (NILP (form))
3959 return 0;
3960
3961 /* Handle `(height HEIGHT)' specifications. */
3962 if (CONSP (spec)
3963 && EQ (XCAR (spec), Qheight)
3964 && CONSP (XCDR (spec)))
3965 {
3966 if (!FRAME_WINDOW_P (it->f))
3967 return 0;
3968
3969 it->font_height = XCAR (XCDR (spec));
3970 if (!NILP (it->font_height))
3971 {
3972 struct face *face = FACE_FROM_ID (it->f, it->face_id);
3973 int new_height = -1;
3974
3975 if (CONSP (it->font_height)
3976 && (EQ (XCAR (it->font_height), Qplus)
3977 || EQ (XCAR (it->font_height), Qminus))
3978 && CONSP (XCDR (it->font_height))
3979 && INTEGERP (XCAR (XCDR (it->font_height))))
3980 {
3981 /* `(+ N)' or `(- N)' where N is an integer. */
3982 int steps = XINT (XCAR (XCDR (it->font_height)));
3983 if (EQ (XCAR (it->font_height), Qplus))
3984 steps = - steps;
3985 it->face_id = smaller_face (it->f, it->face_id, steps);
3986 }
3987 else if (FUNCTIONP (it->font_height))
3988 {
3989 /* Call function with current height as argument.
3990 Value is the new height. */
3991 Lisp_Object height;
3992 height = safe_call1 (it->font_height,
3993 face->lface[LFACE_HEIGHT_INDEX]);
3994 if (NUMBERP (height))
3995 new_height = XFLOATINT (height);
3996 }
3997 else if (NUMBERP (it->font_height))
3998 {
3999 /* Value is a multiple of the canonical char height. */
4000 struct face *f;
4001
4002 f = FACE_FROM_ID (it->f,
4003 lookup_basic_face (it->f, DEFAULT_FACE_ID));
4004 new_height = (XFLOATINT (it->font_height)
4005 * XINT (f->lface[LFACE_HEIGHT_INDEX]));
4006 }
4007 else
4008 {
4009 /* Evaluate IT->font_height with `height' bound to the
4010 current specified height to get the new height. */
4011 int count = SPECPDL_INDEX ();
4012
4013 specbind (Qheight, face->lface[LFACE_HEIGHT_INDEX]);
4014 value = safe_eval (it->font_height);
4015 unbind_to (count, Qnil);
4016
4017 if (NUMBERP (value))
4018 new_height = XFLOATINT (value);
4019 }
4020
4021 if (new_height > 0)
4022 it->face_id = face_with_height (it->f, it->face_id, new_height);
4023 }
4024
4025 return 0;
4026 }
4027
4028 /* Handle `(space-width WIDTH)'. */
4029 if (CONSP (spec)
4030 && EQ (XCAR (spec), Qspace_width)
4031 && CONSP (XCDR (spec)))
4032 {
4033 if (!FRAME_WINDOW_P (it->f))
4034 return 0;
4035
4036 value = XCAR (XCDR (spec));
4037 if (NUMBERP (value) && XFLOATINT (value) > 0)
4038 it->space_width = value;
4039
4040 return 0;
4041 }
4042
4043 /* Handle `(slice X Y WIDTH HEIGHT)'. */
4044 if (CONSP (spec)
4045 && EQ (XCAR (spec), Qslice))
4046 {
4047 Lisp_Object tem;
4048
4049 if (!FRAME_WINDOW_P (it->f))
4050 return 0;
4051
4052 if (tem = XCDR (spec), CONSP (tem))
4053 {
4054 it->slice.x = XCAR (tem);
4055 if (tem = XCDR (tem), CONSP (tem))
4056 {
4057 it->slice.y = XCAR (tem);
4058 if (tem = XCDR (tem), CONSP (tem))
4059 {
4060 it->slice.width = XCAR (tem);
4061 if (tem = XCDR (tem), CONSP (tem))
4062 it->slice.height = XCAR (tem);
4063 }
4064 }
4065 }
4066
4067 return 0;
4068 }
4069
4070 /* Handle `(raise FACTOR)'. */
4071 if (CONSP (spec)
4072 && EQ (XCAR (spec), Qraise)
4073 && CONSP (XCDR (spec)))
4074 {
4075 if (!FRAME_WINDOW_P (it->f))
4076 return 0;
4077
4078 #ifdef HAVE_WINDOW_SYSTEM
4079 value = XCAR (XCDR (spec));
4080 if (NUMBERP (value))
4081 {
4082 struct face *face = FACE_FROM_ID (it->f, it->face_id);
4083 it->voffset = - (XFLOATINT (value)
4084 * (FONT_HEIGHT (face->font)));
4085 }
4086 #endif /* HAVE_WINDOW_SYSTEM */
4087
4088 return 0;
4089 }
4090
4091 /* Don't handle the other kinds of display specifications
4092 inside a string that we got from a `display' property. */
4093 if (it->string_from_display_prop_p)
4094 return 0;
4095
4096 /* Characters having this form of property are not displayed, so
4097 we have to find the end of the property. */
4098 start_pos = *position;
4099 *position = display_prop_end (it, object, start_pos);
4100 value = Qnil;
4101
4102 /* Stop the scan at that end position--we assume that all
4103 text properties change there. */
4104 it->stop_charpos = position->charpos;
4105
4106 /* Handle `(left-fringe BITMAP [FACE])'
4107 and `(right-fringe BITMAP [FACE])'. */
4108 if (CONSP (spec)
4109 && (EQ (XCAR (spec), Qleft_fringe)
4110 || EQ (XCAR (spec), Qright_fringe))
4111 && CONSP (XCDR (spec)))
4112 {
4113 int face_id = lookup_basic_face (it->f, DEFAULT_FACE_ID);
4114 int fringe_bitmap;
4115
4116 if (!FRAME_WINDOW_P (it->f))
4117 /* If we return here, POSITION has been advanced
4118 across the text with this property. */
4119 return 0;
4120
4121 #ifdef HAVE_WINDOW_SYSTEM
4122 value = XCAR (XCDR (spec));
4123 if (!SYMBOLP (value)
4124 || !(fringe_bitmap = lookup_fringe_bitmap (value)))
4125 /* If we return here, POSITION has been advanced
4126 across the text with this property. */
4127 return 0;
4128
4129 if (CONSP (XCDR (XCDR (spec))))
4130 {
4131 Lisp_Object face_name = XCAR (XCDR (XCDR (spec)));
4132 int face_id2 = lookup_derived_face (it->f, face_name,
4133 FRINGE_FACE_ID, 0);
4134 if (face_id2 >= 0)
4135 face_id = face_id2;
4136 }
4137
4138 /* Save current settings of IT so that we can restore them
4139 when we are finished with the glyph property value. */
4140
4141 save_pos = it->position;
4142 it->position = *position;
4143 push_it (it);
4144 it->position = save_pos;
4145
4146 it->area = TEXT_AREA;
4147 it->what = IT_IMAGE;
4148 it->image_id = -1; /* no image */
4149 it->position = start_pos;
4150 it->object = NILP (object) ? it->w->buffer : object;
4151 it->method = GET_FROM_IMAGE;
4152 it->from_overlay = Qnil;
4153 it->face_id = face_id;
4154
4155 /* Say that we haven't consumed the characters with
4156 `display' property yet. The call to pop_it in
4157 set_iterator_to_next will clean this up. */
4158 *position = start_pos;
4159
4160 if (EQ (XCAR (spec), Qleft_fringe))
4161 {
4162 it->left_user_fringe_bitmap = fringe_bitmap;
4163 it->left_user_fringe_face_id = face_id;
4164 }
4165 else
4166 {
4167 it->right_user_fringe_bitmap = fringe_bitmap;
4168 it->right_user_fringe_face_id = face_id;
4169 }
4170 #endif /* HAVE_WINDOW_SYSTEM */
4171 return 1;
4172 }
4173
4174 /* Prepare to handle `((margin left-margin) ...)',
4175 `((margin right-margin) ...)' and `((margin nil) ...)'
4176 prefixes for display specifications. */
4177 location = Qunbound;
4178 if (CONSP (spec) && CONSP (XCAR (spec)))
4179 {
4180 Lisp_Object tem;
4181
4182 value = XCDR (spec);
4183 if (CONSP (value))
4184 value = XCAR (value);
4185
4186 tem = XCAR (spec);
4187 if (EQ (XCAR (tem), Qmargin)
4188 && (tem = XCDR (tem),
4189 tem = CONSP (tem) ? XCAR (tem) : Qnil,
4190 (NILP (tem)
4191 || EQ (tem, Qleft_margin)
4192 || EQ (tem, Qright_margin))))
4193 location = tem;
4194 }
4195
4196 if (EQ (location, Qunbound))
4197 {
4198 location = Qnil;
4199 value = spec;
4200 }
4201
4202 /* After this point, VALUE is the property after any
4203 margin prefix has been stripped. It must be a string,
4204 an image specification, or `(space ...)'.
4205
4206 LOCATION specifies where to display: `left-margin',
4207 `right-margin' or nil. */
4208
4209 valid_p = (STRINGP (value)
4210 #ifdef HAVE_WINDOW_SYSTEM
4211 || (FRAME_WINDOW_P (it->f) && valid_image_p (value))
4212 #endif /* not HAVE_WINDOW_SYSTEM */
4213 || (CONSP (value) && EQ (XCAR (value), Qspace)));
4214
4215 if (valid_p && !display_replaced_before_p)
4216 {
4217 /* Save current settings of IT so that we can restore them
4218 when we are finished with the glyph property value. */
4219 save_pos = it->position;
4220 it->position = *position;
4221 push_it (it);
4222 it->position = save_pos;
4223 it->from_overlay = overlay;
4224
4225 if (NILP (location))
4226 it->area = TEXT_AREA;
4227 else if (EQ (location, Qleft_margin))
4228 it->area = LEFT_MARGIN_AREA;
4229 else
4230 it->area = RIGHT_MARGIN_AREA;
4231
4232 if (STRINGP (value))
4233 {
4234 it->string = value;
4235 it->multibyte_p = STRING_MULTIBYTE (it->string);
4236 it->current.overlay_string_index = -1;
4237 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
4238 it->end_charpos = it->string_nchars = SCHARS (it->string);
4239 it->method = GET_FROM_STRING;
4240 it->stop_charpos = 0;
4241 it->string_from_display_prop_p = 1;
4242 /* Say that we haven't consumed the characters with
4243 `display' property yet. The call to pop_it in
4244 set_iterator_to_next will clean this up. */
4245 if (BUFFERP (object))
4246 *position = start_pos;
4247 }
4248 else if (CONSP (value) && EQ (XCAR (value), Qspace))
4249 {
4250 it->method = GET_FROM_STRETCH;
4251 it->object = value;
4252 *position = it->position = start_pos;
4253 }
4254 #ifdef HAVE_WINDOW_SYSTEM
4255 else
4256 {
4257 it->what = IT_IMAGE;
4258 it->image_id = lookup_image (it->f, value);
4259 it->position = start_pos;
4260 it->object = NILP (object) ? it->w->buffer : object;
4261 it->method = GET_FROM_IMAGE;
4262
4263 /* Say that we haven't consumed the characters with
4264 `display' property yet. The call to pop_it in
4265 set_iterator_to_next will clean this up. */
4266 *position = start_pos;
4267 }
4268 #endif /* HAVE_WINDOW_SYSTEM */
4269
4270 return 1;
4271 }
4272
4273 /* Invalid property or property not supported. Restore
4274 POSITION to what it was before. */
4275 *position = start_pos;
4276 return 0;
4277 }
4278
4279
4280 /* Check if SPEC is a display sub-property value whose text should be
4281 treated as intangible. */
4282
4283 static int
4284 single_display_spec_intangible_p (Lisp_Object prop)
4285 {
4286 /* Skip over `when FORM'. */
4287 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
4288 {
4289 prop = XCDR (prop);
4290 if (!CONSP (prop))
4291 return 0;
4292 prop = XCDR (prop);
4293 }
4294
4295 if (STRINGP (prop))
4296 return 1;
4297
4298 if (!CONSP (prop))
4299 return 0;
4300
4301 /* Skip over `margin LOCATION'. If LOCATION is in the margins,
4302 we don't need to treat text as intangible. */
4303 if (EQ (XCAR (prop), Qmargin))
4304 {
4305 prop = XCDR (prop);
4306 if (!CONSP (prop))
4307 return 0;
4308
4309 prop = XCDR (prop);
4310 if (!CONSP (prop)
4311 || EQ (XCAR (prop), Qleft_margin)
4312 || EQ (XCAR (prop), Qright_margin))
4313 return 0;
4314 }
4315
4316 return (CONSP (prop)
4317 && (EQ (XCAR (prop), Qimage)
4318 || EQ (XCAR (prop), Qspace)));
4319 }
4320
4321
4322 /* Check if PROP is a display property value whose text should be
4323 treated as intangible. */
4324
4325 int
4326 display_prop_intangible_p (Lisp_Object prop)
4327 {
4328 if (CONSP (prop)
4329 && CONSP (XCAR (prop))
4330 && !EQ (Qmargin, XCAR (XCAR (prop))))
4331 {
4332 /* A list of sub-properties. */
4333 while (CONSP (prop))
4334 {
4335 if (single_display_spec_intangible_p (XCAR (prop)))
4336 return 1;
4337 prop = XCDR (prop);
4338 }
4339 }
4340 else if (VECTORP (prop))
4341 {
4342 /* A vector of sub-properties. */
4343 int i;
4344 for (i = 0; i < ASIZE (prop); ++i)
4345 if (single_display_spec_intangible_p (AREF (prop, i)))
4346 return 1;
4347 }
4348 else
4349 return single_display_spec_intangible_p (prop);
4350
4351 return 0;
4352 }
4353
4354
4355 /* Return 1 if PROP is a display sub-property value containing STRING. */
4356
4357 static int
4358 single_display_spec_string_p (Lisp_Object prop, Lisp_Object string)
4359 {
4360 if (EQ (string, prop))
4361 return 1;
4362
4363 /* Skip over `when FORM'. */
4364 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
4365 {
4366 prop = XCDR (prop);
4367 if (!CONSP (prop))
4368 return 0;
4369 prop = XCDR (prop);
4370 }
4371
4372 if (CONSP (prop))
4373 /* Skip over `margin LOCATION'. */
4374 if (EQ (XCAR (prop), Qmargin))
4375 {
4376 prop = XCDR (prop);
4377 if (!CONSP (prop))
4378 return 0;
4379
4380 prop = XCDR (prop);
4381 if (!CONSP (prop))
4382 return 0;
4383 }
4384
4385 return CONSP (prop) && EQ (XCAR (prop), string);
4386 }
4387
4388
4389 /* Return 1 if STRING appears in the `display' property PROP. */
4390
4391 static int
4392 display_prop_string_p (Lisp_Object prop, Lisp_Object string)
4393 {
4394 if (CONSP (prop)
4395 && CONSP (XCAR (prop))
4396 && !EQ (Qmargin, XCAR (XCAR (prop))))
4397 {
4398 /* A list of sub-properties. */
4399 while (CONSP (prop))
4400 {
4401 if (single_display_spec_string_p (XCAR (prop), string))
4402 return 1;
4403 prop = XCDR (prop);
4404 }
4405 }
4406 else if (VECTORP (prop))
4407 {
4408 /* A vector of sub-properties. */
4409 int i;
4410 for (i = 0; i < ASIZE (prop); ++i)
4411 if (single_display_spec_string_p (AREF (prop, i), string))
4412 return 1;
4413 }
4414 else
4415 return single_display_spec_string_p (prop, string);
4416
4417 return 0;
4418 }
4419
4420 /* Look for STRING in overlays and text properties in the current
4421 buffer, between character positions FROM and TO (excluding TO).
4422 BACK_P non-zero means look back (in this case, TO is supposed to be
4423 less than FROM).
4424 Value is the first character position where STRING was found, or
4425 zero if it wasn't found before hitting TO.
4426
4427 This function may only use code that doesn't eval because it is
4428 called asynchronously from note_mouse_highlight. */
4429
4430 static EMACS_INT
4431 string_buffer_position_lim (Lisp_Object string,
4432 EMACS_INT from, EMACS_INT to, int back_p)
4433 {
4434 Lisp_Object limit, prop, pos;
4435 int found = 0;
4436
4437 pos = make_number (from);
4438
4439 if (!back_p) /* looking forward */
4440 {
4441 limit = make_number (min (to, ZV));
4442 while (!found && !EQ (pos, limit))
4443 {
4444 prop = Fget_char_property (pos, Qdisplay, Qnil);
4445 if (!NILP (prop) && display_prop_string_p (prop, string))
4446 found = 1;
4447 else
4448 pos = Fnext_single_char_property_change (pos, Qdisplay, Qnil,
4449 limit);
4450 }
4451 }
4452 else /* looking back */
4453 {
4454 limit = make_number (max (to, BEGV));
4455 while (!found && !EQ (pos, limit))
4456 {
4457 prop = Fget_char_property (pos, Qdisplay, Qnil);
4458 if (!NILP (prop) && display_prop_string_p (prop, string))
4459 found = 1;
4460 else
4461 pos = Fprevious_single_char_property_change (pos, Qdisplay, Qnil,
4462 limit);
4463 }
4464 }
4465
4466 return found ? XINT (pos) : 0;
4467 }
4468
4469 /* Determine which buffer position in current buffer STRING comes from.
4470 AROUND_CHARPOS is an approximate position where it could come from.
4471 Value is the buffer position or 0 if it couldn't be determined.
4472
4473 This function is necessary because we don't record buffer positions
4474 in glyphs generated from strings (to keep struct glyph small).
4475 This function may only use code that doesn't eval because it is
4476 called asynchronously from note_mouse_highlight. */
4477
4478 static EMACS_INT
4479 string_buffer_position (Lisp_Object string, EMACS_INT around_charpos)
4480 {
4481 const int MAX_DISTANCE = 1000;
4482 EMACS_INT found = string_buffer_position_lim (string, around_charpos,
4483 around_charpos + MAX_DISTANCE,
4484 0);
4485
4486 if (!found)
4487 found = string_buffer_position_lim (string, around_charpos,
4488 around_charpos - MAX_DISTANCE, 1);
4489 return found;
4490 }
4491
4492
4493 \f
4494 /***********************************************************************
4495 `composition' property
4496 ***********************************************************************/
4497
4498 /* Set up iterator IT from `composition' property at its current
4499 position. Called from handle_stop. */
4500
4501 static enum prop_handled
4502 handle_composition_prop (struct it *it)
4503 {
4504 Lisp_Object prop, string;
4505 EMACS_INT pos, pos_byte, start, end;
4506
4507 if (STRINGP (it->string))
4508 {
4509 unsigned char *s;
4510
4511 pos = IT_STRING_CHARPOS (*it);
4512 pos_byte = IT_STRING_BYTEPOS (*it);
4513 string = it->string;
4514 s = SDATA (string) + pos_byte;
4515 it->c = STRING_CHAR (s);
4516 }
4517 else
4518 {
4519 pos = IT_CHARPOS (*it);
4520 pos_byte = IT_BYTEPOS (*it);
4521 string = Qnil;
4522 it->c = FETCH_CHAR (pos_byte);
4523 }
4524
4525 /* If there's a valid composition and point is not inside of the
4526 composition (in the case that the composition is from the current
4527 buffer), draw a glyph composed from the composition components. */
4528 if (find_composition (pos, -1, &start, &end, &prop, string)
4529 && COMPOSITION_VALID_P (start, end, prop)
4530 && (STRINGP (it->string) || (PT <= start || PT >= end)))
4531 {
4532 if (start != pos)
4533 {
4534 if (STRINGP (it->string))
4535 pos_byte = string_char_to_byte (it->string, start);
4536 else
4537 pos_byte = CHAR_TO_BYTE (start);
4538 }
4539 it->cmp_it.id = get_composition_id (start, pos_byte, end - start,
4540 prop, string);
4541
4542 if (it->cmp_it.id >= 0)
4543 {
4544 it->cmp_it.ch = -1;
4545 it->cmp_it.nchars = COMPOSITION_LENGTH (prop);
4546 it->cmp_it.nglyphs = -1;
4547 }
4548 }
4549
4550 return HANDLED_NORMALLY;
4551 }
4552
4553
4554 \f
4555 /***********************************************************************
4556 Overlay strings
4557 ***********************************************************************/
4558
4559 /* The following structure is used to record overlay strings for
4560 later sorting in load_overlay_strings. */
4561
4562 struct overlay_entry
4563 {
4564 Lisp_Object overlay;
4565 Lisp_Object string;
4566 int priority;
4567 int after_string_p;
4568 };
4569
4570
4571 /* Set up iterator IT from overlay strings at its current position.
4572 Called from handle_stop. */
4573
4574 static enum prop_handled
4575 handle_overlay_change (struct it *it)
4576 {
4577 if (!STRINGP (it->string) && get_overlay_strings (it, 0))
4578 return HANDLED_RECOMPUTE_PROPS;
4579 else
4580 return HANDLED_NORMALLY;
4581 }
4582
4583
4584 /* Set up the next overlay string for delivery by IT, if there is an
4585 overlay string to deliver. Called by set_iterator_to_next when the
4586 end of the current overlay string is reached. If there are more
4587 overlay strings to display, IT->string and
4588 IT->current.overlay_string_index are set appropriately here.
4589 Otherwise IT->string is set to nil. */
4590
4591 static void
4592 next_overlay_string (struct it *it)
4593 {
4594 ++it->current.overlay_string_index;
4595 if (it->current.overlay_string_index == it->n_overlay_strings)
4596 {
4597 /* No more overlay strings. Restore IT's settings to what
4598 they were before overlay strings were processed, and
4599 continue to deliver from current_buffer. */
4600
4601 it->ellipsis_p = (it->stack[it->sp - 1].display_ellipsis_p != 0);
4602 pop_it (it);
4603 xassert (it->sp > 0
4604 || (NILP (it->string)
4605 && it->method == GET_FROM_BUFFER
4606 && it->stop_charpos >= BEGV
4607 && it->stop_charpos <= it->end_charpos));
4608 it->current.overlay_string_index = -1;
4609 it->n_overlay_strings = 0;
4610 it->overlay_strings_charpos = -1;
4611
4612 /* If we're at the end of the buffer, record that we have
4613 processed the overlay strings there already, so that
4614 next_element_from_buffer doesn't try it again. */
4615 if (NILP (it->string) && IT_CHARPOS (*it) >= it->end_charpos)
4616 it->overlay_strings_at_end_processed_p = 1;
4617 }
4618 else
4619 {
4620 /* There are more overlay strings to process. If
4621 IT->current.overlay_string_index has advanced to a position
4622 where we must load IT->overlay_strings with more strings, do
4623 it. We must load at the IT->overlay_strings_charpos where
4624 IT->n_overlay_strings was originally computed; when invisible
4625 text is present, this might not be IT_CHARPOS (Bug#7016). */
4626 int i = it->current.overlay_string_index % OVERLAY_STRING_CHUNK_SIZE;
4627
4628 if (it->current.overlay_string_index && i == 0)
4629 load_overlay_strings (it, it->overlay_strings_charpos);
4630
4631 /* Initialize IT to deliver display elements from the overlay
4632 string. */
4633 it->string = it->overlay_strings[i];
4634 it->multibyte_p = STRING_MULTIBYTE (it->string);
4635 SET_TEXT_POS (it->current.string_pos, 0, 0);
4636 it->method = GET_FROM_STRING;
4637 it->stop_charpos = 0;
4638 if (it->cmp_it.stop_pos >= 0)
4639 it->cmp_it.stop_pos = 0;
4640 }
4641
4642 CHECK_IT (it);
4643 }
4644
4645
4646 /* Compare two overlay_entry structures E1 and E2. Used as a
4647 comparison function for qsort in load_overlay_strings. Overlay
4648 strings for the same position are sorted so that
4649
4650 1. All after-strings come in front of before-strings, except
4651 when they come from the same overlay.
4652
4653 2. Within after-strings, strings are sorted so that overlay strings
4654 from overlays with higher priorities come first.
4655
4656 2. Within before-strings, strings are sorted so that overlay
4657 strings from overlays with higher priorities come last.
4658
4659 Value is analogous to strcmp. */
4660
4661
4662 static int
4663 compare_overlay_entries (const void *e1, const void *e2)
4664 {
4665 struct overlay_entry *entry1 = (struct overlay_entry *) e1;
4666 struct overlay_entry *entry2 = (struct overlay_entry *) e2;
4667 int result;
4668
4669 if (entry1->after_string_p != entry2->after_string_p)
4670 {
4671 /* Let after-strings appear in front of before-strings if
4672 they come from different overlays. */
4673 if (EQ (entry1->overlay, entry2->overlay))
4674 result = entry1->after_string_p ? 1 : -1;
4675 else
4676 result = entry1->after_string_p ? -1 : 1;
4677 }
4678 else if (entry1->after_string_p)
4679 /* After-strings sorted in order of decreasing priority. */
4680 result = entry2->priority - entry1->priority;
4681 else
4682 /* Before-strings sorted in order of increasing priority. */
4683 result = entry1->priority - entry2->priority;
4684
4685 return result;
4686 }
4687
4688
4689 /* Load the vector IT->overlay_strings with overlay strings from IT's
4690 current buffer position, or from CHARPOS if that is > 0. Set
4691 IT->n_overlays to the total number of overlay strings found.
4692
4693 Overlay strings are processed OVERLAY_STRING_CHUNK_SIZE strings at
4694 a time. On entry into load_overlay_strings,
4695 IT->current.overlay_string_index gives the number of overlay
4696 strings that have already been loaded by previous calls to this
4697 function.
4698
4699 IT->add_overlay_start contains an additional overlay start
4700 position to consider for taking overlay strings from, if non-zero.
4701 This position comes into play when the overlay has an `invisible'
4702 property, and both before and after-strings. When we've skipped to
4703 the end of the overlay, because of its `invisible' property, we
4704 nevertheless want its before-string to appear.
4705 IT->add_overlay_start will contain the overlay start position
4706 in this case.
4707
4708 Overlay strings are sorted so that after-string strings come in
4709 front of before-string strings. Within before and after-strings,
4710 strings are sorted by overlay priority. See also function
4711 compare_overlay_entries. */
4712
4713 static void
4714 load_overlay_strings (struct it *it, EMACS_INT charpos)
4715 {
4716 Lisp_Object overlay, window, str, invisible;
4717 struct Lisp_Overlay *ov;
4718 EMACS_INT start, end;
4719 int size = 20;
4720 int n = 0, i, j, invis_p;
4721 struct overlay_entry *entries
4722 = (struct overlay_entry *) alloca (size * sizeof *entries);
4723
4724 if (charpos <= 0)
4725 charpos = IT_CHARPOS (*it);
4726
4727 /* Append the overlay string STRING of overlay OVERLAY to vector
4728 `entries' which has size `size' and currently contains `n'
4729 elements. AFTER_P non-zero means STRING is an after-string of
4730 OVERLAY. */
4731 #define RECORD_OVERLAY_STRING(OVERLAY, STRING, AFTER_P) \
4732 do \
4733 { \
4734 Lisp_Object priority; \
4735 \
4736 if (n == size) \
4737 { \
4738 int new_size = 2 * size; \
4739 struct overlay_entry *old = entries; \
4740 entries = \
4741 (struct overlay_entry *) alloca (new_size \
4742 * sizeof *entries); \
4743 memcpy (entries, old, size * sizeof *entries); \
4744 size = new_size; \
4745 } \
4746 \
4747 entries[n].string = (STRING); \
4748 entries[n].overlay = (OVERLAY); \
4749 priority = Foverlay_get ((OVERLAY), Qpriority); \
4750 entries[n].priority = INTEGERP (priority) ? XINT (priority) : 0; \
4751 entries[n].after_string_p = (AFTER_P); \
4752 ++n; \
4753 } \
4754 while (0)
4755
4756 /* Process overlay before the overlay center. */
4757 for (ov = current_buffer->overlays_before; ov; ov = ov->next)
4758 {
4759 XSETMISC (overlay, ov);
4760 xassert (OVERLAYP (overlay));
4761 start = OVERLAY_POSITION (OVERLAY_START (overlay));
4762 end = OVERLAY_POSITION (OVERLAY_END (overlay));
4763
4764 if (end < charpos)
4765 break;
4766
4767 /* Skip this overlay if it doesn't start or end at IT's current
4768 position. */
4769 if (end != charpos && start != charpos)
4770 continue;
4771
4772 /* Skip this overlay if it doesn't apply to IT->w. */
4773 window = Foverlay_get (overlay, Qwindow);
4774 if (WINDOWP (window) && XWINDOW (window) != it->w)
4775 continue;
4776
4777 /* If the text ``under'' the overlay is invisible, both before-
4778 and after-strings from this overlay are visible; start and
4779 end position are indistinguishable. */
4780 invisible = Foverlay_get (overlay, Qinvisible);
4781 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
4782
4783 /* If overlay has a non-empty before-string, record it. */
4784 if ((start == charpos || (end == charpos && invis_p))
4785 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
4786 && SCHARS (str))
4787 RECORD_OVERLAY_STRING (overlay, str, 0);
4788
4789 /* If overlay has a non-empty after-string, record it. */
4790 if ((end == charpos || (start == charpos && invis_p))
4791 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
4792 && SCHARS (str))
4793 RECORD_OVERLAY_STRING (overlay, str, 1);
4794 }
4795
4796 /* Process overlays after the overlay center. */
4797 for (ov = current_buffer->overlays_after; ov; ov = ov->next)
4798 {
4799 XSETMISC (overlay, ov);
4800 xassert (OVERLAYP (overlay));
4801 start = OVERLAY_POSITION (OVERLAY_START (overlay));
4802 end = OVERLAY_POSITION (OVERLAY_END (overlay));
4803
4804 if (start > charpos)
4805 break;
4806
4807 /* Skip this overlay if it doesn't start or end at IT's current
4808 position. */
4809 if (end != charpos && start != charpos)
4810 continue;
4811
4812 /* Skip this overlay if it doesn't apply to IT->w. */
4813 window = Foverlay_get (overlay, Qwindow);
4814 if (WINDOWP (window) && XWINDOW (window) != it->w)
4815 continue;
4816
4817 /* If the text ``under'' the overlay is invisible, it has a zero
4818 dimension, and both before- and after-strings apply. */
4819 invisible = Foverlay_get (overlay, Qinvisible);
4820 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
4821
4822 /* If overlay has a non-empty before-string, record it. */
4823 if ((start == charpos || (end == charpos && invis_p))
4824 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
4825 && SCHARS (str))
4826 RECORD_OVERLAY_STRING (overlay, str, 0);
4827
4828 /* If overlay has a non-empty after-string, record it. */
4829 if ((end == charpos || (start == charpos && invis_p))
4830 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
4831 && SCHARS (str))
4832 RECORD_OVERLAY_STRING (overlay, str, 1);
4833 }
4834
4835 #undef RECORD_OVERLAY_STRING
4836
4837 /* Sort entries. */
4838 if (n > 1)
4839 qsort (entries, n, sizeof *entries, compare_overlay_entries);
4840
4841 /* Record number of overlay strings, and where we computed it. */
4842 it->n_overlay_strings = n;
4843 it->overlay_strings_charpos = charpos;
4844
4845 /* IT->current.overlay_string_index is the number of overlay strings
4846 that have already been consumed by IT. Copy some of the
4847 remaining overlay strings to IT->overlay_strings. */
4848 i = 0;
4849 j = it->current.overlay_string_index;
4850 while (i < OVERLAY_STRING_CHUNK_SIZE && j < n)
4851 {
4852 it->overlay_strings[i] = entries[j].string;
4853 it->string_overlays[i++] = entries[j++].overlay;
4854 }
4855
4856 CHECK_IT (it);
4857 }
4858
4859
4860 /* Get the first chunk of overlay strings at IT's current buffer
4861 position, or at CHARPOS if that is > 0. Value is non-zero if at
4862 least one overlay string was found. */
4863
4864 static int
4865 get_overlay_strings_1 (struct it *it, EMACS_INT charpos, int compute_stop_p)
4866 {
4867 /* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to
4868 process. This fills IT->overlay_strings with strings, and sets
4869 IT->n_overlay_strings to the total number of strings to process.
4870 IT->pos.overlay_string_index has to be set temporarily to zero
4871 because load_overlay_strings needs this; it must be set to -1
4872 when no overlay strings are found because a zero value would
4873 indicate a position in the first overlay string. */
4874 it->current.overlay_string_index = 0;
4875 load_overlay_strings (it, charpos);
4876
4877 /* If we found overlay strings, set up IT to deliver display
4878 elements from the first one. Otherwise set up IT to deliver
4879 from current_buffer. */
4880 if (it->n_overlay_strings)
4881 {
4882 /* Make sure we know settings in current_buffer, so that we can
4883 restore meaningful values when we're done with the overlay
4884 strings. */
4885 if (compute_stop_p)
4886 compute_stop_pos (it);
4887 xassert (it->face_id >= 0);
4888
4889 /* Save IT's settings. They are restored after all overlay
4890 strings have been processed. */
4891 xassert (!compute_stop_p || it->sp == 0);
4892
4893 /* When called from handle_stop, there might be an empty display
4894 string loaded. In that case, don't bother saving it. */
4895 if (!STRINGP (it->string) || SCHARS (it->string))
4896 push_it (it);
4897
4898 /* Set up IT to deliver display elements from the first overlay
4899 string. */
4900 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
4901 it->string = it->overlay_strings[0];
4902 it->from_overlay = Qnil;
4903 it->stop_charpos = 0;
4904 xassert (STRINGP (it->string));
4905 it->end_charpos = SCHARS (it->string);
4906 it->multibyte_p = STRING_MULTIBYTE (it->string);
4907 it->method = GET_FROM_STRING;
4908 return 1;
4909 }
4910
4911 it->current.overlay_string_index = -1;
4912 return 0;
4913 }
4914
4915 static int
4916 get_overlay_strings (struct it *it, EMACS_INT charpos)
4917 {
4918 it->string = Qnil;
4919 it->method = GET_FROM_BUFFER;
4920
4921 (void) get_overlay_strings_1 (it, charpos, 1);
4922
4923 CHECK_IT (it);
4924
4925 /* Value is non-zero if we found at least one overlay string. */
4926 return STRINGP (it->string);
4927 }
4928
4929
4930 \f
4931 /***********************************************************************
4932 Saving and restoring state
4933 ***********************************************************************/
4934
4935 /* Save current settings of IT on IT->stack. Called, for example,
4936 before setting up IT for an overlay string, to be able to restore
4937 IT's settings to what they were after the overlay string has been
4938 processed. */
4939
4940 static void
4941 push_it (struct it *it)
4942 {
4943 struct iterator_stack_entry *p;
4944
4945 xassert (it->sp < IT_STACK_SIZE);
4946 p = it->stack + it->sp;
4947
4948 p->stop_charpos = it->stop_charpos;
4949 p->prev_stop = it->prev_stop;
4950 p->base_level_stop = it->base_level_stop;
4951 p->cmp_it = it->cmp_it;
4952 xassert (it->face_id >= 0);
4953 p->face_id = it->face_id;
4954 p->string = it->string;
4955 p->method = it->method;
4956 p->from_overlay = it->from_overlay;
4957 switch (p->method)
4958 {
4959 case GET_FROM_IMAGE:
4960 p->u.image.object = it->object;
4961 p->u.image.image_id = it->image_id;
4962 p->u.image.slice = it->slice;
4963 break;
4964 case GET_FROM_STRETCH:
4965 p->u.stretch.object = it->object;
4966 break;
4967 }
4968 p->position = it->position;
4969 p->current = it->current;
4970 p->end_charpos = it->end_charpos;
4971 p->string_nchars = it->string_nchars;
4972 p->area = it->area;
4973 p->multibyte_p = it->multibyte_p;
4974 p->avoid_cursor_p = it->avoid_cursor_p;
4975 p->space_width = it->space_width;
4976 p->font_height = it->font_height;
4977 p->voffset = it->voffset;
4978 p->string_from_display_prop_p = it->string_from_display_prop_p;
4979 p->display_ellipsis_p = 0;
4980 p->line_wrap = it->line_wrap;
4981 ++it->sp;
4982 }
4983
4984 static void
4985 iterate_out_of_display_property (struct it *it)
4986 {
4987 /* Maybe initialize paragraph direction. If we are at the beginning
4988 of a new paragraph, next_element_from_buffer may not have a
4989 chance to do that. */
4990 if (it->bidi_it.first_elt && it->bidi_it.charpos < ZV)
4991 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1);
4992 /* prev_stop can be zero, so check against BEGV as well. */
4993 while (it->bidi_it.charpos >= BEGV
4994 && it->prev_stop <= it->bidi_it.charpos
4995 && it->bidi_it.charpos < CHARPOS (it->position))
4996 bidi_move_to_visually_next (&it->bidi_it);
4997 /* Record the stop_pos we just crossed, for when we cross it
4998 back, maybe. */
4999 if (it->bidi_it.charpos > CHARPOS (it->position))
5000 it->prev_stop = CHARPOS (it->position);
5001 /* If we ended up not where pop_it put us, resync IT's
5002 positional members with the bidi iterator. */
5003 if (it->bidi_it.charpos != CHARPOS (it->position))
5004 {
5005 SET_TEXT_POS (it->position,
5006 it->bidi_it.charpos, it->bidi_it.bytepos);
5007 it->current.pos = it->position;
5008 }
5009 }
5010
5011 /* Restore IT's settings from IT->stack. Called, for example, when no
5012 more overlay strings must be processed, and we return to delivering
5013 display elements from a buffer, or when the end of a string from a
5014 `display' property is reached and we return to delivering display
5015 elements from an overlay string, or from a buffer. */
5016
5017 static void
5018 pop_it (struct it *it)
5019 {
5020 struct iterator_stack_entry *p;
5021
5022 xassert (it->sp > 0);
5023 --it->sp;
5024 p = it->stack + it->sp;
5025 it->stop_charpos = p->stop_charpos;
5026 it->prev_stop = p->prev_stop;
5027 it->base_level_stop = p->base_level_stop;
5028 it->cmp_it = p->cmp_it;
5029 it->face_id = p->face_id;
5030 it->current = p->current;
5031 it->position = p->position;
5032 it->string = p->string;
5033 it->from_overlay = p->from_overlay;
5034 if (NILP (it->string))
5035 SET_TEXT_POS (it->current.string_pos, -1, -1);
5036 it->method = p->method;
5037 switch (it->method)
5038 {
5039 case GET_FROM_IMAGE:
5040 it->image_id = p->u.image.image_id;
5041 it->object = p->u.image.object;
5042 it->slice = p->u.image.slice;
5043 break;
5044 case GET_FROM_STRETCH:
5045 it->object = p->u.comp.object;
5046 break;
5047 case GET_FROM_BUFFER:
5048 it->object = it->w->buffer;
5049 if (it->bidi_p)
5050 {
5051 /* Bidi-iterate until we get out of the portion of text, if
5052 any, covered by a `display' text property or an overlay
5053 with `display' property. (We cannot just jump there,
5054 because the internal coherency of the bidi iterator state
5055 can not be preserved across such jumps.) We also must
5056 determine the paragraph base direction if the overlay we
5057 just processed is at the beginning of a new
5058 paragraph. */
5059 iterate_out_of_display_property (it);
5060 }
5061 break;
5062 case GET_FROM_STRING:
5063 it->object = it->string;
5064 break;
5065 case GET_FROM_DISPLAY_VECTOR:
5066 if (it->s)
5067 it->method = GET_FROM_C_STRING;
5068 else if (STRINGP (it->string))
5069 it->method = GET_FROM_STRING;
5070 else
5071 {
5072 it->method = GET_FROM_BUFFER;
5073 it->object = it->w->buffer;
5074 }
5075 }
5076 it->end_charpos = p->end_charpos;
5077 it->string_nchars = p->string_nchars;
5078 it->area = p->area;
5079 it->multibyte_p = p->multibyte_p;
5080 it->avoid_cursor_p = p->avoid_cursor_p;
5081 it->space_width = p->space_width;
5082 it->font_height = p->font_height;
5083 it->voffset = p->voffset;
5084 it->string_from_display_prop_p = p->string_from_display_prop_p;
5085 it->line_wrap = p->line_wrap;
5086 }
5087
5088
5089 \f
5090 /***********************************************************************
5091 Moving over lines
5092 ***********************************************************************/
5093
5094 /* Set IT's current position to the previous line start. */
5095
5096 static void
5097 back_to_previous_line_start (struct it *it)
5098 {
5099 IT_CHARPOS (*it) = find_next_newline_no_quit (IT_CHARPOS (*it) - 1, -1);
5100 IT_BYTEPOS (*it) = CHAR_TO_BYTE (IT_CHARPOS (*it));
5101 }
5102
5103
5104 /* Move IT to the next line start.
5105
5106 Value is non-zero if a newline was found. Set *SKIPPED_P to 1 if
5107 we skipped over part of the text (as opposed to moving the iterator
5108 continuously over the text). Otherwise, don't change the value
5109 of *SKIPPED_P.
5110
5111 Newlines may come from buffer text, overlay strings, or strings
5112 displayed via the `display' property. That's the reason we can't
5113 simply use find_next_newline_no_quit.
5114
5115 Note that this function may not skip over invisible text that is so
5116 because of text properties and immediately follows a newline. If
5117 it would, function reseat_at_next_visible_line_start, when called
5118 from set_iterator_to_next, would effectively make invisible
5119 characters following a newline part of the wrong glyph row, which
5120 leads to wrong cursor motion. */
5121
5122 static int
5123 forward_to_next_line_start (struct it *it, int *skipped_p)
5124 {
5125 int old_selective, newline_found_p, n;
5126 const int MAX_NEWLINE_DISTANCE = 500;
5127
5128 /* If already on a newline, just consume it to avoid unintended
5129 skipping over invisible text below. */
5130 if (it->what == IT_CHARACTER
5131 && it->c == '\n'
5132 && CHARPOS (it->position) == IT_CHARPOS (*it))
5133 {
5134 set_iterator_to_next (it, 0);
5135 it->c = 0;
5136 return 1;
5137 }
5138
5139 /* Don't handle selective display in the following. It's (a)
5140 unnecessary because it's done by the caller, and (b) leads to an
5141 infinite recursion because next_element_from_ellipsis indirectly
5142 calls this function. */
5143 old_selective = it->selective;
5144 it->selective = 0;
5145
5146 /* Scan for a newline within MAX_NEWLINE_DISTANCE display elements
5147 from buffer text. */
5148 for (n = newline_found_p = 0;
5149 !newline_found_p && n < MAX_NEWLINE_DISTANCE;
5150 n += STRINGP (it->string) ? 0 : 1)
5151 {
5152 if (!get_next_display_element (it))
5153 return 0;
5154 newline_found_p = it->what == IT_CHARACTER && it->c == '\n';
5155 set_iterator_to_next (it, 0);
5156 }
5157
5158 /* If we didn't find a newline near enough, see if we can use a
5159 short-cut. */
5160 if (!newline_found_p)
5161 {
5162 EMACS_INT start = IT_CHARPOS (*it);
5163 EMACS_INT limit = find_next_newline_no_quit (start, 1);
5164 Lisp_Object pos;
5165
5166 xassert (!STRINGP (it->string));
5167
5168 /* If there isn't any `display' property in sight, and no
5169 overlays, we can just use the position of the newline in
5170 buffer text. */
5171 if (it->stop_charpos >= limit
5172 || ((pos = Fnext_single_property_change (make_number (start),
5173 Qdisplay,
5174 Qnil, make_number (limit)),
5175 NILP (pos))
5176 && next_overlay_change (start) == ZV))
5177 {
5178 IT_CHARPOS (*it) = limit;
5179 IT_BYTEPOS (*it) = CHAR_TO_BYTE (limit);
5180 *skipped_p = newline_found_p = 1;
5181 }
5182 else
5183 {
5184 while (get_next_display_element (it)
5185 && !newline_found_p)
5186 {
5187 newline_found_p = ITERATOR_AT_END_OF_LINE_P (it);
5188 set_iterator_to_next (it, 0);
5189 }
5190 }
5191 }
5192
5193 it->selective = old_selective;
5194 return newline_found_p;
5195 }
5196
5197
5198 /* Set IT's current position to the previous visible line start. Skip
5199 invisible text that is so either due to text properties or due to
5200 selective display. Caution: this does not change IT->current_x and
5201 IT->hpos. */
5202
5203 static void
5204 back_to_previous_visible_line_start (struct it *it)
5205 {
5206 while (IT_CHARPOS (*it) > BEGV)
5207 {
5208 back_to_previous_line_start (it);
5209
5210 if (IT_CHARPOS (*it) <= BEGV)
5211 break;
5212
5213 /* If selective > 0, then lines indented more than its value are
5214 invisible. */
5215 if (it->selective > 0
5216 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
5217 (double) it->selective)) /* iftc */
5218 continue;
5219
5220 /* Check the newline before point for invisibility. */
5221 {
5222 Lisp_Object prop;
5223 prop = Fget_char_property (make_number (IT_CHARPOS (*it) - 1),
5224 Qinvisible, it->window);
5225 if (TEXT_PROP_MEANS_INVISIBLE (prop))
5226 continue;
5227 }
5228
5229 if (IT_CHARPOS (*it) <= BEGV)
5230 break;
5231
5232 {
5233 struct it it2;
5234 EMACS_INT pos;
5235 EMACS_INT beg, end;
5236 Lisp_Object val, overlay;
5237
5238 /* If newline is part of a composition, continue from start of composition */
5239 if (find_composition (IT_CHARPOS (*it), -1, &beg, &end, &val, Qnil)
5240 && beg < IT_CHARPOS (*it))
5241 goto replaced;
5242
5243 /* If newline is replaced by a display property, find start of overlay
5244 or interval and continue search from that point. */
5245 it2 = *it;
5246 pos = --IT_CHARPOS (it2);
5247 --IT_BYTEPOS (it2);
5248 it2.sp = 0;
5249 it2.string_from_display_prop_p = 0;
5250 if (handle_display_prop (&it2) == HANDLED_RETURN
5251 && !NILP (val = get_char_property_and_overlay
5252 (make_number (pos), Qdisplay, Qnil, &overlay))
5253 && (OVERLAYP (overlay)
5254 ? (beg = OVERLAY_POSITION (OVERLAY_START (overlay)))
5255 : get_property_and_range (pos, Qdisplay, &val, &beg, &end, Qnil)))
5256 goto replaced;
5257
5258 /* Newline is not replaced by anything -- so we are done. */
5259 break;
5260
5261 replaced:
5262 if (beg < BEGV)
5263 beg = BEGV;
5264 IT_CHARPOS (*it) = beg;
5265 IT_BYTEPOS (*it) = buf_charpos_to_bytepos (current_buffer, beg);
5266 }
5267 }
5268
5269 it->continuation_lines_width = 0;
5270
5271 xassert (IT_CHARPOS (*it) >= BEGV);
5272 xassert (IT_CHARPOS (*it) == BEGV
5273 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
5274 CHECK_IT (it);
5275 }
5276
5277
5278 /* Reseat iterator IT at the previous visible line start. Skip
5279 invisible text that is so either due to text properties or due to
5280 selective display. At the end, update IT's overlay information,
5281 face information etc. */
5282
5283 void
5284 reseat_at_previous_visible_line_start (struct it *it)
5285 {
5286 back_to_previous_visible_line_start (it);
5287 reseat (it, it->current.pos, 1);
5288 CHECK_IT (it);
5289 }
5290
5291
5292 /* Reseat iterator IT on the next visible line start in the current
5293 buffer. ON_NEWLINE_P non-zero means position IT on the newline
5294 preceding the line start. Skip over invisible text that is so
5295 because of selective display. Compute faces, overlays etc at the
5296 new position. Note that this function does not skip over text that
5297 is invisible because of text properties. */
5298
5299 static void
5300 reseat_at_next_visible_line_start (struct it *it, int on_newline_p)
5301 {
5302 int newline_found_p, skipped_p = 0;
5303
5304 newline_found_p = forward_to_next_line_start (it, &skipped_p);
5305
5306 /* Skip over lines that are invisible because they are indented
5307 more than the value of IT->selective. */
5308 if (it->selective > 0)
5309 while (IT_CHARPOS (*it) < ZV
5310 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
5311 (double) it->selective)) /* iftc */
5312 {
5313 xassert (IT_BYTEPOS (*it) == BEGV
5314 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
5315 newline_found_p = forward_to_next_line_start (it, &skipped_p);
5316 }
5317
5318 /* Position on the newline if that's what's requested. */
5319 if (on_newline_p && newline_found_p)
5320 {
5321 if (STRINGP (it->string))
5322 {
5323 if (IT_STRING_CHARPOS (*it) > 0)
5324 {
5325 --IT_STRING_CHARPOS (*it);
5326 --IT_STRING_BYTEPOS (*it);
5327 }
5328 }
5329 else if (IT_CHARPOS (*it) > BEGV)
5330 {
5331 --IT_CHARPOS (*it);
5332 --IT_BYTEPOS (*it);
5333 reseat (it, it->current.pos, 0);
5334 }
5335 }
5336 else if (skipped_p)
5337 reseat (it, it->current.pos, 0);
5338
5339 CHECK_IT (it);
5340 }
5341
5342
5343 \f
5344 /***********************************************************************
5345 Changing an iterator's position
5346 ***********************************************************************/
5347
5348 /* Change IT's current position to POS in current_buffer. If FORCE_P
5349 is non-zero, always check for text properties at the new position.
5350 Otherwise, text properties are only looked up if POS >=
5351 IT->check_charpos of a property. */
5352
5353 static void
5354 reseat (struct it *it, struct text_pos pos, int force_p)
5355 {
5356 EMACS_INT original_pos = IT_CHARPOS (*it);
5357
5358 reseat_1 (it, pos, 0);
5359
5360 /* Determine where to check text properties. Avoid doing it
5361 where possible because text property lookup is very expensive. */
5362 if (force_p
5363 || CHARPOS (pos) > it->stop_charpos
5364 || CHARPOS (pos) < original_pos)
5365 {
5366 if (it->bidi_p)
5367 {
5368 /* For bidi iteration, we need to prime prev_stop and
5369 base_level_stop with our best estimations. */
5370 if (CHARPOS (pos) < it->prev_stop)
5371 {
5372 handle_stop_backwards (it, BEGV);
5373 if (CHARPOS (pos) < it->base_level_stop)
5374 it->base_level_stop = 0;
5375 }
5376 else if (CHARPOS (pos) > it->stop_charpos
5377 && it->stop_charpos >= BEGV)
5378 handle_stop_backwards (it, it->stop_charpos);
5379 else /* force_p */
5380 handle_stop (it);
5381 }
5382 else
5383 {
5384 handle_stop (it);
5385 it->prev_stop = it->base_level_stop = 0;
5386 }
5387
5388 }
5389
5390 CHECK_IT (it);
5391 }
5392
5393
5394 /* Change IT's buffer position to POS. SET_STOP_P non-zero means set
5395 IT->stop_pos to POS, also. */
5396
5397 static void
5398 reseat_1 (struct it *it, struct text_pos pos, int set_stop_p)
5399 {
5400 /* Don't call this function when scanning a C string. */
5401 xassert (it->s == NULL);
5402
5403 /* POS must be a reasonable value. */
5404 xassert (CHARPOS (pos) >= BEGV && CHARPOS (pos) <= ZV);
5405
5406 it->current.pos = it->position = pos;
5407 it->end_charpos = ZV;
5408 it->dpvec = NULL;
5409 it->current.dpvec_index = -1;
5410 it->current.overlay_string_index = -1;
5411 IT_STRING_CHARPOS (*it) = -1;
5412 IT_STRING_BYTEPOS (*it) = -1;
5413 it->string = Qnil;
5414 it->string_from_display_prop_p = 0;
5415 it->method = GET_FROM_BUFFER;
5416 it->object = it->w->buffer;
5417 it->area = TEXT_AREA;
5418 it->multibyte_p = !NILP (BVAR (current_buffer, enable_multibyte_characters));
5419 it->sp = 0;
5420 it->string_from_display_prop_p = 0;
5421 it->face_before_selective_p = 0;
5422 if (it->bidi_p)
5423 {
5424 it->bidi_it.first_elt = 1;
5425 it->bidi_it.paragraph_dir = NEUTRAL_DIR;
5426 }
5427
5428 if (set_stop_p)
5429 {
5430 it->stop_charpos = CHARPOS (pos);
5431 it->base_level_stop = CHARPOS (pos);
5432 }
5433 }
5434
5435
5436 /* Set up IT for displaying a string, starting at CHARPOS in window W.
5437 If S is non-null, it is a C string to iterate over. Otherwise,
5438 STRING gives a Lisp string to iterate over.
5439
5440 If PRECISION > 0, don't return more then PRECISION number of
5441 characters from the string.
5442
5443 If FIELD_WIDTH > 0, return padding spaces until FIELD_WIDTH
5444 characters have been returned. FIELD_WIDTH < 0 means an infinite
5445 field width.
5446
5447 MULTIBYTE = 0 means disable processing of multibyte characters,
5448 MULTIBYTE > 0 means enable it,
5449 MULTIBYTE < 0 means use IT->multibyte_p.
5450
5451 IT must be initialized via a prior call to init_iterator before
5452 calling this function. */
5453
5454 static void
5455 reseat_to_string (struct it *it, const char *s, Lisp_Object string,
5456 EMACS_INT charpos, EMACS_INT precision, int field_width,
5457 int multibyte)
5458 {
5459 /* No region in strings. */
5460 it->region_beg_charpos = it->region_end_charpos = -1;
5461
5462 /* No text property checks performed by default, but see below. */
5463 it->stop_charpos = -1;
5464
5465 /* Set iterator position and end position. */
5466 memset (&it->current, 0, sizeof it->current);
5467 it->current.overlay_string_index = -1;
5468 it->current.dpvec_index = -1;
5469 xassert (charpos >= 0);
5470
5471 /* If STRING is specified, use its multibyteness, otherwise use the
5472 setting of MULTIBYTE, if specified. */
5473 if (multibyte >= 0)
5474 it->multibyte_p = multibyte > 0;
5475
5476 if (s == NULL)
5477 {
5478 xassert (STRINGP (string));
5479 it->string = string;
5480 it->s = NULL;
5481 it->end_charpos = it->string_nchars = SCHARS (string);
5482 it->method = GET_FROM_STRING;
5483 it->current.string_pos = string_pos (charpos, string);
5484 }
5485 else
5486 {
5487 it->s = (const unsigned char *) s;
5488 it->string = Qnil;
5489
5490 /* Note that we use IT->current.pos, not it->current.string_pos,
5491 for displaying C strings. */
5492 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
5493 if (it->multibyte_p)
5494 {
5495 it->current.pos = c_string_pos (charpos, s, 1);
5496 it->end_charpos = it->string_nchars = number_of_chars (s, 1);
5497 }
5498 else
5499 {
5500 IT_CHARPOS (*it) = IT_BYTEPOS (*it) = charpos;
5501 it->end_charpos = it->string_nchars = strlen (s);
5502 }
5503
5504 it->method = GET_FROM_C_STRING;
5505 }
5506
5507 /* PRECISION > 0 means don't return more than PRECISION characters
5508 from the string. */
5509 if (precision > 0 && it->end_charpos - charpos > precision)
5510 it->end_charpos = it->string_nchars = charpos + precision;
5511
5512 /* FIELD_WIDTH > 0 means pad with spaces until FIELD_WIDTH
5513 characters have been returned. FIELD_WIDTH == 0 means don't pad,
5514 FIELD_WIDTH < 0 means infinite field width. This is useful for
5515 padding with `-' at the end of a mode line. */
5516 if (field_width < 0)
5517 field_width = INFINITY;
5518 if (field_width > it->end_charpos - charpos)
5519 it->end_charpos = charpos + field_width;
5520
5521 /* Use the standard display table for displaying strings. */
5522 if (DISP_TABLE_P (Vstandard_display_table))
5523 it->dp = XCHAR_TABLE (Vstandard_display_table);
5524
5525 it->stop_charpos = charpos;
5526 if (s == NULL && it->multibyte_p)
5527 {
5528 EMACS_INT endpos = SCHARS (it->string);
5529 if (endpos > it->end_charpos)
5530 endpos = it->end_charpos;
5531 composition_compute_stop_pos (&it->cmp_it, charpos, -1, endpos,
5532 it->string);
5533 }
5534 CHECK_IT (it);
5535 }
5536
5537
5538 \f
5539 /***********************************************************************
5540 Iteration
5541 ***********************************************************************/
5542
5543 /* Map enum it_method value to corresponding next_element_from_* function. */
5544
5545 static int (* get_next_element[NUM_IT_METHODS]) (struct it *it) =
5546 {
5547 next_element_from_buffer,
5548 next_element_from_display_vector,
5549 next_element_from_string,
5550 next_element_from_c_string,
5551 next_element_from_image,
5552 next_element_from_stretch
5553 };
5554
5555 #define GET_NEXT_DISPLAY_ELEMENT(it) (*get_next_element[(it)->method]) (it)
5556
5557
5558 /* Return 1 iff a character at CHARPOS (and BYTEPOS) is composed
5559 (possibly with the following characters). */
5560
5561 #define CHAR_COMPOSED_P(IT,CHARPOS,BYTEPOS,END_CHARPOS) \
5562 ((IT)->cmp_it.id >= 0 \
5563 || ((IT)->cmp_it.stop_pos == (CHARPOS) \
5564 && composition_reseat_it (&(IT)->cmp_it, CHARPOS, BYTEPOS, \
5565 END_CHARPOS, (IT)->w, \
5566 FACE_FROM_ID ((IT)->f, (IT)->face_id), \
5567 (IT)->string)))
5568
5569
5570 /* Lookup the char-table Vglyphless_char_display for character C (-1
5571 if we want information for no-font case), and return the display
5572 method symbol. By side-effect, update it->what and
5573 it->glyphless_method. This function is called from
5574 get_next_display_element for each character element, and from
5575 x_produce_glyphs when no suitable font was found. */
5576
5577 Lisp_Object
5578 lookup_glyphless_char_display (int c, struct it *it)
5579 {
5580 Lisp_Object glyphless_method = Qnil;
5581
5582 if (CHAR_TABLE_P (Vglyphless_char_display)
5583 && CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (Vglyphless_char_display)) >= 1)
5584 glyphless_method = (c >= 0
5585 ? CHAR_TABLE_REF (Vglyphless_char_display, c)
5586 : XCHAR_TABLE (Vglyphless_char_display)->extras[0]);
5587 retry:
5588 if (NILP (glyphless_method))
5589 {
5590 if (c >= 0)
5591 /* The default is to display the character by a proper font. */
5592 return Qnil;
5593 /* The default for the no-font case is to display an empty box. */
5594 glyphless_method = Qempty_box;
5595 }
5596 if (EQ (glyphless_method, Qzero_width))
5597 {
5598 if (c >= 0)
5599 return glyphless_method;
5600 /* This method can't be used for the no-font case. */
5601 glyphless_method = Qempty_box;
5602 }
5603 if (EQ (glyphless_method, Qthin_space))
5604 it->glyphless_method = GLYPHLESS_DISPLAY_THIN_SPACE;
5605 else if (EQ (glyphless_method, Qempty_box))
5606 it->glyphless_method = GLYPHLESS_DISPLAY_EMPTY_BOX;
5607 else if (EQ (glyphless_method, Qhex_code))
5608 it->glyphless_method = GLYPHLESS_DISPLAY_HEX_CODE;
5609 else if (STRINGP (glyphless_method))
5610 it->glyphless_method = GLYPHLESS_DISPLAY_ACRONYM;
5611 else
5612 {
5613 /* Invalid value. We use the default method. */
5614 glyphless_method = Qnil;
5615 goto retry;
5616 }
5617 it->what = IT_GLYPHLESS;
5618 return glyphless_method;
5619 }
5620
5621 /* Load IT's display element fields with information about the next
5622 display element from the current position of IT. Value is zero if
5623 end of buffer (or C string) is reached. */
5624
5625 static struct frame *last_escape_glyph_frame = NULL;
5626 static unsigned last_escape_glyph_face_id = (1 << FACE_ID_BITS);
5627 static int last_escape_glyph_merged_face_id = 0;
5628
5629 struct frame *last_glyphless_glyph_frame = NULL;
5630 unsigned last_glyphless_glyph_face_id = (1 << FACE_ID_BITS);
5631 int last_glyphless_glyph_merged_face_id = 0;
5632
5633 int
5634 get_next_display_element (struct it *it)
5635 {
5636 /* Non-zero means that we found a display element. Zero means that
5637 we hit the end of what we iterate over. Performance note: the
5638 function pointer `method' used here turns out to be faster than
5639 using a sequence of if-statements. */
5640 int success_p;
5641
5642 get_next:
5643 success_p = GET_NEXT_DISPLAY_ELEMENT (it);
5644
5645 if (it->what == IT_CHARACTER)
5646 {
5647 /* UAX#9, L4: "A character is depicted by a mirrored glyph if
5648 and only if (a) the resolved directionality of that character
5649 is R..." */
5650 /* FIXME: Do we need an exception for characters from display
5651 tables? */
5652 if (it->bidi_p && it->bidi_it.type == STRONG_R)
5653 it->c = bidi_mirror_char (it->c);
5654 /* Map via display table or translate control characters.
5655 IT->c, IT->len etc. have been set to the next character by
5656 the function call above. If we have a display table, and it
5657 contains an entry for IT->c, translate it. Don't do this if
5658 IT->c itself comes from a display table, otherwise we could
5659 end up in an infinite recursion. (An alternative could be to
5660 count the recursion depth of this function and signal an
5661 error when a certain maximum depth is reached.) Is it worth
5662 it? */
5663 if (success_p && it->dpvec == NULL)
5664 {
5665 Lisp_Object dv;
5666 struct charset *unibyte = CHARSET_FROM_ID (charset_unibyte);
5667 enum { char_is_other = 0, char_is_nbsp, char_is_soft_hyphen }
5668 nbsp_or_shy = char_is_other;
5669 int c = it->c; /* This is the character to display. */
5670
5671 if (! it->multibyte_p && ! ASCII_CHAR_P (c))
5672 {
5673 xassert (SINGLE_BYTE_CHAR_P (c));
5674 if (unibyte_display_via_language_environment)
5675 {
5676 c = DECODE_CHAR (unibyte, c);
5677 if (c < 0)
5678 c = BYTE8_TO_CHAR (it->c);
5679 }
5680 else
5681 c = BYTE8_TO_CHAR (it->c);
5682 }
5683
5684 if (it->dp
5685 && (dv = DISP_CHAR_VECTOR (it->dp, c),
5686 VECTORP (dv)))
5687 {
5688 struct Lisp_Vector *v = XVECTOR (dv);
5689
5690 /* Return the first character from the display table
5691 entry, if not empty. If empty, don't display the
5692 current character. */
5693 if (v->size)
5694 {
5695 it->dpvec_char_len = it->len;
5696 it->dpvec = v->contents;
5697 it->dpend = v->contents + v->size;
5698 it->current.dpvec_index = 0;
5699 it->dpvec_face_id = -1;
5700 it->saved_face_id = it->face_id;
5701 it->method = GET_FROM_DISPLAY_VECTOR;
5702 it->ellipsis_p = 0;
5703 }
5704 else
5705 {
5706 set_iterator_to_next (it, 0);
5707 }
5708 goto get_next;
5709 }
5710
5711 if (! NILP (lookup_glyphless_char_display (c, it)))
5712 {
5713 if (it->what == IT_GLYPHLESS)
5714 goto done;
5715 /* Don't display this character. */
5716 set_iterator_to_next (it, 0);
5717 goto get_next;
5718 }
5719
5720 if (! ASCII_CHAR_P (c) && ! NILP (Vnobreak_char_display))
5721 nbsp_or_shy = (c == 0xA0 ? char_is_nbsp
5722 : c == 0xAD ? char_is_soft_hyphen
5723 : char_is_other);
5724
5725 /* Translate control characters into `\003' or `^C' form.
5726 Control characters coming from a display table entry are
5727 currently not translated because we use IT->dpvec to hold
5728 the translation. This could easily be changed but I
5729 don't believe that it is worth doing.
5730
5731 NBSP and SOFT-HYPEN are property translated too.
5732
5733 Non-printable characters and raw-byte characters are also
5734 translated to octal form. */
5735 if (((c < ' ' || c == 127) /* ASCII control chars */
5736 ? (it->area != TEXT_AREA
5737 /* In mode line, treat \n, \t like other crl chars. */
5738 || (c != '\t'
5739 && it->glyph_row
5740 && (it->glyph_row->mode_line_p || it->avoid_cursor_p))
5741 || (c != '\n' && c != '\t'))
5742 : (nbsp_or_shy
5743 || CHAR_BYTE8_P (c)
5744 || ! CHAR_PRINTABLE_P (c))))
5745 {
5746 /* C is a control character, NBSP, SOFT-HYPEN, raw-byte,
5747 or a non-printable character which must be displayed
5748 either as '\003' or as `^C' where the '\\' and '^'
5749 can be defined in the display table. Fill
5750 IT->ctl_chars with glyphs for what we have to
5751 display. Then, set IT->dpvec to these glyphs. */
5752 Lisp_Object gc;
5753 int ctl_len;
5754 int face_id, lface_id = 0 ;
5755 int escape_glyph;
5756
5757 /* Handle control characters with ^. */
5758
5759 if (ASCII_CHAR_P (c) && it->ctl_arrow_p)
5760 {
5761 int g;
5762
5763 g = '^'; /* default glyph for Control */
5764 /* Set IT->ctl_chars[0] to the glyph for `^'. */
5765 if (it->dp
5766 && (gc = DISP_CTRL_GLYPH (it->dp), GLYPH_CODE_P (gc))
5767 && GLYPH_CODE_CHAR_VALID_P (gc))
5768 {
5769 g = GLYPH_CODE_CHAR (gc);
5770 lface_id = GLYPH_CODE_FACE (gc);
5771 }
5772 if (lface_id)
5773 {
5774 face_id = merge_faces (it->f, Qt, lface_id, it->face_id);
5775 }
5776 else if (it->f == last_escape_glyph_frame
5777 && it->face_id == last_escape_glyph_face_id)
5778 {
5779 face_id = last_escape_glyph_merged_face_id;
5780 }
5781 else
5782 {
5783 /* Merge the escape-glyph face into the current face. */
5784 face_id = merge_faces (it->f, Qescape_glyph, 0,
5785 it->face_id);
5786 last_escape_glyph_frame = it->f;
5787 last_escape_glyph_face_id = it->face_id;
5788 last_escape_glyph_merged_face_id = face_id;
5789 }
5790
5791 XSETINT (it->ctl_chars[0], g);
5792 XSETINT (it->ctl_chars[1], c ^ 0100);
5793 ctl_len = 2;
5794 goto display_control;
5795 }
5796
5797 /* Handle non-break space in the mode where it only gets
5798 highlighting. */
5799
5800 if (EQ (Vnobreak_char_display, Qt)
5801 && nbsp_or_shy == char_is_nbsp)
5802 {
5803 /* Merge the no-break-space face into the current face. */
5804 face_id = merge_faces (it->f, Qnobreak_space, 0,
5805 it->face_id);
5806
5807 c = ' ';
5808 XSETINT (it->ctl_chars[0], ' ');
5809 ctl_len = 1;
5810 goto display_control;
5811 }
5812
5813 /* Handle sequences that start with the "escape glyph". */
5814
5815 /* the default escape glyph is \. */
5816 escape_glyph = '\\';
5817
5818 if (it->dp
5819 && (gc = DISP_ESCAPE_GLYPH (it->dp), GLYPH_CODE_P (gc))
5820 && GLYPH_CODE_CHAR_VALID_P (gc))
5821 {
5822 escape_glyph = GLYPH_CODE_CHAR (gc);
5823 lface_id = GLYPH_CODE_FACE (gc);
5824 }
5825 if (lface_id)
5826 {
5827 /* The display table specified a face.
5828 Merge it into face_id and also into escape_glyph. */
5829 face_id = merge_faces (it->f, Qt, lface_id,
5830 it->face_id);
5831 }
5832 else if (it->f == last_escape_glyph_frame
5833 && it->face_id == last_escape_glyph_face_id)
5834 {
5835 face_id = last_escape_glyph_merged_face_id;
5836 }
5837 else
5838 {
5839 /* Merge the escape-glyph face into the current face. */
5840 face_id = merge_faces (it->f, Qescape_glyph, 0,
5841 it->face_id);
5842 last_escape_glyph_frame = it->f;
5843 last_escape_glyph_face_id = it->face_id;
5844 last_escape_glyph_merged_face_id = face_id;
5845 }
5846
5847 /* Handle soft hyphens in the mode where they only get
5848 highlighting. */
5849
5850 if (EQ (Vnobreak_char_display, Qt)
5851 && nbsp_or_shy == char_is_soft_hyphen)
5852 {
5853 XSETINT (it->ctl_chars[0], '-');
5854 ctl_len = 1;
5855 goto display_control;
5856 }
5857
5858 /* Handle non-break space and soft hyphen
5859 with the escape glyph. */
5860
5861 if (nbsp_or_shy)
5862 {
5863 XSETINT (it->ctl_chars[0], escape_glyph);
5864 c = (nbsp_or_shy == char_is_nbsp ? ' ' : '-');
5865 XSETINT (it->ctl_chars[1], c);
5866 ctl_len = 2;
5867 goto display_control;
5868 }
5869
5870 {
5871 char str[10];
5872 int len, i;
5873
5874 if (CHAR_BYTE8_P (c))
5875 /* Display \200 instead of \17777600. */
5876 c = CHAR_TO_BYTE8 (c);
5877 len = sprintf (str, "%03o", c);
5878
5879 XSETINT (it->ctl_chars[0], escape_glyph);
5880 for (i = 0; i < len; i++)
5881 XSETINT (it->ctl_chars[i + 1], str[i]);
5882 ctl_len = len + 1;
5883 }
5884
5885 display_control:
5886 /* Set up IT->dpvec and return first character from it. */
5887 it->dpvec_char_len = it->len;
5888 it->dpvec = it->ctl_chars;
5889 it->dpend = it->dpvec + ctl_len;
5890 it->current.dpvec_index = 0;
5891 it->dpvec_face_id = face_id;
5892 it->saved_face_id = it->face_id;
5893 it->method = GET_FROM_DISPLAY_VECTOR;
5894 it->ellipsis_p = 0;
5895 goto get_next;
5896 }
5897 it->char_to_display = c;
5898 }
5899 else if (success_p)
5900 {
5901 it->char_to_display = it->c;
5902 }
5903 }
5904
5905 #ifdef HAVE_WINDOW_SYSTEM
5906 /* Adjust face id for a multibyte character. There are no multibyte
5907 character in unibyte text. */
5908 if ((it->what == IT_CHARACTER || it->what == IT_COMPOSITION)
5909 && it->multibyte_p
5910 && success_p
5911 && FRAME_WINDOW_P (it->f))
5912 {
5913 struct face *face = FACE_FROM_ID (it->f, it->face_id);
5914
5915 if (it->what == IT_COMPOSITION && it->cmp_it.ch >= 0)
5916 {
5917 /* Automatic composition with glyph-string. */
5918 Lisp_Object gstring = composition_gstring_from_id (it->cmp_it.id);
5919
5920 it->face_id = face_for_font (it->f, LGSTRING_FONT (gstring), face);
5921 }
5922 else
5923 {
5924 EMACS_INT pos = (it->s ? -1
5925 : STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
5926 : IT_CHARPOS (*it));
5927
5928 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display, pos,
5929 it->string);
5930 }
5931 }
5932 #endif
5933
5934 done:
5935 /* Is this character the last one of a run of characters with
5936 box? If yes, set IT->end_of_box_run_p to 1. */
5937 if (it->face_box_p
5938 && it->s == NULL)
5939 {
5940 if (it->method == GET_FROM_STRING && it->sp)
5941 {
5942 int face_id = underlying_face_id (it);
5943 struct face *face = FACE_FROM_ID (it->f, face_id);
5944
5945 if (face)
5946 {
5947 if (face->box == FACE_NO_BOX)
5948 {
5949 /* If the box comes from face properties in a
5950 display string, check faces in that string. */
5951 int string_face_id = face_after_it_pos (it);
5952 it->end_of_box_run_p
5953 = (FACE_FROM_ID (it->f, string_face_id)->box
5954 == FACE_NO_BOX);
5955 }
5956 /* Otherwise, the box comes from the underlying face.
5957 If this is the last string character displayed, check
5958 the next buffer location. */
5959 else if ((IT_STRING_CHARPOS (*it) >= SCHARS (it->string) - 1)
5960 && (it->current.overlay_string_index
5961 == it->n_overlay_strings - 1))
5962 {
5963 EMACS_INT ignore;
5964 int next_face_id;
5965 struct text_pos pos = it->current.pos;
5966 INC_TEXT_POS (pos, it->multibyte_p);
5967
5968 next_face_id = face_at_buffer_position
5969 (it->w, CHARPOS (pos), it->region_beg_charpos,
5970 it->region_end_charpos, &ignore,
5971 (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT), 0,
5972 -1);
5973 it->end_of_box_run_p
5974 = (FACE_FROM_ID (it->f, next_face_id)->box
5975 == FACE_NO_BOX);
5976 }
5977 }
5978 }
5979 else
5980 {
5981 int face_id = face_after_it_pos (it);
5982 it->end_of_box_run_p
5983 = (face_id != it->face_id
5984 && FACE_FROM_ID (it->f, face_id)->box == FACE_NO_BOX);
5985 }
5986 }
5987
5988 /* Value is 0 if end of buffer or string reached. */
5989 return success_p;
5990 }
5991
5992
5993 /* Move IT to the next display element.
5994
5995 RESEAT_P non-zero means if called on a newline in buffer text,
5996 skip to the next visible line start.
5997
5998 Functions get_next_display_element and set_iterator_to_next are
5999 separate because I find this arrangement easier to handle than a
6000 get_next_display_element function that also increments IT's
6001 position. The way it is we can first look at an iterator's current
6002 display element, decide whether it fits on a line, and if it does,
6003 increment the iterator position. The other way around we probably
6004 would either need a flag indicating whether the iterator has to be
6005 incremented the next time, or we would have to implement a
6006 decrement position function which would not be easy to write. */
6007
6008 void
6009 set_iterator_to_next (struct it *it, int reseat_p)
6010 {
6011 /* Reset flags indicating start and end of a sequence of characters
6012 with box. Reset them at the start of this function because
6013 moving the iterator to a new position might set them. */
6014 it->start_of_box_run_p = it->end_of_box_run_p = 0;
6015
6016 switch (it->method)
6017 {
6018 case GET_FROM_BUFFER:
6019 /* The current display element of IT is a character from
6020 current_buffer. Advance in the buffer, and maybe skip over
6021 invisible lines that are so because of selective display. */
6022 if (ITERATOR_AT_END_OF_LINE_P (it) && reseat_p)
6023 reseat_at_next_visible_line_start (it, 0);
6024 else if (it->cmp_it.id >= 0)
6025 {
6026 /* We are currently getting glyphs from a composition. */
6027 int i;
6028
6029 if (! it->bidi_p)
6030 {
6031 IT_CHARPOS (*it) += it->cmp_it.nchars;
6032 IT_BYTEPOS (*it) += it->cmp_it.nbytes;
6033 if (it->cmp_it.to < it->cmp_it.nglyphs)
6034 {
6035 it->cmp_it.from = it->cmp_it.to;
6036 }
6037 else
6038 {
6039 it->cmp_it.id = -1;
6040 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
6041 IT_BYTEPOS (*it),
6042 it->end_charpos, Qnil);
6043 }
6044 }
6045 else if (! it->cmp_it.reversed_p)
6046 {
6047 /* Composition created while scanning forward. */
6048 /* Update IT's char/byte positions to point to the first
6049 character of the next grapheme cluster, or to the
6050 character visually after the current composition. */
6051 for (i = 0; i < it->cmp_it.nchars; i++)
6052 bidi_move_to_visually_next (&it->bidi_it);
6053 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
6054 IT_CHARPOS (*it) = it->bidi_it.charpos;
6055
6056 if (it->cmp_it.to < it->cmp_it.nglyphs)
6057 {
6058 /* Proceed to the next grapheme cluster. */
6059 it->cmp_it.from = it->cmp_it.to;
6060 }
6061 else
6062 {
6063 /* No more grapheme clusters in this composition.
6064 Find the next stop position. */
6065 EMACS_INT stop = it->end_charpos;
6066 if (it->bidi_it.scan_dir < 0)
6067 /* Now we are scanning backward and don't know
6068 where to stop. */
6069 stop = -1;
6070 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
6071 IT_BYTEPOS (*it), stop, Qnil);
6072 }
6073 }
6074 else
6075 {
6076 /* Composition created while scanning backward. */
6077 /* Update IT's char/byte positions to point to the last
6078 character of the previous grapheme cluster, or the
6079 character visually after the current composition. */
6080 for (i = 0; i < it->cmp_it.nchars; i++)
6081 bidi_move_to_visually_next (&it->bidi_it);
6082 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
6083 IT_CHARPOS (*it) = it->bidi_it.charpos;
6084 if (it->cmp_it.from > 0)
6085 {
6086 /* Proceed to the previous grapheme cluster. */
6087 it->cmp_it.to = it->cmp_it.from;
6088 }
6089 else
6090 {
6091 /* No more grapheme clusters in this composition.
6092 Find the next stop position. */
6093 EMACS_INT stop = it->end_charpos;
6094 if (it->bidi_it.scan_dir < 0)
6095 /* Now we are scanning backward and don't know
6096 where to stop. */
6097 stop = -1;
6098 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
6099 IT_BYTEPOS (*it), stop, Qnil);
6100 }
6101 }
6102 }
6103 else
6104 {
6105 xassert (it->len != 0);
6106
6107 if (!it->bidi_p)
6108 {
6109 IT_BYTEPOS (*it) += it->len;
6110 IT_CHARPOS (*it) += 1;
6111 }
6112 else
6113 {
6114 int prev_scan_dir = it->bidi_it.scan_dir;
6115 /* If this is a new paragraph, determine its base
6116 direction (a.k.a. its base embedding level). */
6117 if (it->bidi_it.new_paragraph)
6118 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 0);
6119 bidi_move_to_visually_next (&it->bidi_it);
6120 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
6121 IT_CHARPOS (*it) = it->bidi_it.charpos;
6122 if (prev_scan_dir != it->bidi_it.scan_dir)
6123 {
6124 /* As the scan direction was changed, we must
6125 re-compute the stop position for composition. */
6126 EMACS_INT stop = it->end_charpos;
6127 if (it->bidi_it.scan_dir < 0)
6128 stop = -1;
6129 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
6130 IT_BYTEPOS (*it), stop, Qnil);
6131 }
6132 }
6133 xassert (IT_BYTEPOS (*it) == CHAR_TO_BYTE (IT_CHARPOS (*it)));
6134 }
6135 break;
6136
6137 case GET_FROM_C_STRING:
6138 /* Current display element of IT is from a C string. */
6139 IT_BYTEPOS (*it) += it->len;
6140 IT_CHARPOS (*it) += 1;
6141 break;
6142
6143 case GET_FROM_DISPLAY_VECTOR:
6144 /* Current display element of IT is from a display table entry.
6145 Advance in the display table definition. Reset it to null if
6146 end reached, and continue with characters from buffers/
6147 strings. */
6148 ++it->current.dpvec_index;
6149
6150 /* Restore face of the iterator to what they were before the
6151 display vector entry (these entries may contain faces). */
6152 it->face_id = it->saved_face_id;
6153
6154 if (it->dpvec + it->current.dpvec_index == it->dpend)
6155 {
6156 int recheck_faces = it->ellipsis_p;
6157
6158 if (it->s)
6159 it->method = GET_FROM_C_STRING;
6160 else if (STRINGP (it->string))
6161 it->method = GET_FROM_STRING;
6162 else
6163 {
6164 it->method = GET_FROM_BUFFER;
6165 it->object = it->w->buffer;
6166 }
6167
6168 it->dpvec = NULL;
6169 it->current.dpvec_index = -1;
6170
6171 /* Skip over characters which were displayed via IT->dpvec. */
6172 if (it->dpvec_char_len < 0)
6173 reseat_at_next_visible_line_start (it, 1);
6174 else if (it->dpvec_char_len > 0)
6175 {
6176 if (it->method == GET_FROM_STRING
6177 && it->n_overlay_strings > 0)
6178 it->ignore_overlay_strings_at_pos_p = 1;
6179 it->len = it->dpvec_char_len;
6180 set_iterator_to_next (it, reseat_p);
6181 }
6182
6183 /* Maybe recheck faces after display vector */
6184 if (recheck_faces)
6185 it->stop_charpos = IT_CHARPOS (*it);
6186 }
6187 break;
6188
6189 case GET_FROM_STRING:
6190 /* Current display element is a character from a Lisp string. */
6191 xassert (it->s == NULL && STRINGP (it->string));
6192 if (it->cmp_it.id >= 0)
6193 {
6194 IT_STRING_CHARPOS (*it) += it->cmp_it.nchars;
6195 IT_STRING_BYTEPOS (*it) += it->cmp_it.nbytes;
6196 if (it->cmp_it.to < it->cmp_it.nglyphs)
6197 it->cmp_it.from = it->cmp_it.to;
6198 else
6199 {
6200 it->cmp_it.id = -1;
6201 composition_compute_stop_pos (&it->cmp_it,
6202 IT_STRING_CHARPOS (*it),
6203 IT_STRING_BYTEPOS (*it),
6204 it->end_charpos, it->string);
6205 }
6206 }
6207 else
6208 {
6209 IT_STRING_BYTEPOS (*it) += it->len;
6210 IT_STRING_CHARPOS (*it) += 1;
6211 }
6212
6213 consider_string_end:
6214
6215 if (it->current.overlay_string_index >= 0)
6216 {
6217 /* IT->string is an overlay string. Advance to the
6218 next, if there is one. */
6219 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
6220 {
6221 it->ellipsis_p = 0;
6222 next_overlay_string (it);
6223 if (it->ellipsis_p)
6224 setup_for_ellipsis (it, 0);
6225 }
6226 }
6227 else
6228 {
6229 /* IT->string is not an overlay string. If we reached
6230 its end, and there is something on IT->stack, proceed
6231 with what is on the stack. This can be either another
6232 string, this time an overlay string, or a buffer. */
6233 if (IT_STRING_CHARPOS (*it) == SCHARS (it->string)
6234 && it->sp > 0)
6235 {
6236 pop_it (it);
6237 if (it->method == GET_FROM_STRING)
6238 goto consider_string_end;
6239 }
6240 }
6241 break;
6242
6243 case GET_FROM_IMAGE:
6244 case GET_FROM_STRETCH:
6245 /* The position etc with which we have to proceed are on
6246 the stack. The position may be at the end of a string,
6247 if the `display' property takes up the whole string. */
6248 xassert (it->sp > 0);
6249 pop_it (it);
6250 if (it->method == GET_FROM_STRING)
6251 goto consider_string_end;
6252 break;
6253
6254 default:
6255 /* There are no other methods defined, so this should be a bug. */
6256 abort ();
6257 }
6258
6259 xassert (it->method != GET_FROM_STRING
6260 || (STRINGP (it->string)
6261 && IT_STRING_CHARPOS (*it) >= 0));
6262 }
6263
6264 /* Load IT's display element fields with information about the next
6265 display element which comes from a display table entry or from the
6266 result of translating a control character to one of the forms `^C'
6267 or `\003'.
6268
6269 IT->dpvec holds the glyphs to return as characters.
6270 IT->saved_face_id holds the face id before the display vector--it
6271 is restored into IT->face_id in set_iterator_to_next. */
6272
6273 static int
6274 next_element_from_display_vector (struct it *it)
6275 {
6276 Lisp_Object gc;
6277
6278 /* Precondition. */
6279 xassert (it->dpvec && it->current.dpvec_index >= 0);
6280
6281 it->face_id = it->saved_face_id;
6282
6283 /* KFS: This code used to check ip->dpvec[0] instead of the current element.
6284 That seemed totally bogus - so I changed it... */
6285 gc = it->dpvec[it->current.dpvec_index];
6286
6287 if (GLYPH_CODE_P (gc) && GLYPH_CODE_CHAR_VALID_P (gc))
6288 {
6289 it->c = GLYPH_CODE_CHAR (gc);
6290 it->len = CHAR_BYTES (it->c);
6291
6292 /* The entry may contain a face id to use. Such a face id is
6293 the id of a Lisp face, not a realized face. A face id of
6294 zero means no face is specified. */
6295 if (it->dpvec_face_id >= 0)
6296 it->face_id = it->dpvec_face_id;
6297 else
6298 {
6299 int lface_id = GLYPH_CODE_FACE (gc);
6300 if (lface_id > 0)
6301 it->face_id = merge_faces (it->f, Qt, lface_id,
6302 it->saved_face_id);
6303 }
6304 }
6305 else
6306 /* Display table entry is invalid. Return a space. */
6307 it->c = ' ', it->len = 1;
6308
6309 /* Don't change position and object of the iterator here. They are
6310 still the values of the character that had this display table
6311 entry or was translated, and that's what we want. */
6312 it->what = IT_CHARACTER;
6313 return 1;
6314 }
6315
6316
6317 /* Load IT with the next display element from Lisp string IT->string.
6318 IT->current.string_pos is the current position within the string.
6319 If IT->current.overlay_string_index >= 0, the Lisp string is an
6320 overlay string. */
6321
6322 static int
6323 next_element_from_string (struct it *it)
6324 {
6325 struct text_pos position;
6326
6327 xassert (STRINGP (it->string));
6328 xassert (IT_STRING_CHARPOS (*it) >= 0);
6329 position = it->current.string_pos;
6330
6331 /* Time to check for invisible text? */
6332 if (IT_STRING_CHARPOS (*it) < it->end_charpos
6333 && IT_STRING_CHARPOS (*it) == it->stop_charpos)
6334 {
6335 handle_stop (it);
6336
6337 /* Since a handler may have changed IT->method, we must
6338 recurse here. */
6339 return GET_NEXT_DISPLAY_ELEMENT (it);
6340 }
6341
6342 if (it->current.overlay_string_index >= 0)
6343 {
6344 /* Get the next character from an overlay string. In overlay
6345 strings, There is no field width or padding with spaces to
6346 do. */
6347 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
6348 {
6349 it->what = IT_EOB;
6350 return 0;
6351 }
6352 else if (CHAR_COMPOSED_P (it, IT_STRING_CHARPOS (*it),
6353 IT_STRING_BYTEPOS (*it), SCHARS (it->string))
6354 && next_element_from_composition (it))
6355 {
6356 return 1;
6357 }
6358 else if (STRING_MULTIBYTE (it->string))
6359 {
6360 const unsigned char *s = (SDATA (it->string)
6361 + IT_STRING_BYTEPOS (*it));
6362 it->c = string_char_and_length (s, &it->len);
6363 }
6364 else
6365 {
6366 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
6367 it->len = 1;
6368 }
6369 }
6370 else
6371 {
6372 /* Get the next character from a Lisp string that is not an
6373 overlay string. Such strings come from the mode line, for
6374 example. We may have to pad with spaces, or truncate the
6375 string. See also next_element_from_c_string. */
6376 if (IT_STRING_CHARPOS (*it) >= it->end_charpos)
6377 {
6378 it->what = IT_EOB;
6379 return 0;
6380 }
6381 else if (IT_STRING_CHARPOS (*it) >= it->string_nchars)
6382 {
6383 /* Pad with spaces. */
6384 it->c = ' ', it->len = 1;
6385 CHARPOS (position) = BYTEPOS (position) = -1;
6386 }
6387 else if (CHAR_COMPOSED_P (it, IT_STRING_CHARPOS (*it),
6388 IT_STRING_BYTEPOS (*it), it->string_nchars)
6389 && next_element_from_composition (it))
6390 {
6391 return 1;
6392 }
6393 else if (STRING_MULTIBYTE (it->string))
6394 {
6395 const unsigned char *s = (SDATA (it->string)
6396 + IT_STRING_BYTEPOS (*it));
6397 it->c = string_char_and_length (s, &it->len);
6398 }
6399 else
6400 {
6401 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
6402 it->len = 1;
6403 }
6404 }
6405
6406 /* Record what we have and where it came from. */
6407 it->what = IT_CHARACTER;
6408 it->object = it->string;
6409 it->position = position;
6410 return 1;
6411 }
6412
6413
6414 /* Load IT with next display element from C string IT->s.
6415 IT->string_nchars is the maximum number of characters to return
6416 from the string. IT->end_charpos may be greater than
6417 IT->string_nchars when this function is called, in which case we
6418 may have to return padding spaces. Value is zero if end of string
6419 reached, including padding spaces. */
6420
6421 static int
6422 next_element_from_c_string (struct it *it)
6423 {
6424 int success_p = 1;
6425
6426 xassert (it->s);
6427 it->what = IT_CHARACTER;
6428 BYTEPOS (it->position) = CHARPOS (it->position) = 0;
6429 it->object = Qnil;
6430
6431 /* IT's position can be greater IT->string_nchars in case a field
6432 width or precision has been specified when the iterator was
6433 initialized. */
6434 if (IT_CHARPOS (*it) >= it->end_charpos)
6435 {
6436 /* End of the game. */
6437 it->what = IT_EOB;
6438 success_p = 0;
6439 }
6440 else if (IT_CHARPOS (*it) >= it->string_nchars)
6441 {
6442 /* Pad with spaces. */
6443 it->c = ' ', it->len = 1;
6444 BYTEPOS (it->position) = CHARPOS (it->position) = -1;
6445 }
6446 else if (it->multibyte_p)
6447 it->c = string_char_and_length (it->s + IT_BYTEPOS (*it), &it->len);
6448 else
6449 it->c = it->s[IT_BYTEPOS (*it)], it->len = 1;
6450
6451 return success_p;
6452 }
6453
6454
6455 /* Set up IT to return characters from an ellipsis, if appropriate.
6456 The definition of the ellipsis glyphs may come from a display table
6457 entry. This function fills IT with the first glyph from the
6458 ellipsis if an ellipsis is to be displayed. */
6459
6460 static int
6461 next_element_from_ellipsis (struct it *it)
6462 {
6463 if (it->selective_display_ellipsis_p)
6464 setup_for_ellipsis (it, it->len);
6465 else
6466 {
6467 /* The face at the current position may be different from the
6468 face we find after the invisible text. Remember what it
6469 was in IT->saved_face_id, and signal that it's there by
6470 setting face_before_selective_p. */
6471 it->saved_face_id = it->face_id;
6472 it->method = GET_FROM_BUFFER;
6473 it->object = it->w->buffer;
6474 reseat_at_next_visible_line_start (it, 1);
6475 it->face_before_selective_p = 1;
6476 }
6477
6478 return GET_NEXT_DISPLAY_ELEMENT (it);
6479 }
6480
6481
6482 /* Deliver an image display element. The iterator IT is already
6483 filled with image information (done in handle_display_prop). Value
6484 is always 1. */
6485
6486
6487 static int
6488 next_element_from_image (struct it *it)
6489 {
6490 it->what = IT_IMAGE;
6491 it->ignore_overlay_strings_at_pos_p = 0;
6492 return 1;
6493 }
6494
6495
6496 /* Fill iterator IT with next display element from a stretch glyph
6497 property. IT->object is the value of the text property. Value is
6498 always 1. */
6499
6500 static int
6501 next_element_from_stretch (struct it *it)
6502 {
6503 it->what = IT_STRETCH;
6504 return 1;
6505 }
6506
6507 /* Scan forward from CHARPOS in the current buffer, until we find a
6508 stop position > current IT's position. Then handle the stop
6509 position before that. This is called when we bump into a stop
6510 position while reordering bidirectional text. CHARPOS should be
6511 the last previously processed stop_pos (or BEGV, if none were
6512 processed yet) whose position is less that IT's current
6513 position. */
6514
6515 static void
6516 handle_stop_backwards (struct it *it, EMACS_INT charpos)
6517 {
6518 EMACS_INT where_we_are = IT_CHARPOS (*it);
6519 struct display_pos save_current = it->current;
6520 struct text_pos save_position = it->position;
6521 struct text_pos pos1;
6522 EMACS_INT next_stop;
6523
6524 /* Scan in strict logical order. */
6525 it->bidi_p = 0;
6526 do
6527 {
6528 it->prev_stop = charpos;
6529 SET_TEXT_POS (pos1, charpos, CHAR_TO_BYTE (charpos));
6530 reseat_1 (it, pos1, 0);
6531 compute_stop_pos (it);
6532 /* We must advance forward, right? */
6533 if (it->stop_charpos <= it->prev_stop)
6534 abort ();
6535 charpos = it->stop_charpos;
6536 }
6537 while (charpos <= where_we_are);
6538
6539 next_stop = it->stop_charpos;
6540 it->stop_charpos = it->prev_stop;
6541 it->bidi_p = 1;
6542 it->current = save_current;
6543 it->position = save_position;
6544 handle_stop (it);
6545 it->stop_charpos = next_stop;
6546 }
6547
6548 /* Load IT with the next display element from current_buffer. Value
6549 is zero if end of buffer reached. IT->stop_charpos is the next
6550 position at which to stop and check for text properties or buffer
6551 end. */
6552
6553 static int
6554 next_element_from_buffer (struct it *it)
6555 {
6556 int success_p = 1;
6557
6558 xassert (IT_CHARPOS (*it) >= BEGV);
6559
6560 /* With bidi reordering, the character to display might not be the
6561 character at IT_CHARPOS. BIDI_IT.FIRST_ELT non-zero means that
6562 we were reseat()ed to a new buffer position, which is potentially
6563 a different paragraph. */
6564 if (it->bidi_p && it->bidi_it.first_elt)
6565 {
6566 it->bidi_it.charpos = IT_CHARPOS (*it);
6567 it->bidi_it.bytepos = IT_BYTEPOS (*it);
6568 if (it->bidi_it.bytepos == ZV_BYTE)
6569 {
6570 /* Nothing to do, but reset the FIRST_ELT flag, like
6571 bidi_paragraph_init does, because we are not going to
6572 call it. */
6573 it->bidi_it.first_elt = 0;
6574 }
6575 else if (it->bidi_it.bytepos == BEGV_BYTE
6576 /* FIXME: Should support all Unicode line separators. */
6577 || FETCH_CHAR (it->bidi_it.bytepos - 1) == '\n'
6578 || FETCH_CHAR (it->bidi_it.bytepos) == '\n')
6579 {
6580 /* If we are at the beginning of a line, we can produce the
6581 next element right away. */
6582 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1);
6583 bidi_move_to_visually_next (&it->bidi_it);
6584 }
6585 else
6586 {
6587 EMACS_INT orig_bytepos = IT_BYTEPOS (*it);
6588
6589 /* We need to prime the bidi iterator starting at the line's
6590 beginning, before we will be able to produce the next
6591 element. */
6592 IT_CHARPOS (*it) = find_next_newline_no_quit (IT_CHARPOS (*it), -1);
6593 IT_BYTEPOS (*it) = CHAR_TO_BYTE (IT_CHARPOS (*it));
6594 it->bidi_it.charpos = IT_CHARPOS (*it);
6595 it->bidi_it.bytepos = IT_BYTEPOS (*it);
6596 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 1);
6597 do
6598 {
6599 /* Now return to buffer position where we were asked to
6600 get the next display element, and produce that. */
6601 bidi_move_to_visually_next (&it->bidi_it);
6602 }
6603 while (it->bidi_it.bytepos != orig_bytepos
6604 && it->bidi_it.bytepos < ZV_BYTE);
6605 }
6606
6607 it->bidi_it.first_elt = 0; /* paranoia: bidi.c does this */
6608 /* Adjust IT's position information to where we ended up. */
6609 IT_CHARPOS (*it) = it->bidi_it.charpos;
6610 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
6611 SET_TEXT_POS (it->position, IT_CHARPOS (*it), IT_BYTEPOS (*it));
6612 {
6613 EMACS_INT stop = it->end_charpos;
6614 if (it->bidi_it.scan_dir < 0)
6615 stop = -1;
6616 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
6617 IT_BYTEPOS (*it), stop, Qnil);
6618 }
6619 }
6620
6621 if (IT_CHARPOS (*it) >= it->stop_charpos)
6622 {
6623 if (IT_CHARPOS (*it) >= it->end_charpos)
6624 {
6625 int overlay_strings_follow_p;
6626
6627 /* End of the game, except when overlay strings follow that
6628 haven't been returned yet. */
6629 if (it->overlay_strings_at_end_processed_p)
6630 overlay_strings_follow_p = 0;
6631 else
6632 {
6633 it->overlay_strings_at_end_processed_p = 1;
6634 overlay_strings_follow_p = get_overlay_strings (it, 0);
6635 }
6636
6637 if (overlay_strings_follow_p)
6638 success_p = GET_NEXT_DISPLAY_ELEMENT (it);
6639 else
6640 {
6641 it->what = IT_EOB;
6642 it->position = it->current.pos;
6643 success_p = 0;
6644 }
6645 }
6646 else if (!(!it->bidi_p
6647 || BIDI_AT_BASE_LEVEL (it->bidi_it)
6648 || IT_CHARPOS (*it) == it->stop_charpos))
6649 {
6650 /* With bidi non-linear iteration, we could find ourselves
6651 far beyond the last computed stop_charpos, with several
6652 other stop positions in between that we missed. Scan
6653 them all now, in buffer's logical order, until we find
6654 and handle the last stop_charpos that precedes our
6655 current position. */
6656 handle_stop_backwards (it, it->stop_charpos);
6657 return GET_NEXT_DISPLAY_ELEMENT (it);
6658 }
6659 else
6660 {
6661 if (it->bidi_p)
6662 {
6663 /* Take note of the stop position we just moved across,
6664 for when we will move back across it. */
6665 it->prev_stop = it->stop_charpos;
6666 /* If we are at base paragraph embedding level, take
6667 note of the last stop position seen at this
6668 level. */
6669 if (BIDI_AT_BASE_LEVEL (it->bidi_it))
6670 it->base_level_stop = it->stop_charpos;
6671 }
6672 handle_stop (it);
6673 return GET_NEXT_DISPLAY_ELEMENT (it);
6674 }
6675 }
6676 else if (it->bidi_p
6677 /* We can sometimes back up for reasons that have nothing
6678 to do with bidi reordering. E.g., compositions. The
6679 code below is only needed when we are above the base
6680 embedding level, so test for that explicitly. */
6681 && !BIDI_AT_BASE_LEVEL (it->bidi_it)
6682 && IT_CHARPOS (*it) < it->prev_stop)
6683 {
6684 if (it->base_level_stop <= 0)
6685 it->base_level_stop = BEGV;
6686 if (IT_CHARPOS (*it) < it->base_level_stop)
6687 abort ();
6688 handle_stop_backwards (it, it->base_level_stop);
6689 return GET_NEXT_DISPLAY_ELEMENT (it);
6690 }
6691 else
6692 {
6693 /* No face changes, overlays etc. in sight, so just return a
6694 character from current_buffer. */
6695 unsigned char *p;
6696 EMACS_INT stop;
6697
6698 /* Maybe run the redisplay end trigger hook. Performance note:
6699 This doesn't seem to cost measurable time. */
6700 if (it->redisplay_end_trigger_charpos
6701 && it->glyph_row
6702 && IT_CHARPOS (*it) >= it->redisplay_end_trigger_charpos)
6703 run_redisplay_end_trigger_hook (it);
6704
6705 stop = it->bidi_it.scan_dir < 0 ? -1 : it->end_charpos;
6706 if (CHAR_COMPOSED_P (it, IT_CHARPOS (*it), IT_BYTEPOS (*it),
6707 stop)
6708 && next_element_from_composition (it))
6709 {
6710 return 1;
6711 }
6712
6713 /* Get the next character, maybe multibyte. */
6714 p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
6715 if (it->multibyte_p && !ASCII_BYTE_P (*p))
6716 it->c = STRING_CHAR_AND_LENGTH (p, it->len);
6717 else
6718 it->c = *p, it->len = 1;
6719
6720 /* Record what we have and where it came from. */
6721 it->what = IT_CHARACTER;
6722 it->object = it->w->buffer;
6723 it->position = it->current.pos;
6724
6725 /* Normally we return the character found above, except when we
6726 really want to return an ellipsis for selective display. */
6727 if (it->selective)
6728 {
6729 if (it->c == '\n')
6730 {
6731 /* A value of selective > 0 means hide lines indented more
6732 than that number of columns. */
6733 if (it->selective > 0
6734 && IT_CHARPOS (*it) + 1 < ZV
6735 && indented_beyond_p (IT_CHARPOS (*it) + 1,
6736 IT_BYTEPOS (*it) + 1,
6737 (double) it->selective)) /* iftc */
6738 {
6739 success_p = next_element_from_ellipsis (it);
6740 it->dpvec_char_len = -1;
6741 }
6742 }
6743 else if (it->c == '\r' && it->selective == -1)
6744 {
6745 /* A value of selective == -1 means that everything from the
6746 CR to the end of the line is invisible, with maybe an
6747 ellipsis displayed for it. */
6748 success_p = next_element_from_ellipsis (it);
6749 it->dpvec_char_len = -1;
6750 }
6751 }
6752 }
6753
6754 /* Value is zero if end of buffer reached. */
6755 xassert (!success_p || it->what != IT_CHARACTER || it->len > 0);
6756 return success_p;
6757 }
6758
6759
6760 /* Run the redisplay end trigger hook for IT. */
6761
6762 static void
6763 run_redisplay_end_trigger_hook (struct it *it)
6764 {
6765 Lisp_Object args[3];
6766
6767 /* IT->glyph_row should be non-null, i.e. we should be actually
6768 displaying something, or otherwise we should not run the hook. */
6769 xassert (it->glyph_row);
6770
6771 /* Set up hook arguments. */
6772 args[0] = Qredisplay_end_trigger_functions;
6773 args[1] = it->window;
6774 XSETINT (args[2], it->redisplay_end_trigger_charpos);
6775 it->redisplay_end_trigger_charpos = 0;
6776
6777 /* Since we are *trying* to run these functions, don't try to run
6778 them again, even if they get an error. */
6779 it->w->redisplay_end_trigger = Qnil;
6780 Frun_hook_with_args (3, args);
6781
6782 /* Notice if it changed the face of the character we are on. */
6783 handle_face_prop (it);
6784 }
6785
6786
6787 /* Deliver a composition display element. Unlike the other
6788 next_element_from_XXX, this function is not registered in the array
6789 get_next_element[]. It is called from next_element_from_buffer and
6790 next_element_from_string when necessary. */
6791
6792 static int
6793 next_element_from_composition (struct it *it)
6794 {
6795 it->what = IT_COMPOSITION;
6796 it->len = it->cmp_it.nbytes;
6797 if (STRINGP (it->string))
6798 {
6799 if (it->c < 0)
6800 {
6801 IT_STRING_CHARPOS (*it) += it->cmp_it.nchars;
6802 IT_STRING_BYTEPOS (*it) += it->cmp_it.nbytes;
6803 return 0;
6804 }
6805 it->position = it->current.string_pos;
6806 it->object = it->string;
6807 it->c = composition_update_it (&it->cmp_it, IT_STRING_CHARPOS (*it),
6808 IT_STRING_BYTEPOS (*it), it->string);
6809 }
6810 else
6811 {
6812 if (it->c < 0)
6813 {
6814 IT_CHARPOS (*it) += it->cmp_it.nchars;
6815 IT_BYTEPOS (*it) += it->cmp_it.nbytes;
6816 if (it->bidi_p)
6817 {
6818 if (it->bidi_it.new_paragraph)
6819 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, 0);
6820 /* Resync the bidi iterator with IT's new position.
6821 FIXME: this doesn't support bidirectional text. */
6822 while (it->bidi_it.charpos < IT_CHARPOS (*it))
6823 bidi_move_to_visually_next (&it->bidi_it);
6824 }
6825 return 0;
6826 }
6827 it->position = it->current.pos;
6828 it->object = it->w->buffer;
6829 it->c = composition_update_it (&it->cmp_it, IT_CHARPOS (*it),
6830 IT_BYTEPOS (*it), Qnil);
6831 }
6832 return 1;
6833 }
6834
6835
6836 \f
6837 /***********************************************************************
6838 Moving an iterator without producing glyphs
6839 ***********************************************************************/
6840
6841 /* Check if iterator is at a position corresponding to a valid buffer
6842 position after some move_it_ call. */
6843
6844 #define IT_POS_VALID_AFTER_MOVE_P(it) \
6845 ((it)->method == GET_FROM_STRING \
6846 ? IT_STRING_CHARPOS (*it) == 0 \
6847 : 1)
6848
6849
6850 /* Move iterator IT to a specified buffer or X position within one
6851 line on the display without producing glyphs.
6852
6853 OP should be a bit mask including some or all of these bits:
6854 MOVE_TO_X: Stop upon reaching x-position TO_X.
6855 MOVE_TO_POS: Stop upon reaching buffer or string position TO_CHARPOS.
6856 Regardless of OP's value, stop upon reaching the end of the display line.
6857
6858 TO_X is normally a value 0 <= TO_X <= IT->last_visible_x.
6859 This means, in particular, that TO_X includes window's horizontal
6860 scroll amount.
6861
6862 The return value has several possible values that
6863 say what condition caused the scan to stop:
6864
6865 MOVE_POS_MATCH_OR_ZV
6866 - when TO_POS or ZV was reached.
6867
6868 MOVE_X_REACHED
6869 -when TO_X was reached before TO_POS or ZV were reached.
6870
6871 MOVE_LINE_CONTINUED
6872 - when we reached the end of the display area and the line must
6873 be continued.
6874
6875 MOVE_LINE_TRUNCATED
6876 - when we reached the end of the display area and the line is
6877 truncated.
6878
6879 MOVE_NEWLINE_OR_CR
6880 - when we stopped at a line end, i.e. a newline or a CR and selective
6881 display is on. */
6882
6883 static enum move_it_result
6884 move_it_in_display_line_to (struct it *it,
6885 EMACS_INT to_charpos, int to_x,
6886 enum move_operation_enum op)
6887 {
6888 enum move_it_result result = MOVE_UNDEFINED;
6889 struct glyph_row *saved_glyph_row;
6890 struct it wrap_it, atpos_it, atx_it;
6891 int may_wrap = 0;
6892 enum it_method prev_method = it->method;
6893 EMACS_INT prev_pos = IT_CHARPOS (*it);
6894
6895 /* Don't produce glyphs in produce_glyphs. */
6896 saved_glyph_row = it->glyph_row;
6897 it->glyph_row = NULL;
6898
6899 /* Use wrap_it to save a copy of IT wherever a word wrap could
6900 occur. Use atpos_it to save a copy of IT at the desired buffer
6901 position, if found, so that we can scan ahead and check if the
6902 word later overshoots the window edge. Use atx_it similarly, for
6903 pixel positions. */
6904 wrap_it.sp = -1;
6905 atpos_it.sp = -1;
6906 atx_it.sp = -1;
6907
6908 #define BUFFER_POS_REACHED_P() \
6909 ((op & MOVE_TO_POS) != 0 \
6910 && BUFFERP (it->object) \
6911 && (IT_CHARPOS (*it) == to_charpos \
6912 || (!it->bidi_p && IT_CHARPOS (*it) > to_charpos)) \
6913 && (it->method == GET_FROM_BUFFER \
6914 || (it->method == GET_FROM_DISPLAY_VECTOR \
6915 && it->dpvec + it->current.dpvec_index + 1 >= it->dpend)))
6916
6917 /* If there's a line-/wrap-prefix, handle it. */
6918 if (it->hpos == 0 && it->method == GET_FROM_BUFFER
6919 && it->current_y < it->last_visible_y)
6920 handle_line_prefix (it);
6921
6922 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
6923 SET_TEXT_POS (this_line_min_pos, IT_CHARPOS (*it), IT_BYTEPOS (*it));
6924
6925 while (1)
6926 {
6927 int x, i, ascent = 0, descent = 0;
6928
6929 /* Utility macro to reset an iterator with x, ascent, and descent. */
6930 #define IT_RESET_X_ASCENT_DESCENT(IT) \
6931 ((IT)->current_x = x, (IT)->max_ascent = ascent, \
6932 (IT)->max_descent = descent)
6933
6934 /* Stop if we move beyond TO_CHARPOS (after an image or stretch
6935 glyph). */
6936 if ((op & MOVE_TO_POS) != 0
6937 && BUFFERP (it->object)
6938 && it->method == GET_FROM_BUFFER
6939 && ((!it->bidi_p && IT_CHARPOS (*it) > to_charpos)
6940 || (it->bidi_p
6941 && (prev_method == GET_FROM_IMAGE
6942 || prev_method == GET_FROM_STRETCH)
6943 /* Passed TO_CHARPOS from left to right. */
6944 && ((prev_pos < to_charpos
6945 && IT_CHARPOS (*it) > to_charpos)
6946 /* Passed TO_CHARPOS from right to left. */
6947 || (prev_pos > to_charpos
6948 && IT_CHARPOS (*it) < to_charpos)))))
6949 {
6950 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
6951 {
6952 result = MOVE_POS_MATCH_OR_ZV;
6953 break;
6954 }
6955 else if (it->line_wrap == WORD_WRAP && atpos_it.sp < 0)
6956 /* If wrap_it is valid, the current position might be in a
6957 word that is wrapped. So, save the iterator in
6958 atpos_it and continue to see if wrapping happens. */
6959 atpos_it = *it;
6960 }
6961
6962 prev_method = it->method;
6963 if (it->method == GET_FROM_BUFFER)
6964 prev_pos = IT_CHARPOS (*it);
6965 /* Stop when ZV reached.
6966 We used to stop here when TO_CHARPOS reached as well, but that is
6967 too soon if this glyph does not fit on this line. So we handle it
6968 explicitly below. */
6969 if (!get_next_display_element (it))
6970 {
6971 result = MOVE_POS_MATCH_OR_ZV;
6972 break;
6973 }
6974
6975 if (it->line_wrap == TRUNCATE)
6976 {
6977 if (BUFFER_POS_REACHED_P ())
6978 {
6979 result = MOVE_POS_MATCH_OR_ZV;
6980 break;
6981 }
6982 }
6983 else
6984 {
6985 if (it->line_wrap == WORD_WRAP)
6986 {
6987 if (IT_DISPLAYING_WHITESPACE (it))
6988 may_wrap = 1;
6989 else if (may_wrap)
6990 {
6991 /* We have reached a glyph that follows one or more
6992 whitespace characters. If the position is
6993 already found, we are done. */
6994 if (atpos_it.sp >= 0)
6995 {
6996 *it = atpos_it;
6997 result = MOVE_POS_MATCH_OR_ZV;
6998 goto done;
6999 }
7000 if (atx_it.sp >= 0)
7001 {
7002 *it = atx_it;
7003 result = MOVE_X_REACHED;
7004 goto done;
7005 }
7006 /* Otherwise, we can wrap here. */
7007 wrap_it = *it;
7008 may_wrap = 0;
7009 }
7010 }
7011 }
7012
7013 /* Remember the line height for the current line, in case
7014 the next element doesn't fit on the line. */
7015 ascent = it->max_ascent;
7016 descent = it->max_descent;
7017
7018 /* The call to produce_glyphs will get the metrics of the
7019 display element IT is loaded with. Record the x-position
7020 before this display element, in case it doesn't fit on the
7021 line. */
7022 x = it->current_x;
7023
7024 PRODUCE_GLYPHS (it);
7025
7026 if (it->area != TEXT_AREA)
7027 {
7028 set_iterator_to_next (it, 1);
7029 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
7030 SET_TEXT_POS (this_line_min_pos,
7031 IT_CHARPOS (*it), IT_BYTEPOS (*it));
7032 continue;
7033 }
7034
7035 /* The number of glyphs we get back in IT->nglyphs will normally
7036 be 1 except when IT->c is (i) a TAB, or (ii) a multi-glyph
7037 character on a terminal frame, or (iii) a line end. For the
7038 second case, IT->nglyphs - 1 padding glyphs will be present.
7039 (On X frames, there is only one glyph produced for a
7040 composite character.)
7041
7042 The behavior implemented below means, for continuation lines,
7043 that as many spaces of a TAB as fit on the current line are
7044 displayed there. For terminal frames, as many glyphs of a
7045 multi-glyph character are displayed in the current line, too.
7046 This is what the old redisplay code did, and we keep it that
7047 way. Under X, the whole shape of a complex character must
7048 fit on the line or it will be completely displayed in the
7049 next line.
7050
7051 Note that both for tabs and padding glyphs, all glyphs have
7052 the same width. */
7053 if (it->nglyphs)
7054 {
7055 /* More than one glyph or glyph doesn't fit on line. All
7056 glyphs have the same width. */
7057 int single_glyph_width = it->pixel_width / it->nglyphs;
7058 int new_x;
7059 int x_before_this_char = x;
7060 int hpos_before_this_char = it->hpos;
7061
7062 for (i = 0; i < it->nglyphs; ++i, x = new_x)
7063 {
7064 new_x = x + single_glyph_width;
7065
7066 /* We want to leave anything reaching TO_X to the caller. */
7067 if ((op & MOVE_TO_X) && new_x > to_x)
7068 {
7069 if (BUFFER_POS_REACHED_P ())
7070 {
7071 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
7072 goto buffer_pos_reached;
7073 if (atpos_it.sp < 0)
7074 {
7075 atpos_it = *it;
7076 IT_RESET_X_ASCENT_DESCENT (&atpos_it);
7077 }
7078 }
7079 else
7080 {
7081 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
7082 {
7083 it->current_x = x;
7084 result = MOVE_X_REACHED;
7085 break;
7086 }
7087 if (atx_it.sp < 0)
7088 {
7089 atx_it = *it;
7090 IT_RESET_X_ASCENT_DESCENT (&atx_it);
7091 }
7092 }
7093 }
7094
7095 if (/* Lines are continued. */
7096 it->line_wrap != TRUNCATE
7097 && (/* And glyph doesn't fit on the line. */
7098 new_x > it->last_visible_x
7099 /* Or it fits exactly and we're on a window
7100 system frame. */
7101 || (new_x == it->last_visible_x
7102 && FRAME_WINDOW_P (it->f))))
7103 {
7104 if (/* IT->hpos == 0 means the very first glyph
7105 doesn't fit on the line, e.g. a wide image. */
7106 it->hpos == 0
7107 || (new_x == it->last_visible_x
7108 && FRAME_WINDOW_P (it->f)))
7109 {
7110 ++it->hpos;
7111 it->current_x = new_x;
7112
7113 /* The character's last glyph just barely fits
7114 in this row. */
7115 if (i == it->nglyphs - 1)
7116 {
7117 /* If this is the destination position,
7118 return a position *before* it in this row,
7119 now that we know it fits in this row. */
7120 if (BUFFER_POS_REACHED_P ())
7121 {
7122 if (it->line_wrap != WORD_WRAP
7123 || wrap_it.sp < 0)
7124 {
7125 it->hpos = hpos_before_this_char;
7126 it->current_x = x_before_this_char;
7127 result = MOVE_POS_MATCH_OR_ZV;
7128 break;
7129 }
7130 if (it->line_wrap == WORD_WRAP
7131 && atpos_it.sp < 0)
7132 {
7133 atpos_it = *it;
7134 atpos_it.current_x = x_before_this_char;
7135 atpos_it.hpos = hpos_before_this_char;
7136 }
7137 }
7138
7139 set_iterator_to_next (it, 1);
7140 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
7141 SET_TEXT_POS (this_line_min_pos,
7142 IT_CHARPOS (*it), IT_BYTEPOS (*it));
7143 /* On graphical terminals, newlines may
7144 "overflow" into the fringe if
7145 overflow-newline-into-fringe is non-nil.
7146 On text-only terminals, newlines may
7147 overflow into the last glyph on the
7148 display line.*/
7149 if (!FRAME_WINDOW_P (it->f)
7150 || IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
7151 {
7152 if (!get_next_display_element (it))
7153 {
7154 result = MOVE_POS_MATCH_OR_ZV;
7155 break;
7156 }
7157 if (BUFFER_POS_REACHED_P ())
7158 {
7159 if (ITERATOR_AT_END_OF_LINE_P (it))
7160 result = MOVE_POS_MATCH_OR_ZV;
7161 else
7162 result = MOVE_LINE_CONTINUED;
7163 break;
7164 }
7165 if (ITERATOR_AT_END_OF_LINE_P (it))
7166 {
7167 result = MOVE_NEWLINE_OR_CR;
7168 break;
7169 }
7170 }
7171 }
7172 }
7173 else
7174 IT_RESET_X_ASCENT_DESCENT (it);
7175
7176 if (wrap_it.sp >= 0)
7177 {
7178 *it = wrap_it;
7179 atpos_it.sp = -1;
7180 atx_it.sp = -1;
7181 }
7182
7183 TRACE_MOVE ((stderr, "move_it_in: continued at %d\n",
7184 IT_CHARPOS (*it)));
7185 result = MOVE_LINE_CONTINUED;
7186 break;
7187 }
7188
7189 if (BUFFER_POS_REACHED_P ())
7190 {
7191 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
7192 goto buffer_pos_reached;
7193 if (it->line_wrap == WORD_WRAP && atpos_it.sp < 0)
7194 {
7195 atpos_it = *it;
7196 IT_RESET_X_ASCENT_DESCENT (&atpos_it);
7197 }
7198 }
7199
7200 if (new_x > it->first_visible_x)
7201 {
7202 /* Glyph is visible. Increment number of glyphs that
7203 would be displayed. */
7204 ++it->hpos;
7205 }
7206 }
7207
7208 if (result != MOVE_UNDEFINED)
7209 break;
7210 }
7211 else if (BUFFER_POS_REACHED_P ())
7212 {
7213 buffer_pos_reached:
7214 IT_RESET_X_ASCENT_DESCENT (it);
7215 result = MOVE_POS_MATCH_OR_ZV;
7216 break;
7217 }
7218 else if ((op & MOVE_TO_X) && it->current_x >= to_x)
7219 {
7220 /* Stop when TO_X specified and reached. This check is
7221 necessary here because of lines consisting of a line end,
7222 only. The line end will not produce any glyphs and we
7223 would never get MOVE_X_REACHED. */
7224 xassert (it->nglyphs == 0);
7225 result = MOVE_X_REACHED;
7226 break;
7227 }
7228
7229 /* Is this a line end? If yes, we're done. */
7230 if (ITERATOR_AT_END_OF_LINE_P (it))
7231 {
7232 result = MOVE_NEWLINE_OR_CR;
7233 break;
7234 }
7235
7236 if (it->method == GET_FROM_BUFFER)
7237 prev_pos = IT_CHARPOS (*it);
7238 /* The current display element has been consumed. Advance
7239 to the next. */
7240 set_iterator_to_next (it, 1);
7241 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
7242 SET_TEXT_POS (this_line_min_pos, IT_CHARPOS (*it), IT_BYTEPOS (*it));
7243
7244 /* Stop if lines are truncated and IT's current x-position is
7245 past the right edge of the window now. */
7246 if (it->line_wrap == TRUNCATE
7247 && it->current_x >= it->last_visible_x)
7248 {
7249 if (!FRAME_WINDOW_P (it->f)
7250 || IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
7251 {
7252 if (!get_next_display_element (it)
7253 || BUFFER_POS_REACHED_P ())
7254 {
7255 result = MOVE_POS_MATCH_OR_ZV;
7256 break;
7257 }
7258 if (ITERATOR_AT_END_OF_LINE_P (it))
7259 {
7260 result = MOVE_NEWLINE_OR_CR;
7261 break;
7262 }
7263 }
7264 result = MOVE_LINE_TRUNCATED;
7265 break;
7266 }
7267 #undef IT_RESET_X_ASCENT_DESCENT
7268 }
7269
7270 #undef BUFFER_POS_REACHED_P
7271
7272 /* If we scanned beyond to_pos and didn't find a point to wrap at,
7273 restore the saved iterator. */
7274 if (atpos_it.sp >= 0)
7275 *it = atpos_it;
7276 else if (atx_it.sp >= 0)
7277 *it = atx_it;
7278
7279 done:
7280
7281 /* Restore the iterator settings altered at the beginning of this
7282 function. */
7283 it->glyph_row = saved_glyph_row;
7284 return result;
7285 }
7286
7287 /* For external use. */
7288 void
7289 move_it_in_display_line (struct it *it,
7290 EMACS_INT to_charpos, int to_x,
7291 enum move_operation_enum op)
7292 {
7293 if (it->line_wrap == WORD_WRAP
7294 && (op & MOVE_TO_X))
7295 {
7296 struct it save_it = *it;
7297 int skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
7298 /* When word-wrap is on, TO_X may lie past the end
7299 of a wrapped line. Then it->current is the
7300 character on the next line, so backtrack to the
7301 space before the wrap point. */
7302 if (skip == MOVE_LINE_CONTINUED)
7303 {
7304 int prev_x = max (it->current_x - 1, 0);
7305 *it = save_it;
7306 move_it_in_display_line_to
7307 (it, -1, prev_x, MOVE_TO_X);
7308 }
7309 }
7310 else
7311 move_it_in_display_line_to (it, to_charpos, to_x, op);
7312 }
7313
7314
7315 /* Move IT forward until it satisfies one or more of the criteria in
7316 TO_CHARPOS, TO_X, TO_Y, and TO_VPOS.
7317
7318 OP is a bit-mask that specifies where to stop, and in particular,
7319 which of those four position arguments makes a difference. See the
7320 description of enum move_operation_enum.
7321
7322 If TO_CHARPOS is in invisible text, e.g. a truncated part of a
7323 screen line, this function will set IT to the next position >
7324 TO_CHARPOS. */
7325
7326 void
7327 move_it_to (struct it *it, EMACS_INT to_charpos, int to_x, int to_y, int to_vpos, int op)
7328 {
7329 enum move_it_result skip, skip2 = MOVE_X_REACHED;
7330 int line_height, line_start_x = 0, reached = 0;
7331
7332 for (;;)
7333 {
7334 if (op & MOVE_TO_VPOS)
7335 {
7336 /* If no TO_CHARPOS and no TO_X specified, stop at the
7337 start of the line TO_VPOS. */
7338 if ((op & (MOVE_TO_X | MOVE_TO_POS)) == 0)
7339 {
7340 if (it->vpos == to_vpos)
7341 {
7342 reached = 1;
7343 break;
7344 }
7345 else
7346 skip = move_it_in_display_line_to (it, -1, -1, 0);
7347 }
7348 else
7349 {
7350 /* TO_VPOS >= 0 means stop at TO_X in the line at
7351 TO_VPOS, or at TO_POS, whichever comes first. */
7352 if (it->vpos == to_vpos)
7353 {
7354 reached = 2;
7355 break;
7356 }
7357
7358 skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
7359
7360 if (skip == MOVE_POS_MATCH_OR_ZV || it->vpos == to_vpos)
7361 {
7362 reached = 3;
7363 break;
7364 }
7365 else if (skip == MOVE_X_REACHED && it->vpos != to_vpos)
7366 {
7367 /* We have reached TO_X but not in the line we want. */
7368 skip = move_it_in_display_line_to (it, to_charpos,
7369 -1, MOVE_TO_POS);
7370 if (skip == MOVE_POS_MATCH_OR_ZV)
7371 {
7372 reached = 4;
7373 break;
7374 }
7375 }
7376 }
7377 }
7378 else if (op & MOVE_TO_Y)
7379 {
7380 struct it it_backup;
7381
7382 if (it->line_wrap == WORD_WRAP)
7383 it_backup = *it;
7384
7385 /* TO_Y specified means stop at TO_X in the line containing
7386 TO_Y---or at TO_CHARPOS if this is reached first. The
7387 problem is that we can't really tell whether the line
7388 contains TO_Y before we have completely scanned it, and
7389 this may skip past TO_X. What we do is to first scan to
7390 TO_X.
7391
7392 If TO_X is not specified, use a TO_X of zero. The reason
7393 is to make the outcome of this function more predictable.
7394 If we didn't use TO_X == 0, we would stop at the end of
7395 the line which is probably not what a caller would expect
7396 to happen. */
7397 skip = move_it_in_display_line_to
7398 (it, to_charpos, ((op & MOVE_TO_X) ? to_x : 0),
7399 (MOVE_TO_X | (op & MOVE_TO_POS)));
7400
7401 /* If TO_CHARPOS is reached or ZV, we don't have to do more. */
7402 if (skip == MOVE_POS_MATCH_OR_ZV)
7403 reached = 5;
7404 else if (skip == MOVE_X_REACHED)
7405 {
7406 /* If TO_X was reached, we want to know whether TO_Y is
7407 in the line. We know this is the case if the already
7408 scanned glyphs make the line tall enough. Otherwise,
7409 we must check by scanning the rest of the line. */
7410 line_height = it->max_ascent + it->max_descent;
7411 if (to_y >= it->current_y
7412 && to_y < it->current_y + line_height)
7413 {
7414 reached = 6;
7415 break;
7416 }
7417 it_backup = *it;
7418 TRACE_MOVE ((stderr, "move_it: from %d\n", IT_CHARPOS (*it)));
7419 skip2 = move_it_in_display_line_to (it, to_charpos, -1,
7420 op & MOVE_TO_POS);
7421 TRACE_MOVE ((stderr, "move_it: to %d\n", IT_CHARPOS (*it)));
7422 line_height = it->max_ascent + it->max_descent;
7423 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
7424
7425 if (to_y >= it->current_y
7426 && to_y < it->current_y + line_height)
7427 {
7428 /* If TO_Y is in this line and TO_X was reached
7429 above, we scanned too far. We have to restore
7430 IT's settings to the ones before skipping. */
7431 *it = it_backup;
7432 reached = 6;
7433 }
7434 else
7435 {
7436 skip = skip2;
7437 if (skip == MOVE_POS_MATCH_OR_ZV)
7438 reached = 7;
7439 }
7440 }
7441 else
7442 {
7443 /* Check whether TO_Y is in this line. */
7444 line_height = it->max_ascent + it->max_descent;
7445 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
7446
7447 if (to_y >= it->current_y
7448 && to_y < it->current_y + line_height)
7449 {
7450 /* When word-wrap is on, TO_X may lie past the end
7451 of a wrapped line. Then it->current is the
7452 character on the next line, so backtrack to the
7453 space before the wrap point. */
7454 if (skip == MOVE_LINE_CONTINUED
7455 && it->line_wrap == WORD_WRAP)
7456 {
7457 int prev_x = max (it->current_x - 1, 0);
7458 *it = it_backup;
7459 skip = move_it_in_display_line_to
7460 (it, -1, prev_x, MOVE_TO_X);
7461 }
7462 reached = 6;
7463 }
7464 }
7465
7466 if (reached)
7467 break;
7468 }
7469 else if (BUFFERP (it->object)
7470 && (it->method == GET_FROM_BUFFER
7471 || it->method == GET_FROM_STRETCH)
7472 && IT_CHARPOS (*it) >= to_charpos)
7473 skip = MOVE_POS_MATCH_OR_ZV;
7474 else
7475 skip = move_it_in_display_line_to (it, to_charpos, -1, MOVE_TO_POS);
7476
7477 switch (skip)
7478 {
7479 case MOVE_POS_MATCH_OR_ZV:
7480 reached = 8;
7481 goto out;
7482
7483 case MOVE_NEWLINE_OR_CR:
7484 set_iterator_to_next (it, 1);
7485 it->continuation_lines_width = 0;
7486 break;
7487
7488 case MOVE_LINE_TRUNCATED:
7489 it->continuation_lines_width = 0;
7490 reseat_at_next_visible_line_start (it, 0);
7491 if ((op & MOVE_TO_POS) != 0
7492 && IT_CHARPOS (*it) > to_charpos)
7493 {
7494 reached = 9;
7495 goto out;
7496 }
7497 break;
7498
7499 case MOVE_LINE_CONTINUED:
7500 /* For continued lines ending in a tab, some of the glyphs
7501 associated with the tab are displayed on the current
7502 line. Since it->current_x does not include these glyphs,
7503 we use it->last_visible_x instead. */
7504 if (it->c == '\t')
7505 {
7506 it->continuation_lines_width += it->last_visible_x;
7507 /* When moving by vpos, ensure that the iterator really
7508 advances to the next line (bug#847, bug#969). Fixme:
7509 do we need to do this in other circumstances? */
7510 if (it->current_x != it->last_visible_x
7511 && (op & MOVE_TO_VPOS)
7512 && !(op & (MOVE_TO_X | MOVE_TO_POS)))
7513 {
7514 line_start_x = it->current_x + it->pixel_width
7515 - it->last_visible_x;
7516 set_iterator_to_next (it, 0);
7517 }
7518 }
7519 else
7520 it->continuation_lines_width += it->current_x;
7521 break;
7522
7523 default:
7524 abort ();
7525 }
7526
7527 /* Reset/increment for the next run. */
7528 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
7529 it->current_x = line_start_x;
7530 line_start_x = 0;
7531 it->hpos = 0;
7532 it->current_y += it->max_ascent + it->max_descent;
7533 ++it->vpos;
7534 last_height = it->max_ascent + it->max_descent;
7535 last_max_ascent = it->max_ascent;
7536 it->max_ascent = it->max_descent = 0;
7537 }
7538
7539 out:
7540
7541 /* On text terminals, we may stop at the end of a line in the middle
7542 of a multi-character glyph. If the glyph itself is continued,
7543 i.e. it is actually displayed on the next line, don't treat this
7544 stopping point as valid; move to the next line instead (unless
7545 that brings us offscreen). */
7546 if (!FRAME_WINDOW_P (it->f)
7547 && op & MOVE_TO_POS
7548 && IT_CHARPOS (*it) == to_charpos
7549 && it->what == IT_CHARACTER
7550 && it->nglyphs > 1
7551 && it->line_wrap == WINDOW_WRAP
7552 && it->current_x == it->last_visible_x - 1
7553 && it->c != '\n'
7554 && it->c != '\t'
7555 && it->vpos < XFASTINT (it->w->window_end_vpos))
7556 {
7557 it->continuation_lines_width += it->current_x;
7558 it->current_x = it->hpos = it->max_ascent = it->max_descent = 0;
7559 it->current_y += it->max_ascent + it->max_descent;
7560 ++it->vpos;
7561 last_height = it->max_ascent + it->max_descent;
7562 last_max_ascent = it->max_ascent;
7563 }
7564
7565 TRACE_MOVE ((stderr, "move_it_to: reached %d\n", reached));
7566 }
7567
7568
7569 /* Move iterator IT backward by a specified y-distance DY, DY >= 0.
7570
7571 If DY > 0, move IT backward at least that many pixels. DY = 0
7572 means move IT backward to the preceding line start or BEGV. This
7573 function may move over more than DY pixels if IT->current_y - DY
7574 ends up in the middle of a line; in this case IT->current_y will be
7575 set to the top of the line moved to. */
7576
7577 void
7578 move_it_vertically_backward (struct it *it, int dy)
7579 {
7580 int nlines, h;
7581 struct it it2, it3;
7582 EMACS_INT start_pos;
7583
7584 move_further_back:
7585 xassert (dy >= 0);
7586
7587 start_pos = IT_CHARPOS (*it);
7588
7589 /* Estimate how many newlines we must move back. */
7590 nlines = max (1, dy / FRAME_LINE_HEIGHT (it->f));
7591
7592 /* Set the iterator's position that many lines back. */
7593 while (nlines-- && IT_CHARPOS (*it) > BEGV)
7594 back_to_previous_visible_line_start (it);
7595
7596 /* Reseat the iterator here. When moving backward, we don't want
7597 reseat to skip forward over invisible text, set up the iterator
7598 to deliver from overlay strings at the new position etc. So,
7599 use reseat_1 here. */
7600 reseat_1 (it, it->current.pos, 1);
7601
7602 /* We are now surely at a line start. */
7603 it->current_x = it->hpos = 0;
7604 it->continuation_lines_width = 0;
7605
7606 /* Move forward and see what y-distance we moved. First move to the
7607 start of the next line so that we get its height. We need this
7608 height to be able to tell whether we reached the specified
7609 y-distance. */
7610 it2 = *it;
7611 it2.max_ascent = it2.max_descent = 0;
7612 do
7613 {
7614 move_it_to (&it2, start_pos, -1, -1, it2.vpos + 1,
7615 MOVE_TO_POS | MOVE_TO_VPOS);
7616 }
7617 while (!IT_POS_VALID_AFTER_MOVE_P (&it2));
7618 xassert (IT_CHARPOS (*it) >= BEGV);
7619 it3 = it2;
7620
7621 move_it_to (&it2, start_pos, -1, -1, -1, MOVE_TO_POS);
7622 xassert (IT_CHARPOS (*it) >= BEGV);
7623 /* H is the actual vertical distance from the position in *IT
7624 and the starting position. */
7625 h = it2.current_y - it->current_y;
7626 /* NLINES is the distance in number of lines. */
7627 nlines = it2.vpos - it->vpos;
7628
7629 /* Correct IT's y and vpos position
7630 so that they are relative to the starting point. */
7631 it->vpos -= nlines;
7632 it->current_y -= h;
7633
7634 if (dy == 0)
7635 {
7636 /* DY == 0 means move to the start of the screen line. The
7637 value of nlines is > 0 if continuation lines were involved. */
7638 if (nlines > 0)
7639 move_it_by_lines (it, nlines);
7640 }
7641 else
7642 {
7643 /* The y-position we try to reach, relative to *IT.
7644 Note that H has been subtracted in front of the if-statement. */
7645 int target_y = it->current_y + h - dy;
7646 int y0 = it3.current_y;
7647 int y1 = line_bottom_y (&it3);
7648 int line_height = y1 - y0;
7649
7650 /* If we did not reach target_y, try to move further backward if
7651 we can. If we moved too far backward, try to move forward. */
7652 if (target_y < it->current_y
7653 /* This is heuristic. In a window that's 3 lines high, with
7654 a line height of 13 pixels each, recentering with point
7655 on the bottom line will try to move -39/2 = 19 pixels
7656 backward. Try to avoid moving into the first line. */
7657 && (it->current_y - target_y
7658 > min (window_box_height (it->w), line_height * 2 / 3))
7659 && IT_CHARPOS (*it) > BEGV)
7660 {
7661 TRACE_MOVE ((stderr, " not far enough -> move_vert %d\n",
7662 target_y - it->current_y));
7663 dy = it->current_y - target_y;
7664 goto move_further_back;
7665 }
7666 else if (target_y >= it->current_y + line_height
7667 && IT_CHARPOS (*it) < ZV)
7668 {
7669 /* Should move forward by at least one line, maybe more.
7670
7671 Note: Calling move_it_by_lines can be expensive on
7672 terminal frames, where compute_motion is used (via
7673 vmotion) to do the job, when there are very long lines
7674 and truncate-lines is nil. That's the reason for
7675 treating terminal frames specially here. */
7676
7677 if (!FRAME_WINDOW_P (it->f))
7678 move_it_vertically (it, target_y - (it->current_y + line_height));
7679 else
7680 {
7681 do
7682 {
7683 move_it_by_lines (it, 1);
7684 }
7685 while (target_y >= line_bottom_y (it) && IT_CHARPOS (*it) < ZV);
7686 }
7687 }
7688 }
7689 }
7690
7691
7692 /* Move IT by a specified amount of pixel lines DY. DY negative means
7693 move backwards. DY = 0 means move to start of screen line. At the
7694 end, IT will be on the start of a screen line. */
7695
7696 void
7697 move_it_vertically (struct it *it, int dy)
7698 {
7699 if (dy <= 0)
7700 move_it_vertically_backward (it, -dy);
7701 else
7702 {
7703 TRACE_MOVE ((stderr, "move_it_v: from %d, %d\n", IT_CHARPOS (*it), dy));
7704 move_it_to (it, ZV, -1, it->current_y + dy, -1,
7705 MOVE_TO_POS | MOVE_TO_Y);
7706 TRACE_MOVE ((stderr, "move_it_v: to %d\n", IT_CHARPOS (*it)));
7707
7708 /* If buffer ends in ZV without a newline, move to the start of
7709 the line to satisfy the post-condition. */
7710 if (IT_CHARPOS (*it) == ZV
7711 && ZV > BEGV
7712 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
7713 move_it_by_lines (it, 0);
7714 }
7715 }
7716
7717
7718 /* Move iterator IT past the end of the text line it is in. */
7719
7720 void
7721 move_it_past_eol (struct it *it)
7722 {
7723 enum move_it_result rc;
7724
7725 rc = move_it_in_display_line_to (it, Z, 0, MOVE_TO_POS);
7726 if (rc == MOVE_NEWLINE_OR_CR)
7727 set_iterator_to_next (it, 0);
7728 }
7729
7730
7731 /* Move IT by a specified number DVPOS of screen lines down. DVPOS
7732 negative means move up. DVPOS == 0 means move to the start of the
7733 screen line.
7734
7735 Optimization idea: If we would know that IT->f doesn't use
7736 a face with proportional font, we could be faster for
7737 truncate-lines nil. */
7738
7739 void
7740 move_it_by_lines (struct it *it, int dvpos)
7741 {
7742
7743 /* The commented-out optimization uses vmotion on terminals. This
7744 gives bad results, because elements like it->what, on which
7745 callers such as pos_visible_p rely, aren't updated. */
7746 /* struct position pos;
7747 if (!FRAME_WINDOW_P (it->f))
7748 {
7749 struct text_pos textpos;
7750
7751 pos = *vmotion (IT_CHARPOS (*it), dvpos, it->w);
7752 SET_TEXT_POS (textpos, pos.bufpos, pos.bytepos);
7753 reseat (it, textpos, 1);
7754 it->vpos += pos.vpos;
7755 it->current_y += pos.vpos;
7756 }
7757 else */
7758
7759 if (dvpos == 0)
7760 {
7761 /* DVPOS == 0 means move to the start of the screen line. */
7762 move_it_vertically_backward (it, 0);
7763 xassert (it->current_x == 0 && it->hpos == 0);
7764 /* Let next call to line_bottom_y calculate real line height */
7765 last_height = 0;
7766 }
7767 else if (dvpos > 0)
7768 {
7769 move_it_to (it, -1, -1, -1, it->vpos + dvpos, MOVE_TO_VPOS);
7770 if (!IT_POS_VALID_AFTER_MOVE_P (it))
7771 move_it_to (it, IT_CHARPOS (*it) + 1, -1, -1, -1, MOVE_TO_POS);
7772 }
7773 else
7774 {
7775 struct it it2;
7776 EMACS_INT start_charpos, i;
7777
7778 /* Start at the beginning of the screen line containing IT's
7779 position. This may actually move vertically backwards,
7780 in case of overlays, so adjust dvpos accordingly. */
7781 dvpos += it->vpos;
7782 move_it_vertically_backward (it, 0);
7783 dvpos -= it->vpos;
7784
7785 /* Go back -DVPOS visible lines and reseat the iterator there. */
7786 start_charpos = IT_CHARPOS (*it);
7787 for (i = -dvpos; i > 0 && IT_CHARPOS (*it) > BEGV; --i)
7788 back_to_previous_visible_line_start (it);
7789 reseat (it, it->current.pos, 1);
7790
7791 /* Move further back if we end up in a string or an image. */
7792 while (!IT_POS_VALID_AFTER_MOVE_P (it))
7793 {
7794 /* First try to move to start of display line. */
7795 dvpos += it->vpos;
7796 move_it_vertically_backward (it, 0);
7797 dvpos -= it->vpos;
7798 if (IT_POS_VALID_AFTER_MOVE_P (it))
7799 break;
7800 /* If start of line is still in string or image,
7801 move further back. */
7802 back_to_previous_visible_line_start (it);
7803 reseat (it, it->current.pos, 1);
7804 dvpos--;
7805 }
7806
7807 it->current_x = it->hpos = 0;
7808
7809 /* Above call may have moved too far if continuation lines
7810 are involved. Scan forward and see if it did. */
7811 it2 = *it;
7812 it2.vpos = it2.current_y = 0;
7813 move_it_to (&it2, start_charpos, -1, -1, -1, MOVE_TO_POS);
7814 it->vpos -= it2.vpos;
7815 it->current_y -= it2.current_y;
7816 it->current_x = it->hpos = 0;
7817
7818 /* If we moved too far back, move IT some lines forward. */
7819 if (it2.vpos > -dvpos)
7820 {
7821 int delta = it2.vpos + dvpos;
7822 it2 = *it;
7823 move_it_to (it, -1, -1, -1, it->vpos + delta, MOVE_TO_VPOS);
7824 /* Move back again if we got too far ahead. */
7825 if (IT_CHARPOS (*it) >= start_charpos)
7826 *it = it2;
7827 }
7828 }
7829 }
7830
7831 /* Return 1 if IT points into the middle of a display vector. */
7832
7833 int
7834 in_display_vector_p (struct it *it)
7835 {
7836 return (it->method == GET_FROM_DISPLAY_VECTOR
7837 && it->current.dpvec_index > 0
7838 && it->dpvec + it->current.dpvec_index != it->dpend);
7839 }
7840
7841 \f
7842 /***********************************************************************
7843 Messages
7844 ***********************************************************************/
7845
7846
7847 /* Add a message with format string FORMAT and arguments ARG1 and ARG2
7848 to *Messages*. */
7849
7850 void
7851 add_to_log (const char *format, Lisp_Object arg1, Lisp_Object arg2)
7852 {
7853 Lisp_Object args[3];
7854 Lisp_Object msg, fmt;
7855 char *buffer;
7856 EMACS_INT len;
7857 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
7858 USE_SAFE_ALLOCA;
7859
7860 /* Do nothing if called asynchronously. Inserting text into
7861 a buffer may call after-change-functions and alike and
7862 that would means running Lisp asynchronously. */
7863 if (handling_signal)
7864 return;
7865
7866 fmt = msg = Qnil;
7867 GCPRO4 (fmt, msg, arg1, arg2);
7868
7869 args[0] = fmt = build_string (format);
7870 args[1] = arg1;
7871 args[2] = arg2;
7872 msg = Fformat (3, args);
7873
7874 len = SBYTES (msg) + 1;
7875 SAFE_ALLOCA (buffer, char *, len);
7876 memcpy (buffer, SDATA (msg), len);
7877
7878 message_dolog (buffer, len - 1, 1, 0);
7879 SAFE_FREE ();
7880
7881 UNGCPRO;
7882 }
7883
7884
7885 /* Output a newline in the *Messages* buffer if "needs" one. */
7886
7887 void
7888 message_log_maybe_newline (void)
7889 {
7890 if (message_log_need_newline)
7891 message_dolog ("", 0, 1, 0);
7892 }
7893
7894
7895 /* Add a string M of length NBYTES to the message log, optionally
7896 terminated with a newline when NLFLAG is non-zero. MULTIBYTE, if
7897 nonzero, means interpret the contents of M as multibyte. This
7898 function calls low-level routines in order to bypass text property
7899 hooks, etc. which might not be safe to run.
7900
7901 This may GC (insert may run before/after change hooks),
7902 so the buffer M must NOT point to a Lisp string. */
7903
7904 void
7905 message_dolog (const char *m, EMACS_INT nbytes, int nlflag, int multibyte)
7906 {
7907 const unsigned char *msg = (const unsigned char *) m;
7908
7909 if (!NILP (Vmemory_full))
7910 return;
7911
7912 if (!NILP (Vmessage_log_max))
7913 {
7914 struct buffer *oldbuf;
7915 Lisp_Object oldpoint, oldbegv, oldzv;
7916 int old_windows_or_buffers_changed = windows_or_buffers_changed;
7917 EMACS_INT point_at_end = 0;
7918 EMACS_INT zv_at_end = 0;
7919 Lisp_Object old_deactivate_mark, tem;
7920 struct gcpro gcpro1;
7921
7922 old_deactivate_mark = Vdeactivate_mark;
7923 oldbuf = current_buffer;
7924 Fset_buffer (Fget_buffer_create (Vmessages_buffer_name));
7925 BVAR (current_buffer, undo_list) = Qt;
7926
7927 oldpoint = message_dolog_marker1;
7928 set_marker_restricted (oldpoint, make_number (PT), Qnil);
7929 oldbegv = message_dolog_marker2;
7930 set_marker_restricted (oldbegv, make_number (BEGV), Qnil);
7931 oldzv = message_dolog_marker3;
7932 set_marker_restricted (oldzv, make_number (ZV), Qnil);
7933 GCPRO1 (old_deactivate_mark);
7934
7935 if (PT == Z)
7936 point_at_end = 1;
7937 if (ZV == Z)
7938 zv_at_end = 1;
7939
7940 BEGV = BEG;
7941 BEGV_BYTE = BEG_BYTE;
7942 ZV = Z;
7943 ZV_BYTE = Z_BYTE;
7944 TEMP_SET_PT_BOTH (Z, Z_BYTE);
7945
7946 /* Insert the string--maybe converting multibyte to single byte
7947 or vice versa, so that all the text fits the buffer. */
7948 if (multibyte
7949 && NILP (BVAR (current_buffer, enable_multibyte_characters)))
7950 {
7951 EMACS_INT i;
7952 int c, char_bytes;
7953 char work[1];
7954
7955 /* Convert a multibyte string to single-byte
7956 for the *Message* buffer. */
7957 for (i = 0; i < nbytes; i += char_bytes)
7958 {
7959 c = string_char_and_length (msg + i, &char_bytes);
7960 work[0] = (ASCII_CHAR_P (c)
7961 ? c
7962 : multibyte_char_to_unibyte (c));
7963 insert_1_both (work, 1, 1, 1, 0, 0);
7964 }
7965 }
7966 else if (! multibyte
7967 && ! NILP (BVAR (current_buffer, enable_multibyte_characters)))
7968 {
7969 EMACS_INT i;
7970 int c, char_bytes;
7971 unsigned char str[MAX_MULTIBYTE_LENGTH];
7972 /* Convert a single-byte string to multibyte
7973 for the *Message* buffer. */
7974 for (i = 0; i < nbytes; i++)
7975 {
7976 c = msg[i];
7977 MAKE_CHAR_MULTIBYTE (c);
7978 char_bytes = CHAR_STRING (c, str);
7979 insert_1_both ((char *) str, 1, char_bytes, 1, 0, 0);
7980 }
7981 }
7982 else if (nbytes)
7983 insert_1 (m, nbytes, 1, 0, 0);
7984
7985 if (nlflag)
7986 {
7987 EMACS_INT this_bol, this_bol_byte, prev_bol, prev_bol_byte;
7988 unsigned long int dups;
7989 insert_1 ("\n", 1, 1, 0, 0);
7990
7991 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE, -2, 0);
7992 this_bol = PT;
7993 this_bol_byte = PT_BYTE;
7994
7995 /* See if this line duplicates the previous one.
7996 If so, combine duplicates. */
7997 if (this_bol > BEG)
7998 {
7999 scan_newline (PT, PT_BYTE, BEG, BEG_BYTE, -2, 0);
8000 prev_bol = PT;
8001 prev_bol_byte = PT_BYTE;
8002
8003 dups = message_log_check_duplicate (prev_bol_byte,
8004 this_bol_byte);
8005 if (dups)
8006 {
8007 del_range_both (prev_bol, prev_bol_byte,
8008 this_bol, this_bol_byte, 0);
8009 if (dups > 1)
8010 {
8011 char dupstr[40];
8012 int duplen;
8013
8014 /* If you change this format, don't forget to also
8015 change message_log_check_duplicate. */
8016 sprintf (dupstr, " [%lu times]", dups);
8017 duplen = strlen (dupstr);
8018 TEMP_SET_PT_BOTH (Z - 1, Z_BYTE - 1);
8019 insert_1 (dupstr, duplen, 1, 0, 1);
8020 }
8021 }
8022 }
8023
8024 /* If we have more than the desired maximum number of lines
8025 in the *Messages* buffer now, delete the oldest ones.
8026 This is safe because we don't have undo in this buffer. */
8027
8028 if (NATNUMP (Vmessage_log_max))
8029 {
8030 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE,
8031 -XFASTINT (Vmessage_log_max) - 1, 0);
8032 del_range_both (BEG, BEG_BYTE, PT, PT_BYTE, 0);
8033 }
8034 }
8035 BEGV = XMARKER (oldbegv)->charpos;
8036 BEGV_BYTE = marker_byte_position (oldbegv);
8037
8038 if (zv_at_end)
8039 {
8040 ZV = Z;
8041 ZV_BYTE = Z_BYTE;
8042 }
8043 else
8044 {
8045 ZV = XMARKER (oldzv)->charpos;
8046 ZV_BYTE = marker_byte_position (oldzv);
8047 }
8048
8049 if (point_at_end)
8050 TEMP_SET_PT_BOTH (Z, Z_BYTE);
8051 else
8052 /* We can't do Fgoto_char (oldpoint) because it will run some
8053 Lisp code. */
8054 TEMP_SET_PT_BOTH (XMARKER (oldpoint)->charpos,
8055 XMARKER (oldpoint)->bytepos);
8056
8057 UNGCPRO;
8058 unchain_marker (XMARKER (oldpoint));
8059 unchain_marker (XMARKER (oldbegv));
8060 unchain_marker (XMARKER (oldzv));
8061
8062 tem = Fget_buffer_window (Fcurrent_buffer (), Qt);
8063 set_buffer_internal (oldbuf);
8064 if (NILP (tem))
8065 windows_or_buffers_changed = old_windows_or_buffers_changed;
8066 message_log_need_newline = !nlflag;
8067 Vdeactivate_mark = old_deactivate_mark;
8068 }
8069 }
8070
8071
8072 /* We are at the end of the buffer after just having inserted a newline.
8073 (Note: We depend on the fact we won't be crossing the gap.)
8074 Check to see if the most recent message looks a lot like the previous one.
8075 Return 0 if different, 1 if the new one should just replace it, or a
8076 value N > 1 if we should also append " [N times]". */
8077
8078 static unsigned long int
8079 message_log_check_duplicate (EMACS_INT prev_bol_byte, EMACS_INT this_bol_byte)
8080 {
8081 EMACS_INT i;
8082 EMACS_INT len = Z_BYTE - 1 - this_bol_byte;
8083 int seen_dots = 0;
8084 unsigned char *p1 = BUF_BYTE_ADDRESS (current_buffer, prev_bol_byte);
8085 unsigned char *p2 = BUF_BYTE_ADDRESS (current_buffer, this_bol_byte);
8086
8087 for (i = 0; i < len; i++)
8088 {
8089 if (i >= 3 && p1[i-3] == '.' && p1[i-2] == '.' && p1[i-1] == '.')
8090 seen_dots = 1;
8091 if (p1[i] != p2[i])
8092 return seen_dots;
8093 }
8094 p1 += len;
8095 if (*p1 == '\n')
8096 return 2;
8097 if (*p1++ == ' ' && *p1++ == '[')
8098 {
8099 char *pend;
8100 unsigned long int n = strtoul ((char *) p1, &pend, 10);
8101 if (strncmp (pend, " times]\n", 8) == 0)
8102 return n+1;
8103 }
8104 return 0;
8105 }
8106 \f
8107
8108 /* Display an echo area message M with a specified length of NBYTES
8109 bytes. The string may include null characters. If M is 0, clear
8110 out any existing message, and let the mini-buffer text show
8111 through.
8112
8113 This may GC, so the buffer M must NOT point to a Lisp string. */
8114
8115 void
8116 message2 (const char *m, EMACS_INT nbytes, int multibyte)
8117 {
8118 /* First flush out any partial line written with print. */
8119 message_log_maybe_newline ();
8120 if (m)
8121 message_dolog (m, nbytes, 1, multibyte);
8122 message2_nolog (m, nbytes, multibyte);
8123 }
8124
8125
8126 /* The non-logging counterpart of message2. */
8127
8128 void
8129 message2_nolog (const char *m, EMACS_INT nbytes, int multibyte)
8130 {
8131 struct frame *sf = SELECTED_FRAME ();
8132 message_enable_multibyte = multibyte;
8133
8134 if (FRAME_INITIAL_P (sf))
8135 {
8136 if (noninteractive_need_newline)
8137 putc ('\n', stderr);
8138 noninteractive_need_newline = 0;
8139 if (m)
8140 fwrite (m, nbytes, 1, stderr);
8141 if (cursor_in_echo_area == 0)
8142 fprintf (stderr, "\n");
8143 fflush (stderr);
8144 }
8145 /* A null message buffer means that the frame hasn't really been
8146 initialized yet. Error messages get reported properly by
8147 cmd_error, so this must be just an informative message; toss it. */
8148 else if (INTERACTIVE
8149 && sf->glyphs_initialized_p
8150 && FRAME_MESSAGE_BUF (sf))
8151 {
8152 Lisp_Object mini_window;
8153 struct frame *f;
8154
8155 /* Get the frame containing the mini-buffer
8156 that the selected frame is using. */
8157 mini_window = FRAME_MINIBUF_WINDOW (sf);
8158 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
8159
8160 FRAME_SAMPLE_VISIBILITY (f);
8161 if (FRAME_VISIBLE_P (sf)
8162 && ! FRAME_VISIBLE_P (f))
8163 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (mini_window)));
8164
8165 if (m)
8166 {
8167 set_message (m, Qnil, nbytes, multibyte);
8168 if (minibuffer_auto_raise)
8169 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
8170 }
8171 else
8172 clear_message (1, 1);
8173
8174 do_pending_window_change (0);
8175 echo_area_display (1);
8176 do_pending_window_change (0);
8177 if (FRAME_TERMINAL (f)->frame_up_to_date_hook != 0 && ! gc_in_progress)
8178 (*FRAME_TERMINAL (f)->frame_up_to_date_hook) (f);
8179 }
8180 }
8181
8182
8183 /* Display an echo area message M with a specified length of NBYTES
8184 bytes. The string may include null characters. If M is not a
8185 string, clear out any existing message, and let the mini-buffer
8186 text show through.
8187
8188 This function cancels echoing. */
8189
8190 void
8191 message3 (Lisp_Object m, EMACS_INT nbytes, int multibyte)
8192 {
8193 struct gcpro gcpro1;
8194
8195 GCPRO1 (m);
8196 clear_message (1,1);
8197 cancel_echoing ();
8198
8199 /* First flush out any partial line written with print. */
8200 message_log_maybe_newline ();
8201 if (STRINGP (m))
8202 {
8203 char *buffer;
8204 USE_SAFE_ALLOCA;
8205
8206 SAFE_ALLOCA (buffer, char *, nbytes);
8207 memcpy (buffer, SDATA (m), nbytes);
8208 message_dolog (buffer, nbytes, 1, multibyte);
8209 SAFE_FREE ();
8210 }
8211 message3_nolog (m, nbytes, multibyte);
8212
8213 UNGCPRO;
8214 }
8215
8216
8217 /* The non-logging version of message3.
8218 This does not cancel echoing, because it is used for echoing.
8219 Perhaps we need to make a separate function for echoing
8220 and make this cancel echoing. */
8221
8222 void
8223 message3_nolog (Lisp_Object m, EMACS_INT nbytes, int multibyte)
8224 {
8225 struct frame *sf = SELECTED_FRAME ();
8226 message_enable_multibyte = multibyte;
8227
8228 if (FRAME_INITIAL_P (sf))
8229 {
8230 if (noninteractive_need_newline)
8231 putc ('\n', stderr);
8232 noninteractive_need_newline = 0;
8233 if (STRINGP (m))
8234 fwrite (SDATA (m), nbytes, 1, stderr);
8235 if (cursor_in_echo_area == 0)
8236 fprintf (stderr, "\n");
8237 fflush (stderr);
8238 }
8239 /* A null message buffer means that the frame hasn't really been
8240 initialized yet. Error messages get reported properly by
8241 cmd_error, so this must be just an informative message; toss it. */
8242 else if (INTERACTIVE
8243 && sf->glyphs_initialized_p
8244 && FRAME_MESSAGE_BUF (sf))
8245 {
8246 Lisp_Object mini_window;
8247 Lisp_Object frame;
8248 struct frame *f;
8249
8250 /* Get the frame containing the mini-buffer
8251 that the selected frame is using. */
8252 mini_window = FRAME_MINIBUF_WINDOW (sf);
8253 frame = XWINDOW (mini_window)->frame;
8254 f = XFRAME (frame);
8255
8256 FRAME_SAMPLE_VISIBILITY (f);
8257 if (FRAME_VISIBLE_P (sf)
8258 && !FRAME_VISIBLE_P (f))
8259 Fmake_frame_visible (frame);
8260
8261 if (STRINGP (m) && SCHARS (m) > 0)
8262 {
8263 set_message (NULL, m, nbytes, multibyte);
8264 if (minibuffer_auto_raise)
8265 Fraise_frame (frame);
8266 /* Assume we are not echoing.
8267 (If we are, echo_now will override this.) */
8268 echo_message_buffer = Qnil;
8269 }
8270 else
8271 clear_message (1, 1);
8272
8273 do_pending_window_change (0);
8274 echo_area_display (1);
8275 do_pending_window_change (0);
8276 if (FRAME_TERMINAL (f)->frame_up_to_date_hook != 0 && ! gc_in_progress)
8277 (*FRAME_TERMINAL (f)->frame_up_to_date_hook) (f);
8278 }
8279 }
8280
8281
8282 /* Display a null-terminated echo area message M. If M is 0, clear
8283 out any existing message, and let the mini-buffer text show through.
8284
8285 The buffer M must continue to exist until after the echo area gets
8286 cleared or some other message gets displayed there. Do not pass
8287 text that is stored in a Lisp string. Do not pass text in a buffer
8288 that was alloca'd. */
8289
8290 void
8291 message1 (const char *m)
8292 {
8293 message2 (m, (m ? strlen (m) : 0), 0);
8294 }
8295
8296
8297 /* The non-logging counterpart of message1. */
8298
8299 void
8300 message1_nolog (const char *m)
8301 {
8302 message2_nolog (m, (m ? strlen (m) : 0), 0);
8303 }
8304
8305 /* Display a message M which contains a single %s
8306 which gets replaced with STRING. */
8307
8308 void
8309 message_with_string (const char *m, Lisp_Object string, int log)
8310 {
8311 CHECK_STRING (string);
8312
8313 if (noninteractive)
8314 {
8315 if (m)
8316 {
8317 if (noninteractive_need_newline)
8318 putc ('\n', stderr);
8319 noninteractive_need_newline = 0;
8320 fprintf (stderr, m, SDATA (string));
8321 if (!cursor_in_echo_area)
8322 fprintf (stderr, "\n");
8323 fflush (stderr);
8324 }
8325 }
8326 else if (INTERACTIVE)
8327 {
8328 /* The frame whose minibuffer we're going to display the message on.
8329 It may be larger than the selected frame, so we need
8330 to use its buffer, not the selected frame's buffer. */
8331 Lisp_Object mini_window;
8332 struct frame *f, *sf = SELECTED_FRAME ();
8333
8334 /* Get the frame containing the minibuffer
8335 that the selected frame is using. */
8336 mini_window = FRAME_MINIBUF_WINDOW (sf);
8337 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
8338
8339 /* A null message buffer means that the frame hasn't really been
8340 initialized yet. Error messages get reported properly by
8341 cmd_error, so this must be just an informative message; toss it. */
8342 if (FRAME_MESSAGE_BUF (f))
8343 {
8344 Lisp_Object args[2], msg;
8345 struct gcpro gcpro1, gcpro2;
8346
8347 args[0] = build_string (m);
8348 args[1] = msg = string;
8349 GCPRO2 (args[0], msg);
8350 gcpro1.nvars = 2;
8351
8352 msg = Fformat (2, args);
8353
8354 if (log)
8355 message3 (msg, SBYTES (msg), STRING_MULTIBYTE (msg));
8356 else
8357 message3_nolog (msg, SBYTES (msg), STRING_MULTIBYTE (msg));
8358
8359 UNGCPRO;
8360
8361 /* Print should start at the beginning of the message
8362 buffer next time. */
8363 message_buf_print = 0;
8364 }
8365 }
8366 }
8367
8368
8369 /* Dump an informative message to the minibuf. If M is 0, clear out
8370 any existing message, and let the mini-buffer text show through. */
8371
8372 static void
8373 vmessage (const char *m, va_list ap)
8374 {
8375 if (noninteractive)
8376 {
8377 if (m)
8378 {
8379 if (noninteractive_need_newline)
8380 putc ('\n', stderr);
8381 noninteractive_need_newline = 0;
8382 vfprintf (stderr, m, ap);
8383 if (cursor_in_echo_area == 0)
8384 fprintf (stderr, "\n");
8385 fflush (stderr);
8386 }
8387 }
8388 else if (INTERACTIVE)
8389 {
8390 /* The frame whose mini-buffer we're going to display the message
8391 on. It may be larger than the selected frame, so we need to
8392 use its buffer, not the selected frame's buffer. */
8393 Lisp_Object mini_window;
8394 struct frame *f, *sf = SELECTED_FRAME ();
8395
8396 /* Get the frame containing the mini-buffer
8397 that the selected frame is using. */
8398 mini_window = FRAME_MINIBUF_WINDOW (sf);
8399 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
8400
8401 /* A null message buffer means that the frame hasn't really been
8402 initialized yet. Error messages get reported properly by
8403 cmd_error, so this must be just an informative message; toss
8404 it. */
8405 if (FRAME_MESSAGE_BUF (f))
8406 {
8407 if (m)
8408 {
8409 EMACS_INT len;
8410
8411 len = doprnt (FRAME_MESSAGE_BUF (f),
8412 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, ap);
8413
8414 message2 (FRAME_MESSAGE_BUF (f), len, 0);
8415 }
8416 else
8417 message1 (0);
8418
8419 /* Print should start at the beginning of the message
8420 buffer next time. */
8421 message_buf_print = 0;
8422 }
8423 }
8424 }
8425
8426 void
8427 message (const char *m, ...)
8428 {
8429 va_list ap;
8430 va_start (ap, m);
8431 vmessage (m, ap);
8432 va_end (ap);
8433 }
8434
8435
8436 /* The non-logging version of message. */
8437
8438 void
8439 message_nolog (const char *m, ...)
8440 {
8441 Lisp_Object old_log_max;
8442 va_list ap;
8443 va_start (ap, m);
8444 old_log_max = Vmessage_log_max;
8445 Vmessage_log_max = Qnil;
8446 vmessage (m, ap);
8447 Vmessage_log_max = old_log_max;
8448 va_end (ap);
8449 }
8450
8451
8452 /* Display the current message in the current mini-buffer. This is
8453 only called from error handlers in process.c, and is not time
8454 critical. */
8455
8456 void
8457 update_echo_area (void)
8458 {
8459 if (!NILP (echo_area_buffer[0]))
8460 {
8461 Lisp_Object string;
8462 string = Fcurrent_message ();
8463 message3 (string, SBYTES (string),
8464 !NILP (BVAR (current_buffer, enable_multibyte_characters)));
8465 }
8466 }
8467
8468
8469 /* Make sure echo area buffers in `echo_buffers' are live.
8470 If they aren't, make new ones. */
8471
8472 static void
8473 ensure_echo_area_buffers (void)
8474 {
8475 int i;
8476
8477 for (i = 0; i < 2; ++i)
8478 if (!BUFFERP (echo_buffer[i])
8479 || NILP (BVAR (XBUFFER (echo_buffer[i]), name)))
8480 {
8481 char name[30];
8482 Lisp_Object old_buffer;
8483 int j;
8484
8485 old_buffer = echo_buffer[i];
8486 sprintf (name, " *Echo Area %d*", i);
8487 echo_buffer[i] = Fget_buffer_create (build_string (name));
8488 BVAR (XBUFFER (echo_buffer[i]), truncate_lines) = Qnil;
8489 /* to force word wrap in echo area -
8490 it was decided to postpone this*/
8491 /* XBUFFER (echo_buffer[i])->word_wrap = Qt; */
8492
8493 for (j = 0; j < 2; ++j)
8494 if (EQ (old_buffer, echo_area_buffer[j]))
8495 echo_area_buffer[j] = echo_buffer[i];
8496 }
8497 }
8498
8499
8500 /* Call FN with args A1..A4 with either the current or last displayed
8501 echo_area_buffer as current buffer.
8502
8503 WHICH zero means use the current message buffer
8504 echo_area_buffer[0]. If that is nil, choose a suitable buffer
8505 from echo_buffer[] and clear it.
8506
8507 WHICH > 0 means use echo_area_buffer[1]. If that is nil, choose a
8508 suitable buffer from echo_buffer[] and clear it.
8509
8510 If WHICH < 0, set echo_area_buffer[1] to echo_area_buffer[0], so
8511 that the current message becomes the last displayed one, make
8512 choose a suitable buffer for echo_area_buffer[0], and clear it.
8513
8514 Value is what FN returns. */
8515
8516 static int
8517 with_echo_area_buffer (struct window *w, int which,
8518 int (*fn) (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT),
8519 EMACS_INT a1, Lisp_Object a2, EMACS_INT a3, EMACS_INT a4)
8520 {
8521 Lisp_Object buffer;
8522 int this_one, the_other, clear_buffer_p, rc;
8523 int count = SPECPDL_INDEX ();
8524
8525 /* If buffers aren't live, make new ones. */
8526 ensure_echo_area_buffers ();
8527
8528 clear_buffer_p = 0;
8529
8530 if (which == 0)
8531 this_one = 0, the_other = 1;
8532 else if (which > 0)
8533 this_one = 1, the_other = 0;
8534 else
8535 {
8536 this_one = 0, the_other = 1;
8537 clear_buffer_p = 1;
8538
8539 /* We need a fresh one in case the current echo buffer equals
8540 the one containing the last displayed echo area message. */
8541 if (!NILP (echo_area_buffer[this_one])
8542 && EQ (echo_area_buffer[this_one], echo_area_buffer[the_other]))
8543 echo_area_buffer[this_one] = Qnil;
8544 }
8545
8546 /* Choose a suitable buffer from echo_buffer[] is we don't
8547 have one. */
8548 if (NILP (echo_area_buffer[this_one]))
8549 {
8550 echo_area_buffer[this_one]
8551 = (EQ (echo_area_buffer[the_other], echo_buffer[this_one])
8552 ? echo_buffer[the_other]
8553 : echo_buffer[this_one]);
8554 clear_buffer_p = 1;
8555 }
8556
8557 buffer = echo_area_buffer[this_one];
8558
8559 /* Don't get confused by reusing the buffer used for echoing
8560 for a different purpose. */
8561 if (echo_kboard == NULL && EQ (buffer, echo_message_buffer))
8562 cancel_echoing ();
8563
8564 record_unwind_protect (unwind_with_echo_area_buffer,
8565 with_echo_area_buffer_unwind_data (w));
8566
8567 /* Make the echo area buffer current. Note that for display
8568 purposes, it is not necessary that the displayed window's buffer
8569 == current_buffer, except for text property lookup. So, let's
8570 only set that buffer temporarily here without doing a full
8571 Fset_window_buffer. We must also change w->pointm, though,
8572 because otherwise an assertions in unshow_buffer fails, and Emacs
8573 aborts. */
8574 set_buffer_internal_1 (XBUFFER (buffer));
8575 if (w)
8576 {
8577 w->buffer = buffer;
8578 set_marker_both (w->pointm, buffer, BEG, BEG_BYTE);
8579 }
8580
8581 BVAR (current_buffer, undo_list) = Qt;
8582 BVAR (current_buffer, read_only) = Qnil;
8583 specbind (Qinhibit_read_only, Qt);
8584 specbind (Qinhibit_modification_hooks, Qt);
8585
8586 if (clear_buffer_p && Z > BEG)
8587 del_range (BEG, Z);
8588
8589 xassert (BEGV >= BEG);
8590 xassert (ZV <= Z && ZV >= BEGV);
8591
8592 rc = fn (a1, a2, a3, a4);
8593
8594 xassert (BEGV >= BEG);
8595 xassert (ZV <= Z && ZV >= BEGV);
8596
8597 unbind_to (count, Qnil);
8598 return rc;
8599 }
8600
8601
8602 /* Save state that should be preserved around the call to the function
8603 FN called in with_echo_area_buffer. */
8604
8605 static Lisp_Object
8606 with_echo_area_buffer_unwind_data (struct window *w)
8607 {
8608 int i = 0;
8609 Lisp_Object vector, tmp;
8610
8611 /* Reduce consing by keeping one vector in
8612 Vwith_echo_area_save_vector. */
8613 vector = Vwith_echo_area_save_vector;
8614 Vwith_echo_area_save_vector = Qnil;
8615
8616 if (NILP (vector))
8617 vector = Fmake_vector (make_number (7), Qnil);
8618
8619 XSETBUFFER (tmp, current_buffer); ASET (vector, i, tmp); ++i;
8620 ASET (vector, i, Vdeactivate_mark); ++i;
8621 ASET (vector, i, make_number (windows_or_buffers_changed)); ++i;
8622
8623 if (w)
8624 {
8625 XSETWINDOW (tmp, w); ASET (vector, i, tmp); ++i;
8626 ASET (vector, i, w->buffer); ++i;
8627 ASET (vector, i, make_number (XMARKER (w->pointm)->charpos)); ++i;
8628 ASET (vector, i, make_number (XMARKER (w->pointm)->bytepos)); ++i;
8629 }
8630 else
8631 {
8632 int end = i + 4;
8633 for (; i < end; ++i)
8634 ASET (vector, i, Qnil);
8635 }
8636
8637 xassert (i == ASIZE (vector));
8638 return vector;
8639 }
8640
8641
8642 /* Restore global state from VECTOR which was created by
8643 with_echo_area_buffer_unwind_data. */
8644
8645 static Lisp_Object
8646 unwind_with_echo_area_buffer (Lisp_Object vector)
8647 {
8648 set_buffer_internal_1 (XBUFFER (AREF (vector, 0)));
8649 Vdeactivate_mark = AREF (vector, 1);
8650 windows_or_buffers_changed = XFASTINT (AREF (vector, 2));
8651
8652 if (WINDOWP (AREF (vector, 3)))
8653 {
8654 struct window *w;
8655 Lisp_Object buffer, charpos, bytepos;
8656
8657 w = XWINDOW (AREF (vector, 3));
8658 buffer = AREF (vector, 4);
8659 charpos = AREF (vector, 5);
8660 bytepos = AREF (vector, 6);
8661
8662 w->buffer = buffer;
8663 set_marker_both (w->pointm, buffer,
8664 XFASTINT (charpos), XFASTINT (bytepos));
8665 }
8666
8667 Vwith_echo_area_save_vector = vector;
8668 return Qnil;
8669 }
8670
8671
8672 /* Set up the echo area for use by print functions. MULTIBYTE_P
8673 non-zero means we will print multibyte. */
8674
8675 void
8676 setup_echo_area_for_printing (int multibyte_p)
8677 {
8678 /* If we can't find an echo area any more, exit. */
8679 if (! FRAME_LIVE_P (XFRAME (selected_frame)))
8680 Fkill_emacs (Qnil);
8681
8682 ensure_echo_area_buffers ();
8683
8684 if (!message_buf_print)
8685 {
8686 /* A message has been output since the last time we printed.
8687 Choose a fresh echo area buffer. */
8688 if (EQ (echo_area_buffer[1], echo_buffer[0]))
8689 echo_area_buffer[0] = echo_buffer[1];
8690 else
8691 echo_area_buffer[0] = echo_buffer[0];
8692
8693 /* Switch to that buffer and clear it. */
8694 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
8695 BVAR (current_buffer, truncate_lines) = Qnil;
8696
8697 if (Z > BEG)
8698 {
8699 int count = SPECPDL_INDEX ();
8700 specbind (Qinhibit_read_only, Qt);
8701 /* Note that undo recording is always disabled. */
8702 del_range (BEG, Z);
8703 unbind_to (count, Qnil);
8704 }
8705 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
8706
8707 /* Set up the buffer for the multibyteness we need. */
8708 if (multibyte_p
8709 != !NILP (BVAR (current_buffer, enable_multibyte_characters)))
8710 Fset_buffer_multibyte (multibyte_p ? Qt : Qnil);
8711
8712 /* Raise the frame containing the echo area. */
8713 if (minibuffer_auto_raise)
8714 {
8715 struct frame *sf = SELECTED_FRAME ();
8716 Lisp_Object mini_window;
8717 mini_window = FRAME_MINIBUF_WINDOW (sf);
8718 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
8719 }
8720
8721 message_log_maybe_newline ();
8722 message_buf_print = 1;
8723 }
8724 else
8725 {
8726 if (NILP (echo_area_buffer[0]))
8727 {
8728 if (EQ (echo_area_buffer[1], echo_buffer[0]))
8729 echo_area_buffer[0] = echo_buffer[1];
8730 else
8731 echo_area_buffer[0] = echo_buffer[0];
8732 }
8733
8734 if (current_buffer != XBUFFER (echo_area_buffer[0]))
8735 {
8736 /* Someone switched buffers between print requests. */
8737 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
8738 BVAR (current_buffer, truncate_lines) = Qnil;
8739 }
8740 }
8741 }
8742
8743
8744 /* Display an echo area message in window W. Value is non-zero if W's
8745 height is changed. If display_last_displayed_message_p is
8746 non-zero, display the message that was last displayed, otherwise
8747 display the current message. */
8748
8749 static int
8750 display_echo_area (struct window *w)
8751 {
8752 int i, no_message_p, window_height_changed_p, count;
8753
8754 /* Temporarily disable garbage collections while displaying the echo
8755 area. This is done because a GC can print a message itself.
8756 That message would modify the echo area buffer's contents while a
8757 redisplay of the buffer is going on, and seriously confuse
8758 redisplay. */
8759 count = inhibit_garbage_collection ();
8760
8761 /* If there is no message, we must call display_echo_area_1
8762 nevertheless because it resizes the window. But we will have to
8763 reset the echo_area_buffer in question to nil at the end because
8764 with_echo_area_buffer will sets it to an empty buffer. */
8765 i = display_last_displayed_message_p ? 1 : 0;
8766 no_message_p = NILP (echo_area_buffer[i]);
8767
8768 window_height_changed_p
8769 = with_echo_area_buffer (w, display_last_displayed_message_p,
8770 display_echo_area_1,
8771 (EMACS_INT) w, Qnil, 0, 0);
8772
8773 if (no_message_p)
8774 echo_area_buffer[i] = Qnil;
8775
8776 unbind_to (count, Qnil);
8777 return window_height_changed_p;
8778 }
8779
8780
8781 /* Helper for display_echo_area. Display the current buffer which
8782 contains the current echo area message in window W, a mini-window,
8783 a pointer to which is passed in A1. A2..A4 are currently not used.
8784 Change the height of W so that all of the message is displayed.
8785 Value is non-zero if height of W was changed. */
8786
8787 static int
8788 display_echo_area_1 (EMACS_INT a1, Lisp_Object a2, EMACS_INT a3, EMACS_INT a4)
8789 {
8790 struct window *w = (struct window *) a1;
8791 Lisp_Object window;
8792 struct text_pos start;
8793 int window_height_changed_p = 0;
8794
8795 /* Do this before displaying, so that we have a large enough glyph
8796 matrix for the display. If we can't get enough space for the
8797 whole text, display the last N lines. That works by setting w->start. */
8798 window_height_changed_p = resize_mini_window (w, 0);
8799
8800 /* Use the starting position chosen by resize_mini_window. */
8801 SET_TEXT_POS_FROM_MARKER (start, w->start);
8802
8803 /* Display. */
8804 clear_glyph_matrix (w->desired_matrix);
8805 XSETWINDOW (window, w);
8806 try_window (window, start, 0);
8807
8808 return window_height_changed_p;
8809 }
8810
8811
8812 /* Resize the echo area window to exactly the size needed for the
8813 currently displayed message, if there is one. If a mini-buffer
8814 is active, don't shrink it. */
8815
8816 void
8817 resize_echo_area_exactly (void)
8818 {
8819 if (BUFFERP (echo_area_buffer[0])
8820 && WINDOWP (echo_area_window))
8821 {
8822 struct window *w = XWINDOW (echo_area_window);
8823 int resized_p;
8824 Lisp_Object resize_exactly;
8825
8826 if (minibuf_level == 0)
8827 resize_exactly = Qt;
8828 else
8829 resize_exactly = Qnil;
8830
8831 resized_p = with_echo_area_buffer (w, 0, resize_mini_window_1,
8832 (EMACS_INT) w, resize_exactly, 0, 0);
8833 if (resized_p)
8834 {
8835 ++windows_or_buffers_changed;
8836 ++update_mode_lines;
8837 redisplay_internal ();
8838 }
8839 }
8840 }
8841
8842
8843 /* Callback function for with_echo_area_buffer, when used from
8844 resize_echo_area_exactly. A1 contains a pointer to the window to
8845 resize, EXACTLY non-nil means resize the mini-window exactly to the
8846 size of the text displayed. A3 and A4 are not used. Value is what
8847 resize_mini_window returns. */
8848
8849 static int
8850 resize_mini_window_1 (EMACS_INT a1, Lisp_Object exactly, EMACS_INT a3, EMACS_INT a4)
8851 {
8852 return resize_mini_window ((struct window *) a1, !NILP (exactly));
8853 }
8854
8855
8856 /* Resize mini-window W to fit the size of its contents. EXACT_P
8857 means size the window exactly to the size needed. Otherwise, it's
8858 only enlarged until W's buffer is empty.
8859
8860 Set W->start to the right place to begin display. If the whole
8861 contents fit, start at the beginning. Otherwise, start so as
8862 to make the end of the contents appear. This is particularly
8863 important for y-or-n-p, but seems desirable generally.
8864
8865 Value is non-zero if the window height has been changed. */
8866
8867 int
8868 resize_mini_window (struct window *w, int exact_p)
8869 {
8870 struct frame *f = XFRAME (w->frame);
8871 int window_height_changed_p = 0;
8872
8873 xassert (MINI_WINDOW_P (w));
8874
8875 /* By default, start display at the beginning. */
8876 set_marker_both (w->start, w->buffer,
8877 BUF_BEGV (XBUFFER (w->buffer)),
8878 BUF_BEGV_BYTE (XBUFFER (w->buffer)));
8879
8880 /* Don't resize windows while redisplaying a window; it would
8881 confuse redisplay functions when the size of the window they are
8882 displaying changes from under them. Such a resizing can happen,
8883 for instance, when which-func prints a long message while
8884 we are running fontification-functions. We're running these
8885 functions with safe_call which binds inhibit-redisplay to t. */
8886 if (!NILP (Vinhibit_redisplay))
8887 return 0;
8888
8889 /* Nil means don't try to resize. */
8890 if (NILP (Vresize_mini_windows)
8891 || (FRAME_X_P (f) && FRAME_X_OUTPUT (f) == NULL))
8892 return 0;
8893
8894 if (!FRAME_MINIBUF_ONLY_P (f))
8895 {
8896 struct it it;
8897 struct window *root = XWINDOW (FRAME_ROOT_WINDOW (f));
8898 int total_height = WINDOW_TOTAL_LINES (root) + WINDOW_TOTAL_LINES (w);
8899 int height, max_height;
8900 int unit = FRAME_LINE_HEIGHT (f);
8901 struct text_pos start;
8902 struct buffer *old_current_buffer = NULL;
8903
8904 if (current_buffer != XBUFFER (w->buffer))
8905 {
8906 old_current_buffer = current_buffer;
8907 set_buffer_internal (XBUFFER (w->buffer));
8908 }
8909
8910 init_iterator (&it, w, BEGV, BEGV_BYTE, NULL, DEFAULT_FACE_ID);
8911
8912 /* Compute the max. number of lines specified by the user. */
8913 if (FLOATP (Vmax_mini_window_height))
8914 max_height = XFLOATINT (Vmax_mini_window_height) * FRAME_LINES (f);
8915 else if (INTEGERP (Vmax_mini_window_height))
8916 max_height = XINT (Vmax_mini_window_height);
8917 else
8918 max_height = total_height / 4;
8919
8920 /* Correct that max. height if it's bogus. */
8921 max_height = max (1, max_height);
8922 max_height = min (total_height, max_height);
8923
8924 /* Find out the height of the text in the window. */
8925 if (it.line_wrap == TRUNCATE)
8926 height = 1;
8927 else
8928 {
8929 last_height = 0;
8930 move_it_to (&it, ZV, -1, -1, -1, MOVE_TO_POS);
8931 if (it.max_ascent == 0 && it.max_descent == 0)
8932 height = it.current_y + last_height;
8933 else
8934 height = it.current_y + it.max_ascent + it.max_descent;
8935 height -= min (it.extra_line_spacing, it.max_extra_line_spacing);
8936 height = (height + unit - 1) / unit;
8937 }
8938
8939 /* Compute a suitable window start. */
8940 if (height > max_height)
8941 {
8942 height = max_height;
8943 init_iterator (&it, w, ZV, ZV_BYTE, NULL, DEFAULT_FACE_ID);
8944 move_it_vertically_backward (&it, (height - 1) * unit);
8945 start = it.current.pos;
8946 }
8947 else
8948 SET_TEXT_POS (start, BEGV, BEGV_BYTE);
8949 SET_MARKER_FROM_TEXT_POS (w->start, start);
8950
8951 if (EQ (Vresize_mini_windows, Qgrow_only))
8952 {
8953 /* Let it grow only, until we display an empty message, in which
8954 case the window shrinks again. */
8955 if (height > WINDOW_TOTAL_LINES (w))
8956 {
8957 int old_height = WINDOW_TOTAL_LINES (w);
8958 freeze_window_starts (f, 1);
8959 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
8960 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
8961 }
8962 else if (height < WINDOW_TOTAL_LINES (w)
8963 && (exact_p || BEGV == ZV))
8964 {
8965 int old_height = WINDOW_TOTAL_LINES (w);
8966 freeze_window_starts (f, 0);
8967 shrink_mini_window (w);
8968 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
8969 }
8970 }
8971 else
8972 {
8973 /* Always resize to exact size needed. */
8974 if (height > WINDOW_TOTAL_LINES (w))
8975 {
8976 int old_height = WINDOW_TOTAL_LINES (w);
8977 freeze_window_starts (f, 1);
8978 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
8979 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
8980 }
8981 else if (height < WINDOW_TOTAL_LINES (w))
8982 {
8983 int old_height = WINDOW_TOTAL_LINES (w);
8984 freeze_window_starts (f, 0);
8985 shrink_mini_window (w);
8986
8987 if (height)
8988 {
8989 freeze_window_starts (f, 1);
8990 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
8991 }
8992
8993 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
8994 }
8995 }
8996
8997 if (old_current_buffer)
8998 set_buffer_internal (old_current_buffer);
8999 }
9000
9001 return window_height_changed_p;
9002 }
9003
9004
9005 /* Value is the current message, a string, or nil if there is no
9006 current message. */
9007
9008 Lisp_Object
9009 current_message (void)
9010 {
9011 Lisp_Object msg;
9012
9013 if (!BUFFERP (echo_area_buffer[0]))
9014 msg = Qnil;
9015 else
9016 {
9017 with_echo_area_buffer (0, 0, current_message_1,
9018 (EMACS_INT) &msg, Qnil, 0, 0);
9019 if (NILP (msg))
9020 echo_area_buffer[0] = Qnil;
9021 }
9022
9023 return msg;
9024 }
9025
9026
9027 static int
9028 current_message_1 (EMACS_INT a1, Lisp_Object a2, EMACS_INT a3, EMACS_INT a4)
9029 {
9030 Lisp_Object *msg = (Lisp_Object *) a1;
9031
9032 if (Z > BEG)
9033 *msg = make_buffer_string (BEG, Z, 1);
9034 else
9035 *msg = Qnil;
9036 return 0;
9037 }
9038
9039
9040 /* Push the current message on Vmessage_stack for later restauration
9041 by restore_message. Value is non-zero if the current message isn't
9042 empty. This is a relatively infrequent operation, so it's not
9043 worth optimizing. */
9044
9045 int
9046 push_message (void)
9047 {
9048 Lisp_Object msg;
9049 msg = current_message ();
9050 Vmessage_stack = Fcons (msg, Vmessage_stack);
9051 return STRINGP (msg);
9052 }
9053
9054
9055 /* Restore message display from the top of Vmessage_stack. */
9056
9057 void
9058 restore_message (void)
9059 {
9060 Lisp_Object msg;
9061
9062 xassert (CONSP (Vmessage_stack));
9063 msg = XCAR (Vmessage_stack);
9064 if (STRINGP (msg))
9065 message3_nolog (msg, SBYTES (msg), STRING_MULTIBYTE (msg));
9066 else
9067 message3_nolog (msg, 0, 0);
9068 }
9069
9070
9071 /* Handler for record_unwind_protect calling pop_message. */
9072
9073 Lisp_Object
9074 pop_message_unwind (Lisp_Object dummy)
9075 {
9076 pop_message ();
9077 return Qnil;
9078 }
9079
9080 /* Pop the top-most entry off Vmessage_stack. */
9081
9082 void
9083 pop_message (void)
9084 {
9085 xassert (CONSP (Vmessage_stack));
9086 Vmessage_stack = XCDR (Vmessage_stack);
9087 }
9088
9089
9090 /* Check that Vmessage_stack is nil. Called from emacs.c when Emacs
9091 exits. If the stack is not empty, we have a missing pop_message
9092 somewhere. */
9093
9094 void
9095 check_message_stack (void)
9096 {
9097 if (!NILP (Vmessage_stack))
9098 abort ();
9099 }
9100
9101
9102 /* Truncate to NCHARS what will be displayed in the echo area the next
9103 time we display it---but don't redisplay it now. */
9104
9105 void
9106 truncate_echo_area (EMACS_INT nchars)
9107 {
9108 if (nchars == 0)
9109 echo_area_buffer[0] = Qnil;
9110 /* A null message buffer means that the frame hasn't really been
9111 initialized yet. Error messages get reported properly by
9112 cmd_error, so this must be just an informative message; toss it. */
9113 else if (!noninteractive
9114 && INTERACTIVE
9115 && !NILP (echo_area_buffer[0]))
9116 {
9117 struct frame *sf = SELECTED_FRAME ();
9118 if (FRAME_MESSAGE_BUF (sf))
9119 with_echo_area_buffer (0, 0, truncate_message_1, nchars, Qnil, 0, 0);
9120 }
9121 }
9122
9123
9124 /* Helper function for truncate_echo_area. Truncate the current
9125 message to at most NCHARS characters. */
9126
9127 static int
9128 truncate_message_1 (EMACS_INT nchars, Lisp_Object a2, EMACS_INT a3, EMACS_INT a4)
9129 {
9130 if (BEG + nchars < Z)
9131 del_range (BEG + nchars, Z);
9132 if (Z == BEG)
9133 echo_area_buffer[0] = Qnil;
9134 return 0;
9135 }
9136
9137
9138 /* Set the current message to a substring of S or STRING.
9139
9140 If STRING is a Lisp string, set the message to the first NBYTES
9141 bytes from STRING. NBYTES zero means use the whole string. If
9142 STRING is multibyte, the message will be displayed multibyte.
9143
9144 If S is not null, set the message to the first LEN bytes of S. LEN
9145 zero means use the whole string. MULTIBYTE_P non-zero means S is
9146 multibyte. Display the message multibyte in that case.
9147
9148 Doesn't GC, as with_echo_area_buffer binds Qinhibit_modification_hooks
9149 to t before calling set_message_1 (which calls insert).
9150 */
9151
9152 void
9153 set_message (const char *s, Lisp_Object string,
9154 EMACS_INT nbytes, int multibyte_p)
9155 {
9156 message_enable_multibyte
9157 = ((s && multibyte_p)
9158 || (STRINGP (string) && STRING_MULTIBYTE (string)));
9159
9160 with_echo_area_buffer (0, -1, set_message_1,
9161 (EMACS_INT) s, string, nbytes, multibyte_p);
9162 message_buf_print = 0;
9163 help_echo_showing_p = 0;
9164 }
9165
9166
9167 /* Helper function for set_message. Arguments have the same meaning
9168 as there, with A1 corresponding to S and A2 corresponding to STRING
9169 This function is called with the echo area buffer being
9170 current. */
9171
9172 static int
9173 set_message_1 (EMACS_INT a1, Lisp_Object a2, EMACS_INT nbytes, EMACS_INT multibyte_p)
9174 {
9175 const char *s = (const char *) a1;
9176 const unsigned char *msg = (const unsigned char *) s;
9177 Lisp_Object string = a2;
9178
9179 /* Change multibyteness of the echo buffer appropriately. */
9180 if (message_enable_multibyte
9181 != !NILP (BVAR (current_buffer, enable_multibyte_characters)))
9182 Fset_buffer_multibyte (message_enable_multibyte ? Qt : Qnil);
9183
9184 BVAR (current_buffer, truncate_lines) = message_truncate_lines ? Qt : Qnil;
9185 if (!NILP (BVAR (current_buffer, bidi_display_reordering)))
9186 BVAR (current_buffer, bidi_paragraph_direction) = Qleft_to_right;
9187
9188 /* Insert new message at BEG. */
9189 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
9190
9191 if (STRINGP (string))
9192 {
9193 EMACS_INT nchars;
9194
9195 if (nbytes == 0)
9196 nbytes = SBYTES (string);
9197 nchars = string_byte_to_char (string, nbytes);
9198
9199 /* This function takes care of single/multibyte conversion. We
9200 just have to ensure that the echo area buffer has the right
9201 setting of enable_multibyte_characters. */
9202 insert_from_string (string, 0, 0, nchars, nbytes, 1);
9203 }
9204 else if (s)
9205 {
9206 if (nbytes == 0)
9207 nbytes = strlen (s);
9208
9209 if (multibyte_p && NILP (BVAR (current_buffer, enable_multibyte_characters)))
9210 {
9211 /* Convert from multi-byte to single-byte. */
9212 EMACS_INT i;
9213 int c, n;
9214 char work[1];
9215
9216 /* Convert a multibyte string to single-byte. */
9217 for (i = 0; i < nbytes; i += n)
9218 {
9219 c = string_char_and_length (msg + i, &n);
9220 work[0] = (ASCII_CHAR_P (c)
9221 ? c
9222 : multibyte_char_to_unibyte (c));
9223 insert_1_both (work, 1, 1, 1, 0, 0);
9224 }
9225 }
9226 else if (!multibyte_p
9227 && !NILP (BVAR (current_buffer, enable_multibyte_characters)))
9228 {
9229 /* Convert from single-byte to multi-byte. */
9230 EMACS_INT i;
9231 int c, n;
9232 unsigned char str[MAX_MULTIBYTE_LENGTH];
9233
9234 /* Convert a single-byte string to multibyte. */
9235 for (i = 0; i < nbytes; i++)
9236 {
9237 c = msg[i];
9238 MAKE_CHAR_MULTIBYTE (c);
9239 n = CHAR_STRING (c, str);
9240 insert_1_both ((char *) str, 1, n, 1, 0, 0);
9241 }
9242 }
9243 else
9244 insert_1 (s, nbytes, 1, 0, 0);
9245 }
9246
9247 return 0;
9248 }
9249
9250
9251 /* Clear messages. CURRENT_P non-zero means clear the current
9252 message. LAST_DISPLAYED_P non-zero means clear the message
9253 last displayed. */
9254
9255 void
9256 clear_message (int current_p, int last_displayed_p)
9257 {
9258 if (current_p)
9259 {
9260 echo_area_buffer[0] = Qnil;
9261 message_cleared_p = 1;
9262 }
9263
9264 if (last_displayed_p)
9265 echo_area_buffer[1] = Qnil;
9266
9267 message_buf_print = 0;
9268 }
9269
9270 /* Clear garbaged frames.
9271
9272 This function is used where the old redisplay called
9273 redraw_garbaged_frames which in turn called redraw_frame which in
9274 turn called clear_frame. The call to clear_frame was a source of
9275 flickering. I believe a clear_frame is not necessary. It should
9276 suffice in the new redisplay to invalidate all current matrices,
9277 and ensure a complete redisplay of all windows. */
9278
9279 static void
9280 clear_garbaged_frames (void)
9281 {
9282 if (frame_garbaged)
9283 {
9284 Lisp_Object tail, frame;
9285 int changed_count = 0;
9286
9287 FOR_EACH_FRAME (tail, frame)
9288 {
9289 struct frame *f = XFRAME (frame);
9290
9291 if (FRAME_VISIBLE_P (f) && FRAME_GARBAGED_P (f))
9292 {
9293 if (f->resized_p)
9294 {
9295 Fredraw_frame (frame);
9296 f->force_flush_display_p = 1;
9297 }
9298 clear_current_matrices (f);
9299 changed_count++;
9300 f->garbaged = 0;
9301 f->resized_p = 0;
9302 }
9303 }
9304
9305 frame_garbaged = 0;
9306 if (changed_count)
9307 ++windows_or_buffers_changed;
9308 }
9309 }
9310
9311
9312 /* Redisplay the echo area of the selected frame. If UPDATE_FRAME_P
9313 is non-zero update selected_frame. Value is non-zero if the
9314 mini-windows height has been changed. */
9315
9316 static int
9317 echo_area_display (int update_frame_p)
9318 {
9319 Lisp_Object mini_window;
9320 struct window *w;
9321 struct frame *f;
9322 int window_height_changed_p = 0;
9323 struct frame *sf = SELECTED_FRAME ();
9324
9325 mini_window = FRAME_MINIBUF_WINDOW (sf);
9326 w = XWINDOW (mini_window);
9327 f = XFRAME (WINDOW_FRAME (w));
9328
9329 /* Don't display if frame is invisible or not yet initialized. */
9330 if (!FRAME_VISIBLE_P (f) || !f->glyphs_initialized_p)
9331 return 0;
9332
9333 #ifdef HAVE_WINDOW_SYSTEM
9334 /* When Emacs starts, selected_frame may be the initial terminal
9335 frame. If we let this through, a message would be displayed on
9336 the terminal. */
9337 if (FRAME_INITIAL_P (XFRAME (selected_frame)))
9338 return 0;
9339 #endif /* HAVE_WINDOW_SYSTEM */
9340
9341 /* Redraw garbaged frames. */
9342 if (frame_garbaged)
9343 clear_garbaged_frames ();
9344
9345 if (!NILP (echo_area_buffer[0]) || minibuf_level == 0)
9346 {
9347 echo_area_window = mini_window;
9348 window_height_changed_p = display_echo_area (w);
9349 w->must_be_updated_p = 1;
9350
9351 /* Update the display, unless called from redisplay_internal.
9352 Also don't update the screen during redisplay itself. The
9353 update will happen at the end of redisplay, and an update
9354 here could cause confusion. */
9355 if (update_frame_p && !redisplaying_p)
9356 {
9357 int n = 0;
9358
9359 /* If the display update has been interrupted by pending
9360 input, update mode lines in the frame. Due to the
9361 pending input, it might have been that redisplay hasn't
9362 been called, so that mode lines above the echo area are
9363 garbaged. This looks odd, so we prevent it here. */
9364 if (!display_completed)
9365 n = redisplay_mode_lines (FRAME_ROOT_WINDOW (f), 0);
9366
9367 if (window_height_changed_p
9368 /* Don't do this if Emacs is shutting down. Redisplay
9369 needs to run hooks. */
9370 && !NILP (Vrun_hooks))
9371 {
9372 /* Must update other windows. Likewise as in other
9373 cases, don't let this update be interrupted by
9374 pending input. */
9375 int count = SPECPDL_INDEX ();
9376 specbind (Qredisplay_dont_pause, Qt);
9377 windows_or_buffers_changed = 1;
9378 redisplay_internal ();
9379 unbind_to (count, Qnil);
9380 }
9381 else if (FRAME_WINDOW_P (f) && n == 0)
9382 {
9383 /* Window configuration is the same as before.
9384 Can do with a display update of the echo area,
9385 unless we displayed some mode lines. */
9386 update_single_window (w, 1);
9387 FRAME_RIF (f)->flush_display (f);
9388 }
9389 else
9390 update_frame (f, 1, 1);
9391
9392 /* If cursor is in the echo area, make sure that the next
9393 redisplay displays the minibuffer, so that the cursor will
9394 be replaced with what the minibuffer wants. */
9395 if (cursor_in_echo_area)
9396 ++windows_or_buffers_changed;
9397 }
9398 }
9399 else if (!EQ (mini_window, selected_window))
9400 windows_or_buffers_changed++;
9401
9402 /* Last displayed message is now the current message. */
9403 echo_area_buffer[1] = echo_area_buffer[0];
9404 /* Inform read_char that we're not echoing. */
9405 echo_message_buffer = Qnil;
9406
9407 /* Prevent redisplay optimization in redisplay_internal by resetting
9408 this_line_start_pos. This is done because the mini-buffer now
9409 displays the message instead of its buffer text. */
9410 if (EQ (mini_window, selected_window))
9411 CHARPOS (this_line_start_pos) = 0;
9412
9413 return window_height_changed_p;
9414 }
9415
9416
9417 \f
9418 /***********************************************************************
9419 Mode Lines and Frame Titles
9420 ***********************************************************************/
9421
9422 /* A buffer for constructing non-propertized mode-line strings and
9423 frame titles in it; allocated from the heap in init_xdisp and
9424 resized as needed in store_mode_line_noprop_char. */
9425
9426 static char *mode_line_noprop_buf;
9427
9428 /* The buffer's end, and a current output position in it. */
9429
9430 static char *mode_line_noprop_buf_end;
9431 static char *mode_line_noprop_ptr;
9432
9433 #define MODE_LINE_NOPROP_LEN(start) \
9434 ((mode_line_noprop_ptr - mode_line_noprop_buf) - start)
9435
9436 static enum {
9437 MODE_LINE_DISPLAY = 0,
9438 MODE_LINE_TITLE,
9439 MODE_LINE_NOPROP,
9440 MODE_LINE_STRING
9441 } mode_line_target;
9442
9443 /* Alist that caches the results of :propertize.
9444 Each element is (PROPERTIZED-STRING . PROPERTY-LIST). */
9445 static Lisp_Object mode_line_proptrans_alist;
9446
9447 /* List of strings making up the mode-line. */
9448 static Lisp_Object mode_line_string_list;
9449
9450 /* Base face property when building propertized mode line string. */
9451 static Lisp_Object mode_line_string_face;
9452 static Lisp_Object mode_line_string_face_prop;
9453
9454
9455 /* Unwind data for mode line strings */
9456
9457 static Lisp_Object Vmode_line_unwind_vector;
9458
9459 static Lisp_Object
9460 format_mode_line_unwind_data (struct buffer *obuf,
9461 Lisp_Object owin,
9462 int save_proptrans)
9463 {
9464 Lisp_Object vector, tmp;
9465
9466 /* Reduce consing by keeping one vector in
9467 Vwith_echo_area_save_vector. */
9468 vector = Vmode_line_unwind_vector;
9469 Vmode_line_unwind_vector = Qnil;
9470
9471 if (NILP (vector))
9472 vector = Fmake_vector (make_number (8), Qnil);
9473
9474 ASET (vector, 0, make_number (mode_line_target));
9475 ASET (vector, 1, make_number (MODE_LINE_NOPROP_LEN (0)));
9476 ASET (vector, 2, mode_line_string_list);
9477 ASET (vector, 3, save_proptrans ? mode_line_proptrans_alist : Qt);
9478 ASET (vector, 4, mode_line_string_face);
9479 ASET (vector, 5, mode_line_string_face_prop);
9480
9481 if (obuf)
9482 XSETBUFFER (tmp, obuf);
9483 else
9484 tmp = Qnil;
9485 ASET (vector, 6, tmp);
9486 ASET (vector, 7, owin);
9487
9488 return vector;
9489 }
9490
9491 static Lisp_Object
9492 unwind_format_mode_line (Lisp_Object vector)
9493 {
9494 mode_line_target = XINT (AREF (vector, 0));
9495 mode_line_noprop_ptr = mode_line_noprop_buf + XINT (AREF (vector, 1));
9496 mode_line_string_list = AREF (vector, 2);
9497 if (! EQ (AREF (vector, 3), Qt))
9498 mode_line_proptrans_alist = AREF (vector, 3);
9499 mode_line_string_face = AREF (vector, 4);
9500 mode_line_string_face_prop = AREF (vector, 5);
9501
9502 if (!NILP (AREF (vector, 7)))
9503 /* Select window before buffer, since it may change the buffer. */
9504 Fselect_window (AREF (vector, 7), Qt);
9505
9506 if (!NILP (AREF (vector, 6)))
9507 {
9508 set_buffer_internal_1 (XBUFFER (AREF (vector, 6)));
9509 ASET (vector, 6, Qnil);
9510 }
9511
9512 Vmode_line_unwind_vector = vector;
9513 return Qnil;
9514 }
9515
9516
9517 /* Store a single character C for the frame title in mode_line_noprop_buf.
9518 Re-allocate mode_line_noprop_buf if necessary. */
9519
9520 static void
9521 store_mode_line_noprop_char (char c)
9522 {
9523 /* If output position has reached the end of the allocated buffer,
9524 double the buffer's size. */
9525 if (mode_line_noprop_ptr == mode_line_noprop_buf_end)
9526 {
9527 int len = MODE_LINE_NOPROP_LEN (0);
9528 int new_size = 2 * len * sizeof *mode_line_noprop_buf;
9529 mode_line_noprop_buf = (char *) xrealloc (mode_line_noprop_buf, new_size);
9530 mode_line_noprop_buf_end = mode_line_noprop_buf + new_size;
9531 mode_line_noprop_ptr = mode_line_noprop_buf + len;
9532 }
9533
9534 *mode_line_noprop_ptr++ = c;
9535 }
9536
9537
9538 /* Store part of a frame title in mode_line_noprop_buf, beginning at
9539 mode_line_noprop_ptr. STRING is the string to store. Do not copy
9540 characters that yield more columns than PRECISION; PRECISION <= 0
9541 means copy the whole string. Pad with spaces until FIELD_WIDTH
9542 number of characters have been copied; FIELD_WIDTH <= 0 means don't
9543 pad. Called from display_mode_element when it is used to build a
9544 frame title. */
9545
9546 static int
9547 store_mode_line_noprop (const char *string, int field_width, int precision)
9548 {
9549 const unsigned char *str = (const unsigned char *) string;
9550 int n = 0;
9551 EMACS_INT dummy, nbytes;
9552
9553 /* Copy at most PRECISION chars from STR. */
9554 nbytes = strlen (string);
9555 n += c_string_width (str, nbytes, precision, &dummy, &nbytes);
9556 while (nbytes--)
9557 store_mode_line_noprop_char (*str++);
9558
9559 /* Fill up with spaces until FIELD_WIDTH reached. */
9560 while (field_width > 0
9561 && n < field_width)
9562 {
9563 store_mode_line_noprop_char (' ');
9564 ++n;
9565 }
9566
9567 return n;
9568 }
9569
9570 /***********************************************************************
9571 Frame Titles
9572 ***********************************************************************/
9573
9574 #ifdef HAVE_WINDOW_SYSTEM
9575
9576 /* Set the title of FRAME, if it has changed. The title format is
9577 Vicon_title_format if FRAME is iconified, otherwise it is
9578 frame_title_format. */
9579
9580 static void
9581 x_consider_frame_title (Lisp_Object frame)
9582 {
9583 struct frame *f = XFRAME (frame);
9584
9585 if (FRAME_WINDOW_P (f)
9586 || FRAME_MINIBUF_ONLY_P (f)
9587 || f->explicit_name)
9588 {
9589 /* Do we have more than one visible frame on this X display? */
9590 Lisp_Object tail;
9591 Lisp_Object fmt;
9592 int title_start;
9593 char *title;
9594 int len;
9595 struct it it;
9596 int count = SPECPDL_INDEX ();
9597
9598 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
9599 {
9600 Lisp_Object other_frame = XCAR (tail);
9601 struct frame *tf = XFRAME (other_frame);
9602
9603 if (tf != f
9604 && FRAME_KBOARD (tf) == FRAME_KBOARD (f)
9605 && !FRAME_MINIBUF_ONLY_P (tf)
9606 && !EQ (other_frame, tip_frame)
9607 && (FRAME_VISIBLE_P (tf) || FRAME_ICONIFIED_P (tf)))
9608 break;
9609 }
9610
9611 /* Set global variable indicating that multiple frames exist. */
9612 multiple_frames = CONSP (tail);
9613
9614 /* Switch to the buffer of selected window of the frame. Set up
9615 mode_line_target so that display_mode_element will output into
9616 mode_line_noprop_buf; then display the title. */
9617 record_unwind_protect (unwind_format_mode_line,
9618 format_mode_line_unwind_data
9619 (current_buffer, selected_window, 0));
9620
9621 Fselect_window (f->selected_window, Qt);
9622 set_buffer_internal_1 (XBUFFER (XWINDOW (f->selected_window)->buffer));
9623 fmt = FRAME_ICONIFIED_P (f) ? Vicon_title_format : Vframe_title_format;
9624
9625 mode_line_target = MODE_LINE_TITLE;
9626 title_start = MODE_LINE_NOPROP_LEN (0);
9627 init_iterator (&it, XWINDOW (f->selected_window), -1, -1,
9628 NULL, DEFAULT_FACE_ID);
9629 display_mode_element (&it, 0, -1, -1, fmt, Qnil, 0);
9630 len = MODE_LINE_NOPROP_LEN (title_start);
9631 title = mode_line_noprop_buf + title_start;
9632 unbind_to (count, Qnil);
9633
9634 /* Set the title only if it's changed. This avoids consing in
9635 the common case where it hasn't. (If it turns out that we've
9636 already wasted too much time by walking through the list with
9637 display_mode_element, then we might need to optimize at a
9638 higher level than this.) */
9639 if (! STRINGP (f->name)
9640 || SBYTES (f->name) != len
9641 || memcmp (title, SDATA (f->name), len) != 0)
9642 x_implicitly_set_name (f, make_string (title, len), Qnil);
9643 }
9644 }
9645
9646 #endif /* not HAVE_WINDOW_SYSTEM */
9647
9648
9649
9650 \f
9651 /***********************************************************************
9652 Menu Bars
9653 ***********************************************************************/
9654
9655
9656 /* Prepare for redisplay by updating menu-bar item lists when
9657 appropriate. This can call eval. */
9658
9659 void
9660 prepare_menu_bars (void)
9661 {
9662 int all_windows;
9663 struct gcpro gcpro1, gcpro2;
9664 struct frame *f;
9665 Lisp_Object tooltip_frame;
9666
9667 #ifdef HAVE_WINDOW_SYSTEM
9668 tooltip_frame = tip_frame;
9669 #else
9670 tooltip_frame = Qnil;
9671 #endif
9672
9673 /* Update all frame titles based on their buffer names, etc. We do
9674 this before the menu bars so that the buffer-menu will show the
9675 up-to-date frame titles. */
9676 #ifdef HAVE_WINDOW_SYSTEM
9677 if (windows_or_buffers_changed || update_mode_lines)
9678 {
9679 Lisp_Object tail, frame;
9680
9681 FOR_EACH_FRAME (tail, frame)
9682 {
9683 f = XFRAME (frame);
9684 if (!EQ (frame, tooltip_frame)
9685 && (FRAME_VISIBLE_P (f) || FRAME_ICONIFIED_P (f)))
9686 x_consider_frame_title (frame);
9687 }
9688 }
9689 #endif /* HAVE_WINDOW_SYSTEM */
9690
9691 /* Update the menu bar item lists, if appropriate. This has to be
9692 done before any actual redisplay or generation of display lines. */
9693 all_windows = (update_mode_lines
9694 || buffer_shared > 1
9695 || windows_or_buffers_changed);
9696 if (all_windows)
9697 {
9698 Lisp_Object tail, frame;
9699 int count = SPECPDL_INDEX ();
9700 /* 1 means that update_menu_bar has run its hooks
9701 so any further calls to update_menu_bar shouldn't do so again. */
9702 int menu_bar_hooks_run = 0;
9703
9704 record_unwind_save_match_data ();
9705
9706 FOR_EACH_FRAME (tail, frame)
9707 {
9708 f = XFRAME (frame);
9709
9710 /* Ignore tooltip frame. */
9711 if (EQ (frame, tooltip_frame))
9712 continue;
9713
9714 /* If a window on this frame changed size, report that to
9715 the user and clear the size-change flag. */
9716 if (FRAME_WINDOW_SIZES_CHANGED (f))
9717 {
9718 Lisp_Object functions;
9719
9720 /* Clear flag first in case we get an error below. */
9721 FRAME_WINDOW_SIZES_CHANGED (f) = 0;
9722 functions = Vwindow_size_change_functions;
9723 GCPRO2 (tail, functions);
9724
9725 while (CONSP (functions))
9726 {
9727 if (!EQ (XCAR (functions), Qt))
9728 call1 (XCAR (functions), frame);
9729 functions = XCDR (functions);
9730 }
9731 UNGCPRO;
9732 }
9733
9734 GCPRO1 (tail);
9735 menu_bar_hooks_run = update_menu_bar (f, 0, menu_bar_hooks_run);
9736 #ifdef HAVE_WINDOW_SYSTEM
9737 update_tool_bar (f, 0);
9738 #endif
9739 #ifdef HAVE_NS
9740 if (windows_or_buffers_changed
9741 && FRAME_NS_P (f))
9742 ns_set_doc_edited (f, Fbuffer_modified_p
9743 (XWINDOW (f->selected_window)->buffer));
9744 #endif
9745 UNGCPRO;
9746 }
9747
9748 unbind_to (count, Qnil);
9749 }
9750 else
9751 {
9752 struct frame *sf = SELECTED_FRAME ();
9753 update_menu_bar (sf, 1, 0);
9754 #ifdef HAVE_WINDOW_SYSTEM
9755 update_tool_bar (sf, 1);
9756 #endif
9757 }
9758 }
9759
9760
9761 /* Update the menu bar item list for frame F. This has to be done
9762 before we start to fill in any display lines, because it can call
9763 eval.
9764
9765 If SAVE_MATCH_DATA is non-zero, we must save and restore it here.
9766
9767 If HOOKS_RUN is 1, that means a previous call to update_menu_bar
9768 already ran the menu bar hooks for this redisplay, so there
9769 is no need to run them again. The return value is the
9770 updated value of this flag, to pass to the next call. */
9771
9772 static int
9773 update_menu_bar (struct frame *f, int save_match_data, int hooks_run)
9774 {
9775 Lisp_Object window;
9776 register struct window *w;
9777
9778 /* If called recursively during a menu update, do nothing. This can
9779 happen when, for instance, an activate-menubar-hook causes a
9780 redisplay. */
9781 if (inhibit_menubar_update)
9782 return hooks_run;
9783
9784 window = FRAME_SELECTED_WINDOW (f);
9785 w = XWINDOW (window);
9786
9787 if (FRAME_WINDOW_P (f)
9788 ?
9789 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
9790 || defined (HAVE_NS) || defined (USE_GTK)
9791 FRAME_EXTERNAL_MENU_BAR (f)
9792 #else
9793 FRAME_MENU_BAR_LINES (f) > 0
9794 #endif
9795 : FRAME_MENU_BAR_LINES (f) > 0)
9796 {
9797 /* If the user has switched buffers or windows, we need to
9798 recompute to reflect the new bindings. But we'll
9799 recompute when update_mode_lines is set too; that means
9800 that people can use force-mode-line-update to request
9801 that the menu bar be recomputed. The adverse effect on
9802 the rest of the redisplay algorithm is about the same as
9803 windows_or_buffers_changed anyway. */
9804 if (windows_or_buffers_changed
9805 /* This used to test w->update_mode_line, but we believe
9806 there is no need to recompute the menu in that case. */
9807 || update_mode_lines
9808 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
9809 < BUF_MODIFF (XBUFFER (w->buffer)))
9810 != !NILP (w->last_had_star))
9811 || ((!NILP (Vtransient_mark_mode)
9812 && !NILP (BVAR (XBUFFER (w->buffer), mark_active)))
9813 != !NILP (w->region_showing)))
9814 {
9815 struct buffer *prev = current_buffer;
9816 int count = SPECPDL_INDEX ();
9817
9818 specbind (Qinhibit_menubar_update, Qt);
9819
9820 set_buffer_internal_1 (XBUFFER (w->buffer));
9821 if (save_match_data)
9822 record_unwind_save_match_data ();
9823 if (NILP (Voverriding_local_map_menu_flag))
9824 {
9825 specbind (Qoverriding_terminal_local_map, Qnil);
9826 specbind (Qoverriding_local_map, Qnil);
9827 }
9828
9829 if (!hooks_run)
9830 {
9831 /* Run the Lucid hook. */
9832 safe_run_hooks (Qactivate_menubar_hook);
9833
9834 /* If it has changed current-menubar from previous value,
9835 really recompute the menu-bar from the value. */
9836 if (! NILP (Vlucid_menu_bar_dirty_flag))
9837 call0 (Qrecompute_lucid_menubar);
9838
9839 safe_run_hooks (Qmenu_bar_update_hook);
9840
9841 hooks_run = 1;
9842 }
9843
9844 XSETFRAME (Vmenu_updating_frame, f);
9845 FRAME_MENU_BAR_ITEMS (f) = menu_bar_items (FRAME_MENU_BAR_ITEMS (f));
9846
9847 /* Redisplay the menu bar in case we changed it. */
9848 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
9849 || defined (HAVE_NS) || defined (USE_GTK)
9850 if (FRAME_WINDOW_P (f))
9851 {
9852 #if defined (HAVE_NS)
9853 /* All frames on Mac OS share the same menubar. So only
9854 the selected frame should be allowed to set it. */
9855 if (f == SELECTED_FRAME ())
9856 #endif
9857 set_frame_menubar (f, 0, 0);
9858 }
9859 else
9860 /* On a terminal screen, the menu bar is an ordinary screen
9861 line, and this makes it get updated. */
9862 w->update_mode_line = Qt;
9863 #else /* ! (USE_X_TOOLKIT || HAVE_NTGUI || HAVE_NS || USE_GTK) */
9864 /* In the non-toolkit version, the menu bar is an ordinary screen
9865 line, and this makes it get updated. */
9866 w->update_mode_line = Qt;
9867 #endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI || HAVE_NS || USE_GTK) */
9868
9869 unbind_to (count, Qnil);
9870 set_buffer_internal_1 (prev);
9871 }
9872 }
9873
9874 return hooks_run;
9875 }
9876
9877
9878 \f
9879 /***********************************************************************
9880 Output Cursor
9881 ***********************************************************************/
9882
9883 #ifdef HAVE_WINDOW_SYSTEM
9884
9885 /* EXPORT:
9886 Nominal cursor position -- where to draw output.
9887 HPOS and VPOS are window relative glyph matrix coordinates.
9888 X and Y are window relative pixel coordinates. */
9889
9890 struct cursor_pos output_cursor;
9891
9892
9893 /* EXPORT:
9894 Set the global variable output_cursor to CURSOR. All cursor
9895 positions are relative to updated_window. */
9896
9897 void
9898 set_output_cursor (struct cursor_pos *cursor)
9899 {
9900 output_cursor.hpos = cursor->hpos;
9901 output_cursor.vpos = cursor->vpos;
9902 output_cursor.x = cursor->x;
9903 output_cursor.y = cursor->y;
9904 }
9905
9906
9907 /* EXPORT for RIF:
9908 Set a nominal cursor position.
9909
9910 HPOS and VPOS are column/row positions in a window glyph matrix. X
9911 and Y are window text area relative pixel positions.
9912
9913 If this is done during an update, updated_window will contain the
9914 window that is being updated and the position is the future output
9915 cursor position for that window. If updated_window is null, use
9916 selected_window and display the cursor at the given position. */
9917
9918 void
9919 x_cursor_to (int vpos, int hpos, int y, int x)
9920 {
9921 struct window *w;
9922
9923 /* If updated_window is not set, work on selected_window. */
9924 if (updated_window)
9925 w = updated_window;
9926 else
9927 w = XWINDOW (selected_window);
9928
9929 /* Set the output cursor. */
9930 output_cursor.hpos = hpos;
9931 output_cursor.vpos = vpos;
9932 output_cursor.x = x;
9933 output_cursor.y = y;
9934
9935 /* If not called as part of an update, really display the cursor.
9936 This will also set the cursor position of W. */
9937 if (updated_window == NULL)
9938 {
9939 BLOCK_INPUT;
9940 display_and_set_cursor (w, 1, hpos, vpos, x, y);
9941 if (FRAME_RIF (SELECTED_FRAME ())->flush_display_optional)
9942 FRAME_RIF (SELECTED_FRAME ())->flush_display_optional (SELECTED_FRAME ());
9943 UNBLOCK_INPUT;
9944 }
9945 }
9946
9947 #endif /* HAVE_WINDOW_SYSTEM */
9948
9949 \f
9950 /***********************************************************************
9951 Tool-bars
9952 ***********************************************************************/
9953
9954 #ifdef HAVE_WINDOW_SYSTEM
9955
9956 /* Where the mouse was last time we reported a mouse event. */
9957
9958 FRAME_PTR last_mouse_frame;
9959
9960 /* Tool-bar item index of the item on which a mouse button was pressed
9961 or -1. */
9962
9963 int last_tool_bar_item;
9964
9965
9966 static Lisp_Object
9967 update_tool_bar_unwind (Lisp_Object frame)
9968 {
9969 selected_frame = frame;
9970 return Qnil;
9971 }
9972
9973 /* Update the tool-bar item list for frame F. This has to be done
9974 before we start to fill in any display lines. Called from
9975 prepare_menu_bars. If SAVE_MATCH_DATA is non-zero, we must save
9976 and restore it here. */
9977
9978 static void
9979 update_tool_bar (struct frame *f, int save_match_data)
9980 {
9981 #if defined (USE_GTK) || defined (HAVE_NS)
9982 int do_update = FRAME_EXTERNAL_TOOL_BAR (f);
9983 #else
9984 int do_update = WINDOWP (f->tool_bar_window)
9985 && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)) > 0;
9986 #endif
9987
9988 if (do_update)
9989 {
9990 Lisp_Object window;
9991 struct window *w;
9992
9993 window = FRAME_SELECTED_WINDOW (f);
9994 w = XWINDOW (window);
9995
9996 /* If the user has switched buffers or windows, we need to
9997 recompute to reflect the new bindings. But we'll
9998 recompute when update_mode_lines is set too; that means
9999 that people can use force-mode-line-update to request
10000 that the menu bar be recomputed. The adverse effect on
10001 the rest of the redisplay algorithm is about the same as
10002 windows_or_buffers_changed anyway. */
10003 if (windows_or_buffers_changed
10004 || !NILP (w->update_mode_line)
10005 || update_mode_lines
10006 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
10007 < BUF_MODIFF (XBUFFER (w->buffer)))
10008 != !NILP (w->last_had_star))
10009 || ((!NILP (Vtransient_mark_mode)
10010 && !NILP (BVAR (XBUFFER (w->buffer), mark_active)))
10011 != !NILP (w->region_showing)))
10012 {
10013 struct buffer *prev = current_buffer;
10014 int count = SPECPDL_INDEX ();
10015 Lisp_Object frame, new_tool_bar;
10016 int new_n_tool_bar;
10017 struct gcpro gcpro1;
10018
10019 /* Set current_buffer to the buffer of the selected
10020 window of the frame, so that we get the right local
10021 keymaps. */
10022 set_buffer_internal_1 (XBUFFER (w->buffer));
10023
10024 /* Save match data, if we must. */
10025 if (save_match_data)
10026 record_unwind_save_match_data ();
10027
10028 /* Make sure that we don't accidentally use bogus keymaps. */
10029 if (NILP (Voverriding_local_map_menu_flag))
10030 {
10031 specbind (Qoverriding_terminal_local_map, Qnil);
10032 specbind (Qoverriding_local_map, Qnil);
10033 }
10034
10035 GCPRO1 (new_tool_bar);
10036
10037 /* We must temporarily set the selected frame to this frame
10038 before calling tool_bar_items, because the calculation of
10039 the tool-bar keymap uses the selected frame (see
10040 `tool-bar-make-keymap' in tool-bar.el). */
10041 record_unwind_protect (update_tool_bar_unwind, selected_frame);
10042 XSETFRAME (frame, f);
10043 selected_frame = frame;
10044
10045 /* Build desired tool-bar items from keymaps. */
10046 new_tool_bar = tool_bar_items (Fcopy_sequence (f->tool_bar_items),
10047 &new_n_tool_bar);
10048
10049 /* Redisplay the tool-bar if we changed it. */
10050 if (new_n_tool_bar != f->n_tool_bar_items
10051 || NILP (Fequal (new_tool_bar, f->tool_bar_items)))
10052 {
10053 /* Redisplay that happens asynchronously due to an expose event
10054 may access f->tool_bar_items. Make sure we update both
10055 variables within BLOCK_INPUT so no such event interrupts. */
10056 BLOCK_INPUT;
10057 f->tool_bar_items = new_tool_bar;
10058 f->n_tool_bar_items = new_n_tool_bar;
10059 w->update_mode_line = Qt;
10060 UNBLOCK_INPUT;
10061 }
10062
10063 UNGCPRO;
10064
10065 unbind_to (count, Qnil);
10066 set_buffer_internal_1 (prev);
10067 }
10068 }
10069 }
10070
10071
10072 /* Set F->desired_tool_bar_string to a Lisp string representing frame
10073 F's desired tool-bar contents. F->tool_bar_items must have
10074 been set up previously by calling prepare_menu_bars. */
10075
10076 static void
10077 build_desired_tool_bar_string (struct frame *f)
10078 {
10079 int i, size, size_needed;
10080 struct gcpro gcpro1, gcpro2, gcpro3;
10081 Lisp_Object image, plist, props;
10082
10083 image = plist = props = Qnil;
10084 GCPRO3 (image, plist, props);
10085
10086 /* Prepare F->desired_tool_bar_string. If we can reuse it, do so.
10087 Otherwise, make a new string. */
10088
10089 /* The size of the string we might be able to reuse. */
10090 size = (STRINGP (f->desired_tool_bar_string)
10091 ? SCHARS (f->desired_tool_bar_string)
10092 : 0);
10093
10094 /* We need one space in the string for each image. */
10095 size_needed = f->n_tool_bar_items;
10096
10097 /* Reuse f->desired_tool_bar_string, if possible. */
10098 if (size < size_needed || NILP (f->desired_tool_bar_string))
10099 f->desired_tool_bar_string = Fmake_string (make_number (size_needed),
10100 make_number (' '));
10101 else
10102 {
10103 props = list4 (Qdisplay, Qnil, Qmenu_item, Qnil);
10104 Fremove_text_properties (make_number (0), make_number (size),
10105 props, f->desired_tool_bar_string);
10106 }
10107
10108 /* Put a `display' property on the string for the images to display,
10109 put a `menu_item' property on tool-bar items with a value that
10110 is the index of the item in F's tool-bar item vector. */
10111 for (i = 0; i < f->n_tool_bar_items; ++i)
10112 {
10113 #define PROP(IDX) AREF (f->tool_bar_items, i * TOOL_BAR_ITEM_NSLOTS + (IDX))
10114
10115 int enabled_p = !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P));
10116 int selected_p = !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P));
10117 int hmargin, vmargin, relief, idx, end;
10118
10119 /* If image is a vector, choose the image according to the
10120 button state. */
10121 image = PROP (TOOL_BAR_ITEM_IMAGES);
10122 if (VECTORP (image))
10123 {
10124 if (enabled_p)
10125 idx = (selected_p
10126 ? TOOL_BAR_IMAGE_ENABLED_SELECTED
10127 : TOOL_BAR_IMAGE_ENABLED_DESELECTED);
10128 else
10129 idx = (selected_p
10130 ? TOOL_BAR_IMAGE_DISABLED_SELECTED
10131 : TOOL_BAR_IMAGE_DISABLED_DESELECTED);
10132
10133 xassert (ASIZE (image) >= idx);
10134 image = AREF (image, idx);
10135 }
10136 else
10137 idx = -1;
10138
10139 /* Ignore invalid image specifications. */
10140 if (!valid_image_p (image))
10141 continue;
10142
10143 /* Display the tool-bar button pressed, or depressed. */
10144 plist = Fcopy_sequence (XCDR (image));
10145
10146 /* Compute margin and relief to draw. */
10147 relief = (tool_bar_button_relief >= 0
10148 ? tool_bar_button_relief
10149 : DEFAULT_TOOL_BAR_BUTTON_RELIEF);
10150 hmargin = vmargin = relief;
10151
10152 if (INTEGERP (Vtool_bar_button_margin)
10153 && XINT (Vtool_bar_button_margin) > 0)
10154 {
10155 hmargin += XFASTINT (Vtool_bar_button_margin);
10156 vmargin += XFASTINT (Vtool_bar_button_margin);
10157 }
10158 else if (CONSP (Vtool_bar_button_margin))
10159 {
10160 if (INTEGERP (XCAR (Vtool_bar_button_margin))
10161 && XINT (XCAR (Vtool_bar_button_margin)) > 0)
10162 hmargin += XFASTINT (XCAR (Vtool_bar_button_margin));
10163
10164 if (INTEGERP (XCDR (Vtool_bar_button_margin))
10165 && XINT (XCDR (Vtool_bar_button_margin)) > 0)
10166 vmargin += XFASTINT (XCDR (Vtool_bar_button_margin));
10167 }
10168
10169 if (auto_raise_tool_bar_buttons_p)
10170 {
10171 /* Add a `:relief' property to the image spec if the item is
10172 selected. */
10173 if (selected_p)
10174 {
10175 plist = Fplist_put (plist, QCrelief, make_number (-relief));
10176 hmargin -= relief;
10177 vmargin -= relief;
10178 }
10179 }
10180 else
10181 {
10182 /* If image is selected, display it pressed, i.e. with a
10183 negative relief. If it's not selected, display it with a
10184 raised relief. */
10185 plist = Fplist_put (plist, QCrelief,
10186 (selected_p
10187 ? make_number (-relief)
10188 : make_number (relief)));
10189 hmargin -= relief;
10190 vmargin -= relief;
10191 }
10192
10193 /* Put a margin around the image. */
10194 if (hmargin || vmargin)
10195 {
10196 if (hmargin == vmargin)
10197 plist = Fplist_put (plist, QCmargin, make_number (hmargin));
10198 else
10199 plist = Fplist_put (plist, QCmargin,
10200 Fcons (make_number (hmargin),
10201 make_number (vmargin)));
10202 }
10203
10204 /* If button is not enabled, and we don't have special images
10205 for the disabled state, make the image appear disabled by
10206 applying an appropriate algorithm to it. */
10207 if (!enabled_p && idx < 0)
10208 plist = Fplist_put (plist, QCconversion, Qdisabled);
10209
10210 /* Put a `display' text property on the string for the image to
10211 display. Put a `menu-item' property on the string that gives
10212 the start of this item's properties in the tool-bar items
10213 vector. */
10214 image = Fcons (Qimage, plist);
10215 props = list4 (Qdisplay, image,
10216 Qmenu_item, make_number (i * TOOL_BAR_ITEM_NSLOTS));
10217
10218 /* Let the last image hide all remaining spaces in the tool bar
10219 string. The string can be longer than needed when we reuse a
10220 previous string. */
10221 if (i + 1 == f->n_tool_bar_items)
10222 end = SCHARS (f->desired_tool_bar_string);
10223 else
10224 end = i + 1;
10225 Fadd_text_properties (make_number (i), make_number (end),
10226 props, f->desired_tool_bar_string);
10227 #undef PROP
10228 }
10229
10230 UNGCPRO;
10231 }
10232
10233
10234 /* Display one line of the tool-bar of frame IT->f.
10235
10236 HEIGHT specifies the desired height of the tool-bar line.
10237 If the actual height of the glyph row is less than HEIGHT, the
10238 row's height is increased to HEIGHT, and the icons are centered
10239 vertically in the new height.
10240
10241 If HEIGHT is -1, we are counting needed tool-bar lines, so don't
10242 count a final empty row in case the tool-bar width exactly matches
10243 the window width.
10244 */
10245
10246 static void
10247 display_tool_bar_line (struct it *it, int height)
10248 {
10249 struct glyph_row *row = it->glyph_row;
10250 int max_x = it->last_visible_x;
10251 struct glyph *last;
10252
10253 prepare_desired_row (row);
10254 row->y = it->current_y;
10255
10256 /* Note that this isn't made use of if the face hasn't a box,
10257 so there's no need to check the face here. */
10258 it->start_of_box_run_p = 1;
10259
10260 while (it->current_x < max_x)
10261 {
10262 int x, n_glyphs_before, i, nglyphs;
10263 struct it it_before;
10264
10265 /* Get the next display element. */
10266 if (!get_next_display_element (it))
10267 {
10268 /* Don't count empty row if we are counting needed tool-bar lines. */
10269 if (height < 0 && !it->hpos)
10270 return;
10271 break;
10272 }
10273
10274 /* Produce glyphs. */
10275 n_glyphs_before = row->used[TEXT_AREA];
10276 it_before = *it;
10277
10278 PRODUCE_GLYPHS (it);
10279
10280 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
10281 i = 0;
10282 x = it_before.current_x;
10283 while (i < nglyphs)
10284 {
10285 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
10286
10287 if (x + glyph->pixel_width > max_x)
10288 {
10289 /* Glyph doesn't fit on line. Backtrack. */
10290 row->used[TEXT_AREA] = n_glyphs_before;
10291 *it = it_before;
10292 /* If this is the only glyph on this line, it will never fit on the
10293 tool-bar, so skip it. But ensure there is at least one glyph,
10294 so we don't accidentally disable the tool-bar. */
10295 if (n_glyphs_before == 0
10296 && (it->vpos > 0 || IT_STRING_CHARPOS (*it) < it->end_charpos-1))
10297 break;
10298 goto out;
10299 }
10300
10301 ++it->hpos;
10302 x += glyph->pixel_width;
10303 ++i;
10304 }
10305
10306 /* Stop at line ends. */
10307 if (ITERATOR_AT_END_OF_LINE_P (it))
10308 break;
10309
10310 set_iterator_to_next (it, 1);
10311 }
10312
10313 out:;
10314
10315 row->displays_text_p = row->used[TEXT_AREA] != 0;
10316
10317 /* Use default face for the border below the tool bar.
10318
10319 FIXME: When auto-resize-tool-bars is grow-only, there is
10320 no additional border below the possibly empty tool-bar lines.
10321 So to make the extra empty lines look "normal", we have to
10322 use the tool-bar face for the border too. */
10323 if (!row->displays_text_p && !EQ (Vauto_resize_tool_bars, Qgrow_only))
10324 it->face_id = DEFAULT_FACE_ID;
10325
10326 extend_face_to_end_of_line (it);
10327 last = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
10328 last->right_box_line_p = 1;
10329 if (last == row->glyphs[TEXT_AREA])
10330 last->left_box_line_p = 1;
10331
10332 /* Make line the desired height and center it vertically. */
10333 if ((height -= it->max_ascent + it->max_descent) > 0)
10334 {
10335 /* Don't add more than one line height. */
10336 height %= FRAME_LINE_HEIGHT (it->f);
10337 it->max_ascent += height / 2;
10338 it->max_descent += (height + 1) / 2;
10339 }
10340
10341 compute_line_metrics (it);
10342
10343 /* If line is empty, make it occupy the rest of the tool-bar. */
10344 if (!row->displays_text_p)
10345 {
10346 row->height = row->phys_height = it->last_visible_y - row->y;
10347 row->visible_height = row->height;
10348 row->ascent = row->phys_ascent = 0;
10349 row->extra_line_spacing = 0;
10350 }
10351
10352 row->full_width_p = 1;
10353 row->continued_p = 0;
10354 row->truncated_on_left_p = 0;
10355 row->truncated_on_right_p = 0;
10356
10357 it->current_x = it->hpos = 0;
10358 it->current_y += row->height;
10359 ++it->vpos;
10360 ++it->glyph_row;
10361 }
10362
10363
10364 /* Max tool-bar height. */
10365
10366 #define MAX_FRAME_TOOL_BAR_HEIGHT(f) \
10367 ((FRAME_LINE_HEIGHT (f) * FRAME_LINES (f)))
10368
10369 /* Value is the number of screen lines needed to make all tool-bar
10370 items of frame F visible. The number of actual rows needed is
10371 returned in *N_ROWS if non-NULL. */
10372
10373 static int
10374 tool_bar_lines_needed (struct frame *f, int *n_rows)
10375 {
10376 struct window *w = XWINDOW (f->tool_bar_window);
10377 struct it it;
10378 /* tool_bar_lines_needed is called from redisplay_tool_bar after building
10379 the desired matrix, so use (unused) mode-line row as temporary row to
10380 avoid destroying the first tool-bar row. */
10381 struct glyph_row *temp_row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
10382
10383 /* Initialize an iterator for iteration over
10384 F->desired_tool_bar_string in the tool-bar window of frame F. */
10385 init_iterator (&it, w, -1, -1, temp_row, TOOL_BAR_FACE_ID);
10386 it.first_visible_x = 0;
10387 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
10388 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
10389
10390 while (!ITERATOR_AT_END_P (&it))
10391 {
10392 clear_glyph_row (temp_row);
10393 it.glyph_row = temp_row;
10394 display_tool_bar_line (&it, -1);
10395 }
10396 clear_glyph_row (temp_row);
10397
10398 /* f->n_tool_bar_rows == 0 means "unknown"; -1 means no tool-bar. */
10399 if (n_rows)
10400 *n_rows = it.vpos > 0 ? it.vpos : -1;
10401
10402 return (it.current_y + FRAME_LINE_HEIGHT (f) - 1) / FRAME_LINE_HEIGHT (f);
10403 }
10404
10405
10406 DEFUN ("tool-bar-lines-needed", Ftool_bar_lines_needed, Stool_bar_lines_needed,
10407 0, 1, 0,
10408 doc: /* Return the number of lines occupied by the tool bar of FRAME. */)
10409 (Lisp_Object frame)
10410 {
10411 struct frame *f;
10412 struct window *w;
10413 int nlines = 0;
10414
10415 if (NILP (frame))
10416 frame = selected_frame;
10417 else
10418 CHECK_FRAME (frame);
10419 f = XFRAME (frame);
10420
10421 if (WINDOWP (f->tool_bar_window)
10422 || (w = XWINDOW (f->tool_bar_window),
10423 WINDOW_TOTAL_LINES (w) > 0))
10424 {
10425 update_tool_bar (f, 1);
10426 if (f->n_tool_bar_items)
10427 {
10428 build_desired_tool_bar_string (f);
10429 nlines = tool_bar_lines_needed (f, NULL);
10430 }
10431 }
10432
10433 return make_number (nlines);
10434 }
10435
10436
10437 /* Display the tool-bar of frame F. Value is non-zero if tool-bar's
10438 height should be changed. */
10439
10440 static int
10441 redisplay_tool_bar (struct frame *f)
10442 {
10443 struct window *w;
10444 struct it it;
10445 struct glyph_row *row;
10446
10447 #if defined (USE_GTK) || defined (HAVE_NS)
10448 if (FRAME_EXTERNAL_TOOL_BAR (f))
10449 update_frame_tool_bar (f);
10450 return 0;
10451 #endif
10452
10453 /* If frame hasn't a tool-bar window or if it is zero-height, don't
10454 do anything. This means you must start with tool-bar-lines
10455 non-zero to get the auto-sizing effect. Or in other words, you
10456 can turn off tool-bars by specifying tool-bar-lines zero. */
10457 if (!WINDOWP (f->tool_bar_window)
10458 || (w = XWINDOW (f->tool_bar_window),
10459 WINDOW_TOTAL_LINES (w) == 0))
10460 return 0;
10461
10462 /* Set up an iterator for the tool-bar window. */
10463 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
10464 it.first_visible_x = 0;
10465 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
10466 row = it.glyph_row;
10467
10468 /* Build a string that represents the contents of the tool-bar. */
10469 build_desired_tool_bar_string (f);
10470 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
10471
10472 if (f->n_tool_bar_rows == 0)
10473 {
10474 int nlines;
10475
10476 if ((nlines = tool_bar_lines_needed (f, &f->n_tool_bar_rows),
10477 nlines != WINDOW_TOTAL_LINES (w)))
10478 {
10479 Lisp_Object frame;
10480 int old_height = WINDOW_TOTAL_LINES (w);
10481
10482 XSETFRAME (frame, f);
10483 Fmodify_frame_parameters (frame,
10484 Fcons (Fcons (Qtool_bar_lines,
10485 make_number (nlines)),
10486 Qnil));
10487 if (WINDOW_TOTAL_LINES (w) != old_height)
10488 {
10489 clear_glyph_matrix (w->desired_matrix);
10490 fonts_changed_p = 1;
10491 return 1;
10492 }
10493 }
10494 }
10495
10496 /* Display as many lines as needed to display all tool-bar items. */
10497
10498 if (f->n_tool_bar_rows > 0)
10499 {
10500 int border, rows, height, extra;
10501
10502 if (INTEGERP (Vtool_bar_border))
10503 border = XINT (Vtool_bar_border);
10504 else if (EQ (Vtool_bar_border, Qinternal_border_width))
10505 border = FRAME_INTERNAL_BORDER_WIDTH (f);
10506 else if (EQ (Vtool_bar_border, Qborder_width))
10507 border = f->border_width;
10508 else
10509 border = 0;
10510 if (border < 0)
10511 border = 0;
10512
10513 rows = f->n_tool_bar_rows;
10514 height = max (1, (it.last_visible_y - border) / rows);
10515 extra = it.last_visible_y - border - height * rows;
10516
10517 while (it.current_y < it.last_visible_y)
10518 {
10519 int h = 0;
10520 if (extra > 0 && rows-- > 0)
10521 {
10522 h = (extra + rows - 1) / rows;
10523 extra -= h;
10524 }
10525 display_tool_bar_line (&it, height + h);
10526 }
10527 }
10528 else
10529 {
10530 while (it.current_y < it.last_visible_y)
10531 display_tool_bar_line (&it, 0);
10532 }
10533
10534 /* It doesn't make much sense to try scrolling in the tool-bar
10535 window, so don't do it. */
10536 w->desired_matrix->no_scrolling_p = 1;
10537 w->must_be_updated_p = 1;
10538
10539 if (!NILP (Vauto_resize_tool_bars))
10540 {
10541 int max_tool_bar_height = MAX_FRAME_TOOL_BAR_HEIGHT (f);
10542 int change_height_p = 0;
10543
10544 /* If we couldn't display everything, change the tool-bar's
10545 height if there is room for more. */
10546 if (IT_STRING_CHARPOS (it) < it.end_charpos
10547 && it.current_y < max_tool_bar_height)
10548 change_height_p = 1;
10549
10550 row = it.glyph_row - 1;
10551
10552 /* If there are blank lines at the end, except for a partially
10553 visible blank line at the end that is smaller than
10554 FRAME_LINE_HEIGHT, change the tool-bar's height. */
10555 if (!row->displays_text_p
10556 && row->height >= FRAME_LINE_HEIGHT (f))
10557 change_height_p = 1;
10558
10559 /* If row displays tool-bar items, but is partially visible,
10560 change the tool-bar's height. */
10561 if (row->displays_text_p
10562 && MATRIX_ROW_BOTTOM_Y (row) > it.last_visible_y
10563 && MATRIX_ROW_BOTTOM_Y (row) < max_tool_bar_height)
10564 change_height_p = 1;
10565
10566 /* Resize windows as needed by changing the `tool-bar-lines'
10567 frame parameter. */
10568 if (change_height_p)
10569 {
10570 Lisp_Object frame;
10571 int old_height = WINDOW_TOTAL_LINES (w);
10572 int nrows;
10573 int nlines = tool_bar_lines_needed (f, &nrows);
10574
10575 change_height_p = ((EQ (Vauto_resize_tool_bars, Qgrow_only)
10576 && !f->minimize_tool_bar_window_p)
10577 ? (nlines > old_height)
10578 : (nlines != old_height));
10579 f->minimize_tool_bar_window_p = 0;
10580
10581 if (change_height_p)
10582 {
10583 XSETFRAME (frame, f);
10584 Fmodify_frame_parameters (frame,
10585 Fcons (Fcons (Qtool_bar_lines,
10586 make_number (nlines)),
10587 Qnil));
10588 if (WINDOW_TOTAL_LINES (w) != old_height)
10589 {
10590 clear_glyph_matrix (w->desired_matrix);
10591 f->n_tool_bar_rows = nrows;
10592 fonts_changed_p = 1;
10593 return 1;
10594 }
10595 }
10596 }
10597 }
10598
10599 f->minimize_tool_bar_window_p = 0;
10600 return 0;
10601 }
10602
10603
10604 /* Get information about the tool-bar item which is displayed in GLYPH
10605 on frame F. Return in *PROP_IDX the index where tool-bar item
10606 properties start in F->tool_bar_items. Value is zero if
10607 GLYPH doesn't display a tool-bar item. */
10608
10609 static int
10610 tool_bar_item_info (struct frame *f, struct glyph *glyph, int *prop_idx)
10611 {
10612 Lisp_Object prop;
10613 int success_p;
10614 int charpos;
10615
10616 /* This function can be called asynchronously, which means we must
10617 exclude any possibility that Fget_text_property signals an
10618 error. */
10619 charpos = min (SCHARS (f->current_tool_bar_string), glyph->charpos);
10620 charpos = max (0, charpos);
10621
10622 /* Get the text property `menu-item' at pos. The value of that
10623 property is the start index of this item's properties in
10624 F->tool_bar_items. */
10625 prop = Fget_text_property (make_number (charpos),
10626 Qmenu_item, f->current_tool_bar_string);
10627 if (INTEGERP (prop))
10628 {
10629 *prop_idx = XINT (prop);
10630 success_p = 1;
10631 }
10632 else
10633 success_p = 0;
10634
10635 return success_p;
10636 }
10637
10638 \f
10639 /* Get information about the tool-bar item at position X/Y on frame F.
10640 Return in *GLYPH a pointer to the glyph of the tool-bar item in
10641 the current matrix of the tool-bar window of F, or NULL if not
10642 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
10643 item in F->tool_bar_items. Value is
10644
10645 -1 if X/Y is not on a tool-bar item
10646 0 if X/Y is on the same item that was highlighted before.
10647 1 otherwise. */
10648
10649 static int
10650 get_tool_bar_item (struct frame *f, int x, int y, struct glyph **glyph,
10651 int *hpos, int *vpos, int *prop_idx)
10652 {
10653 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
10654 struct window *w = XWINDOW (f->tool_bar_window);
10655 int area;
10656
10657 /* Find the glyph under X/Y. */
10658 *glyph = x_y_to_hpos_vpos (w, x, y, hpos, vpos, 0, 0, &area);
10659 if (*glyph == NULL)
10660 return -1;
10661
10662 /* Get the start of this tool-bar item's properties in
10663 f->tool_bar_items. */
10664 if (!tool_bar_item_info (f, *glyph, prop_idx))
10665 return -1;
10666
10667 /* Is mouse on the highlighted item? */
10668 if (EQ (f->tool_bar_window, hlinfo->mouse_face_window)
10669 && *vpos >= hlinfo->mouse_face_beg_row
10670 && *vpos <= hlinfo->mouse_face_end_row
10671 && (*vpos > hlinfo->mouse_face_beg_row
10672 || *hpos >= hlinfo->mouse_face_beg_col)
10673 && (*vpos < hlinfo->mouse_face_end_row
10674 || *hpos < hlinfo->mouse_face_end_col
10675 || hlinfo->mouse_face_past_end))
10676 return 0;
10677
10678 return 1;
10679 }
10680
10681
10682 /* EXPORT:
10683 Handle mouse button event on the tool-bar of frame F, at
10684 frame-relative coordinates X/Y. DOWN_P is 1 for a button press,
10685 0 for button release. MODIFIERS is event modifiers for button
10686 release. */
10687
10688 void
10689 handle_tool_bar_click (struct frame *f, int x, int y, int down_p,
10690 unsigned int modifiers)
10691 {
10692 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
10693 struct window *w = XWINDOW (f->tool_bar_window);
10694 int hpos, vpos, prop_idx;
10695 struct glyph *glyph;
10696 Lisp_Object enabled_p;
10697
10698 /* If not on the highlighted tool-bar item, return. */
10699 frame_to_window_pixel_xy (w, &x, &y);
10700 if (get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx) != 0)
10701 return;
10702
10703 /* If item is disabled, do nothing. */
10704 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
10705 if (NILP (enabled_p))
10706 return;
10707
10708 if (down_p)
10709 {
10710 /* Show item in pressed state. */
10711 show_mouse_face (hlinfo, DRAW_IMAGE_SUNKEN);
10712 hlinfo->mouse_face_image_state = DRAW_IMAGE_SUNKEN;
10713 last_tool_bar_item = prop_idx;
10714 }
10715 else
10716 {
10717 Lisp_Object key, frame;
10718 struct input_event event;
10719 EVENT_INIT (event);
10720
10721 /* Show item in released state. */
10722 show_mouse_face (hlinfo, DRAW_IMAGE_RAISED);
10723 hlinfo->mouse_face_image_state = DRAW_IMAGE_RAISED;
10724
10725 key = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_KEY);
10726
10727 XSETFRAME (frame, f);
10728 event.kind = TOOL_BAR_EVENT;
10729 event.frame_or_window = frame;
10730 event.arg = frame;
10731 kbd_buffer_store_event (&event);
10732
10733 event.kind = TOOL_BAR_EVENT;
10734 event.frame_or_window = frame;
10735 event.arg = key;
10736 event.modifiers = modifiers;
10737 kbd_buffer_store_event (&event);
10738 last_tool_bar_item = -1;
10739 }
10740 }
10741
10742
10743 /* Possibly highlight a tool-bar item on frame F when mouse moves to
10744 tool-bar window-relative coordinates X/Y. Called from
10745 note_mouse_highlight. */
10746
10747 static void
10748 note_tool_bar_highlight (struct frame *f, int x, int y)
10749 {
10750 Lisp_Object window = f->tool_bar_window;
10751 struct window *w = XWINDOW (window);
10752 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
10753 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
10754 int hpos, vpos;
10755 struct glyph *glyph;
10756 struct glyph_row *row;
10757 int i;
10758 Lisp_Object enabled_p;
10759 int prop_idx;
10760 enum draw_glyphs_face draw = DRAW_IMAGE_RAISED;
10761 int mouse_down_p, rc;
10762
10763 /* Function note_mouse_highlight is called with negative X/Y
10764 values when mouse moves outside of the frame. */
10765 if (x <= 0 || y <= 0)
10766 {
10767 clear_mouse_face (hlinfo);
10768 return;
10769 }
10770
10771 rc = get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx);
10772 if (rc < 0)
10773 {
10774 /* Not on tool-bar item. */
10775 clear_mouse_face (hlinfo);
10776 return;
10777 }
10778 else if (rc == 0)
10779 /* On same tool-bar item as before. */
10780 goto set_help_echo;
10781
10782 clear_mouse_face (hlinfo);
10783
10784 /* Mouse is down, but on different tool-bar item? */
10785 mouse_down_p = (dpyinfo->grabbed
10786 && f == last_mouse_frame
10787 && FRAME_LIVE_P (f));
10788 if (mouse_down_p
10789 && last_tool_bar_item != prop_idx)
10790 return;
10791
10792 hlinfo->mouse_face_image_state = DRAW_NORMAL_TEXT;
10793 draw = mouse_down_p ? DRAW_IMAGE_SUNKEN : DRAW_IMAGE_RAISED;
10794
10795 /* If tool-bar item is not enabled, don't highlight it. */
10796 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
10797 if (!NILP (enabled_p))
10798 {
10799 /* Compute the x-position of the glyph. In front and past the
10800 image is a space. We include this in the highlighted area. */
10801 row = MATRIX_ROW (w->current_matrix, vpos);
10802 for (i = x = 0; i < hpos; ++i)
10803 x += row->glyphs[TEXT_AREA][i].pixel_width;
10804
10805 /* Record this as the current active region. */
10806 hlinfo->mouse_face_beg_col = hpos;
10807 hlinfo->mouse_face_beg_row = vpos;
10808 hlinfo->mouse_face_beg_x = x;
10809 hlinfo->mouse_face_beg_y = row->y;
10810 hlinfo->mouse_face_past_end = 0;
10811
10812 hlinfo->mouse_face_end_col = hpos + 1;
10813 hlinfo->mouse_face_end_row = vpos;
10814 hlinfo->mouse_face_end_x = x + glyph->pixel_width;
10815 hlinfo->mouse_face_end_y = row->y;
10816 hlinfo->mouse_face_window = window;
10817 hlinfo->mouse_face_face_id = TOOL_BAR_FACE_ID;
10818
10819 /* Display it as active. */
10820 show_mouse_face (hlinfo, draw);
10821 hlinfo->mouse_face_image_state = draw;
10822 }
10823
10824 set_help_echo:
10825
10826 /* Set help_echo_string to a help string to display for this tool-bar item.
10827 XTread_socket does the rest. */
10828 help_echo_object = help_echo_window = Qnil;
10829 help_echo_pos = -1;
10830 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_HELP);
10831 if (NILP (help_echo_string))
10832 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_CAPTION);
10833 }
10834
10835 #endif /* HAVE_WINDOW_SYSTEM */
10836
10837
10838 \f
10839 /************************************************************************
10840 Horizontal scrolling
10841 ************************************************************************/
10842
10843 static int hscroll_window_tree (Lisp_Object);
10844 static int hscroll_windows (Lisp_Object);
10845
10846 /* For all leaf windows in the window tree rooted at WINDOW, set their
10847 hscroll value so that PT is (i) visible in the window, and (ii) so
10848 that it is not within a certain margin at the window's left and
10849 right border. Value is non-zero if any window's hscroll has been
10850 changed. */
10851
10852 static int
10853 hscroll_window_tree (Lisp_Object window)
10854 {
10855 int hscrolled_p = 0;
10856 int hscroll_relative_p = FLOATP (Vhscroll_step);
10857 int hscroll_step_abs = 0;
10858 double hscroll_step_rel = 0;
10859
10860 if (hscroll_relative_p)
10861 {
10862 hscroll_step_rel = XFLOAT_DATA (Vhscroll_step);
10863 if (hscroll_step_rel < 0)
10864 {
10865 hscroll_relative_p = 0;
10866 hscroll_step_abs = 0;
10867 }
10868 }
10869 else if (INTEGERP (Vhscroll_step))
10870 {
10871 hscroll_step_abs = XINT (Vhscroll_step);
10872 if (hscroll_step_abs < 0)
10873 hscroll_step_abs = 0;
10874 }
10875 else
10876 hscroll_step_abs = 0;
10877
10878 while (WINDOWP (window))
10879 {
10880 struct window *w = XWINDOW (window);
10881
10882 if (WINDOWP (w->hchild))
10883 hscrolled_p |= hscroll_window_tree (w->hchild);
10884 else if (WINDOWP (w->vchild))
10885 hscrolled_p |= hscroll_window_tree (w->vchild);
10886 else if (w->cursor.vpos >= 0)
10887 {
10888 int h_margin;
10889 int text_area_width;
10890 struct glyph_row *current_cursor_row
10891 = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
10892 struct glyph_row *desired_cursor_row
10893 = MATRIX_ROW (w->desired_matrix, w->cursor.vpos);
10894 struct glyph_row *cursor_row
10895 = (desired_cursor_row->enabled_p
10896 ? desired_cursor_row
10897 : current_cursor_row);
10898
10899 text_area_width = window_box_width (w, TEXT_AREA);
10900
10901 /* Scroll when cursor is inside this scroll margin. */
10902 h_margin = hscroll_margin * WINDOW_FRAME_COLUMN_WIDTH (w);
10903
10904 if (!NILP (Fbuffer_local_value (Qauto_hscroll_mode, w->buffer))
10905 && ((XFASTINT (w->hscroll)
10906 && w->cursor.x <= h_margin)
10907 || (cursor_row->enabled_p
10908 && cursor_row->truncated_on_right_p
10909 && (w->cursor.x >= text_area_width - h_margin))))
10910 {
10911 struct it it;
10912 int hscroll;
10913 struct buffer *saved_current_buffer;
10914 EMACS_INT pt;
10915 int wanted_x;
10916
10917 /* Find point in a display of infinite width. */
10918 saved_current_buffer = current_buffer;
10919 current_buffer = XBUFFER (w->buffer);
10920
10921 if (w == XWINDOW (selected_window))
10922 pt = PT;
10923 else
10924 {
10925 pt = marker_position (w->pointm);
10926 pt = max (BEGV, pt);
10927 pt = min (ZV, pt);
10928 }
10929
10930 /* Move iterator to pt starting at cursor_row->start in
10931 a line with infinite width. */
10932 init_to_row_start (&it, w, cursor_row);
10933 it.last_visible_x = INFINITY;
10934 move_it_in_display_line_to (&it, pt, -1, MOVE_TO_POS);
10935 current_buffer = saved_current_buffer;
10936
10937 /* Position cursor in window. */
10938 if (!hscroll_relative_p && hscroll_step_abs == 0)
10939 hscroll = max (0, (it.current_x
10940 - (ITERATOR_AT_END_OF_LINE_P (&it)
10941 ? (text_area_width - 4 * FRAME_COLUMN_WIDTH (it.f))
10942 : (text_area_width / 2))))
10943 / FRAME_COLUMN_WIDTH (it.f);
10944 else if (w->cursor.x >= text_area_width - h_margin)
10945 {
10946 if (hscroll_relative_p)
10947 wanted_x = text_area_width * (1 - hscroll_step_rel)
10948 - h_margin;
10949 else
10950 wanted_x = text_area_width
10951 - hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
10952 - h_margin;
10953 hscroll
10954 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
10955 }
10956 else
10957 {
10958 if (hscroll_relative_p)
10959 wanted_x = text_area_width * hscroll_step_rel
10960 + h_margin;
10961 else
10962 wanted_x = hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
10963 + h_margin;
10964 hscroll
10965 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
10966 }
10967 hscroll = max (hscroll, XFASTINT (w->min_hscroll));
10968
10969 /* Don't call Fset_window_hscroll if value hasn't
10970 changed because it will prevent redisplay
10971 optimizations. */
10972 if (XFASTINT (w->hscroll) != hscroll)
10973 {
10974 XBUFFER (w->buffer)->prevent_redisplay_optimizations_p = 1;
10975 w->hscroll = make_number (hscroll);
10976 hscrolled_p = 1;
10977 }
10978 }
10979 }
10980
10981 window = w->next;
10982 }
10983
10984 /* Value is non-zero if hscroll of any leaf window has been changed. */
10985 return hscrolled_p;
10986 }
10987
10988
10989 /* Set hscroll so that cursor is visible and not inside horizontal
10990 scroll margins for all windows in the tree rooted at WINDOW. See
10991 also hscroll_window_tree above. Value is non-zero if any window's
10992 hscroll has been changed. If it has, desired matrices on the frame
10993 of WINDOW are cleared. */
10994
10995 static int
10996 hscroll_windows (Lisp_Object window)
10997 {
10998 int hscrolled_p = hscroll_window_tree (window);
10999 if (hscrolled_p)
11000 clear_desired_matrices (XFRAME (WINDOW_FRAME (XWINDOW (window))));
11001 return hscrolled_p;
11002 }
11003
11004
11005 \f
11006 /************************************************************************
11007 Redisplay
11008 ************************************************************************/
11009
11010 /* Variables holding some state of redisplay if GLYPH_DEBUG is defined
11011 to a non-zero value. This is sometimes handy to have in a debugger
11012 session. */
11013
11014 #if GLYPH_DEBUG
11015
11016 /* First and last unchanged row for try_window_id. */
11017
11018 int debug_first_unchanged_at_end_vpos;
11019 int debug_last_unchanged_at_beg_vpos;
11020
11021 /* Delta vpos and y. */
11022
11023 int debug_dvpos, debug_dy;
11024
11025 /* Delta in characters and bytes for try_window_id. */
11026
11027 EMACS_INT debug_delta, debug_delta_bytes;
11028
11029 /* Values of window_end_pos and window_end_vpos at the end of
11030 try_window_id. */
11031
11032 EMACS_INT debug_end_vpos;
11033
11034 /* Append a string to W->desired_matrix->method. FMT is a printf
11035 format string. A1...A9 are a supplement for a variable-length
11036 argument list. If trace_redisplay_p is non-zero also printf the
11037 resulting string to stderr. */
11038
11039 static void
11040 debug_method_add (w, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9)
11041 struct window *w;
11042 char *fmt;
11043 int a1, a2, a3, a4, a5, a6, a7, a8, a9;
11044 {
11045 char buffer[512];
11046 char *method = w->desired_matrix->method;
11047 int len = strlen (method);
11048 int size = sizeof w->desired_matrix->method;
11049 int remaining = size - len - 1;
11050
11051 sprintf (buffer, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9);
11052 if (len && remaining)
11053 {
11054 method[len] = '|';
11055 --remaining, ++len;
11056 }
11057
11058 strncpy (method + len, buffer, remaining);
11059
11060 if (trace_redisplay_p)
11061 fprintf (stderr, "%p (%s): %s\n",
11062 w,
11063 ((BUFFERP (w->buffer)
11064 && STRINGP (XBUFFER (w->buffer)->name))
11065 ? SSDATA (XBUFFER (w->buffer)->name)
11066 : "no buffer"),
11067 buffer);
11068 }
11069
11070 #endif /* GLYPH_DEBUG */
11071
11072
11073 /* Value is non-zero if all changes in window W, which displays
11074 current_buffer, are in the text between START and END. START is a
11075 buffer position, END is given as a distance from Z. Used in
11076 redisplay_internal for display optimization. */
11077
11078 static INLINE int
11079 text_outside_line_unchanged_p (struct window *w,
11080 EMACS_INT start, EMACS_INT end)
11081 {
11082 int unchanged_p = 1;
11083
11084 /* If text or overlays have changed, see where. */
11085 if (XFASTINT (w->last_modified) < MODIFF
11086 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
11087 {
11088 /* Gap in the line? */
11089 if (GPT < start || Z - GPT < end)
11090 unchanged_p = 0;
11091
11092 /* Changes start in front of the line, or end after it? */
11093 if (unchanged_p
11094 && (BEG_UNCHANGED < start - 1
11095 || END_UNCHANGED < end))
11096 unchanged_p = 0;
11097
11098 /* If selective display, can't optimize if changes start at the
11099 beginning of the line. */
11100 if (unchanged_p
11101 && INTEGERP (BVAR (current_buffer, selective_display))
11102 && XINT (BVAR (current_buffer, selective_display)) > 0
11103 && (BEG_UNCHANGED < start || GPT <= start))
11104 unchanged_p = 0;
11105
11106 /* If there are overlays at the start or end of the line, these
11107 may have overlay strings with newlines in them. A change at
11108 START, for instance, may actually concern the display of such
11109 overlay strings as well, and they are displayed on different
11110 lines. So, quickly rule out this case. (For the future, it
11111 might be desirable to implement something more telling than
11112 just BEG/END_UNCHANGED.) */
11113 if (unchanged_p)
11114 {
11115 if (BEG + BEG_UNCHANGED == start
11116 && overlay_touches_p (start))
11117 unchanged_p = 0;
11118 if (END_UNCHANGED == end
11119 && overlay_touches_p (Z - end))
11120 unchanged_p = 0;
11121 }
11122
11123 /* Under bidi reordering, adding or deleting a character in the
11124 beginning of a paragraph, before the first strong directional
11125 character, can change the base direction of the paragraph (unless
11126 the buffer specifies a fixed paragraph direction), which will
11127 require to redisplay the whole paragraph. It might be worthwhile
11128 to find the paragraph limits and widen the range of redisplayed
11129 lines to that, but for now just give up this optimization. */
11130 if (!NILP (BVAR (XBUFFER (w->buffer), bidi_display_reordering))
11131 && NILP (BVAR (XBUFFER (w->buffer), bidi_paragraph_direction)))
11132 unchanged_p = 0;
11133 }
11134
11135 return unchanged_p;
11136 }
11137
11138
11139 /* Do a frame update, taking possible shortcuts into account. This is
11140 the main external entry point for redisplay.
11141
11142 If the last redisplay displayed an echo area message and that message
11143 is no longer requested, we clear the echo area or bring back the
11144 mini-buffer if that is in use. */
11145
11146 void
11147 redisplay (void)
11148 {
11149 redisplay_internal ();
11150 }
11151
11152
11153 static Lisp_Object
11154 overlay_arrow_string_or_property (Lisp_Object var)
11155 {
11156 Lisp_Object val;
11157
11158 if (val = Fget (var, Qoverlay_arrow_string), STRINGP (val))
11159 return val;
11160
11161 return Voverlay_arrow_string;
11162 }
11163
11164 /* Return 1 if there are any overlay-arrows in current_buffer. */
11165 static int
11166 overlay_arrow_in_current_buffer_p (void)
11167 {
11168 Lisp_Object vlist;
11169
11170 for (vlist = Voverlay_arrow_variable_list;
11171 CONSP (vlist);
11172 vlist = XCDR (vlist))
11173 {
11174 Lisp_Object var = XCAR (vlist);
11175 Lisp_Object val;
11176
11177 if (!SYMBOLP (var))
11178 continue;
11179 val = find_symbol_value (var);
11180 if (MARKERP (val)
11181 && current_buffer == XMARKER (val)->buffer)
11182 return 1;
11183 }
11184 return 0;
11185 }
11186
11187
11188 /* Return 1 if any overlay_arrows have moved or overlay-arrow-string
11189 has changed. */
11190
11191 static int
11192 overlay_arrows_changed_p (void)
11193 {
11194 Lisp_Object vlist;
11195
11196 for (vlist = Voverlay_arrow_variable_list;
11197 CONSP (vlist);
11198 vlist = XCDR (vlist))
11199 {
11200 Lisp_Object var = XCAR (vlist);
11201 Lisp_Object val, pstr;
11202
11203 if (!SYMBOLP (var))
11204 continue;
11205 val = find_symbol_value (var);
11206 if (!MARKERP (val))
11207 continue;
11208 if (! EQ (COERCE_MARKER (val),
11209 Fget (var, Qlast_arrow_position))
11210 || ! (pstr = overlay_arrow_string_or_property (var),
11211 EQ (pstr, Fget (var, Qlast_arrow_string))))
11212 return 1;
11213 }
11214 return 0;
11215 }
11216
11217 /* Mark overlay arrows to be updated on next redisplay. */
11218
11219 static void
11220 update_overlay_arrows (int up_to_date)
11221 {
11222 Lisp_Object vlist;
11223
11224 for (vlist = Voverlay_arrow_variable_list;
11225 CONSP (vlist);
11226 vlist = XCDR (vlist))
11227 {
11228 Lisp_Object var = XCAR (vlist);
11229
11230 if (!SYMBOLP (var))
11231 continue;
11232
11233 if (up_to_date > 0)
11234 {
11235 Lisp_Object val = find_symbol_value (var);
11236 Fput (var, Qlast_arrow_position,
11237 COERCE_MARKER (val));
11238 Fput (var, Qlast_arrow_string,
11239 overlay_arrow_string_or_property (var));
11240 }
11241 else if (up_to_date < 0
11242 || !NILP (Fget (var, Qlast_arrow_position)))
11243 {
11244 Fput (var, Qlast_arrow_position, Qt);
11245 Fput (var, Qlast_arrow_string, Qt);
11246 }
11247 }
11248 }
11249
11250
11251 /* Return overlay arrow string to display at row.
11252 Return integer (bitmap number) for arrow bitmap in left fringe.
11253 Return nil if no overlay arrow. */
11254
11255 static Lisp_Object
11256 overlay_arrow_at_row (struct it *it, struct glyph_row *row)
11257 {
11258 Lisp_Object vlist;
11259
11260 for (vlist = Voverlay_arrow_variable_list;
11261 CONSP (vlist);
11262 vlist = XCDR (vlist))
11263 {
11264 Lisp_Object var = XCAR (vlist);
11265 Lisp_Object val;
11266
11267 if (!SYMBOLP (var))
11268 continue;
11269
11270 val = find_symbol_value (var);
11271
11272 if (MARKERP (val)
11273 && current_buffer == XMARKER (val)->buffer
11274 && (MATRIX_ROW_START_CHARPOS (row) == marker_position (val)))
11275 {
11276 if (FRAME_WINDOW_P (it->f)
11277 /* FIXME: if ROW->reversed_p is set, this should test
11278 the right fringe, not the left one. */
11279 && WINDOW_LEFT_FRINGE_WIDTH (it->w) > 0)
11280 {
11281 #ifdef HAVE_WINDOW_SYSTEM
11282 if (val = Fget (var, Qoverlay_arrow_bitmap), SYMBOLP (val))
11283 {
11284 int fringe_bitmap;
11285 if ((fringe_bitmap = lookup_fringe_bitmap (val)) != 0)
11286 return make_number (fringe_bitmap);
11287 }
11288 #endif
11289 return make_number (-1); /* Use default arrow bitmap */
11290 }
11291 return overlay_arrow_string_or_property (var);
11292 }
11293 }
11294
11295 return Qnil;
11296 }
11297
11298 /* Return 1 if point moved out of or into a composition. Otherwise
11299 return 0. PREV_BUF and PREV_PT are the last point buffer and
11300 position. BUF and PT are the current point buffer and position. */
11301
11302 int
11303 check_point_in_composition (struct buffer *prev_buf, EMACS_INT prev_pt,
11304 struct buffer *buf, EMACS_INT pt)
11305 {
11306 EMACS_INT start, end;
11307 Lisp_Object prop;
11308 Lisp_Object buffer;
11309
11310 XSETBUFFER (buffer, buf);
11311 /* Check a composition at the last point if point moved within the
11312 same buffer. */
11313 if (prev_buf == buf)
11314 {
11315 if (prev_pt == pt)
11316 /* Point didn't move. */
11317 return 0;
11318
11319 if (prev_pt > BUF_BEGV (buf) && prev_pt < BUF_ZV (buf)
11320 && find_composition (prev_pt, -1, &start, &end, &prop, buffer)
11321 && COMPOSITION_VALID_P (start, end, prop)
11322 && start < prev_pt && end > prev_pt)
11323 /* The last point was within the composition. Return 1 iff
11324 point moved out of the composition. */
11325 return (pt <= start || pt >= end);
11326 }
11327
11328 /* Check a composition at the current point. */
11329 return (pt > BUF_BEGV (buf) && pt < BUF_ZV (buf)
11330 && find_composition (pt, -1, &start, &end, &prop, buffer)
11331 && COMPOSITION_VALID_P (start, end, prop)
11332 && start < pt && end > pt);
11333 }
11334
11335
11336 /* Reconsider the setting of B->clip_changed which is displayed
11337 in window W. */
11338
11339 static INLINE void
11340 reconsider_clip_changes (struct window *w, struct buffer *b)
11341 {
11342 if (b->clip_changed
11343 && !NILP (w->window_end_valid)
11344 && w->current_matrix->buffer == b
11345 && w->current_matrix->zv == BUF_ZV (b)
11346 && w->current_matrix->begv == BUF_BEGV (b))
11347 b->clip_changed = 0;
11348
11349 /* If display wasn't paused, and W is not a tool bar window, see if
11350 point has been moved into or out of a composition. In that case,
11351 we set b->clip_changed to 1 to force updating the screen. If
11352 b->clip_changed has already been set to 1, we can skip this
11353 check. */
11354 if (!b->clip_changed
11355 && BUFFERP (w->buffer) && !NILP (w->window_end_valid))
11356 {
11357 EMACS_INT pt;
11358
11359 if (w == XWINDOW (selected_window))
11360 pt = PT;
11361 else
11362 pt = marker_position (w->pointm);
11363
11364 if ((w->current_matrix->buffer != XBUFFER (w->buffer)
11365 || pt != XINT (w->last_point))
11366 && check_point_in_composition (w->current_matrix->buffer,
11367 XINT (w->last_point),
11368 XBUFFER (w->buffer), pt))
11369 b->clip_changed = 1;
11370 }
11371 }
11372 \f
11373
11374 /* Select FRAME to forward the values of frame-local variables into C
11375 variables so that the redisplay routines can access those values
11376 directly. */
11377
11378 static void
11379 select_frame_for_redisplay (Lisp_Object frame)
11380 {
11381 Lisp_Object tail, tem;
11382 Lisp_Object old = selected_frame;
11383 struct Lisp_Symbol *sym;
11384
11385 xassert (FRAMEP (frame) && FRAME_LIVE_P (XFRAME (frame)));
11386
11387 selected_frame = frame;
11388
11389 do {
11390 for (tail = XFRAME (frame)->param_alist; CONSP (tail); tail = XCDR (tail))
11391 if (CONSP (XCAR (tail))
11392 && (tem = XCAR (XCAR (tail)),
11393 SYMBOLP (tem))
11394 && (sym = indirect_variable (XSYMBOL (tem)),
11395 sym->redirect == SYMBOL_LOCALIZED)
11396 && sym->val.blv->frame_local)
11397 /* Use find_symbol_value rather than Fsymbol_value
11398 to avoid an error if it is void. */
11399 find_symbol_value (tem);
11400 } while (!EQ (frame, old) && (frame = old, 1));
11401 }
11402
11403
11404 #define STOP_POLLING \
11405 do { if (! polling_stopped_here) stop_polling (); \
11406 polling_stopped_here = 1; } while (0)
11407
11408 #define RESUME_POLLING \
11409 do { if (polling_stopped_here) start_polling (); \
11410 polling_stopped_here = 0; } while (0)
11411
11412
11413 /* Perhaps in the future avoid recentering windows if it
11414 is not necessary; currently that causes some problems. */
11415
11416 static void
11417 redisplay_internal (void)
11418 {
11419 struct window *w = XWINDOW (selected_window);
11420 struct window *sw;
11421 struct frame *fr;
11422 int pending;
11423 int must_finish = 0;
11424 struct text_pos tlbufpos, tlendpos;
11425 int number_of_visible_frames;
11426 int count, count1;
11427 struct frame *sf;
11428 int polling_stopped_here = 0;
11429 Lisp_Object old_frame = selected_frame;
11430
11431 /* Non-zero means redisplay has to consider all windows on all
11432 frames. Zero means, only selected_window is considered. */
11433 int consider_all_windows_p;
11434
11435 TRACE ((stderr, "redisplay_internal %d\n", redisplaying_p));
11436
11437 /* No redisplay if running in batch mode or frame is not yet fully
11438 initialized, or redisplay is explicitly turned off by setting
11439 Vinhibit_redisplay. */
11440 if (FRAME_INITIAL_P (SELECTED_FRAME ())
11441 || !NILP (Vinhibit_redisplay))
11442 return;
11443
11444 /* Don't examine these until after testing Vinhibit_redisplay.
11445 When Emacs is shutting down, perhaps because its connection to
11446 X has dropped, we should not look at them at all. */
11447 fr = XFRAME (w->frame);
11448 sf = SELECTED_FRAME ();
11449
11450 if (!fr->glyphs_initialized_p)
11451 return;
11452
11453 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS)
11454 if (popup_activated ())
11455 return;
11456 #endif
11457
11458 /* I don't think this happens but let's be paranoid. */
11459 if (redisplaying_p)
11460 return;
11461
11462 /* Record a function that resets redisplaying_p to its old value
11463 when we leave this function. */
11464 count = SPECPDL_INDEX ();
11465 record_unwind_protect (unwind_redisplay,
11466 Fcons (make_number (redisplaying_p), selected_frame));
11467 ++redisplaying_p;
11468 specbind (Qinhibit_free_realized_faces, Qnil);
11469
11470 {
11471 Lisp_Object tail, frame;
11472
11473 FOR_EACH_FRAME (tail, frame)
11474 {
11475 struct frame *f = XFRAME (frame);
11476 f->already_hscrolled_p = 0;
11477 }
11478 }
11479
11480 retry:
11481 /* Remember the currently selected window. */
11482 sw = w;
11483
11484 if (!EQ (old_frame, selected_frame)
11485 && FRAME_LIVE_P (XFRAME (old_frame)))
11486 /* When running redisplay, we play a bit fast-and-loose and allow e.g.
11487 selected_frame and selected_window to be temporarily out-of-sync so
11488 when we come back here via `goto retry', we need to resync because we
11489 may need to run Elisp code (via prepare_menu_bars). */
11490 select_frame_for_redisplay (old_frame);
11491
11492 pending = 0;
11493 reconsider_clip_changes (w, current_buffer);
11494 last_escape_glyph_frame = NULL;
11495 last_escape_glyph_face_id = (1 << FACE_ID_BITS);
11496 last_glyphless_glyph_frame = NULL;
11497 last_glyphless_glyph_face_id = (1 << FACE_ID_BITS);
11498
11499 /* If new fonts have been loaded that make a glyph matrix adjustment
11500 necessary, do it. */
11501 if (fonts_changed_p)
11502 {
11503 adjust_glyphs (NULL);
11504 ++windows_or_buffers_changed;
11505 fonts_changed_p = 0;
11506 }
11507
11508 /* If face_change_count is non-zero, init_iterator will free all
11509 realized faces, which includes the faces referenced from current
11510 matrices. So, we can't reuse current matrices in this case. */
11511 if (face_change_count)
11512 ++windows_or_buffers_changed;
11513
11514 if ((FRAME_TERMCAP_P (sf) || FRAME_MSDOS_P (sf))
11515 && FRAME_TTY (sf)->previous_frame != sf)
11516 {
11517 /* Since frames on a single ASCII terminal share the same
11518 display area, displaying a different frame means redisplay
11519 the whole thing. */
11520 windows_or_buffers_changed++;
11521 SET_FRAME_GARBAGED (sf);
11522 #ifndef DOS_NT
11523 set_tty_color_mode (FRAME_TTY (sf), sf);
11524 #endif
11525 FRAME_TTY (sf)->previous_frame = sf;
11526 }
11527
11528 /* Set the visible flags for all frames. Do this before checking
11529 for resized or garbaged frames; they want to know if their frames
11530 are visible. See the comment in frame.h for
11531 FRAME_SAMPLE_VISIBILITY. */
11532 {
11533 Lisp_Object tail, frame;
11534
11535 number_of_visible_frames = 0;
11536
11537 FOR_EACH_FRAME (tail, frame)
11538 {
11539 struct frame *f = XFRAME (frame);
11540
11541 FRAME_SAMPLE_VISIBILITY (f);
11542 if (FRAME_VISIBLE_P (f))
11543 ++number_of_visible_frames;
11544 clear_desired_matrices (f);
11545 }
11546 }
11547
11548 /* Notice any pending interrupt request to change frame size. */
11549 do_pending_window_change (1);
11550
11551 /* do_pending_window_change could change the selected_window due to
11552 frame resizing which makes the selected window too small. */
11553 if (WINDOWP (selected_window) && (w = XWINDOW (selected_window)) != sw)
11554 {
11555 sw = w;
11556 reconsider_clip_changes (w, current_buffer);
11557 }
11558
11559 /* Clear frames marked as garbaged. */
11560 if (frame_garbaged)
11561 clear_garbaged_frames ();
11562
11563 /* Build menubar and tool-bar items. */
11564 if (NILP (Vmemory_full))
11565 prepare_menu_bars ();
11566
11567 if (windows_or_buffers_changed)
11568 update_mode_lines++;
11569
11570 /* Detect case that we need to write or remove a star in the mode line. */
11571 if ((SAVE_MODIFF < MODIFF) != !NILP (w->last_had_star))
11572 {
11573 w->update_mode_line = Qt;
11574 if (buffer_shared > 1)
11575 update_mode_lines++;
11576 }
11577
11578 /* Avoid invocation of point motion hooks by `current_column' below. */
11579 count1 = SPECPDL_INDEX ();
11580 specbind (Qinhibit_point_motion_hooks, Qt);
11581
11582 /* If %c is in the mode line, update it if needed. */
11583 if (!NILP (w->column_number_displayed)
11584 /* This alternative quickly identifies a common case
11585 where no change is needed. */
11586 && !(PT == XFASTINT (w->last_point)
11587 && XFASTINT (w->last_modified) >= MODIFF
11588 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
11589 && (XFASTINT (w->column_number_displayed) != current_column ()))
11590 w->update_mode_line = Qt;
11591
11592 unbind_to (count1, Qnil);
11593
11594 FRAME_SCROLL_BOTTOM_VPOS (XFRAME (w->frame)) = -1;
11595
11596 /* The variable buffer_shared is set in redisplay_window and
11597 indicates that we redisplay a buffer in different windows. See
11598 there. */
11599 consider_all_windows_p = (update_mode_lines || buffer_shared > 1
11600 || cursor_type_changed);
11601
11602 /* If specs for an arrow have changed, do thorough redisplay
11603 to ensure we remove any arrow that should no longer exist. */
11604 if (overlay_arrows_changed_p ())
11605 consider_all_windows_p = windows_or_buffers_changed = 1;
11606
11607 /* Normally the message* functions will have already displayed and
11608 updated the echo area, but the frame may have been trashed, or
11609 the update may have been preempted, so display the echo area
11610 again here. Checking message_cleared_p captures the case that
11611 the echo area should be cleared. */
11612 if ((!NILP (echo_area_buffer[0]) && !display_last_displayed_message_p)
11613 || (!NILP (echo_area_buffer[1]) && display_last_displayed_message_p)
11614 || (message_cleared_p
11615 && minibuf_level == 0
11616 /* If the mini-window is currently selected, this means the
11617 echo-area doesn't show through. */
11618 && !MINI_WINDOW_P (XWINDOW (selected_window))))
11619 {
11620 int window_height_changed_p = echo_area_display (0);
11621 must_finish = 1;
11622
11623 /* If we don't display the current message, don't clear the
11624 message_cleared_p flag, because, if we did, we wouldn't clear
11625 the echo area in the next redisplay which doesn't preserve
11626 the echo area. */
11627 if (!display_last_displayed_message_p)
11628 message_cleared_p = 0;
11629
11630 if (fonts_changed_p)
11631 goto retry;
11632 else if (window_height_changed_p)
11633 {
11634 consider_all_windows_p = 1;
11635 ++update_mode_lines;
11636 ++windows_or_buffers_changed;
11637
11638 /* If window configuration was changed, frames may have been
11639 marked garbaged. Clear them or we will experience
11640 surprises wrt scrolling. */
11641 if (frame_garbaged)
11642 clear_garbaged_frames ();
11643 }
11644 }
11645 else if (EQ (selected_window, minibuf_window)
11646 && (current_buffer->clip_changed
11647 || XFASTINT (w->last_modified) < MODIFF
11648 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
11649 && resize_mini_window (w, 0))
11650 {
11651 /* Resized active mini-window to fit the size of what it is
11652 showing if its contents might have changed. */
11653 must_finish = 1;
11654 /* FIXME: this causes all frames to be updated, which seems unnecessary
11655 since only the current frame needs to be considered. This function needs
11656 to be rewritten with two variables, consider_all_windows and
11657 consider_all_frames. */
11658 consider_all_windows_p = 1;
11659 ++windows_or_buffers_changed;
11660 ++update_mode_lines;
11661
11662 /* If window configuration was changed, frames may have been
11663 marked garbaged. Clear them or we will experience
11664 surprises wrt scrolling. */
11665 if (frame_garbaged)
11666 clear_garbaged_frames ();
11667 }
11668
11669
11670 /* If showing the region, and mark has changed, we must redisplay
11671 the whole window. The assignment to this_line_start_pos prevents
11672 the optimization directly below this if-statement. */
11673 if (((!NILP (Vtransient_mark_mode)
11674 && !NILP (BVAR (XBUFFER (w->buffer), mark_active)))
11675 != !NILP (w->region_showing))
11676 || (!NILP (w->region_showing)
11677 && !EQ (w->region_showing,
11678 Fmarker_position (BVAR (XBUFFER (w->buffer), mark)))))
11679 CHARPOS (this_line_start_pos) = 0;
11680
11681 /* Optimize the case that only the line containing the cursor in the
11682 selected window has changed. Variables starting with this_ are
11683 set in display_line and record information about the line
11684 containing the cursor. */
11685 tlbufpos = this_line_start_pos;
11686 tlendpos = this_line_end_pos;
11687 if (!consider_all_windows_p
11688 && CHARPOS (tlbufpos) > 0
11689 && NILP (w->update_mode_line)
11690 && !current_buffer->clip_changed
11691 && !current_buffer->prevent_redisplay_optimizations_p
11692 && FRAME_VISIBLE_P (XFRAME (w->frame))
11693 && !FRAME_OBSCURED_P (XFRAME (w->frame))
11694 /* Make sure recorded data applies to current buffer, etc. */
11695 && this_line_buffer == current_buffer
11696 && current_buffer == XBUFFER (w->buffer)
11697 && NILP (w->force_start)
11698 && NILP (w->optional_new_start)
11699 /* Point must be on the line that we have info recorded about. */
11700 && PT >= CHARPOS (tlbufpos)
11701 && PT <= Z - CHARPOS (tlendpos)
11702 /* All text outside that line, including its final newline,
11703 must be unchanged. */
11704 && text_outside_line_unchanged_p (w, CHARPOS (tlbufpos),
11705 CHARPOS (tlendpos)))
11706 {
11707 if (CHARPOS (tlbufpos) > BEGV
11708 && FETCH_BYTE (BYTEPOS (tlbufpos) - 1) != '\n'
11709 && (CHARPOS (tlbufpos) == ZV
11710 || FETCH_BYTE (BYTEPOS (tlbufpos)) == '\n'))
11711 /* Former continuation line has disappeared by becoming empty. */
11712 goto cancel;
11713 else if (XFASTINT (w->last_modified) < MODIFF
11714 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF
11715 || MINI_WINDOW_P (w))
11716 {
11717 /* We have to handle the case of continuation around a
11718 wide-column character (see the comment in indent.c around
11719 line 1340).
11720
11721 For instance, in the following case:
11722
11723 -------- Insert --------
11724 K_A_N_\\ `a' K_A_N_a\ `X_' are wide-column chars.
11725 J_I_ ==> J_I_ `^^' are cursors.
11726 ^^ ^^
11727 -------- --------
11728
11729 As we have to redraw the line above, we cannot use this
11730 optimization. */
11731
11732 struct it it;
11733 int line_height_before = this_line_pixel_height;
11734
11735 /* Note that start_display will handle the case that the
11736 line starting at tlbufpos is a continuation line. */
11737 start_display (&it, w, tlbufpos);
11738
11739 /* Implementation note: It this still necessary? */
11740 if (it.current_x != this_line_start_x)
11741 goto cancel;
11742
11743 TRACE ((stderr, "trying display optimization 1\n"));
11744 w->cursor.vpos = -1;
11745 overlay_arrow_seen = 0;
11746 it.vpos = this_line_vpos;
11747 it.current_y = this_line_y;
11748 it.glyph_row = MATRIX_ROW (w->desired_matrix, this_line_vpos);
11749 display_line (&it);
11750
11751 /* If line contains point, is not continued,
11752 and ends at same distance from eob as before, we win. */
11753 if (w->cursor.vpos >= 0
11754 /* Line is not continued, otherwise this_line_start_pos
11755 would have been set to 0 in display_line. */
11756 && CHARPOS (this_line_start_pos)
11757 /* Line ends as before. */
11758 && CHARPOS (this_line_end_pos) == CHARPOS (tlendpos)
11759 /* Line has same height as before. Otherwise other lines
11760 would have to be shifted up or down. */
11761 && this_line_pixel_height == line_height_before)
11762 {
11763 /* If this is not the window's last line, we must adjust
11764 the charstarts of the lines below. */
11765 if (it.current_y < it.last_visible_y)
11766 {
11767 struct glyph_row *row
11768 = MATRIX_ROW (w->current_matrix, this_line_vpos + 1);
11769 EMACS_INT delta, delta_bytes;
11770
11771 /* We used to distinguish between two cases here,
11772 conditioned by Z - CHARPOS (tlendpos) == ZV, for
11773 when the line ends in a newline or the end of the
11774 buffer's accessible portion. But both cases did
11775 the same, so they were collapsed. */
11776 delta = (Z
11777 - CHARPOS (tlendpos)
11778 - MATRIX_ROW_START_CHARPOS (row));
11779 delta_bytes = (Z_BYTE
11780 - BYTEPOS (tlendpos)
11781 - MATRIX_ROW_START_BYTEPOS (row));
11782
11783 increment_matrix_positions (w->current_matrix,
11784 this_line_vpos + 1,
11785 w->current_matrix->nrows,
11786 delta, delta_bytes);
11787 }
11788
11789 /* If this row displays text now but previously didn't,
11790 or vice versa, w->window_end_vpos may have to be
11791 adjusted. */
11792 if ((it.glyph_row - 1)->displays_text_p)
11793 {
11794 if (XFASTINT (w->window_end_vpos) < this_line_vpos)
11795 XSETINT (w->window_end_vpos, this_line_vpos);
11796 }
11797 else if (XFASTINT (w->window_end_vpos) == this_line_vpos
11798 && this_line_vpos > 0)
11799 XSETINT (w->window_end_vpos, this_line_vpos - 1);
11800 w->window_end_valid = Qnil;
11801
11802 /* Update hint: No need to try to scroll in update_window. */
11803 w->desired_matrix->no_scrolling_p = 1;
11804
11805 #if GLYPH_DEBUG
11806 *w->desired_matrix->method = 0;
11807 debug_method_add (w, "optimization 1");
11808 #endif
11809 #ifdef HAVE_WINDOW_SYSTEM
11810 update_window_fringes (w, 0);
11811 #endif
11812 goto update;
11813 }
11814 else
11815 goto cancel;
11816 }
11817 else if (/* Cursor position hasn't changed. */
11818 PT == XFASTINT (w->last_point)
11819 /* Make sure the cursor was last displayed
11820 in this window. Otherwise we have to reposition it. */
11821 && 0 <= w->cursor.vpos
11822 && WINDOW_TOTAL_LINES (w) > w->cursor.vpos)
11823 {
11824 if (!must_finish)
11825 {
11826 do_pending_window_change (1);
11827 /* If selected_window changed, redisplay again. */
11828 if (WINDOWP (selected_window)
11829 && (w = XWINDOW (selected_window)) != sw)
11830 goto retry;
11831
11832 /* We used to always goto end_of_redisplay here, but this
11833 isn't enough if we have a blinking cursor. */
11834 if (w->cursor_off_p == w->last_cursor_off_p)
11835 goto end_of_redisplay;
11836 }
11837 goto update;
11838 }
11839 /* If highlighting the region, or if the cursor is in the echo area,
11840 then we can't just move the cursor. */
11841 else if (! (!NILP (Vtransient_mark_mode)
11842 && !NILP (BVAR (current_buffer, mark_active)))
11843 && (EQ (selected_window, BVAR (current_buffer, last_selected_window))
11844 || highlight_nonselected_windows)
11845 && NILP (w->region_showing)
11846 && NILP (Vshow_trailing_whitespace)
11847 && !cursor_in_echo_area)
11848 {
11849 struct it it;
11850 struct glyph_row *row;
11851
11852 /* Skip from tlbufpos to PT and see where it is. Note that
11853 PT may be in invisible text. If so, we will end at the
11854 next visible position. */
11855 init_iterator (&it, w, CHARPOS (tlbufpos), BYTEPOS (tlbufpos),
11856 NULL, DEFAULT_FACE_ID);
11857 it.current_x = this_line_start_x;
11858 it.current_y = this_line_y;
11859 it.vpos = this_line_vpos;
11860
11861 /* The call to move_it_to stops in front of PT, but
11862 moves over before-strings. */
11863 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
11864
11865 if (it.vpos == this_line_vpos
11866 && (row = MATRIX_ROW (w->current_matrix, this_line_vpos),
11867 row->enabled_p))
11868 {
11869 xassert (this_line_vpos == it.vpos);
11870 xassert (this_line_y == it.current_y);
11871 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
11872 #if GLYPH_DEBUG
11873 *w->desired_matrix->method = 0;
11874 debug_method_add (w, "optimization 3");
11875 #endif
11876 goto update;
11877 }
11878 else
11879 goto cancel;
11880 }
11881
11882 cancel:
11883 /* Text changed drastically or point moved off of line. */
11884 SET_MATRIX_ROW_ENABLED_P (w->desired_matrix, this_line_vpos, 0);
11885 }
11886
11887 CHARPOS (this_line_start_pos) = 0;
11888 consider_all_windows_p |= buffer_shared > 1;
11889 ++clear_face_cache_count;
11890 #ifdef HAVE_WINDOW_SYSTEM
11891 ++clear_image_cache_count;
11892 #endif
11893
11894 /* Build desired matrices, and update the display. If
11895 consider_all_windows_p is non-zero, do it for all windows on all
11896 frames. Otherwise do it for selected_window, only. */
11897
11898 if (consider_all_windows_p)
11899 {
11900 Lisp_Object tail, frame;
11901
11902 FOR_EACH_FRAME (tail, frame)
11903 XFRAME (frame)->updated_p = 0;
11904
11905 /* Recompute # windows showing selected buffer. This will be
11906 incremented each time such a window is displayed. */
11907 buffer_shared = 0;
11908
11909 FOR_EACH_FRAME (tail, frame)
11910 {
11911 struct frame *f = XFRAME (frame);
11912
11913 if (FRAME_WINDOW_P (f) || FRAME_TERMCAP_P (f) || f == sf)
11914 {
11915 if (! EQ (frame, selected_frame))
11916 /* Select the frame, for the sake of frame-local
11917 variables. */
11918 select_frame_for_redisplay (frame);
11919
11920 /* Mark all the scroll bars to be removed; we'll redeem
11921 the ones we want when we redisplay their windows. */
11922 if (FRAME_TERMINAL (f)->condemn_scroll_bars_hook)
11923 FRAME_TERMINAL (f)->condemn_scroll_bars_hook (f);
11924
11925 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
11926 redisplay_windows (FRAME_ROOT_WINDOW (f));
11927
11928 /* The X error handler may have deleted that frame. */
11929 if (!FRAME_LIVE_P (f))
11930 continue;
11931
11932 /* Any scroll bars which redisplay_windows should have
11933 nuked should now go away. */
11934 if (FRAME_TERMINAL (f)->judge_scroll_bars_hook)
11935 FRAME_TERMINAL (f)->judge_scroll_bars_hook (f);
11936
11937 /* If fonts changed, display again. */
11938 /* ??? rms: I suspect it is a mistake to jump all the way
11939 back to retry here. It should just retry this frame. */
11940 if (fonts_changed_p)
11941 goto retry;
11942
11943 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
11944 {
11945 /* See if we have to hscroll. */
11946 if (!f->already_hscrolled_p)
11947 {
11948 f->already_hscrolled_p = 1;
11949 if (hscroll_windows (f->root_window))
11950 goto retry;
11951 }
11952
11953 /* Prevent various kinds of signals during display
11954 update. stdio is not robust about handling
11955 signals, which can cause an apparent I/O
11956 error. */
11957 if (interrupt_input)
11958 unrequest_sigio ();
11959 STOP_POLLING;
11960
11961 /* Update the display. */
11962 set_window_update_flags (XWINDOW (f->root_window), 1);
11963 pending |= update_frame (f, 0, 0);
11964 f->updated_p = 1;
11965 }
11966 }
11967 }
11968
11969 if (!EQ (old_frame, selected_frame)
11970 && FRAME_LIVE_P (XFRAME (old_frame)))
11971 /* We played a bit fast-and-loose above and allowed selected_frame
11972 and selected_window to be temporarily out-of-sync but let's make
11973 sure this stays contained. */
11974 select_frame_for_redisplay (old_frame);
11975 eassert (EQ (XFRAME (selected_frame)->selected_window, selected_window));
11976
11977 if (!pending)
11978 {
11979 /* Do the mark_window_display_accurate after all windows have
11980 been redisplayed because this call resets flags in buffers
11981 which are needed for proper redisplay. */
11982 FOR_EACH_FRAME (tail, frame)
11983 {
11984 struct frame *f = XFRAME (frame);
11985 if (f->updated_p)
11986 {
11987 mark_window_display_accurate (f->root_window, 1);
11988 if (FRAME_TERMINAL (f)->frame_up_to_date_hook)
11989 FRAME_TERMINAL (f)->frame_up_to_date_hook (f);
11990 }
11991 }
11992 }
11993 }
11994 else if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
11995 {
11996 Lisp_Object mini_window;
11997 struct frame *mini_frame;
11998
11999 displayed_buffer = XBUFFER (XWINDOW (selected_window)->buffer);
12000 /* Use list_of_error, not Qerror, so that
12001 we catch only errors and don't run the debugger. */
12002 internal_condition_case_1 (redisplay_window_1, selected_window,
12003 list_of_error,
12004 redisplay_window_error);
12005
12006 /* Compare desired and current matrices, perform output. */
12007
12008 update:
12009 /* If fonts changed, display again. */
12010 if (fonts_changed_p)
12011 goto retry;
12012
12013 /* Prevent various kinds of signals during display update.
12014 stdio is not robust about handling signals,
12015 which can cause an apparent I/O error. */
12016 if (interrupt_input)
12017 unrequest_sigio ();
12018 STOP_POLLING;
12019
12020 if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
12021 {
12022 if (hscroll_windows (selected_window))
12023 goto retry;
12024
12025 XWINDOW (selected_window)->must_be_updated_p = 1;
12026 pending = update_frame (sf, 0, 0);
12027 }
12028
12029 /* We may have called echo_area_display at the top of this
12030 function. If the echo area is on another frame, that may
12031 have put text on a frame other than the selected one, so the
12032 above call to update_frame would not have caught it. Catch
12033 it here. */
12034 mini_window = FRAME_MINIBUF_WINDOW (sf);
12035 mini_frame = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
12036
12037 if (mini_frame != sf && FRAME_WINDOW_P (mini_frame))
12038 {
12039 XWINDOW (mini_window)->must_be_updated_p = 1;
12040 pending |= update_frame (mini_frame, 0, 0);
12041 if (!pending && hscroll_windows (mini_window))
12042 goto retry;
12043 }
12044 }
12045
12046 /* If display was paused because of pending input, make sure we do a
12047 thorough update the next time. */
12048 if (pending)
12049 {
12050 /* Prevent the optimization at the beginning of
12051 redisplay_internal that tries a single-line update of the
12052 line containing the cursor in the selected window. */
12053 CHARPOS (this_line_start_pos) = 0;
12054
12055 /* Let the overlay arrow be updated the next time. */
12056 update_overlay_arrows (0);
12057
12058 /* If we pause after scrolling, some rows in the current
12059 matrices of some windows are not valid. */
12060 if (!WINDOW_FULL_WIDTH_P (w)
12061 && !FRAME_WINDOW_P (XFRAME (w->frame)))
12062 update_mode_lines = 1;
12063 }
12064 else
12065 {
12066 if (!consider_all_windows_p)
12067 {
12068 /* This has already been done above if
12069 consider_all_windows_p is set. */
12070 mark_window_display_accurate_1 (w, 1);
12071
12072 /* Say overlay arrows are up to date. */
12073 update_overlay_arrows (1);
12074
12075 if (FRAME_TERMINAL (sf)->frame_up_to_date_hook != 0)
12076 FRAME_TERMINAL (sf)->frame_up_to_date_hook (sf);
12077 }
12078
12079 update_mode_lines = 0;
12080 windows_or_buffers_changed = 0;
12081 cursor_type_changed = 0;
12082 }
12083
12084 /* Start SIGIO interrupts coming again. Having them off during the
12085 code above makes it less likely one will discard output, but not
12086 impossible, since there might be stuff in the system buffer here.
12087 But it is much hairier to try to do anything about that. */
12088 if (interrupt_input)
12089 request_sigio ();
12090 RESUME_POLLING;
12091
12092 /* If a frame has become visible which was not before, redisplay
12093 again, so that we display it. Expose events for such a frame
12094 (which it gets when becoming visible) don't call the parts of
12095 redisplay constructing glyphs, so simply exposing a frame won't
12096 display anything in this case. So, we have to display these
12097 frames here explicitly. */
12098 if (!pending)
12099 {
12100 Lisp_Object tail, frame;
12101 int new_count = 0;
12102
12103 FOR_EACH_FRAME (tail, frame)
12104 {
12105 int this_is_visible = 0;
12106
12107 if (XFRAME (frame)->visible)
12108 this_is_visible = 1;
12109 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
12110 if (XFRAME (frame)->visible)
12111 this_is_visible = 1;
12112
12113 if (this_is_visible)
12114 new_count++;
12115 }
12116
12117 if (new_count != number_of_visible_frames)
12118 windows_or_buffers_changed++;
12119 }
12120
12121 /* Change frame size now if a change is pending. */
12122 do_pending_window_change (1);
12123
12124 /* If we just did a pending size change, or have additional
12125 visible frames, or selected_window changed, redisplay again. */
12126 if ((windows_or_buffers_changed && !pending)
12127 || (WINDOWP (selected_window) && (w = XWINDOW (selected_window)) != sw))
12128 goto retry;
12129
12130 /* Clear the face and image caches.
12131
12132 We used to do this only if consider_all_windows_p. But the cache
12133 needs to be cleared if a timer creates images in the current
12134 buffer (e.g. the test case in Bug#6230). */
12135
12136 if (clear_face_cache_count > CLEAR_FACE_CACHE_COUNT)
12137 {
12138 clear_face_cache (0);
12139 clear_face_cache_count = 0;
12140 }
12141
12142 #ifdef HAVE_WINDOW_SYSTEM
12143 if (clear_image_cache_count > CLEAR_IMAGE_CACHE_COUNT)
12144 {
12145 clear_image_caches (Qnil);
12146 clear_image_cache_count = 0;
12147 }
12148 #endif /* HAVE_WINDOW_SYSTEM */
12149
12150 end_of_redisplay:
12151 unbind_to (count, Qnil);
12152 RESUME_POLLING;
12153 }
12154
12155
12156 /* Redisplay, but leave alone any recent echo area message unless
12157 another message has been requested in its place.
12158
12159 This is useful in situations where you need to redisplay but no
12160 user action has occurred, making it inappropriate for the message
12161 area to be cleared. See tracking_off and
12162 wait_reading_process_output for examples of these situations.
12163
12164 FROM_WHERE is an integer saying from where this function was
12165 called. This is useful for debugging. */
12166
12167 void
12168 redisplay_preserve_echo_area (int from_where)
12169 {
12170 TRACE ((stderr, "redisplay_preserve_echo_area (%d)\n", from_where));
12171
12172 if (!NILP (echo_area_buffer[1]))
12173 {
12174 /* We have a previously displayed message, but no current
12175 message. Redisplay the previous message. */
12176 display_last_displayed_message_p = 1;
12177 redisplay_internal ();
12178 display_last_displayed_message_p = 0;
12179 }
12180 else
12181 redisplay_internal ();
12182
12183 if (FRAME_RIF (SELECTED_FRAME ()) != NULL
12184 && FRAME_RIF (SELECTED_FRAME ())->flush_display_optional)
12185 FRAME_RIF (SELECTED_FRAME ())->flush_display_optional (NULL);
12186 }
12187
12188
12189 /* Function registered with record_unwind_protect in
12190 redisplay_internal. Reset redisplaying_p to the value it had
12191 before redisplay_internal was called, and clear
12192 prevent_freeing_realized_faces_p. It also selects the previously
12193 selected frame, unless it has been deleted (by an X connection
12194 failure during redisplay, for example). */
12195
12196 static Lisp_Object
12197 unwind_redisplay (Lisp_Object val)
12198 {
12199 Lisp_Object old_redisplaying_p, old_frame;
12200
12201 old_redisplaying_p = XCAR (val);
12202 redisplaying_p = XFASTINT (old_redisplaying_p);
12203 old_frame = XCDR (val);
12204 if (! EQ (old_frame, selected_frame)
12205 && FRAME_LIVE_P (XFRAME (old_frame)))
12206 select_frame_for_redisplay (old_frame);
12207 return Qnil;
12208 }
12209
12210
12211 /* Mark the display of window W as accurate or inaccurate. If
12212 ACCURATE_P is non-zero mark display of W as accurate. If
12213 ACCURATE_P is zero, arrange for W to be redisplayed the next time
12214 redisplay_internal is called. */
12215
12216 static void
12217 mark_window_display_accurate_1 (struct window *w, int accurate_p)
12218 {
12219 if (BUFFERP (w->buffer))
12220 {
12221 struct buffer *b = XBUFFER (w->buffer);
12222
12223 w->last_modified
12224 = make_number (accurate_p ? BUF_MODIFF (b) : 0);
12225 w->last_overlay_modified
12226 = make_number (accurate_p ? BUF_OVERLAY_MODIFF (b) : 0);
12227 w->last_had_star
12228 = BUF_MODIFF (b) > BUF_SAVE_MODIFF (b) ? Qt : Qnil;
12229
12230 if (accurate_p)
12231 {
12232 b->clip_changed = 0;
12233 b->prevent_redisplay_optimizations_p = 0;
12234
12235 BUF_UNCHANGED_MODIFIED (b) = BUF_MODIFF (b);
12236 BUF_OVERLAY_UNCHANGED_MODIFIED (b) = BUF_OVERLAY_MODIFF (b);
12237 BUF_BEG_UNCHANGED (b) = BUF_GPT (b) - BUF_BEG (b);
12238 BUF_END_UNCHANGED (b) = BUF_Z (b) - BUF_GPT (b);
12239
12240 w->current_matrix->buffer = b;
12241 w->current_matrix->begv = BUF_BEGV (b);
12242 w->current_matrix->zv = BUF_ZV (b);
12243
12244 w->last_cursor = w->cursor;
12245 w->last_cursor_off_p = w->cursor_off_p;
12246
12247 if (w == XWINDOW (selected_window))
12248 w->last_point = make_number (BUF_PT (b));
12249 else
12250 w->last_point = make_number (XMARKER (w->pointm)->charpos);
12251 }
12252 }
12253
12254 if (accurate_p)
12255 {
12256 w->window_end_valid = w->buffer;
12257 w->update_mode_line = Qnil;
12258 }
12259 }
12260
12261
12262 /* Mark the display of windows in the window tree rooted at WINDOW as
12263 accurate or inaccurate. If ACCURATE_P is non-zero mark display of
12264 windows as accurate. If ACCURATE_P is zero, arrange for windows to
12265 be redisplayed the next time redisplay_internal is called. */
12266
12267 void
12268 mark_window_display_accurate (Lisp_Object window, int accurate_p)
12269 {
12270 struct window *w;
12271
12272 for (; !NILP (window); window = w->next)
12273 {
12274 w = XWINDOW (window);
12275 mark_window_display_accurate_1 (w, accurate_p);
12276
12277 if (!NILP (w->vchild))
12278 mark_window_display_accurate (w->vchild, accurate_p);
12279 if (!NILP (w->hchild))
12280 mark_window_display_accurate (w->hchild, accurate_p);
12281 }
12282
12283 if (accurate_p)
12284 {
12285 update_overlay_arrows (1);
12286 }
12287 else
12288 {
12289 /* Force a thorough redisplay the next time by setting
12290 last_arrow_position and last_arrow_string to t, which is
12291 unequal to any useful value of Voverlay_arrow_... */
12292 update_overlay_arrows (-1);
12293 }
12294 }
12295
12296
12297 /* Return value in display table DP (Lisp_Char_Table *) for character
12298 C. Since a display table doesn't have any parent, we don't have to
12299 follow parent. Do not call this function directly but use the
12300 macro DISP_CHAR_VECTOR. */
12301
12302 Lisp_Object
12303 disp_char_vector (struct Lisp_Char_Table *dp, int c)
12304 {
12305 Lisp_Object val;
12306
12307 if (ASCII_CHAR_P (c))
12308 {
12309 val = dp->ascii;
12310 if (SUB_CHAR_TABLE_P (val))
12311 val = XSUB_CHAR_TABLE (val)->contents[c];
12312 }
12313 else
12314 {
12315 Lisp_Object table;
12316
12317 XSETCHAR_TABLE (table, dp);
12318 val = char_table_ref (table, c);
12319 }
12320 if (NILP (val))
12321 val = dp->defalt;
12322 return val;
12323 }
12324
12325
12326 \f
12327 /***********************************************************************
12328 Window Redisplay
12329 ***********************************************************************/
12330
12331 /* Redisplay all leaf windows in the window tree rooted at WINDOW. */
12332
12333 static void
12334 redisplay_windows (Lisp_Object window)
12335 {
12336 while (!NILP (window))
12337 {
12338 struct window *w = XWINDOW (window);
12339
12340 if (!NILP (w->hchild))
12341 redisplay_windows (w->hchild);
12342 else if (!NILP (w->vchild))
12343 redisplay_windows (w->vchild);
12344 else if (!NILP (w->buffer))
12345 {
12346 displayed_buffer = XBUFFER (w->buffer);
12347 /* Use list_of_error, not Qerror, so that
12348 we catch only errors and don't run the debugger. */
12349 internal_condition_case_1 (redisplay_window_0, window,
12350 list_of_error,
12351 redisplay_window_error);
12352 }
12353
12354 window = w->next;
12355 }
12356 }
12357
12358 static Lisp_Object
12359 redisplay_window_error (Lisp_Object ignore)
12360 {
12361 displayed_buffer->display_error_modiff = BUF_MODIFF (displayed_buffer);
12362 return Qnil;
12363 }
12364
12365 static Lisp_Object
12366 redisplay_window_0 (Lisp_Object window)
12367 {
12368 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
12369 redisplay_window (window, 0);
12370 return Qnil;
12371 }
12372
12373 static Lisp_Object
12374 redisplay_window_1 (Lisp_Object window)
12375 {
12376 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
12377 redisplay_window (window, 1);
12378 return Qnil;
12379 }
12380 \f
12381
12382 /* Set cursor position of W. PT is assumed to be displayed in ROW.
12383 DELTA and DELTA_BYTES are the numbers of characters and bytes by
12384 which positions recorded in ROW differ from current buffer
12385 positions.
12386
12387 Return 0 if cursor is not on this row, 1 otherwise. */
12388
12389 int
12390 set_cursor_from_row (struct window *w, struct glyph_row *row,
12391 struct glyph_matrix *matrix,
12392 EMACS_INT delta, EMACS_INT delta_bytes,
12393 int dy, int dvpos)
12394 {
12395 struct glyph *glyph = row->glyphs[TEXT_AREA];
12396 struct glyph *end = glyph + row->used[TEXT_AREA];
12397 struct glyph *cursor = NULL;
12398 /* The last known character position in row. */
12399 EMACS_INT last_pos = MATRIX_ROW_START_CHARPOS (row) + delta;
12400 int x = row->x;
12401 EMACS_INT pt_old = PT - delta;
12402 EMACS_INT pos_before = MATRIX_ROW_START_CHARPOS (row) + delta;
12403 EMACS_INT pos_after = MATRIX_ROW_END_CHARPOS (row) + delta;
12404 struct glyph *glyph_before = glyph - 1, *glyph_after = end;
12405 /* A glyph beyond the edge of TEXT_AREA which we should never
12406 touch. */
12407 struct glyph *glyphs_end = end;
12408 /* Non-zero means we've found a match for cursor position, but that
12409 glyph has the avoid_cursor_p flag set. */
12410 int match_with_avoid_cursor = 0;
12411 /* Non-zero means we've seen at least one glyph that came from a
12412 display string. */
12413 int string_seen = 0;
12414 /* Largest and smalles buffer positions seen so far during scan of
12415 glyph row. */
12416 EMACS_INT bpos_max = pos_before;
12417 EMACS_INT bpos_min = pos_after;
12418 /* Last buffer position covered by an overlay string with an integer
12419 `cursor' property. */
12420 EMACS_INT bpos_covered = 0;
12421
12422 /* Skip over glyphs not having an object at the start and the end of
12423 the row. These are special glyphs like truncation marks on
12424 terminal frames. */
12425 if (row->displays_text_p)
12426 {
12427 if (!row->reversed_p)
12428 {
12429 while (glyph < end
12430 && INTEGERP (glyph->object)
12431 && glyph->charpos < 0)
12432 {
12433 x += glyph->pixel_width;
12434 ++glyph;
12435 }
12436 while (end > glyph
12437 && INTEGERP ((end - 1)->object)
12438 /* CHARPOS is zero for blanks and stretch glyphs
12439 inserted by extend_face_to_end_of_line. */
12440 && (end - 1)->charpos <= 0)
12441 --end;
12442 glyph_before = glyph - 1;
12443 glyph_after = end;
12444 }
12445 else
12446 {
12447 struct glyph *g;
12448
12449 /* If the glyph row is reversed, we need to process it from back
12450 to front, so swap the edge pointers. */
12451 glyphs_end = end = glyph - 1;
12452 glyph += row->used[TEXT_AREA] - 1;
12453
12454 while (glyph > end + 1
12455 && INTEGERP (glyph->object)
12456 && glyph->charpos < 0)
12457 {
12458 --glyph;
12459 x -= glyph->pixel_width;
12460 }
12461 if (INTEGERP (glyph->object) && glyph->charpos < 0)
12462 --glyph;
12463 /* By default, in reversed rows we put the cursor on the
12464 rightmost (first in the reading order) glyph. */
12465 for (g = end + 1; g < glyph; g++)
12466 x += g->pixel_width;
12467 while (end < glyph
12468 && INTEGERP ((end + 1)->object)
12469 && (end + 1)->charpos <= 0)
12470 ++end;
12471 glyph_before = glyph + 1;
12472 glyph_after = end;
12473 }
12474 }
12475 else if (row->reversed_p)
12476 {
12477 /* In R2L rows that don't display text, put the cursor on the
12478 rightmost glyph. Case in point: an empty last line that is
12479 part of an R2L paragraph. */
12480 cursor = end - 1;
12481 /* Avoid placing the cursor on the last glyph of the row, where
12482 on terminal frames we hold the vertical border between
12483 adjacent windows. */
12484 if (!FRAME_WINDOW_P (WINDOW_XFRAME (w))
12485 && !WINDOW_RIGHTMOST_P (w)
12486 && cursor == row->glyphs[LAST_AREA] - 1)
12487 cursor--;
12488 x = -1; /* will be computed below, at label compute_x */
12489 }
12490
12491 /* Step 1: Try to find the glyph whose character position
12492 corresponds to point. If that's not possible, find 2 glyphs
12493 whose character positions are the closest to point, one before
12494 point, the other after it. */
12495 if (!row->reversed_p)
12496 while (/* not marched to end of glyph row */
12497 glyph < end
12498 /* glyph was not inserted by redisplay for internal purposes */
12499 && !INTEGERP (glyph->object))
12500 {
12501 if (BUFFERP (glyph->object))
12502 {
12503 EMACS_INT dpos = glyph->charpos - pt_old;
12504
12505 if (glyph->charpos > bpos_max)
12506 bpos_max = glyph->charpos;
12507 if (glyph->charpos < bpos_min)
12508 bpos_min = glyph->charpos;
12509 if (!glyph->avoid_cursor_p)
12510 {
12511 /* If we hit point, we've found the glyph on which to
12512 display the cursor. */
12513 if (dpos == 0)
12514 {
12515 match_with_avoid_cursor = 0;
12516 break;
12517 }
12518 /* See if we've found a better approximation to
12519 POS_BEFORE or to POS_AFTER. Note that we want the
12520 first (leftmost) glyph of all those that are the
12521 closest from below, and the last (rightmost) of all
12522 those from above. */
12523 if (0 > dpos && dpos > pos_before - pt_old)
12524 {
12525 pos_before = glyph->charpos;
12526 glyph_before = glyph;
12527 }
12528 else if (0 < dpos && dpos <= pos_after - pt_old)
12529 {
12530 pos_after = glyph->charpos;
12531 glyph_after = glyph;
12532 }
12533 }
12534 else if (dpos == 0)
12535 match_with_avoid_cursor = 1;
12536 }
12537 else if (STRINGP (glyph->object))
12538 {
12539 Lisp_Object chprop;
12540 EMACS_INT glyph_pos = glyph->charpos;
12541
12542 chprop = Fget_char_property (make_number (glyph_pos), Qcursor,
12543 glyph->object);
12544 if (INTEGERP (chprop))
12545 {
12546 bpos_covered = bpos_max + XINT (chprop);
12547 /* If the `cursor' property covers buffer positions up
12548 to and including point, we should display cursor on
12549 this glyph. Note that overlays and text properties
12550 with string values stop bidi reordering, so every
12551 buffer position to the left of the string is always
12552 smaller than any position to the right of the
12553 string. Therefore, if a `cursor' property on one
12554 of the string's characters has an integer value, we
12555 will break out of the loop below _before_ we get to
12556 the position match above. IOW, integer values of
12557 the `cursor' property override the "exact match for
12558 point" strategy of positioning the cursor. */
12559 /* Implementation note: bpos_max == pt_old when, e.g.,
12560 we are in an empty line, where bpos_max is set to
12561 MATRIX_ROW_START_CHARPOS, see above. */
12562 if (bpos_max <= pt_old && bpos_covered >= pt_old)
12563 {
12564 cursor = glyph;
12565 break;
12566 }
12567 }
12568
12569 string_seen = 1;
12570 }
12571 x += glyph->pixel_width;
12572 ++glyph;
12573 }
12574 else if (glyph > end) /* row is reversed */
12575 while (!INTEGERP (glyph->object))
12576 {
12577 if (BUFFERP (glyph->object))
12578 {
12579 EMACS_INT dpos = glyph->charpos - pt_old;
12580
12581 if (glyph->charpos > bpos_max)
12582 bpos_max = glyph->charpos;
12583 if (glyph->charpos < bpos_min)
12584 bpos_min = glyph->charpos;
12585 if (!glyph->avoid_cursor_p)
12586 {
12587 if (dpos == 0)
12588 {
12589 match_with_avoid_cursor = 0;
12590 break;
12591 }
12592 if (0 > dpos && dpos > pos_before - pt_old)
12593 {
12594 pos_before = glyph->charpos;
12595 glyph_before = glyph;
12596 }
12597 else if (0 < dpos && dpos <= pos_after - pt_old)
12598 {
12599 pos_after = glyph->charpos;
12600 glyph_after = glyph;
12601 }
12602 }
12603 else if (dpos == 0)
12604 match_with_avoid_cursor = 1;
12605 }
12606 else if (STRINGP (glyph->object))
12607 {
12608 Lisp_Object chprop;
12609 EMACS_INT glyph_pos = glyph->charpos;
12610
12611 chprop = Fget_char_property (make_number (glyph_pos), Qcursor,
12612 glyph->object);
12613 if (INTEGERP (chprop))
12614 {
12615 bpos_covered = bpos_max + XINT (chprop);
12616 /* If the `cursor' property covers buffer positions up
12617 to and including point, we should display cursor on
12618 this glyph. */
12619 if (bpos_max <= pt_old && bpos_covered >= pt_old)
12620 {
12621 cursor = glyph;
12622 break;
12623 }
12624 }
12625 string_seen = 1;
12626 }
12627 --glyph;
12628 if (glyph == glyphs_end) /* don't dereference outside TEXT_AREA */
12629 {
12630 x--; /* can't use any pixel_width */
12631 break;
12632 }
12633 x -= glyph->pixel_width;
12634 }
12635
12636 /* Step 2: If we didn't find an exact match for point, we need to
12637 look for a proper place to put the cursor among glyphs between
12638 GLYPH_BEFORE and GLYPH_AFTER. */
12639 if (!((row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end)
12640 && BUFFERP (glyph->object) && glyph->charpos == pt_old)
12641 && bpos_covered < pt_old)
12642 {
12643 /* An empty line has a single glyph whose OBJECT is zero and
12644 whose CHARPOS is the position of a newline on that line.
12645 Note that on a TTY, there are more glyphs after that, which
12646 were produced by extend_face_to_end_of_line, but their
12647 CHARPOS is zero or negative. */
12648 int empty_line_p =
12649 (row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end)
12650 && INTEGERP (glyph->object) && glyph->charpos > 0;
12651
12652 if (row->ends_in_ellipsis_p && pos_after == last_pos)
12653 {
12654 EMACS_INT ellipsis_pos;
12655
12656 /* Scan back over the ellipsis glyphs. */
12657 if (!row->reversed_p)
12658 {
12659 ellipsis_pos = (glyph - 1)->charpos;
12660 while (glyph > row->glyphs[TEXT_AREA]
12661 && (glyph - 1)->charpos == ellipsis_pos)
12662 glyph--, x -= glyph->pixel_width;
12663 /* That loop always goes one position too far, including
12664 the glyph before the ellipsis. So scan forward over
12665 that one. */
12666 x += glyph->pixel_width;
12667 glyph++;
12668 }
12669 else /* row is reversed */
12670 {
12671 ellipsis_pos = (glyph + 1)->charpos;
12672 while (glyph < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1
12673 && (glyph + 1)->charpos == ellipsis_pos)
12674 glyph++, x += glyph->pixel_width;
12675 x -= glyph->pixel_width;
12676 glyph--;
12677 }
12678 }
12679 else if (match_with_avoid_cursor
12680 /* A truncated row may not include PT among its
12681 character positions. Setting the cursor inside the
12682 scroll margin will trigger recalculation of hscroll
12683 in hscroll_window_tree. */
12684 || (row->truncated_on_left_p && pt_old < bpos_min)
12685 || (row->truncated_on_right_p && pt_old > bpos_max)
12686 /* Zero-width characters produce no glyphs. */
12687 || (!string_seen
12688 && !empty_line_p
12689 && (row->reversed_p
12690 ? glyph_after > glyphs_end
12691 : glyph_after < glyphs_end)))
12692 {
12693 cursor = glyph_after;
12694 x = -1;
12695 }
12696 else if (string_seen)
12697 {
12698 int incr = row->reversed_p ? -1 : +1;
12699
12700 /* Need to find the glyph that came out of a string which is
12701 present at point. That glyph is somewhere between
12702 GLYPH_BEFORE and GLYPH_AFTER, and it came from a string
12703 positioned between POS_BEFORE and POS_AFTER in the
12704 buffer. */
12705 struct glyph *stop = glyph_after;
12706 EMACS_INT pos = pos_before;
12707
12708 x = -1;
12709 for (glyph = glyph_before + incr;
12710 row->reversed_p ? glyph > stop : glyph < stop; )
12711 {
12712
12713 /* Any glyphs that come from the buffer are here because
12714 of bidi reordering. Skip them, and only pay
12715 attention to glyphs that came from some string. */
12716 if (STRINGP (glyph->object))
12717 {
12718 Lisp_Object str;
12719 EMACS_INT tem;
12720
12721 str = glyph->object;
12722 tem = string_buffer_position_lim (str, pos, pos_after, 0);
12723 if (tem == 0 /* from overlay */
12724 || pos <= tem)
12725 {
12726 /* If the string from which this glyph came is
12727 found in the buffer at point, then we've
12728 found the glyph we've been looking for. If
12729 it comes from an overlay (tem == 0), and it
12730 has the `cursor' property on one of its
12731 glyphs, record that glyph as a candidate for
12732 displaying the cursor. (As in the
12733 unidirectional version, we will display the
12734 cursor on the last candidate we find.) */
12735 if (tem == 0 || tem == pt_old)
12736 {
12737 /* The glyphs from this string could have
12738 been reordered. Find the one with the
12739 smallest string position. Or there could
12740 be a character in the string with the
12741 `cursor' property, which means display
12742 cursor on that character's glyph. */
12743 EMACS_INT strpos = glyph->charpos;
12744
12745 if (tem)
12746 cursor = glyph;
12747 for ( ;
12748 (row->reversed_p ? glyph > stop : glyph < stop)
12749 && EQ (glyph->object, str);
12750 glyph += incr)
12751 {
12752 Lisp_Object cprop;
12753 EMACS_INT gpos = glyph->charpos;
12754
12755 cprop = Fget_char_property (make_number (gpos),
12756 Qcursor,
12757 glyph->object);
12758 if (!NILP (cprop))
12759 {
12760 cursor = glyph;
12761 break;
12762 }
12763 if (tem && glyph->charpos < strpos)
12764 {
12765 strpos = glyph->charpos;
12766 cursor = glyph;
12767 }
12768 }
12769
12770 if (tem == pt_old)
12771 goto compute_x;
12772 }
12773 if (tem)
12774 pos = tem + 1; /* don't find previous instances */
12775 }
12776 /* This string is not what we want; skip all of the
12777 glyphs that came from it. */
12778 while ((row->reversed_p ? glyph > stop : glyph < stop)
12779 && EQ (glyph->object, str))
12780 glyph += incr;
12781 }
12782 else
12783 glyph += incr;
12784 }
12785
12786 /* If we reached the end of the line, and END was from a string,
12787 the cursor is not on this line. */
12788 if (cursor == NULL
12789 && (row->reversed_p ? glyph <= end : glyph >= end)
12790 && STRINGP (end->object)
12791 && row->continued_p)
12792 return 0;
12793 }
12794 }
12795
12796 compute_x:
12797 if (cursor != NULL)
12798 glyph = cursor;
12799 if (x < 0)
12800 {
12801 struct glyph *g;
12802
12803 /* Need to compute x that corresponds to GLYPH. */
12804 for (g = row->glyphs[TEXT_AREA], x = row->x; g < glyph; g++)
12805 {
12806 if (g >= row->glyphs[TEXT_AREA] + row->used[TEXT_AREA])
12807 abort ();
12808 x += g->pixel_width;
12809 }
12810 }
12811
12812 /* ROW could be part of a continued line, which, under bidi
12813 reordering, might have other rows whose start and end charpos
12814 occlude point. Only set w->cursor if we found a better
12815 approximation to the cursor position than we have from previously
12816 examined candidate rows belonging to the same continued line. */
12817 if (/* we already have a candidate row */
12818 w->cursor.vpos >= 0
12819 /* that candidate is not the row we are processing */
12820 && MATRIX_ROW (matrix, w->cursor.vpos) != row
12821 /* the row we are processing is part of a continued line */
12822 && (row->continued_p || MATRIX_ROW_CONTINUATION_LINE_P (row))
12823 /* Make sure cursor.vpos specifies a row whose start and end
12824 charpos occlude point. This is because some callers of this
12825 function leave cursor.vpos at the row where the cursor was
12826 displayed during the last redisplay cycle. */
12827 && MATRIX_ROW_START_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos)) <= pt_old
12828 && pt_old < MATRIX_ROW_END_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos)))
12829 {
12830 struct glyph *g1 =
12831 MATRIX_ROW_GLYPH_START (matrix, w->cursor.vpos) + w->cursor.hpos;
12832
12833 /* Don't consider glyphs that are outside TEXT_AREA. */
12834 if (!(row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end))
12835 return 0;
12836 /* Keep the candidate whose buffer position is the closest to
12837 point. */
12838 if (/* previous candidate is a glyph in TEXT_AREA of that row */
12839 w->cursor.hpos >= 0
12840 && w->cursor.hpos < MATRIX_ROW_USED (matrix, w->cursor.vpos)
12841 && BUFFERP (g1->object)
12842 && (g1->charpos == pt_old /* an exact match always wins */
12843 || (BUFFERP (glyph->object)
12844 && eabs (g1->charpos - pt_old)
12845 < eabs (glyph->charpos - pt_old))))
12846 return 0;
12847 /* If this candidate gives an exact match, use that. */
12848 if (!(BUFFERP (glyph->object) && glyph->charpos == pt_old)
12849 /* Otherwise, keep the candidate that comes from a row
12850 spanning less buffer positions. This may win when one or
12851 both candidate positions are on glyphs that came from
12852 display strings, for which we cannot compare buffer
12853 positions. */
12854 && MATRIX_ROW_END_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))
12855 - MATRIX_ROW_START_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))
12856 < MATRIX_ROW_END_CHARPOS (row) - MATRIX_ROW_START_CHARPOS (row))
12857 return 0;
12858 }
12859 w->cursor.hpos = glyph - row->glyphs[TEXT_AREA];
12860 w->cursor.x = x;
12861 w->cursor.vpos = MATRIX_ROW_VPOS (row, matrix) + dvpos;
12862 w->cursor.y = row->y + dy;
12863
12864 if (w == XWINDOW (selected_window))
12865 {
12866 if (!row->continued_p
12867 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
12868 && row->x == 0)
12869 {
12870 this_line_buffer = XBUFFER (w->buffer);
12871
12872 CHARPOS (this_line_start_pos)
12873 = MATRIX_ROW_START_CHARPOS (row) + delta;
12874 BYTEPOS (this_line_start_pos)
12875 = MATRIX_ROW_START_BYTEPOS (row) + delta_bytes;
12876
12877 CHARPOS (this_line_end_pos)
12878 = Z - (MATRIX_ROW_END_CHARPOS (row) + delta);
12879 BYTEPOS (this_line_end_pos)
12880 = Z_BYTE - (MATRIX_ROW_END_BYTEPOS (row) + delta_bytes);
12881
12882 this_line_y = w->cursor.y;
12883 this_line_pixel_height = row->height;
12884 this_line_vpos = w->cursor.vpos;
12885 this_line_start_x = row->x;
12886 }
12887 else
12888 CHARPOS (this_line_start_pos) = 0;
12889 }
12890
12891 return 1;
12892 }
12893
12894
12895 /* Run window scroll functions, if any, for WINDOW with new window
12896 start STARTP. Sets the window start of WINDOW to that position.
12897
12898 We assume that the window's buffer is really current. */
12899
12900 static INLINE struct text_pos
12901 run_window_scroll_functions (Lisp_Object window, struct text_pos startp)
12902 {
12903 struct window *w = XWINDOW (window);
12904 SET_MARKER_FROM_TEXT_POS (w->start, startp);
12905
12906 if (current_buffer != XBUFFER (w->buffer))
12907 abort ();
12908
12909 if (!NILP (Vwindow_scroll_functions))
12910 {
12911 run_hook_with_args_2 (Qwindow_scroll_functions, window,
12912 make_number (CHARPOS (startp)));
12913 SET_TEXT_POS_FROM_MARKER (startp, w->start);
12914 /* In case the hook functions switch buffers. */
12915 if (current_buffer != XBUFFER (w->buffer))
12916 set_buffer_internal_1 (XBUFFER (w->buffer));
12917 }
12918
12919 return startp;
12920 }
12921
12922
12923 /* Make sure the line containing the cursor is fully visible.
12924 A value of 1 means there is nothing to be done.
12925 (Either the line is fully visible, or it cannot be made so,
12926 or we cannot tell.)
12927
12928 If FORCE_P is non-zero, return 0 even if partial visible cursor row
12929 is higher than window.
12930
12931 A value of 0 means the caller should do scrolling
12932 as if point had gone off the screen. */
12933
12934 static int
12935 cursor_row_fully_visible_p (struct window *w, int force_p, int current_matrix_p)
12936 {
12937 struct glyph_matrix *matrix;
12938 struct glyph_row *row;
12939 int window_height;
12940
12941 if (!make_cursor_line_fully_visible_p)
12942 return 1;
12943
12944 /* It's not always possible to find the cursor, e.g, when a window
12945 is full of overlay strings. Don't do anything in that case. */
12946 if (w->cursor.vpos < 0)
12947 return 1;
12948
12949 matrix = current_matrix_p ? w->current_matrix : w->desired_matrix;
12950 row = MATRIX_ROW (matrix, w->cursor.vpos);
12951
12952 /* If the cursor row is not partially visible, there's nothing to do. */
12953 if (!MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row))
12954 return 1;
12955
12956 /* If the row the cursor is in is taller than the window's height,
12957 it's not clear what to do, so do nothing. */
12958 window_height = window_box_height (w);
12959 if (row->height >= window_height)
12960 {
12961 if (!force_p || MINI_WINDOW_P (w)
12962 || w->vscroll || w->cursor.vpos == 0)
12963 return 1;
12964 }
12965 return 0;
12966 }
12967
12968
12969 /* Try scrolling PT into view in window WINDOW. JUST_THIS_ONE_P
12970 non-zero means only WINDOW is redisplayed in redisplay_internal.
12971 TEMP_SCROLL_STEP has the same meaning as emacs_scroll_step, and is used
12972 in redisplay_window to bring a partially visible line into view in
12973 the case that only the cursor has moved.
12974
12975 LAST_LINE_MISFIT should be nonzero if we're scrolling because the
12976 last screen line's vertical height extends past the end of the screen.
12977
12978 Value is
12979
12980 1 if scrolling succeeded
12981
12982 0 if scrolling didn't find point.
12983
12984 -1 if new fonts have been loaded so that we must interrupt
12985 redisplay, adjust glyph matrices, and try again. */
12986
12987 enum
12988 {
12989 SCROLLING_SUCCESS,
12990 SCROLLING_FAILED,
12991 SCROLLING_NEED_LARGER_MATRICES
12992 };
12993
12994 /* If scroll-conservatively is more than this, never recenter.
12995
12996 If you change this, don't forget to update the doc string of
12997 `scroll-conservatively' and the Emacs manual. */
12998 #define SCROLL_LIMIT 100
12999
13000 static int
13001 try_scrolling (Lisp_Object window, int just_this_one_p,
13002 EMACS_INT arg_scroll_conservatively, EMACS_INT scroll_step,
13003 int temp_scroll_step, int last_line_misfit)
13004 {
13005 struct window *w = XWINDOW (window);
13006 struct frame *f = XFRAME (w->frame);
13007 struct text_pos pos, startp;
13008 struct it it;
13009 int this_scroll_margin, scroll_max, rc, height;
13010 int dy = 0, amount_to_scroll = 0, scroll_down_p = 0;
13011 int extra_scroll_margin_lines = last_line_misfit ? 1 : 0;
13012 Lisp_Object aggressive;
13013 /* We will never try scrolling more than this number of lines. */
13014 int scroll_limit = SCROLL_LIMIT;
13015
13016 #if GLYPH_DEBUG
13017 debug_method_add (w, "try_scrolling");
13018 #endif
13019
13020 SET_TEXT_POS_FROM_MARKER (startp, w->start);
13021
13022 /* Compute scroll margin height in pixels. We scroll when point is
13023 within this distance from the top or bottom of the window. */
13024 if (scroll_margin > 0)
13025 this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4)
13026 * FRAME_LINE_HEIGHT (f);
13027 else
13028 this_scroll_margin = 0;
13029
13030 /* Force arg_scroll_conservatively to have a reasonable value, to
13031 avoid scrolling too far away with slow move_it_* functions. Note
13032 that the user can supply scroll-conservatively equal to
13033 `most-positive-fixnum', which can be larger than INT_MAX. */
13034 if (arg_scroll_conservatively > scroll_limit)
13035 {
13036 arg_scroll_conservatively = scroll_limit + 1;
13037 scroll_max = scroll_limit * FRAME_LINE_HEIGHT (f);
13038 }
13039 else if (scroll_step || arg_scroll_conservatively || temp_scroll_step)
13040 /* Compute how much we should try to scroll maximally to bring
13041 point into view. */
13042 scroll_max = (max (scroll_step,
13043 max (arg_scroll_conservatively, temp_scroll_step))
13044 * FRAME_LINE_HEIGHT (f));
13045 else if (NUMBERP (BVAR (current_buffer, scroll_down_aggressively))
13046 || NUMBERP (BVAR (current_buffer, scroll_up_aggressively)))
13047 /* We're trying to scroll because of aggressive scrolling but no
13048 scroll_step is set. Choose an arbitrary one. */
13049 scroll_max = 10 * FRAME_LINE_HEIGHT (f);
13050 else
13051 scroll_max = 0;
13052
13053 too_near_end:
13054
13055 /* Decide whether to scroll down. */
13056 if (PT > CHARPOS (startp))
13057 {
13058 int scroll_margin_y;
13059
13060 /* Compute the pixel ypos of the scroll margin, then move it to
13061 either that ypos or PT, whichever comes first. */
13062 start_display (&it, w, startp);
13063 scroll_margin_y = it.last_visible_y - this_scroll_margin
13064 - FRAME_LINE_HEIGHT (f) * extra_scroll_margin_lines;
13065 move_it_to (&it, PT, -1, scroll_margin_y - 1, -1,
13066 (MOVE_TO_POS | MOVE_TO_Y));
13067
13068 if (PT > CHARPOS (it.current.pos))
13069 {
13070 int y0 = line_bottom_y (&it);
13071 /* Compute how many pixels below window bottom to stop searching
13072 for PT. This avoids costly search for PT that is far away if
13073 the user limited scrolling by a small number of lines, but
13074 always finds PT if scroll_conservatively is set to a large
13075 number, such as most-positive-fixnum. */
13076 int slack = max (scroll_max, 10 * FRAME_LINE_HEIGHT (f));
13077 int y_to_move = it.last_visible_y + slack;
13078
13079 /* Compute the distance from the scroll margin to PT or to
13080 the scroll limit, whichever comes first. This should
13081 include the height of the cursor line, to make that line
13082 fully visible. */
13083 move_it_to (&it, PT, -1, y_to_move,
13084 -1, MOVE_TO_POS | MOVE_TO_Y);
13085 dy = line_bottom_y (&it) - y0;
13086
13087 if (dy > scroll_max)
13088 return SCROLLING_FAILED;
13089
13090 scroll_down_p = 1;
13091 }
13092 }
13093
13094 if (scroll_down_p)
13095 {
13096 /* Point is in or below the bottom scroll margin, so move the
13097 window start down. If scrolling conservatively, move it just
13098 enough down to make point visible. If scroll_step is set,
13099 move it down by scroll_step. */
13100 if (arg_scroll_conservatively)
13101 amount_to_scroll
13102 = min (max (dy, FRAME_LINE_HEIGHT (f)),
13103 FRAME_LINE_HEIGHT (f) * arg_scroll_conservatively);
13104 else if (scroll_step || temp_scroll_step)
13105 amount_to_scroll = scroll_max;
13106 else
13107 {
13108 aggressive = BVAR (current_buffer, scroll_up_aggressively);
13109 height = WINDOW_BOX_TEXT_HEIGHT (w);
13110 if (NUMBERP (aggressive))
13111 {
13112 double float_amount = XFLOATINT (aggressive) * height;
13113 amount_to_scroll = float_amount;
13114 if (amount_to_scroll == 0 && float_amount > 0)
13115 amount_to_scroll = 1;
13116 /* Don't let point enter the scroll margin near top of
13117 the window. */
13118 if (amount_to_scroll > height - 2*this_scroll_margin + dy)
13119 amount_to_scroll = height - 2*this_scroll_margin + dy;
13120 }
13121 }
13122
13123 if (amount_to_scroll <= 0)
13124 return SCROLLING_FAILED;
13125
13126 start_display (&it, w, startp);
13127 if (arg_scroll_conservatively <= scroll_limit)
13128 move_it_vertically (&it, amount_to_scroll);
13129 else
13130 {
13131 /* Extra precision for users who set scroll-conservatively
13132 to a large number: make sure the amount we scroll
13133 the window start is never less than amount_to_scroll,
13134 which was computed as distance from window bottom to
13135 point. This matters when lines at window top and lines
13136 below window bottom have different height. */
13137 struct it it1 = it;
13138 /* We use a temporary it1 because line_bottom_y can modify
13139 its argument, if it moves one line down; see there. */
13140 int start_y = line_bottom_y (&it1);
13141
13142 do {
13143 move_it_by_lines (&it, 1);
13144 it1 = it;
13145 } while (line_bottom_y (&it1) - start_y < amount_to_scroll);
13146 }
13147
13148 /* If STARTP is unchanged, move it down another screen line. */
13149 if (CHARPOS (it.current.pos) == CHARPOS (startp))
13150 move_it_by_lines (&it, 1);
13151 startp = it.current.pos;
13152 }
13153 else
13154 {
13155 struct text_pos scroll_margin_pos = startp;
13156
13157 /* See if point is inside the scroll margin at the top of the
13158 window. */
13159 if (this_scroll_margin)
13160 {
13161 start_display (&it, w, startp);
13162 move_it_vertically (&it, this_scroll_margin);
13163 scroll_margin_pos = it.current.pos;
13164 }
13165
13166 if (PT < CHARPOS (scroll_margin_pos))
13167 {
13168 /* Point is in the scroll margin at the top of the window or
13169 above what is displayed in the window. */
13170 int y0, y_to_move;
13171
13172 /* Compute the vertical distance from PT to the scroll
13173 margin position. Move as far as scroll_max allows, or
13174 one screenful, or 10 screen lines, whichever is largest.
13175 Give up if distance is greater than scroll_max. */
13176 SET_TEXT_POS (pos, PT, PT_BYTE);
13177 start_display (&it, w, pos);
13178 y0 = it.current_y;
13179 y_to_move = max (it.last_visible_y,
13180 max (scroll_max, 10 * FRAME_LINE_HEIGHT (f)));
13181 move_it_to (&it, CHARPOS (scroll_margin_pos), 0,
13182 y_to_move, -1,
13183 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
13184 dy = it.current_y - y0;
13185 if (dy > scroll_max)
13186 return SCROLLING_FAILED;
13187
13188 /* Compute new window start. */
13189 start_display (&it, w, startp);
13190
13191 if (arg_scroll_conservatively)
13192 amount_to_scroll = max (dy, FRAME_LINE_HEIGHT (f) *
13193 max (scroll_step, temp_scroll_step));
13194 else if (scroll_step || temp_scroll_step)
13195 amount_to_scroll = scroll_max;
13196 else
13197 {
13198 aggressive = BVAR (current_buffer, scroll_down_aggressively);
13199 height = WINDOW_BOX_TEXT_HEIGHT (w);
13200 if (NUMBERP (aggressive))
13201 {
13202 double float_amount = XFLOATINT (aggressive) * height;
13203 amount_to_scroll = float_amount;
13204 if (amount_to_scroll == 0 && float_amount > 0)
13205 amount_to_scroll = 1;
13206 amount_to_scroll -=
13207 this_scroll_margin - dy - FRAME_LINE_HEIGHT (f);
13208 /* Don't let point enter the scroll margin near
13209 bottom of the window. */
13210 if (amount_to_scroll > height - 2*this_scroll_margin + dy)
13211 amount_to_scroll = height - 2*this_scroll_margin + dy;
13212 }
13213 }
13214
13215 if (amount_to_scroll <= 0)
13216 return SCROLLING_FAILED;
13217
13218 move_it_vertically_backward (&it, amount_to_scroll);
13219 startp = it.current.pos;
13220 }
13221 }
13222
13223 /* Run window scroll functions. */
13224 startp = run_window_scroll_functions (window, startp);
13225
13226 /* Display the window. Give up if new fonts are loaded, or if point
13227 doesn't appear. */
13228 if (!try_window (window, startp, 0))
13229 rc = SCROLLING_NEED_LARGER_MATRICES;
13230 else if (w->cursor.vpos < 0)
13231 {
13232 clear_glyph_matrix (w->desired_matrix);
13233 rc = SCROLLING_FAILED;
13234 }
13235 else
13236 {
13237 /* Maybe forget recorded base line for line number display. */
13238 if (!just_this_one_p
13239 || current_buffer->clip_changed
13240 || BEG_UNCHANGED < CHARPOS (startp))
13241 w->base_line_number = Qnil;
13242
13243 /* If cursor ends up on a partially visible line,
13244 treat that as being off the bottom of the screen. */
13245 if (! cursor_row_fully_visible_p (w, extra_scroll_margin_lines <= 1, 0)
13246 /* It's possible that the cursor is on the first line of the
13247 buffer, which is partially obscured due to a vscroll
13248 (Bug#7537). In that case, avoid looping forever . */
13249 && extra_scroll_margin_lines < w->desired_matrix->nrows - 1)
13250 {
13251 clear_glyph_matrix (w->desired_matrix);
13252 ++extra_scroll_margin_lines;
13253 goto too_near_end;
13254 }
13255 rc = SCROLLING_SUCCESS;
13256 }
13257
13258 return rc;
13259 }
13260
13261
13262 /* Compute a suitable window start for window W if display of W starts
13263 on a continuation line. Value is non-zero if a new window start
13264 was computed.
13265
13266 The new window start will be computed, based on W's width, starting
13267 from the start of the continued line. It is the start of the
13268 screen line with the minimum distance from the old start W->start. */
13269
13270 static int
13271 compute_window_start_on_continuation_line (struct window *w)
13272 {
13273 struct text_pos pos, start_pos;
13274 int window_start_changed_p = 0;
13275
13276 SET_TEXT_POS_FROM_MARKER (start_pos, w->start);
13277
13278 /* If window start is on a continuation line... Window start may be
13279 < BEGV in case there's invisible text at the start of the
13280 buffer (M-x rmail, for example). */
13281 if (CHARPOS (start_pos) > BEGV
13282 && FETCH_BYTE (BYTEPOS (start_pos) - 1) != '\n')
13283 {
13284 struct it it;
13285 struct glyph_row *row;
13286
13287 /* Handle the case that the window start is out of range. */
13288 if (CHARPOS (start_pos) < BEGV)
13289 SET_TEXT_POS (start_pos, BEGV, BEGV_BYTE);
13290 else if (CHARPOS (start_pos) > ZV)
13291 SET_TEXT_POS (start_pos, ZV, ZV_BYTE);
13292
13293 /* Find the start of the continued line. This should be fast
13294 because scan_buffer is fast (newline cache). */
13295 row = w->desired_matrix->rows + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0);
13296 init_iterator (&it, w, CHARPOS (start_pos), BYTEPOS (start_pos),
13297 row, DEFAULT_FACE_ID);
13298 reseat_at_previous_visible_line_start (&it);
13299
13300 /* If the line start is "too far" away from the window start,
13301 say it takes too much time to compute a new window start. */
13302 if (CHARPOS (start_pos) - IT_CHARPOS (it)
13303 < WINDOW_TOTAL_LINES (w) * WINDOW_TOTAL_COLS (w))
13304 {
13305 int min_distance, distance;
13306
13307 /* Move forward by display lines to find the new window
13308 start. If window width was enlarged, the new start can
13309 be expected to be > the old start. If window width was
13310 decreased, the new window start will be < the old start.
13311 So, we're looking for the display line start with the
13312 minimum distance from the old window start. */
13313 pos = it.current.pos;
13314 min_distance = INFINITY;
13315 while ((distance = eabs (CHARPOS (start_pos) - IT_CHARPOS (it))),
13316 distance < min_distance)
13317 {
13318 min_distance = distance;
13319 pos = it.current.pos;
13320 move_it_by_lines (&it, 1);
13321 }
13322
13323 /* Set the window start there. */
13324 SET_MARKER_FROM_TEXT_POS (w->start, pos);
13325 window_start_changed_p = 1;
13326 }
13327 }
13328
13329 return window_start_changed_p;
13330 }
13331
13332
13333 /* Try cursor movement in case text has not changed in window WINDOW,
13334 with window start STARTP. Value is
13335
13336 CURSOR_MOVEMENT_SUCCESS if successful
13337
13338 CURSOR_MOVEMENT_CANNOT_BE_USED if this method cannot be used
13339
13340 CURSOR_MOVEMENT_MUST_SCROLL if we know we have to scroll the
13341 display. *SCROLL_STEP is set to 1, under certain circumstances, if
13342 we want to scroll as if scroll-step were set to 1. See the code.
13343
13344 CURSOR_MOVEMENT_NEED_LARGER_MATRICES if we need larger matrices, in
13345 which case we have to abort this redisplay, and adjust matrices
13346 first. */
13347
13348 enum
13349 {
13350 CURSOR_MOVEMENT_SUCCESS,
13351 CURSOR_MOVEMENT_CANNOT_BE_USED,
13352 CURSOR_MOVEMENT_MUST_SCROLL,
13353 CURSOR_MOVEMENT_NEED_LARGER_MATRICES
13354 };
13355
13356 static int
13357 try_cursor_movement (Lisp_Object window, struct text_pos startp, int *scroll_step)
13358 {
13359 struct window *w = XWINDOW (window);
13360 struct frame *f = XFRAME (w->frame);
13361 int rc = CURSOR_MOVEMENT_CANNOT_BE_USED;
13362
13363 #if GLYPH_DEBUG
13364 if (inhibit_try_cursor_movement)
13365 return rc;
13366 #endif
13367
13368 /* Handle case where text has not changed, only point, and it has
13369 not moved off the frame. */
13370 if (/* Point may be in this window. */
13371 PT >= CHARPOS (startp)
13372 /* Selective display hasn't changed. */
13373 && !current_buffer->clip_changed
13374 /* Function force-mode-line-update is used to force a thorough
13375 redisplay. It sets either windows_or_buffers_changed or
13376 update_mode_lines. So don't take a shortcut here for these
13377 cases. */
13378 && !update_mode_lines
13379 && !windows_or_buffers_changed
13380 && !cursor_type_changed
13381 /* Can't use this case if highlighting a region. When a
13382 region exists, cursor movement has to do more than just
13383 set the cursor. */
13384 && !(!NILP (Vtransient_mark_mode)
13385 && !NILP (BVAR (current_buffer, mark_active)))
13386 && NILP (w->region_showing)
13387 && NILP (Vshow_trailing_whitespace)
13388 /* Right after splitting windows, last_point may be nil. */
13389 && INTEGERP (w->last_point)
13390 /* This code is not used for mini-buffer for the sake of the case
13391 of redisplaying to replace an echo area message; since in
13392 that case the mini-buffer contents per se are usually
13393 unchanged. This code is of no real use in the mini-buffer
13394 since the handling of this_line_start_pos, etc., in redisplay
13395 handles the same cases. */
13396 && !EQ (window, minibuf_window)
13397 /* When splitting windows or for new windows, it happens that
13398 redisplay is called with a nil window_end_vpos or one being
13399 larger than the window. This should really be fixed in
13400 window.c. I don't have this on my list, now, so we do
13401 approximately the same as the old redisplay code. --gerd. */
13402 && INTEGERP (w->window_end_vpos)
13403 && XFASTINT (w->window_end_vpos) < w->current_matrix->nrows
13404 && (FRAME_WINDOW_P (f)
13405 || !overlay_arrow_in_current_buffer_p ()))
13406 {
13407 int this_scroll_margin, top_scroll_margin;
13408 struct glyph_row *row = NULL;
13409
13410 #if GLYPH_DEBUG
13411 debug_method_add (w, "cursor movement");
13412 #endif
13413
13414 /* Scroll if point within this distance from the top or bottom
13415 of the window. This is a pixel value. */
13416 if (scroll_margin > 0)
13417 {
13418 this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
13419 this_scroll_margin *= FRAME_LINE_HEIGHT (f);
13420 }
13421 else
13422 this_scroll_margin = 0;
13423
13424 top_scroll_margin = this_scroll_margin;
13425 if (WINDOW_WANTS_HEADER_LINE_P (w))
13426 top_scroll_margin += CURRENT_HEADER_LINE_HEIGHT (w);
13427
13428 /* Start with the row the cursor was displayed during the last
13429 not paused redisplay. Give up if that row is not valid. */
13430 if (w->last_cursor.vpos < 0
13431 || w->last_cursor.vpos >= w->current_matrix->nrows)
13432 rc = CURSOR_MOVEMENT_MUST_SCROLL;
13433 else
13434 {
13435 row = MATRIX_ROW (w->current_matrix, w->last_cursor.vpos);
13436 if (row->mode_line_p)
13437 ++row;
13438 if (!row->enabled_p)
13439 rc = CURSOR_MOVEMENT_MUST_SCROLL;
13440 }
13441
13442 if (rc == CURSOR_MOVEMENT_CANNOT_BE_USED)
13443 {
13444 int scroll_p = 0, must_scroll = 0;
13445 int last_y = window_text_bottom_y (w) - this_scroll_margin;
13446
13447 if (PT > XFASTINT (w->last_point))
13448 {
13449 /* Point has moved forward. */
13450 while (MATRIX_ROW_END_CHARPOS (row) < PT
13451 && MATRIX_ROW_BOTTOM_Y (row) < last_y)
13452 {
13453 xassert (row->enabled_p);
13454 ++row;
13455 }
13456
13457 /* If the end position of a row equals the start
13458 position of the next row, and PT is at that position,
13459 we would rather display cursor in the next line. */
13460 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
13461 && MATRIX_ROW_END_CHARPOS (row) == PT
13462 && row < w->current_matrix->rows
13463 + w->current_matrix->nrows - 1
13464 && MATRIX_ROW_START_CHARPOS (row+1) == PT
13465 && !cursor_row_p (row))
13466 ++row;
13467
13468 /* If within the scroll margin, scroll. Note that
13469 MATRIX_ROW_BOTTOM_Y gives the pixel position at which
13470 the next line would be drawn, and that
13471 this_scroll_margin can be zero. */
13472 if (MATRIX_ROW_BOTTOM_Y (row) > last_y
13473 || PT > MATRIX_ROW_END_CHARPOS (row)
13474 /* Line is completely visible last line in window
13475 and PT is to be set in the next line. */
13476 || (MATRIX_ROW_BOTTOM_Y (row) == last_y
13477 && PT == MATRIX_ROW_END_CHARPOS (row)
13478 && !row->ends_at_zv_p
13479 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
13480 scroll_p = 1;
13481 }
13482 else if (PT < XFASTINT (w->last_point))
13483 {
13484 /* Cursor has to be moved backward. Note that PT >=
13485 CHARPOS (startp) because of the outer if-statement. */
13486 while (!row->mode_line_p
13487 && (MATRIX_ROW_START_CHARPOS (row) > PT
13488 || (MATRIX_ROW_START_CHARPOS (row) == PT
13489 && (MATRIX_ROW_STARTS_IN_MIDDLE_OF_CHAR_P (row)
13490 || (/* STARTS_IN_MIDDLE_OF_STRING_P (row) */
13491 row > w->current_matrix->rows
13492 && (row-1)->ends_in_newline_from_string_p))))
13493 && (row->y > top_scroll_margin
13494 || CHARPOS (startp) == BEGV))
13495 {
13496 xassert (row->enabled_p);
13497 --row;
13498 }
13499
13500 /* Consider the following case: Window starts at BEGV,
13501 there is invisible, intangible text at BEGV, so that
13502 display starts at some point START > BEGV. It can
13503 happen that we are called with PT somewhere between
13504 BEGV and START. Try to handle that case. */
13505 if (row < w->current_matrix->rows
13506 || row->mode_line_p)
13507 {
13508 row = w->current_matrix->rows;
13509 if (row->mode_line_p)
13510 ++row;
13511 }
13512
13513 /* Due to newlines in overlay strings, we may have to
13514 skip forward over overlay strings. */
13515 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
13516 && MATRIX_ROW_END_CHARPOS (row) == PT
13517 && !cursor_row_p (row))
13518 ++row;
13519
13520 /* If within the scroll margin, scroll. */
13521 if (row->y < top_scroll_margin
13522 && CHARPOS (startp) != BEGV)
13523 scroll_p = 1;
13524 }
13525 else
13526 {
13527 /* Cursor did not move. So don't scroll even if cursor line
13528 is partially visible, as it was so before. */
13529 rc = CURSOR_MOVEMENT_SUCCESS;
13530 }
13531
13532 if (PT < MATRIX_ROW_START_CHARPOS (row)
13533 || PT > MATRIX_ROW_END_CHARPOS (row))
13534 {
13535 /* if PT is not in the glyph row, give up. */
13536 rc = CURSOR_MOVEMENT_MUST_SCROLL;
13537 must_scroll = 1;
13538 }
13539 else if (rc != CURSOR_MOVEMENT_SUCCESS
13540 && !NILP (BVAR (XBUFFER (w->buffer), bidi_display_reordering)))
13541 {
13542 /* If rows are bidi-reordered and point moved, back up
13543 until we find a row that does not belong to a
13544 continuation line. This is because we must consider
13545 all rows of a continued line as candidates for the
13546 new cursor positioning, since row start and end
13547 positions change non-linearly with vertical position
13548 in such rows. */
13549 /* FIXME: Revisit this when glyph ``spilling'' in
13550 continuation lines' rows is implemented for
13551 bidi-reordered rows. */
13552 while (MATRIX_ROW_CONTINUATION_LINE_P (row))
13553 {
13554 xassert (row->enabled_p);
13555 --row;
13556 /* If we hit the beginning of the displayed portion
13557 without finding the first row of a continued
13558 line, give up. */
13559 if (row <= w->current_matrix->rows)
13560 {
13561 rc = CURSOR_MOVEMENT_MUST_SCROLL;
13562 break;
13563 }
13564
13565 }
13566 }
13567 if (must_scroll)
13568 ;
13569 else if (rc != CURSOR_MOVEMENT_SUCCESS
13570 && MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row)
13571 && make_cursor_line_fully_visible_p)
13572 {
13573 if (PT == MATRIX_ROW_END_CHARPOS (row)
13574 && !row->ends_at_zv_p
13575 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
13576 rc = CURSOR_MOVEMENT_MUST_SCROLL;
13577 else if (row->height > window_box_height (w))
13578 {
13579 /* If we end up in a partially visible line, let's
13580 make it fully visible, except when it's taller
13581 than the window, in which case we can't do much
13582 about it. */
13583 *scroll_step = 1;
13584 rc = CURSOR_MOVEMENT_MUST_SCROLL;
13585 }
13586 else
13587 {
13588 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
13589 if (!cursor_row_fully_visible_p (w, 0, 1))
13590 rc = CURSOR_MOVEMENT_MUST_SCROLL;
13591 else
13592 rc = CURSOR_MOVEMENT_SUCCESS;
13593 }
13594 }
13595 else if (scroll_p)
13596 rc = CURSOR_MOVEMENT_MUST_SCROLL;
13597 else if (rc != CURSOR_MOVEMENT_SUCCESS
13598 && !NILP (BVAR (XBUFFER (w->buffer), bidi_display_reordering)))
13599 {
13600 /* With bidi-reordered rows, there could be more than
13601 one candidate row whose start and end positions
13602 occlude point. We need to let set_cursor_from_row
13603 find the best candidate. */
13604 /* FIXME: Revisit this when glyph ``spilling'' in
13605 continuation lines' rows is implemented for
13606 bidi-reordered rows. */
13607 int rv = 0;
13608
13609 do
13610 {
13611 if (MATRIX_ROW_START_CHARPOS (row) <= PT
13612 && PT <= MATRIX_ROW_END_CHARPOS (row)
13613 && cursor_row_p (row))
13614 rv |= set_cursor_from_row (w, row, w->current_matrix,
13615 0, 0, 0, 0);
13616 /* As soon as we've found the first suitable row
13617 whose ends_at_zv_p flag is set, we are done. */
13618 if (rv
13619 && MATRIX_ROW (w->current_matrix, w->cursor.vpos)->ends_at_zv_p)
13620 {
13621 rc = CURSOR_MOVEMENT_SUCCESS;
13622 break;
13623 }
13624 ++row;
13625 }
13626 while ((MATRIX_ROW_CONTINUATION_LINE_P (row)
13627 && MATRIX_ROW_BOTTOM_Y (row) <= last_y)
13628 || (MATRIX_ROW_START_CHARPOS (row) == PT
13629 && MATRIX_ROW_BOTTOM_Y (row) < last_y));
13630 /* If we didn't find any candidate rows, or exited the
13631 loop before all the candidates were examined, signal
13632 to the caller that this method failed. */
13633 if (rc != CURSOR_MOVEMENT_SUCCESS
13634 && (!rv || MATRIX_ROW_CONTINUATION_LINE_P (row)))
13635 rc = CURSOR_MOVEMENT_MUST_SCROLL;
13636 else if (rv)
13637 rc = CURSOR_MOVEMENT_SUCCESS;
13638 }
13639 else
13640 {
13641 do
13642 {
13643 if (set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0))
13644 {
13645 rc = CURSOR_MOVEMENT_SUCCESS;
13646 break;
13647 }
13648 ++row;
13649 }
13650 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
13651 && MATRIX_ROW_START_CHARPOS (row) == PT
13652 && cursor_row_p (row));
13653 }
13654 }
13655 }
13656
13657 return rc;
13658 }
13659
13660 void
13661 set_vertical_scroll_bar (struct window *w)
13662 {
13663 EMACS_INT start, end, whole;
13664
13665 /* Calculate the start and end positions for the current window.
13666 At some point, it would be nice to choose between scrollbars
13667 which reflect the whole buffer size, with special markers
13668 indicating narrowing, and scrollbars which reflect only the
13669 visible region.
13670
13671 Note that mini-buffers sometimes aren't displaying any text. */
13672 if (!MINI_WINDOW_P (w)
13673 || (w == XWINDOW (minibuf_window)
13674 && NILP (echo_area_buffer[0])))
13675 {
13676 struct buffer *buf = XBUFFER (w->buffer);
13677 whole = BUF_ZV (buf) - BUF_BEGV (buf);
13678 start = marker_position (w->start) - BUF_BEGV (buf);
13679 /* I don't think this is guaranteed to be right. For the
13680 moment, we'll pretend it is. */
13681 end = BUF_Z (buf) - XFASTINT (w->window_end_pos) - BUF_BEGV (buf);
13682
13683 if (end < start)
13684 end = start;
13685 if (whole < (end - start))
13686 whole = end - start;
13687 }
13688 else
13689 start = end = whole = 0;
13690
13691 /* Indicate what this scroll bar ought to be displaying now. */
13692 if (FRAME_TERMINAL (XFRAME (w->frame))->set_vertical_scroll_bar_hook)
13693 (*FRAME_TERMINAL (XFRAME (w->frame))->set_vertical_scroll_bar_hook)
13694 (w, end - start, whole, start);
13695 }
13696
13697
13698 /* Redisplay leaf window WINDOW. JUST_THIS_ONE_P non-zero means only
13699 selected_window is redisplayed.
13700
13701 We can return without actually redisplaying the window if
13702 fonts_changed_p is nonzero. In that case, redisplay_internal will
13703 retry. */
13704
13705 static void
13706 redisplay_window (Lisp_Object window, int just_this_one_p)
13707 {
13708 struct window *w = XWINDOW (window);
13709 struct frame *f = XFRAME (w->frame);
13710 struct buffer *buffer = XBUFFER (w->buffer);
13711 struct buffer *old = current_buffer;
13712 struct text_pos lpoint, opoint, startp;
13713 int update_mode_line;
13714 int tem;
13715 struct it it;
13716 /* Record it now because it's overwritten. */
13717 int current_matrix_up_to_date_p = 0;
13718 int used_current_matrix_p = 0;
13719 /* This is less strict than current_matrix_up_to_date_p.
13720 It indictes that the buffer contents and narrowing are unchanged. */
13721 int buffer_unchanged_p = 0;
13722 int temp_scroll_step = 0;
13723 int count = SPECPDL_INDEX ();
13724 int rc;
13725 int centering_position = -1;
13726 int last_line_misfit = 0;
13727 EMACS_INT beg_unchanged, end_unchanged;
13728
13729 SET_TEXT_POS (lpoint, PT, PT_BYTE);
13730 opoint = lpoint;
13731
13732 /* W must be a leaf window here. */
13733 xassert (!NILP (w->buffer));
13734 #if GLYPH_DEBUG
13735 *w->desired_matrix->method = 0;
13736 #endif
13737
13738 restart:
13739 reconsider_clip_changes (w, buffer);
13740
13741 /* Has the mode line to be updated? */
13742 update_mode_line = (!NILP (w->update_mode_line)
13743 || update_mode_lines
13744 || buffer->clip_changed
13745 || buffer->prevent_redisplay_optimizations_p);
13746
13747 if (MINI_WINDOW_P (w))
13748 {
13749 if (w == XWINDOW (echo_area_window)
13750 && !NILP (echo_area_buffer[0]))
13751 {
13752 if (update_mode_line)
13753 /* We may have to update a tty frame's menu bar or a
13754 tool-bar. Example `M-x C-h C-h C-g'. */
13755 goto finish_menu_bars;
13756 else
13757 /* We've already displayed the echo area glyphs in this window. */
13758 goto finish_scroll_bars;
13759 }
13760 else if ((w != XWINDOW (minibuf_window)
13761 || minibuf_level == 0)
13762 /* When buffer is nonempty, redisplay window normally. */
13763 && BUF_Z (XBUFFER (w->buffer)) == BUF_BEG (XBUFFER (w->buffer))
13764 /* Quail displays non-mini buffers in minibuffer window.
13765 In that case, redisplay the window normally. */
13766 && !NILP (Fmemq (w->buffer, Vminibuffer_list)))
13767 {
13768 /* W is a mini-buffer window, but it's not active, so clear
13769 it. */
13770 int yb = window_text_bottom_y (w);
13771 struct glyph_row *row;
13772 int y;
13773
13774 for (y = 0, row = w->desired_matrix->rows;
13775 y < yb;
13776 y += row->height, ++row)
13777 blank_row (w, row, y);
13778 goto finish_scroll_bars;
13779 }
13780
13781 clear_glyph_matrix (w->desired_matrix);
13782 }
13783
13784 /* Otherwise set up data on this window; select its buffer and point
13785 value. */
13786 /* Really select the buffer, for the sake of buffer-local
13787 variables. */
13788 set_buffer_internal_1 (XBUFFER (w->buffer));
13789
13790 current_matrix_up_to_date_p
13791 = (!NILP (w->window_end_valid)
13792 && !current_buffer->clip_changed
13793 && !current_buffer->prevent_redisplay_optimizations_p
13794 && XFASTINT (w->last_modified) >= MODIFF
13795 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
13796
13797 /* Run the window-bottom-change-functions
13798 if it is possible that the text on the screen has changed
13799 (either due to modification of the text, or any other reason). */
13800 if (!current_matrix_up_to_date_p
13801 && !NILP (Vwindow_text_change_functions))
13802 {
13803 safe_run_hooks (Qwindow_text_change_functions);
13804 goto restart;
13805 }
13806
13807 beg_unchanged = BEG_UNCHANGED;
13808 end_unchanged = END_UNCHANGED;
13809
13810 SET_TEXT_POS (opoint, PT, PT_BYTE);
13811
13812 specbind (Qinhibit_point_motion_hooks, Qt);
13813
13814 buffer_unchanged_p
13815 = (!NILP (w->window_end_valid)
13816 && !current_buffer->clip_changed
13817 && XFASTINT (w->last_modified) >= MODIFF
13818 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
13819
13820 /* When windows_or_buffers_changed is non-zero, we can't rely on
13821 the window end being valid, so set it to nil there. */
13822 if (windows_or_buffers_changed)
13823 {
13824 /* If window starts on a continuation line, maybe adjust the
13825 window start in case the window's width changed. */
13826 if (XMARKER (w->start)->buffer == current_buffer)
13827 compute_window_start_on_continuation_line (w);
13828
13829 w->window_end_valid = Qnil;
13830 }
13831
13832 /* Some sanity checks. */
13833 CHECK_WINDOW_END (w);
13834 if (Z == Z_BYTE && CHARPOS (opoint) != BYTEPOS (opoint))
13835 abort ();
13836 if (BYTEPOS (opoint) < CHARPOS (opoint))
13837 abort ();
13838
13839 /* If %c is in mode line, update it if needed. */
13840 if (!NILP (w->column_number_displayed)
13841 /* This alternative quickly identifies a common case
13842 where no change is needed. */
13843 && !(PT == XFASTINT (w->last_point)
13844 && XFASTINT (w->last_modified) >= MODIFF
13845 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
13846 && (XFASTINT (w->column_number_displayed) != current_column ()))
13847 update_mode_line = 1;
13848
13849 /* Count number of windows showing the selected buffer. An indirect
13850 buffer counts as its base buffer. */
13851 if (!just_this_one_p)
13852 {
13853 struct buffer *current_base, *window_base;
13854 current_base = current_buffer;
13855 window_base = XBUFFER (XWINDOW (selected_window)->buffer);
13856 if (current_base->base_buffer)
13857 current_base = current_base->base_buffer;
13858 if (window_base->base_buffer)
13859 window_base = window_base->base_buffer;
13860 if (current_base == window_base)
13861 buffer_shared++;
13862 }
13863
13864 /* Point refers normally to the selected window. For any other
13865 window, set up appropriate value. */
13866 if (!EQ (window, selected_window))
13867 {
13868 EMACS_INT new_pt = XMARKER (w->pointm)->charpos;
13869 EMACS_INT new_pt_byte = marker_byte_position (w->pointm);
13870 if (new_pt < BEGV)
13871 {
13872 new_pt = BEGV;
13873 new_pt_byte = BEGV_BYTE;
13874 set_marker_both (w->pointm, Qnil, BEGV, BEGV_BYTE);
13875 }
13876 else if (new_pt > (ZV - 1))
13877 {
13878 new_pt = ZV;
13879 new_pt_byte = ZV_BYTE;
13880 set_marker_both (w->pointm, Qnil, ZV, ZV_BYTE);
13881 }
13882
13883 /* We don't use SET_PT so that the point-motion hooks don't run. */
13884 TEMP_SET_PT_BOTH (new_pt, new_pt_byte);
13885 }
13886
13887 /* If any of the character widths specified in the display table
13888 have changed, invalidate the width run cache. It's true that
13889 this may be a bit late to catch such changes, but the rest of
13890 redisplay goes (non-fatally) haywire when the display table is
13891 changed, so why should we worry about doing any better? */
13892 if (current_buffer->width_run_cache)
13893 {
13894 struct Lisp_Char_Table *disptab = buffer_display_table ();
13895
13896 if (! disptab_matches_widthtab (disptab,
13897 XVECTOR (BVAR (current_buffer, width_table))))
13898 {
13899 invalidate_region_cache (current_buffer,
13900 current_buffer->width_run_cache,
13901 BEG, Z);
13902 recompute_width_table (current_buffer, disptab);
13903 }
13904 }
13905
13906 /* If window-start is screwed up, choose a new one. */
13907 if (XMARKER (w->start)->buffer != current_buffer)
13908 goto recenter;
13909
13910 SET_TEXT_POS_FROM_MARKER (startp, w->start);
13911
13912 /* If someone specified a new starting point but did not insist,
13913 check whether it can be used. */
13914 if (!NILP (w->optional_new_start)
13915 && CHARPOS (startp) >= BEGV
13916 && CHARPOS (startp) <= ZV)
13917 {
13918 w->optional_new_start = Qnil;
13919 start_display (&it, w, startp);
13920 move_it_to (&it, PT, 0, it.last_visible_y, -1,
13921 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
13922 if (IT_CHARPOS (it) == PT)
13923 w->force_start = Qt;
13924 /* IT may overshoot PT if text at PT is invisible. */
13925 else if (IT_CHARPOS (it) > PT && CHARPOS (startp) <= PT)
13926 w->force_start = Qt;
13927 }
13928
13929 force_start:
13930
13931 /* Handle case where place to start displaying has been specified,
13932 unless the specified location is outside the accessible range. */
13933 if (!NILP (w->force_start)
13934 || w->frozen_window_start_p)
13935 {
13936 /* We set this later on if we have to adjust point. */
13937 int new_vpos = -1;
13938
13939 w->force_start = Qnil;
13940 w->vscroll = 0;
13941 w->window_end_valid = Qnil;
13942
13943 /* Forget any recorded base line for line number display. */
13944 if (!buffer_unchanged_p)
13945 w->base_line_number = Qnil;
13946
13947 /* Redisplay the mode line. Select the buffer properly for that.
13948 Also, run the hook window-scroll-functions
13949 because we have scrolled. */
13950 /* Note, we do this after clearing force_start because
13951 if there's an error, it is better to forget about force_start
13952 than to get into an infinite loop calling the hook functions
13953 and having them get more errors. */
13954 if (!update_mode_line
13955 || ! NILP (Vwindow_scroll_functions))
13956 {
13957 update_mode_line = 1;
13958 w->update_mode_line = Qt;
13959 startp = run_window_scroll_functions (window, startp);
13960 }
13961
13962 w->last_modified = make_number (0);
13963 w->last_overlay_modified = make_number (0);
13964 if (CHARPOS (startp) < BEGV)
13965 SET_TEXT_POS (startp, BEGV, BEGV_BYTE);
13966 else if (CHARPOS (startp) > ZV)
13967 SET_TEXT_POS (startp, ZV, ZV_BYTE);
13968
13969 /* Redisplay, then check if cursor has been set during the
13970 redisplay. Give up if new fonts were loaded. */
13971 /* We used to issue a CHECK_MARGINS argument to try_window here,
13972 but this causes scrolling to fail when point begins inside
13973 the scroll margin (bug#148) -- cyd */
13974 if (!try_window (window, startp, 0))
13975 {
13976 w->force_start = Qt;
13977 clear_glyph_matrix (w->desired_matrix);
13978 goto need_larger_matrices;
13979 }
13980
13981 if (w->cursor.vpos < 0 && !w->frozen_window_start_p)
13982 {
13983 /* If point does not appear, try to move point so it does
13984 appear. The desired matrix has been built above, so we
13985 can use it here. */
13986 new_vpos = window_box_height (w) / 2;
13987 }
13988
13989 if (!cursor_row_fully_visible_p (w, 0, 0))
13990 {
13991 /* Point does appear, but on a line partly visible at end of window.
13992 Move it back to a fully-visible line. */
13993 new_vpos = window_box_height (w);
13994 }
13995
13996 /* If we need to move point for either of the above reasons,
13997 now actually do it. */
13998 if (new_vpos >= 0)
13999 {
14000 struct glyph_row *row;
14001
14002 row = MATRIX_FIRST_TEXT_ROW (w->desired_matrix);
14003 while (MATRIX_ROW_BOTTOM_Y (row) < new_vpos)
14004 ++row;
14005
14006 TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row),
14007 MATRIX_ROW_START_BYTEPOS (row));
14008
14009 if (w != XWINDOW (selected_window))
14010 set_marker_both (w->pointm, Qnil, PT, PT_BYTE);
14011 else if (current_buffer == old)
14012 SET_TEXT_POS (lpoint, PT, PT_BYTE);
14013
14014 set_cursor_from_row (w, row, w->desired_matrix, 0, 0, 0, 0);
14015
14016 /* If we are highlighting the region, then we just changed
14017 the region, so redisplay to show it. */
14018 if (!NILP (Vtransient_mark_mode)
14019 && !NILP (BVAR (current_buffer, mark_active)))
14020 {
14021 clear_glyph_matrix (w->desired_matrix);
14022 if (!try_window (window, startp, 0))
14023 goto need_larger_matrices;
14024 }
14025 }
14026
14027 #if GLYPH_DEBUG
14028 debug_method_add (w, "forced window start");
14029 #endif
14030 goto done;
14031 }
14032
14033 /* Handle case where text has not changed, only point, and it has
14034 not moved off the frame, and we are not retrying after hscroll.
14035 (current_matrix_up_to_date_p is nonzero when retrying.) */
14036 if (current_matrix_up_to_date_p
14037 && (rc = try_cursor_movement (window, startp, &temp_scroll_step),
14038 rc != CURSOR_MOVEMENT_CANNOT_BE_USED))
14039 {
14040 switch (rc)
14041 {
14042 case CURSOR_MOVEMENT_SUCCESS:
14043 used_current_matrix_p = 1;
14044 goto done;
14045
14046 case CURSOR_MOVEMENT_MUST_SCROLL:
14047 goto try_to_scroll;
14048
14049 default:
14050 abort ();
14051 }
14052 }
14053 /* If current starting point was originally the beginning of a line
14054 but no longer is, find a new starting point. */
14055 else if (!NILP (w->start_at_line_beg)
14056 && !(CHARPOS (startp) <= BEGV
14057 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n'))
14058 {
14059 #if GLYPH_DEBUG
14060 debug_method_add (w, "recenter 1");
14061 #endif
14062 goto recenter;
14063 }
14064
14065 /* Try scrolling with try_window_id. Value is > 0 if update has
14066 been done, it is -1 if we know that the same window start will
14067 not work. It is 0 if unsuccessful for some other reason. */
14068 else if ((tem = try_window_id (w)) != 0)
14069 {
14070 #if GLYPH_DEBUG
14071 debug_method_add (w, "try_window_id %d", tem);
14072 #endif
14073
14074 if (fonts_changed_p)
14075 goto need_larger_matrices;
14076 if (tem > 0)
14077 goto done;
14078
14079 /* Otherwise try_window_id has returned -1 which means that we
14080 don't want the alternative below this comment to execute. */
14081 }
14082 else if (CHARPOS (startp) >= BEGV
14083 && CHARPOS (startp) <= ZV
14084 && PT >= CHARPOS (startp)
14085 && (CHARPOS (startp) < ZV
14086 /* Avoid starting at end of buffer. */
14087 || CHARPOS (startp) == BEGV
14088 || (XFASTINT (w->last_modified) >= MODIFF
14089 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)))
14090 {
14091
14092 /* If first window line is a continuation line, and window start
14093 is inside the modified region, but the first change is before
14094 current window start, we must select a new window start.
14095
14096 However, if this is the result of a down-mouse event (e.g. by
14097 extending the mouse-drag-overlay), we don't want to select a
14098 new window start, since that would change the position under
14099 the mouse, resulting in an unwanted mouse-movement rather
14100 than a simple mouse-click. */
14101 if (NILP (w->start_at_line_beg)
14102 && NILP (do_mouse_tracking)
14103 && CHARPOS (startp) > BEGV
14104 && CHARPOS (startp) > BEG + beg_unchanged
14105 && CHARPOS (startp) <= Z - end_unchanged
14106 /* Even if w->start_at_line_beg is nil, a new window may
14107 start at a line_beg, since that's how set_buffer_window
14108 sets it. So, we need to check the return value of
14109 compute_window_start_on_continuation_line. (See also
14110 bug#197). */
14111 && XMARKER (w->start)->buffer == current_buffer
14112 && compute_window_start_on_continuation_line (w))
14113 {
14114 w->force_start = Qt;
14115 SET_TEXT_POS_FROM_MARKER (startp, w->start);
14116 goto force_start;
14117 }
14118
14119 #if GLYPH_DEBUG
14120 debug_method_add (w, "same window start");
14121 #endif
14122
14123 /* Try to redisplay starting at same place as before.
14124 If point has not moved off frame, accept the results. */
14125 if (!current_matrix_up_to_date_p
14126 /* Don't use try_window_reusing_current_matrix in this case
14127 because a window scroll function can have changed the
14128 buffer. */
14129 || !NILP (Vwindow_scroll_functions)
14130 || MINI_WINDOW_P (w)
14131 || !(used_current_matrix_p
14132 = try_window_reusing_current_matrix (w)))
14133 {
14134 IF_DEBUG (debug_method_add (w, "1"));
14135 if (try_window (window, startp, TRY_WINDOW_CHECK_MARGINS) < 0)
14136 /* -1 means we need to scroll.
14137 0 means we need new matrices, but fonts_changed_p
14138 is set in that case, so we will detect it below. */
14139 goto try_to_scroll;
14140 }
14141
14142 if (fonts_changed_p)
14143 goto need_larger_matrices;
14144
14145 if (w->cursor.vpos >= 0)
14146 {
14147 if (!just_this_one_p
14148 || current_buffer->clip_changed
14149 || BEG_UNCHANGED < CHARPOS (startp))
14150 /* Forget any recorded base line for line number display. */
14151 w->base_line_number = Qnil;
14152
14153 if (!cursor_row_fully_visible_p (w, 1, 0))
14154 {
14155 clear_glyph_matrix (w->desired_matrix);
14156 last_line_misfit = 1;
14157 }
14158 /* Drop through and scroll. */
14159 else
14160 goto done;
14161 }
14162 else
14163 clear_glyph_matrix (w->desired_matrix);
14164 }
14165
14166 try_to_scroll:
14167
14168 w->last_modified = make_number (0);
14169 w->last_overlay_modified = make_number (0);
14170
14171 /* Redisplay the mode line. Select the buffer properly for that. */
14172 if (!update_mode_line)
14173 {
14174 update_mode_line = 1;
14175 w->update_mode_line = Qt;
14176 }
14177
14178 /* Try to scroll by specified few lines. */
14179 if ((scroll_conservatively
14180 || emacs_scroll_step
14181 || temp_scroll_step
14182 || NUMBERP (BVAR (current_buffer, scroll_up_aggressively))
14183 || NUMBERP (BVAR (current_buffer, scroll_down_aggressively)))
14184 && CHARPOS (startp) >= BEGV
14185 && CHARPOS (startp) <= ZV)
14186 {
14187 /* The function returns -1 if new fonts were loaded, 1 if
14188 successful, 0 if not successful. */
14189 int ss = try_scrolling (window, just_this_one_p,
14190 scroll_conservatively,
14191 emacs_scroll_step,
14192 temp_scroll_step, last_line_misfit);
14193 switch (ss)
14194 {
14195 case SCROLLING_SUCCESS:
14196 goto done;
14197
14198 case SCROLLING_NEED_LARGER_MATRICES:
14199 goto need_larger_matrices;
14200
14201 case SCROLLING_FAILED:
14202 break;
14203
14204 default:
14205 abort ();
14206 }
14207 }
14208
14209 /* Finally, just choose a place to start which positions point
14210 according to user preferences. */
14211
14212 recenter:
14213
14214 #if GLYPH_DEBUG
14215 debug_method_add (w, "recenter");
14216 #endif
14217
14218 /* w->vscroll = 0; */
14219
14220 /* Forget any previously recorded base line for line number display. */
14221 if (!buffer_unchanged_p)
14222 w->base_line_number = Qnil;
14223
14224 /* Determine the window start relative to point. */
14225 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
14226 it.current_y = it.last_visible_y;
14227 if (centering_position < 0)
14228 {
14229 int margin =
14230 scroll_margin > 0
14231 ? min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4)
14232 : 0;
14233 EMACS_INT margin_pos = CHARPOS (startp);
14234 int scrolling_up;
14235 Lisp_Object aggressive;
14236
14237 /* If there is a scroll margin at the top of the window, find
14238 its character position. */
14239 if (margin)
14240 {
14241 struct it it1;
14242
14243 start_display (&it1, w, startp);
14244 move_it_vertically (&it1, margin);
14245 margin_pos = IT_CHARPOS (it1);
14246 }
14247 scrolling_up = PT > margin_pos;
14248 aggressive =
14249 scrolling_up
14250 ? BVAR (current_buffer, scroll_up_aggressively)
14251 : BVAR (current_buffer, scroll_down_aggressively);
14252
14253 if (!MINI_WINDOW_P (w)
14254 && (scroll_conservatively > SCROLL_LIMIT || NUMBERP (aggressive)))
14255 {
14256 int pt_offset = 0;
14257
14258 /* Setting scroll-conservatively overrides
14259 scroll-*-aggressively. */
14260 if (!scroll_conservatively && NUMBERP (aggressive))
14261 {
14262 double float_amount = XFLOATINT (aggressive);
14263
14264 pt_offset = float_amount * WINDOW_BOX_TEXT_HEIGHT (w);
14265 if (pt_offset == 0 && float_amount > 0)
14266 pt_offset = 1;
14267 if (pt_offset)
14268 margin -= 1;
14269 }
14270 /* Compute how much to move the window start backward from
14271 point so that point will be displayed where the user
14272 wants it. */
14273 if (scrolling_up)
14274 {
14275 centering_position = it.last_visible_y;
14276 if (pt_offset)
14277 centering_position -= pt_offset;
14278 centering_position -=
14279 FRAME_LINE_HEIGHT (f) * (1 + margin + (last_line_misfit != 0));
14280 /* Don't let point enter the scroll margin near top of
14281 the window. */
14282 if (centering_position < margin * FRAME_LINE_HEIGHT (f))
14283 centering_position = margin * FRAME_LINE_HEIGHT (f);
14284 }
14285 else
14286 centering_position = margin * FRAME_LINE_HEIGHT (f) + pt_offset;
14287 }
14288 else
14289 /* Set the window start half the height of the window backward
14290 from point. */
14291 centering_position = window_box_height (w) / 2;
14292 }
14293 move_it_vertically_backward (&it, centering_position);
14294
14295 xassert (IT_CHARPOS (it) >= BEGV);
14296
14297 /* The function move_it_vertically_backward may move over more
14298 than the specified y-distance. If it->w is small, e.g. a
14299 mini-buffer window, we may end up in front of the window's
14300 display area. Start displaying at the start of the line
14301 containing PT in this case. */
14302 if (it.current_y <= 0)
14303 {
14304 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
14305 move_it_vertically_backward (&it, 0);
14306 it.current_y = 0;
14307 }
14308
14309 it.current_x = it.hpos = 0;
14310
14311 /* Set the window start position here explicitly, to avoid an
14312 infinite loop in case the functions in window-scroll-functions
14313 get errors. */
14314 set_marker_both (w->start, Qnil, IT_CHARPOS (it), IT_BYTEPOS (it));
14315
14316 /* Run scroll hooks. */
14317 startp = run_window_scroll_functions (window, it.current.pos);
14318
14319 /* Redisplay the window. */
14320 if (!current_matrix_up_to_date_p
14321 || windows_or_buffers_changed
14322 || cursor_type_changed
14323 /* Don't use try_window_reusing_current_matrix in this case
14324 because it can have changed the buffer. */
14325 || !NILP (Vwindow_scroll_functions)
14326 || !just_this_one_p
14327 || MINI_WINDOW_P (w)
14328 || !(used_current_matrix_p
14329 = try_window_reusing_current_matrix (w)))
14330 try_window (window, startp, 0);
14331
14332 /* If new fonts have been loaded (due to fontsets), give up. We
14333 have to start a new redisplay since we need to re-adjust glyph
14334 matrices. */
14335 if (fonts_changed_p)
14336 goto need_larger_matrices;
14337
14338 /* If cursor did not appear assume that the middle of the window is
14339 in the first line of the window. Do it again with the next line.
14340 (Imagine a window of height 100, displaying two lines of height
14341 60. Moving back 50 from it->last_visible_y will end in the first
14342 line.) */
14343 if (w->cursor.vpos < 0)
14344 {
14345 if (!NILP (w->window_end_valid)
14346 && PT >= Z - XFASTINT (w->window_end_pos))
14347 {
14348 clear_glyph_matrix (w->desired_matrix);
14349 move_it_by_lines (&it, 1);
14350 try_window (window, it.current.pos, 0);
14351 }
14352 else if (PT < IT_CHARPOS (it))
14353 {
14354 clear_glyph_matrix (w->desired_matrix);
14355 move_it_by_lines (&it, -1);
14356 try_window (window, it.current.pos, 0);
14357 }
14358 else
14359 {
14360 /* Not much we can do about it. */
14361 }
14362 }
14363
14364 /* Consider the following case: Window starts at BEGV, there is
14365 invisible, intangible text at BEGV, so that display starts at
14366 some point START > BEGV. It can happen that we are called with
14367 PT somewhere between BEGV and START. Try to handle that case. */
14368 if (w->cursor.vpos < 0)
14369 {
14370 struct glyph_row *row = w->current_matrix->rows;
14371 if (row->mode_line_p)
14372 ++row;
14373 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
14374 }
14375
14376 if (!cursor_row_fully_visible_p (w, 0, 0))
14377 {
14378 /* If vscroll is enabled, disable it and try again. */
14379 if (w->vscroll)
14380 {
14381 w->vscroll = 0;
14382 clear_glyph_matrix (w->desired_matrix);
14383 goto recenter;
14384 }
14385
14386 /* If centering point failed to make the whole line visible,
14387 put point at the top instead. That has to make the whole line
14388 visible, if it can be done. */
14389 if (centering_position == 0)
14390 goto done;
14391
14392 clear_glyph_matrix (w->desired_matrix);
14393 centering_position = 0;
14394 goto recenter;
14395 }
14396
14397 done:
14398
14399 SET_TEXT_POS_FROM_MARKER (startp, w->start);
14400 w->start_at_line_beg = ((CHARPOS (startp) == BEGV
14401 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n')
14402 ? Qt : Qnil);
14403
14404 /* Display the mode line, if we must. */
14405 if ((update_mode_line
14406 /* If window not full width, must redo its mode line
14407 if (a) the window to its side is being redone and
14408 (b) we do a frame-based redisplay. This is a consequence
14409 of how inverted lines are drawn in frame-based redisplay. */
14410 || (!just_this_one_p
14411 && !FRAME_WINDOW_P (f)
14412 && !WINDOW_FULL_WIDTH_P (w))
14413 /* Line number to display. */
14414 || INTEGERP (w->base_line_pos)
14415 /* Column number is displayed and different from the one displayed. */
14416 || (!NILP (w->column_number_displayed)
14417 && (XFASTINT (w->column_number_displayed) != current_column ())))
14418 /* This means that the window has a mode line. */
14419 && (WINDOW_WANTS_MODELINE_P (w)
14420 || WINDOW_WANTS_HEADER_LINE_P (w)))
14421 {
14422 display_mode_lines (w);
14423
14424 /* If mode line height has changed, arrange for a thorough
14425 immediate redisplay using the correct mode line height. */
14426 if (WINDOW_WANTS_MODELINE_P (w)
14427 && CURRENT_MODE_LINE_HEIGHT (w) != DESIRED_MODE_LINE_HEIGHT (w))
14428 {
14429 fonts_changed_p = 1;
14430 MATRIX_MODE_LINE_ROW (w->current_matrix)->height
14431 = DESIRED_MODE_LINE_HEIGHT (w);
14432 }
14433
14434 /* If header line height has changed, arrange for a thorough
14435 immediate redisplay using the correct header line height. */
14436 if (WINDOW_WANTS_HEADER_LINE_P (w)
14437 && CURRENT_HEADER_LINE_HEIGHT (w) != DESIRED_HEADER_LINE_HEIGHT (w))
14438 {
14439 fonts_changed_p = 1;
14440 MATRIX_HEADER_LINE_ROW (w->current_matrix)->height
14441 = DESIRED_HEADER_LINE_HEIGHT (w);
14442 }
14443
14444 if (fonts_changed_p)
14445 goto need_larger_matrices;
14446 }
14447
14448 if (!line_number_displayed
14449 && !BUFFERP (w->base_line_pos))
14450 {
14451 w->base_line_pos = Qnil;
14452 w->base_line_number = Qnil;
14453 }
14454
14455 finish_menu_bars:
14456
14457 /* When we reach a frame's selected window, redo the frame's menu bar. */
14458 if (update_mode_line
14459 && EQ (FRAME_SELECTED_WINDOW (f), window))
14460 {
14461 int redisplay_menu_p = 0;
14462 int redisplay_tool_bar_p = 0;
14463
14464 if (FRAME_WINDOW_P (f))
14465 {
14466 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
14467 || defined (HAVE_NS) || defined (USE_GTK)
14468 redisplay_menu_p = FRAME_EXTERNAL_MENU_BAR (f);
14469 #else
14470 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
14471 #endif
14472 }
14473 else
14474 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
14475
14476 if (redisplay_menu_p)
14477 display_menu_bar (w);
14478
14479 #ifdef HAVE_WINDOW_SYSTEM
14480 if (FRAME_WINDOW_P (f))
14481 {
14482 #if defined (USE_GTK) || defined (HAVE_NS)
14483 redisplay_tool_bar_p = FRAME_EXTERNAL_TOOL_BAR (f);
14484 #else
14485 redisplay_tool_bar_p = WINDOWP (f->tool_bar_window)
14486 && (FRAME_TOOL_BAR_LINES (f) > 0
14487 || !NILP (Vauto_resize_tool_bars));
14488 #endif
14489
14490 if (redisplay_tool_bar_p && redisplay_tool_bar (f))
14491 {
14492 ignore_mouse_drag_p = 1;
14493 }
14494 }
14495 #endif
14496 }
14497
14498 #ifdef HAVE_WINDOW_SYSTEM
14499 if (FRAME_WINDOW_P (f)
14500 && update_window_fringes (w, (just_this_one_p
14501 || (!used_current_matrix_p && !overlay_arrow_seen)
14502 || w->pseudo_window_p)))
14503 {
14504 update_begin (f);
14505 BLOCK_INPUT;
14506 if (draw_window_fringes (w, 1))
14507 x_draw_vertical_border (w);
14508 UNBLOCK_INPUT;
14509 update_end (f);
14510 }
14511 #endif /* HAVE_WINDOW_SYSTEM */
14512
14513 /* We go to this label, with fonts_changed_p nonzero,
14514 if it is necessary to try again using larger glyph matrices.
14515 We have to redeem the scroll bar even in this case,
14516 because the loop in redisplay_internal expects that. */
14517 need_larger_matrices:
14518 ;
14519 finish_scroll_bars:
14520
14521 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
14522 {
14523 /* Set the thumb's position and size. */
14524 set_vertical_scroll_bar (w);
14525
14526 /* Note that we actually used the scroll bar attached to this
14527 window, so it shouldn't be deleted at the end of redisplay. */
14528 if (FRAME_TERMINAL (f)->redeem_scroll_bar_hook)
14529 (*FRAME_TERMINAL (f)->redeem_scroll_bar_hook) (w);
14530 }
14531
14532 /* Restore current_buffer and value of point in it. The window
14533 update may have changed the buffer, so first make sure `opoint'
14534 is still valid (Bug#6177). */
14535 if (CHARPOS (opoint) < BEGV)
14536 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
14537 else if (CHARPOS (opoint) > ZV)
14538 TEMP_SET_PT_BOTH (Z, Z_BYTE);
14539 else
14540 TEMP_SET_PT_BOTH (CHARPOS (opoint), BYTEPOS (opoint));
14541
14542 set_buffer_internal_1 (old);
14543 /* Avoid an abort in TEMP_SET_PT_BOTH if the buffer has become
14544 shorter. This can be caused by log truncation in *Messages*. */
14545 if (CHARPOS (lpoint) <= ZV)
14546 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
14547
14548 unbind_to (count, Qnil);
14549 }
14550
14551
14552 /* Build the complete desired matrix of WINDOW with a window start
14553 buffer position POS.
14554
14555 Value is 1 if successful. It is zero if fonts were loaded during
14556 redisplay which makes re-adjusting glyph matrices necessary, and -1
14557 if point would appear in the scroll margins.
14558 (We check the former only if TRY_WINDOW_IGNORE_FONTS_CHANGE is
14559 unset in FLAGS, and the latter only if TRY_WINDOW_CHECK_MARGINS is
14560 set in FLAGS.) */
14561
14562 int
14563 try_window (Lisp_Object window, struct text_pos pos, int flags)
14564 {
14565 struct window *w = XWINDOW (window);
14566 struct it it;
14567 struct glyph_row *last_text_row = NULL;
14568 struct frame *f = XFRAME (w->frame);
14569
14570 /* Make POS the new window start. */
14571 set_marker_both (w->start, Qnil, CHARPOS (pos), BYTEPOS (pos));
14572
14573 /* Mark cursor position as unknown. No overlay arrow seen. */
14574 w->cursor.vpos = -1;
14575 overlay_arrow_seen = 0;
14576
14577 /* Initialize iterator and info to start at POS. */
14578 start_display (&it, w, pos);
14579
14580 /* Display all lines of W. */
14581 while (it.current_y < it.last_visible_y)
14582 {
14583 if (display_line (&it))
14584 last_text_row = it.glyph_row - 1;
14585 if (fonts_changed_p && !(flags & TRY_WINDOW_IGNORE_FONTS_CHANGE))
14586 return 0;
14587 }
14588
14589 /* Don't let the cursor end in the scroll margins. */
14590 if ((flags & TRY_WINDOW_CHECK_MARGINS)
14591 && !MINI_WINDOW_P (w))
14592 {
14593 int this_scroll_margin;
14594
14595 if (scroll_margin > 0)
14596 {
14597 this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
14598 this_scroll_margin *= FRAME_LINE_HEIGHT (f);
14599 }
14600 else
14601 this_scroll_margin = 0;
14602
14603 if ((w->cursor.y >= 0 /* not vscrolled */
14604 && w->cursor.y < this_scroll_margin
14605 && CHARPOS (pos) > BEGV
14606 && IT_CHARPOS (it) < ZV)
14607 /* rms: considering make_cursor_line_fully_visible_p here
14608 seems to give wrong results. We don't want to recenter
14609 when the last line is partly visible, we want to allow
14610 that case to be handled in the usual way. */
14611 || w->cursor.y > it.last_visible_y - this_scroll_margin - 1)
14612 {
14613 w->cursor.vpos = -1;
14614 clear_glyph_matrix (w->desired_matrix);
14615 return -1;
14616 }
14617 }
14618
14619 /* If bottom moved off end of frame, change mode line percentage. */
14620 if (XFASTINT (w->window_end_pos) <= 0
14621 && Z != IT_CHARPOS (it))
14622 w->update_mode_line = Qt;
14623
14624 /* Set window_end_pos to the offset of the last character displayed
14625 on the window from the end of current_buffer. Set
14626 window_end_vpos to its row number. */
14627 if (last_text_row)
14628 {
14629 xassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row));
14630 w->window_end_bytepos
14631 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
14632 w->window_end_pos
14633 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
14634 w->window_end_vpos
14635 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
14636 xassert (MATRIX_ROW (w->desired_matrix, XFASTINT (w->window_end_vpos))
14637 ->displays_text_p);
14638 }
14639 else
14640 {
14641 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
14642 w->window_end_pos = make_number (Z - ZV);
14643 w->window_end_vpos = make_number (0);
14644 }
14645
14646 /* But that is not valid info until redisplay finishes. */
14647 w->window_end_valid = Qnil;
14648 return 1;
14649 }
14650
14651
14652 \f
14653 /************************************************************************
14654 Window redisplay reusing current matrix when buffer has not changed
14655 ************************************************************************/
14656
14657 /* Try redisplay of window W showing an unchanged buffer with a
14658 different window start than the last time it was displayed by
14659 reusing its current matrix. Value is non-zero if successful.
14660 W->start is the new window start. */
14661
14662 static int
14663 try_window_reusing_current_matrix (struct window *w)
14664 {
14665 struct frame *f = XFRAME (w->frame);
14666 struct glyph_row *bottom_row;
14667 struct it it;
14668 struct run run;
14669 struct text_pos start, new_start;
14670 int nrows_scrolled, i;
14671 struct glyph_row *last_text_row;
14672 struct glyph_row *last_reused_text_row;
14673 struct glyph_row *start_row;
14674 int start_vpos, min_y, max_y;
14675
14676 #if GLYPH_DEBUG
14677 if (inhibit_try_window_reusing)
14678 return 0;
14679 #endif
14680
14681 if (/* This function doesn't handle terminal frames. */
14682 !FRAME_WINDOW_P (f)
14683 /* Don't try to reuse the display if windows have been split
14684 or such. */
14685 || windows_or_buffers_changed
14686 || cursor_type_changed)
14687 return 0;
14688
14689 /* Can't do this if region may have changed. */
14690 if ((!NILP (Vtransient_mark_mode)
14691 && !NILP (BVAR (current_buffer, mark_active)))
14692 || !NILP (w->region_showing)
14693 || !NILP (Vshow_trailing_whitespace))
14694 return 0;
14695
14696 /* If top-line visibility has changed, give up. */
14697 if (WINDOW_WANTS_HEADER_LINE_P (w)
14698 != MATRIX_HEADER_LINE_ROW (w->current_matrix)->mode_line_p)
14699 return 0;
14700
14701 /* Give up if old or new display is scrolled vertically. We could
14702 make this function handle this, but right now it doesn't. */
14703 start_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
14704 if (w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row))
14705 return 0;
14706
14707 /* The variable new_start now holds the new window start. The old
14708 start `start' can be determined from the current matrix. */
14709 SET_TEXT_POS_FROM_MARKER (new_start, w->start);
14710 start = start_row->minpos;
14711 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
14712
14713 /* Clear the desired matrix for the display below. */
14714 clear_glyph_matrix (w->desired_matrix);
14715
14716 if (CHARPOS (new_start) <= CHARPOS (start))
14717 {
14718 /* Don't use this method if the display starts with an ellipsis
14719 displayed for invisible text. It's not easy to handle that case
14720 below, and it's certainly not worth the effort since this is
14721 not a frequent case. */
14722 if (in_ellipses_for_invisible_text_p (&start_row->start, w))
14723 return 0;
14724
14725 IF_DEBUG (debug_method_add (w, "twu1"));
14726
14727 /* Display up to a row that can be reused. The variable
14728 last_text_row is set to the last row displayed that displays
14729 text. Note that it.vpos == 0 if or if not there is a
14730 header-line; it's not the same as the MATRIX_ROW_VPOS! */
14731 start_display (&it, w, new_start);
14732 w->cursor.vpos = -1;
14733 last_text_row = last_reused_text_row = NULL;
14734
14735 while (it.current_y < it.last_visible_y
14736 && !fonts_changed_p)
14737 {
14738 /* If we have reached into the characters in the START row,
14739 that means the line boundaries have changed. So we
14740 can't start copying with the row START. Maybe it will
14741 work to start copying with the following row. */
14742 while (IT_CHARPOS (it) > CHARPOS (start))
14743 {
14744 /* Advance to the next row as the "start". */
14745 start_row++;
14746 start = start_row->minpos;
14747 /* If there are no more rows to try, or just one, give up. */
14748 if (start_row == MATRIX_MODE_LINE_ROW (w->current_matrix) - 1
14749 || w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row)
14750 || CHARPOS (start) == ZV)
14751 {
14752 clear_glyph_matrix (w->desired_matrix);
14753 return 0;
14754 }
14755
14756 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
14757 }
14758 /* If we have reached alignment,
14759 we can copy the rest of the rows. */
14760 if (IT_CHARPOS (it) == CHARPOS (start))
14761 break;
14762
14763 if (display_line (&it))
14764 last_text_row = it.glyph_row - 1;
14765 }
14766
14767 /* A value of current_y < last_visible_y means that we stopped
14768 at the previous window start, which in turn means that we
14769 have at least one reusable row. */
14770 if (it.current_y < it.last_visible_y)
14771 {
14772 struct glyph_row *row;
14773
14774 /* IT.vpos always starts from 0; it counts text lines. */
14775 nrows_scrolled = it.vpos - (start_row - MATRIX_FIRST_TEXT_ROW (w->current_matrix));
14776
14777 /* Find PT if not already found in the lines displayed. */
14778 if (w->cursor.vpos < 0)
14779 {
14780 int dy = it.current_y - start_row->y;
14781
14782 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
14783 row = row_containing_pos (w, PT, row, NULL, dy);
14784 if (row)
14785 set_cursor_from_row (w, row, w->current_matrix, 0, 0,
14786 dy, nrows_scrolled);
14787 else
14788 {
14789 clear_glyph_matrix (w->desired_matrix);
14790 return 0;
14791 }
14792 }
14793
14794 /* Scroll the display. Do it before the current matrix is
14795 changed. The problem here is that update has not yet
14796 run, i.e. part of the current matrix is not up to date.
14797 scroll_run_hook will clear the cursor, and use the
14798 current matrix to get the height of the row the cursor is
14799 in. */
14800 run.current_y = start_row->y;
14801 run.desired_y = it.current_y;
14802 run.height = it.last_visible_y - it.current_y;
14803
14804 if (run.height > 0 && run.current_y != run.desired_y)
14805 {
14806 update_begin (f);
14807 FRAME_RIF (f)->update_window_begin_hook (w);
14808 FRAME_RIF (f)->clear_window_mouse_face (w);
14809 FRAME_RIF (f)->scroll_run_hook (w, &run);
14810 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
14811 update_end (f);
14812 }
14813
14814 /* Shift current matrix down by nrows_scrolled lines. */
14815 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
14816 rotate_matrix (w->current_matrix,
14817 start_vpos,
14818 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
14819 nrows_scrolled);
14820
14821 /* Disable lines that must be updated. */
14822 for (i = 0; i < nrows_scrolled; ++i)
14823 (start_row + i)->enabled_p = 0;
14824
14825 /* Re-compute Y positions. */
14826 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
14827 max_y = it.last_visible_y;
14828 for (row = start_row + nrows_scrolled;
14829 row < bottom_row;
14830 ++row)
14831 {
14832 row->y = it.current_y;
14833 row->visible_height = row->height;
14834
14835 if (row->y < min_y)
14836 row->visible_height -= min_y - row->y;
14837 if (row->y + row->height > max_y)
14838 row->visible_height -= row->y + row->height - max_y;
14839 row->redraw_fringe_bitmaps_p = 1;
14840
14841 it.current_y += row->height;
14842
14843 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
14844 last_reused_text_row = row;
14845 if (MATRIX_ROW_BOTTOM_Y (row) >= it.last_visible_y)
14846 break;
14847 }
14848
14849 /* Disable lines in the current matrix which are now
14850 below the window. */
14851 for (++row; row < bottom_row; ++row)
14852 row->enabled_p = row->mode_line_p = 0;
14853 }
14854
14855 /* Update window_end_pos etc.; last_reused_text_row is the last
14856 reused row from the current matrix containing text, if any.
14857 The value of last_text_row is the last displayed line
14858 containing text. */
14859 if (last_reused_text_row)
14860 {
14861 w->window_end_bytepos
14862 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_reused_text_row);
14863 w->window_end_pos
14864 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_reused_text_row));
14865 w->window_end_vpos
14866 = make_number (MATRIX_ROW_VPOS (last_reused_text_row,
14867 w->current_matrix));
14868 }
14869 else if (last_text_row)
14870 {
14871 w->window_end_bytepos
14872 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
14873 w->window_end_pos
14874 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
14875 w->window_end_vpos
14876 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
14877 }
14878 else
14879 {
14880 /* This window must be completely empty. */
14881 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
14882 w->window_end_pos = make_number (Z - ZV);
14883 w->window_end_vpos = make_number (0);
14884 }
14885 w->window_end_valid = Qnil;
14886
14887 /* Update hint: don't try scrolling again in update_window. */
14888 w->desired_matrix->no_scrolling_p = 1;
14889
14890 #if GLYPH_DEBUG
14891 debug_method_add (w, "try_window_reusing_current_matrix 1");
14892 #endif
14893 return 1;
14894 }
14895 else if (CHARPOS (new_start) > CHARPOS (start))
14896 {
14897 struct glyph_row *pt_row, *row;
14898 struct glyph_row *first_reusable_row;
14899 struct glyph_row *first_row_to_display;
14900 int dy;
14901 int yb = window_text_bottom_y (w);
14902
14903 /* Find the row starting at new_start, if there is one. Don't
14904 reuse a partially visible line at the end. */
14905 first_reusable_row = start_row;
14906 while (first_reusable_row->enabled_p
14907 && MATRIX_ROW_BOTTOM_Y (first_reusable_row) < yb
14908 && (MATRIX_ROW_START_CHARPOS (first_reusable_row)
14909 < CHARPOS (new_start)))
14910 ++first_reusable_row;
14911
14912 /* Give up if there is no row to reuse. */
14913 if (MATRIX_ROW_BOTTOM_Y (first_reusable_row) >= yb
14914 || !first_reusable_row->enabled_p
14915 || (MATRIX_ROW_START_CHARPOS (first_reusable_row)
14916 != CHARPOS (new_start)))
14917 return 0;
14918
14919 /* We can reuse fully visible rows beginning with
14920 first_reusable_row to the end of the window. Set
14921 first_row_to_display to the first row that cannot be reused.
14922 Set pt_row to the row containing point, if there is any. */
14923 pt_row = NULL;
14924 for (first_row_to_display = first_reusable_row;
14925 MATRIX_ROW_BOTTOM_Y (first_row_to_display) < yb;
14926 ++first_row_to_display)
14927 {
14928 if (PT >= MATRIX_ROW_START_CHARPOS (first_row_to_display)
14929 && PT < MATRIX_ROW_END_CHARPOS (first_row_to_display))
14930 pt_row = first_row_to_display;
14931 }
14932
14933 /* Start displaying at the start of first_row_to_display. */
14934 xassert (first_row_to_display->y < yb);
14935 init_to_row_start (&it, w, first_row_to_display);
14936
14937 nrows_scrolled = (MATRIX_ROW_VPOS (first_reusable_row, w->current_matrix)
14938 - start_vpos);
14939 it.vpos = (MATRIX_ROW_VPOS (first_row_to_display, w->current_matrix)
14940 - nrows_scrolled);
14941 it.current_y = (first_row_to_display->y - first_reusable_row->y
14942 + WINDOW_HEADER_LINE_HEIGHT (w));
14943
14944 /* Display lines beginning with first_row_to_display in the
14945 desired matrix. Set last_text_row to the last row displayed
14946 that displays text. */
14947 it.glyph_row = MATRIX_ROW (w->desired_matrix, it.vpos);
14948 if (pt_row == NULL)
14949 w->cursor.vpos = -1;
14950 last_text_row = NULL;
14951 while (it.current_y < it.last_visible_y && !fonts_changed_p)
14952 if (display_line (&it))
14953 last_text_row = it.glyph_row - 1;
14954
14955 /* If point is in a reused row, adjust y and vpos of the cursor
14956 position. */
14957 if (pt_row)
14958 {
14959 w->cursor.vpos -= nrows_scrolled;
14960 w->cursor.y -= first_reusable_row->y - start_row->y;
14961 }
14962
14963 /* Give up if point isn't in a row displayed or reused. (This
14964 also handles the case where w->cursor.vpos < nrows_scrolled
14965 after the calls to display_line, which can happen with scroll
14966 margins. See bug#1295.) */
14967 if (w->cursor.vpos < 0)
14968 {
14969 clear_glyph_matrix (w->desired_matrix);
14970 return 0;
14971 }
14972
14973 /* Scroll the display. */
14974 run.current_y = first_reusable_row->y;
14975 run.desired_y = WINDOW_HEADER_LINE_HEIGHT (w);
14976 run.height = it.last_visible_y - run.current_y;
14977 dy = run.current_y - run.desired_y;
14978
14979 if (run.height)
14980 {
14981 update_begin (f);
14982 FRAME_RIF (f)->update_window_begin_hook (w);
14983 FRAME_RIF (f)->clear_window_mouse_face (w);
14984 FRAME_RIF (f)->scroll_run_hook (w, &run);
14985 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
14986 update_end (f);
14987 }
14988
14989 /* Adjust Y positions of reused rows. */
14990 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
14991 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
14992 max_y = it.last_visible_y;
14993 for (row = first_reusable_row; row < first_row_to_display; ++row)
14994 {
14995 row->y -= dy;
14996 row->visible_height = row->height;
14997 if (row->y < min_y)
14998 row->visible_height -= min_y - row->y;
14999 if (row->y + row->height > max_y)
15000 row->visible_height -= row->y + row->height - max_y;
15001 row->redraw_fringe_bitmaps_p = 1;
15002 }
15003
15004 /* Scroll the current matrix. */
15005 xassert (nrows_scrolled > 0);
15006 rotate_matrix (w->current_matrix,
15007 start_vpos,
15008 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
15009 -nrows_scrolled);
15010
15011 /* Disable rows not reused. */
15012 for (row -= nrows_scrolled; row < bottom_row; ++row)
15013 row->enabled_p = 0;
15014
15015 /* Point may have moved to a different line, so we cannot assume that
15016 the previous cursor position is valid; locate the correct row. */
15017 if (pt_row)
15018 {
15019 for (row = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
15020 row < bottom_row && PT >= MATRIX_ROW_END_CHARPOS (row);
15021 row++)
15022 {
15023 w->cursor.vpos++;
15024 w->cursor.y = row->y;
15025 }
15026 if (row < bottom_row)
15027 {
15028 struct glyph *glyph = row->glyphs[TEXT_AREA] + w->cursor.hpos;
15029 struct glyph *end = glyph + row->used[TEXT_AREA];
15030
15031 /* Can't use this optimization with bidi-reordered glyph
15032 rows, unless cursor is already at point. */
15033 if (!NILP (BVAR (XBUFFER (w->buffer), bidi_display_reordering)))
15034 {
15035 if (!(w->cursor.hpos >= 0
15036 && w->cursor.hpos < row->used[TEXT_AREA]
15037 && BUFFERP (glyph->object)
15038 && glyph->charpos == PT))
15039 return 0;
15040 }
15041 else
15042 for (; glyph < end
15043 && (!BUFFERP (glyph->object)
15044 || glyph->charpos < PT);
15045 glyph++)
15046 {
15047 w->cursor.hpos++;
15048 w->cursor.x += glyph->pixel_width;
15049 }
15050 }
15051 }
15052
15053 /* Adjust window end. A null value of last_text_row means that
15054 the window end is in reused rows which in turn means that
15055 only its vpos can have changed. */
15056 if (last_text_row)
15057 {
15058 w->window_end_bytepos
15059 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
15060 w->window_end_pos
15061 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
15062 w->window_end_vpos
15063 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
15064 }
15065 else
15066 {
15067 w->window_end_vpos
15068 = make_number (XFASTINT (w->window_end_vpos) - nrows_scrolled);
15069 }
15070
15071 w->window_end_valid = Qnil;
15072 w->desired_matrix->no_scrolling_p = 1;
15073
15074 #if GLYPH_DEBUG
15075 debug_method_add (w, "try_window_reusing_current_matrix 2");
15076 #endif
15077 return 1;
15078 }
15079
15080 return 0;
15081 }
15082
15083
15084 \f
15085 /************************************************************************
15086 Window redisplay reusing current matrix when buffer has changed
15087 ************************************************************************/
15088
15089 static struct glyph_row *find_last_unchanged_at_beg_row (struct window *);
15090 static struct glyph_row *find_first_unchanged_at_end_row (struct window *,
15091 EMACS_INT *, EMACS_INT *);
15092 static struct glyph_row *
15093 find_last_row_displaying_text (struct glyph_matrix *, struct it *,
15094 struct glyph_row *);
15095
15096
15097 /* Return the last row in MATRIX displaying text. If row START is
15098 non-null, start searching with that row. IT gives the dimensions
15099 of the display. Value is null if matrix is empty; otherwise it is
15100 a pointer to the row found. */
15101
15102 static struct glyph_row *
15103 find_last_row_displaying_text (struct glyph_matrix *matrix, struct it *it,
15104 struct glyph_row *start)
15105 {
15106 struct glyph_row *row, *row_found;
15107
15108 /* Set row_found to the last row in IT->w's current matrix
15109 displaying text. The loop looks funny but think of partially
15110 visible lines. */
15111 row_found = NULL;
15112 row = start ? start : MATRIX_FIRST_TEXT_ROW (matrix);
15113 while (MATRIX_ROW_DISPLAYS_TEXT_P (row))
15114 {
15115 xassert (row->enabled_p);
15116 row_found = row;
15117 if (MATRIX_ROW_BOTTOM_Y (row) >= it->last_visible_y)
15118 break;
15119 ++row;
15120 }
15121
15122 return row_found;
15123 }
15124
15125
15126 /* Return the last row in the current matrix of W that is not affected
15127 by changes at the start of current_buffer that occurred since W's
15128 current matrix was built. Value is null if no such row exists.
15129
15130 BEG_UNCHANGED us the number of characters unchanged at the start of
15131 current_buffer. BEG + BEG_UNCHANGED is the buffer position of the
15132 first changed character in current_buffer. Characters at positions <
15133 BEG + BEG_UNCHANGED are at the same buffer positions as they were
15134 when the current matrix was built. */
15135
15136 static struct glyph_row *
15137 find_last_unchanged_at_beg_row (struct window *w)
15138 {
15139 EMACS_INT first_changed_pos = BEG + BEG_UNCHANGED;
15140 struct glyph_row *row;
15141 struct glyph_row *row_found = NULL;
15142 int yb = window_text_bottom_y (w);
15143
15144 /* Find the last row displaying unchanged text. */
15145 for (row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
15146 MATRIX_ROW_DISPLAYS_TEXT_P (row)
15147 && MATRIX_ROW_START_CHARPOS (row) < first_changed_pos;
15148 ++row)
15149 {
15150 if (/* If row ends before first_changed_pos, it is unchanged,
15151 except in some case. */
15152 MATRIX_ROW_END_CHARPOS (row) <= first_changed_pos
15153 /* When row ends in ZV and we write at ZV it is not
15154 unchanged. */
15155 && !row->ends_at_zv_p
15156 /* When first_changed_pos is the end of a continued line,
15157 row is not unchanged because it may be no longer
15158 continued. */
15159 && !(MATRIX_ROW_END_CHARPOS (row) == first_changed_pos
15160 && (row->continued_p
15161 || row->exact_window_width_line_p)))
15162 row_found = row;
15163
15164 /* Stop if last visible row. */
15165 if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
15166 break;
15167 }
15168
15169 return row_found;
15170 }
15171
15172
15173 /* Find the first glyph row in the current matrix of W that is not
15174 affected by changes at the end of current_buffer since the
15175 time W's current matrix was built.
15176
15177 Return in *DELTA the number of chars by which buffer positions in
15178 unchanged text at the end of current_buffer must be adjusted.
15179
15180 Return in *DELTA_BYTES the corresponding number of bytes.
15181
15182 Value is null if no such row exists, i.e. all rows are affected by
15183 changes. */
15184
15185 static struct glyph_row *
15186 find_first_unchanged_at_end_row (struct window *w,
15187 EMACS_INT *delta, EMACS_INT *delta_bytes)
15188 {
15189 struct glyph_row *row;
15190 struct glyph_row *row_found = NULL;
15191
15192 *delta = *delta_bytes = 0;
15193
15194 /* Display must not have been paused, otherwise the current matrix
15195 is not up to date. */
15196 eassert (!NILP (w->window_end_valid));
15197
15198 /* A value of window_end_pos >= END_UNCHANGED means that the window
15199 end is in the range of changed text. If so, there is no
15200 unchanged row at the end of W's current matrix. */
15201 if (XFASTINT (w->window_end_pos) >= END_UNCHANGED)
15202 return NULL;
15203
15204 /* Set row to the last row in W's current matrix displaying text. */
15205 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
15206
15207 /* If matrix is entirely empty, no unchanged row exists. */
15208 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
15209 {
15210 /* The value of row is the last glyph row in the matrix having a
15211 meaningful buffer position in it. The end position of row
15212 corresponds to window_end_pos. This allows us to translate
15213 buffer positions in the current matrix to current buffer
15214 positions for characters not in changed text. */
15215 EMACS_INT Z_old =
15216 MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
15217 EMACS_INT Z_BYTE_old =
15218 MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
15219 EMACS_INT last_unchanged_pos, last_unchanged_pos_old;
15220 struct glyph_row *first_text_row
15221 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
15222
15223 *delta = Z - Z_old;
15224 *delta_bytes = Z_BYTE - Z_BYTE_old;
15225
15226 /* Set last_unchanged_pos to the buffer position of the last
15227 character in the buffer that has not been changed. Z is the
15228 index + 1 of the last character in current_buffer, i.e. by
15229 subtracting END_UNCHANGED we get the index of the last
15230 unchanged character, and we have to add BEG to get its buffer
15231 position. */
15232 last_unchanged_pos = Z - END_UNCHANGED + BEG;
15233 last_unchanged_pos_old = last_unchanged_pos - *delta;
15234
15235 /* Search backward from ROW for a row displaying a line that
15236 starts at a minimum position >= last_unchanged_pos_old. */
15237 for (; row > first_text_row; --row)
15238 {
15239 /* This used to abort, but it can happen.
15240 It is ok to just stop the search instead here. KFS. */
15241 if (!row->enabled_p || !MATRIX_ROW_DISPLAYS_TEXT_P (row))
15242 break;
15243
15244 if (MATRIX_ROW_START_CHARPOS (row) >= last_unchanged_pos_old)
15245 row_found = row;
15246 }
15247 }
15248
15249 eassert (!row_found || MATRIX_ROW_DISPLAYS_TEXT_P (row_found));
15250
15251 return row_found;
15252 }
15253
15254
15255 /* Make sure that glyph rows in the current matrix of window W
15256 reference the same glyph memory as corresponding rows in the
15257 frame's frame matrix. This function is called after scrolling W's
15258 current matrix on a terminal frame in try_window_id and
15259 try_window_reusing_current_matrix. */
15260
15261 static void
15262 sync_frame_with_window_matrix_rows (struct window *w)
15263 {
15264 struct frame *f = XFRAME (w->frame);
15265 struct glyph_row *window_row, *window_row_end, *frame_row;
15266
15267 /* Preconditions: W must be a leaf window and full-width. Its frame
15268 must have a frame matrix. */
15269 xassert (NILP (w->hchild) && NILP (w->vchild));
15270 xassert (WINDOW_FULL_WIDTH_P (w));
15271 xassert (!FRAME_WINDOW_P (f));
15272
15273 /* If W is a full-width window, glyph pointers in W's current matrix
15274 have, by definition, to be the same as glyph pointers in the
15275 corresponding frame matrix. Note that frame matrices have no
15276 marginal areas (see build_frame_matrix). */
15277 window_row = w->current_matrix->rows;
15278 window_row_end = window_row + w->current_matrix->nrows;
15279 frame_row = f->current_matrix->rows + WINDOW_TOP_EDGE_LINE (w);
15280 while (window_row < window_row_end)
15281 {
15282 struct glyph *start = window_row->glyphs[LEFT_MARGIN_AREA];
15283 struct glyph *end = window_row->glyphs[LAST_AREA];
15284
15285 frame_row->glyphs[LEFT_MARGIN_AREA] = start;
15286 frame_row->glyphs[TEXT_AREA] = start;
15287 frame_row->glyphs[RIGHT_MARGIN_AREA] = end;
15288 frame_row->glyphs[LAST_AREA] = end;
15289
15290 /* Disable frame rows whose corresponding window rows have
15291 been disabled in try_window_id. */
15292 if (!window_row->enabled_p)
15293 frame_row->enabled_p = 0;
15294
15295 ++window_row, ++frame_row;
15296 }
15297 }
15298
15299
15300 /* Find the glyph row in window W containing CHARPOS. Consider all
15301 rows between START and END (not inclusive). END null means search
15302 all rows to the end of the display area of W. Value is the row
15303 containing CHARPOS or null. */
15304
15305 struct glyph_row *
15306 row_containing_pos (struct window *w, EMACS_INT charpos,
15307 struct glyph_row *start, struct glyph_row *end, int dy)
15308 {
15309 struct glyph_row *row = start;
15310 struct glyph_row *best_row = NULL;
15311 EMACS_INT mindif = BUF_ZV (XBUFFER (w->buffer)) + 1;
15312 int last_y;
15313
15314 /* If we happen to start on a header-line, skip that. */
15315 if (row->mode_line_p)
15316 ++row;
15317
15318 if ((end && row >= end) || !row->enabled_p)
15319 return NULL;
15320
15321 last_y = window_text_bottom_y (w) - dy;
15322
15323 while (1)
15324 {
15325 /* Give up if we have gone too far. */
15326 if (end && row >= end)
15327 return NULL;
15328 /* This formerly returned if they were equal.
15329 I think that both quantities are of a "last plus one" type;
15330 if so, when they are equal, the row is within the screen. -- rms. */
15331 if (MATRIX_ROW_BOTTOM_Y (row) > last_y)
15332 return NULL;
15333
15334 /* If it is in this row, return this row. */
15335 if (! (MATRIX_ROW_END_CHARPOS (row) < charpos
15336 || (MATRIX_ROW_END_CHARPOS (row) == charpos
15337 /* The end position of a row equals the start
15338 position of the next row. If CHARPOS is there, we
15339 would rather display it in the next line, except
15340 when this line ends in ZV. */
15341 && !row->ends_at_zv_p
15342 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
15343 && charpos >= MATRIX_ROW_START_CHARPOS (row))
15344 {
15345 struct glyph *g;
15346
15347 if (NILP (BVAR (XBUFFER (w->buffer), bidi_display_reordering))
15348 || (!best_row && !row->continued_p))
15349 return row;
15350 /* In bidi-reordered rows, there could be several rows
15351 occluding point, all of them belonging to the same
15352 continued line. We need to find the row which fits
15353 CHARPOS the best. */
15354 for (g = row->glyphs[TEXT_AREA];
15355 g < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
15356 g++)
15357 {
15358 if (!STRINGP (g->object))
15359 {
15360 if (g->charpos > 0 && eabs (g->charpos - charpos) < mindif)
15361 {
15362 mindif = eabs (g->charpos - charpos);
15363 best_row = row;
15364 /* Exact match always wins. */
15365 if (mindif == 0)
15366 return best_row;
15367 }
15368 }
15369 }
15370 }
15371 else if (best_row && !row->continued_p)
15372 return best_row;
15373 ++row;
15374 }
15375 }
15376
15377
15378 /* Try to redisplay window W by reusing its existing display. W's
15379 current matrix must be up to date when this function is called,
15380 i.e. window_end_valid must not be nil.
15381
15382 Value is
15383
15384 1 if display has been updated
15385 0 if otherwise unsuccessful
15386 -1 if redisplay with same window start is known not to succeed
15387
15388 The following steps are performed:
15389
15390 1. Find the last row in the current matrix of W that is not
15391 affected by changes at the start of current_buffer. If no such row
15392 is found, give up.
15393
15394 2. Find the first row in W's current matrix that is not affected by
15395 changes at the end of current_buffer. Maybe there is no such row.
15396
15397 3. Display lines beginning with the row + 1 found in step 1 to the
15398 row found in step 2 or, if step 2 didn't find a row, to the end of
15399 the window.
15400
15401 4. If cursor is not known to appear on the window, give up.
15402
15403 5. If display stopped at the row found in step 2, scroll the
15404 display and current matrix as needed.
15405
15406 6. Maybe display some lines at the end of W, if we must. This can
15407 happen under various circumstances, like a partially visible line
15408 becoming fully visible, or because newly displayed lines are displayed
15409 in smaller font sizes.
15410
15411 7. Update W's window end information. */
15412
15413 static int
15414 try_window_id (struct window *w)
15415 {
15416 struct frame *f = XFRAME (w->frame);
15417 struct glyph_matrix *current_matrix = w->current_matrix;
15418 struct glyph_matrix *desired_matrix = w->desired_matrix;
15419 struct glyph_row *last_unchanged_at_beg_row;
15420 struct glyph_row *first_unchanged_at_end_row;
15421 struct glyph_row *row;
15422 struct glyph_row *bottom_row;
15423 int bottom_vpos;
15424 struct it it;
15425 EMACS_INT delta = 0, delta_bytes = 0, stop_pos;
15426 int dvpos, dy;
15427 struct text_pos start_pos;
15428 struct run run;
15429 int first_unchanged_at_end_vpos = 0;
15430 struct glyph_row *last_text_row, *last_text_row_at_end;
15431 struct text_pos start;
15432 EMACS_INT first_changed_charpos, last_changed_charpos;
15433
15434 #if GLYPH_DEBUG
15435 if (inhibit_try_window_id)
15436 return 0;
15437 #endif
15438
15439 /* This is handy for debugging. */
15440 #if 0
15441 #define GIVE_UP(X) \
15442 do { \
15443 fprintf (stderr, "try_window_id give up %d\n", (X)); \
15444 return 0; \
15445 } while (0)
15446 #else
15447 #define GIVE_UP(X) return 0
15448 #endif
15449
15450 SET_TEXT_POS_FROM_MARKER (start, w->start);
15451
15452 /* Don't use this for mini-windows because these can show
15453 messages and mini-buffers, and we don't handle that here. */
15454 if (MINI_WINDOW_P (w))
15455 GIVE_UP (1);
15456
15457 /* This flag is used to prevent redisplay optimizations. */
15458 if (windows_or_buffers_changed || cursor_type_changed)
15459 GIVE_UP (2);
15460
15461 /* Verify that narrowing has not changed.
15462 Also verify that we were not told to prevent redisplay optimizations.
15463 It would be nice to further
15464 reduce the number of cases where this prevents try_window_id. */
15465 if (current_buffer->clip_changed
15466 || current_buffer->prevent_redisplay_optimizations_p)
15467 GIVE_UP (3);
15468
15469 /* Window must either use window-based redisplay or be full width. */
15470 if (!FRAME_WINDOW_P (f)
15471 && (!FRAME_LINE_INS_DEL_OK (f)
15472 || !WINDOW_FULL_WIDTH_P (w)))
15473 GIVE_UP (4);
15474
15475 /* Give up if point is known NOT to appear in W. */
15476 if (PT < CHARPOS (start))
15477 GIVE_UP (5);
15478
15479 /* Another way to prevent redisplay optimizations. */
15480 if (XFASTINT (w->last_modified) == 0)
15481 GIVE_UP (6);
15482
15483 /* Verify that window is not hscrolled. */
15484 if (XFASTINT (w->hscroll) != 0)
15485 GIVE_UP (7);
15486
15487 /* Verify that display wasn't paused. */
15488 if (NILP (w->window_end_valid))
15489 GIVE_UP (8);
15490
15491 /* Can't use this if highlighting a region because a cursor movement
15492 will do more than just set the cursor. */
15493 if (!NILP (Vtransient_mark_mode)
15494 && !NILP (BVAR (current_buffer, mark_active)))
15495 GIVE_UP (9);
15496
15497 /* Likewise if highlighting trailing whitespace. */
15498 if (!NILP (Vshow_trailing_whitespace))
15499 GIVE_UP (11);
15500
15501 /* Likewise if showing a region. */
15502 if (!NILP (w->region_showing))
15503 GIVE_UP (10);
15504
15505 /* Can't use this if overlay arrow position and/or string have
15506 changed. */
15507 if (overlay_arrows_changed_p ())
15508 GIVE_UP (12);
15509
15510 /* When word-wrap is on, adding a space to the first word of a
15511 wrapped line can change the wrap position, altering the line
15512 above it. It might be worthwhile to handle this more
15513 intelligently, but for now just redisplay from scratch. */
15514 if (!NILP (BVAR (XBUFFER (w->buffer), word_wrap)))
15515 GIVE_UP (21);
15516
15517 /* Under bidi reordering, adding or deleting a character in the
15518 beginning of a paragraph, before the first strong directional
15519 character, can change the base direction of the paragraph (unless
15520 the buffer specifies a fixed paragraph direction), which will
15521 require to redisplay the whole paragraph. It might be worthwhile
15522 to find the paragraph limits and widen the range of redisplayed
15523 lines to that, but for now just give up this optimization and
15524 redisplay from scratch. */
15525 if (!NILP (BVAR (XBUFFER (w->buffer), bidi_display_reordering))
15526 && NILP (BVAR (XBUFFER (w->buffer), bidi_paragraph_direction)))
15527 GIVE_UP (22);
15528
15529 /* Make sure beg_unchanged and end_unchanged are up to date. Do it
15530 only if buffer has really changed. The reason is that the gap is
15531 initially at Z for freshly visited files. The code below would
15532 set end_unchanged to 0 in that case. */
15533 if (MODIFF > SAVE_MODIFF
15534 /* This seems to happen sometimes after saving a buffer. */
15535 || BEG_UNCHANGED + END_UNCHANGED > Z_BYTE)
15536 {
15537 if (GPT - BEG < BEG_UNCHANGED)
15538 BEG_UNCHANGED = GPT - BEG;
15539 if (Z - GPT < END_UNCHANGED)
15540 END_UNCHANGED = Z - GPT;
15541 }
15542
15543 /* The position of the first and last character that has been changed. */
15544 first_changed_charpos = BEG + BEG_UNCHANGED;
15545 last_changed_charpos = Z - END_UNCHANGED;
15546
15547 /* If window starts after a line end, and the last change is in
15548 front of that newline, then changes don't affect the display.
15549 This case happens with stealth-fontification. Note that although
15550 the display is unchanged, glyph positions in the matrix have to
15551 be adjusted, of course. */
15552 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
15553 if (MATRIX_ROW_DISPLAYS_TEXT_P (row)
15554 && ((last_changed_charpos < CHARPOS (start)
15555 && CHARPOS (start) == BEGV)
15556 || (last_changed_charpos < CHARPOS (start) - 1
15557 && FETCH_BYTE (BYTEPOS (start) - 1) == '\n')))
15558 {
15559 EMACS_INT Z_old, Z_delta, Z_BYTE_old, Z_delta_bytes;
15560 struct glyph_row *r0;
15561
15562 /* Compute how many chars/bytes have been added to or removed
15563 from the buffer. */
15564 Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
15565 Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
15566 Z_delta = Z - Z_old;
15567 Z_delta_bytes = Z_BYTE - Z_BYTE_old;
15568
15569 /* Give up if PT is not in the window. Note that it already has
15570 been checked at the start of try_window_id that PT is not in
15571 front of the window start. */
15572 if (PT >= MATRIX_ROW_END_CHARPOS (row) + Z_delta)
15573 GIVE_UP (13);
15574
15575 /* If window start is unchanged, we can reuse the whole matrix
15576 as is, after adjusting glyph positions. No need to compute
15577 the window end again, since its offset from Z hasn't changed. */
15578 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
15579 if (CHARPOS (start) == MATRIX_ROW_START_CHARPOS (r0) + Z_delta
15580 && BYTEPOS (start) == MATRIX_ROW_START_BYTEPOS (r0) + Z_delta_bytes
15581 /* PT must not be in a partially visible line. */
15582 && !(PT >= MATRIX_ROW_START_CHARPOS (row) + Z_delta
15583 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
15584 {
15585 /* Adjust positions in the glyph matrix. */
15586 if (Z_delta || Z_delta_bytes)
15587 {
15588 struct glyph_row *r1
15589 = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
15590 increment_matrix_positions (w->current_matrix,
15591 MATRIX_ROW_VPOS (r0, current_matrix),
15592 MATRIX_ROW_VPOS (r1, current_matrix),
15593 Z_delta, Z_delta_bytes);
15594 }
15595
15596 /* Set the cursor. */
15597 row = row_containing_pos (w, PT, r0, NULL, 0);
15598 if (row)
15599 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
15600 else
15601 abort ();
15602 return 1;
15603 }
15604 }
15605
15606 /* Handle the case that changes are all below what is displayed in
15607 the window, and that PT is in the window. This shortcut cannot
15608 be taken if ZV is visible in the window, and text has been added
15609 there that is visible in the window. */
15610 if (first_changed_charpos >= MATRIX_ROW_END_CHARPOS (row)
15611 /* ZV is not visible in the window, or there are no
15612 changes at ZV, actually. */
15613 && (current_matrix->zv > MATRIX_ROW_END_CHARPOS (row)
15614 || first_changed_charpos == last_changed_charpos))
15615 {
15616 struct glyph_row *r0;
15617
15618 /* Give up if PT is not in the window. Note that it already has
15619 been checked at the start of try_window_id that PT is not in
15620 front of the window start. */
15621 if (PT >= MATRIX_ROW_END_CHARPOS (row))
15622 GIVE_UP (14);
15623
15624 /* If window start is unchanged, we can reuse the whole matrix
15625 as is, without changing glyph positions since no text has
15626 been added/removed in front of the window end. */
15627 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
15628 if (TEXT_POS_EQUAL_P (start, r0->minpos)
15629 /* PT must not be in a partially visible line. */
15630 && !(PT >= MATRIX_ROW_START_CHARPOS (row)
15631 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
15632 {
15633 /* We have to compute the window end anew since text
15634 could have been added/removed after it. */
15635 w->window_end_pos
15636 = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
15637 w->window_end_bytepos
15638 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
15639
15640 /* Set the cursor. */
15641 row = row_containing_pos (w, PT, r0, NULL, 0);
15642 if (row)
15643 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
15644 else
15645 abort ();
15646 return 2;
15647 }
15648 }
15649
15650 /* Give up if window start is in the changed area.
15651
15652 The condition used to read
15653
15654 (BEG_UNCHANGED + END_UNCHANGED != Z - BEG && ...)
15655
15656 but why that was tested escapes me at the moment. */
15657 if (CHARPOS (start) >= first_changed_charpos
15658 && CHARPOS (start) <= last_changed_charpos)
15659 GIVE_UP (15);
15660
15661 /* Check that window start agrees with the start of the first glyph
15662 row in its current matrix. Check this after we know the window
15663 start is not in changed text, otherwise positions would not be
15664 comparable. */
15665 row = MATRIX_FIRST_TEXT_ROW (current_matrix);
15666 if (!TEXT_POS_EQUAL_P (start, row->minpos))
15667 GIVE_UP (16);
15668
15669 /* Give up if the window ends in strings. Overlay strings
15670 at the end are difficult to handle, so don't try. */
15671 row = MATRIX_ROW (current_matrix, XFASTINT (w->window_end_vpos));
15672 if (MATRIX_ROW_START_CHARPOS (row) == MATRIX_ROW_END_CHARPOS (row))
15673 GIVE_UP (20);
15674
15675 /* Compute the position at which we have to start displaying new
15676 lines. Some of the lines at the top of the window might be
15677 reusable because they are not displaying changed text. Find the
15678 last row in W's current matrix not affected by changes at the
15679 start of current_buffer. Value is null if changes start in the
15680 first line of window. */
15681 last_unchanged_at_beg_row = find_last_unchanged_at_beg_row (w);
15682 if (last_unchanged_at_beg_row)
15683 {
15684 /* Avoid starting to display in the moddle of a character, a TAB
15685 for instance. This is easier than to set up the iterator
15686 exactly, and it's not a frequent case, so the additional
15687 effort wouldn't really pay off. */
15688 while ((MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row)
15689 || last_unchanged_at_beg_row->ends_in_newline_from_string_p)
15690 && last_unchanged_at_beg_row > w->current_matrix->rows)
15691 --last_unchanged_at_beg_row;
15692
15693 if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row))
15694 GIVE_UP (17);
15695
15696 if (init_to_row_end (&it, w, last_unchanged_at_beg_row) == 0)
15697 GIVE_UP (18);
15698 start_pos = it.current.pos;
15699
15700 /* Start displaying new lines in the desired matrix at the same
15701 vpos we would use in the current matrix, i.e. below
15702 last_unchanged_at_beg_row. */
15703 it.vpos = 1 + MATRIX_ROW_VPOS (last_unchanged_at_beg_row,
15704 current_matrix);
15705 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
15706 it.current_y = MATRIX_ROW_BOTTOM_Y (last_unchanged_at_beg_row);
15707
15708 xassert (it.hpos == 0 && it.current_x == 0);
15709 }
15710 else
15711 {
15712 /* There are no reusable lines at the start of the window.
15713 Start displaying in the first text line. */
15714 start_display (&it, w, start);
15715 it.vpos = it.first_vpos;
15716 start_pos = it.current.pos;
15717 }
15718
15719 /* Find the first row that is not affected by changes at the end of
15720 the buffer. Value will be null if there is no unchanged row, in
15721 which case we must redisplay to the end of the window. delta
15722 will be set to the value by which buffer positions beginning with
15723 first_unchanged_at_end_row have to be adjusted due to text
15724 changes. */
15725 first_unchanged_at_end_row
15726 = find_first_unchanged_at_end_row (w, &delta, &delta_bytes);
15727 IF_DEBUG (debug_delta = delta);
15728 IF_DEBUG (debug_delta_bytes = delta_bytes);
15729
15730 /* Set stop_pos to the buffer position up to which we will have to
15731 display new lines. If first_unchanged_at_end_row != NULL, this
15732 is the buffer position of the start of the line displayed in that
15733 row. For first_unchanged_at_end_row == NULL, use 0 to indicate
15734 that we don't stop at a buffer position. */
15735 stop_pos = 0;
15736 if (first_unchanged_at_end_row)
15737 {
15738 xassert (last_unchanged_at_beg_row == NULL
15739 || first_unchanged_at_end_row >= last_unchanged_at_beg_row);
15740
15741 /* If this is a continuation line, move forward to the next one
15742 that isn't. Changes in lines above affect this line.
15743 Caution: this may move first_unchanged_at_end_row to a row
15744 not displaying text. */
15745 while (MATRIX_ROW_CONTINUATION_LINE_P (first_unchanged_at_end_row)
15746 && MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
15747 && (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
15748 < it.last_visible_y))
15749 ++first_unchanged_at_end_row;
15750
15751 if (!MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
15752 || (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
15753 >= it.last_visible_y))
15754 first_unchanged_at_end_row = NULL;
15755 else
15756 {
15757 stop_pos = (MATRIX_ROW_START_CHARPOS (first_unchanged_at_end_row)
15758 + delta);
15759 first_unchanged_at_end_vpos
15760 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, current_matrix);
15761 xassert (stop_pos >= Z - END_UNCHANGED);
15762 }
15763 }
15764 else if (last_unchanged_at_beg_row == NULL)
15765 GIVE_UP (19);
15766
15767
15768 #if GLYPH_DEBUG
15769
15770 /* Either there is no unchanged row at the end, or the one we have
15771 now displays text. This is a necessary condition for the window
15772 end pos calculation at the end of this function. */
15773 xassert (first_unchanged_at_end_row == NULL
15774 || MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
15775
15776 debug_last_unchanged_at_beg_vpos
15777 = (last_unchanged_at_beg_row
15778 ? MATRIX_ROW_VPOS (last_unchanged_at_beg_row, current_matrix)
15779 : -1);
15780 debug_first_unchanged_at_end_vpos = first_unchanged_at_end_vpos;
15781
15782 #endif /* GLYPH_DEBUG != 0 */
15783
15784
15785 /* Display new lines. Set last_text_row to the last new line
15786 displayed which has text on it, i.e. might end up as being the
15787 line where the window_end_vpos is. */
15788 w->cursor.vpos = -1;
15789 last_text_row = NULL;
15790 overlay_arrow_seen = 0;
15791 while (it.current_y < it.last_visible_y
15792 && !fonts_changed_p
15793 && (first_unchanged_at_end_row == NULL
15794 || IT_CHARPOS (it) < stop_pos))
15795 {
15796 if (display_line (&it))
15797 last_text_row = it.glyph_row - 1;
15798 }
15799
15800 if (fonts_changed_p)
15801 return -1;
15802
15803
15804 /* Compute differences in buffer positions, y-positions etc. for
15805 lines reused at the bottom of the window. Compute what we can
15806 scroll. */
15807 if (first_unchanged_at_end_row
15808 /* No lines reused because we displayed everything up to the
15809 bottom of the window. */
15810 && it.current_y < it.last_visible_y)
15811 {
15812 dvpos = (it.vpos
15813 - MATRIX_ROW_VPOS (first_unchanged_at_end_row,
15814 current_matrix));
15815 dy = it.current_y - first_unchanged_at_end_row->y;
15816 run.current_y = first_unchanged_at_end_row->y;
15817 run.desired_y = run.current_y + dy;
15818 run.height = it.last_visible_y - max (run.current_y, run.desired_y);
15819 }
15820 else
15821 {
15822 delta = delta_bytes = dvpos = dy
15823 = run.current_y = run.desired_y = run.height = 0;
15824 first_unchanged_at_end_row = NULL;
15825 }
15826 IF_DEBUG (debug_dvpos = dvpos; debug_dy = dy);
15827
15828
15829 /* Find the cursor if not already found. We have to decide whether
15830 PT will appear on this window (it sometimes doesn't, but this is
15831 not a very frequent case.) This decision has to be made before
15832 the current matrix is altered. A value of cursor.vpos < 0 means
15833 that PT is either in one of the lines beginning at
15834 first_unchanged_at_end_row or below the window. Don't care for
15835 lines that might be displayed later at the window end; as
15836 mentioned, this is not a frequent case. */
15837 if (w->cursor.vpos < 0)
15838 {
15839 /* Cursor in unchanged rows at the top? */
15840 if (PT < CHARPOS (start_pos)
15841 && last_unchanged_at_beg_row)
15842 {
15843 row = row_containing_pos (w, PT,
15844 MATRIX_FIRST_TEXT_ROW (w->current_matrix),
15845 last_unchanged_at_beg_row + 1, 0);
15846 if (row)
15847 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
15848 }
15849
15850 /* Start from first_unchanged_at_end_row looking for PT. */
15851 else if (first_unchanged_at_end_row)
15852 {
15853 row = row_containing_pos (w, PT - delta,
15854 first_unchanged_at_end_row, NULL, 0);
15855 if (row)
15856 set_cursor_from_row (w, row, w->current_matrix, delta,
15857 delta_bytes, dy, dvpos);
15858 }
15859
15860 /* Give up if cursor was not found. */
15861 if (w->cursor.vpos < 0)
15862 {
15863 clear_glyph_matrix (w->desired_matrix);
15864 return -1;
15865 }
15866 }
15867
15868 /* Don't let the cursor end in the scroll margins. */
15869 {
15870 int this_scroll_margin, cursor_height;
15871
15872 this_scroll_margin = max (0, scroll_margin);
15873 this_scroll_margin = min (this_scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
15874 this_scroll_margin *= FRAME_LINE_HEIGHT (it.f);
15875 cursor_height = MATRIX_ROW (w->desired_matrix, w->cursor.vpos)->height;
15876
15877 if ((w->cursor.y < this_scroll_margin
15878 && CHARPOS (start) > BEGV)
15879 /* Old redisplay didn't take scroll margin into account at the bottom,
15880 but then global-hl-line-mode doesn't scroll. KFS 2004-06-14 */
15881 || (w->cursor.y + (make_cursor_line_fully_visible_p
15882 ? cursor_height + this_scroll_margin
15883 : 1)) > it.last_visible_y)
15884 {
15885 w->cursor.vpos = -1;
15886 clear_glyph_matrix (w->desired_matrix);
15887 return -1;
15888 }
15889 }
15890
15891 /* Scroll the display. Do it before changing the current matrix so
15892 that xterm.c doesn't get confused about where the cursor glyph is
15893 found. */
15894 if (dy && run.height)
15895 {
15896 update_begin (f);
15897
15898 if (FRAME_WINDOW_P (f))
15899 {
15900 FRAME_RIF (f)->update_window_begin_hook (w);
15901 FRAME_RIF (f)->clear_window_mouse_face (w);
15902 FRAME_RIF (f)->scroll_run_hook (w, &run);
15903 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
15904 }
15905 else
15906 {
15907 /* Terminal frame. In this case, dvpos gives the number of
15908 lines to scroll by; dvpos < 0 means scroll up. */
15909 int from_vpos
15910 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, w->current_matrix);
15911 int from = WINDOW_TOP_EDGE_LINE (w) + from_vpos;
15912 int end = (WINDOW_TOP_EDGE_LINE (w)
15913 + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0)
15914 + window_internal_height (w));
15915
15916 #if defined (HAVE_GPM) || defined (MSDOS)
15917 x_clear_window_mouse_face (w);
15918 #endif
15919 /* Perform the operation on the screen. */
15920 if (dvpos > 0)
15921 {
15922 /* Scroll last_unchanged_at_beg_row to the end of the
15923 window down dvpos lines. */
15924 set_terminal_window (f, end);
15925
15926 /* On dumb terminals delete dvpos lines at the end
15927 before inserting dvpos empty lines. */
15928 if (!FRAME_SCROLL_REGION_OK (f))
15929 ins_del_lines (f, end - dvpos, -dvpos);
15930
15931 /* Insert dvpos empty lines in front of
15932 last_unchanged_at_beg_row. */
15933 ins_del_lines (f, from, dvpos);
15934 }
15935 else if (dvpos < 0)
15936 {
15937 /* Scroll up last_unchanged_at_beg_vpos to the end of
15938 the window to last_unchanged_at_beg_vpos - |dvpos|. */
15939 set_terminal_window (f, end);
15940
15941 /* Delete dvpos lines in front of
15942 last_unchanged_at_beg_vpos. ins_del_lines will set
15943 the cursor to the given vpos and emit |dvpos| delete
15944 line sequences. */
15945 ins_del_lines (f, from + dvpos, dvpos);
15946
15947 /* On a dumb terminal insert dvpos empty lines at the
15948 end. */
15949 if (!FRAME_SCROLL_REGION_OK (f))
15950 ins_del_lines (f, end + dvpos, -dvpos);
15951 }
15952
15953 set_terminal_window (f, 0);
15954 }
15955
15956 update_end (f);
15957 }
15958
15959 /* Shift reused rows of the current matrix to the right position.
15960 BOTTOM_ROW is the last + 1 row in the current matrix reserved for
15961 text. */
15962 bottom_row = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
15963 bottom_vpos = MATRIX_ROW_VPOS (bottom_row, current_matrix);
15964 if (dvpos < 0)
15965 {
15966 rotate_matrix (current_matrix, first_unchanged_at_end_vpos + dvpos,
15967 bottom_vpos, dvpos);
15968 enable_glyph_matrix_rows (current_matrix, bottom_vpos + dvpos,
15969 bottom_vpos, 0);
15970 }
15971 else if (dvpos > 0)
15972 {
15973 rotate_matrix (current_matrix, first_unchanged_at_end_vpos,
15974 bottom_vpos, dvpos);
15975 enable_glyph_matrix_rows (current_matrix, first_unchanged_at_end_vpos,
15976 first_unchanged_at_end_vpos + dvpos, 0);
15977 }
15978
15979 /* For frame-based redisplay, make sure that current frame and window
15980 matrix are in sync with respect to glyph memory. */
15981 if (!FRAME_WINDOW_P (f))
15982 sync_frame_with_window_matrix_rows (w);
15983
15984 /* Adjust buffer positions in reused rows. */
15985 if (delta || delta_bytes)
15986 increment_matrix_positions (current_matrix,
15987 first_unchanged_at_end_vpos + dvpos,
15988 bottom_vpos, delta, delta_bytes);
15989
15990 /* Adjust Y positions. */
15991 if (dy)
15992 shift_glyph_matrix (w, current_matrix,
15993 first_unchanged_at_end_vpos + dvpos,
15994 bottom_vpos, dy);
15995
15996 if (first_unchanged_at_end_row)
15997 {
15998 first_unchanged_at_end_row += dvpos;
15999 if (first_unchanged_at_end_row->y >= it.last_visible_y
16000 || !MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row))
16001 first_unchanged_at_end_row = NULL;
16002 }
16003
16004 /* If scrolling up, there may be some lines to display at the end of
16005 the window. */
16006 last_text_row_at_end = NULL;
16007 if (dy < 0)
16008 {
16009 /* Scrolling up can leave for example a partially visible line
16010 at the end of the window to be redisplayed. */
16011 /* Set last_row to the glyph row in the current matrix where the
16012 window end line is found. It has been moved up or down in
16013 the matrix by dvpos. */
16014 int last_vpos = XFASTINT (w->window_end_vpos) + dvpos;
16015 struct glyph_row *last_row = MATRIX_ROW (current_matrix, last_vpos);
16016
16017 /* If last_row is the window end line, it should display text. */
16018 xassert (last_row->displays_text_p);
16019
16020 /* If window end line was partially visible before, begin
16021 displaying at that line. Otherwise begin displaying with the
16022 line following it. */
16023 if (MATRIX_ROW_BOTTOM_Y (last_row) - dy >= it.last_visible_y)
16024 {
16025 init_to_row_start (&it, w, last_row);
16026 it.vpos = last_vpos;
16027 it.current_y = last_row->y;
16028 }
16029 else
16030 {
16031 init_to_row_end (&it, w, last_row);
16032 it.vpos = 1 + last_vpos;
16033 it.current_y = MATRIX_ROW_BOTTOM_Y (last_row);
16034 ++last_row;
16035 }
16036
16037 /* We may start in a continuation line. If so, we have to
16038 get the right continuation_lines_width and current_x. */
16039 it.continuation_lines_width = last_row->continuation_lines_width;
16040 it.hpos = it.current_x = 0;
16041
16042 /* Display the rest of the lines at the window end. */
16043 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
16044 while (it.current_y < it.last_visible_y
16045 && !fonts_changed_p)
16046 {
16047 /* Is it always sure that the display agrees with lines in
16048 the current matrix? I don't think so, so we mark rows
16049 displayed invalid in the current matrix by setting their
16050 enabled_p flag to zero. */
16051 MATRIX_ROW (w->current_matrix, it.vpos)->enabled_p = 0;
16052 if (display_line (&it))
16053 last_text_row_at_end = it.glyph_row - 1;
16054 }
16055 }
16056
16057 /* Update window_end_pos and window_end_vpos. */
16058 if (first_unchanged_at_end_row
16059 && !last_text_row_at_end)
16060 {
16061 /* Window end line if one of the preserved rows from the current
16062 matrix. Set row to the last row displaying text in current
16063 matrix starting at first_unchanged_at_end_row, after
16064 scrolling. */
16065 xassert (first_unchanged_at_end_row->displays_text_p);
16066 row = find_last_row_displaying_text (w->current_matrix, &it,
16067 first_unchanged_at_end_row);
16068 xassert (row && MATRIX_ROW_DISPLAYS_TEXT_P (row));
16069
16070 w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
16071 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
16072 w->window_end_vpos
16073 = make_number (MATRIX_ROW_VPOS (row, w->current_matrix));
16074 xassert (w->window_end_bytepos >= 0);
16075 IF_DEBUG (debug_method_add (w, "A"));
16076 }
16077 else if (last_text_row_at_end)
16078 {
16079 w->window_end_pos
16080 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row_at_end));
16081 w->window_end_bytepos
16082 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row_at_end);
16083 w->window_end_vpos
16084 = make_number (MATRIX_ROW_VPOS (last_text_row_at_end, desired_matrix));
16085 xassert (w->window_end_bytepos >= 0);
16086 IF_DEBUG (debug_method_add (w, "B"));
16087 }
16088 else if (last_text_row)
16089 {
16090 /* We have displayed either to the end of the window or at the
16091 end of the window, i.e. the last row with text is to be found
16092 in the desired matrix. */
16093 w->window_end_pos
16094 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
16095 w->window_end_bytepos
16096 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
16097 w->window_end_vpos
16098 = make_number (MATRIX_ROW_VPOS (last_text_row, desired_matrix));
16099 xassert (w->window_end_bytepos >= 0);
16100 }
16101 else if (first_unchanged_at_end_row == NULL
16102 && last_text_row == NULL
16103 && last_text_row_at_end == NULL)
16104 {
16105 /* Displayed to end of window, but no line containing text was
16106 displayed. Lines were deleted at the end of the window. */
16107 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
16108 int vpos = XFASTINT (w->window_end_vpos);
16109 struct glyph_row *current_row = current_matrix->rows + vpos;
16110 struct glyph_row *desired_row = desired_matrix->rows + vpos;
16111
16112 for (row = NULL;
16113 row == NULL && vpos >= first_vpos;
16114 --vpos, --current_row, --desired_row)
16115 {
16116 if (desired_row->enabled_p)
16117 {
16118 if (desired_row->displays_text_p)
16119 row = desired_row;
16120 }
16121 else if (current_row->displays_text_p)
16122 row = current_row;
16123 }
16124
16125 xassert (row != NULL);
16126 w->window_end_vpos = make_number (vpos + 1);
16127 w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
16128 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
16129 xassert (w->window_end_bytepos >= 0);
16130 IF_DEBUG (debug_method_add (w, "C"));
16131 }
16132 else
16133 abort ();
16134
16135 IF_DEBUG (debug_end_pos = XFASTINT (w->window_end_pos);
16136 debug_end_vpos = XFASTINT (w->window_end_vpos));
16137
16138 /* Record that display has not been completed. */
16139 w->window_end_valid = Qnil;
16140 w->desired_matrix->no_scrolling_p = 1;
16141 return 3;
16142
16143 #undef GIVE_UP
16144 }
16145
16146
16147 \f
16148 /***********************************************************************
16149 More debugging support
16150 ***********************************************************************/
16151
16152 #if GLYPH_DEBUG
16153
16154 void dump_glyph_row (struct glyph_row *, int, int);
16155 void dump_glyph_matrix (struct glyph_matrix *, int);
16156 void dump_glyph (struct glyph_row *, struct glyph *, int);
16157
16158
16159 /* Dump the contents of glyph matrix MATRIX on stderr.
16160
16161 GLYPHS 0 means don't show glyph contents.
16162 GLYPHS 1 means show glyphs in short form
16163 GLYPHS > 1 means show glyphs in long form. */
16164
16165 void
16166 dump_glyph_matrix (matrix, glyphs)
16167 struct glyph_matrix *matrix;
16168 int glyphs;
16169 {
16170 int i;
16171 for (i = 0; i < matrix->nrows; ++i)
16172 dump_glyph_row (MATRIX_ROW (matrix, i), i, glyphs);
16173 }
16174
16175
16176 /* Dump contents of glyph GLYPH to stderr. ROW and AREA are
16177 the glyph row and area where the glyph comes from. */
16178
16179 void
16180 dump_glyph (row, glyph, area)
16181 struct glyph_row *row;
16182 struct glyph *glyph;
16183 int area;
16184 {
16185 if (glyph->type == CHAR_GLYPH)
16186 {
16187 fprintf (stderr,
16188 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
16189 glyph - row->glyphs[TEXT_AREA],
16190 'C',
16191 glyph->charpos,
16192 (BUFFERP (glyph->object)
16193 ? 'B'
16194 : (STRINGP (glyph->object)
16195 ? 'S'
16196 : '-')),
16197 glyph->pixel_width,
16198 glyph->u.ch,
16199 (glyph->u.ch < 0x80 && glyph->u.ch >= ' '
16200 ? glyph->u.ch
16201 : '.'),
16202 glyph->face_id,
16203 glyph->left_box_line_p,
16204 glyph->right_box_line_p);
16205 }
16206 else if (glyph->type == STRETCH_GLYPH)
16207 {
16208 fprintf (stderr,
16209 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
16210 glyph - row->glyphs[TEXT_AREA],
16211 'S',
16212 glyph->charpos,
16213 (BUFFERP (glyph->object)
16214 ? 'B'
16215 : (STRINGP (glyph->object)
16216 ? 'S'
16217 : '-')),
16218 glyph->pixel_width,
16219 0,
16220 '.',
16221 glyph->face_id,
16222 glyph->left_box_line_p,
16223 glyph->right_box_line_p);
16224 }
16225 else if (glyph->type == IMAGE_GLYPH)
16226 {
16227 fprintf (stderr,
16228 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
16229 glyph - row->glyphs[TEXT_AREA],
16230 'I',
16231 glyph->charpos,
16232 (BUFFERP (glyph->object)
16233 ? 'B'
16234 : (STRINGP (glyph->object)
16235 ? 'S'
16236 : '-')),
16237 glyph->pixel_width,
16238 glyph->u.img_id,
16239 '.',
16240 glyph->face_id,
16241 glyph->left_box_line_p,
16242 glyph->right_box_line_p);
16243 }
16244 else if (glyph->type == COMPOSITE_GLYPH)
16245 {
16246 fprintf (stderr,
16247 " %5d %4c %6d %c %3d 0x%05x",
16248 glyph - row->glyphs[TEXT_AREA],
16249 '+',
16250 glyph->charpos,
16251 (BUFFERP (glyph->object)
16252 ? 'B'
16253 : (STRINGP (glyph->object)
16254 ? 'S'
16255 : '-')),
16256 glyph->pixel_width,
16257 glyph->u.cmp.id);
16258 if (glyph->u.cmp.automatic)
16259 fprintf (stderr,
16260 "[%d-%d]",
16261 glyph->slice.cmp.from, glyph->slice.cmp.to);
16262 fprintf (stderr, " . %4d %1.1d%1.1d\n",
16263 glyph->face_id,
16264 glyph->left_box_line_p,
16265 glyph->right_box_line_p);
16266 }
16267 }
16268
16269
16270 /* Dump the contents of glyph row at VPOS in MATRIX to stderr.
16271 GLYPHS 0 means don't show glyph contents.
16272 GLYPHS 1 means show glyphs in short form
16273 GLYPHS > 1 means show glyphs in long form. */
16274
16275 void
16276 dump_glyph_row (row, vpos, glyphs)
16277 struct glyph_row *row;
16278 int vpos, glyphs;
16279 {
16280 if (glyphs != 1)
16281 {
16282 fprintf (stderr, "Row Start End Used oE><\\CTZFesm X Y W H V A P\n");
16283 fprintf (stderr, "======================================================================\n");
16284
16285 fprintf (stderr, "%3d %5d %5d %4d %1.1d%1.1d%1.1d%1.1d\
16286 %1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d %4d %4d %4d %4d %4d %4d %4d\n",
16287 vpos,
16288 MATRIX_ROW_START_CHARPOS (row),
16289 MATRIX_ROW_END_CHARPOS (row),
16290 row->used[TEXT_AREA],
16291 row->contains_overlapping_glyphs_p,
16292 row->enabled_p,
16293 row->truncated_on_left_p,
16294 row->truncated_on_right_p,
16295 row->continued_p,
16296 MATRIX_ROW_CONTINUATION_LINE_P (row),
16297 row->displays_text_p,
16298 row->ends_at_zv_p,
16299 row->fill_line_p,
16300 row->ends_in_middle_of_char_p,
16301 row->starts_in_middle_of_char_p,
16302 row->mouse_face_p,
16303 row->x,
16304 row->y,
16305 row->pixel_width,
16306 row->height,
16307 row->visible_height,
16308 row->ascent,
16309 row->phys_ascent);
16310 fprintf (stderr, "%9d %5d\t%5d\n", row->start.overlay_string_index,
16311 row->end.overlay_string_index,
16312 row->continuation_lines_width);
16313 fprintf (stderr, "%9d %5d\n",
16314 CHARPOS (row->start.string_pos),
16315 CHARPOS (row->end.string_pos));
16316 fprintf (stderr, "%9d %5d\n", row->start.dpvec_index,
16317 row->end.dpvec_index);
16318 }
16319
16320 if (glyphs > 1)
16321 {
16322 int area;
16323
16324 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
16325 {
16326 struct glyph *glyph = row->glyphs[area];
16327 struct glyph *glyph_end = glyph + row->used[area];
16328
16329 /* Glyph for a line end in text. */
16330 if (area == TEXT_AREA && glyph == glyph_end && glyph->charpos > 0)
16331 ++glyph_end;
16332
16333 if (glyph < glyph_end)
16334 fprintf (stderr, " Glyph Type Pos O W Code C Face LR\n");
16335
16336 for (; glyph < glyph_end; ++glyph)
16337 dump_glyph (row, glyph, area);
16338 }
16339 }
16340 else if (glyphs == 1)
16341 {
16342 int area;
16343
16344 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
16345 {
16346 char *s = (char *) alloca (row->used[area] + 1);
16347 int i;
16348
16349 for (i = 0; i < row->used[area]; ++i)
16350 {
16351 struct glyph *glyph = row->glyphs[area] + i;
16352 if (glyph->type == CHAR_GLYPH
16353 && glyph->u.ch < 0x80
16354 && glyph->u.ch >= ' ')
16355 s[i] = glyph->u.ch;
16356 else
16357 s[i] = '.';
16358 }
16359
16360 s[i] = '\0';
16361 fprintf (stderr, "%3d: (%d) '%s'\n", vpos, row->enabled_p, s);
16362 }
16363 }
16364 }
16365
16366
16367 DEFUN ("dump-glyph-matrix", Fdump_glyph_matrix,
16368 Sdump_glyph_matrix, 0, 1, "p",
16369 doc: /* Dump the current matrix of the selected window to stderr.
16370 Shows contents of glyph row structures. With non-nil
16371 parameter GLYPHS, dump glyphs as well. If GLYPHS is 1 show
16372 glyphs in short form, otherwise show glyphs in long form. */)
16373 (Lisp_Object glyphs)
16374 {
16375 struct window *w = XWINDOW (selected_window);
16376 struct buffer *buffer = XBUFFER (w->buffer);
16377
16378 fprintf (stderr, "PT = %d, BEGV = %d. ZV = %d\n",
16379 BUF_PT (buffer), BUF_BEGV (buffer), BUF_ZV (buffer));
16380 fprintf (stderr, "Cursor x = %d, y = %d, hpos = %d, vpos = %d\n",
16381 w->cursor.x, w->cursor.y, w->cursor.hpos, w->cursor.vpos);
16382 fprintf (stderr, "=============================================\n");
16383 dump_glyph_matrix (w->current_matrix,
16384 NILP (glyphs) ? 0 : XINT (glyphs));
16385 return Qnil;
16386 }
16387
16388
16389 DEFUN ("dump-frame-glyph-matrix", Fdump_frame_glyph_matrix,
16390 Sdump_frame_glyph_matrix, 0, 0, "", doc: /* */)
16391 (void)
16392 {
16393 struct frame *f = XFRAME (selected_frame);
16394 dump_glyph_matrix (f->current_matrix, 1);
16395 return Qnil;
16396 }
16397
16398
16399 DEFUN ("dump-glyph-row", Fdump_glyph_row, Sdump_glyph_row, 1, 2, "",
16400 doc: /* Dump glyph row ROW to stderr.
16401 GLYPH 0 means don't dump glyphs.
16402 GLYPH 1 means dump glyphs in short form.
16403 GLYPH > 1 or omitted means dump glyphs in long form. */)
16404 (Lisp_Object row, Lisp_Object glyphs)
16405 {
16406 struct glyph_matrix *matrix;
16407 int vpos;
16408
16409 CHECK_NUMBER (row);
16410 matrix = XWINDOW (selected_window)->current_matrix;
16411 vpos = XINT (row);
16412 if (vpos >= 0 && vpos < matrix->nrows)
16413 dump_glyph_row (MATRIX_ROW (matrix, vpos),
16414 vpos,
16415 INTEGERP (glyphs) ? XINT (glyphs) : 2);
16416 return Qnil;
16417 }
16418
16419
16420 DEFUN ("dump-tool-bar-row", Fdump_tool_bar_row, Sdump_tool_bar_row, 1, 2, "",
16421 doc: /* Dump glyph row ROW of the tool-bar of the current frame to stderr.
16422 GLYPH 0 means don't dump glyphs.
16423 GLYPH 1 means dump glyphs in short form.
16424 GLYPH > 1 or omitted means dump glyphs in long form. */)
16425 (Lisp_Object row, Lisp_Object glyphs)
16426 {
16427 struct frame *sf = SELECTED_FRAME ();
16428 struct glyph_matrix *m = XWINDOW (sf->tool_bar_window)->current_matrix;
16429 int vpos;
16430
16431 CHECK_NUMBER (row);
16432 vpos = XINT (row);
16433 if (vpos >= 0 && vpos < m->nrows)
16434 dump_glyph_row (MATRIX_ROW (m, vpos), vpos,
16435 INTEGERP (glyphs) ? XINT (glyphs) : 2);
16436 return Qnil;
16437 }
16438
16439
16440 DEFUN ("trace-redisplay", Ftrace_redisplay, Strace_redisplay, 0, 1, "P",
16441 doc: /* Toggle tracing of redisplay.
16442 With ARG, turn tracing on if and only if ARG is positive. */)
16443 (Lisp_Object arg)
16444 {
16445 if (NILP (arg))
16446 trace_redisplay_p = !trace_redisplay_p;
16447 else
16448 {
16449 arg = Fprefix_numeric_value (arg);
16450 trace_redisplay_p = XINT (arg) > 0;
16451 }
16452
16453 return Qnil;
16454 }
16455
16456
16457 DEFUN ("trace-to-stderr", Ftrace_to_stderr, Strace_to_stderr, 1, MANY, "",
16458 doc: /* Like `format', but print result to stderr.
16459 usage: (trace-to-stderr STRING &rest OBJECTS) */)
16460 (size_t nargs, Lisp_Object *args)
16461 {
16462 Lisp_Object s = Fformat (nargs, args);
16463 fprintf (stderr, "%s", SDATA (s));
16464 return Qnil;
16465 }
16466
16467 #endif /* GLYPH_DEBUG */
16468
16469
16470 \f
16471 /***********************************************************************
16472 Building Desired Matrix Rows
16473 ***********************************************************************/
16474
16475 /* Return a temporary glyph row holding the glyphs of an overlay arrow.
16476 Used for non-window-redisplay windows, and for windows w/o left fringe. */
16477
16478 static struct glyph_row *
16479 get_overlay_arrow_glyph_row (struct window *w, Lisp_Object overlay_arrow_string)
16480 {
16481 struct frame *f = XFRAME (WINDOW_FRAME (w));
16482 struct buffer *buffer = XBUFFER (w->buffer);
16483 struct buffer *old = current_buffer;
16484 const unsigned char *arrow_string = SDATA (overlay_arrow_string);
16485 int arrow_len = SCHARS (overlay_arrow_string);
16486 const unsigned char *arrow_end = arrow_string + arrow_len;
16487 const unsigned char *p;
16488 struct it it;
16489 int multibyte_p;
16490 int n_glyphs_before;
16491
16492 set_buffer_temp (buffer);
16493 init_iterator (&it, w, -1, -1, &scratch_glyph_row, DEFAULT_FACE_ID);
16494 it.glyph_row->used[TEXT_AREA] = 0;
16495 SET_TEXT_POS (it.position, 0, 0);
16496
16497 multibyte_p = !NILP (BVAR (buffer, enable_multibyte_characters));
16498 p = arrow_string;
16499 while (p < arrow_end)
16500 {
16501 Lisp_Object face, ilisp;
16502
16503 /* Get the next character. */
16504 if (multibyte_p)
16505 it.c = it.char_to_display = string_char_and_length (p, &it.len);
16506 else
16507 {
16508 it.c = it.char_to_display = *p, it.len = 1;
16509 if (! ASCII_CHAR_P (it.c))
16510 it.char_to_display = BYTE8_TO_CHAR (it.c);
16511 }
16512 p += it.len;
16513
16514 /* Get its face. */
16515 ilisp = make_number (p - arrow_string);
16516 face = Fget_text_property (ilisp, Qface, overlay_arrow_string);
16517 it.face_id = compute_char_face (f, it.char_to_display, face);
16518
16519 /* Compute its width, get its glyphs. */
16520 n_glyphs_before = it.glyph_row->used[TEXT_AREA];
16521 SET_TEXT_POS (it.position, -1, -1);
16522 PRODUCE_GLYPHS (&it);
16523
16524 /* If this character doesn't fit any more in the line, we have
16525 to remove some glyphs. */
16526 if (it.current_x > it.last_visible_x)
16527 {
16528 it.glyph_row->used[TEXT_AREA] = n_glyphs_before;
16529 break;
16530 }
16531 }
16532
16533 set_buffer_temp (old);
16534 return it.glyph_row;
16535 }
16536
16537
16538 /* Insert truncation glyphs at the start of IT->glyph_row. Truncation
16539 glyphs are only inserted for terminal frames since we can't really
16540 win with truncation glyphs when partially visible glyphs are
16541 involved. Which glyphs to insert is determined by
16542 produce_special_glyphs. */
16543
16544 static void
16545 insert_left_trunc_glyphs (struct it *it)
16546 {
16547 struct it truncate_it;
16548 struct glyph *from, *end, *to, *toend;
16549
16550 xassert (!FRAME_WINDOW_P (it->f));
16551
16552 /* Get the truncation glyphs. */
16553 truncate_it = *it;
16554 truncate_it.current_x = 0;
16555 truncate_it.face_id = DEFAULT_FACE_ID;
16556 truncate_it.glyph_row = &scratch_glyph_row;
16557 truncate_it.glyph_row->used[TEXT_AREA] = 0;
16558 CHARPOS (truncate_it.position) = BYTEPOS (truncate_it.position) = -1;
16559 truncate_it.object = make_number (0);
16560 produce_special_glyphs (&truncate_it, IT_TRUNCATION);
16561
16562 /* Overwrite glyphs from IT with truncation glyphs. */
16563 if (!it->glyph_row->reversed_p)
16564 {
16565 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
16566 end = from + truncate_it.glyph_row->used[TEXT_AREA];
16567 to = it->glyph_row->glyphs[TEXT_AREA];
16568 toend = to + it->glyph_row->used[TEXT_AREA];
16569
16570 while (from < end)
16571 *to++ = *from++;
16572
16573 /* There may be padding glyphs left over. Overwrite them too. */
16574 while (to < toend && CHAR_GLYPH_PADDING_P (*to))
16575 {
16576 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
16577 while (from < end)
16578 *to++ = *from++;
16579 }
16580
16581 if (to > toend)
16582 it->glyph_row->used[TEXT_AREA] = to - it->glyph_row->glyphs[TEXT_AREA];
16583 }
16584 else
16585 {
16586 /* In R2L rows, overwrite the last (rightmost) glyphs, and do
16587 that back to front. */
16588 end = truncate_it.glyph_row->glyphs[TEXT_AREA];
16589 from = end + truncate_it.glyph_row->used[TEXT_AREA] - 1;
16590 toend = it->glyph_row->glyphs[TEXT_AREA];
16591 to = toend + it->glyph_row->used[TEXT_AREA] - 1;
16592
16593 while (from >= end && to >= toend)
16594 *to-- = *from--;
16595 while (to >= toend && CHAR_GLYPH_PADDING_P (*to))
16596 {
16597 from =
16598 truncate_it.glyph_row->glyphs[TEXT_AREA]
16599 + truncate_it.glyph_row->used[TEXT_AREA] - 1;
16600 while (from >= end && to >= toend)
16601 *to-- = *from--;
16602 }
16603 if (from >= end)
16604 {
16605 /* Need to free some room before prepending additional
16606 glyphs. */
16607 int move_by = from - end + 1;
16608 struct glyph *g0 = it->glyph_row->glyphs[TEXT_AREA];
16609 struct glyph *g = g0 + it->glyph_row->used[TEXT_AREA] - 1;
16610
16611 for ( ; g >= g0; g--)
16612 g[move_by] = *g;
16613 while (from >= end)
16614 *to-- = *from--;
16615 it->glyph_row->used[TEXT_AREA] += move_by;
16616 }
16617 }
16618 }
16619
16620
16621 /* Compute the pixel height and width of IT->glyph_row.
16622
16623 Most of the time, ascent and height of a display line will be equal
16624 to the max_ascent and max_height values of the display iterator
16625 structure. This is not the case if
16626
16627 1. We hit ZV without displaying anything. In this case, max_ascent
16628 and max_height will be zero.
16629
16630 2. We have some glyphs that don't contribute to the line height.
16631 (The glyph row flag contributes_to_line_height_p is for future
16632 pixmap extensions).
16633
16634 The first case is easily covered by using default values because in
16635 these cases, the line height does not really matter, except that it
16636 must not be zero. */
16637
16638 static void
16639 compute_line_metrics (struct it *it)
16640 {
16641 struct glyph_row *row = it->glyph_row;
16642
16643 if (FRAME_WINDOW_P (it->f))
16644 {
16645 int i, min_y, max_y;
16646
16647 /* The line may consist of one space only, that was added to
16648 place the cursor on it. If so, the row's height hasn't been
16649 computed yet. */
16650 if (row->height == 0)
16651 {
16652 if (it->max_ascent + it->max_descent == 0)
16653 it->max_descent = it->max_phys_descent = FRAME_LINE_HEIGHT (it->f);
16654 row->ascent = it->max_ascent;
16655 row->height = it->max_ascent + it->max_descent;
16656 row->phys_ascent = it->max_phys_ascent;
16657 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
16658 row->extra_line_spacing = it->max_extra_line_spacing;
16659 }
16660
16661 /* Compute the width of this line. */
16662 row->pixel_width = row->x;
16663 for (i = 0; i < row->used[TEXT_AREA]; ++i)
16664 row->pixel_width += row->glyphs[TEXT_AREA][i].pixel_width;
16665
16666 xassert (row->pixel_width >= 0);
16667 xassert (row->ascent >= 0 && row->height > 0);
16668
16669 row->overlapping_p = (MATRIX_ROW_OVERLAPS_SUCC_P (row)
16670 || MATRIX_ROW_OVERLAPS_PRED_P (row));
16671
16672 /* If first line's physical ascent is larger than its logical
16673 ascent, use the physical ascent, and make the row taller.
16674 This makes accented characters fully visible. */
16675 if (row == MATRIX_FIRST_TEXT_ROW (it->w->desired_matrix)
16676 && row->phys_ascent > row->ascent)
16677 {
16678 row->height += row->phys_ascent - row->ascent;
16679 row->ascent = row->phys_ascent;
16680 }
16681
16682 /* Compute how much of the line is visible. */
16683 row->visible_height = row->height;
16684
16685 min_y = WINDOW_HEADER_LINE_HEIGHT (it->w);
16686 max_y = WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w);
16687
16688 if (row->y < min_y)
16689 row->visible_height -= min_y - row->y;
16690 if (row->y + row->height > max_y)
16691 row->visible_height -= row->y + row->height - max_y;
16692 }
16693 else
16694 {
16695 row->pixel_width = row->used[TEXT_AREA];
16696 if (row->continued_p)
16697 row->pixel_width -= it->continuation_pixel_width;
16698 else if (row->truncated_on_right_p)
16699 row->pixel_width -= it->truncation_pixel_width;
16700 row->ascent = row->phys_ascent = 0;
16701 row->height = row->phys_height = row->visible_height = 1;
16702 row->extra_line_spacing = 0;
16703 }
16704
16705 /* Compute a hash code for this row. */
16706 {
16707 int area, i;
16708 row->hash = 0;
16709 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
16710 for (i = 0; i < row->used[area]; ++i)
16711 row->hash = ((((row->hash << 4) + (row->hash >> 24)) & 0x0fffffff)
16712 + row->glyphs[area][i].u.val
16713 + row->glyphs[area][i].face_id
16714 + row->glyphs[area][i].padding_p
16715 + (row->glyphs[area][i].type << 2));
16716 }
16717
16718 it->max_ascent = it->max_descent = 0;
16719 it->max_phys_ascent = it->max_phys_descent = 0;
16720 }
16721
16722
16723 /* Append one space to the glyph row of iterator IT if doing a
16724 window-based redisplay. The space has the same face as
16725 IT->face_id. Value is non-zero if a space was added.
16726
16727 This function is called to make sure that there is always one glyph
16728 at the end of a glyph row that the cursor can be set on under
16729 window-systems. (If there weren't such a glyph we would not know
16730 how wide and tall a box cursor should be displayed).
16731
16732 At the same time this space let's a nicely handle clearing to the
16733 end of the line if the row ends in italic text. */
16734
16735 static int
16736 append_space_for_newline (struct it *it, int default_face_p)
16737 {
16738 if (FRAME_WINDOW_P (it->f))
16739 {
16740 int n = it->glyph_row->used[TEXT_AREA];
16741
16742 if (it->glyph_row->glyphs[TEXT_AREA] + n
16743 < it->glyph_row->glyphs[1 + TEXT_AREA])
16744 {
16745 /* Save some values that must not be changed.
16746 Must save IT->c and IT->len because otherwise
16747 ITERATOR_AT_END_P wouldn't work anymore after
16748 append_space_for_newline has been called. */
16749 enum display_element_type saved_what = it->what;
16750 int saved_c = it->c, saved_len = it->len;
16751 int saved_char_to_display = it->char_to_display;
16752 int saved_x = it->current_x;
16753 int saved_face_id = it->face_id;
16754 struct text_pos saved_pos;
16755 Lisp_Object saved_object;
16756 struct face *face;
16757
16758 saved_object = it->object;
16759 saved_pos = it->position;
16760
16761 it->what = IT_CHARACTER;
16762 memset (&it->position, 0, sizeof it->position);
16763 it->object = make_number (0);
16764 it->c = it->char_to_display = ' ';
16765 it->len = 1;
16766
16767 if (default_face_p)
16768 it->face_id = DEFAULT_FACE_ID;
16769 else if (it->face_before_selective_p)
16770 it->face_id = it->saved_face_id;
16771 face = FACE_FROM_ID (it->f, it->face_id);
16772 it->face_id = FACE_FOR_CHAR (it->f, face, 0, -1, Qnil);
16773
16774 PRODUCE_GLYPHS (it);
16775
16776 it->override_ascent = -1;
16777 it->constrain_row_ascent_descent_p = 0;
16778 it->current_x = saved_x;
16779 it->object = saved_object;
16780 it->position = saved_pos;
16781 it->what = saved_what;
16782 it->face_id = saved_face_id;
16783 it->len = saved_len;
16784 it->c = saved_c;
16785 it->char_to_display = saved_char_to_display;
16786 return 1;
16787 }
16788 }
16789
16790 return 0;
16791 }
16792
16793
16794 /* Extend the face of the last glyph in the text area of IT->glyph_row
16795 to the end of the display line. Called from display_line. If the
16796 glyph row is empty, add a space glyph to it so that we know the
16797 face to draw. Set the glyph row flag fill_line_p. If the glyph
16798 row is R2L, prepend a stretch glyph to cover the empty space to the
16799 left of the leftmost glyph. */
16800
16801 static void
16802 extend_face_to_end_of_line (struct it *it)
16803 {
16804 struct face *face;
16805 struct frame *f = it->f;
16806
16807 /* If line is already filled, do nothing. Non window-system frames
16808 get a grace of one more ``pixel'' because their characters are
16809 1-``pixel'' wide, so they hit the equality too early. This grace
16810 is needed only for R2L rows that are not continued, to produce
16811 one extra blank where we could display the cursor. */
16812 if (it->current_x >= it->last_visible_x
16813 + (!FRAME_WINDOW_P (f)
16814 && it->glyph_row->reversed_p
16815 && !it->glyph_row->continued_p))
16816 return;
16817
16818 /* Face extension extends the background and box of IT->face_id
16819 to the end of the line. If the background equals the background
16820 of the frame, we don't have to do anything. */
16821 if (it->face_before_selective_p)
16822 face = FACE_FROM_ID (f, it->saved_face_id);
16823 else
16824 face = FACE_FROM_ID (f, it->face_id);
16825
16826 if (FRAME_WINDOW_P (f)
16827 && it->glyph_row->displays_text_p
16828 && face->box == FACE_NO_BOX
16829 && face->background == FRAME_BACKGROUND_PIXEL (f)
16830 && !face->stipple
16831 && !it->glyph_row->reversed_p)
16832 return;
16833
16834 /* Set the glyph row flag indicating that the face of the last glyph
16835 in the text area has to be drawn to the end of the text area. */
16836 it->glyph_row->fill_line_p = 1;
16837
16838 /* If current character of IT is not ASCII, make sure we have the
16839 ASCII face. This will be automatically undone the next time
16840 get_next_display_element returns a multibyte character. Note
16841 that the character will always be single byte in unibyte
16842 text. */
16843 if (!ASCII_CHAR_P (it->c))
16844 {
16845 it->face_id = FACE_FOR_CHAR (f, face, 0, -1, Qnil);
16846 }
16847
16848 if (FRAME_WINDOW_P (f))
16849 {
16850 /* If the row is empty, add a space with the current face of IT,
16851 so that we know which face to draw. */
16852 if (it->glyph_row->used[TEXT_AREA] == 0)
16853 {
16854 it->glyph_row->glyphs[TEXT_AREA][0] = space_glyph;
16855 it->glyph_row->glyphs[TEXT_AREA][0].face_id = it->face_id;
16856 it->glyph_row->used[TEXT_AREA] = 1;
16857 }
16858 #ifdef HAVE_WINDOW_SYSTEM
16859 if (it->glyph_row->reversed_p)
16860 {
16861 /* Prepend a stretch glyph to the row, such that the
16862 rightmost glyph will be drawn flushed all the way to the
16863 right margin of the window. The stretch glyph that will
16864 occupy the empty space, if any, to the left of the
16865 glyphs. */
16866 struct font *font = face->font ? face->font : FRAME_FONT (f);
16867 struct glyph *row_start = it->glyph_row->glyphs[TEXT_AREA];
16868 struct glyph *row_end = row_start + it->glyph_row->used[TEXT_AREA];
16869 struct glyph *g;
16870 int row_width, stretch_ascent, stretch_width;
16871 struct text_pos saved_pos;
16872 int saved_face_id, saved_avoid_cursor;
16873
16874 for (row_width = 0, g = row_start; g < row_end; g++)
16875 row_width += g->pixel_width;
16876 stretch_width = window_box_width (it->w, TEXT_AREA) - row_width;
16877 if (stretch_width > 0)
16878 {
16879 stretch_ascent =
16880 (((it->ascent + it->descent)
16881 * FONT_BASE (font)) / FONT_HEIGHT (font));
16882 saved_pos = it->position;
16883 memset (&it->position, 0, sizeof it->position);
16884 saved_avoid_cursor = it->avoid_cursor_p;
16885 it->avoid_cursor_p = 1;
16886 saved_face_id = it->face_id;
16887 /* The last row's stretch glyph should get the default
16888 face, to avoid painting the rest of the window with
16889 the region face, if the region ends at ZV. */
16890 if (it->glyph_row->ends_at_zv_p)
16891 it->face_id = DEFAULT_FACE_ID;
16892 else
16893 it->face_id = face->id;
16894 append_stretch_glyph (it, make_number (0), stretch_width,
16895 it->ascent + it->descent, stretch_ascent);
16896 it->position = saved_pos;
16897 it->avoid_cursor_p = saved_avoid_cursor;
16898 it->face_id = saved_face_id;
16899 }
16900 }
16901 #endif /* HAVE_WINDOW_SYSTEM */
16902 }
16903 else
16904 {
16905 /* Save some values that must not be changed. */
16906 int saved_x = it->current_x;
16907 struct text_pos saved_pos;
16908 Lisp_Object saved_object;
16909 enum display_element_type saved_what = it->what;
16910 int saved_face_id = it->face_id;
16911
16912 saved_object = it->object;
16913 saved_pos = it->position;
16914
16915 it->what = IT_CHARACTER;
16916 memset (&it->position, 0, sizeof it->position);
16917 it->object = make_number (0);
16918 it->c = it->char_to_display = ' ';
16919 it->len = 1;
16920 /* The last row's blank glyphs should get the default face, to
16921 avoid painting the rest of the window with the region face,
16922 if the region ends at ZV. */
16923 if (it->glyph_row->ends_at_zv_p)
16924 it->face_id = DEFAULT_FACE_ID;
16925 else
16926 it->face_id = face->id;
16927
16928 PRODUCE_GLYPHS (it);
16929
16930 while (it->current_x <= it->last_visible_x)
16931 PRODUCE_GLYPHS (it);
16932
16933 /* Don't count these blanks really. It would let us insert a left
16934 truncation glyph below and make us set the cursor on them, maybe. */
16935 it->current_x = saved_x;
16936 it->object = saved_object;
16937 it->position = saved_pos;
16938 it->what = saved_what;
16939 it->face_id = saved_face_id;
16940 }
16941 }
16942
16943
16944 /* Value is non-zero if text starting at CHARPOS in current_buffer is
16945 trailing whitespace. */
16946
16947 static int
16948 trailing_whitespace_p (EMACS_INT charpos)
16949 {
16950 EMACS_INT bytepos = CHAR_TO_BYTE (charpos);
16951 int c = 0;
16952
16953 while (bytepos < ZV_BYTE
16954 && (c = FETCH_CHAR (bytepos),
16955 c == ' ' || c == '\t'))
16956 ++bytepos;
16957
16958 if (bytepos >= ZV_BYTE || c == '\n' || c == '\r')
16959 {
16960 if (bytepos != PT_BYTE)
16961 return 1;
16962 }
16963 return 0;
16964 }
16965
16966
16967 /* Highlight trailing whitespace, if any, in ROW. */
16968
16969 void
16970 highlight_trailing_whitespace (struct frame *f, struct glyph_row *row)
16971 {
16972 int used = row->used[TEXT_AREA];
16973
16974 if (used)
16975 {
16976 struct glyph *start = row->glyphs[TEXT_AREA];
16977 struct glyph *glyph = start + used - 1;
16978
16979 if (row->reversed_p)
16980 {
16981 /* Right-to-left rows need to be processed in the opposite
16982 direction, so swap the edge pointers. */
16983 glyph = start;
16984 start = row->glyphs[TEXT_AREA] + used - 1;
16985 }
16986
16987 /* Skip over glyphs inserted to display the cursor at the
16988 end of a line, for extending the face of the last glyph
16989 to the end of the line on terminals, and for truncation
16990 and continuation glyphs. */
16991 if (!row->reversed_p)
16992 {
16993 while (glyph >= start
16994 && glyph->type == CHAR_GLYPH
16995 && INTEGERP (glyph->object))
16996 --glyph;
16997 }
16998 else
16999 {
17000 while (glyph <= start
17001 && glyph->type == CHAR_GLYPH
17002 && INTEGERP (glyph->object))
17003 ++glyph;
17004 }
17005
17006 /* If last glyph is a space or stretch, and it's trailing
17007 whitespace, set the face of all trailing whitespace glyphs in
17008 IT->glyph_row to `trailing-whitespace'. */
17009 if ((row->reversed_p ? glyph <= start : glyph >= start)
17010 && BUFFERP (glyph->object)
17011 && (glyph->type == STRETCH_GLYPH
17012 || (glyph->type == CHAR_GLYPH
17013 && glyph->u.ch == ' '))
17014 && trailing_whitespace_p (glyph->charpos))
17015 {
17016 int face_id = lookup_named_face (f, Qtrailing_whitespace, 0);
17017 if (face_id < 0)
17018 return;
17019
17020 if (!row->reversed_p)
17021 {
17022 while (glyph >= start
17023 && BUFFERP (glyph->object)
17024 && (glyph->type == STRETCH_GLYPH
17025 || (glyph->type == CHAR_GLYPH
17026 && glyph->u.ch == ' ')))
17027 (glyph--)->face_id = face_id;
17028 }
17029 else
17030 {
17031 while (glyph <= start
17032 && BUFFERP (glyph->object)
17033 && (glyph->type == STRETCH_GLYPH
17034 || (glyph->type == CHAR_GLYPH
17035 && glyph->u.ch == ' ')))
17036 (glyph++)->face_id = face_id;
17037 }
17038 }
17039 }
17040 }
17041
17042
17043 /* Value is non-zero if glyph row ROW should be
17044 used to hold the cursor. */
17045
17046 static int
17047 cursor_row_p (struct glyph_row *row)
17048 {
17049 int result = 1;
17050
17051 if (PT == CHARPOS (row->end.pos))
17052 {
17053 /* Suppose the row ends on a string.
17054 Unless the row is continued, that means it ends on a newline
17055 in the string. If it's anything other than a display string
17056 (e.g. a before-string from an overlay), we don't want the
17057 cursor there. (This heuristic seems to give the optimal
17058 behavior for the various types of multi-line strings.) */
17059 if (CHARPOS (row->end.string_pos) >= 0)
17060 {
17061 if (row->continued_p)
17062 result = 1;
17063 else
17064 {
17065 /* Check for `display' property. */
17066 struct glyph *beg = row->glyphs[TEXT_AREA];
17067 struct glyph *end = beg + row->used[TEXT_AREA] - 1;
17068 struct glyph *glyph;
17069
17070 result = 0;
17071 for (glyph = end; glyph >= beg; --glyph)
17072 if (STRINGP (glyph->object))
17073 {
17074 Lisp_Object prop
17075 = Fget_char_property (make_number (PT),
17076 Qdisplay, Qnil);
17077 result =
17078 (!NILP (prop)
17079 && display_prop_string_p (prop, glyph->object));
17080 break;
17081 }
17082 }
17083 }
17084 else if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
17085 {
17086 /* If the row ends in middle of a real character,
17087 and the line is continued, we want the cursor here.
17088 That's because CHARPOS (ROW->end.pos) would equal
17089 PT if PT is before the character. */
17090 if (!row->ends_in_ellipsis_p)
17091 result = row->continued_p;
17092 else
17093 /* If the row ends in an ellipsis, then
17094 CHARPOS (ROW->end.pos) will equal point after the
17095 invisible text. We want that position to be displayed
17096 after the ellipsis. */
17097 result = 0;
17098 }
17099 /* If the row ends at ZV, display the cursor at the end of that
17100 row instead of at the start of the row below. */
17101 else if (row->ends_at_zv_p)
17102 result = 1;
17103 else
17104 result = 0;
17105 }
17106
17107 return result;
17108 }
17109
17110 \f
17111
17112 /* Push the display property PROP so that it will be rendered at the
17113 current position in IT. Return 1 if PROP was successfully pushed,
17114 0 otherwise. */
17115
17116 static int
17117 push_display_prop (struct it *it, Lisp_Object prop)
17118 {
17119 push_it (it);
17120
17121 if (STRINGP (prop))
17122 {
17123 if (SCHARS (prop) == 0)
17124 {
17125 pop_it (it);
17126 return 0;
17127 }
17128
17129 it->string = prop;
17130 it->multibyte_p = STRING_MULTIBYTE (it->string);
17131 it->current.overlay_string_index = -1;
17132 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
17133 it->end_charpos = it->string_nchars = SCHARS (it->string);
17134 it->method = GET_FROM_STRING;
17135 it->stop_charpos = 0;
17136 }
17137 else if (CONSP (prop) && EQ (XCAR (prop), Qspace))
17138 {
17139 it->method = GET_FROM_STRETCH;
17140 it->object = prop;
17141 }
17142 #ifdef HAVE_WINDOW_SYSTEM
17143 else if (IMAGEP (prop))
17144 {
17145 it->what = IT_IMAGE;
17146 it->image_id = lookup_image (it->f, prop);
17147 it->method = GET_FROM_IMAGE;
17148 }
17149 #endif /* HAVE_WINDOW_SYSTEM */
17150 else
17151 {
17152 pop_it (it); /* bogus display property, give up */
17153 return 0;
17154 }
17155
17156 return 1;
17157 }
17158
17159 /* Return the character-property PROP at the current position in IT. */
17160
17161 static Lisp_Object
17162 get_it_property (struct it *it, Lisp_Object prop)
17163 {
17164 Lisp_Object position;
17165
17166 if (STRINGP (it->object))
17167 position = make_number (IT_STRING_CHARPOS (*it));
17168 else if (BUFFERP (it->object))
17169 position = make_number (IT_CHARPOS (*it));
17170 else
17171 return Qnil;
17172
17173 return Fget_char_property (position, prop, it->object);
17174 }
17175
17176 /* See if there's a line- or wrap-prefix, and if so, push it on IT. */
17177
17178 static void
17179 handle_line_prefix (struct it *it)
17180 {
17181 Lisp_Object prefix;
17182 if (it->continuation_lines_width > 0)
17183 {
17184 prefix = get_it_property (it, Qwrap_prefix);
17185 if (NILP (prefix))
17186 prefix = Vwrap_prefix;
17187 }
17188 else
17189 {
17190 prefix = get_it_property (it, Qline_prefix);
17191 if (NILP (prefix))
17192 prefix = Vline_prefix;
17193 }
17194 if (! NILP (prefix) && push_display_prop (it, prefix))
17195 {
17196 /* If the prefix is wider than the window, and we try to wrap
17197 it, it would acquire its own wrap prefix, and so on till the
17198 iterator stack overflows. So, don't wrap the prefix. */
17199 it->line_wrap = TRUNCATE;
17200 it->avoid_cursor_p = 1;
17201 }
17202 }
17203
17204 \f
17205
17206 /* Remove N glyphs at the start of a reversed IT->glyph_row. Called
17207 only for R2L lines from display_line, when it decides that too many
17208 glyphs were produced by PRODUCE_GLYPHS, and the line needs to be
17209 continued. */
17210 static void
17211 unproduce_glyphs (struct it *it, int n)
17212 {
17213 struct glyph *glyph, *end;
17214
17215 xassert (it->glyph_row);
17216 xassert (it->glyph_row->reversed_p);
17217 xassert (it->area == TEXT_AREA);
17218 xassert (n <= it->glyph_row->used[TEXT_AREA]);
17219
17220 if (n > it->glyph_row->used[TEXT_AREA])
17221 n = it->glyph_row->used[TEXT_AREA];
17222 glyph = it->glyph_row->glyphs[TEXT_AREA] + n;
17223 end = it->glyph_row->glyphs[TEXT_AREA] + it->glyph_row->used[TEXT_AREA];
17224 for ( ; glyph < end; glyph++)
17225 glyph[-n] = *glyph;
17226 }
17227
17228 /* Find the positions in a bidi-reordered ROW to serve as ROW->minpos
17229 and ROW->maxpos. */
17230 static void
17231 find_row_edges (struct it *it, struct glyph_row *row,
17232 EMACS_INT min_pos, EMACS_INT min_bpos,
17233 EMACS_INT max_pos, EMACS_INT max_bpos)
17234 {
17235 /* FIXME: Revisit this when glyph ``spilling'' in continuation
17236 lines' rows is implemented for bidi-reordered rows. */
17237
17238 /* ROW->minpos is the value of min_pos, the minimal buffer position
17239 we have in ROW. */
17240 if (min_pos <= ZV)
17241 SET_TEXT_POS (row->minpos, min_pos, min_bpos);
17242 else
17243 /* We didn't find _any_ valid buffer positions in any of the
17244 glyphs, so we must trust the iterator's computed positions. */
17245 row->minpos = row->start.pos;
17246 if (max_pos <= 0)
17247 {
17248 max_pos = CHARPOS (it->current.pos);
17249 max_bpos = BYTEPOS (it->current.pos);
17250 }
17251
17252 /* Here are the various use-cases for ending the row, and the
17253 corresponding values for ROW->maxpos:
17254
17255 Line ends in a newline from buffer eol_pos + 1
17256 Line is continued from buffer max_pos + 1
17257 Line is truncated on right it->current.pos
17258 Line ends in a newline from string max_pos
17259 Line is continued from string max_pos
17260 Line is continued from display vector max_pos
17261 Line is entirely from a string min_pos == max_pos
17262 Line is entirely from a display vector min_pos == max_pos
17263 Line that ends at ZV ZV
17264
17265 If you discover other use-cases, please add them here as
17266 appropriate. */
17267 if (row->ends_at_zv_p)
17268 row->maxpos = it->current.pos;
17269 else if (row->used[TEXT_AREA])
17270 {
17271 if (row->ends_in_newline_from_string_p)
17272 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
17273 else if (CHARPOS (it->eol_pos) > 0)
17274 SET_TEXT_POS (row->maxpos,
17275 CHARPOS (it->eol_pos) + 1, BYTEPOS (it->eol_pos) + 1);
17276 else if (row->continued_p)
17277 {
17278 /* If max_pos is different from IT's current position, it
17279 means IT->method does not belong to the display element
17280 at max_pos. However, it also means that the display
17281 element at max_pos was displayed in its entirety on this
17282 line, which is equivalent to saying that the next line
17283 starts at the next buffer position. */
17284 if (IT_CHARPOS (*it) == max_pos && it->method != GET_FROM_BUFFER)
17285 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
17286 else
17287 {
17288 INC_BOTH (max_pos, max_bpos);
17289 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
17290 }
17291 }
17292 else if (row->truncated_on_right_p)
17293 /* display_line already called reseat_at_next_visible_line_start,
17294 which puts the iterator at the beginning of the next line, in
17295 the logical order. */
17296 row->maxpos = it->current.pos;
17297 else if (max_pos == min_pos && it->method != GET_FROM_BUFFER)
17298 /* A line that is entirely from a string/image/stretch... */
17299 row->maxpos = row->minpos;
17300 else
17301 abort ();
17302 }
17303 else
17304 row->maxpos = it->current.pos;
17305 }
17306
17307 /* Construct the glyph row IT->glyph_row in the desired matrix of
17308 IT->w from text at the current position of IT. See dispextern.h
17309 for an overview of struct it. Value is non-zero if
17310 IT->glyph_row displays text, as opposed to a line displaying ZV
17311 only. */
17312
17313 static int
17314 display_line (struct it *it)
17315 {
17316 struct glyph_row *row = it->glyph_row;
17317 Lisp_Object overlay_arrow_string;
17318 struct it wrap_it;
17319 int may_wrap = 0, wrap_x IF_LINT (= 0);
17320 int wrap_row_used = -1;
17321 int wrap_row_ascent IF_LINT (= 0), wrap_row_height IF_LINT (= 0);
17322 int wrap_row_phys_ascent IF_LINT (= 0), wrap_row_phys_height IF_LINT (= 0);
17323 int wrap_row_extra_line_spacing IF_LINT (= 0);
17324 EMACS_INT wrap_row_min_pos IF_LINT (= 0), wrap_row_min_bpos IF_LINT (= 0);
17325 EMACS_INT wrap_row_max_pos IF_LINT (= 0), wrap_row_max_bpos IF_LINT (= 0);
17326 int cvpos;
17327 EMACS_INT min_pos = ZV + 1, max_pos = 0;
17328 EMACS_INT min_bpos IF_LINT (= 0), max_bpos IF_LINT (= 0);
17329
17330 /* We always start displaying at hpos zero even if hscrolled. */
17331 xassert (it->hpos == 0 && it->current_x == 0);
17332
17333 if (MATRIX_ROW_VPOS (row, it->w->desired_matrix)
17334 >= it->w->desired_matrix->nrows)
17335 {
17336 it->w->nrows_scale_factor++;
17337 fonts_changed_p = 1;
17338 return 0;
17339 }
17340
17341 /* Is IT->w showing the region? */
17342 it->w->region_showing = it->region_beg_charpos > 0 ? Qt : Qnil;
17343
17344 /* Clear the result glyph row and enable it. */
17345 prepare_desired_row (row);
17346
17347 row->y = it->current_y;
17348 row->start = it->start;
17349 row->continuation_lines_width = it->continuation_lines_width;
17350 row->displays_text_p = 1;
17351 row->starts_in_middle_of_char_p = it->starts_in_middle_of_char_p;
17352 it->starts_in_middle_of_char_p = 0;
17353
17354 /* Arrange the overlays nicely for our purposes. Usually, we call
17355 display_line on only one line at a time, in which case this
17356 can't really hurt too much, or we call it on lines which appear
17357 one after another in the buffer, in which case all calls to
17358 recenter_overlay_lists but the first will be pretty cheap. */
17359 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
17360
17361 /* Move over display elements that are not visible because we are
17362 hscrolled. This may stop at an x-position < IT->first_visible_x
17363 if the first glyph is partially visible or if we hit a line end. */
17364 if (it->current_x < it->first_visible_x)
17365 {
17366 this_line_min_pos = row->start.pos;
17367 move_it_in_display_line_to (it, ZV, it->first_visible_x,
17368 MOVE_TO_POS | MOVE_TO_X);
17369 /* Record the smallest positions seen while we moved over
17370 display elements that are not visible. This is needed by
17371 redisplay_internal for optimizing the case where the cursor
17372 stays inside the same line. The rest of this function only
17373 considers positions that are actually displayed, so
17374 RECORD_MAX_MIN_POS will not otherwise record positions that
17375 are hscrolled to the left of the left edge of the window. */
17376 min_pos = CHARPOS (this_line_min_pos);
17377 min_bpos = BYTEPOS (this_line_min_pos);
17378 }
17379 else
17380 {
17381 /* We only do this when not calling `move_it_in_display_line_to'
17382 above, because move_it_in_display_line_to calls
17383 handle_line_prefix itself. */
17384 handle_line_prefix (it);
17385 }
17386
17387 /* Get the initial row height. This is either the height of the
17388 text hscrolled, if there is any, or zero. */
17389 row->ascent = it->max_ascent;
17390 row->height = it->max_ascent + it->max_descent;
17391 row->phys_ascent = it->max_phys_ascent;
17392 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
17393 row->extra_line_spacing = it->max_extra_line_spacing;
17394
17395 /* Utility macro to record max and min buffer positions seen until now. */
17396 #define RECORD_MAX_MIN_POS(IT) \
17397 do \
17398 { \
17399 if (IT_CHARPOS (*(IT)) < min_pos) \
17400 { \
17401 min_pos = IT_CHARPOS (*(IT)); \
17402 min_bpos = IT_BYTEPOS (*(IT)); \
17403 } \
17404 if (IT_CHARPOS (*(IT)) > max_pos) \
17405 { \
17406 max_pos = IT_CHARPOS (*(IT)); \
17407 max_bpos = IT_BYTEPOS (*(IT)); \
17408 } \
17409 } \
17410 while (0)
17411
17412 /* Loop generating characters. The loop is left with IT on the next
17413 character to display. */
17414 while (1)
17415 {
17416 int n_glyphs_before, hpos_before, x_before;
17417 int x, nglyphs;
17418 int ascent = 0, descent = 0, phys_ascent = 0, phys_descent = 0;
17419
17420 /* Retrieve the next thing to display. Value is zero if end of
17421 buffer reached. */
17422 if (!get_next_display_element (it))
17423 {
17424 /* Maybe add a space at the end of this line that is used to
17425 display the cursor there under X. Set the charpos of the
17426 first glyph of blank lines not corresponding to any text
17427 to -1. */
17428 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
17429 row->exact_window_width_line_p = 1;
17430 else if ((append_space_for_newline (it, 1) && row->used[TEXT_AREA] == 1)
17431 || row->used[TEXT_AREA] == 0)
17432 {
17433 row->glyphs[TEXT_AREA]->charpos = -1;
17434 row->displays_text_p = 0;
17435
17436 if (!NILP (BVAR (XBUFFER (it->w->buffer), indicate_empty_lines))
17437 && (!MINI_WINDOW_P (it->w)
17438 || (minibuf_level && EQ (it->window, minibuf_window))))
17439 row->indicate_empty_line_p = 1;
17440 }
17441
17442 it->continuation_lines_width = 0;
17443 row->ends_at_zv_p = 1;
17444 /* A row that displays right-to-left text must always have
17445 its last face extended all the way to the end of line,
17446 even if this row ends in ZV, because we still write to
17447 the screen left to right. */
17448 if (row->reversed_p)
17449 extend_face_to_end_of_line (it);
17450 break;
17451 }
17452
17453 /* Now, get the metrics of what we want to display. This also
17454 generates glyphs in `row' (which is IT->glyph_row). */
17455 n_glyphs_before = row->used[TEXT_AREA];
17456 x = it->current_x;
17457
17458 /* Remember the line height so far in case the next element doesn't
17459 fit on the line. */
17460 if (it->line_wrap != TRUNCATE)
17461 {
17462 ascent = it->max_ascent;
17463 descent = it->max_descent;
17464 phys_ascent = it->max_phys_ascent;
17465 phys_descent = it->max_phys_descent;
17466
17467 if (it->line_wrap == WORD_WRAP && it->area == TEXT_AREA)
17468 {
17469 if (IT_DISPLAYING_WHITESPACE (it))
17470 may_wrap = 1;
17471 else if (may_wrap)
17472 {
17473 wrap_it = *it;
17474 wrap_x = x;
17475 wrap_row_used = row->used[TEXT_AREA];
17476 wrap_row_ascent = row->ascent;
17477 wrap_row_height = row->height;
17478 wrap_row_phys_ascent = row->phys_ascent;
17479 wrap_row_phys_height = row->phys_height;
17480 wrap_row_extra_line_spacing = row->extra_line_spacing;
17481 wrap_row_min_pos = min_pos;
17482 wrap_row_min_bpos = min_bpos;
17483 wrap_row_max_pos = max_pos;
17484 wrap_row_max_bpos = max_bpos;
17485 may_wrap = 0;
17486 }
17487 }
17488 }
17489
17490 PRODUCE_GLYPHS (it);
17491
17492 /* If this display element was in marginal areas, continue with
17493 the next one. */
17494 if (it->area != TEXT_AREA)
17495 {
17496 row->ascent = max (row->ascent, it->max_ascent);
17497 row->height = max (row->height, it->max_ascent + it->max_descent);
17498 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
17499 row->phys_height = max (row->phys_height,
17500 it->max_phys_ascent + it->max_phys_descent);
17501 row->extra_line_spacing = max (row->extra_line_spacing,
17502 it->max_extra_line_spacing);
17503 set_iterator_to_next (it, 1);
17504 continue;
17505 }
17506
17507 /* Does the display element fit on the line? If we truncate
17508 lines, we should draw past the right edge of the window. If
17509 we don't truncate, we want to stop so that we can display the
17510 continuation glyph before the right margin. If lines are
17511 continued, there are two possible strategies for characters
17512 resulting in more than 1 glyph (e.g. tabs): Display as many
17513 glyphs as possible in this line and leave the rest for the
17514 continuation line, or display the whole element in the next
17515 line. Original redisplay did the former, so we do it also. */
17516 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
17517 hpos_before = it->hpos;
17518 x_before = x;
17519
17520 if (/* Not a newline. */
17521 nglyphs > 0
17522 /* Glyphs produced fit entirely in the line. */
17523 && it->current_x < it->last_visible_x)
17524 {
17525 it->hpos += nglyphs;
17526 row->ascent = max (row->ascent, it->max_ascent);
17527 row->height = max (row->height, it->max_ascent + it->max_descent);
17528 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
17529 row->phys_height = max (row->phys_height,
17530 it->max_phys_ascent + it->max_phys_descent);
17531 row->extra_line_spacing = max (row->extra_line_spacing,
17532 it->max_extra_line_spacing);
17533 if (it->current_x - it->pixel_width < it->first_visible_x)
17534 row->x = x - it->first_visible_x;
17535 /* Record the maximum and minimum buffer positions seen so
17536 far in glyphs that will be displayed by this row. */
17537 if (it->bidi_p)
17538 RECORD_MAX_MIN_POS (it);
17539 }
17540 else
17541 {
17542 int i, new_x;
17543 struct glyph *glyph;
17544
17545 for (i = 0; i < nglyphs; ++i, x = new_x)
17546 {
17547 glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
17548 new_x = x + glyph->pixel_width;
17549
17550 if (/* Lines are continued. */
17551 it->line_wrap != TRUNCATE
17552 && (/* Glyph doesn't fit on the line. */
17553 new_x > it->last_visible_x
17554 /* Or it fits exactly on a window system frame. */
17555 || (new_x == it->last_visible_x
17556 && FRAME_WINDOW_P (it->f))))
17557 {
17558 /* End of a continued line. */
17559
17560 if (it->hpos == 0
17561 || (new_x == it->last_visible_x
17562 && FRAME_WINDOW_P (it->f)))
17563 {
17564 /* Current glyph is the only one on the line or
17565 fits exactly on the line. We must continue
17566 the line because we can't draw the cursor
17567 after the glyph. */
17568 row->continued_p = 1;
17569 it->current_x = new_x;
17570 it->continuation_lines_width += new_x;
17571 ++it->hpos;
17572 /* Record the maximum and minimum buffer
17573 positions seen so far in glyphs that will be
17574 displayed by this row. */
17575 if (it->bidi_p)
17576 RECORD_MAX_MIN_POS (it);
17577 if (i == nglyphs - 1)
17578 {
17579 /* If line-wrap is on, check if a previous
17580 wrap point was found. */
17581 if (wrap_row_used > 0
17582 /* Even if there is a previous wrap
17583 point, continue the line here as
17584 usual, if (i) the previous character
17585 was a space or tab AND (ii) the
17586 current character is not. */
17587 && (!may_wrap
17588 || IT_DISPLAYING_WHITESPACE (it)))
17589 goto back_to_wrap;
17590
17591 set_iterator_to_next (it, 1);
17592 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
17593 {
17594 if (!get_next_display_element (it))
17595 {
17596 row->exact_window_width_line_p = 1;
17597 it->continuation_lines_width = 0;
17598 row->continued_p = 0;
17599 row->ends_at_zv_p = 1;
17600 }
17601 else if (ITERATOR_AT_END_OF_LINE_P (it))
17602 {
17603 row->continued_p = 0;
17604 row->exact_window_width_line_p = 1;
17605 }
17606 }
17607 }
17608 }
17609 else if (CHAR_GLYPH_PADDING_P (*glyph)
17610 && !FRAME_WINDOW_P (it->f))
17611 {
17612 /* A padding glyph that doesn't fit on this line.
17613 This means the whole character doesn't fit
17614 on the line. */
17615 if (row->reversed_p)
17616 unproduce_glyphs (it, row->used[TEXT_AREA]
17617 - n_glyphs_before);
17618 row->used[TEXT_AREA] = n_glyphs_before;
17619
17620 /* Fill the rest of the row with continuation
17621 glyphs like in 20.x. */
17622 while (row->glyphs[TEXT_AREA] + row->used[TEXT_AREA]
17623 < row->glyphs[1 + TEXT_AREA])
17624 produce_special_glyphs (it, IT_CONTINUATION);
17625
17626 row->continued_p = 1;
17627 it->current_x = x_before;
17628 it->continuation_lines_width += x_before;
17629
17630 /* Restore the height to what it was before the
17631 element not fitting on the line. */
17632 it->max_ascent = ascent;
17633 it->max_descent = descent;
17634 it->max_phys_ascent = phys_ascent;
17635 it->max_phys_descent = phys_descent;
17636 }
17637 else if (wrap_row_used > 0)
17638 {
17639 back_to_wrap:
17640 if (row->reversed_p)
17641 unproduce_glyphs (it,
17642 row->used[TEXT_AREA] - wrap_row_used);
17643 *it = wrap_it;
17644 it->continuation_lines_width += wrap_x;
17645 row->used[TEXT_AREA] = wrap_row_used;
17646 row->ascent = wrap_row_ascent;
17647 row->height = wrap_row_height;
17648 row->phys_ascent = wrap_row_phys_ascent;
17649 row->phys_height = wrap_row_phys_height;
17650 row->extra_line_spacing = wrap_row_extra_line_spacing;
17651 min_pos = wrap_row_min_pos;
17652 min_bpos = wrap_row_min_bpos;
17653 max_pos = wrap_row_max_pos;
17654 max_bpos = wrap_row_max_bpos;
17655 row->continued_p = 1;
17656 row->ends_at_zv_p = 0;
17657 row->exact_window_width_line_p = 0;
17658 it->continuation_lines_width += x;
17659
17660 /* Make sure that a non-default face is extended
17661 up to the right margin of the window. */
17662 extend_face_to_end_of_line (it);
17663 }
17664 else if (it->c == '\t' && FRAME_WINDOW_P (it->f))
17665 {
17666 /* A TAB that extends past the right edge of the
17667 window. This produces a single glyph on
17668 window system frames. We leave the glyph in
17669 this row and let it fill the row, but don't
17670 consume the TAB. */
17671 it->continuation_lines_width += it->last_visible_x;
17672 row->ends_in_middle_of_char_p = 1;
17673 row->continued_p = 1;
17674 glyph->pixel_width = it->last_visible_x - x;
17675 it->starts_in_middle_of_char_p = 1;
17676 }
17677 else
17678 {
17679 /* Something other than a TAB that draws past
17680 the right edge of the window. Restore
17681 positions to values before the element. */
17682 if (row->reversed_p)
17683 unproduce_glyphs (it, row->used[TEXT_AREA]
17684 - (n_glyphs_before + i));
17685 row->used[TEXT_AREA] = n_glyphs_before + i;
17686
17687 /* Display continuation glyphs. */
17688 if (!FRAME_WINDOW_P (it->f))
17689 produce_special_glyphs (it, IT_CONTINUATION);
17690 row->continued_p = 1;
17691
17692 it->current_x = x_before;
17693 it->continuation_lines_width += x;
17694 extend_face_to_end_of_line (it);
17695
17696 if (nglyphs > 1 && i > 0)
17697 {
17698 row->ends_in_middle_of_char_p = 1;
17699 it->starts_in_middle_of_char_p = 1;
17700 }
17701
17702 /* Restore the height to what it was before the
17703 element not fitting on the line. */
17704 it->max_ascent = ascent;
17705 it->max_descent = descent;
17706 it->max_phys_ascent = phys_ascent;
17707 it->max_phys_descent = phys_descent;
17708 }
17709
17710 break;
17711 }
17712 else if (new_x > it->first_visible_x)
17713 {
17714 /* Increment number of glyphs actually displayed. */
17715 ++it->hpos;
17716
17717 /* Record the maximum and minimum buffer positions
17718 seen so far in glyphs that will be displayed by
17719 this row. */
17720 if (it->bidi_p)
17721 RECORD_MAX_MIN_POS (it);
17722
17723 if (x < it->first_visible_x)
17724 /* Glyph is partially visible, i.e. row starts at
17725 negative X position. */
17726 row->x = x - it->first_visible_x;
17727 }
17728 else
17729 {
17730 /* Glyph is completely off the left margin of the
17731 window. This should not happen because of the
17732 move_it_in_display_line at the start of this
17733 function, unless the text display area of the
17734 window is empty. */
17735 xassert (it->first_visible_x <= it->last_visible_x);
17736 }
17737 }
17738
17739 row->ascent = max (row->ascent, it->max_ascent);
17740 row->height = max (row->height, it->max_ascent + it->max_descent);
17741 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
17742 row->phys_height = max (row->phys_height,
17743 it->max_phys_ascent + it->max_phys_descent);
17744 row->extra_line_spacing = max (row->extra_line_spacing,
17745 it->max_extra_line_spacing);
17746
17747 /* End of this display line if row is continued. */
17748 if (row->continued_p || row->ends_at_zv_p)
17749 break;
17750 }
17751
17752 at_end_of_line:
17753 /* Is this a line end? If yes, we're also done, after making
17754 sure that a non-default face is extended up to the right
17755 margin of the window. */
17756 if (ITERATOR_AT_END_OF_LINE_P (it))
17757 {
17758 int used_before = row->used[TEXT_AREA];
17759
17760 row->ends_in_newline_from_string_p = STRINGP (it->object);
17761
17762 /* Add a space at the end of the line that is used to
17763 display the cursor there. */
17764 if (!IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
17765 append_space_for_newline (it, 0);
17766
17767 /* Extend the face to the end of the line. */
17768 extend_face_to_end_of_line (it);
17769
17770 /* Make sure we have the position. */
17771 if (used_before == 0)
17772 row->glyphs[TEXT_AREA]->charpos = CHARPOS (it->position);
17773
17774 /* Record the position of the newline, for use in
17775 find_row_edges. */
17776 it->eol_pos = it->current.pos;
17777
17778 /* Consume the line end. This skips over invisible lines. */
17779 set_iterator_to_next (it, 1);
17780 it->continuation_lines_width = 0;
17781 break;
17782 }
17783
17784 /* Proceed with next display element. Note that this skips
17785 over lines invisible because of selective display. */
17786 set_iterator_to_next (it, 1);
17787
17788 /* If we truncate lines, we are done when the last displayed
17789 glyphs reach past the right margin of the window. */
17790 if (it->line_wrap == TRUNCATE
17791 && (FRAME_WINDOW_P (it->f)
17792 ? (it->current_x >= it->last_visible_x)
17793 : (it->current_x > it->last_visible_x)))
17794 {
17795 /* Maybe add truncation glyphs. */
17796 if (!FRAME_WINDOW_P (it->f))
17797 {
17798 int i, n;
17799
17800 if (!row->reversed_p)
17801 {
17802 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
17803 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
17804 break;
17805 }
17806 else
17807 {
17808 for (i = 0; i < row->used[TEXT_AREA]; i++)
17809 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
17810 break;
17811 /* Remove any padding glyphs at the front of ROW, to
17812 make room for the truncation glyphs we will be
17813 adding below. The loop below always inserts at
17814 least one truncation glyph, so also remove the
17815 last glyph added to ROW. */
17816 unproduce_glyphs (it, i + 1);
17817 /* Adjust i for the loop below. */
17818 i = row->used[TEXT_AREA] - (i + 1);
17819 }
17820
17821 for (n = row->used[TEXT_AREA]; i < n; ++i)
17822 {
17823 row->used[TEXT_AREA] = i;
17824 produce_special_glyphs (it, IT_TRUNCATION);
17825 }
17826 }
17827 else if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
17828 {
17829 /* Don't truncate if we can overflow newline into fringe. */
17830 if (!get_next_display_element (it))
17831 {
17832 it->continuation_lines_width = 0;
17833 row->ends_at_zv_p = 1;
17834 row->exact_window_width_line_p = 1;
17835 break;
17836 }
17837 if (ITERATOR_AT_END_OF_LINE_P (it))
17838 {
17839 row->exact_window_width_line_p = 1;
17840 goto at_end_of_line;
17841 }
17842 }
17843
17844 row->truncated_on_right_p = 1;
17845 it->continuation_lines_width = 0;
17846 reseat_at_next_visible_line_start (it, 0);
17847 row->ends_at_zv_p = FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n';
17848 it->hpos = hpos_before;
17849 it->current_x = x_before;
17850 break;
17851 }
17852 }
17853
17854 /* If line is not empty and hscrolled, maybe insert truncation glyphs
17855 at the left window margin. */
17856 if (it->first_visible_x
17857 && IT_CHARPOS (*it) != CHARPOS (row->start.pos))
17858 {
17859 if (!FRAME_WINDOW_P (it->f))
17860 insert_left_trunc_glyphs (it);
17861 row->truncated_on_left_p = 1;
17862 }
17863
17864 /* Remember the position at which this line ends.
17865
17866 BIDI Note: any code that needs MATRIX_ROW_START/END_CHARPOS
17867 cannot be before the call to find_row_edges below, since that is
17868 where these positions are determined. */
17869 row->end = it->current;
17870 if (!it->bidi_p)
17871 {
17872 row->minpos = row->start.pos;
17873 row->maxpos = row->end.pos;
17874 }
17875 else
17876 {
17877 /* ROW->minpos and ROW->maxpos must be the smallest and
17878 `1 + the largest' buffer positions in ROW. But if ROW was
17879 bidi-reordered, these two positions can be anywhere in the
17880 row, so we must determine them now. */
17881 find_row_edges (it, row, min_pos, min_bpos, max_pos, max_bpos);
17882 }
17883
17884 /* If the start of this line is the overlay arrow-position, then
17885 mark this glyph row as the one containing the overlay arrow.
17886 This is clearly a mess with variable size fonts. It would be
17887 better to let it be displayed like cursors under X. */
17888 if ((row->displays_text_p || !overlay_arrow_seen)
17889 && (overlay_arrow_string = overlay_arrow_at_row (it, row),
17890 !NILP (overlay_arrow_string)))
17891 {
17892 /* Overlay arrow in window redisplay is a fringe bitmap. */
17893 if (STRINGP (overlay_arrow_string))
17894 {
17895 struct glyph_row *arrow_row
17896 = get_overlay_arrow_glyph_row (it->w, overlay_arrow_string);
17897 struct glyph *glyph = arrow_row->glyphs[TEXT_AREA];
17898 struct glyph *arrow_end = glyph + arrow_row->used[TEXT_AREA];
17899 struct glyph *p = row->glyphs[TEXT_AREA];
17900 struct glyph *p2, *end;
17901
17902 /* Copy the arrow glyphs. */
17903 while (glyph < arrow_end)
17904 *p++ = *glyph++;
17905
17906 /* Throw away padding glyphs. */
17907 p2 = p;
17908 end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
17909 while (p2 < end && CHAR_GLYPH_PADDING_P (*p2))
17910 ++p2;
17911 if (p2 > p)
17912 {
17913 while (p2 < end)
17914 *p++ = *p2++;
17915 row->used[TEXT_AREA] = p2 - row->glyphs[TEXT_AREA];
17916 }
17917 }
17918 else
17919 {
17920 xassert (INTEGERP (overlay_arrow_string));
17921 row->overlay_arrow_bitmap = XINT (overlay_arrow_string);
17922 }
17923 overlay_arrow_seen = 1;
17924 }
17925
17926 /* Compute pixel dimensions of this line. */
17927 compute_line_metrics (it);
17928
17929 /* Record whether this row ends inside an ellipsis. */
17930 row->ends_in_ellipsis_p
17931 = (it->method == GET_FROM_DISPLAY_VECTOR
17932 && it->ellipsis_p);
17933
17934 /* Save fringe bitmaps in this row. */
17935 row->left_user_fringe_bitmap = it->left_user_fringe_bitmap;
17936 row->left_user_fringe_face_id = it->left_user_fringe_face_id;
17937 row->right_user_fringe_bitmap = it->right_user_fringe_bitmap;
17938 row->right_user_fringe_face_id = it->right_user_fringe_face_id;
17939
17940 it->left_user_fringe_bitmap = 0;
17941 it->left_user_fringe_face_id = 0;
17942 it->right_user_fringe_bitmap = 0;
17943 it->right_user_fringe_face_id = 0;
17944
17945 /* Maybe set the cursor. */
17946 cvpos = it->w->cursor.vpos;
17947 if ((cvpos < 0
17948 /* In bidi-reordered rows, keep checking for proper cursor
17949 position even if one has been found already, because buffer
17950 positions in such rows change non-linearly with ROW->VPOS,
17951 when a line is continued. One exception: when we are at ZV,
17952 display cursor on the first suitable glyph row, since all
17953 the empty rows after that also have their position set to ZV. */
17954 /* FIXME: Revisit this when glyph ``spilling'' in continuation
17955 lines' rows is implemented for bidi-reordered rows. */
17956 || (it->bidi_p
17957 && !MATRIX_ROW (it->w->desired_matrix, cvpos)->ends_at_zv_p))
17958 && PT >= MATRIX_ROW_START_CHARPOS (row)
17959 && PT <= MATRIX_ROW_END_CHARPOS (row)
17960 && cursor_row_p (row))
17961 set_cursor_from_row (it->w, row, it->w->desired_matrix, 0, 0, 0, 0);
17962
17963 /* Highlight trailing whitespace. */
17964 if (!NILP (Vshow_trailing_whitespace))
17965 highlight_trailing_whitespace (it->f, it->glyph_row);
17966
17967 /* Prepare for the next line. This line starts horizontally at (X
17968 HPOS) = (0 0). Vertical positions are incremented. As a
17969 convenience for the caller, IT->glyph_row is set to the next
17970 row to be used. */
17971 it->current_x = it->hpos = 0;
17972 it->current_y += row->height;
17973 SET_TEXT_POS (it->eol_pos, 0, 0);
17974 ++it->vpos;
17975 ++it->glyph_row;
17976 /* The next row should by default use the same value of the
17977 reversed_p flag as this one. set_iterator_to_next decides when
17978 it's a new paragraph, and PRODUCE_GLYPHS recomputes the value of
17979 the flag accordingly. */
17980 if (it->glyph_row < MATRIX_BOTTOM_TEXT_ROW (it->w->desired_matrix, it->w))
17981 it->glyph_row->reversed_p = row->reversed_p;
17982 it->start = row->end;
17983 return row->displays_text_p;
17984
17985 #undef RECORD_MAX_MIN_POS
17986 }
17987
17988 DEFUN ("current-bidi-paragraph-direction", Fcurrent_bidi_paragraph_direction,
17989 Scurrent_bidi_paragraph_direction, 0, 1, 0,
17990 doc: /* Return paragraph direction at point in BUFFER.
17991 Value is either `left-to-right' or `right-to-left'.
17992 If BUFFER is omitted or nil, it defaults to the current buffer.
17993
17994 Paragraph direction determines how the text in the paragraph is displayed.
17995 In left-to-right paragraphs, text begins at the left margin of the window
17996 and the reading direction is generally left to right. In right-to-left
17997 paragraphs, text begins at the right margin and is read from right to left.
17998
17999 See also `bidi-paragraph-direction'. */)
18000 (Lisp_Object buffer)
18001 {
18002 struct buffer *buf = current_buffer;
18003 struct buffer *old = buf;
18004
18005 if (! NILP (buffer))
18006 {
18007 CHECK_BUFFER (buffer);
18008 buf = XBUFFER (buffer);
18009 }
18010
18011 if (NILP (BVAR (buf, bidi_display_reordering)))
18012 return Qleft_to_right;
18013 else if (!NILP (BVAR (buf, bidi_paragraph_direction)))
18014 return BVAR (buf, bidi_paragraph_direction);
18015 else
18016 {
18017 /* Determine the direction from buffer text. We could try to
18018 use current_matrix if it is up to date, but this seems fast
18019 enough as it is. */
18020 struct bidi_it itb;
18021 EMACS_INT pos = BUF_PT (buf);
18022 EMACS_INT bytepos = BUF_PT_BYTE (buf);
18023 int c;
18024
18025 set_buffer_temp (buf);
18026 /* bidi_paragraph_init finds the base direction of the paragraph
18027 by searching forward from paragraph start. We need the base
18028 direction of the current or _previous_ paragraph, so we need
18029 to make sure we are within that paragraph. To that end, find
18030 the previous non-empty line. */
18031 if (pos >= ZV && pos > BEGV)
18032 {
18033 pos--;
18034 bytepos = CHAR_TO_BYTE (pos);
18035 }
18036 while ((c = FETCH_BYTE (bytepos)) == '\n'
18037 || c == ' ' || c == '\t' || c == '\f')
18038 {
18039 if (bytepos <= BEGV_BYTE)
18040 break;
18041 bytepos--;
18042 pos--;
18043 }
18044 while (!CHAR_HEAD_P (FETCH_BYTE (bytepos)))
18045 bytepos--;
18046 itb.charpos = pos;
18047 itb.bytepos = bytepos;
18048 itb.first_elt = 1;
18049 itb.separator_limit = -1;
18050 itb.paragraph_dir = NEUTRAL_DIR;
18051
18052 bidi_paragraph_init (NEUTRAL_DIR, &itb, 1);
18053 set_buffer_temp (old);
18054 switch (itb.paragraph_dir)
18055 {
18056 case L2R:
18057 return Qleft_to_right;
18058 break;
18059 case R2L:
18060 return Qright_to_left;
18061 break;
18062 default:
18063 abort ();
18064 }
18065 }
18066 }
18067
18068
18069 \f
18070 /***********************************************************************
18071 Menu Bar
18072 ***********************************************************************/
18073
18074 /* Redisplay the menu bar in the frame for window W.
18075
18076 The menu bar of X frames that don't have X toolkit support is
18077 displayed in a special window W->frame->menu_bar_window.
18078
18079 The menu bar of terminal frames is treated specially as far as
18080 glyph matrices are concerned. Menu bar lines are not part of
18081 windows, so the update is done directly on the frame matrix rows
18082 for the menu bar. */
18083
18084 static void
18085 display_menu_bar (struct window *w)
18086 {
18087 struct frame *f = XFRAME (WINDOW_FRAME (w));
18088 struct it it;
18089 Lisp_Object items;
18090 int i;
18091
18092 /* Don't do all this for graphical frames. */
18093 #ifdef HAVE_NTGUI
18094 if (FRAME_W32_P (f))
18095 return;
18096 #endif
18097 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
18098 if (FRAME_X_P (f))
18099 return;
18100 #endif
18101
18102 #ifdef HAVE_NS
18103 if (FRAME_NS_P (f))
18104 return;
18105 #endif /* HAVE_NS */
18106
18107 #ifdef USE_X_TOOLKIT
18108 xassert (!FRAME_WINDOW_P (f));
18109 init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MENU_FACE_ID);
18110 it.first_visible_x = 0;
18111 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
18112 #else /* not USE_X_TOOLKIT */
18113 if (FRAME_WINDOW_P (f))
18114 {
18115 /* Menu bar lines are displayed in the desired matrix of the
18116 dummy window menu_bar_window. */
18117 struct window *menu_w;
18118 xassert (WINDOWP (f->menu_bar_window));
18119 menu_w = XWINDOW (f->menu_bar_window);
18120 init_iterator (&it, menu_w, -1, -1, menu_w->desired_matrix->rows,
18121 MENU_FACE_ID);
18122 it.first_visible_x = 0;
18123 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
18124 }
18125 else
18126 {
18127 /* This is a TTY frame, i.e. character hpos/vpos are used as
18128 pixel x/y. */
18129 init_iterator (&it, w, -1, -1, f->desired_matrix->rows,
18130 MENU_FACE_ID);
18131 it.first_visible_x = 0;
18132 it.last_visible_x = FRAME_COLS (f);
18133 }
18134 #endif /* not USE_X_TOOLKIT */
18135
18136 if (! mode_line_inverse_video)
18137 /* Force the menu-bar to be displayed in the default face. */
18138 it.base_face_id = it.face_id = DEFAULT_FACE_ID;
18139
18140 /* Clear all rows of the menu bar. */
18141 for (i = 0; i < FRAME_MENU_BAR_LINES (f); ++i)
18142 {
18143 struct glyph_row *row = it.glyph_row + i;
18144 clear_glyph_row (row);
18145 row->enabled_p = 1;
18146 row->full_width_p = 1;
18147 }
18148
18149 /* Display all items of the menu bar. */
18150 items = FRAME_MENU_BAR_ITEMS (it.f);
18151 for (i = 0; i < XVECTOR (items)->size; i += 4)
18152 {
18153 Lisp_Object string;
18154
18155 /* Stop at nil string. */
18156 string = AREF (items, i + 1);
18157 if (NILP (string))
18158 break;
18159
18160 /* Remember where item was displayed. */
18161 ASET (items, i + 3, make_number (it.hpos));
18162
18163 /* Display the item, pad with one space. */
18164 if (it.current_x < it.last_visible_x)
18165 display_string (NULL, string, Qnil, 0, 0, &it,
18166 SCHARS (string) + 1, 0, 0, -1);
18167 }
18168
18169 /* Fill out the line with spaces. */
18170 if (it.current_x < it.last_visible_x)
18171 display_string ("", Qnil, Qnil, 0, 0, &it, -1, 0, 0, -1);
18172
18173 /* Compute the total height of the lines. */
18174 compute_line_metrics (&it);
18175 }
18176
18177
18178 \f
18179 /***********************************************************************
18180 Mode Line
18181 ***********************************************************************/
18182
18183 /* Redisplay mode lines in the window tree whose root is WINDOW. If
18184 FORCE is non-zero, redisplay mode lines unconditionally.
18185 Otherwise, redisplay only mode lines that are garbaged. Value is
18186 the number of windows whose mode lines were redisplayed. */
18187
18188 static int
18189 redisplay_mode_lines (Lisp_Object window, int force)
18190 {
18191 int nwindows = 0;
18192
18193 while (!NILP (window))
18194 {
18195 struct window *w = XWINDOW (window);
18196
18197 if (WINDOWP (w->hchild))
18198 nwindows += redisplay_mode_lines (w->hchild, force);
18199 else if (WINDOWP (w->vchild))
18200 nwindows += redisplay_mode_lines (w->vchild, force);
18201 else if (force
18202 || FRAME_GARBAGED_P (XFRAME (w->frame))
18203 || !MATRIX_MODE_LINE_ROW (w->current_matrix)->enabled_p)
18204 {
18205 struct text_pos lpoint;
18206 struct buffer *old = current_buffer;
18207
18208 /* Set the window's buffer for the mode line display. */
18209 SET_TEXT_POS (lpoint, PT, PT_BYTE);
18210 set_buffer_internal_1 (XBUFFER (w->buffer));
18211
18212 /* Point refers normally to the selected window. For any
18213 other window, set up appropriate value. */
18214 if (!EQ (window, selected_window))
18215 {
18216 struct text_pos pt;
18217
18218 SET_TEXT_POS_FROM_MARKER (pt, w->pointm);
18219 if (CHARPOS (pt) < BEGV)
18220 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
18221 else if (CHARPOS (pt) > (ZV - 1))
18222 TEMP_SET_PT_BOTH (ZV, ZV_BYTE);
18223 else
18224 TEMP_SET_PT_BOTH (CHARPOS (pt), BYTEPOS (pt));
18225 }
18226
18227 /* Display mode lines. */
18228 clear_glyph_matrix (w->desired_matrix);
18229 if (display_mode_lines (w))
18230 {
18231 ++nwindows;
18232 w->must_be_updated_p = 1;
18233 }
18234
18235 /* Restore old settings. */
18236 set_buffer_internal_1 (old);
18237 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
18238 }
18239
18240 window = w->next;
18241 }
18242
18243 return nwindows;
18244 }
18245
18246
18247 /* Display the mode and/or header line of window W. Value is the
18248 sum number of mode lines and header lines displayed. */
18249
18250 static int
18251 display_mode_lines (struct window *w)
18252 {
18253 Lisp_Object old_selected_window, old_selected_frame;
18254 int n = 0;
18255
18256 old_selected_frame = selected_frame;
18257 selected_frame = w->frame;
18258 old_selected_window = selected_window;
18259 XSETWINDOW (selected_window, w);
18260
18261 /* These will be set while the mode line specs are processed. */
18262 line_number_displayed = 0;
18263 w->column_number_displayed = Qnil;
18264
18265 if (WINDOW_WANTS_MODELINE_P (w))
18266 {
18267 struct window *sel_w = XWINDOW (old_selected_window);
18268
18269 /* Select mode line face based on the real selected window. */
18270 display_mode_line (w, CURRENT_MODE_LINE_FACE_ID_3 (sel_w, sel_w, w),
18271 BVAR (current_buffer, mode_line_format));
18272 ++n;
18273 }
18274
18275 if (WINDOW_WANTS_HEADER_LINE_P (w))
18276 {
18277 display_mode_line (w, HEADER_LINE_FACE_ID,
18278 BVAR (current_buffer, header_line_format));
18279 ++n;
18280 }
18281
18282 selected_frame = old_selected_frame;
18283 selected_window = old_selected_window;
18284 return n;
18285 }
18286
18287
18288 /* Display mode or header line of window W. FACE_ID specifies which
18289 line to display; it is either MODE_LINE_FACE_ID or
18290 HEADER_LINE_FACE_ID. FORMAT is the mode/header line format to
18291 display. Value is the pixel height of the mode/header line
18292 displayed. */
18293
18294 static int
18295 display_mode_line (struct window *w, enum face_id face_id, Lisp_Object format)
18296 {
18297 struct it it;
18298 struct face *face;
18299 int count = SPECPDL_INDEX ();
18300
18301 init_iterator (&it, w, -1, -1, NULL, face_id);
18302 /* Don't extend on a previously drawn mode-line.
18303 This may happen if called from pos_visible_p. */
18304 it.glyph_row->enabled_p = 0;
18305 prepare_desired_row (it.glyph_row);
18306
18307 it.glyph_row->mode_line_p = 1;
18308
18309 if (! mode_line_inverse_video)
18310 /* Force the mode-line to be displayed in the default face. */
18311 it.base_face_id = it.face_id = DEFAULT_FACE_ID;
18312
18313 record_unwind_protect (unwind_format_mode_line,
18314 format_mode_line_unwind_data (NULL, Qnil, 0));
18315
18316 mode_line_target = MODE_LINE_DISPLAY;
18317
18318 /* Temporarily make frame's keyboard the current kboard so that
18319 kboard-local variables in the mode_line_format will get the right
18320 values. */
18321 push_kboard (FRAME_KBOARD (it.f));
18322 record_unwind_save_match_data ();
18323 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
18324 pop_kboard ();
18325
18326 unbind_to (count, Qnil);
18327
18328 /* Fill up with spaces. */
18329 display_string (" ", Qnil, Qnil, 0, 0, &it, 10000, -1, -1, 0);
18330
18331 compute_line_metrics (&it);
18332 it.glyph_row->full_width_p = 1;
18333 it.glyph_row->continued_p = 0;
18334 it.glyph_row->truncated_on_left_p = 0;
18335 it.glyph_row->truncated_on_right_p = 0;
18336
18337 /* Make a 3D mode-line have a shadow at its right end. */
18338 face = FACE_FROM_ID (it.f, face_id);
18339 extend_face_to_end_of_line (&it);
18340 if (face->box != FACE_NO_BOX)
18341 {
18342 struct glyph *last = (it.glyph_row->glyphs[TEXT_AREA]
18343 + it.glyph_row->used[TEXT_AREA] - 1);
18344 last->right_box_line_p = 1;
18345 }
18346
18347 return it.glyph_row->height;
18348 }
18349
18350 /* Move element ELT in LIST to the front of LIST.
18351 Return the updated list. */
18352
18353 static Lisp_Object
18354 move_elt_to_front (Lisp_Object elt, Lisp_Object list)
18355 {
18356 register Lisp_Object tail, prev;
18357 register Lisp_Object tem;
18358
18359 tail = list;
18360 prev = Qnil;
18361 while (CONSP (tail))
18362 {
18363 tem = XCAR (tail);
18364
18365 if (EQ (elt, tem))
18366 {
18367 /* Splice out the link TAIL. */
18368 if (NILP (prev))
18369 list = XCDR (tail);
18370 else
18371 Fsetcdr (prev, XCDR (tail));
18372
18373 /* Now make it the first. */
18374 Fsetcdr (tail, list);
18375 return tail;
18376 }
18377 else
18378 prev = tail;
18379 tail = XCDR (tail);
18380 QUIT;
18381 }
18382
18383 /* Not found--return unchanged LIST. */
18384 return list;
18385 }
18386
18387 /* Contribute ELT to the mode line for window IT->w. How it
18388 translates into text depends on its data type.
18389
18390 IT describes the display environment in which we display, as usual.
18391
18392 DEPTH is the depth in recursion. It is used to prevent
18393 infinite recursion here.
18394
18395 FIELD_WIDTH is the number of characters the display of ELT should
18396 occupy in the mode line, and PRECISION is the maximum number of
18397 characters to display from ELT's representation. See
18398 display_string for details.
18399
18400 Returns the hpos of the end of the text generated by ELT.
18401
18402 PROPS is a property list to add to any string we encounter.
18403
18404 If RISKY is nonzero, remove (disregard) any properties in any string
18405 we encounter, and ignore :eval and :propertize.
18406
18407 The global variable `mode_line_target' determines whether the
18408 output is passed to `store_mode_line_noprop',
18409 `store_mode_line_string', or `display_string'. */
18410
18411 static int
18412 display_mode_element (struct it *it, int depth, int field_width, int precision,
18413 Lisp_Object elt, Lisp_Object props, int risky)
18414 {
18415 int n = 0, field, prec;
18416 int literal = 0;
18417
18418 tail_recurse:
18419 if (depth > 100)
18420 elt = build_string ("*too-deep*");
18421
18422 depth++;
18423
18424 switch (SWITCH_ENUM_CAST (XTYPE (elt)))
18425 {
18426 case Lisp_String:
18427 {
18428 /* A string: output it and check for %-constructs within it. */
18429 unsigned char c;
18430 EMACS_INT offset = 0;
18431
18432 if (SCHARS (elt) > 0
18433 && (!NILP (props) || risky))
18434 {
18435 Lisp_Object oprops, aelt;
18436 oprops = Ftext_properties_at (make_number (0), elt);
18437
18438 /* If the starting string's properties are not what
18439 we want, translate the string. Also, if the string
18440 is risky, do that anyway. */
18441
18442 if (NILP (Fequal (props, oprops)) || risky)
18443 {
18444 /* If the starting string has properties,
18445 merge the specified ones onto the existing ones. */
18446 if (! NILP (oprops) && !risky)
18447 {
18448 Lisp_Object tem;
18449
18450 oprops = Fcopy_sequence (oprops);
18451 tem = props;
18452 while (CONSP (tem))
18453 {
18454 oprops = Fplist_put (oprops, XCAR (tem),
18455 XCAR (XCDR (tem)));
18456 tem = XCDR (XCDR (tem));
18457 }
18458 props = oprops;
18459 }
18460
18461 aelt = Fassoc (elt, mode_line_proptrans_alist);
18462 if (! NILP (aelt) && !NILP (Fequal (props, XCDR (aelt))))
18463 {
18464 /* AELT is what we want. Move it to the front
18465 without consing. */
18466 elt = XCAR (aelt);
18467 mode_line_proptrans_alist
18468 = move_elt_to_front (aelt, mode_line_proptrans_alist);
18469 }
18470 else
18471 {
18472 Lisp_Object tem;
18473
18474 /* If AELT has the wrong props, it is useless.
18475 so get rid of it. */
18476 if (! NILP (aelt))
18477 mode_line_proptrans_alist
18478 = Fdelq (aelt, mode_line_proptrans_alist);
18479
18480 elt = Fcopy_sequence (elt);
18481 Fset_text_properties (make_number (0), Flength (elt),
18482 props, elt);
18483 /* Add this item to mode_line_proptrans_alist. */
18484 mode_line_proptrans_alist
18485 = Fcons (Fcons (elt, props),
18486 mode_line_proptrans_alist);
18487 /* Truncate mode_line_proptrans_alist
18488 to at most 50 elements. */
18489 tem = Fnthcdr (make_number (50),
18490 mode_line_proptrans_alist);
18491 if (! NILP (tem))
18492 XSETCDR (tem, Qnil);
18493 }
18494 }
18495 }
18496
18497 offset = 0;
18498
18499 if (literal)
18500 {
18501 prec = precision - n;
18502 switch (mode_line_target)
18503 {
18504 case MODE_LINE_NOPROP:
18505 case MODE_LINE_TITLE:
18506 n += store_mode_line_noprop (SSDATA (elt), -1, prec);
18507 break;
18508 case MODE_LINE_STRING:
18509 n += store_mode_line_string (NULL, elt, 1, 0, prec, Qnil);
18510 break;
18511 case MODE_LINE_DISPLAY:
18512 n += display_string (NULL, elt, Qnil, 0, 0, it,
18513 0, prec, 0, STRING_MULTIBYTE (elt));
18514 break;
18515 }
18516
18517 break;
18518 }
18519
18520 /* Handle the non-literal case. */
18521
18522 while ((precision <= 0 || n < precision)
18523 && SREF (elt, offset) != 0
18524 && (mode_line_target != MODE_LINE_DISPLAY
18525 || it->current_x < it->last_visible_x))
18526 {
18527 EMACS_INT last_offset = offset;
18528
18529 /* Advance to end of string or next format specifier. */
18530 while ((c = SREF (elt, offset++)) != '\0' && c != '%')
18531 ;
18532
18533 if (offset - 1 != last_offset)
18534 {
18535 EMACS_INT nchars, nbytes;
18536
18537 /* Output to end of string or up to '%'. Field width
18538 is length of string. Don't output more than
18539 PRECISION allows us. */
18540 offset--;
18541
18542 prec = c_string_width (SDATA (elt) + last_offset,
18543 offset - last_offset, precision - n,
18544 &nchars, &nbytes);
18545
18546 switch (mode_line_target)
18547 {
18548 case MODE_LINE_NOPROP:
18549 case MODE_LINE_TITLE:
18550 n += store_mode_line_noprop (SSDATA (elt) + last_offset, 0, prec);
18551 break;
18552 case MODE_LINE_STRING:
18553 {
18554 EMACS_INT bytepos = last_offset;
18555 EMACS_INT charpos = string_byte_to_char (elt, bytepos);
18556 EMACS_INT endpos = (precision <= 0
18557 ? string_byte_to_char (elt, offset)
18558 : charpos + nchars);
18559
18560 n += store_mode_line_string (NULL,
18561 Fsubstring (elt, make_number (charpos),
18562 make_number (endpos)),
18563 0, 0, 0, Qnil);
18564 }
18565 break;
18566 case MODE_LINE_DISPLAY:
18567 {
18568 EMACS_INT bytepos = last_offset;
18569 EMACS_INT charpos = string_byte_to_char (elt, bytepos);
18570
18571 if (precision <= 0)
18572 nchars = string_byte_to_char (elt, offset) - charpos;
18573 n += display_string (NULL, elt, Qnil, 0, charpos,
18574 it, 0, nchars, 0,
18575 STRING_MULTIBYTE (elt));
18576 }
18577 break;
18578 }
18579 }
18580 else /* c == '%' */
18581 {
18582 EMACS_INT percent_position = offset;
18583
18584 /* Get the specified minimum width. Zero means
18585 don't pad. */
18586 field = 0;
18587 while ((c = SREF (elt, offset++)) >= '0' && c <= '9')
18588 field = field * 10 + c - '0';
18589
18590 /* Don't pad beyond the total padding allowed. */
18591 if (field_width - n > 0 && field > field_width - n)
18592 field = field_width - n;
18593
18594 /* Note that either PRECISION <= 0 or N < PRECISION. */
18595 prec = precision - n;
18596
18597 if (c == 'M')
18598 n += display_mode_element (it, depth, field, prec,
18599 Vglobal_mode_string, props,
18600 risky);
18601 else if (c != 0)
18602 {
18603 int multibyte;
18604 EMACS_INT bytepos, charpos;
18605 const char *spec;
18606 Lisp_Object string;
18607
18608 bytepos = percent_position;
18609 charpos = (STRING_MULTIBYTE (elt)
18610 ? string_byte_to_char (elt, bytepos)
18611 : bytepos);
18612 spec = decode_mode_spec (it->w, c, field, &string);
18613 multibyte = STRINGP (string) && STRING_MULTIBYTE (string);
18614
18615 switch (mode_line_target)
18616 {
18617 case MODE_LINE_NOPROP:
18618 case MODE_LINE_TITLE:
18619 n += store_mode_line_noprop (spec, field, prec);
18620 break;
18621 case MODE_LINE_STRING:
18622 {
18623 int len = strlen (spec);
18624 Lisp_Object tem = make_string (spec, len);
18625 props = Ftext_properties_at (make_number (charpos), elt);
18626 /* Should only keep face property in props */
18627 n += store_mode_line_string (NULL, tem, 0, field, prec, props);
18628 }
18629 break;
18630 case MODE_LINE_DISPLAY:
18631 {
18632 int nglyphs_before, nwritten;
18633
18634 nglyphs_before = it->glyph_row->used[TEXT_AREA];
18635 nwritten = display_string (spec, string, elt,
18636 charpos, 0, it,
18637 field, prec, 0,
18638 multibyte);
18639
18640 /* Assign to the glyphs written above the
18641 string where the `%x' came from, position
18642 of the `%'. */
18643 if (nwritten > 0)
18644 {
18645 struct glyph *glyph
18646 = (it->glyph_row->glyphs[TEXT_AREA]
18647 + nglyphs_before);
18648 int i;
18649
18650 for (i = 0; i < nwritten; ++i)
18651 {
18652 glyph[i].object = elt;
18653 glyph[i].charpos = charpos;
18654 }
18655
18656 n += nwritten;
18657 }
18658 }
18659 break;
18660 }
18661 }
18662 else /* c == 0 */
18663 break;
18664 }
18665 }
18666 }
18667 break;
18668
18669 case Lisp_Symbol:
18670 /* A symbol: process the value of the symbol recursively
18671 as if it appeared here directly. Avoid error if symbol void.
18672 Special case: if value of symbol is a string, output the string
18673 literally. */
18674 {
18675 register Lisp_Object tem;
18676
18677 /* If the variable is not marked as risky to set
18678 then its contents are risky to use. */
18679 if (NILP (Fget (elt, Qrisky_local_variable)))
18680 risky = 1;
18681
18682 tem = Fboundp (elt);
18683 if (!NILP (tem))
18684 {
18685 tem = Fsymbol_value (elt);
18686 /* If value is a string, output that string literally:
18687 don't check for % within it. */
18688 if (STRINGP (tem))
18689 literal = 1;
18690
18691 if (!EQ (tem, elt))
18692 {
18693 /* Give up right away for nil or t. */
18694 elt = tem;
18695 goto tail_recurse;
18696 }
18697 }
18698 }
18699 break;
18700
18701 case Lisp_Cons:
18702 {
18703 register Lisp_Object car, tem;
18704
18705 /* A cons cell: five distinct cases.
18706 If first element is :eval or :propertize, do something special.
18707 If first element is a string or a cons, process all the elements
18708 and effectively concatenate them.
18709 If first element is a negative number, truncate displaying cdr to
18710 at most that many characters. If positive, pad (with spaces)
18711 to at least that many characters.
18712 If first element is a symbol, process the cadr or caddr recursively
18713 according to whether the symbol's value is non-nil or nil. */
18714 car = XCAR (elt);
18715 if (EQ (car, QCeval))
18716 {
18717 /* An element of the form (:eval FORM) means evaluate FORM
18718 and use the result as mode line elements. */
18719
18720 if (risky)
18721 break;
18722
18723 if (CONSP (XCDR (elt)))
18724 {
18725 Lisp_Object spec;
18726 spec = safe_eval (XCAR (XCDR (elt)));
18727 n += display_mode_element (it, depth, field_width - n,
18728 precision - n, spec, props,
18729 risky);
18730 }
18731 }
18732 else if (EQ (car, QCpropertize))
18733 {
18734 /* An element of the form (:propertize ELT PROPS...)
18735 means display ELT but applying properties PROPS. */
18736
18737 if (risky)
18738 break;
18739
18740 if (CONSP (XCDR (elt)))
18741 n += display_mode_element (it, depth, field_width - n,
18742 precision - n, XCAR (XCDR (elt)),
18743 XCDR (XCDR (elt)), risky);
18744 }
18745 else if (SYMBOLP (car))
18746 {
18747 tem = Fboundp (car);
18748 elt = XCDR (elt);
18749 if (!CONSP (elt))
18750 goto invalid;
18751 /* elt is now the cdr, and we know it is a cons cell.
18752 Use its car if CAR has a non-nil value. */
18753 if (!NILP (tem))
18754 {
18755 tem = Fsymbol_value (car);
18756 if (!NILP (tem))
18757 {
18758 elt = XCAR (elt);
18759 goto tail_recurse;
18760 }
18761 }
18762 /* Symbol's value is nil (or symbol is unbound)
18763 Get the cddr of the original list
18764 and if possible find the caddr and use that. */
18765 elt = XCDR (elt);
18766 if (NILP (elt))
18767 break;
18768 else if (!CONSP (elt))
18769 goto invalid;
18770 elt = XCAR (elt);
18771 goto tail_recurse;
18772 }
18773 else if (INTEGERP (car))
18774 {
18775 register int lim = XINT (car);
18776 elt = XCDR (elt);
18777 if (lim < 0)
18778 {
18779 /* Negative int means reduce maximum width. */
18780 if (precision <= 0)
18781 precision = -lim;
18782 else
18783 precision = min (precision, -lim);
18784 }
18785 else if (lim > 0)
18786 {
18787 /* Padding specified. Don't let it be more than
18788 current maximum. */
18789 if (precision > 0)
18790 lim = min (precision, lim);
18791
18792 /* If that's more padding than already wanted, queue it.
18793 But don't reduce padding already specified even if
18794 that is beyond the current truncation point. */
18795 field_width = max (lim, field_width);
18796 }
18797 goto tail_recurse;
18798 }
18799 else if (STRINGP (car) || CONSP (car))
18800 {
18801 Lisp_Object halftail = elt;
18802 int len = 0;
18803
18804 while (CONSP (elt)
18805 && (precision <= 0 || n < precision))
18806 {
18807 n += display_mode_element (it, depth,
18808 /* Do padding only after the last
18809 element in the list. */
18810 (! CONSP (XCDR (elt))
18811 ? field_width - n
18812 : 0),
18813 precision - n, XCAR (elt),
18814 props, risky);
18815 elt = XCDR (elt);
18816 len++;
18817 if ((len & 1) == 0)
18818 halftail = XCDR (halftail);
18819 /* Check for cycle. */
18820 if (EQ (halftail, elt))
18821 break;
18822 }
18823 }
18824 }
18825 break;
18826
18827 default:
18828 invalid:
18829 elt = build_string ("*invalid*");
18830 goto tail_recurse;
18831 }
18832
18833 /* Pad to FIELD_WIDTH. */
18834 if (field_width > 0 && n < field_width)
18835 {
18836 switch (mode_line_target)
18837 {
18838 case MODE_LINE_NOPROP:
18839 case MODE_LINE_TITLE:
18840 n += store_mode_line_noprop ("", field_width - n, 0);
18841 break;
18842 case MODE_LINE_STRING:
18843 n += store_mode_line_string ("", Qnil, 0, field_width - n, 0, Qnil);
18844 break;
18845 case MODE_LINE_DISPLAY:
18846 n += display_string ("", Qnil, Qnil, 0, 0, it, field_width - n,
18847 0, 0, 0);
18848 break;
18849 }
18850 }
18851
18852 return n;
18853 }
18854
18855 /* Store a mode-line string element in mode_line_string_list.
18856
18857 If STRING is non-null, display that C string. Otherwise, the Lisp
18858 string LISP_STRING is displayed.
18859
18860 FIELD_WIDTH is the minimum number of output glyphs to produce.
18861 If STRING has fewer characters than FIELD_WIDTH, pad to the right
18862 with spaces. FIELD_WIDTH <= 0 means don't pad.
18863
18864 PRECISION is the maximum number of characters to output from
18865 STRING. PRECISION <= 0 means don't truncate the string.
18866
18867 If COPY_STRING is non-zero, make a copy of LISP_STRING before adding
18868 properties to the string.
18869
18870 PROPS are the properties to add to the string.
18871 The mode_line_string_face face property is always added to the string.
18872 */
18873
18874 static int
18875 store_mode_line_string (const char *string, Lisp_Object lisp_string, int copy_string,
18876 int field_width, int precision, Lisp_Object props)
18877 {
18878 EMACS_INT len;
18879 int n = 0;
18880
18881 if (string != NULL)
18882 {
18883 len = strlen (string);
18884 if (precision > 0 && len > precision)
18885 len = precision;
18886 lisp_string = make_string (string, len);
18887 if (NILP (props))
18888 props = mode_line_string_face_prop;
18889 else if (!NILP (mode_line_string_face))
18890 {
18891 Lisp_Object face = Fplist_get (props, Qface);
18892 props = Fcopy_sequence (props);
18893 if (NILP (face))
18894 face = mode_line_string_face;
18895 else
18896 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
18897 props = Fplist_put (props, Qface, face);
18898 }
18899 Fadd_text_properties (make_number (0), make_number (len),
18900 props, lisp_string);
18901 }
18902 else
18903 {
18904 len = XFASTINT (Flength (lisp_string));
18905 if (precision > 0 && len > precision)
18906 {
18907 len = precision;
18908 lisp_string = Fsubstring (lisp_string, make_number (0), make_number (len));
18909 precision = -1;
18910 }
18911 if (!NILP (mode_line_string_face))
18912 {
18913 Lisp_Object face;
18914 if (NILP (props))
18915 props = Ftext_properties_at (make_number (0), lisp_string);
18916 face = Fplist_get (props, Qface);
18917 if (NILP (face))
18918 face = mode_line_string_face;
18919 else
18920 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
18921 props = Fcons (Qface, Fcons (face, Qnil));
18922 if (copy_string)
18923 lisp_string = Fcopy_sequence (lisp_string);
18924 }
18925 if (!NILP (props))
18926 Fadd_text_properties (make_number (0), make_number (len),
18927 props, lisp_string);
18928 }
18929
18930 if (len > 0)
18931 {
18932 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
18933 n += len;
18934 }
18935
18936 if (field_width > len)
18937 {
18938 field_width -= len;
18939 lisp_string = Fmake_string (make_number (field_width), make_number (' '));
18940 if (!NILP (props))
18941 Fadd_text_properties (make_number (0), make_number (field_width),
18942 props, lisp_string);
18943 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
18944 n += field_width;
18945 }
18946
18947 return n;
18948 }
18949
18950
18951 DEFUN ("format-mode-line", Fformat_mode_line, Sformat_mode_line,
18952 1, 4, 0,
18953 doc: /* Format a string out of a mode line format specification.
18954 First arg FORMAT specifies the mode line format (see `mode-line-format'
18955 for details) to use.
18956
18957 By default, the format is evaluated for the currently selected window.
18958
18959 Optional second arg FACE specifies the face property to put on all
18960 characters for which no face is specified. The value nil means the
18961 default face. The value t means whatever face the window's mode line
18962 currently uses (either `mode-line' or `mode-line-inactive',
18963 depending on whether the window is the selected window or not).
18964 An integer value means the value string has no text
18965 properties.
18966
18967 Optional third and fourth args WINDOW and BUFFER specify the window
18968 and buffer to use as the context for the formatting (defaults
18969 are the selected window and the WINDOW's buffer). */)
18970 (Lisp_Object format, Lisp_Object face,
18971 Lisp_Object window, Lisp_Object buffer)
18972 {
18973 struct it it;
18974 int len;
18975 struct window *w;
18976 struct buffer *old_buffer = NULL;
18977 int face_id;
18978 int no_props = INTEGERP (face);
18979 int count = SPECPDL_INDEX ();
18980 Lisp_Object str;
18981 int string_start = 0;
18982
18983 if (NILP (window))
18984 window = selected_window;
18985 CHECK_WINDOW (window);
18986 w = XWINDOW (window);
18987
18988 if (NILP (buffer))
18989 buffer = w->buffer;
18990 CHECK_BUFFER (buffer);
18991
18992 /* Make formatting the modeline a non-op when noninteractive, otherwise
18993 there will be problems later caused by a partially initialized frame. */
18994 if (NILP (format) || noninteractive)
18995 return empty_unibyte_string;
18996
18997 if (no_props)
18998 face = Qnil;
18999
19000 face_id = (NILP (face) || EQ (face, Qdefault)) ? DEFAULT_FACE_ID
19001 : EQ (face, Qt) ? (EQ (window, selected_window)
19002 ? MODE_LINE_FACE_ID : MODE_LINE_INACTIVE_FACE_ID)
19003 : EQ (face, Qmode_line) ? MODE_LINE_FACE_ID
19004 : EQ (face, Qmode_line_inactive) ? MODE_LINE_INACTIVE_FACE_ID
19005 : EQ (face, Qheader_line) ? HEADER_LINE_FACE_ID
19006 : EQ (face, Qtool_bar) ? TOOL_BAR_FACE_ID
19007 : DEFAULT_FACE_ID;
19008
19009 if (XBUFFER (buffer) != current_buffer)
19010 old_buffer = current_buffer;
19011
19012 /* Save things including mode_line_proptrans_alist,
19013 and set that to nil so that we don't alter the outer value. */
19014 record_unwind_protect (unwind_format_mode_line,
19015 format_mode_line_unwind_data
19016 (old_buffer, selected_window, 1));
19017 mode_line_proptrans_alist = Qnil;
19018
19019 Fselect_window (window, Qt);
19020 if (old_buffer)
19021 set_buffer_internal_1 (XBUFFER (buffer));
19022
19023 init_iterator (&it, w, -1, -1, NULL, face_id);
19024
19025 if (no_props)
19026 {
19027 mode_line_target = MODE_LINE_NOPROP;
19028 mode_line_string_face_prop = Qnil;
19029 mode_line_string_list = Qnil;
19030 string_start = MODE_LINE_NOPROP_LEN (0);
19031 }
19032 else
19033 {
19034 mode_line_target = MODE_LINE_STRING;
19035 mode_line_string_list = Qnil;
19036 mode_line_string_face = face;
19037 mode_line_string_face_prop
19038 = (NILP (face) ? Qnil : Fcons (Qface, Fcons (face, Qnil)));
19039 }
19040
19041 push_kboard (FRAME_KBOARD (it.f));
19042 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
19043 pop_kboard ();
19044
19045 if (no_props)
19046 {
19047 len = MODE_LINE_NOPROP_LEN (string_start);
19048 str = make_string (mode_line_noprop_buf + string_start, len);
19049 }
19050 else
19051 {
19052 mode_line_string_list = Fnreverse (mode_line_string_list);
19053 str = Fmapconcat (intern ("identity"), mode_line_string_list,
19054 empty_unibyte_string);
19055 }
19056
19057 unbind_to (count, Qnil);
19058 return str;
19059 }
19060
19061 /* Write a null-terminated, right justified decimal representation of
19062 the positive integer D to BUF using a minimal field width WIDTH. */
19063
19064 static void
19065 pint2str (register char *buf, register int width, register EMACS_INT d)
19066 {
19067 register char *p = buf;
19068
19069 if (d <= 0)
19070 *p++ = '0';
19071 else
19072 {
19073 while (d > 0)
19074 {
19075 *p++ = d % 10 + '0';
19076 d /= 10;
19077 }
19078 }
19079
19080 for (width -= (int) (p - buf); width > 0; --width)
19081 *p++ = ' ';
19082 *p-- = '\0';
19083 while (p > buf)
19084 {
19085 d = *buf;
19086 *buf++ = *p;
19087 *p-- = d;
19088 }
19089 }
19090
19091 /* Write a null-terminated, right justified decimal and "human
19092 readable" representation of the nonnegative integer D to BUF using
19093 a minimal field width WIDTH. D should be smaller than 999.5e24. */
19094
19095 static const char power_letter[] =
19096 {
19097 0, /* no letter */
19098 'k', /* kilo */
19099 'M', /* mega */
19100 'G', /* giga */
19101 'T', /* tera */
19102 'P', /* peta */
19103 'E', /* exa */
19104 'Z', /* zetta */
19105 'Y' /* yotta */
19106 };
19107
19108 static void
19109 pint2hrstr (char *buf, int width, int d)
19110 {
19111 /* We aim to represent the nonnegative integer D as
19112 QUOTIENT.TENTHS * 10 ^ (3 * EXPONENT). */
19113 int quotient = d;
19114 int remainder = 0;
19115 /* -1 means: do not use TENTHS. */
19116 int tenths = -1;
19117 int exponent = 0;
19118
19119 /* Length of QUOTIENT.TENTHS as a string. */
19120 int length;
19121
19122 char * psuffix;
19123 char * p;
19124
19125 if (1000 <= quotient)
19126 {
19127 /* Scale to the appropriate EXPONENT. */
19128 do
19129 {
19130 remainder = quotient % 1000;
19131 quotient /= 1000;
19132 exponent++;
19133 }
19134 while (1000 <= quotient);
19135
19136 /* Round to nearest and decide whether to use TENTHS or not. */
19137 if (quotient <= 9)
19138 {
19139 tenths = remainder / 100;
19140 if (50 <= remainder % 100)
19141 {
19142 if (tenths < 9)
19143 tenths++;
19144 else
19145 {
19146 quotient++;
19147 if (quotient == 10)
19148 tenths = -1;
19149 else
19150 tenths = 0;
19151 }
19152 }
19153 }
19154 else
19155 if (500 <= remainder)
19156 {
19157 if (quotient < 999)
19158 quotient++;
19159 else
19160 {
19161 quotient = 1;
19162 exponent++;
19163 tenths = 0;
19164 }
19165 }
19166 }
19167
19168 /* Calculate the LENGTH of QUOTIENT.TENTHS as a string. */
19169 if (tenths == -1 && quotient <= 99)
19170 if (quotient <= 9)
19171 length = 1;
19172 else
19173 length = 2;
19174 else
19175 length = 3;
19176 p = psuffix = buf + max (width, length);
19177
19178 /* Print EXPONENT. */
19179 *psuffix++ = power_letter[exponent];
19180 *psuffix = '\0';
19181
19182 /* Print TENTHS. */
19183 if (tenths >= 0)
19184 {
19185 *--p = '0' + tenths;
19186 *--p = '.';
19187 }
19188
19189 /* Print QUOTIENT. */
19190 do
19191 {
19192 int digit = quotient % 10;
19193 *--p = '0' + digit;
19194 }
19195 while ((quotient /= 10) != 0);
19196
19197 /* Print leading spaces. */
19198 while (buf < p)
19199 *--p = ' ';
19200 }
19201
19202 /* Set a mnemonic character for coding_system (Lisp symbol) in BUF.
19203 If EOL_FLAG is 1, set also a mnemonic character for end-of-line
19204 type of CODING_SYSTEM. Return updated pointer into BUF. */
19205
19206 static unsigned char invalid_eol_type[] = "(*invalid*)";
19207
19208 static char *
19209 decode_mode_spec_coding (Lisp_Object coding_system, register char *buf, int eol_flag)
19210 {
19211 Lisp_Object val;
19212 int multibyte = !NILP (BVAR (current_buffer, enable_multibyte_characters));
19213 const unsigned char *eol_str;
19214 int eol_str_len;
19215 /* The EOL conversion we are using. */
19216 Lisp_Object eoltype;
19217
19218 val = CODING_SYSTEM_SPEC (coding_system);
19219 eoltype = Qnil;
19220
19221 if (!VECTORP (val)) /* Not yet decided. */
19222 {
19223 if (multibyte)
19224 *buf++ = '-';
19225 if (eol_flag)
19226 eoltype = eol_mnemonic_undecided;
19227 /* Don't mention EOL conversion if it isn't decided. */
19228 }
19229 else
19230 {
19231 Lisp_Object attrs;
19232 Lisp_Object eolvalue;
19233
19234 attrs = AREF (val, 0);
19235 eolvalue = AREF (val, 2);
19236
19237 if (multibyte)
19238 *buf++ = XFASTINT (CODING_ATTR_MNEMONIC (attrs));
19239
19240 if (eol_flag)
19241 {
19242 /* The EOL conversion that is normal on this system. */
19243
19244 if (NILP (eolvalue)) /* Not yet decided. */
19245 eoltype = eol_mnemonic_undecided;
19246 else if (VECTORP (eolvalue)) /* Not yet decided. */
19247 eoltype = eol_mnemonic_undecided;
19248 else /* eolvalue is Qunix, Qdos, or Qmac. */
19249 eoltype = (EQ (eolvalue, Qunix)
19250 ? eol_mnemonic_unix
19251 : (EQ (eolvalue, Qdos) == 1
19252 ? eol_mnemonic_dos : eol_mnemonic_mac));
19253 }
19254 }
19255
19256 if (eol_flag)
19257 {
19258 /* Mention the EOL conversion if it is not the usual one. */
19259 if (STRINGP (eoltype))
19260 {
19261 eol_str = SDATA (eoltype);
19262 eol_str_len = SBYTES (eoltype);
19263 }
19264 else if (CHARACTERP (eoltype))
19265 {
19266 unsigned char *tmp = (unsigned char *) alloca (MAX_MULTIBYTE_LENGTH);
19267 eol_str_len = CHAR_STRING (XINT (eoltype), tmp);
19268 eol_str = tmp;
19269 }
19270 else
19271 {
19272 eol_str = invalid_eol_type;
19273 eol_str_len = sizeof (invalid_eol_type) - 1;
19274 }
19275 memcpy (buf, eol_str, eol_str_len);
19276 buf += eol_str_len;
19277 }
19278
19279 return buf;
19280 }
19281
19282 /* Return a string for the output of a mode line %-spec for window W,
19283 generated by character C. FIELD_WIDTH > 0 means pad the string
19284 returned with spaces to that value. Return a Lisp string in
19285 *STRING if the resulting string is taken from that Lisp string.
19286
19287 Note we operate on the current buffer for most purposes,
19288 the exception being w->base_line_pos. */
19289
19290 static char lots_of_dashes[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
19291
19292 static const char *
19293 decode_mode_spec (struct window *w, register int c, int field_width,
19294 Lisp_Object *string)
19295 {
19296 Lisp_Object obj;
19297 struct frame *f = XFRAME (WINDOW_FRAME (w));
19298 char *decode_mode_spec_buf = f->decode_mode_spec_buffer;
19299 struct buffer *b = current_buffer;
19300
19301 obj = Qnil;
19302 *string = Qnil;
19303
19304 switch (c)
19305 {
19306 case '*':
19307 if (!NILP (BVAR (b, read_only)))
19308 return "%";
19309 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
19310 return "*";
19311 return "-";
19312
19313 case '+':
19314 /* This differs from %* only for a modified read-only buffer. */
19315 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
19316 return "*";
19317 if (!NILP (BVAR (b, read_only)))
19318 return "%";
19319 return "-";
19320
19321 case '&':
19322 /* This differs from %* in ignoring read-only-ness. */
19323 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
19324 return "*";
19325 return "-";
19326
19327 case '%':
19328 return "%";
19329
19330 case '[':
19331 {
19332 int i;
19333 char *p;
19334
19335 if (command_loop_level > 5)
19336 return "[[[... ";
19337 p = decode_mode_spec_buf;
19338 for (i = 0; i < command_loop_level; i++)
19339 *p++ = '[';
19340 *p = 0;
19341 return decode_mode_spec_buf;
19342 }
19343
19344 case ']':
19345 {
19346 int i;
19347 char *p;
19348
19349 if (command_loop_level > 5)
19350 return " ...]]]";
19351 p = decode_mode_spec_buf;
19352 for (i = 0; i < command_loop_level; i++)
19353 *p++ = ']';
19354 *p = 0;
19355 return decode_mode_spec_buf;
19356 }
19357
19358 case '-':
19359 {
19360 register int i;
19361
19362 /* Let lots_of_dashes be a string of infinite length. */
19363 if (mode_line_target == MODE_LINE_NOPROP ||
19364 mode_line_target == MODE_LINE_STRING)
19365 return "--";
19366 if (field_width <= 0
19367 || field_width > sizeof (lots_of_dashes))
19368 {
19369 for (i = 0; i < FRAME_MESSAGE_BUF_SIZE (f) - 1; ++i)
19370 decode_mode_spec_buf[i] = '-';
19371 decode_mode_spec_buf[i] = '\0';
19372 return decode_mode_spec_buf;
19373 }
19374 else
19375 return lots_of_dashes;
19376 }
19377
19378 case 'b':
19379 obj = BVAR (b, name);
19380 break;
19381
19382 case 'c':
19383 /* %c and %l are ignored in `frame-title-format'.
19384 (In redisplay_internal, the frame title is drawn _before_ the
19385 windows are updated, so the stuff which depends on actual
19386 window contents (such as %l) may fail to render properly, or
19387 even crash emacs.) */
19388 if (mode_line_target == MODE_LINE_TITLE)
19389 return "";
19390 else
19391 {
19392 EMACS_INT col = current_column ();
19393 w->column_number_displayed = make_number (col);
19394 pint2str (decode_mode_spec_buf, field_width, col);
19395 return decode_mode_spec_buf;
19396 }
19397
19398 case 'e':
19399 #ifndef SYSTEM_MALLOC
19400 {
19401 if (NILP (Vmemory_full))
19402 return "";
19403 else
19404 return "!MEM FULL! ";
19405 }
19406 #else
19407 return "";
19408 #endif
19409
19410 case 'F':
19411 /* %F displays the frame name. */
19412 if (!NILP (f->title))
19413 return SSDATA (f->title);
19414 if (f->explicit_name || ! FRAME_WINDOW_P (f))
19415 return SSDATA (f->name);
19416 return "Emacs";
19417
19418 case 'f':
19419 obj = BVAR (b, filename);
19420 break;
19421
19422 case 'i':
19423 {
19424 EMACS_INT size = ZV - BEGV;
19425 pint2str (decode_mode_spec_buf, field_width, size);
19426 return decode_mode_spec_buf;
19427 }
19428
19429 case 'I':
19430 {
19431 EMACS_INT size = ZV - BEGV;
19432 pint2hrstr (decode_mode_spec_buf, field_width, size);
19433 return decode_mode_spec_buf;
19434 }
19435
19436 case 'l':
19437 {
19438 EMACS_INT startpos, startpos_byte, line, linepos, linepos_byte;
19439 int topline, nlines, height;
19440 EMACS_INT junk;
19441
19442 /* %c and %l are ignored in `frame-title-format'. */
19443 if (mode_line_target == MODE_LINE_TITLE)
19444 return "";
19445
19446 startpos = XMARKER (w->start)->charpos;
19447 startpos_byte = marker_byte_position (w->start);
19448 height = WINDOW_TOTAL_LINES (w);
19449
19450 /* If we decided that this buffer isn't suitable for line numbers,
19451 don't forget that too fast. */
19452 if (EQ (w->base_line_pos, w->buffer))
19453 goto no_value;
19454 /* But do forget it, if the window shows a different buffer now. */
19455 else if (BUFFERP (w->base_line_pos))
19456 w->base_line_pos = Qnil;
19457
19458 /* If the buffer is very big, don't waste time. */
19459 if (INTEGERP (Vline_number_display_limit)
19460 && BUF_ZV (b) - BUF_BEGV (b) > XINT (Vline_number_display_limit))
19461 {
19462 w->base_line_pos = Qnil;
19463 w->base_line_number = Qnil;
19464 goto no_value;
19465 }
19466
19467 if (INTEGERP (w->base_line_number)
19468 && INTEGERP (w->base_line_pos)
19469 && XFASTINT (w->base_line_pos) <= startpos)
19470 {
19471 line = XFASTINT (w->base_line_number);
19472 linepos = XFASTINT (w->base_line_pos);
19473 linepos_byte = buf_charpos_to_bytepos (b, linepos);
19474 }
19475 else
19476 {
19477 line = 1;
19478 linepos = BUF_BEGV (b);
19479 linepos_byte = BUF_BEGV_BYTE (b);
19480 }
19481
19482 /* Count lines from base line to window start position. */
19483 nlines = display_count_lines (linepos_byte,
19484 startpos_byte,
19485 startpos, &junk);
19486
19487 topline = nlines + line;
19488
19489 /* Determine a new base line, if the old one is too close
19490 or too far away, or if we did not have one.
19491 "Too close" means it's plausible a scroll-down would
19492 go back past it. */
19493 if (startpos == BUF_BEGV (b))
19494 {
19495 w->base_line_number = make_number (topline);
19496 w->base_line_pos = make_number (BUF_BEGV (b));
19497 }
19498 else if (nlines < height + 25 || nlines > height * 3 + 50
19499 || linepos == BUF_BEGV (b))
19500 {
19501 EMACS_INT limit = BUF_BEGV (b);
19502 EMACS_INT limit_byte = BUF_BEGV_BYTE (b);
19503 EMACS_INT position;
19504 int distance = (height * 2 + 30) * line_number_display_limit_width;
19505
19506 if (startpos - distance > limit)
19507 {
19508 limit = startpos - distance;
19509 limit_byte = CHAR_TO_BYTE (limit);
19510 }
19511
19512 nlines = display_count_lines (startpos_byte,
19513 limit_byte,
19514 - (height * 2 + 30),
19515 &position);
19516 /* If we couldn't find the lines we wanted within
19517 line_number_display_limit_width chars per line,
19518 give up on line numbers for this window. */
19519 if (position == limit_byte && limit == startpos - distance)
19520 {
19521 w->base_line_pos = w->buffer;
19522 w->base_line_number = Qnil;
19523 goto no_value;
19524 }
19525
19526 w->base_line_number = make_number (topline - nlines);
19527 w->base_line_pos = make_number (BYTE_TO_CHAR (position));
19528 }
19529
19530 /* Now count lines from the start pos to point. */
19531 nlines = display_count_lines (startpos_byte,
19532 PT_BYTE, PT, &junk);
19533
19534 /* Record that we did display the line number. */
19535 line_number_displayed = 1;
19536
19537 /* Make the string to show. */
19538 pint2str (decode_mode_spec_buf, field_width, topline + nlines);
19539 return decode_mode_spec_buf;
19540 no_value:
19541 {
19542 char* p = decode_mode_spec_buf;
19543 int pad = field_width - 2;
19544 while (pad-- > 0)
19545 *p++ = ' ';
19546 *p++ = '?';
19547 *p++ = '?';
19548 *p = '\0';
19549 return decode_mode_spec_buf;
19550 }
19551 }
19552 break;
19553
19554 case 'm':
19555 obj = BVAR (b, mode_name);
19556 break;
19557
19558 case 'n':
19559 if (BUF_BEGV (b) > BUF_BEG (b) || BUF_ZV (b) < BUF_Z (b))
19560 return " Narrow";
19561 break;
19562
19563 case 'p':
19564 {
19565 EMACS_INT pos = marker_position (w->start);
19566 EMACS_INT total = BUF_ZV (b) - BUF_BEGV (b);
19567
19568 if (XFASTINT (w->window_end_pos) <= BUF_Z (b) - BUF_ZV (b))
19569 {
19570 if (pos <= BUF_BEGV (b))
19571 return "All";
19572 else
19573 return "Bottom";
19574 }
19575 else if (pos <= BUF_BEGV (b))
19576 return "Top";
19577 else
19578 {
19579 if (total > 1000000)
19580 /* Do it differently for a large value, to avoid overflow. */
19581 total = ((pos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
19582 else
19583 total = ((pos - BUF_BEGV (b)) * 100 + total - 1) / total;
19584 /* We can't normally display a 3-digit number,
19585 so get us a 2-digit number that is close. */
19586 if (total == 100)
19587 total = 99;
19588 sprintf (decode_mode_spec_buf, "%2ld%%", (long)total);
19589 return decode_mode_spec_buf;
19590 }
19591 }
19592
19593 /* Display percentage of size above the bottom of the screen. */
19594 case 'P':
19595 {
19596 EMACS_INT toppos = marker_position (w->start);
19597 EMACS_INT botpos = BUF_Z (b) - XFASTINT (w->window_end_pos);
19598 EMACS_INT total = BUF_ZV (b) - BUF_BEGV (b);
19599
19600 if (botpos >= BUF_ZV (b))
19601 {
19602 if (toppos <= BUF_BEGV (b))
19603 return "All";
19604 else
19605 return "Bottom";
19606 }
19607 else
19608 {
19609 if (total > 1000000)
19610 /* Do it differently for a large value, to avoid overflow. */
19611 total = ((botpos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
19612 else
19613 total = ((botpos - BUF_BEGV (b)) * 100 + total - 1) / total;
19614 /* We can't normally display a 3-digit number,
19615 so get us a 2-digit number that is close. */
19616 if (total == 100)
19617 total = 99;
19618 if (toppos <= BUF_BEGV (b))
19619 sprintf (decode_mode_spec_buf, "Top%2ld%%", (long)total);
19620 else
19621 sprintf (decode_mode_spec_buf, "%2ld%%", (long)total);
19622 return decode_mode_spec_buf;
19623 }
19624 }
19625
19626 case 's':
19627 /* status of process */
19628 obj = Fget_buffer_process (Fcurrent_buffer ());
19629 if (NILP (obj))
19630 return "no process";
19631 #ifndef MSDOS
19632 obj = Fsymbol_name (Fprocess_status (obj));
19633 #endif
19634 break;
19635
19636 case '@':
19637 {
19638 int count = inhibit_garbage_collection ();
19639 Lisp_Object val = call1 (intern ("file-remote-p"),
19640 BVAR (current_buffer, directory));
19641 unbind_to (count, Qnil);
19642
19643 if (NILP (val))
19644 return "-";
19645 else
19646 return "@";
19647 }
19648
19649 case 't': /* indicate TEXT or BINARY */
19650 return "T";
19651
19652 case 'z':
19653 /* coding-system (not including end-of-line format) */
19654 case 'Z':
19655 /* coding-system (including end-of-line type) */
19656 {
19657 int eol_flag = (c == 'Z');
19658 char *p = decode_mode_spec_buf;
19659
19660 if (! FRAME_WINDOW_P (f))
19661 {
19662 /* No need to mention EOL here--the terminal never needs
19663 to do EOL conversion. */
19664 p = decode_mode_spec_coding (CODING_ID_NAME
19665 (FRAME_KEYBOARD_CODING (f)->id),
19666 p, 0);
19667 p = decode_mode_spec_coding (CODING_ID_NAME
19668 (FRAME_TERMINAL_CODING (f)->id),
19669 p, 0);
19670 }
19671 p = decode_mode_spec_coding (BVAR (b, buffer_file_coding_system),
19672 p, eol_flag);
19673
19674 #if 0 /* This proves to be annoying; I think we can do without. -- rms. */
19675 #ifdef subprocesses
19676 obj = Fget_buffer_process (Fcurrent_buffer ());
19677 if (PROCESSP (obj))
19678 {
19679 p = decode_mode_spec_coding (XPROCESS (obj)->decode_coding_system,
19680 p, eol_flag);
19681 p = decode_mode_spec_coding (XPROCESS (obj)->encode_coding_system,
19682 p, eol_flag);
19683 }
19684 #endif /* subprocesses */
19685 #endif /* 0 */
19686 *p = 0;
19687 return decode_mode_spec_buf;
19688 }
19689 }
19690
19691 if (STRINGP (obj))
19692 {
19693 *string = obj;
19694 return SSDATA (obj);
19695 }
19696 else
19697 return "";
19698 }
19699
19700
19701 /* Count up to COUNT lines starting from START_BYTE.
19702 But don't go beyond LIMIT_BYTE.
19703 Return the number of lines thus found (always nonnegative).
19704
19705 Set *BYTE_POS_PTR to 1 if we found COUNT lines, 0 if we hit LIMIT. */
19706
19707 static int
19708 display_count_lines (EMACS_INT start_byte,
19709 EMACS_INT limit_byte, int count,
19710 EMACS_INT *byte_pos_ptr)
19711 {
19712 register unsigned char *cursor;
19713 unsigned char *base;
19714
19715 register int ceiling;
19716 register unsigned char *ceiling_addr;
19717 int orig_count = count;
19718
19719 /* If we are not in selective display mode,
19720 check only for newlines. */
19721 int selective_display = (!NILP (BVAR (current_buffer, selective_display))
19722 && !INTEGERP (BVAR (current_buffer, selective_display)));
19723
19724 if (count > 0)
19725 {
19726 while (start_byte < limit_byte)
19727 {
19728 ceiling = BUFFER_CEILING_OF (start_byte);
19729 ceiling = min (limit_byte - 1, ceiling);
19730 ceiling_addr = BYTE_POS_ADDR (ceiling) + 1;
19731 base = (cursor = BYTE_POS_ADDR (start_byte));
19732 while (1)
19733 {
19734 if (selective_display)
19735 while (*cursor != '\n' && *cursor != 015 && ++cursor != ceiling_addr)
19736 ;
19737 else
19738 while (*cursor != '\n' && ++cursor != ceiling_addr)
19739 ;
19740
19741 if (cursor != ceiling_addr)
19742 {
19743 if (--count == 0)
19744 {
19745 start_byte += cursor - base + 1;
19746 *byte_pos_ptr = start_byte;
19747 return orig_count;
19748 }
19749 else
19750 if (++cursor == ceiling_addr)
19751 break;
19752 }
19753 else
19754 break;
19755 }
19756 start_byte += cursor - base;
19757 }
19758 }
19759 else
19760 {
19761 while (start_byte > limit_byte)
19762 {
19763 ceiling = BUFFER_FLOOR_OF (start_byte - 1);
19764 ceiling = max (limit_byte, ceiling);
19765 ceiling_addr = BYTE_POS_ADDR (ceiling) - 1;
19766 base = (cursor = BYTE_POS_ADDR (start_byte - 1) + 1);
19767 while (1)
19768 {
19769 if (selective_display)
19770 while (--cursor != ceiling_addr
19771 && *cursor != '\n' && *cursor != 015)
19772 ;
19773 else
19774 while (--cursor != ceiling_addr && *cursor != '\n')
19775 ;
19776
19777 if (cursor != ceiling_addr)
19778 {
19779 if (++count == 0)
19780 {
19781 start_byte += cursor - base + 1;
19782 *byte_pos_ptr = start_byte;
19783 /* When scanning backwards, we should
19784 not count the newline posterior to which we stop. */
19785 return - orig_count - 1;
19786 }
19787 }
19788 else
19789 break;
19790 }
19791 /* Here we add 1 to compensate for the last decrement
19792 of CURSOR, which took it past the valid range. */
19793 start_byte += cursor - base + 1;
19794 }
19795 }
19796
19797 *byte_pos_ptr = limit_byte;
19798
19799 if (count < 0)
19800 return - orig_count + count;
19801 return orig_count - count;
19802
19803 }
19804
19805
19806 \f
19807 /***********************************************************************
19808 Displaying strings
19809 ***********************************************************************/
19810
19811 /* Display a NUL-terminated string, starting with index START.
19812
19813 If STRING is non-null, display that C string. Otherwise, the Lisp
19814 string LISP_STRING is displayed. There's a case that STRING is
19815 non-null and LISP_STRING is not nil. It means STRING is a string
19816 data of LISP_STRING. In that case, we display LISP_STRING while
19817 ignoring its text properties.
19818
19819 If FACE_STRING is not nil, FACE_STRING_POS is a position in
19820 FACE_STRING. Display STRING or LISP_STRING with the face at
19821 FACE_STRING_POS in FACE_STRING:
19822
19823 Display the string in the environment given by IT, but use the
19824 standard display table, temporarily.
19825
19826 FIELD_WIDTH is the minimum number of output glyphs to produce.
19827 If STRING has fewer characters than FIELD_WIDTH, pad to the right
19828 with spaces. If STRING has more characters, more than FIELD_WIDTH
19829 glyphs will be produced. FIELD_WIDTH <= 0 means don't pad.
19830
19831 PRECISION is the maximum number of characters to output from
19832 STRING. PRECISION < 0 means don't truncate the string.
19833
19834 This is roughly equivalent to printf format specifiers:
19835
19836 FIELD_WIDTH PRECISION PRINTF
19837 ----------------------------------------
19838 -1 -1 %s
19839 -1 10 %.10s
19840 10 -1 %10s
19841 20 10 %20.10s
19842
19843 MULTIBYTE zero means do not display multibyte chars, > 0 means do
19844 display them, and < 0 means obey the current buffer's value of
19845 enable_multibyte_characters.
19846
19847 Value is the number of columns displayed. */
19848
19849 static int
19850 display_string (const char *string, Lisp_Object lisp_string, Lisp_Object face_string,
19851 EMACS_INT face_string_pos, EMACS_INT start, struct it *it,
19852 int field_width, int precision, int max_x, int multibyte)
19853 {
19854 int hpos_at_start = it->hpos;
19855 int saved_face_id = it->face_id;
19856 struct glyph_row *row = it->glyph_row;
19857
19858 /* Initialize the iterator IT for iteration over STRING beginning
19859 with index START. */
19860 reseat_to_string (it, NILP (lisp_string) ? string : NULL, lisp_string, start,
19861 precision, field_width, multibyte);
19862 if (string && STRINGP (lisp_string))
19863 /* LISP_STRING is the one returned by decode_mode_spec. We should
19864 ignore its text properties. */
19865 it->stop_charpos = -1;
19866
19867 /* If displaying STRING, set up the face of the iterator
19868 from LISP_STRING, if that's given. */
19869 if (STRINGP (face_string))
19870 {
19871 EMACS_INT endptr;
19872 struct face *face;
19873
19874 it->face_id
19875 = face_at_string_position (it->w, face_string, face_string_pos,
19876 0, it->region_beg_charpos,
19877 it->region_end_charpos,
19878 &endptr, it->base_face_id, 0);
19879 face = FACE_FROM_ID (it->f, it->face_id);
19880 it->face_box_p = face->box != FACE_NO_BOX;
19881 }
19882
19883 /* Set max_x to the maximum allowed X position. Don't let it go
19884 beyond the right edge of the window. */
19885 if (max_x <= 0)
19886 max_x = it->last_visible_x;
19887 else
19888 max_x = min (max_x, it->last_visible_x);
19889
19890 /* Skip over display elements that are not visible. because IT->w is
19891 hscrolled. */
19892 if (it->current_x < it->first_visible_x)
19893 move_it_in_display_line_to (it, 100000, it->first_visible_x,
19894 MOVE_TO_POS | MOVE_TO_X);
19895
19896 row->ascent = it->max_ascent;
19897 row->height = it->max_ascent + it->max_descent;
19898 row->phys_ascent = it->max_phys_ascent;
19899 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
19900 row->extra_line_spacing = it->max_extra_line_spacing;
19901
19902 /* This condition is for the case that we are called with current_x
19903 past last_visible_x. */
19904 while (it->current_x < max_x)
19905 {
19906 int x_before, x, n_glyphs_before, i, nglyphs;
19907
19908 /* Get the next display element. */
19909 if (!get_next_display_element (it))
19910 break;
19911
19912 /* Produce glyphs. */
19913 x_before = it->current_x;
19914 n_glyphs_before = it->glyph_row->used[TEXT_AREA];
19915 PRODUCE_GLYPHS (it);
19916
19917 nglyphs = it->glyph_row->used[TEXT_AREA] - n_glyphs_before;
19918 i = 0;
19919 x = x_before;
19920 while (i < nglyphs)
19921 {
19922 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
19923
19924 if (it->line_wrap != TRUNCATE
19925 && x + glyph->pixel_width > max_x)
19926 {
19927 /* End of continued line or max_x reached. */
19928 if (CHAR_GLYPH_PADDING_P (*glyph))
19929 {
19930 /* A wide character is unbreakable. */
19931 it->glyph_row->used[TEXT_AREA] = n_glyphs_before;
19932 it->current_x = x_before;
19933 }
19934 else
19935 {
19936 it->glyph_row->used[TEXT_AREA] = n_glyphs_before + i;
19937 it->current_x = x;
19938 }
19939 break;
19940 }
19941 else if (x + glyph->pixel_width >= it->first_visible_x)
19942 {
19943 /* Glyph is at least partially visible. */
19944 ++it->hpos;
19945 if (x < it->first_visible_x)
19946 it->glyph_row->x = x - it->first_visible_x;
19947 }
19948 else
19949 {
19950 /* Glyph is off the left margin of the display area.
19951 Should not happen. */
19952 abort ();
19953 }
19954
19955 row->ascent = max (row->ascent, it->max_ascent);
19956 row->height = max (row->height, it->max_ascent + it->max_descent);
19957 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
19958 row->phys_height = max (row->phys_height,
19959 it->max_phys_ascent + it->max_phys_descent);
19960 row->extra_line_spacing = max (row->extra_line_spacing,
19961 it->max_extra_line_spacing);
19962 x += glyph->pixel_width;
19963 ++i;
19964 }
19965
19966 /* Stop if max_x reached. */
19967 if (i < nglyphs)
19968 break;
19969
19970 /* Stop at line ends. */
19971 if (ITERATOR_AT_END_OF_LINE_P (it))
19972 {
19973 it->continuation_lines_width = 0;
19974 break;
19975 }
19976
19977 set_iterator_to_next (it, 1);
19978
19979 /* Stop if truncating at the right edge. */
19980 if (it->line_wrap == TRUNCATE
19981 && it->current_x >= it->last_visible_x)
19982 {
19983 /* Add truncation mark, but don't do it if the line is
19984 truncated at a padding space. */
19985 if (IT_CHARPOS (*it) < it->string_nchars)
19986 {
19987 if (!FRAME_WINDOW_P (it->f))
19988 {
19989 int ii, n;
19990
19991 if (it->current_x > it->last_visible_x)
19992 {
19993 for (ii = row->used[TEXT_AREA] - 1; ii > 0; --ii)
19994 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][ii]))
19995 break;
19996 for (n = row->used[TEXT_AREA]; ii < n; ++ii)
19997 {
19998 row->used[TEXT_AREA] = ii;
19999 produce_special_glyphs (it, IT_TRUNCATION);
20000 }
20001 }
20002 produce_special_glyphs (it, IT_TRUNCATION);
20003 }
20004 it->glyph_row->truncated_on_right_p = 1;
20005 }
20006 break;
20007 }
20008 }
20009
20010 /* Maybe insert a truncation at the left. */
20011 if (it->first_visible_x
20012 && IT_CHARPOS (*it) > 0)
20013 {
20014 if (!FRAME_WINDOW_P (it->f))
20015 insert_left_trunc_glyphs (it);
20016 it->glyph_row->truncated_on_left_p = 1;
20017 }
20018
20019 it->face_id = saved_face_id;
20020
20021 /* Value is number of columns displayed. */
20022 return it->hpos - hpos_at_start;
20023 }
20024
20025
20026 \f
20027 /* This is like a combination of memq and assq. Return 1/2 if PROPVAL
20028 appears as an element of LIST or as the car of an element of LIST.
20029 If PROPVAL is a list, compare each element against LIST in that
20030 way, and return 1/2 if any element of PROPVAL is found in LIST.
20031 Otherwise return 0. This function cannot quit.
20032 The return value is 2 if the text is invisible but with an ellipsis
20033 and 1 if it's invisible and without an ellipsis. */
20034
20035 int
20036 invisible_p (register Lisp_Object propval, Lisp_Object list)
20037 {
20038 register Lisp_Object tail, proptail;
20039
20040 for (tail = list; CONSP (tail); tail = XCDR (tail))
20041 {
20042 register Lisp_Object tem;
20043 tem = XCAR (tail);
20044 if (EQ (propval, tem))
20045 return 1;
20046 if (CONSP (tem) && EQ (propval, XCAR (tem)))
20047 return NILP (XCDR (tem)) ? 1 : 2;
20048 }
20049
20050 if (CONSP (propval))
20051 {
20052 for (proptail = propval; CONSP (proptail); proptail = XCDR (proptail))
20053 {
20054 Lisp_Object propelt;
20055 propelt = XCAR (proptail);
20056 for (tail = list; CONSP (tail); tail = XCDR (tail))
20057 {
20058 register Lisp_Object tem;
20059 tem = XCAR (tail);
20060 if (EQ (propelt, tem))
20061 return 1;
20062 if (CONSP (tem) && EQ (propelt, XCAR (tem)))
20063 return NILP (XCDR (tem)) ? 1 : 2;
20064 }
20065 }
20066 }
20067
20068 return 0;
20069 }
20070
20071 DEFUN ("invisible-p", Finvisible_p, Sinvisible_p, 1, 1, 0,
20072 doc: /* Non-nil if the property makes the text invisible.
20073 POS-OR-PROP can be a marker or number, in which case it is taken to be
20074 a position in the current buffer and the value of the `invisible' property
20075 is checked; or it can be some other value, which is then presumed to be the
20076 value of the `invisible' property of the text of interest.
20077 The non-nil value returned can be t for truly invisible text or something
20078 else if the text is replaced by an ellipsis. */)
20079 (Lisp_Object pos_or_prop)
20080 {
20081 Lisp_Object prop
20082 = (NATNUMP (pos_or_prop) || MARKERP (pos_or_prop)
20083 ? Fget_char_property (pos_or_prop, Qinvisible, Qnil)
20084 : pos_or_prop);
20085 int invis = TEXT_PROP_MEANS_INVISIBLE (prop);
20086 return (invis == 0 ? Qnil
20087 : invis == 1 ? Qt
20088 : make_number (invis));
20089 }
20090
20091 /* Calculate a width or height in pixels from a specification using
20092 the following elements:
20093
20094 SPEC ::=
20095 NUM - a (fractional) multiple of the default font width/height
20096 (NUM) - specifies exactly NUM pixels
20097 UNIT - a fixed number of pixels, see below.
20098 ELEMENT - size of a display element in pixels, see below.
20099 (NUM . SPEC) - equals NUM * SPEC
20100 (+ SPEC SPEC ...) - add pixel values
20101 (- SPEC SPEC ...) - subtract pixel values
20102 (- SPEC) - negate pixel value
20103
20104 NUM ::=
20105 INT or FLOAT - a number constant
20106 SYMBOL - use symbol's (buffer local) variable binding.
20107
20108 UNIT ::=
20109 in - pixels per inch *)
20110 mm - pixels per 1/1000 meter *)
20111 cm - pixels per 1/100 meter *)
20112 width - width of current font in pixels.
20113 height - height of current font in pixels.
20114
20115 *) using the ratio(s) defined in display-pixels-per-inch.
20116
20117 ELEMENT ::=
20118
20119 left-fringe - left fringe width in pixels
20120 right-fringe - right fringe width in pixels
20121
20122 left-margin - left margin width in pixels
20123 right-margin - right margin width in pixels
20124
20125 scroll-bar - scroll-bar area width in pixels
20126
20127 Examples:
20128
20129 Pixels corresponding to 5 inches:
20130 (5 . in)
20131
20132 Total width of non-text areas on left side of window (if scroll-bar is on left):
20133 '(space :width (+ left-fringe left-margin scroll-bar))
20134
20135 Align to first text column (in header line):
20136 '(space :align-to 0)
20137
20138 Align to middle of text area minus half the width of variable `my-image'
20139 containing a loaded image:
20140 '(space :align-to (0.5 . (- text my-image)))
20141
20142 Width of left margin minus width of 1 character in the default font:
20143 '(space :width (- left-margin 1))
20144
20145 Width of left margin minus width of 2 characters in the current font:
20146 '(space :width (- left-margin (2 . width)))
20147
20148 Center 1 character over left-margin (in header line):
20149 '(space :align-to (+ left-margin (0.5 . left-margin) -0.5))
20150
20151 Different ways to express width of left fringe plus left margin minus one pixel:
20152 '(space :width (- (+ left-fringe left-margin) (1)))
20153 '(space :width (+ left-fringe left-margin (- (1))))
20154 '(space :width (+ left-fringe left-margin (-1)))
20155
20156 */
20157
20158 #define NUMVAL(X) \
20159 ((INTEGERP (X) || FLOATP (X)) \
20160 ? XFLOATINT (X) \
20161 : - 1)
20162
20163 int
20164 calc_pixel_width_or_height (double *res, struct it *it, Lisp_Object prop,
20165 struct font *font, int width_p, int *align_to)
20166 {
20167 double pixels;
20168
20169 #define OK_PIXELS(val) ((*res = (double)(val)), 1)
20170 #define OK_ALIGN_TO(val) ((*align_to = (int)(val)), 1)
20171
20172 if (NILP (prop))
20173 return OK_PIXELS (0);
20174
20175 xassert (FRAME_LIVE_P (it->f));
20176
20177 if (SYMBOLP (prop))
20178 {
20179 if (SCHARS (SYMBOL_NAME (prop)) == 2)
20180 {
20181 char *unit = SSDATA (SYMBOL_NAME (prop));
20182
20183 if (unit[0] == 'i' && unit[1] == 'n')
20184 pixels = 1.0;
20185 else if (unit[0] == 'm' && unit[1] == 'm')
20186 pixels = 25.4;
20187 else if (unit[0] == 'c' && unit[1] == 'm')
20188 pixels = 2.54;
20189 else
20190 pixels = 0;
20191 if (pixels > 0)
20192 {
20193 double ppi;
20194 #ifdef HAVE_WINDOW_SYSTEM
20195 if (FRAME_WINDOW_P (it->f)
20196 && (ppi = (width_p
20197 ? FRAME_X_DISPLAY_INFO (it->f)->resx
20198 : FRAME_X_DISPLAY_INFO (it->f)->resy),
20199 ppi > 0))
20200 return OK_PIXELS (ppi / pixels);
20201 #endif
20202
20203 if ((ppi = NUMVAL (Vdisplay_pixels_per_inch), ppi > 0)
20204 || (CONSP (Vdisplay_pixels_per_inch)
20205 && (ppi = (width_p
20206 ? NUMVAL (XCAR (Vdisplay_pixels_per_inch))
20207 : NUMVAL (XCDR (Vdisplay_pixels_per_inch))),
20208 ppi > 0)))
20209 return OK_PIXELS (ppi / pixels);
20210
20211 return 0;
20212 }
20213 }
20214
20215 #ifdef HAVE_WINDOW_SYSTEM
20216 if (EQ (prop, Qheight))
20217 return OK_PIXELS (font ? FONT_HEIGHT (font) : FRAME_LINE_HEIGHT (it->f));
20218 if (EQ (prop, Qwidth))
20219 return OK_PIXELS (font ? FONT_WIDTH (font) : FRAME_COLUMN_WIDTH (it->f));
20220 #else
20221 if (EQ (prop, Qheight) || EQ (prop, Qwidth))
20222 return OK_PIXELS (1);
20223 #endif
20224
20225 if (EQ (prop, Qtext))
20226 return OK_PIXELS (width_p
20227 ? window_box_width (it->w, TEXT_AREA)
20228 : WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w));
20229
20230 if (align_to && *align_to < 0)
20231 {
20232 *res = 0;
20233 if (EQ (prop, Qleft))
20234 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA));
20235 if (EQ (prop, Qright))
20236 return OK_ALIGN_TO (window_box_right_offset (it->w, TEXT_AREA));
20237 if (EQ (prop, Qcenter))
20238 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA)
20239 + window_box_width (it->w, TEXT_AREA) / 2);
20240 if (EQ (prop, Qleft_fringe))
20241 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
20242 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (it->w)
20243 : window_box_right_offset (it->w, LEFT_MARGIN_AREA));
20244 if (EQ (prop, Qright_fringe))
20245 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
20246 ? window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
20247 : window_box_right_offset (it->w, TEXT_AREA));
20248 if (EQ (prop, Qleft_margin))
20249 return OK_ALIGN_TO (window_box_left_offset (it->w, LEFT_MARGIN_AREA));
20250 if (EQ (prop, Qright_margin))
20251 return OK_ALIGN_TO (window_box_left_offset (it->w, RIGHT_MARGIN_AREA));
20252 if (EQ (prop, Qscroll_bar))
20253 return OK_ALIGN_TO (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (it->w)
20254 ? 0
20255 : (window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
20256 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
20257 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
20258 : 0)));
20259 }
20260 else
20261 {
20262 if (EQ (prop, Qleft_fringe))
20263 return OK_PIXELS (WINDOW_LEFT_FRINGE_WIDTH (it->w));
20264 if (EQ (prop, Qright_fringe))
20265 return OK_PIXELS (WINDOW_RIGHT_FRINGE_WIDTH (it->w));
20266 if (EQ (prop, Qleft_margin))
20267 return OK_PIXELS (WINDOW_LEFT_MARGIN_WIDTH (it->w));
20268 if (EQ (prop, Qright_margin))
20269 return OK_PIXELS (WINDOW_RIGHT_MARGIN_WIDTH (it->w));
20270 if (EQ (prop, Qscroll_bar))
20271 return OK_PIXELS (WINDOW_SCROLL_BAR_AREA_WIDTH (it->w));
20272 }
20273
20274 prop = Fbuffer_local_value (prop, it->w->buffer);
20275 }
20276
20277 if (INTEGERP (prop) || FLOATP (prop))
20278 {
20279 int base_unit = (width_p
20280 ? FRAME_COLUMN_WIDTH (it->f)
20281 : FRAME_LINE_HEIGHT (it->f));
20282 return OK_PIXELS (XFLOATINT (prop) * base_unit);
20283 }
20284
20285 if (CONSP (prop))
20286 {
20287 Lisp_Object car = XCAR (prop);
20288 Lisp_Object cdr = XCDR (prop);
20289
20290 if (SYMBOLP (car))
20291 {
20292 #ifdef HAVE_WINDOW_SYSTEM
20293 if (FRAME_WINDOW_P (it->f)
20294 && valid_image_p (prop))
20295 {
20296 int id = lookup_image (it->f, prop);
20297 struct image *img = IMAGE_FROM_ID (it->f, id);
20298
20299 return OK_PIXELS (width_p ? img->width : img->height);
20300 }
20301 #endif
20302 if (EQ (car, Qplus) || EQ (car, Qminus))
20303 {
20304 int first = 1;
20305 double px;
20306
20307 pixels = 0;
20308 while (CONSP (cdr))
20309 {
20310 if (!calc_pixel_width_or_height (&px, it, XCAR (cdr),
20311 font, width_p, align_to))
20312 return 0;
20313 if (first)
20314 pixels = (EQ (car, Qplus) ? px : -px), first = 0;
20315 else
20316 pixels += px;
20317 cdr = XCDR (cdr);
20318 }
20319 if (EQ (car, Qminus))
20320 pixels = -pixels;
20321 return OK_PIXELS (pixels);
20322 }
20323
20324 car = Fbuffer_local_value (car, it->w->buffer);
20325 }
20326
20327 if (INTEGERP (car) || FLOATP (car))
20328 {
20329 double fact;
20330 pixels = XFLOATINT (car);
20331 if (NILP (cdr))
20332 return OK_PIXELS (pixels);
20333 if (calc_pixel_width_or_height (&fact, it, cdr,
20334 font, width_p, align_to))
20335 return OK_PIXELS (pixels * fact);
20336 return 0;
20337 }
20338
20339 return 0;
20340 }
20341
20342 return 0;
20343 }
20344
20345 \f
20346 /***********************************************************************
20347 Glyph Display
20348 ***********************************************************************/
20349
20350 #ifdef HAVE_WINDOW_SYSTEM
20351
20352 #if GLYPH_DEBUG
20353
20354 void
20355 dump_glyph_string (s)
20356 struct glyph_string *s;
20357 {
20358 fprintf (stderr, "glyph string\n");
20359 fprintf (stderr, " x, y, w, h = %d, %d, %d, %d\n",
20360 s->x, s->y, s->width, s->height);
20361 fprintf (stderr, " ybase = %d\n", s->ybase);
20362 fprintf (stderr, " hl = %d\n", s->hl);
20363 fprintf (stderr, " left overhang = %d, right = %d\n",
20364 s->left_overhang, s->right_overhang);
20365 fprintf (stderr, " nchars = %d\n", s->nchars);
20366 fprintf (stderr, " extends to end of line = %d\n",
20367 s->extends_to_end_of_line_p);
20368 fprintf (stderr, " font height = %d\n", FONT_HEIGHT (s->font));
20369 fprintf (stderr, " bg width = %d\n", s->background_width);
20370 }
20371
20372 #endif /* GLYPH_DEBUG */
20373
20374 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
20375 of XChar2b structures for S; it can't be allocated in
20376 init_glyph_string because it must be allocated via `alloca'. W
20377 is the window on which S is drawn. ROW and AREA are the glyph row
20378 and area within the row from which S is constructed. START is the
20379 index of the first glyph structure covered by S. HL is a
20380 face-override for drawing S. */
20381
20382 #ifdef HAVE_NTGUI
20383 #define OPTIONAL_HDC(hdc) HDC hdc,
20384 #define DECLARE_HDC(hdc) HDC hdc;
20385 #define ALLOCATE_HDC(hdc, f) hdc = get_frame_dc ((f))
20386 #define RELEASE_HDC(hdc, f) release_frame_dc ((f), (hdc))
20387 #endif
20388
20389 #ifndef OPTIONAL_HDC
20390 #define OPTIONAL_HDC(hdc)
20391 #define DECLARE_HDC(hdc)
20392 #define ALLOCATE_HDC(hdc, f)
20393 #define RELEASE_HDC(hdc, f)
20394 #endif
20395
20396 static void
20397 init_glyph_string (struct glyph_string *s,
20398 OPTIONAL_HDC (hdc)
20399 XChar2b *char2b, struct window *w, struct glyph_row *row,
20400 enum glyph_row_area area, int start, enum draw_glyphs_face hl)
20401 {
20402 memset (s, 0, sizeof *s);
20403 s->w = w;
20404 s->f = XFRAME (w->frame);
20405 #ifdef HAVE_NTGUI
20406 s->hdc = hdc;
20407 #endif
20408 s->display = FRAME_X_DISPLAY (s->f);
20409 s->window = FRAME_X_WINDOW (s->f);
20410 s->char2b = char2b;
20411 s->hl = hl;
20412 s->row = row;
20413 s->area = area;
20414 s->first_glyph = row->glyphs[area] + start;
20415 s->height = row->height;
20416 s->y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
20417 s->ybase = s->y + row->ascent;
20418 }
20419
20420
20421 /* Append the list of glyph strings with head H and tail T to the list
20422 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
20423
20424 static INLINE void
20425 append_glyph_string_lists (struct glyph_string **head, struct glyph_string **tail,
20426 struct glyph_string *h, struct glyph_string *t)
20427 {
20428 if (h)
20429 {
20430 if (*head)
20431 (*tail)->next = h;
20432 else
20433 *head = h;
20434 h->prev = *tail;
20435 *tail = t;
20436 }
20437 }
20438
20439
20440 /* Prepend the list of glyph strings with head H and tail T to the
20441 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
20442 result. */
20443
20444 static INLINE void
20445 prepend_glyph_string_lists (struct glyph_string **head, struct glyph_string **tail,
20446 struct glyph_string *h, struct glyph_string *t)
20447 {
20448 if (h)
20449 {
20450 if (*head)
20451 (*head)->prev = t;
20452 else
20453 *tail = t;
20454 t->next = *head;
20455 *head = h;
20456 }
20457 }
20458
20459
20460 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
20461 Set *HEAD and *TAIL to the resulting list. */
20462
20463 static INLINE void
20464 append_glyph_string (struct glyph_string **head, struct glyph_string **tail,
20465 struct glyph_string *s)
20466 {
20467 s->next = s->prev = NULL;
20468 append_glyph_string_lists (head, tail, s, s);
20469 }
20470
20471
20472 /* Get face and two-byte form of character C in face FACE_ID on frame F.
20473 The encoding of C is returned in *CHAR2B. DISPLAY_P non-zero means
20474 make sure that X resources for the face returned are allocated.
20475 Value is a pointer to a realized face that is ready for display if
20476 DISPLAY_P is non-zero. */
20477
20478 static INLINE struct face *
20479 get_char_face_and_encoding (struct frame *f, int c, int face_id,
20480 XChar2b *char2b, int display_p)
20481 {
20482 struct face *face = FACE_FROM_ID (f, face_id);
20483
20484 if (face->font)
20485 {
20486 unsigned code = face->font->driver->encode_char (face->font, c);
20487
20488 if (code != FONT_INVALID_CODE)
20489 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
20490 else
20491 STORE_XCHAR2B (char2b, 0, 0);
20492 }
20493
20494 /* Make sure X resources of the face are allocated. */
20495 #ifdef HAVE_X_WINDOWS
20496 if (display_p)
20497 #endif
20498 {
20499 xassert (face != NULL);
20500 PREPARE_FACE_FOR_DISPLAY (f, face);
20501 }
20502
20503 return face;
20504 }
20505
20506
20507 /* Get face and two-byte form of character glyph GLYPH on frame F.
20508 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
20509 a pointer to a realized face that is ready for display. */
20510
20511 static INLINE struct face *
20512 get_glyph_face_and_encoding (struct frame *f, struct glyph *glyph,
20513 XChar2b *char2b, int *two_byte_p)
20514 {
20515 struct face *face;
20516
20517 xassert (glyph->type == CHAR_GLYPH);
20518 face = FACE_FROM_ID (f, glyph->face_id);
20519
20520 if (two_byte_p)
20521 *two_byte_p = 0;
20522
20523 if (face->font)
20524 {
20525 unsigned code;
20526
20527 if (CHAR_BYTE8_P (glyph->u.ch))
20528 code = CHAR_TO_BYTE8 (glyph->u.ch);
20529 else
20530 code = face->font->driver->encode_char (face->font, glyph->u.ch);
20531
20532 if (code != FONT_INVALID_CODE)
20533 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
20534 else
20535 STORE_XCHAR2B (char2b, 0, 0);
20536 }
20537
20538 /* Make sure X resources of the face are allocated. */
20539 xassert (face != NULL);
20540 PREPARE_FACE_FOR_DISPLAY (f, face);
20541 return face;
20542 }
20543
20544
20545 /* Get glyph code of character C in FONT in the two-byte form CHAR2B.
20546 Retunr 1 if FONT has a glyph for C, otherwise return 0. */
20547
20548 static INLINE int
20549 get_char_glyph_code (int c, struct font *font, XChar2b *char2b)
20550 {
20551 unsigned code;
20552
20553 if (CHAR_BYTE8_P (c))
20554 code = CHAR_TO_BYTE8 (c);
20555 else
20556 code = font->driver->encode_char (font, c);
20557
20558 if (code == FONT_INVALID_CODE)
20559 return 0;
20560 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
20561 return 1;
20562 }
20563
20564
20565 /* Fill glyph string S with composition components specified by S->cmp.
20566
20567 BASE_FACE is the base face of the composition.
20568 S->cmp_from is the index of the first component for S.
20569
20570 OVERLAPS non-zero means S should draw the foreground only, and use
20571 its physical height for clipping. See also draw_glyphs.
20572
20573 Value is the index of a component not in S. */
20574
20575 static int
20576 fill_composite_glyph_string (struct glyph_string *s, struct face *base_face,
20577 int overlaps)
20578 {
20579 int i;
20580 /* For all glyphs of this composition, starting at the offset
20581 S->cmp_from, until we reach the end of the definition or encounter a
20582 glyph that requires the different face, add it to S. */
20583 struct face *face;
20584
20585 xassert (s);
20586
20587 s->for_overlaps = overlaps;
20588 s->face = NULL;
20589 s->font = NULL;
20590 for (i = s->cmp_from; i < s->cmp->glyph_len; i++)
20591 {
20592 int c = COMPOSITION_GLYPH (s->cmp, i);
20593
20594 if (c != '\t')
20595 {
20596 int face_id = FACE_FOR_CHAR (s->f, base_face->ascii_face, c,
20597 -1, Qnil);
20598
20599 face = get_char_face_and_encoding (s->f, c, face_id,
20600 s->char2b + i, 1);
20601 if (face)
20602 {
20603 if (! s->face)
20604 {
20605 s->face = face;
20606 s->font = s->face->font;
20607 }
20608 else if (s->face != face)
20609 break;
20610 }
20611 }
20612 ++s->nchars;
20613 }
20614 s->cmp_to = i;
20615
20616 /* All glyph strings for the same composition has the same width,
20617 i.e. the width set for the first component of the composition. */
20618 s->width = s->first_glyph->pixel_width;
20619
20620 /* If the specified font could not be loaded, use the frame's
20621 default font, but record the fact that we couldn't load it in
20622 the glyph string so that we can draw rectangles for the
20623 characters of the glyph string. */
20624 if (s->font == NULL)
20625 {
20626 s->font_not_found_p = 1;
20627 s->font = FRAME_FONT (s->f);
20628 }
20629
20630 /* Adjust base line for subscript/superscript text. */
20631 s->ybase += s->first_glyph->voffset;
20632
20633 /* This glyph string must always be drawn with 16-bit functions. */
20634 s->two_byte_p = 1;
20635
20636 return s->cmp_to;
20637 }
20638
20639 static int
20640 fill_gstring_glyph_string (struct glyph_string *s, int face_id,
20641 int start, int end, int overlaps)
20642 {
20643 struct glyph *glyph, *last;
20644 Lisp_Object lgstring;
20645 int i;
20646
20647 s->for_overlaps = overlaps;
20648 glyph = s->row->glyphs[s->area] + start;
20649 last = s->row->glyphs[s->area] + end;
20650 s->cmp_id = glyph->u.cmp.id;
20651 s->cmp_from = glyph->slice.cmp.from;
20652 s->cmp_to = glyph->slice.cmp.to + 1;
20653 s->face = FACE_FROM_ID (s->f, face_id);
20654 lgstring = composition_gstring_from_id (s->cmp_id);
20655 s->font = XFONT_OBJECT (LGSTRING_FONT (lgstring));
20656 glyph++;
20657 while (glyph < last
20658 && glyph->u.cmp.automatic
20659 && glyph->u.cmp.id == s->cmp_id
20660 && s->cmp_to == glyph->slice.cmp.from)
20661 s->cmp_to = (glyph++)->slice.cmp.to + 1;
20662
20663 for (i = s->cmp_from; i < s->cmp_to; i++)
20664 {
20665 Lisp_Object lglyph = LGSTRING_GLYPH (lgstring, i);
20666 unsigned code = LGLYPH_CODE (lglyph);
20667
20668 STORE_XCHAR2B ((s->char2b + i), code >> 8, code & 0xFF);
20669 }
20670 s->width = composition_gstring_width (lgstring, s->cmp_from, s->cmp_to, NULL);
20671 return glyph - s->row->glyphs[s->area];
20672 }
20673
20674
20675 /* Fill glyph string S from a sequence glyphs for glyphless characters.
20676 See the comment of fill_glyph_string for arguments.
20677 Value is the index of the first glyph not in S. */
20678
20679
20680 static int
20681 fill_glyphless_glyph_string (struct glyph_string *s, int face_id,
20682 int start, int end, int overlaps)
20683 {
20684 struct glyph *glyph, *last;
20685 int voffset;
20686
20687 xassert (s->first_glyph->type == GLYPHLESS_GLYPH);
20688 s->for_overlaps = overlaps;
20689 glyph = s->row->glyphs[s->area] + start;
20690 last = s->row->glyphs[s->area] + end;
20691 voffset = glyph->voffset;
20692 s->face = FACE_FROM_ID (s->f, face_id);
20693 s->font = s->face->font;
20694 s->nchars = 1;
20695 s->width = glyph->pixel_width;
20696 glyph++;
20697 while (glyph < last
20698 && glyph->type == GLYPHLESS_GLYPH
20699 && glyph->voffset == voffset
20700 && glyph->face_id == face_id)
20701 {
20702 s->nchars++;
20703 s->width += glyph->pixel_width;
20704 glyph++;
20705 }
20706 s->ybase += voffset;
20707 return glyph - s->row->glyphs[s->area];
20708 }
20709
20710
20711 /* Fill glyph string S from a sequence of character glyphs.
20712
20713 FACE_ID is the face id of the string. START is the index of the
20714 first glyph to consider, END is the index of the last + 1.
20715 OVERLAPS non-zero means S should draw the foreground only, and use
20716 its physical height for clipping. See also draw_glyphs.
20717
20718 Value is the index of the first glyph not in S. */
20719
20720 static int
20721 fill_glyph_string (struct glyph_string *s, int face_id,
20722 int start, int end, int overlaps)
20723 {
20724 struct glyph *glyph, *last;
20725 int voffset;
20726 int glyph_not_available_p;
20727
20728 xassert (s->f == XFRAME (s->w->frame));
20729 xassert (s->nchars == 0);
20730 xassert (start >= 0 && end > start);
20731
20732 s->for_overlaps = overlaps;
20733 glyph = s->row->glyphs[s->area] + start;
20734 last = s->row->glyphs[s->area] + end;
20735 voffset = glyph->voffset;
20736 s->padding_p = glyph->padding_p;
20737 glyph_not_available_p = glyph->glyph_not_available_p;
20738
20739 while (glyph < last
20740 && glyph->type == CHAR_GLYPH
20741 && glyph->voffset == voffset
20742 /* Same face id implies same font, nowadays. */
20743 && glyph->face_id == face_id
20744 && glyph->glyph_not_available_p == glyph_not_available_p)
20745 {
20746 int two_byte_p;
20747
20748 s->face = get_glyph_face_and_encoding (s->f, glyph,
20749 s->char2b + s->nchars,
20750 &two_byte_p);
20751 s->two_byte_p = two_byte_p;
20752 ++s->nchars;
20753 xassert (s->nchars <= end - start);
20754 s->width += glyph->pixel_width;
20755 if (glyph++->padding_p != s->padding_p)
20756 break;
20757 }
20758
20759 s->font = s->face->font;
20760
20761 /* If the specified font could not be loaded, use the frame's font,
20762 but record the fact that we couldn't load it in
20763 S->font_not_found_p so that we can draw rectangles for the
20764 characters of the glyph string. */
20765 if (s->font == NULL || glyph_not_available_p)
20766 {
20767 s->font_not_found_p = 1;
20768 s->font = FRAME_FONT (s->f);
20769 }
20770
20771 /* Adjust base line for subscript/superscript text. */
20772 s->ybase += voffset;
20773
20774 xassert (s->face && s->face->gc);
20775 return glyph - s->row->glyphs[s->area];
20776 }
20777
20778
20779 /* Fill glyph string S from image glyph S->first_glyph. */
20780
20781 static void
20782 fill_image_glyph_string (struct glyph_string *s)
20783 {
20784 xassert (s->first_glyph->type == IMAGE_GLYPH);
20785 s->img = IMAGE_FROM_ID (s->f, s->first_glyph->u.img_id);
20786 xassert (s->img);
20787 s->slice = s->first_glyph->slice.img;
20788 s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
20789 s->font = s->face->font;
20790 s->width = s->first_glyph->pixel_width;
20791
20792 /* Adjust base line for subscript/superscript text. */
20793 s->ybase += s->first_glyph->voffset;
20794 }
20795
20796
20797 /* Fill glyph string S from a sequence of stretch glyphs.
20798
20799 START is the index of the first glyph to consider,
20800 END is the index of the last + 1.
20801
20802 Value is the index of the first glyph not in S. */
20803
20804 static int
20805 fill_stretch_glyph_string (struct glyph_string *s, int start, int end)
20806 {
20807 struct glyph *glyph, *last;
20808 int voffset, face_id;
20809
20810 xassert (s->first_glyph->type == STRETCH_GLYPH);
20811
20812 glyph = s->row->glyphs[s->area] + start;
20813 last = s->row->glyphs[s->area] + end;
20814 face_id = glyph->face_id;
20815 s->face = FACE_FROM_ID (s->f, face_id);
20816 s->font = s->face->font;
20817 s->width = glyph->pixel_width;
20818 s->nchars = 1;
20819 voffset = glyph->voffset;
20820
20821 for (++glyph;
20822 (glyph < last
20823 && glyph->type == STRETCH_GLYPH
20824 && glyph->voffset == voffset
20825 && glyph->face_id == face_id);
20826 ++glyph)
20827 s->width += glyph->pixel_width;
20828
20829 /* Adjust base line for subscript/superscript text. */
20830 s->ybase += voffset;
20831
20832 /* The case that face->gc == 0 is handled when drawing the glyph
20833 string by calling PREPARE_FACE_FOR_DISPLAY. */
20834 xassert (s->face);
20835 return glyph - s->row->glyphs[s->area];
20836 }
20837
20838 static struct font_metrics *
20839 get_per_char_metric (struct font *font, XChar2b *char2b)
20840 {
20841 static struct font_metrics metrics;
20842 unsigned code = (XCHAR2B_BYTE1 (char2b) << 8) | XCHAR2B_BYTE2 (char2b);
20843
20844 if (! font || code == FONT_INVALID_CODE)
20845 return NULL;
20846 font->driver->text_extents (font, &code, 1, &metrics);
20847 return &metrics;
20848 }
20849
20850 /* EXPORT for RIF:
20851 Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
20852 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
20853 assumed to be zero. */
20854
20855 void
20856 x_get_glyph_overhangs (struct glyph *glyph, struct frame *f, int *left, int *right)
20857 {
20858 *left = *right = 0;
20859
20860 if (glyph->type == CHAR_GLYPH)
20861 {
20862 struct face *face;
20863 XChar2b char2b;
20864 struct font_metrics *pcm;
20865
20866 face = get_glyph_face_and_encoding (f, glyph, &char2b, NULL);
20867 if (face->font && (pcm = get_per_char_metric (face->font, &char2b)))
20868 {
20869 if (pcm->rbearing > pcm->width)
20870 *right = pcm->rbearing - pcm->width;
20871 if (pcm->lbearing < 0)
20872 *left = -pcm->lbearing;
20873 }
20874 }
20875 else if (glyph->type == COMPOSITE_GLYPH)
20876 {
20877 if (! glyph->u.cmp.automatic)
20878 {
20879 struct composition *cmp = composition_table[glyph->u.cmp.id];
20880
20881 if (cmp->rbearing > cmp->pixel_width)
20882 *right = cmp->rbearing - cmp->pixel_width;
20883 if (cmp->lbearing < 0)
20884 *left = - cmp->lbearing;
20885 }
20886 else
20887 {
20888 Lisp_Object gstring = composition_gstring_from_id (glyph->u.cmp.id);
20889 struct font_metrics metrics;
20890
20891 composition_gstring_width (gstring, glyph->slice.cmp.from,
20892 glyph->slice.cmp.to + 1, &metrics);
20893 if (metrics.rbearing > metrics.width)
20894 *right = metrics.rbearing - metrics.width;
20895 if (metrics.lbearing < 0)
20896 *left = - metrics.lbearing;
20897 }
20898 }
20899 }
20900
20901
20902 /* Return the index of the first glyph preceding glyph string S that
20903 is overwritten by S because of S's left overhang. Value is -1
20904 if no glyphs are overwritten. */
20905
20906 static int
20907 left_overwritten (struct glyph_string *s)
20908 {
20909 int k;
20910
20911 if (s->left_overhang)
20912 {
20913 int x = 0, i;
20914 struct glyph *glyphs = s->row->glyphs[s->area];
20915 int first = s->first_glyph - glyphs;
20916
20917 for (i = first - 1; i >= 0 && x > -s->left_overhang; --i)
20918 x -= glyphs[i].pixel_width;
20919
20920 k = i + 1;
20921 }
20922 else
20923 k = -1;
20924
20925 return k;
20926 }
20927
20928
20929 /* Return the index of the first glyph preceding glyph string S that
20930 is overwriting S because of its right overhang. Value is -1 if no
20931 glyph in front of S overwrites S. */
20932
20933 static int
20934 left_overwriting (struct glyph_string *s)
20935 {
20936 int i, k, x;
20937 struct glyph *glyphs = s->row->glyphs[s->area];
20938 int first = s->first_glyph - glyphs;
20939
20940 k = -1;
20941 x = 0;
20942 for (i = first - 1; i >= 0; --i)
20943 {
20944 int left, right;
20945 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
20946 if (x + right > 0)
20947 k = i;
20948 x -= glyphs[i].pixel_width;
20949 }
20950
20951 return k;
20952 }
20953
20954
20955 /* Return the index of the last glyph following glyph string S that is
20956 overwritten by S because of S's right overhang. Value is -1 if
20957 no such glyph is found. */
20958
20959 static int
20960 right_overwritten (struct glyph_string *s)
20961 {
20962 int k = -1;
20963
20964 if (s->right_overhang)
20965 {
20966 int x = 0, i;
20967 struct glyph *glyphs = s->row->glyphs[s->area];
20968 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
20969 int end = s->row->used[s->area];
20970
20971 for (i = first; i < end && s->right_overhang > x; ++i)
20972 x += glyphs[i].pixel_width;
20973
20974 k = i;
20975 }
20976
20977 return k;
20978 }
20979
20980
20981 /* Return the index of the last glyph following glyph string S that
20982 overwrites S because of its left overhang. Value is negative
20983 if no such glyph is found. */
20984
20985 static int
20986 right_overwriting (struct glyph_string *s)
20987 {
20988 int i, k, x;
20989 int end = s->row->used[s->area];
20990 struct glyph *glyphs = s->row->glyphs[s->area];
20991 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
20992
20993 k = -1;
20994 x = 0;
20995 for (i = first; i < end; ++i)
20996 {
20997 int left, right;
20998 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
20999 if (x - left < 0)
21000 k = i;
21001 x += glyphs[i].pixel_width;
21002 }
21003
21004 return k;
21005 }
21006
21007
21008 /* Set background width of glyph string S. START is the index of the
21009 first glyph following S. LAST_X is the right-most x-position + 1
21010 in the drawing area. */
21011
21012 static INLINE void
21013 set_glyph_string_background_width (struct glyph_string *s, int start, int last_x)
21014 {
21015 /* If the face of this glyph string has to be drawn to the end of
21016 the drawing area, set S->extends_to_end_of_line_p. */
21017
21018 if (start == s->row->used[s->area]
21019 && s->area == TEXT_AREA
21020 && ((s->row->fill_line_p
21021 && (s->hl == DRAW_NORMAL_TEXT
21022 || s->hl == DRAW_IMAGE_RAISED
21023 || s->hl == DRAW_IMAGE_SUNKEN))
21024 || s->hl == DRAW_MOUSE_FACE))
21025 s->extends_to_end_of_line_p = 1;
21026
21027 /* If S extends its face to the end of the line, set its
21028 background_width to the distance to the right edge of the drawing
21029 area. */
21030 if (s->extends_to_end_of_line_p)
21031 s->background_width = last_x - s->x + 1;
21032 else
21033 s->background_width = s->width;
21034 }
21035
21036
21037 /* Compute overhangs and x-positions for glyph string S and its
21038 predecessors, or successors. X is the starting x-position for S.
21039 BACKWARD_P non-zero means process predecessors. */
21040
21041 static void
21042 compute_overhangs_and_x (struct glyph_string *s, int x, int backward_p)
21043 {
21044 if (backward_p)
21045 {
21046 while (s)
21047 {
21048 if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
21049 FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
21050 x -= s->width;
21051 s->x = x;
21052 s = s->prev;
21053 }
21054 }
21055 else
21056 {
21057 while (s)
21058 {
21059 if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
21060 FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
21061 s->x = x;
21062 x += s->width;
21063 s = s->next;
21064 }
21065 }
21066 }
21067
21068
21069
21070 /* The following macros are only called from draw_glyphs below.
21071 They reference the following parameters of that function directly:
21072 `w', `row', `area', and `overlap_p'
21073 as well as the following local variables:
21074 `s', `f', and `hdc' (in W32) */
21075
21076 #ifdef HAVE_NTGUI
21077 /* On W32, silently add local `hdc' variable to argument list of
21078 init_glyph_string. */
21079 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
21080 init_glyph_string (s, hdc, char2b, w, row, area, start, hl)
21081 #else
21082 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
21083 init_glyph_string (s, char2b, w, row, area, start, hl)
21084 #endif
21085
21086 /* Add a glyph string for a stretch glyph to the list of strings
21087 between HEAD and TAIL. START is the index of the stretch glyph in
21088 row area AREA of glyph row ROW. END is the index of the last glyph
21089 in that glyph row area. X is the current output position assigned
21090 to the new glyph string constructed. HL overrides that face of the
21091 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
21092 is the right-most x-position of the drawing area. */
21093
21094 /* SunOS 4 bundled cc, barfed on continuations in the arg lists here
21095 and below -- keep them on one line. */
21096 #define BUILD_STRETCH_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
21097 do \
21098 { \
21099 s = (struct glyph_string *) alloca (sizeof *s); \
21100 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
21101 START = fill_stretch_glyph_string (s, START, END); \
21102 append_glyph_string (&HEAD, &TAIL, s); \
21103 s->x = (X); \
21104 } \
21105 while (0)
21106
21107
21108 /* Add a glyph string for an image glyph to the list of strings
21109 between HEAD and TAIL. START is the index of the image glyph in
21110 row area AREA of glyph row ROW. END is the index of the last glyph
21111 in that glyph row area. X is the current output position assigned
21112 to the new glyph string constructed. HL overrides that face of the
21113 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
21114 is the right-most x-position of the drawing area. */
21115
21116 #define BUILD_IMAGE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
21117 do \
21118 { \
21119 s = (struct glyph_string *) alloca (sizeof *s); \
21120 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
21121 fill_image_glyph_string (s); \
21122 append_glyph_string (&HEAD, &TAIL, s); \
21123 ++START; \
21124 s->x = (X); \
21125 } \
21126 while (0)
21127
21128
21129 /* Add a glyph string for a sequence of character glyphs to the list
21130 of strings between HEAD and TAIL. START is the index of the first
21131 glyph in row area AREA of glyph row ROW that is part of the new
21132 glyph string. END is the index of the last glyph in that glyph row
21133 area. X is the current output position assigned to the new glyph
21134 string constructed. HL overrides that face of the glyph; e.g. it
21135 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
21136 right-most x-position of the drawing area. */
21137
21138 #define BUILD_CHAR_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
21139 do \
21140 { \
21141 int face_id; \
21142 XChar2b *char2b; \
21143 \
21144 face_id = (row)->glyphs[area][START].face_id; \
21145 \
21146 s = (struct glyph_string *) alloca (sizeof *s); \
21147 char2b = (XChar2b *) alloca ((END - START) * sizeof *char2b); \
21148 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
21149 append_glyph_string (&HEAD, &TAIL, s); \
21150 s->x = (X); \
21151 START = fill_glyph_string (s, face_id, START, END, overlaps); \
21152 } \
21153 while (0)
21154
21155
21156 /* Add a glyph string for a composite sequence to the list of strings
21157 between HEAD and TAIL. START is the index of the first glyph in
21158 row area AREA of glyph row ROW that is part of the new glyph
21159 string. END is the index of the last glyph in that glyph row area.
21160 X is the current output position assigned to the new glyph string
21161 constructed. HL overrides that face of the glyph; e.g. it is
21162 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
21163 x-position of the drawing area. */
21164
21165 #define BUILD_COMPOSITE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
21166 do { \
21167 int face_id = (row)->glyphs[area][START].face_id; \
21168 struct face *base_face = FACE_FROM_ID (f, face_id); \
21169 int cmp_id = (row)->glyphs[area][START].u.cmp.id; \
21170 struct composition *cmp = composition_table[cmp_id]; \
21171 XChar2b *char2b; \
21172 struct glyph_string *first_s IF_LINT (= NULL); \
21173 int n; \
21174 \
21175 char2b = (XChar2b *) alloca ((sizeof *char2b) * cmp->glyph_len); \
21176 \
21177 /* Make glyph_strings for each glyph sequence that is drawable by \
21178 the same face, and append them to HEAD/TAIL. */ \
21179 for (n = 0; n < cmp->glyph_len;) \
21180 { \
21181 s = (struct glyph_string *) alloca (sizeof *s); \
21182 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
21183 append_glyph_string (&(HEAD), &(TAIL), s); \
21184 s->cmp = cmp; \
21185 s->cmp_from = n; \
21186 s->x = (X); \
21187 if (n == 0) \
21188 first_s = s; \
21189 n = fill_composite_glyph_string (s, base_face, overlaps); \
21190 } \
21191 \
21192 ++START; \
21193 s = first_s; \
21194 } while (0)
21195
21196
21197 /* Add a glyph string for a glyph-string sequence to the list of strings
21198 between HEAD and TAIL. */
21199
21200 #define BUILD_GSTRING_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
21201 do { \
21202 int face_id; \
21203 XChar2b *char2b; \
21204 Lisp_Object gstring; \
21205 \
21206 face_id = (row)->glyphs[area][START].face_id; \
21207 gstring = (composition_gstring_from_id \
21208 ((row)->glyphs[area][START].u.cmp.id)); \
21209 s = (struct glyph_string *) alloca (sizeof *s); \
21210 char2b = (XChar2b *) alloca ((sizeof *char2b) \
21211 * LGSTRING_GLYPH_LEN (gstring)); \
21212 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
21213 append_glyph_string (&(HEAD), &(TAIL), s); \
21214 s->x = (X); \
21215 START = fill_gstring_glyph_string (s, face_id, START, END, overlaps); \
21216 } while (0)
21217
21218
21219 /* Add a glyph string for a sequence of glyphless character's glyphs
21220 to the list of strings between HEAD and TAIL. The meanings of
21221 arguments are the same as those of BUILD_CHAR_GLYPH_STRINGS. */
21222
21223 #define BUILD_GLYPHLESS_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
21224 do \
21225 { \
21226 int face_id; \
21227 \
21228 face_id = (row)->glyphs[area][START].face_id; \
21229 \
21230 s = (struct glyph_string *) alloca (sizeof *s); \
21231 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
21232 append_glyph_string (&HEAD, &TAIL, s); \
21233 s->x = (X); \
21234 START = fill_glyphless_glyph_string (s, face_id, START, END, \
21235 overlaps); \
21236 } \
21237 while (0)
21238
21239
21240 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
21241 of AREA of glyph row ROW on window W between indices START and END.
21242 HL overrides the face for drawing glyph strings, e.g. it is
21243 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
21244 x-positions of the drawing area.
21245
21246 This is an ugly monster macro construct because we must use alloca
21247 to allocate glyph strings (because draw_glyphs can be called
21248 asynchronously). */
21249
21250 #define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
21251 do \
21252 { \
21253 HEAD = TAIL = NULL; \
21254 while (START < END) \
21255 { \
21256 struct glyph *first_glyph = (row)->glyphs[area] + START; \
21257 switch (first_glyph->type) \
21258 { \
21259 case CHAR_GLYPH: \
21260 BUILD_CHAR_GLYPH_STRINGS (START, END, HEAD, TAIL, \
21261 HL, X, LAST_X); \
21262 break; \
21263 \
21264 case COMPOSITE_GLYPH: \
21265 if (first_glyph->u.cmp.automatic) \
21266 BUILD_GSTRING_GLYPH_STRING (START, END, HEAD, TAIL, \
21267 HL, X, LAST_X); \
21268 else \
21269 BUILD_COMPOSITE_GLYPH_STRING (START, END, HEAD, TAIL, \
21270 HL, X, LAST_X); \
21271 break; \
21272 \
21273 case STRETCH_GLYPH: \
21274 BUILD_STRETCH_GLYPH_STRING (START, END, HEAD, TAIL, \
21275 HL, X, LAST_X); \
21276 break; \
21277 \
21278 case IMAGE_GLYPH: \
21279 BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL, \
21280 HL, X, LAST_X); \
21281 break; \
21282 \
21283 case GLYPHLESS_GLYPH: \
21284 BUILD_GLYPHLESS_GLYPH_STRING (START, END, HEAD, TAIL, \
21285 HL, X, LAST_X); \
21286 break; \
21287 \
21288 default: \
21289 abort (); \
21290 } \
21291 \
21292 if (s) \
21293 { \
21294 set_glyph_string_background_width (s, START, LAST_X); \
21295 (X) += s->width; \
21296 } \
21297 } \
21298 } while (0)
21299
21300
21301 /* Draw glyphs between START and END in AREA of ROW on window W,
21302 starting at x-position X. X is relative to AREA in W. HL is a
21303 face-override with the following meaning:
21304
21305 DRAW_NORMAL_TEXT draw normally
21306 DRAW_CURSOR draw in cursor face
21307 DRAW_MOUSE_FACE draw in mouse face.
21308 DRAW_INVERSE_VIDEO draw in mode line face
21309 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
21310 DRAW_IMAGE_RAISED draw an image with a raised relief around it
21311
21312 If OVERLAPS is non-zero, draw only the foreground of characters and
21313 clip to the physical height of ROW. Non-zero value also defines
21314 the overlapping part to be drawn:
21315
21316 OVERLAPS_PRED overlap with preceding rows
21317 OVERLAPS_SUCC overlap with succeeding rows
21318 OVERLAPS_BOTH overlap with both preceding/succeeding rows
21319 OVERLAPS_ERASED_CURSOR overlap with erased cursor area
21320
21321 Value is the x-position reached, relative to AREA of W. */
21322
21323 static int
21324 draw_glyphs (struct window *w, int x, struct glyph_row *row,
21325 enum glyph_row_area area, EMACS_INT start, EMACS_INT end,
21326 enum draw_glyphs_face hl, int overlaps)
21327 {
21328 struct glyph_string *head, *tail;
21329 struct glyph_string *s;
21330 struct glyph_string *clip_head = NULL, *clip_tail = NULL;
21331 int i, j, x_reached, last_x, area_left = 0;
21332 struct frame *f = XFRAME (WINDOW_FRAME (w));
21333 DECLARE_HDC (hdc);
21334
21335 ALLOCATE_HDC (hdc, f);
21336
21337 /* Let's rather be paranoid than getting a SEGV. */
21338 end = min (end, row->used[area]);
21339 start = max (0, start);
21340 start = min (end, start);
21341
21342 /* Translate X to frame coordinates. Set last_x to the right
21343 end of the drawing area. */
21344 if (row->full_width_p)
21345 {
21346 /* X is relative to the left edge of W, without scroll bars
21347 or fringes. */
21348 area_left = WINDOW_LEFT_EDGE_X (w);
21349 last_x = WINDOW_LEFT_EDGE_X (w) + WINDOW_TOTAL_WIDTH (w);
21350 }
21351 else
21352 {
21353 area_left = window_box_left (w, area);
21354 last_x = area_left + window_box_width (w, area);
21355 }
21356 x += area_left;
21357
21358 /* Build a doubly-linked list of glyph_string structures between
21359 head and tail from what we have to draw. Note that the macro
21360 BUILD_GLYPH_STRINGS will modify its start parameter. That's
21361 the reason we use a separate variable `i'. */
21362 i = start;
21363 BUILD_GLYPH_STRINGS (i, end, head, tail, hl, x, last_x);
21364 if (tail)
21365 x_reached = tail->x + tail->background_width;
21366 else
21367 x_reached = x;
21368
21369 /* If there are any glyphs with lbearing < 0 or rbearing > width in
21370 the row, redraw some glyphs in front or following the glyph
21371 strings built above. */
21372 if (head && !overlaps && row->contains_overlapping_glyphs_p)
21373 {
21374 struct glyph_string *h, *t;
21375 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
21376 int mouse_beg_col IF_LINT (= 0), mouse_end_col IF_LINT (= 0);
21377 int check_mouse_face = 0;
21378 int dummy_x = 0;
21379
21380 /* If mouse highlighting is on, we may need to draw adjacent
21381 glyphs using mouse-face highlighting. */
21382 if (area == TEXT_AREA && row->mouse_face_p)
21383 {
21384 struct glyph_row *mouse_beg_row, *mouse_end_row;
21385
21386 mouse_beg_row = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_beg_row);
21387 mouse_end_row = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_end_row);
21388
21389 if (row >= mouse_beg_row && row <= mouse_end_row)
21390 {
21391 check_mouse_face = 1;
21392 mouse_beg_col = (row == mouse_beg_row)
21393 ? hlinfo->mouse_face_beg_col : 0;
21394 mouse_end_col = (row == mouse_end_row)
21395 ? hlinfo->mouse_face_end_col
21396 : row->used[TEXT_AREA];
21397 }
21398 }
21399
21400 /* Compute overhangs for all glyph strings. */
21401 if (FRAME_RIF (f)->compute_glyph_string_overhangs)
21402 for (s = head; s; s = s->next)
21403 FRAME_RIF (f)->compute_glyph_string_overhangs (s);
21404
21405 /* Prepend glyph strings for glyphs in front of the first glyph
21406 string that are overwritten because of the first glyph
21407 string's left overhang. The background of all strings
21408 prepended must be drawn because the first glyph string
21409 draws over it. */
21410 i = left_overwritten (head);
21411 if (i >= 0)
21412 {
21413 enum draw_glyphs_face overlap_hl;
21414
21415 /* If this row contains mouse highlighting, attempt to draw
21416 the overlapped glyphs with the correct highlight. This
21417 code fails if the overlap encompasses more than one glyph
21418 and mouse-highlight spans only some of these glyphs.
21419 However, making it work perfectly involves a lot more
21420 code, and I don't know if the pathological case occurs in
21421 practice, so we'll stick to this for now. --- cyd */
21422 if (check_mouse_face
21423 && mouse_beg_col < start && mouse_end_col > i)
21424 overlap_hl = DRAW_MOUSE_FACE;
21425 else
21426 overlap_hl = DRAW_NORMAL_TEXT;
21427
21428 j = i;
21429 BUILD_GLYPH_STRINGS (j, start, h, t,
21430 overlap_hl, dummy_x, last_x);
21431 start = i;
21432 compute_overhangs_and_x (t, head->x, 1);
21433 prepend_glyph_string_lists (&head, &tail, h, t);
21434 clip_head = head;
21435 }
21436
21437 /* Prepend glyph strings for glyphs in front of the first glyph
21438 string that overwrite that glyph string because of their
21439 right overhang. For these strings, only the foreground must
21440 be drawn, because it draws over the glyph string at `head'.
21441 The background must not be drawn because this would overwrite
21442 right overhangs of preceding glyphs for which no glyph
21443 strings exist. */
21444 i = left_overwriting (head);
21445 if (i >= 0)
21446 {
21447 enum draw_glyphs_face overlap_hl;
21448
21449 if (check_mouse_face
21450 && mouse_beg_col < start && mouse_end_col > i)
21451 overlap_hl = DRAW_MOUSE_FACE;
21452 else
21453 overlap_hl = DRAW_NORMAL_TEXT;
21454
21455 clip_head = head;
21456 BUILD_GLYPH_STRINGS (i, start, h, t,
21457 overlap_hl, dummy_x, last_x);
21458 for (s = h; s; s = s->next)
21459 s->background_filled_p = 1;
21460 compute_overhangs_and_x (t, head->x, 1);
21461 prepend_glyph_string_lists (&head, &tail, h, t);
21462 }
21463
21464 /* Append glyphs strings for glyphs following the last glyph
21465 string tail that are overwritten by tail. The background of
21466 these strings has to be drawn because tail's foreground draws
21467 over it. */
21468 i = right_overwritten (tail);
21469 if (i >= 0)
21470 {
21471 enum draw_glyphs_face overlap_hl;
21472
21473 if (check_mouse_face
21474 && mouse_beg_col < i && mouse_end_col > end)
21475 overlap_hl = DRAW_MOUSE_FACE;
21476 else
21477 overlap_hl = DRAW_NORMAL_TEXT;
21478
21479 BUILD_GLYPH_STRINGS (end, i, h, t,
21480 overlap_hl, x, last_x);
21481 /* Because BUILD_GLYPH_STRINGS updates the first argument,
21482 we don't have `end = i;' here. */
21483 compute_overhangs_and_x (h, tail->x + tail->width, 0);
21484 append_glyph_string_lists (&head, &tail, h, t);
21485 clip_tail = tail;
21486 }
21487
21488 /* Append glyph strings for glyphs following the last glyph
21489 string tail that overwrite tail. The foreground of such
21490 glyphs has to be drawn because it writes into the background
21491 of tail. The background must not be drawn because it could
21492 paint over the foreground of following glyphs. */
21493 i = right_overwriting (tail);
21494 if (i >= 0)
21495 {
21496 enum draw_glyphs_face overlap_hl;
21497 if (check_mouse_face
21498 && mouse_beg_col < i && mouse_end_col > end)
21499 overlap_hl = DRAW_MOUSE_FACE;
21500 else
21501 overlap_hl = DRAW_NORMAL_TEXT;
21502
21503 clip_tail = tail;
21504 i++; /* We must include the Ith glyph. */
21505 BUILD_GLYPH_STRINGS (end, i, h, t,
21506 overlap_hl, x, last_x);
21507 for (s = h; s; s = s->next)
21508 s->background_filled_p = 1;
21509 compute_overhangs_and_x (h, tail->x + tail->width, 0);
21510 append_glyph_string_lists (&head, &tail, h, t);
21511 }
21512 if (clip_head || clip_tail)
21513 for (s = head; s; s = s->next)
21514 {
21515 s->clip_head = clip_head;
21516 s->clip_tail = clip_tail;
21517 }
21518 }
21519
21520 /* Draw all strings. */
21521 for (s = head; s; s = s->next)
21522 FRAME_RIF (f)->draw_glyph_string (s);
21523
21524 #ifndef HAVE_NS
21525 /* When focus a sole frame and move horizontally, this sets on_p to 0
21526 causing a failure to erase prev cursor position. */
21527 if (area == TEXT_AREA
21528 && !row->full_width_p
21529 /* When drawing overlapping rows, only the glyph strings'
21530 foreground is drawn, which doesn't erase a cursor
21531 completely. */
21532 && !overlaps)
21533 {
21534 int x0 = clip_head ? clip_head->x : (head ? head->x : x);
21535 int x1 = (clip_tail ? clip_tail->x + clip_tail->background_width
21536 : (tail ? tail->x + tail->background_width : x));
21537 x0 -= area_left;
21538 x1 -= area_left;
21539
21540 notice_overwritten_cursor (w, TEXT_AREA, x0, x1,
21541 row->y, MATRIX_ROW_BOTTOM_Y (row));
21542 }
21543 #endif
21544
21545 /* Value is the x-position up to which drawn, relative to AREA of W.
21546 This doesn't include parts drawn because of overhangs. */
21547 if (row->full_width_p)
21548 x_reached = FRAME_TO_WINDOW_PIXEL_X (w, x_reached);
21549 else
21550 x_reached -= area_left;
21551
21552 RELEASE_HDC (hdc, f);
21553
21554 return x_reached;
21555 }
21556
21557 /* Expand row matrix if too narrow. Don't expand if area
21558 is not present. */
21559
21560 #define IT_EXPAND_MATRIX_WIDTH(it, area) \
21561 { \
21562 if (!fonts_changed_p \
21563 && (it->glyph_row->glyphs[area] \
21564 < it->glyph_row->glyphs[area + 1])) \
21565 { \
21566 it->w->ncols_scale_factor++; \
21567 fonts_changed_p = 1; \
21568 } \
21569 }
21570
21571 /* Store one glyph for IT->char_to_display in IT->glyph_row.
21572 Called from x_produce_glyphs when IT->glyph_row is non-null. */
21573
21574 static INLINE void
21575 append_glyph (struct it *it)
21576 {
21577 struct glyph *glyph;
21578 enum glyph_row_area area = it->area;
21579
21580 xassert (it->glyph_row);
21581 xassert (it->char_to_display != '\n' && it->char_to_display != '\t');
21582
21583 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
21584 if (glyph < it->glyph_row->glyphs[area + 1])
21585 {
21586 /* If the glyph row is reversed, we need to prepend the glyph
21587 rather than append it. */
21588 if (it->glyph_row->reversed_p && area == TEXT_AREA)
21589 {
21590 struct glyph *g;
21591
21592 /* Make room for the additional glyph. */
21593 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
21594 g[1] = *g;
21595 glyph = it->glyph_row->glyphs[area];
21596 }
21597 glyph->charpos = CHARPOS (it->position);
21598 glyph->object = it->object;
21599 if (it->pixel_width > 0)
21600 {
21601 glyph->pixel_width = it->pixel_width;
21602 glyph->padding_p = 0;
21603 }
21604 else
21605 {
21606 /* Assure at least 1-pixel width. Otherwise, cursor can't
21607 be displayed correctly. */
21608 glyph->pixel_width = 1;
21609 glyph->padding_p = 1;
21610 }
21611 glyph->ascent = it->ascent;
21612 glyph->descent = it->descent;
21613 glyph->voffset = it->voffset;
21614 glyph->type = CHAR_GLYPH;
21615 glyph->avoid_cursor_p = it->avoid_cursor_p;
21616 glyph->multibyte_p = it->multibyte_p;
21617 glyph->left_box_line_p = it->start_of_box_run_p;
21618 glyph->right_box_line_p = it->end_of_box_run_p;
21619 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
21620 || it->phys_descent > it->descent);
21621 glyph->glyph_not_available_p = it->glyph_not_available_p;
21622 glyph->face_id = it->face_id;
21623 glyph->u.ch = it->char_to_display;
21624 glyph->slice.img = null_glyph_slice;
21625 glyph->font_type = FONT_TYPE_UNKNOWN;
21626 if (it->bidi_p)
21627 {
21628 glyph->resolved_level = it->bidi_it.resolved_level;
21629 if ((it->bidi_it.type & 7) != it->bidi_it.type)
21630 abort ();
21631 glyph->bidi_type = it->bidi_it.type;
21632 }
21633 else
21634 {
21635 glyph->resolved_level = 0;
21636 glyph->bidi_type = UNKNOWN_BT;
21637 }
21638 ++it->glyph_row->used[area];
21639 }
21640 else
21641 IT_EXPAND_MATRIX_WIDTH (it, area);
21642 }
21643
21644 /* Store one glyph for the composition IT->cmp_it.id in
21645 IT->glyph_row. Called from x_produce_glyphs when IT->glyph_row is
21646 non-null. */
21647
21648 static INLINE void
21649 append_composite_glyph (struct it *it)
21650 {
21651 struct glyph *glyph;
21652 enum glyph_row_area area = it->area;
21653
21654 xassert (it->glyph_row);
21655
21656 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
21657 if (glyph < it->glyph_row->glyphs[area + 1])
21658 {
21659 /* If the glyph row is reversed, we need to prepend the glyph
21660 rather than append it. */
21661 if (it->glyph_row->reversed_p && it->area == TEXT_AREA)
21662 {
21663 struct glyph *g;
21664
21665 /* Make room for the new glyph. */
21666 for (g = glyph - 1; g >= it->glyph_row->glyphs[it->area]; g--)
21667 g[1] = *g;
21668 glyph = it->glyph_row->glyphs[it->area];
21669 }
21670 glyph->charpos = it->cmp_it.charpos;
21671 glyph->object = it->object;
21672 glyph->pixel_width = it->pixel_width;
21673 glyph->ascent = it->ascent;
21674 glyph->descent = it->descent;
21675 glyph->voffset = it->voffset;
21676 glyph->type = COMPOSITE_GLYPH;
21677 if (it->cmp_it.ch < 0)
21678 {
21679 glyph->u.cmp.automatic = 0;
21680 glyph->u.cmp.id = it->cmp_it.id;
21681 glyph->slice.cmp.from = glyph->slice.cmp.to = 0;
21682 }
21683 else
21684 {
21685 glyph->u.cmp.automatic = 1;
21686 glyph->u.cmp.id = it->cmp_it.id;
21687 glyph->slice.cmp.from = it->cmp_it.from;
21688 glyph->slice.cmp.to = it->cmp_it.to - 1;
21689 }
21690 glyph->avoid_cursor_p = it->avoid_cursor_p;
21691 glyph->multibyte_p = it->multibyte_p;
21692 glyph->left_box_line_p = it->start_of_box_run_p;
21693 glyph->right_box_line_p = it->end_of_box_run_p;
21694 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
21695 || it->phys_descent > it->descent);
21696 glyph->padding_p = 0;
21697 glyph->glyph_not_available_p = 0;
21698 glyph->face_id = it->face_id;
21699 glyph->font_type = FONT_TYPE_UNKNOWN;
21700 if (it->bidi_p)
21701 {
21702 glyph->resolved_level = it->bidi_it.resolved_level;
21703 if ((it->bidi_it.type & 7) != it->bidi_it.type)
21704 abort ();
21705 glyph->bidi_type = it->bidi_it.type;
21706 }
21707 ++it->glyph_row->used[area];
21708 }
21709 else
21710 IT_EXPAND_MATRIX_WIDTH (it, area);
21711 }
21712
21713
21714 /* Change IT->ascent and IT->height according to the setting of
21715 IT->voffset. */
21716
21717 static INLINE void
21718 take_vertical_position_into_account (struct it *it)
21719 {
21720 if (it->voffset)
21721 {
21722 if (it->voffset < 0)
21723 /* Increase the ascent so that we can display the text higher
21724 in the line. */
21725 it->ascent -= it->voffset;
21726 else
21727 /* Increase the descent so that we can display the text lower
21728 in the line. */
21729 it->descent += it->voffset;
21730 }
21731 }
21732
21733
21734 /* Produce glyphs/get display metrics for the image IT is loaded with.
21735 See the description of struct display_iterator in dispextern.h for
21736 an overview of struct display_iterator. */
21737
21738 static void
21739 produce_image_glyph (struct it *it)
21740 {
21741 struct image *img;
21742 struct face *face;
21743 int glyph_ascent, crop;
21744 struct glyph_slice slice;
21745
21746 xassert (it->what == IT_IMAGE);
21747
21748 face = FACE_FROM_ID (it->f, it->face_id);
21749 xassert (face);
21750 /* Make sure X resources of the face is loaded. */
21751 PREPARE_FACE_FOR_DISPLAY (it->f, face);
21752
21753 if (it->image_id < 0)
21754 {
21755 /* Fringe bitmap. */
21756 it->ascent = it->phys_ascent = 0;
21757 it->descent = it->phys_descent = 0;
21758 it->pixel_width = 0;
21759 it->nglyphs = 0;
21760 return;
21761 }
21762
21763 img = IMAGE_FROM_ID (it->f, it->image_id);
21764 xassert (img);
21765 /* Make sure X resources of the image is loaded. */
21766 prepare_image_for_display (it->f, img);
21767
21768 slice.x = slice.y = 0;
21769 slice.width = img->width;
21770 slice.height = img->height;
21771
21772 if (INTEGERP (it->slice.x))
21773 slice.x = XINT (it->slice.x);
21774 else if (FLOATP (it->slice.x))
21775 slice.x = XFLOAT_DATA (it->slice.x) * img->width;
21776
21777 if (INTEGERP (it->slice.y))
21778 slice.y = XINT (it->slice.y);
21779 else if (FLOATP (it->slice.y))
21780 slice.y = XFLOAT_DATA (it->slice.y) * img->height;
21781
21782 if (INTEGERP (it->slice.width))
21783 slice.width = XINT (it->slice.width);
21784 else if (FLOATP (it->slice.width))
21785 slice.width = XFLOAT_DATA (it->slice.width) * img->width;
21786
21787 if (INTEGERP (it->slice.height))
21788 slice.height = XINT (it->slice.height);
21789 else if (FLOATP (it->slice.height))
21790 slice.height = XFLOAT_DATA (it->slice.height) * img->height;
21791
21792 if (slice.x >= img->width)
21793 slice.x = img->width;
21794 if (slice.y >= img->height)
21795 slice.y = img->height;
21796 if (slice.x + slice.width >= img->width)
21797 slice.width = img->width - slice.x;
21798 if (slice.y + slice.height > img->height)
21799 slice.height = img->height - slice.y;
21800
21801 if (slice.width == 0 || slice.height == 0)
21802 return;
21803
21804 it->ascent = it->phys_ascent = glyph_ascent = image_ascent (img, face, &slice);
21805
21806 it->descent = slice.height - glyph_ascent;
21807 if (slice.y == 0)
21808 it->descent += img->vmargin;
21809 if (slice.y + slice.height == img->height)
21810 it->descent += img->vmargin;
21811 it->phys_descent = it->descent;
21812
21813 it->pixel_width = slice.width;
21814 if (slice.x == 0)
21815 it->pixel_width += img->hmargin;
21816 if (slice.x + slice.width == img->width)
21817 it->pixel_width += img->hmargin;
21818
21819 /* It's quite possible for images to have an ascent greater than
21820 their height, so don't get confused in that case. */
21821 if (it->descent < 0)
21822 it->descent = 0;
21823
21824 it->nglyphs = 1;
21825
21826 if (face->box != FACE_NO_BOX)
21827 {
21828 if (face->box_line_width > 0)
21829 {
21830 if (slice.y == 0)
21831 it->ascent += face->box_line_width;
21832 if (slice.y + slice.height == img->height)
21833 it->descent += face->box_line_width;
21834 }
21835
21836 if (it->start_of_box_run_p && slice.x == 0)
21837 it->pixel_width += eabs (face->box_line_width);
21838 if (it->end_of_box_run_p && slice.x + slice.width == img->width)
21839 it->pixel_width += eabs (face->box_line_width);
21840 }
21841
21842 take_vertical_position_into_account (it);
21843
21844 /* Automatically crop wide image glyphs at right edge so we can
21845 draw the cursor on same display row. */
21846 if ((crop = it->pixel_width - (it->last_visible_x - it->current_x), crop > 0)
21847 && (it->hpos == 0 || it->pixel_width > it->last_visible_x / 4))
21848 {
21849 it->pixel_width -= crop;
21850 slice.width -= crop;
21851 }
21852
21853 if (it->glyph_row)
21854 {
21855 struct glyph *glyph;
21856 enum glyph_row_area area = it->area;
21857
21858 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
21859 if (glyph < it->glyph_row->glyphs[area + 1])
21860 {
21861 glyph->charpos = CHARPOS (it->position);
21862 glyph->object = it->object;
21863 glyph->pixel_width = it->pixel_width;
21864 glyph->ascent = glyph_ascent;
21865 glyph->descent = it->descent;
21866 glyph->voffset = it->voffset;
21867 glyph->type = IMAGE_GLYPH;
21868 glyph->avoid_cursor_p = it->avoid_cursor_p;
21869 glyph->multibyte_p = it->multibyte_p;
21870 glyph->left_box_line_p = it->start_of_box_run_p;
21871 glyph->right_box_line_p = it->end_of_box_run_p;
21872 glyph->overlaps_vertically_p = 0;
21873 glyph->padding_p = 0;
21874 glyph->glyph_not_available_p = 0;
21875 glyph->face_id = it->face_id;
21876 glyph->u.img_id = img->id;
21877 glyph->slice.img = slice;
21878 glyph->font_type = FONT_TYPE_UNKNOWN;
21879 if (it->bidi_p)
21880 {
21881 glyph->resolved_level = it->bidi_it.resolved_level;
21882 if ((it->bidi_it.type & 7) != it->bidi_it.type)
21883 abort ();
21884 glyph->bidi_type = it->bidi_it.type;
21885 }
21886 ++it->glyph_row->used[area];
21887 }
21888 else
21889 IT_EXPAND_MATRIX_WIDTH (it, area);
21890 }
21891 }
21892
21893
21894 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
21895 of the glyph, WIDTH and HEIGHT are the width and height of the
21896 stretch. ASCENT is the ascent of the glyph (0 <= ASCENT <= HEIGHT). */
21897
21898 static void
21899 append_stretch_glyph (struct it *it, Lisp_Object object,
21900 int width, int height, int ascent)
21901 {
21902 struct glyph *glyph;
21903 enum glyph_row_area area = it->area;
21904
21905 xassert (ascent >= 0 && ascent <= height);
21906
21907 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
21908 if (glyph < it->glyph_row->glyphs[area + 1])
21909 {
21910 /* If the glyph row is reversed, we need to prepend the glyph
21911 rather than append it. */
21912 if (it->glyph_row->reversed_p && area == TEXT_AREA)
21913 {
21914 struct glyph *g;
21915
21916 /* Make room for the additional glyph. */
21917 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
21918 g[1] = *g;
21919 glyph = it->glyph_row->glyphs[area];
21920 }
21921 glyph->charpos = CHARPOS (it->position);
21922 glyph->object = object;
21923 glyph->pixel_width = width;
21924 glyph->ascent = ascent;
21925 glyph->descent = height - ascent;
21926 glyph->voffset = it->voffset;
21927 glyph->type = STRETCH_GLYPH;
21928 glyph->avoid_cursor_p = it->avoid_cursor_p;
21929 glyph->multibyte_p = it->multibyte_p;
21930 glyph->left_box_line_p = it->start_of_box_run_p;
21931 glyph->right_box_line_p = it->end_of_box_run_p;
21932 glyph->overlaps_vertically_p = 0;
21933 glyph->padding_p = 0;
21934 glyph->glyph_not_available_p = 0;
21935 glyph->face_id = it->face_id;
21936 glyph->u.stretch.ascent = ascent;
21937 glyph->u.stretch.height = height;
21938 glyph->slice.img = null_glyph_slice;
21939 glyph->font_type = FONT_TYPE_UNKNOWN;
21940 if (it->bidi_p)
21941 {
21942 glyph->resolved_level = it->bidi_it.resolved_level;
21943 if ((it->bidi_it.type & 7) != it->bidi_it.type)
21944 abort ();
21945 glyph->bidi_type = it->bidi_it.type;
21946 }
21947 else
21948 {
21949 glyph->resolved_level = 0;
21950 glyph->bidi_type = UNKNOWN_BT;
21951 }
21952 ++it->glyph_row->used[area];
21953 }
21954 else
21955 IT_EXPAND_MATRIX_WIDTH (it, area);
21956 }
21957
21958
21959 /* Produce a stretch glyph for iterator IT. IT->object is the value
21960 of the glyph property displayed. The value must be a list
21961 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
21962 being recognized:
21963
21964 1. `:width WIDTH' specifies that the space should be WIDTH *
21965 canonical char width wide. WIDTH may be an integer or floating
21966 point number.
21967
21968 2. `:relative-width FACTOR' specifies that the width of the stretch
21969 should be computed from the width of the first character having the
21970 `glyph' property, and should be FACTOR times that width.
21971
21972 3. `:align-to HPOS' specifies that the space should be wide enough
21973 to reach HPOS, a value in canonical character units.
21974
21975 Exactly one of the above pairs must be present.
21976
21977 4. `:height HEIGHT' specifies that the height of the stretch produced
21978 should be HEIGHT, measured in canonical character units.
21979
21980 5. `:relative-height FACTOR' specifies that the height of the
21981 stretch should be FACTOR times the height of the characters having
21982 the glyph property.
21983
21984 Either none or exactly one of 4 or 5 must be present.
21985
21986 6. `:ascent ASCENT' specifies that ASCENT percent of the height
21987 of the stretch should be used for the ascent of the stretch.
21988 ASCENT must be in the range 0 <= ASCENT <= 100. */
21989
21990 static void
21991 produce_stretch_glyph (struct it *it)
21992 {
21993 /* (space :width WIDTH :height HEIGHT ...) */
21994 Lisp_Object prop, plist;
21995 int width = 0, height = 0, align_to = -1;
21996 int zero_width_ok_p = 0, zero_height_ok_p = 0;
21997 int ascent = 0;
21998 double tem;
21999 struct face *face = FACE_FROM_ID (it->f, it->face_id);
22000 struct font *font = face->font ? face->font : FRAME_FONT (it->f);
22001
22002 PREPARE_FACE_FOR_DISPLAY (it->f, face);
22003
22004 /* List should start with `space'. */
22005 xassert (CONSP (it->object) && EQ (XCAR (it->object), Qspace));
22006 plist = XCDR (it->object);
22007
22008 /* Compute the width of the stretch. */
22009 if ((prop = Fplist_get (plist, QCwidth), !NILP (prop))
22010 && calc_pixel_width_or_height (&tem, it, prop, font, 1, 0))
22011 {
22012 /* Absolute width `:width WIDTH' specified and valid. */
22013 zero_width_ok_p = 1;
22014 width = (int)tem;
22015 }
22016 else if (prop = Fplist_get (plist, QCrelative_width),
22017 NUMVAL (prop) > 0)
22018 {
22019 /* Relative width `:relative-width FACTOR' specified and valid.
22020 Compute the width of the characters having the `glyph'
22021 property. */
22022 struct it it2;
22023 unsigned char *p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
22024
22025 it2 = *it;
22026 if (it->multibyte_p)
22027 it2.c = it2.char_to_display = STRING_CHAR_AND_LENGTH (p, it2.len);
22028 else
22029 {
22030 it2.c = it2.char_to_display = *p, it2.len = 1;
22031 if (! ASCII_CHAR_P (it2.c))
22032 it2.char_to_display = BYTE8_TO_CHAR (it2.c);
22033 }
22034
22035 it2.glyph_row = NULL;
22036 it2.what = IT_CHARACTER;
22037 x_produce_glyphs (&it2);
22038 width = NUMVAL (prop) * it2.pixel_width;
22039 }
22040 else if ((prop = Fplist_get (plist, QCalign_to), !NILP (prop))
22041 && calc_pixel_width_or_height (&tem, it, prop, font, 1, &align_to))
22042 {
22043 if (it->glyph_row == NULL || !it->glyph_row->mode_line_p)
22044 align_to = (align_to < 0
22045 ? 0
22046 : align_to - window_box_left_offset (it->w, TEXT_AREA));
22047 else if (align_to < 0)
22048 align_to = window_box_left_offset (it->w, TEXT_AREA);
22049 width = max (0, (int)tem + align_to - it->current_x);
22050 zero_width_ok_p = 1;
22051 }
22052 else
22053 /* Nothing specified -> width defaults to canonical char width. */
22054 width = FRAME_COLUMN_WIDTH (it->f);
22055
22056 if (width <= 0 && (width < 0 || !zero_width_ok_p))
22057 width = 1;
22058
22059 /* Compute height. */
22060 if ((prop = Fplist_get (plist, QCheight), !NILP (prop))
22061 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
22062 {
22063 height = (int)tem;
22064 zero_height_ok_p = 1;
22065 }
22066 else if (prop = Fplist_get (plist, QCrelative_height),
22067 NUMVAL (prop) > 0)
22068 height = FONT_HEIGHT (font) * NUMVAL (prop);
22069 else
22070 height = FONT_HEIGHT (font);
22071
22072 if (height <= 0 && (height < 0 || !zero_height_ok_p))
22073 height = 1;
22074
22075 /* Compute percentage of height used for ascent. If
22076 `:ascent ASCENT' is present and valid, use that. Otherwise,
22077 derive the ascent from the font in use. */
22078 if (prop = Fplist_get (plist, QCascent),
22079 NUMVAL (prop) > 0 && NUMVAL (prop) <= 100)
22080 ascent = height * NUMVAL (prop) / 100.0;
22081 else if (!NILP (prop)
22082 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
22083 ascent = min (max (0, (int)tem), height);
22084 else
22085 ascent = (height * FONT_BASE (font)) / FONT_HEIGHT (font);
22086
22087 if (width > 0 && it->line_wrap != TRUNCATE
22088 && it->current_x + width > it->last_visible_x)
22089 width = it->last_visible_x - it->current_x - 1;
22090
22091 if (width > 0 && height > 0 && it->glyph_row)
22092 {
22093 Lisp_Object object = it->stack[it->sp - 1].string;
22094 if (!STRINGP (object))
22095 object = it->w->buffer;
22096 append_stretch_glyph (it, object, width, height, ascent);
22097 }
22098
22099 it->pixel_width = width;
22100 it->ascent = it->phys_ascent = ascent;
22101 it->descent = it->phys_descent = height - it->ascent;
22102 it->nglyphs = width > 0 && height > 0 ? 1 : 0;
22103
22104 take_vertical_position_into_account (it);
22105 }
22106
22107 /* Calculate line-height and line-spacing properties.
22108 An integer value specifies explicit pixel value.
22109 A float value specifies relative value to current face height.
22110 A cons (float . face-name) specifies relative value to
22111 height of specified face font.
22112
22113 Returns height in pixels, or nil. */
22114
22115
22116 static Lisp_Object
22117 calc_line_height_property (struct it *it, Lisp_Object val, struct font *font,
22118 int boff, int override)
22119 {
22120 Lisp_Object face_name = Qnil;
22121 int ascent, descent, height;
22122
22123 if (NILP (val) || INTEGERP (val) || (override && EQ (val, Qt)))
22124 return val;
22125
22126 if (CONSP (val))
22127 {
22128 face_name = XCAR (val);
22129 val = XCDR (val);
22130 if (!NUMBERP (val))
22131 val = make_number (1);
22132 if (NILP (face_name))
22133 {
22134 height = it->ascent + it->descent;
22135 goto scale;
22136 }
22137 }
22138
22139 if (NILP (face_name))
22140 {
22141 font = FRAME_FONT (it->f);
22142 boff = FRAME_BASELINE_OFFSET (it->f);
22143 }
22144 else if (EQ (face_name, Qt))
22145 {
22146 override = 0;
22147 }
22148 else
22149 {
22150 int face_id;
22151 struct face *face;
22152
22153 face_id = lookup_named_face (it->f, face_name, 0);
22154 if (face_id < 0)
22155 return make_number (-1);
22156
22157 face = FACE_FROM_ID (it->f, face_id);
22158 font = face->font;
22159 if (font == NULL)
22160 return make_number (-1);
22161 boff = font->baseline_offset;
22162 if (font->vertical_centering)
22163 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
22164 }
22165
22166 ascent = FONT_BASE (font) + boff;
22167 descent = FONT_DESCENT (font) - boff;
22168
22169 if (override)
22170 {
22171 it->override_ascent = ascent;
22172 it->override_descent = descent;
22173 it->override_boff = boff;
22174 }
22175
22176 height = ascent + descent;
22177
22178 scale:
22179 if (FLOATP (val))
22180 height = (int)(XFLOAT_DATA (val) * height);
22181 else if (INTEGERP (val))
22182 height *= XINT (val);
22183
22184 return make_number (height);
22185 }
22186
22187
22188 /* Append a glyph for a glyphless character to IT->glyph_row. FACE_ID
22189 is a face ID to be used for the glyph. FOR_NO_FONT is nonzero if
22190 and only if this is for a character for which no font was found.
22191
22192 If the display method (it->glyphless_method) is
22193 GLYPHLESS_DISPLAY_ACRONYM or GLYPHLESS_DISPLAY_HEX_CODE, LEN is a
22194 length of the acronym or the hexadecimal string, UPPER_XOFF and
22195 UPPER_YOFF are pixel offsets for the upper part of the string,
22196 LOWER_XOFF and LOWER_YOFF are for the lower part.
22197
22198 For the other display methods, LEN through LOWER_YOFF are zero. */
22199
22200 static void
22201 append_glyphless_glyph (struct it *it, int face_id, int for_no_font, int len,
22202 short upper_xoff, short upper_yoff,
22203 short lower_xoff, short lower_yoff)
22204 {
22205 struct glyph *glyph;
22206 enum glyph_row_area area = it->area;
22207
22208 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
22209 if (glyph < it->glyph_row->glyphs[area + 1])
22210 {
22211 /* If the glyph row is reversed, we need to prepend the glyph
22212 rather than append it. */
22213 if (it->glyph_row->reversed_p && area == TEXT_AREA)
22214 {
22215 struct glyph *g;
22216
22217 /* Make room for the additional glyph. */
22218 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
22219 g[1] = *g;
22220 glyph = it->glyph_row->glyphs[area];
22221 }
22222 glyph->charpos = CHARPOS (it->position);
22223 glyph->object = it->object;
22224 glyph->pixel_width = it->pixel_width;
22225 glyph->ascent = it->ascent;
22226 glyph->descent = it->descent;
22227 glyph->voffset = it->voffset;
22228 glyph->type = GLYPHLESS_GLYPH;
22229 glyph->u.glyphless.method = it->glyphless_method;
22230 glyph->u.glyphless.for_no_font = for_no_font;
22231 glyph->u.glyphless.len = len;
22232 glyph->u.glyphless.ch = it->c;
22233 glyph->slice.glyphless.upper_xoff = upper_xoff;
22234 glyph->slice.glyphless.upper_yoff = upper_yoff;
22235 glyph->slice.glyphless.lower_xoff = lower_xoff;
22236 glyph->slice.glyphless.lower_yoff = lower_yoff;
22237 glyph->avoid_cursor_p = it->avoid_cursor_p;
22238 glyph->multibyte_p = it->multibyte_p;
22239 glyph->left_box_line_p = it->start_of_box_run_p;
22240 glyph->right_box_line_p = it->end_of_box_run_p;
22241 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
22242 || it->phys_descent > it->descent);
22243 glyph->padding_p = 0;
22244 glyph->glyph_not_available_p = 0;
22245 glyph->face_id = face_id;
22246 glyph->font_type = FONT_TYPE_UNKNOWN;
22247 if (it->bidi_p)
22248 {
22249 glyph->resolved_level = it->bidi_it.resolved_level;
22250 if ((it->bidi_it.type & 7) != it->bidi_it.type)
22251 abort ();
22252 glyph->bidi_type = it->bidi_it.type;
22253 }
22254 ++it->glyph_row->used[area];
22255 }
22256 else
22257 IT_EXPAND_MATRIX_WIDTH (it, area);
22258 }
22259
22260
22261 /* Produce a glyph for a glyphless character for iterator IT.
22262 IT->glyphless_method specifies which method to use for displaying
22263 the character. See the description of enum
22264 glyphless_display_method in dispextern.h for the detail.
22265
22266 FOR_NO_FONT is nonzero if and only if this is for a character for
22267 which no font was found. ACRONYM, if non-nil, is an acronym string
22268 for the character. */
22269
22270 static void
22271 produce_glyphless_glyph (struct it *it, int for_no_font, Lisp_Object acronym)
22272 {
22273 int face_id;
22274 struct face *face;
22275 struct font *font;
22276 int base_width, base_height, width, height;
22277 short upper_xoff, upper_yoff, lower_xoff, lower_yoff;
22278 int len;
22279
22280 /* Get the metrics of the base font. We always refer to the current
22281 ASCII face. */
22282 face = FACE_FROM_ID (it->f, it->face_id)->ascii_face;
22283 font = face->font ? face->font : FRAME_FONT (it->f);
22284 it->ascent = FONT_BASE (font) + font->baseline_offset;
22285 it->descent = FONT_DESCENT (font) - font->baseline_offset;
22286 base_height = it->ascent + it->descent;
22287 base_width = font->average_width;
22288
22289 /* Get a face ID for the glyph by utilizing a cache (the same way as
22290 doen for `escape-glyph' in get_next_display_element). */
22291 if (it->f == last_glyphless_glyph_frame
22292 && it->face_id == last_glyphless_glyph_face_id)
22293 {
22294 face_id = last_glyphless_glyph_merged_face_id;
22295 }
22296 else
22297 {
22298 /* Merge the `glyphless-char' face into the current face. */
22299 face_id = merge_faces (it->f, Qglyphless_char, 0, it->face_id);
22300 last_glyphless_glyph_frame = it->f;
22301 last_glyphless_glyph_face_id = it->face_id;
22302 last_glyphless_glyph_merged_face_id = face_id;
22303 }
22304
22305 if (it->glyphless_method == GLYPHLESS_DISPLAY_THIN_SPACE)
22306 {
22307 it->pixel_width = THIN_SPACE_WIDTH;
22308 len = 0;
22309 upper_xoff = upper_yoff = lower_xoff = lower_yoff = 0;
22310 }
22311 else if (it->glyphless_method == GLYPHLESS_DISPLAY_EMPTY_BOX)
22312 {
22313 width = CHAR_WIDTH (it->c);
22314 if (width == 0)
22315 width = 1;
22316 else if (width > 4)
22317 width = 4;
22318 it->pixel_width = base_width * width;
22319 len = 0;
22320 upper_xoff = upper_yoff = lower_xoff = lower_yoff = 0;
22321 }
22322 else
22323 {
22324 char buf[7];
22325 const char *str;
22326 unsigned int code[6];
22327 int upper_len;
22328 int ascent, descent;
22329 struct font_metrics metrics_upper, metrics_lower;
22330
22331 face = FACE_FROM_ID (it->f, face_id);
22332 font = face->font ? face->font : FRAME_FONT (it->f);
22333 PREPARE_FACE_FOR_DISPLAY (it->f, face);
22334
22335 if (it->glyphless_method == GLYPHLESS_DISPLAY_ACRONYM)
22336 {
22337 if (! STRINGP (acronym) && CHAR_TABLE_P (Vglyphless_char_display))
22338 acronym = CHAR_TABLE_REF (Vglyphless_char_display, it->c);
22339 str = STRINGP (acronym) ? SSDATA (acronym) : "";
22340 }
22341 else
22342 {
22343 xassert (it->glyphless_method == GLYPHLESS_DISPLAY_HEX_CODE);
22344 sprintf (buf, "%0*X", it->c < 0x10000 ? 4 : 6, it->c);
22345 str = buf;
22346 }
22347 for (len = 0; str[len] && ASCII_BYTE_P (str[len]); len++)
22348 code[len] = font->driver->encode_char (font, str[len]);
22349 upper_len = (len + 1) / 2;
22350 font->driver->text_extents (font, code, upper_len,
22351 &metrics_upper);
22352 font->driver->text_extents (font, code + upper_len, len - upper_len,
22353 &metrics_lower);
22354
22355
22356
22357 /* +4 is for vertical bars of a box plus 1-pixel spaces at both side. */
22358 width = max (metrics_upper.width, metrics_lower.width) + 4;
22359 upper_xoff = upper_yoff = 2; /* the typical case */
22360 if (base_width >= width)
22361 {
22362 /* Align the upper to the left, the lower to the right. */
22363 it->pixel_width = base_width;
22364 lower_xoff = base_width - 2 - metrics_lower.width;
22365 }
22366 else
22367 {
22368 /* Center the shorter one. */
22369 it->pixel_width = width;
22370 if (metrics_upper.width >= metrics_lower.width)
22371 lower_xoff = (width - metrics_lower.width) / 2;
22372 else
22373 {
22374 /* FIXME: This code doesn't look right. It formerly was
22375 missing the "lower_xoff = 0;", which couldn't have
22376 been right since it left lower_xoff uninitialized. */
22377 lower_xoff = 0;
22378 upper_xoff = (width - metrics_upper.width) / 2;
22379 }
22380 }
22381
22382 /* +5 is for horizontal bars of a box plus 1-pixel spaces at
22383 top, bottom, and between upper and lower strings. */
22384 height = (metrics_upper.ascent + metrics_upper.descent
22385 + metrics_lower.ascent + metrics_lower.descent) + 5;
22386 /* Center vertically.
22387 H:base_height, D:base_descent
22388 h:height, ld:lower_descent, la:lower_ascent, ud:upper_descent
22389
22390 ascent = - (D - H/2 - h/2 + 1); "+ 1" for rounding up
22391 descent = D - H/2 + h/2;
22392 lower_yoff = descent - 2 - ld;
22393 upper_yoff = lower_yoff - la - 1 - ud; */
22394 ascent = - (it->descent - (base_height + height + 1) / 2);
22395 descent = it->descent - (base_height - height) / 2;
22396 lower_yoff = descent - 2 - metrics_lower.descent;
22397 upper_yoff = (lower_yoff - metrics_lower.ascent - 1
22398 - metrics_upper.descent);
22399 /* Don't make the height shorter than the base height. */
22400 if (height > base_height)
22401 {
22402 it->ascent = ascent;
22403 it->descent = descent;
22404 }
22405 }
22406
22407 it->phys_ascent = it->ascent;
22408 it->phys_descent = it->descent;
22409 if (it->glyph_row)
22410 append_glyphless_glyph (it, face_id, for_no_font, len,
22411 upper_xoff, upper_yoff,
22412 lower_xoff, lower_yoff);
22413 it->nglyphs = 1;
22414 take_vertical_position_into_account (it);
22415 }
22416
22417
22418 /* RIF:
22419 Produce glyphs/get display metrics for the display element IT is
22420 loaded with. See the description of struct it in dispextern.h
22421 for an overview of struct it. */
22422
22423 void
22424 x_produce_glyphs (struct it *it)
22425 {
22426 int extra_line_spacing = it->extra_line_spacing;
22427
22428 it->glyph_not_available_p = 0;
22429
22430 if (it->what == IT_CHARACTER)
22431 {
22432 XChar2b char2b;
22433 struct face *face = FACE_FROM_ID (it->f, it->face_id);
22434 struct font *font = face->font;
22435 struct font_metrics *pcm = NULL;
22436 int boff; /* baseline offset */
22437
22438 if (font == NULL)
22439 {
22440 /* When no suitable font is found, display this character by
22441 the method specified in the first extra slot of
22442 Vglyphless_char_display. */
22443 Lisp_Object acronym = lookup_glyphless_char_display (-1, it);
22444
22445 xassert (it->what == IT_GLYPHLESS);
22446 produce_glyphless_glyph (it, 1, STRINGP (acronym) ? acronym : Qnil);
22447 goto done;
22448 }
22449
22450 boff = font->baseline_offset;
22451 if (font->vertical_centering)
22452 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
22453
22454 if (it->char_to_display != '\n' && it->char_to_display != '\t')
22455 {
22456 int stretched_p;
22457
22458 it->nglyphs = 1;
22459
22460 if (it->override_ascent >= 0)
22461 {
22462 it->ascent = it->override_ascent;
22463 it->descent = it->override_descent;
22464 boff = it->override_boff;
22465 }
22466 else
22467 {
22468 it->ascent = FONT_BASE (font) + boff;
22469 it->descent = FONT_DESCENT (font) - boff;
22470 }
22471
22472 if (get_char_glyph_code (it->char_to_display, font, &char2b))
22473 {
22474 pcm = get_per_char_metric (font, &char2b);
22475 if (pcm->width == 0
22476 && pcm->rbearing == 0 && pcm->lbearing == 0)
22477 pcm = NULL;
22478 }
22479
22480 if (pcm)
22481 {
22482 it->phys_ascent = pcm->ascent + boff;
22483 it->phys_descent = pcm->descent - boff;
22484 it->pixel_width = pcm->width;
22485 }
22486 else
22487 {
22488 it->glyph_not_available_p = 1;
22489 it->phys_ascent = it->ascent;
22490 it->phys_descent = it->descent;
22491 it->pixel_width = font->space_width;
22492 }
22493
22494 if (it->constrain_row_ascent_descent_p)
22495 {
22496 if (it->descent > it->max_descent)
22497 {
22498 it->ascent += it->descent - it->max_descent;
22499 it->descent = it->max_descent;
22500 }
22501 if (it->ascent > it->max_ascent)
22502 {
22503 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
22504 it->ascent = it->max_ascent;
22505 }
22506 it->phys_ascent = min (it->phys_ascent, it->ascent);
22507 it->phys_descent = min (it->phys_descent, it->descent);
22508 extra_line_spacing = 0;
22509 }
22510
22511 /* If this is a space inside a region of text with
22512 `space-width' property, change its width. */
22513 stretched_p = it->char_to_display == ' ' && !NILP (it->space_width);
22514 if (stretched_p)
22515 it->pixel_width *= XFLOATINT (it->space_width);
22516
22517 /* If face has a box, add the box thickness to the character
22518 height. If character has a box line to the left and/or
22519 right, add the box line width to the character's width. */
22520 if (face->box != FACE_NO_BOX)
22521 {
22522 int thick = face->box_line_width;
22523
22524 if (thick > 0)
22525 {
22526 it->ascent += thick;
22527 it->descent += thick;
22528 }
22529 else
22530 thick = -thick;
22531
22532 if (it->start_of_box_run_p)
22533 it->pixel_width += thick;
22534 if (it->end_of_box_run_p)
22535 it->pixel_width += thick;
22536 }
22537
22538 /* If face has an overline, add the height of the overline
22539 (1 pixel) and a 1 pixel margin to the character height. */
22540 if (face->overline_p)
22541 it->ascent += overline_margin;
22542
22543 if (it->constrain_row_ascent_descent_p)
22544 {
22545 if (it->ascent > it->max_ascent)
22546 it->ascent = it->max_ascent;
22547 if (it->descent > it->max_descent)
22548 it->descent = it->max_descent;
22549 }
22550
22551 take_vertical_position_into_account (it);
22552
22553 /* If we have to actually produce glyphs, do it. */
22554 if (it->glyph_row)
22555 {
22556 if (stretched_p)
22557 {
22558 /* Translate a space with a `space-width' property
22559 into a stretch glyph. */
22560 int ascent = (((it->ascent + it->descent) * FONT_BASE (font))
22561 / FONT_HEIGHT (font));
22562 append_stretch_glyph (it, it->object, it->pixel_width,
22563 it->ascent + it->descent, ascent);
22564 }
22565 else
22566 append_glyph (it);
22567
22568 /* If characters with lbearing or rbearing are displayed
22569 in this line, record that fact in a flag of the
22570 glyph row. This is used to optimize X output code. */
22571 if (pcm && (pcm->lbearing < 0 || pcm->rbearing > pcm->width))
22572 it->glyph_row->contains_overlapping_glyphs_p = 1;
22573 }
22574 if (! stretched_p && it->pixel_width == 0)
22575 /* We assure that all visible glyphs have at least 1-pixel
22576 width. */
22577 it->pixel_width = 1;
22578 }
22579 else if (it->char_to_display == '\n')
22580 {
22581 /* A newline has no width, but we need the height of the
22582 line. But if previous part of the line sets a height,
22583 don't increase that height */
22584
22585 Lisp_Object height;
22586 Lisp_Object total_height = Qnil;
22587
22588 it->override_ascent = -1;
22589 it->pixel_width = 0;
22590 it->nglyphs = 0;
22591
22592 height = get_it_property (it, Qline_height);
22593 /* Split (line-height total-height) list */
22594 if (CONSP (height)
22595 && CONSP (XCDR (height))
22596 && NILP (XCDR (XCDR (height))))
22597 {
22598 total_height = XCAR (XCDR (height));
22599 height = XCAR (height);
22600 }
22601 height = calc_line_height_property (it, height, font, boff, 1);
22602
22603 if (it->override_ascent >= 0)
22604 {
22605 it->ascent = it->override_ascent;
22606 it->descent = it->override_descent;
22607 boff = it->override_boff;
22608 }
22609 else
22610 {
22611 it->ascent = FONT_BASE (font) + boff;
22612 it->descent = FONT_DESCENT (font) - boff;
22613 }
22614
22615 if (EQ (height, Qt))
22616 {
22617 if (it->descent > it->max_descent)
22618 {
22619 it->ascent += it->descent - it->max_descent;
22620 it->descent = it->max_descent;
22621 }
22622 if (it->ascent > it->max_ascent)
22623 {
22624 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
22625 it->ascent = it->max_ascent;
22626 }
22627 it->phys_ascent = min (it->phys_ascent, it->ascent);
22628 it->phys_descent = min (it->phys_descent, it->descent);
22629 it->constrain_row_ascent_descent_p = 1;
22630 extra_line_spacing = 0;
22631 }
22632 else
22633 {
22634 Lisp_Object spacing;
22635
22636 it->phys_ascent = it->ascent;
22637 it->phys_descent = it->descent;
22638
22639 if ((it->max_ascent > 0 || it->max_descent > 0)
22640 && face->box != FACE_NO_BOX
22641 && face->box_line_width > 0)
22642 {
22643 it->ascent += face->box_line_width;
22644 it->descent += face->box_line_width;
22645 }
22646 if (!NILP (height)
22647 && XINT (height) > it->ascent + it->descent)
22648 it->ascent = XINT (height) - it->descent;
22649
22650 if (!NILP (total_height))
22651 spacing = calc_line_height_property (it, total_height, font, boff, 0);
22652 else
22653 {
22654 spacing = get_it_property (it, Qline_spacing);
22655 spacing = calc_line_height_property (it, spacing, font, boff, 0);
22656 }
22657 if (INTEGERP (spacing))
22658 {
22659 extra_line_spacing = XINT (spacing);
22660 if (!NILP (total_height))
22661 extra_line_spacing -= (it->phys_ascent + it->phys_descent);
22662 }
22663 }
22664 }
22665 else /* i.e. (it->char_to_display == '\t') */
22666 {
22667 if (font->space_width > 0)
22668 {
22669 int tab_width = it->tab_width * font->space_width;
22670 int x = it->current_x + it->continuation_lines_width;
22671 int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width;
22672
22673 /* If the distance from the current position to the next tab
22674 stop is less than a space character width, use the
22675 tab stop after that. */
22676 if (next_tab_x - x < font->space_width)
22677 next_tab_x += tab_width;
22678
22679 it->pixel_width = next_tab_x - x;
22680 it->nglyphs = 1;
22681 it->ascent = it->phys_ascent = FONT_BASE (font) + boff;
22682 it->descent = it->phys_descent = FONT_DESCENT (font) - boff;
22683
22684 if (it->glyph_row)
22685 {
22686 append_stretch_glyph (it, it->object, it->pixel_width,
22687 it->ascent + it->descent, it->ascent);
22688 }
22689 }
22690 else
22691 {
22692 it->pixel_width = 0;
22693 it->nglyphs = 1;
22694 }
22695 }
22696 }
22697 else if (it->what == IT_COMPOSITION && it->cmp_it.ch < 0)
22698 {
22699 /* A static composition.
22700
22701 Note: A composition is represented as one glyph in the
22702 glyph matrix. There are no padding glyphs.
22703
22704 Important note: pixel_width, ascent, and descent are the
22705 values of what is drawn by draw_glyphs (i.e. the values of
22706 the overall glyphs composed). */
22707 struct face *face = FACE_FROM_ID (it->f, it->face_id);
22708 int boff; /* baseline offset */
22709 struct composition *cmp = composition_table[it->cmp_it.id];
22710 int glyph_len = cmp->glyph_len;
22711 struct font *font = face->font;
22712
22713 it->nglyphs = 1;
22714
22715 /* If we have not yet calculated pixel size data of glyphs of
22716 the composition for the current face font, calculate them
22717 now. Theoretically, we have to check all fonts for the
22718 glyphs, but that requires much time and memory space. So,
22719 here we check only the font of the first glyph. This may
22720 lead to incorrect display, but it's very rare, and C-l
22721 (recenter-top-bottom) can correct the display anyway. */
22722 if (! cmp->font || cmp->font != font)
22723 {
22724 /* Ascent and descent of the font of the first character
22725 of this composition (adjusted by baseline offset).
22726 Ascent and descent of overall glyphs should not be less
22727 than these, respectively. */
22728 int font_ascent, font_descent, font_height;
22729 /* Bounding box of the overall glyphs. */
22730 int leftmost, rightmost, lowest, highest;
22731 int lbearing, rbearing;
22732 int i, width, ascent, descent;
22733 int left_padded = 0, right_padded = 0;
22734 int c;
22735 XChar2b char2b;
22736 struct font_metrics *pcm;
22737 int font_not_found_p;
22738 EMACS_INT pos;
22739
22740 for (glyph_len = cmp->glyph_len; glyph_len > 0; glyph_len--)
22741 if ((c = COMPOSITION_GLYPH (cmp, glyph_len - 1)) != '\t')
22742 break;
22743 if (glyph_len < cmp->glyph_len)
22744 right_padded = 1;
22745 for (i = 0; i < glyph_len; i++)
22746 {
22747 if ((c = COMPOSITION_GLYPH (cmp, i)) != '\t')
22748 break;
22749 cmp->offsets[i * 2] = cmp->offsets[i * 2 + 1] = 0;
22750 }
22751 if (i > 0)
22752 left_padded = 1;
22753
22754 pos = (STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
22755 : IT_CHARPOS (*it));
22756 /* If no suitable font is found, use the default font. */
22757 font_not_found_p = font == NULL;
22758 if (font_not_found_p)
22759 {
22760 face = face->ascii_face;
22761 font = face->font;
22762 }
22763 boff = font->baseline_offset;
22764 if (font->vertical_centering)
22765 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
22766 font_ascent = FONT_BASE (font) + boff;
22767 font_descent = FONT_DESCENT (font) - boff;
22768 font_height = FONT_HEIGHT (font);
22769
22770 cmp->font = (void *) font;
22771
22772 pcm = NULL;
22773 if (! font_not_found_p)
22774 {
22775 get_char_face_and_encoding (it->f, c, it->face_id,
22776 &char2b, 0);
22777 pcm = get_per_char_metric (font, &char2b);
22778 }
22779
22780 /* Initialize the bounding box. */
22781 if (pcm)
22782 {
22783 width = pcm->width;
22784 ascent = pcm->ascent;
22785 descent = pcm->descent;
22786 lbearing = pcm->lbearing;
22787 rbearing = pcm->rbearing;
22788 }
22789 else
22790 {
22791 width = font->space_width;
22792 ascent = FONT_BASE (font);
22793 descent = FONT_DESCENT (font);
22794 lbearing = 0;
22795 rbearing = width;
22796 }
22797
22798 rightmost = width;
22799 leftmost = 0;
22800 lowest = - descent + boff;
22801 highest = ascent + boff;
22802
22803 if (! font_not_found_p
22804 && font->default_ascent
22805 && CHAR_TABLE_P (Vuse_default_ascent)
22806 && !NILP (Faref (Vuse_default_ascent,
22807 make_number (it->char_to_display))))
22808 highest = font->default_ascent + boff;
22809
22810 /* Draw the first glyph at the normal position. It may be
22811 shifted to right later if some other glyphs are drawn
22812 at the left. */
22813 cmp->offsets[i * 2] = 0;
22814 cmp->offsets[i * 2 + 1] = boff;
22815 cmp->lbearing = lbearing;
22816 cmp->rbearing = rbearing;
22817
22818 /* Set cmp->offsets for the remaining glyphs. */
22819 for (i++; i < glyph_len; i++)
22820 {
22821 int left, right, btm, top;
22822 int ch = COMPOSITION_GLYPH (cmp, i);
22823 int face_id;
22824 struct face *this_face;
22825
22826 if (ch == '\t')
22827 ch = ' ';
22828 face_id = FACE_FOR_CHAR (it->f, face, ch, pos, it->string);
22829 this_face = FACE_FROM_ID (it->f, face_id);
22830 font = this_face->font;
22831
22832 if (font == NULL)
22833 pcm = NULL;
22834 else
22835 {
22836 get_char_face_and_encoding (it->f, ch, face_id,
22837 &char2b, 0);
22838 pcm = get_per_char_metric (font, &char2b);
22839 }
22840 if (! pcm)
22841 cmp->offsets[i * 2] = cmp->offsets[i * 2 + 1] = 0;
22842 else
22843 {
22844 width = pcm->width;
22845 ascent = pcm->ascent;
22846 descent = pcm->descent;
22847 lbearing = pcm->lbearing;
22848 rbearing = pcm->rbearing;
22849 if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS)
22850 {
22851 /* Relative composition with or without
22852 alternate chars. */
22853 left = (leftmost + rightmost - width) / 2;
22854 btm = - descent + boff;
22855 if (font->relative_compose
22856 && (! CHAR_TABLE_P (Vignore_relative_composition)
22857 || NILP (Faref (Vignore_relative_composition,
22858 make_number (ch)))))
22859 {
22860
22861 if (- descent >= font->relative_compose)
22862 /* One extra pixel between two glyphs. */
22863 btm = highest + 1;
22864 else if (ascent <= 0)
22865 /* One extra pixel between two glyphs. */
22866 btm = lowest - 1 - ascent - descent;
22867 }
22868 }
22869 else
22870 {
22871 /* A composition rule is specified by an integer
22872 value that encodes global and new reference
22873 points (GREF and NREF). GREF and NREF are
22874 specified by numbers as below:
22875
22876 0---1---2 -- ascent
22877 | |
22878 | |
22879 | |
22880 9--10--11 -- center
22881 | |
22882 ---3---4---5--- baseline
22883 | |
22884 6---7---8 -- descent
22885 */
22886 int rule = COMPOSITION_RULE (cmp, i);
22887 int gref, nref, grefx, grefy, nrefx, nrefy, xoff, yoff;
22888
22889 COMPOSITION_DECODE_RULE (rule, gref, nref, xoff, yoff);
22890 grefx = gref % 3, nrefx = nref % 3;
22891 grefy = gref / 3, nrefy = nref / 3;
22892 if (xoff)
22893 xoff = font_height * (xoff - 128) / 256;
22894 if (yoff)
22895 yoff = font_height * (yoff - 128) / 256;
22896
22897 left = (leftmost
22898 + grefx * (rightmost - leftmost) / 2
22899 - nrefx * width / 2
22900 + xoff);
22901
22902 btm = ((grefy == 0 ? highest
22903 : grefy == 1 ? 0
22904 : grefy == 2 ? lowest
22905 : (highest + lowest) / 2)
22906 - (nrefy == 0 ? ascent + descent
22907 : nrefy == 1 ? descent - boff
22908 : nrefy == 2 ? 0
22909 : (ascent + descent) / 2)
22910 + yoff);
22911 }
22912
22913 cmp->offsets[i * 2] = left;
22914 cmp->offsets[i * 2 + 1] = btm + descent;
22915
22916 /* Update the bounding box of the overall glyphs. */
22917 if (width > 0)
22918 {
22919 right = left + width;
22920 if (left < leftmost)
22921 leftmost = left;
22922 if (right > rightmost)
22923 rightmost = right;
22924 }
22925 top = btm + descent + ascent;
22926 if (top > highest)
22927 highest = top;
22928 if (btm < lowest)
22929 lowest = btm;
22930
22931 if (cmp->lbearing > left + lbearing)
22932 cmp->lbearing = left + lbearing;
22933 if (cmp->rbearing < left + rbearing)
22934 cmp->rbearing = left + rbearing;
22935 }
22936 }
22937
22938 /* If there are glyphs whose x-offsets are negative,
22939 shift all glyphs to the right and make all x-offsets
22940 non-negative. */
22941 if (leftmost < 0)
22942 {
22943 for (i = 0; i < cmp->glyph_len; i++)
22944 cmp->offsets[i * 2] -= leftmost;
22945 rightmost -= leftmost;
22946 cmp->lbearing -= leftmost;
22947 cmp->rbearing -= leftmost;
22948 }
22949
22950 if (left_padded && cmp->lbearing < 0)
22951 {
22952 for (i = 0; i < cmp->glyph_len; i++)
22953 cmp->offsets[i * 2] -= cmp->lbearing;
22954 rightmost -= cmp->lbearing;
22955 cmp->rbearing -= cmp->lbearing;
22956 cmp->lbearing = 0;
22957 }
22958 if (right_padded && rightmost < cmp->rbearing)
22959 {
22960 rightmost = cmp->rbearing;
22961 }
22962
22963 cmp->pixel_width = rightmost;
22964 cmp->ascent = highest;
22965 cmp->descent = - lowest;
22966 if (cmp->ascent < font_ascent)
22967 cmp->ascent = font_ascent;
22968 if (cmp->descent < font_descent)
22969 cmp->descent = font_descent;
22970 }
22971
22972 if (it->glyph_row
22973 && (cmp->lbearing < 0
22974 || cmp->rbearing > cmp->pixel_width))
22975 it->glyph_row->contains_overlapping_glyphs_p = 1;
22976
22977 it->pixel_width = cmp->pixel_width;
22978 it->ascent = it->phys_ascent = cmp->ascent;
22979 it->descent = it->phys_descent = cmp->descent;
22980 if (face->box != FACE_NO_BOX)
22981 {
22982 int thick = face->box_line_width;
22983
22984 if (thick > 0)
22985 {
22986 it->ascent += thick;
22987 it->descent += thick;
22988 }
22989 else
22990 thick = - thick;
22991
22992 if (it->start_of_box_run_p)
22993 it->pixel_width += thick;
22994 if (it->end_of_box_run_p)
22995 it->pixel_width += thick;
22996 }
22997
22998 /* If face has an overline, add the height of the overline
22999 (1 pixel) and a 1 pixel margin to the character height. */
23000 if (face->overline_p)
23001 it->ascent += overline_margin;
23002
23003 take_vertical_position_into_account (it);
23004 if (it->ascent < 0)
23005 it->ascent = 0;
23006 if (it->descent < 0)
23007 it->descent = 0;
23008
23009 if (it->glyph_row)
23010 append_composite_glyph (it);
23011 }
23012 else if (it->what == IT_COMPOSITION)
23013 {
23014 /* A dynamic (automatic) composition. */
23015 struct face *face = FACE_FROM_ID (it->f, it->face_id);
23016 Lisp_Object gstring;
23017 struct font_metrics metrics;
23018
23019 gstring = composition_gstring_from_id (it->cmp_it.id);
23020 it->pixel_width
23021 = composition_gstring_width (gstring, it->cmp_it.from, it->cmp_it.to,
23022 &metrics);
23023 if (it->glyph_row
23024 && (metrics.lbearing < 0 || metrics.rbearing > metrics.width))
23025 it->glyph_row->contains_overlapping_glyphs_p = 1;
23026 it->ascent = it->phys_ascent = metrics.ascent;
23027 it->descent = it->phys_descent = metrics.descent;
23028 if (face->box != FACE_NO_BOX)
23029 {
23030 int thick = face->box_line_width;
23031
23032 if (thick > 0)
23033 {
23034 it->ascent += thick;
23035 it->descent += thick;
23036 }
23037 else
23038 thick = - thick;
23039
23040 if (it->start_of_box_run_p)
23041 it->pixel_width += thick;
23042 if (it->end_of_box_run_p)
23043 it->pixel_width += thick;
23044 }
23045 /* If face has an overline, add the height of the overline
23046 (1 pixel) and a 1 pixel margin to the character height. */
23047 if (face->overline_p)
23048 it->ascent += overline_margin;
23049 take_vertical_position_into_account (it);
23050 if (it->ascent < 0)
23051 it->ascent = 0;
23052 if (it->descent < 0)
23053 it->descent = 0;
23054
23055 if (it->glyph_row)
23056 append_composite_glyph (it);
23057 }
23058 else if (it->what == IT_GLYPHLESS)
23059 produce_glyphless_glyph (it, 0, Qnil);
23060 else if (it->what == IT_IMAGE)
23061 produce_image_glyph (it);
23062 else if (it->what == IT_STRETCH)
23063 produce_stretch_glyph (it);
23064
23065 done:
23066 /* Accumulate dimensions. Note: can't assume that it->descent > 0
23067 because this isn't true for images with `:ascent 100'. */
23068 xassert (it->ascent >= 0 && it->descent >= 0);
23069 if (it->area == TEXT_AREA)
23070 it->current_x += it->pixel_width;
23071
23072 if (extra_line_spacing > 0)
23073 {
23074 it->descent += extra_line_spacing;
23075 if (extra_line_spacing > it->max_extra_line_spacing)
23076 it->max_extra_line_spacing = extra_line_spacing;
23077 }
23078
23079 it->max_ascent = max (it->max_ascent, it->ascent);
23080 it->max_descent = max (it->max_descent, it->descent);
23081 it->max_phys_ascent = max (it->max_phys_ascent, it->phys_ascent);
23082 it->max_phys_descent = max (it->max_phys_descent, it->phys_descent);
23083 }
23084
23085 /* EXPORT for RIF:
23086 Output LEN glyphs starting at START at the nominal cursor position.
23087 Advance the nominal cursor over the text. The global variable
23088 updated_window contains the window being updated, updated_row is
23089 the glyph row being updated, and updated_area is the area of that
23090 row being updated. */
23091
23092 void
23093 x_write_glyphs (struct glyph *start, int len)
23094 {
23095 int x, hpos;
23096
23097 xassert (updated_window && updated_row);
23098 BLOCK_INPUT;
23099
23100 /* Write glyphs. */
23101
23102 hpos = start - updated_row->glyphs[updated_area];
23103 x = draw_glyphs (updated_window, output_cursor.x,
23104 updated_row, updated_area,
23105 hpos, hpos + len,
23106 DRAW_NORMAL_TEXT, 0);
23107
23108 /* Invalidate old phys cursor if the glyph at its hpos is redrawn. */
23109 if (updated_area == TEXT_AREA
23110 && updated_window->phys_cursor_on_p
23111 && updated_window->phys_cursor.vpos == output_cursor.vpos
23112 && updated_window->phys_cursor.hpos >= hpos
23113 && updated_window->phys_cursor.hpos < hpos + len)
23114 updated_window->phys_cursor_on_p = 0;
23115
23116 UNBLOCK_INPUT;
23117
23118 /* Advance the output cursor. */
23119 output_cursor.hpos += len;
23120 output_cursor.x = x;
23121 }
23122
23123
23124 /* EXPORT for RIF:
23125 Insert LEN glyphs from START at the nominal cursor position. */
23126
23127 void
23128 x_insert_glyphs (struct glyph *start, int len)
23129 {
23130 struct frame *f;
23131 struct window *w;
23132 int line_height, shift_by_width, shifted_region_width;
23133 struct glyph_row *row;
23134 struct glyph *glyph;
23135 int frame_x, frame_y;
23136 EMACS_INT hpos;
23137
23138 xassert (updated_window && updated_row);
23139 BLOCK_INPUT;
23140 w = updated_window;
23141 f = XFRAME (WINDOW_FRAME (w));
23142
23143 /* Get the height of the line we are in. */
23144 row = updated_row;
23145 line_height = row->height;
23146
23147 /* Get the width of the glyphs to insert. */
23148 shift_by_width = 0;
23149 for (glyph = start; glyph < start + len; ++glyph)
23150 shift_by_width += glyph->pixel_width;
23151
23152 /* Get the width of the region to shift right. */
23153 shifted_region_width = (window_box_width (w, updated_area)
23154 - output_cursor.x
23155 - shift_by_width);
23156
23157 /* Shift right. */
23158 frame_x = window_box_left (w, updated_area) + output_cursor.x;
23159 frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, output_cursor.y);
23160
23161 FRAME_RIF (f)->shift_glyphs_for_insert (f, frame_x, frame_y, shifted_region_width,
23162 line_height, shift_by_width);
23163
23164 /* Write the glyphs. */
23165 hpos = start - row->glyphs[updated_area];
23166 draw_glyphs (w, output_cursor.x, row, updated_area,
23167 hpos, hpos + len,
23168 DRAW_NORMAL_TEXT, 0);
23169
23170 /* Advance the output cursor. */
23171 output_cursor.hpos += len;
23172 output_cursor.x += shift_by_width;
23173 UNBLOCK_INPUT;
23174 }
23175
23176
23177 /* EXPORT for RIF:
23178 Erase the current text line from the nominal cursor position
23179 (inclusive) to pixel column TO_X (exclusive). The idea is that
23180 everything from TO_X onward is already erased.
23181
23182 TO_X is a pixel position relative to updated_area of
23183 updated_window. TO_X == -1 means clear to the end of this area. */
23184
23185 void
23186 x_clear_end_of_line (int to_x)
23187 {
23188 struct frame *f;
23189 struct window *w = updated_window;
23190 int max_x, min_y, max_y;
23191 int from_x, from_y, to_y;
23192
23193 xassert (updated_window && updated_row);
23194 f = XFRAME (w->frame);
23195
23196 if (updated_row->full_width_p)
23197 max_x = WINDOW_TOTAL_WIDTH (w);
23198 else
23199 max_x = window_box_width (w, updated_area);
23200 max_y = window_text_bottom_y (w);
23201
23202 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
23203 of window. For TO_X > 0, truncate to end of drawing area. */
23204 if (to_x == 0)
23205 return;
23206 else if (to_x < 0)
23207 to_x = max_x;
23208 else
23209 to_x = min (to_x, max_x);
23210
23211 to_y = min (max_y, output_cursor.y + updated_row->height);
23212
23213 /* Notice if the cursor will be cleared by this operation. */
23214 if (!updated_row->full_width_p)
23215 notice_overwritten_cursor (w, updated_area,
23216 output_cursor.x, -1,
23217 updated_row->y,
23218 MATRIX_ROW_BOTTOM_Y (updated_row));
23219
23220 from_x = output_cursor.x;
23221
23222 /* Translate to frame coordinates. */
23223 if (updated_row->full_width_p)
23224 {
23225 from_x = WINDOW_TO_FRAME_PIXEL_X (w, from_x);
23226 to_x = WINDOW_TO_FRAME_PIXEL_X (w, to_x);
23227 }
23228 else
23229 {
23230 int area_left = window_box_left (w, updated_area);
23231 from_x += area_left;
23232 to_x += area_left;
23233 }
23234
23235 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
23236 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, max (min_y, output_cursor.y));
23237 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, to_y);
23238
23239 /* Prevent inadvertently clearing to end of the X window. */
23240 if (to_x > from_x && to_y > from_y)
23241 {
23242 BLOCK_INPUT;
23243 FRAME_RIF (f)->clear_frame_area (f, from_x, from_y,
23244 to_x - from_x, to_y - from_y);
23245 UNBLOCK_INPUT;
23246 }
23247 }
23248
23249 #endif /* HAVE_WINDOW_SYSTEM */
23250
23251
23252 \f
23253 /***********************************************************************
23254 Cursor types
23255 ***********************************************************************/
23256
23257 /* Value is the internal representation of the specified cursor type
23258 ARG. If type is BAR_CURSOR, return in *WIDTH the specified width
23259 of the bar cursor. */
23260
23261 static enum text_cursor_kinds
23262 get_specified_cursor_type (Lisp_Object arg, int *width)
23263 {
23264 enum text_cursor_kinds type;
23265
23266 if (NILP (arg))
23267 return NO_CURSOR;
23268
23269 if (EQ (arg, Qbox))
23270 return FILLED_BOX_CURSOR;
23271
23272 if (EQ (arg, Qhollow))
23273 return HOLLOW_BOX_CURSOR;
23274
23275 if (EQ (arg, Qbar))
23276 {
23277 *width = 2;
23278 return BAR_CURSOR;
23279 }
23280
23281 if (CONSP (arg)
23282 && EQ (XCAR (arg), Qbar)
23283 && INTEGERP (XCDR (arg))
23284 && XINT (XCDR (arg)) >= 0)
23285 {
23286 *width = XINT (XCDR (arg));
23287 return BAR_CURSOR;
23288 }
23289
23290 if (EQ (arg, Qhbar))
23291 {
23292 *width = 2;
23293 return HBAR_CURSOR;
23294 }
23295
23296 if (CONSP (arg)
23297 && EQ (XCAR (arg), Qhbar)
23298 && INTEGERP (XCDR (arg))
23299 && XINT (XCDR (arg)) >= 0)
23300 {
23301 *width = XINT (XCDR (arg));
23302 return HBAR_CURSOR;
23303 }
23304
23305 /* Treat anything unknown as "hollow box cursor".
23306 It was bad to signal an error; people have trouble fixing
23307 .Xdefaults with Emacs, when it has something bad in it. */
23308 type = HOLLOW_BOX_CURSOR;
23309
23310 return type;
23311 }
23312
23313 /* Set the default cursor types for specified frame. */
23314 void
23315 set_frame_cursor_types (struct frame *f, Lisp_Object arg)
23316 {
23317 int width = 1;
23318 Lisp_Object tem;
23319
23320 FRAME_DESIRED_CURSOR (f) = get_specified_cursor_type (arg, &width);
23321 FRAME_CURSOR_WIDTH (f) = width;
23322
23323 /* By default, set up the blink-off state depending on the on-state. */
23324
23325 tem = Fassoc (arg, Vblink_cursor_alist);
23326 if (!NILP (tem))
23327 {
23328 FRAME_BLINK_OFF_CURSOR (f)
23329 = get_specified_cursor_type (XCDR (tem), &width);
23330 FRAME_BLINK_OFF_CURSOR_WIDTH (f) = width;
23331 }
23332 else
23333 FRAME_BLINK_OFF_CURSOR (f) = DEFAULT_CURSOR;
23334 }
23335
23336
23337 #ifdef HAVE_WINDOW_SYSTEM
23338
23339 /* Return the cursor we want to be displayed in window W. Return
23340 width of bar/hbar cursor through WIDTH arg. Return with
23341 ACTIVE_CURSOR arg set to 1 if cursor in window W is `active'
23342 (i.e. if the `system caret' should track this cursor).
23343
23344 In a mini-buffer window, we want the cursor only to appear if we
23345 are reading input from this window. For the selected window, we
23346 want the cursor type given by the frame parameter or buffer local
23347 setting of cursor-type. If explicitly marked off, draw no cursor.
23348 In all other cases, we want a hollow box cursor. */
23349
23350 static enum text_cursor_kinds
23351 get_window_cursor_type (struct window *w, struct glyph *glyph, int *width,
23352 int *active_cursor)
23353 {
23354 struct frame *f = XFRAME (w->frame);
23355 struct buffer *b = XBUFFER (w->buffer);
23356 int cursor_type = DEFAULT_CURSOR;
23357 Lisp_Object alt_cursor;
23358 int non_selected = 0;
23359
23360 *active_cursor = 1;
23361
23362 /* Echo area */
23363 if (cursor_in_echo_area
23364 && FRAME_HAS_MINIBUF_P (f)
23365 && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
23366 {
23367 if (w == XWINDOW (echo_area_window))
23368 {
23369 if (EQ (BVAR (b, cursor_type), Qt) || NILP (BVAR (b, cursor_type)))
23370 {
23371 *width = FRAME_CURSOR_WIDTH (f);
23372 return FRAME_DESIRED_CURSOR (f);
23373 }
23374 else
23375 return get_specified_cursor_type (BVAR (b, cursor_type), width);
23376 }
23377
23378 *active_cursor = 0;
23379 non_selected = 1;
23380 }
23381
23382 /* Detect a nonselected window or nonselected frame. */
23383 else if (w != XWINDOW (f->selected_window)
23384 || f != FRAME_X_DISPLAY_INFO (f)->x_highlight_frame)
23385 {
23386 *active_cursor = 0;
23387
23388 if (MINI_WINDOW_P (w) && minibuf_level == 0)
23389 return NO_CURSOR;
23390
23391 non_selected = 1;
23392 }
23393
23394 /* Never display a cursor in a window in which cursor-type is nil. */
23395 if (NILP (BVAR (b, cursor_type)))
23396 return NO_CURSOR;
23397
23398 /* Get the normal cursor type for this window. */
23399 if (EQ (BVAR (b, cursor_type), Qt))
23400 {
23401 cursor_type = FRAME_DESIRED_CURSOR (f);
23402 *width = FRAME_CURSOR_WIDTH (f);
23403 }
23404 else
23405 cursor_type = get_specified_cursor_type (BVAR (b, cursor_type), width);
23406
23407 /* Use cursor-in-non-selected-windows instead
23408 for non-selected window or frame. */
23409 if (non_selected)
23410 {
23411 alt_cursor = BVAR (b, cursor_in_non_selected_windows);
23412 if (!EQ (Qt, alt_cursor))
23413 return get_specified_cursor_type (alt_cursor, width);
23414 /* t means modify the normal cursor type. */
23415 if (cursor_type == FILLED_BOX_CURSOR)
23416 cursor_type = HOLLOW_BOX_CURSOR;
23417 else if (cursor_type == BAR_CURSOR && *width > 1)
23418 --*width;
23419 return cursor_type;
23420 }
23421
23422 /* Use normal cursor if not blinked off. */
23423 if (!w->cursor_off_p)
23424 {
23425 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
23426 {
23427 if (cursor_type == FILLED_BOX_CURSOR)
23428 {
23429 /* Using a block cursor on large images can be very annoying.
23430 So use a hollow cursor for "large" images.
23431 If image is not transparent (no mask), also use hollow cursor. */
23432 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
23433 if (img != NULL && IMAGEP (img->spec))
23434 {
23435 /* Arbitrarily, interpret "Large" as >32x32 and >NxN
23436 where N = size of default frame font size.
23437 This should cover most of the "tiny" icons people may use. */
23438 if (!img->mask
23439 || img->width > max (32, WINDOW_FRAME_COLUMN_WIDTH (w))
23440 || img->height > max (32, WINDOW_FRAME_LINE_HEIGHT (w)))
23441 cursor_type = HOLLOW_BOX_CURSOR;
23442 }
23443 }
23444 else if (cursor_type != NO_CURSOR)
23445 {
23446 /* Display current only supports BOX and HOLLOW cursors for images.
23447 So for now, unconditionally use a HOLLOW cursor when cursor is
23448 not a solid box cursor. */
23449 cursor_type = HOLLOW_BOX_CURSOR;
23450 }
23451 }
23452 return cursor_type;
23453 }
23454
23455 /* Cursor is blinked off, so determine how to "toggle" it. */
23456
23457 /* First look for an entry matching the buffer's cursor-type in blink-cursor-alist. */
23458 if ((alt_cursor = Fassoc (BVAR (b, cursor_type), Vblink_cursor_alist), !NILP (alt_cursor)))
23459 return get_specified_cursor_type (XCDR (alt_cursor), width);
23460
23461 /* Then see if frame has specified a specific blink off cursor type. */
23462 if (FRAME_BLINK_OFF_CURSOR (f) != DEFAULT_CURSOR)
23463 {
23464 *width = FRAME_BLINK_OFF_CURSOR_WIDTH (f);
23465 return FRAME_BLINK_OFF_CURSOR (f);
23466 }
23467
23468 #if 0
23469 /* Some people liked having a permanently visible blinking cursor,
23470 while others had very strong opinions against it. So it was
23471 decided to remove it. KFS 2003-09-03 */
23472
23473 /* Finally perform built-in cursor blinking:
23474 filled box <-> hollow box
23475 wide [h]bar <-> narrow [h]bar
23476 narrow [h]bar <-> no cursor
23477 other type <-> no cursor */
23478
23479 if (cursor_type == FILLED_BOX_CURSOR)
23480 return HOLLOW_BOX_CURSOR;
23481
23482 if ((cursor_type == BAR_CURSOR || cursor_type == HBAR_CURSOR) && *width > 1)
23483 {
23484 *width = 1;
23485 return cursor_type;
23486 }
23487 #endif
23488
23489 return NO_CURSOR;
23490 }
23491
23492
23493 /* Notice when the text cursor of window W has been completely
23494 overwritten by a drawing operation that outputs glyphs in AREA
23495 starting at X0 and ending at X1 in the line starting at Y0 and
23496 ending at Y1. X coordinates are area-relative. X1 < 0 means all
23497 the rest of the line after X0 has been written. Y coordinates
23498 are window-relative. */
23499
23500 static void
23501 notice_overwritten_cursor (struct window *w, enum glyph_row_area area,
23502 int x0, int x1, int y0, int y1)
23503 {
23504 int cx0, cx1, cy0, cy1;
23505 struct glyph_row *row;
23506
23507 if (!w->phys_cursor_on_p)
23508 return;
23509 if (area != TEXT_AREA)
23510 return;
23511
23512 if (w->phys_cursor.vpos < 0
23513 || w->phys_cursor.vpos >= w->current_matrix->nrows
23514 || (row = w->current_matrix->rows + w->phys_cursor.vpos,
23515 !(row->enabled_p && row->displays_text_p)))
23516 return;
23517
23518 if (row->cursor_in_fringe_p)
23519 {
23520 row->cursor_in_fringe_p = 0;
23521 draw_fringe_bitmap (w, row, row->reversed_p);
23522 w->phys_cursor_on_p = 0;
23523 return;
23524 }
23525
23526 cx0 = w->phys_cursor.x;
23527 cx1 = cx0 + w->phys_cursor_width;
23528 if (x0 > cx0 || (x1 >= 0 && x1 < cx1))
23529 return;
23530
23531 /* The cursor image will be completely removed from the
23532 screen if the output area intersects the cursor area in
23533 y-direction. When we draw in [y0 y1[, and some part of
23534 the cursor is at y < y0, that part must have been drawn
23535 before. When scrolling, the cursor is erased before
23536 actually scrolling, so we don't come here. When not
23537 scrolling, the rows above the old cursor row must have
23538 changed, and in this case these rows must have written
23539 over the cursor image.
23540
23541 Likewise if part of the cursor is below y1, with the
23542 exception of the cursor being in the first blank row at
23543 the buffer and window end because update_text_area
23544 doesn't draw that row. (Except when it does, but
23545 that's handled in update_text_area.) */
23546
23547 cy0 = w->phys_cursor.y;
23548 cy1 = cy0 + w->phys_cursor_height;
23549 if ((y0 < cy0 || y0 >= cy1) && (y1 <= cy0 || y1 >= cy1))
23550 return;
23551
23552 w->phys_cursor_on_p = 0;
23553 }
23554
23555 #endif /* HAVE_WINDOW_SYSTEM */
23556
23557 \f
23558 /************************************************************************
23559 Mouse Face
23560 ************************************************************************/
23561
23562 #ifdef HAVE_WINDOW_SYSTEM
23563
23564 /* EXPORT for RIF:
23565 Fix the display of area AREA of overlapping row ROW in window W
23566 with respect to the overlapping part OVERLAPS. */
23567
23568 void
23569 x_fix_overlapping_area (struct window *w, struct glyph_row *row,
23570 enum glyph_row_area area, int overlaps)
23571 {
23572 int i, x;
23573
23574 BLOCK_INPUT;
23575
23576 x = 0;
23577 for (i = 0; i < row->used[area];)
23578 {
23579 if (row->glyphs[area][i].overlaps_vertically_p)
23580 {
23581 int start = i, start_x = x;
23582
23583 do
23584 {
23585 x += row->glyphs[area][i].pixel_width;
23586 ++i;
23587 }
23588 while (i < row->used[area]
23589 && row->glyphs[area][i].overlaps_vertically_p);
23590
23591 draw_glyphs (w, start_x, row, area,
23592 start, i,
23593 DRAW_NORMAL_TEXT, overlaps);
23594 }
23595 else
23596 {
23597 x += row->glyphs[area][i].pixel_width;
23598 ++i;
23599 }
23600 }
23601
23602 UNBLOCK_INPUT;
23603 }
23604
23605
23606 /* EXPORT:
23607 Draw the cursor glyph of window W in glyph row ROW. See the
23608 comment of draw_glyphs for the meaning of HL. */
23609
23610 void
23611 draw_phys_cursor_glyph (struct window *w, struct glyph_row *row,
23612 enum draw_glyphs_face hl)
23613 {
23614 /* If cursor hpos is out of bounds, don't draw garbage. This can
23615 happen in mini-buffer windows when switching between echo area
23616 glyphs and mini-buffer. */
23617 if ((row->reversed_p
23618 ? (w->phys_cursor.hpos >= 0)
23619 : (w->phys_cursor.hpos < row->used[TEXT_AREA])))
23620 {
23621 int on_p = w->phys_cursor_on_p;
23622 int x1;
23623 x1 = draw_glyphs (w, w->phys_cursor.x, row, TEXT_AREA,
23624 w->phys_cursor.hpos, w->phys_cursor.hpos + 1,
23625 hl, 0);
23626 w->phys_cursor_on_p = on_p;
23627
23628 if (hl == DRAW_CURSOR)
23629 w->phys_cursor_width = x1 - w->phys_cursor.x;
23630 /* When we erase the cursor, and ROW is overlapped by other
23631 rows, make sure that these overlapping parts of other rows
23632 are redrawn. */
23633 else if (hl == DRAW_NORMAL_TEXT && row->overlapped_p)
23634 {
23635 w->phys_cursor_width = x1 - w->phys_cursor.x;
23636
23637 if (row > w->current_matrix->rows
23638 && MATRIX_ROW_OVERLAPS_SUCC_P (row - 1))
23639 x_fix_overlapping_area (w, row - 1, TEXT_AREA,
23640 OVERLAPS_ERASED_CURSOR);
23641
23642 if (MATRIX_ROW_BOTTOM_Y (row) < window_text_bottom_y (w)
23643 && MATRIX_ROW_OVERLAPS_PRED_P (row + 1))
23644 x_fix_overlapping_area (w, row + 1, TEXT_AREA,
23645 OVERLAPS_ERASED_CURSOR);
23646 }
23647 }
23648 }
23649
23650
23651 /* EXPORT:
23652 Erase the image of a cursor of window W from the screen. */
23653
23654 void
23655 erase_phys_cursor (struct window *w)
23656 {
23657 struct frame *f = XFRAME (w->frame);
23658 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
23659 int hpos = w->phys_cursor.hpos;
23660 int vpos = w->phys_cursor.vpos;
23661 int mouse_face_here_p = 0;
23662 struct glyph_matrix *active_glyphs = w->current_matrix;
23663 struct glyph_row *cursor_row;
23664 struct glyph *cursor_glyph;
23665 enum draw_glyphs_face hl;
23666
23667 /* No cursor displayed or row invalidated => nothing to do on the
23668 screen. */
23669 if (w->phys_cursor_type == NO_CURSOR)
23670 goto mark_cursor_off;
23671
23672 /* VPOS >= active_glyphs->nrows means that window has been resized.
23673 Don't bother to erase the cursor. */
23674 if (vpos >= active_glyphs->nrows)
23675 goto mark_cursor_off;
23676
23677 /* If row containing cursor is marked invalid, there is nothing we
23678 can do. */
23679 cursor_row = MATRIX_ROW (active_glyphs, vpos);
23680 if (!cursor_row->enabled_p)
23681 goto mark_cursor_off;
23682
23683 /* If line spacing is > 0, old cursor may only be partially visible in
23684 window after split-window. So adjust visible height. */
23685 cursor_row->visible_height = min (cursor_row->visible_height,
23686 window_text_bottom_y (w) - cursor_row->y);
23687
23688 /* If row is completely invisible, don't attempt to delete a cursor which
23689 isn't there. This can happen if cursor is at top of a window, and
23690 we switch to a buffer with a header line in that window. */
23691 if (cursor_row->visible_height <= 0)
23692 goto mark_cursor_off;
23693
23694 /* If cursor is in the fringe, erase by drawing actual bitmap there. */
23695 if (cursor_row->cursor_in_fringe_p)
23696 {
23697 cursor_row->cursor_in_fringe_p = 0;
23698 draw_fringe_bitmap (w, cursor_row, cursor_row->reversed_p);
23699 goto mark_cursor_off;
23700 }
23701
23702 /* This can happen when the new row is shorter than the old one.
23703 In this case, either draw_glyphs or clear_end_of_line
23704 should have cleared the cursor. Note that we wouldn't be
23705 able to erase the cursor in this case because we don't have a
23706 cursor glyph at hand. */
23707 if ((cursor_row->reversed_p
23708 ? (w->phys_cursor.hpos < 0)
23709 : (w->phys_cursor.hpos >= cursor_row->used[TEXT_AREA])))
23710 goto mark_cursor_off;
23711
23712 /* If the cursor is in the mouse face area, redisplay that when
23713 we clear the cursor. */
23714 if (! NILP (hlinfo->mouse_face_window)
23715 && coords_in_mouse_face_p (w, hpos, vpos)
23716 /* Don't redraw the cursor's spot in mouse face if it is at the
23717 end of a line (on a newline). The cursor appears there, but
23718 mouse highlighting does not. */
23719 && cursor_row->used[TEXT_AREA] > hpos && hpos >= 0)
23720 mouse_face_here_p = 1;
23721
23722 /* Maybe clear the display under the cursor. */
23723 if (w->phys_cursor_type == HOLLOW_BOX_CURSOR)
23724 {
23725 int x, y, left_x;
23726 int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
23727 int width;
23728
23729 cursor_glyph = get_phys_cursor_glyph (w);
23730 if (cursor_glyph == NULL)
23731 goto mark_cursor_off;
23732
23733 width = cursor_glyph->pixel_width;
23734 left_x = window_box_left_offset (w, TEXT_AREA);
23735 x = w->phys_cursor.x;
23736 if (x < left_x)
23737 width -= left_x - x;
23738 width = min (width, window_box_width (w, TEXT_AREA) - x);
23739 y = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, cursor_row->y));
23740 x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, max (x, left_x));
23741
23742 if (width > 0)
23743 FRAME_RIF (f)->clear_frame_area (f, x, y, width, cursor_row->visible_height);
23744 }
23745
23746 /* Erase the cursor by redrawing the character underneath it. */
23747 if (mouse_face_here_p)
23748 hl = DRAW_MOUSE_FACE;
23749 else
23750 hl = DRAW_NORMAL_TEXT;
23751 draw_phys_cursor_glyph (w, cursor_row, hl);
23752
23753 mark_cursor_off:
23754 w->phys_cursor_on_p = 0;
23755 w->phys_cursor_type = NO_CURSOR;
23756 }
23757
23758
23759 /* EXPORT:
23760 Display or clear cursor of window W. If ON is zero, clear the
23761 cursor. If it is non-zero, display the cursor. If ON is nonzero,
23762 where to put the cursor is specified by HPOS, VPOS, X and Y. */
23763
23764 void
23765 display_and_set_cursor (struct window *w, int on,
23766 int hpos, int vpos, int x, int y)
23767 {
23768 struct frame *f = XFRAME (w->frame);
23769 int new_cursor_type;
23770 int new_cursor_width;
23771 int active_cursor;
23772 struct glyph_row *glyph_row;
23773 struct glyph *glyph;
23774
23775 /* This is pointless on invisible frames, and dangerous on garbaged
23776 windows and frames; in the latter case, the frame or window may
23777 be in the midst of changing its size, and x and y may be off the
23778 window. */
23779 if (! FRAME_VISIBLE_P (f)
23780 || FRAME_GARBAGED_P (f)
23781 || vpos >= w->current_matrix->nrows
23782 || hpos >= w->current_matrix->matrix_w)
23783 return;
23784
23785 /* If cursor is off and we want it off, return quickly. */
23786 if (!on && !w->phys_cursor_on_p)
23787 return;
23788
23789 glyph_row = MATRIX_ROW (w->current_matrix, vpos);
23790 /* If cursor row is not enabled, we don't really know where to
23791 display the cursor. */
23792 if (!glyph_row->enabled_p)
23793 {
23794 w->phys_cursor_on_p = 0;
23795 return;
23796 }
23797
23798 glyph = NULL;
23799 if (!glyph_row->exact_window_width_line_p
23800 || (0 <= hpos && hpos < glyph_row->used[TEXT_AREA]))
23801 glyph = glyph_row->glyphs[TEXT_AREA] + hpos;
23802
23803 xassert (interrupt_input_blocked);
23804
23805 /* Set new_cursor_type to the cursor we want to be displayed. */
23806 new_cursor_type = get_window_cursor_type (w, glyph,
23807 &new_cursor_width, &active_cursor);
23808
23809 /* If cursor is currently being shown and we don't want it to be or
23810 it is in the wrong place, or the cursor type is not what we want,
23811 erase it. */
23812 if (w->phys_cursor_on_p
23813 && (!on
23814 || w->phys_cursor.x != x
23815 || w->phys_cursor.y != y
23816 || new_cursor_type != w->phys_cursor_type
23817 || ((new_cursor_type == BAR_CURSOR || new_cursor_type == HBAR_CURSOR)
23818 && new_cursor_width != w->phys_cursor_width)))
23819 erase_phys_cursor (w);
23820
23821 /* Don't check phys_cursor_on_p here because that flag is only set
23822 to zero in some cases where we know that the cursor has been
23823 completely erased, to avoid the extra work of erasing the cursor
23824 twice. In other words, phys_cursor_on_p can be 1 and the cursor
23825 still not be visible, or it has only been partly erased. */
23826 if (on)
23827 {
23828 w->phys_cursor_ascent = glyph_row->ascent;
23829 w->phys_cursor_height = glyph_row->height;
23830
23831 /* Set phys_cursor_.* before x_draw_.* is called because some
23832 of them may need the information. */
23833 w->phys_cursor.x = x;
23834 w->phys_cursor.y = glyph_row->y;
23835 w->phys_cursor.hpos = hpos;
23836 w->phys_cursor.vpos = vpos;
23837 }
23838
23839 FRAME_RIF (f)->draw_window_cursor (w, glyph_row, x, y,
23840 new_cursor_type, new_cursor_width,
23841 on, active_cursor);
23842 }
23843
23844
23845 /* Switch the display of W's cursor on or off, according to the value
23846 of ON. */
23847
23848 static void
23849 update_window_cursor (struct window *w, int on)
23850 {
23851 /* Don't update cursor in windows whose frame is in the process
23852 of being deleted. */
23853 if (w->current_matrix)
23854 {
23855 BLOCK_INPUT;
23856 display_and_set_cursor (w, on, w->phys_cursor.hpos, w->phys_cursor.vpos,
23857 w->phys_cursor.x, w->phys_cursor.y);
23858 UNBLOCK_INPUT;
23859 }
23860 }
23861
23862
23863 /* Call update_window_cursor with parameter ON_P on all leaf windows
23864 in the window tree rooted at W. */
23865
23866 static void
23867 update_cursor_in_window_tree (struct window *w, int on_p)
23868 {
23869 while (w)
23870 {
23871 if (!NILP (w->hchild))
23872 update_cursor_in_window_tree (XWINDOW (w->hchild), on_p);
23873 else if (!NILP (w->vchild))
23874 update_cursor_in_window_tree (XWINDOW (w->vchild), on_p);
23875 else
23876 update_window_cursor (w, on_p);
23877
23878 w = NILP (w->next) ? 0 : XWINDOW (w->next);
23879 }
23880 }
23881
23882
23883 /* EXPORT:
23884 Display the cursor on window W, or clear it, according to ON_P.
23885 Don't change the cursor's position. */
23886
23887 void
23888 x_update_cursor (struct frame *f, int on_p)
23889 {
23890 update_cursor_in_window_tree (XWINDOW (f->root_window), on_p);
23891 }
23892
23893
23894 /* EXPORT:
23895 Clear the cursor of window W to background color, and mark the
23896 cursor as not shown. This is used when the text where the cursor
23897 is about to be rewritten. */
23898
23899 void
23900 x_clear_cursor (struct window *w)
23901 {
23902 if (FRAME_VISIBLE_P (XFRAME (w->frame)) && w->phys_cursor_on_p)
23903 update_window_cursor (w, 0);
23904 }
23905
23906 #endif /* HAVE_WINDOW_SYSTEM */
23907
23908 /* Implementation of draw_row_with_mouse_face for GUI sessions, GPM,
23909 and MSDOS. */
23910 void
23911 draw_row_with_mouse_face (struct window *w, int start_x, struct glyph_row *row,
23912 int start_hpos, int end_hpos,
23913 enum draw_glyphs_face draw)
23914 {
23915 #ifdef HAVE_WINDOW_SYSTEM
23916 if (FRAME_WINDOW_P (XFRAME (w->frame)))
23917 {
23918 draw_glyphs (w, start_x, row, TEXT_AREA, start_hpos, end_hpos, draw, 0);
23919 return;
23920 }
23921 #endif
23922 #if defined (HAVE_GPM) || defined (MSDOS)
23923 tty_draw_row_with_mouse_face (w, row, start_hpos, end_hpos, draw);
23924 #endif
23925 }
23926
23927 /* EXPORT:
23928 Display the active region described by mouse_face_* according to DRAW. */
23929
23930 void
23931 show_mouse_face (Mouse_HLInfo *hlinfo, enum draw_glyphs_face draw)
23932 {
23933 struct window *w = XWINDOW (hlinfo->mouse_face_window);
23934 struct frame *f = XFRAME (WINDOW_FRAME (w));
23935
23936 if (/* If window is in the process of being destroyed, don't bother
23937 to do anything. */
23938 w->current_matrix != NULL
23939 /* Don't update mouse highlight if hidden */
23940 && (draw != DRAW_MOUSE_FACE || !hlinfo->mouse_face_hidden)
23941 /* Recognize when we are called to operate on rows that don't exist
23942 anymore. This can happen when a window is split. */
23943 && hlinfo->mouse_face_end_row < w->current_matrix->nrows)
23944 {
23945 int phys_cursor_on_p = w->phys_cursor_on_p;
23946 struct glyph_row *row, *first, *last;
23947
23948 first = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_beg_row);
23949 last = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_end_row);
23950
23951 for (row = first; row <= last && row->enabled_p; ++row)
23952 {
23953 int start_hpos, end_hpos, start_x;
23954
23955 /* For all but the first row, the highlight starts at column 0. */
23956 if (row == first)
23957 {
23958 /* R2L rows have BEG and END in reversed order, but the
23959 screen drawing geometry is always left to right. So
23960 we need to mirror the beginning and end of the
23961 highlighted area in R2L rows. */
23962 if (!row->reversed_p)
23963 {
23964 start_hpos = hlinfo->mouse_face_beg_col;
23965 start_x = hlinfo->mouse_face_beg_x;
23966 }
23967 else if (row == last)
23968 {
23969 start_hpos = hlinfo->mouse_face_end_col;
23970 start_x = hlinfo->mouse_face_end_x;
23971 }
23972 else
23973 {
23974 start_hpos = 0;
23975 start_x = 0;
23976 }
23977 }
23978 else if (row->reversed_p && row == last)
23979 {
23980 start_hpos = hlinfo->mouse_face_end_col;
23981 start_x = hlinfo->mouse_face_end_x;
23982 }
23983 else
23984 {
23985 start_hpos = 0;
23986 start_x = 0;
23987 }
23988
23989 if (row == last)
23990 {
23991 if (!row->reversed_p)
23992 end_hpos = hlinfo->mouse_face_end_col;
23993 else if (row == first)
23994 end_hpos = hlinfo->mouse_face_beg_col;
23995 else
23996 {
23997 end_hpos = row->used[TEXT_AREA];
23998 if (draw == DRAW_NORMAL_TEXT)
23999 row->fill_line_p = 1; /* Clear to end of line */
24000 }
24001 }
24002 else if (row->reversed_p && row == first)
24003 end_hpos = hlinfo->mouse_face_beg_col;
24004 else
24005 {
24006 end_hpos = row->used[TEXT_AREA];
24007 if (draw == DRAW_NORMAL_TEXT)
24008 row->fill_line_p = 1; /* Clear to end of line */
24009 }
24010
24011 if (end_hpos > start_hpos)
24012 {
24013 draw_row_with_mouse_face (w, start_x, row,
24014 start_hpos, end_hpos, draw);
24015
24016 row->mouse_face_p
24017 = draw == DRAW_MOUSE_FACE || draw == DRAW_IMAGE_RAISED;
24018 }
24019 }
24020
24021 #ifdef HAVE_WINDOW_SYSTEM
24022 /* When we've written over the cursor, arrange for it to
24023 be displayed again. */
24024 if (FRAME_WINDOW_P (f)
24025 && phys_cursor_on_p && !w->phys_cursor_on_p)
24026 {
24027 BLOCK_INPUT;
24028 display_and_set_cursor (w, 1,
24029 w->phys_cursor.hpos, w->phys_cursor.vpos,
24030 w->phys_cursor.x, w->phys_cursor.y);
24031 UNBLOCK_INPUT;
24032 }
24033 #endif /* HAVE_WINDOW_SYSTEM */
24034 }
24035
24036 #ifdef HAVE_WINDOW_SYSTEM
24037 /* Change the mouse cursor. */
24038 if (FRAME_WINDOW_P (f))
24039 {
24040 if (draw == DRAW_NORMAL_TEXT
24041 && !EQ (hlinfo->mouse_face_window, f->tool_bar_window))
24042 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->text_cursor);
24043 else if (draw == DRAW_MOUSE_FACE)
24044 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->hand_cursor);
24045 else
24046 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->nontext_cursor);
24047 }
24048 #endif /* HAVE_WINDOW_SYSTEM */
24049 }
24050
24051 /* EXPORT:
24052 Clear out the mouse-highlighted active region.
24053 Redraw it un-highlighted first. Value is non-zero if mouse
24054 face was actually drawn unhighlighted. */
24055
24056 int
24057 clear_mouse_face (Mouse_HLInfo *hlinfo)
24058 {
24059 int cleared = 0;
24060
24061 if (!hlinfo->mouse_face_hidden && !NILP (hlinfo->mouse_face_window))
24062 {
24063 show_mouse_face (hlinfo, DRAW_NORMAL_TEXT);
24064 cleared = 1;
24065 }
24066
24067 hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
24068 hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
24069 hlinfo->mouse_face_window = Qnil;
24070 hlinfo->mouse_face_overlay = Qnil;
24071 return cleared;
24072 }
24073
24074 /* Return non-zero if the coordinates HPOS and VPOS on windows W are
24075 within the mouse face on that window. */
24076 static int
24077 coords_in_mouse_face_p (struct window *w, int hpos, int vpos)
24078 {
24079 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame));
24080
24081 /* Quickly resolve the easy cases. */
24082 if (!(WINDOWP (hlinfo->mouse_face_window)
24083 && XWINDOW (hlinfo->mouse_face_window) == w))
24084 return 0;
24085 if (vpos < hlinfo->mouse_face_beg_row
24086 || vpos > hlinfo->mouse_face_end_row)
24087 return 0;
24088 if (vpos > hlinfo->mouse_face_beg_row
24089 && vpos < hlinfo->mouse_face_end_row)
24090 return 1;
24091
24092 if (!MATRIX_ROW (w->current_matrix, vpos)->reversed_p)
24093 {
24094 if (hlinfo->mouse_face_beg_row == hlinfo->mouse_face_end_row)
24095 {
24096 if (hlinfo->mouse_face_beg_col <= hpos && hpos < hlinfo->mouse_face_end_col)
24097 return 1;
24098 }
24099 else if ((vpos == hlinfo->mouse_face_beg_row
24100 && hpos >= hlinfo->mouse_face_beg_col)
24101 || (vpos == hlinfo->mouse_face_end_row
24102 && hpos < hlinfo->mouse_face_end_col))
24103 return 1;
24104 }
24105 else
24106 {
24107 if (hlinfo->mouse_face_beg_row == hlinfo->mouse_face_end_row)
24108 {
24109 if (hlinfo->mouse_face_end_col < hpos && hpos <= hlinfo->mouse_face_beg_col)
24110 return 1;
24111 }
24112 else if ((vpos == hlinfo->mouse_face_beg_row
24113 && hpos <= hlinfo->mouse_face_beg_col)
24114 || (vpos == hlinfo->mouse_face_end_row
24115 && hpos > hlinfo->mouse_face_end_col))
24116 return 1;
24117 }
24118 return 0;
24119 }
24120
24121
24122 /* EXPORT:
24123 Non-zero if physical cursor of window W is within mouse face. */
24124
24125 int
24126 cursor_in_mouse_face_p (struct window *w)
24127 {
24128 return coords_in_mouse_face_p (w, w->phys_cursor.hpos, w->phys_cursor.vpos);
24129 }
24130
24131
24132 \f
24133 /* Find the glyph rows START_ROW and END_ROW of window W that display
24134 characters between buffer positions START_CHARPOS and END_CHARPOS
24135 (excluding END_CHARPOS). This is similar to row_containing_pos,
24136 but is more accurate when bidi reordering makes buffer positions
24137 change non-linearly with glyph rows. */
24138 static void
24139 rows_from_pos_range (struct window *w,
24140 EMACS_INT start_charpos, EMACS_INT end_charpos,
24141 struct glyph_row **start, struct glyph_row **end)
24142 {
24143 struct glyph_row *first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
24144 int last_y = window_text_bottom_y (w);
24145 struct glyph_row *row;
24146
24147 *start = NULL;
24148 *end = NULL;
24149
24150 while (!first->enabled_p
24151 && first < MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w))
24152 first++;
24153
24154 /* Find the START row. */
24155 for (row = first;
24156 row->enabled_p && MATRIX_ROW_BOTTOM_Y (row) <= last_y;
24157 row++)
24158 {
24159 /* A row can potentially be the START row if the range of the
24160 characters it displays intersects the range
24161 [START_CHARPOS..END_CHARPOS). */
24162 if (! ((start_charpos < MATRIX_ROW_START_CHARPOS (row)
24163 && end_charpos < MATRIX_ROW_START_CHARPOS (row))
24164 /* See the commentary in row_containing_pos, for the
24165 explanation of the complicated way to check whether
24166 some position is beyond the end of the characters
24167 displayed by a row. */
24168 || ((start_charpos > MATRIX_ROW_END_CHARPOS (row)
24169 || (start_charpos == MATRIX_ROW_END_CHARPOS (row)
24170 && !row->ends_at_zv_p
24171 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
24172 && (end_charpos > MATRIX_ROW_END_CHARPOS (row)
24173 || (end_charpos == MATRIX_ROW_END_CHARPOS (row)
24174 && !row->ends_at_zv_p
24175 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))))))
24176 {
24177 /* Found a candidate row. Now make sure at least one of the
24178 glyphs it displays has a charpos from the range
24179 [START_CHARPOS..END_CHARPOS).
24180
24181 This is not obvious because bidi reordering could make
24182 buffer positions of a row be 1,2,3,102,101,100, and if we
24183 want to highlight characters in [50..60), we don't want
24184 this row, even though [50..60) does intersect [1..103),
24185 the range of character positions given by the row's start
24186 and end positions. */
24187 struct glyph *g = row->glyphs[TEXT_AREA];
24188 struct glyph *e = g + row->used[TEXT_AREA];
24189
24190 while (g < e)
24191 {
24192 if (BUFFERP (g->object)
24193 && start_charpos <= g->charpos && g->charpos < end_charpos)
24194 *start = row;
24195 g++;
24196 }
24197 if (*start)
24198 break;
24199 }
24200 }
24201
24202 /* Find the END row. */
24203 if (!*start
24204 /* If the last row is partially visible, start looking for END
24205 from that row, instead of starting from FIRST. */
24206 && !(row->enabled_p
24207 && row->y < last_y && MATRIX_ROW_BOTTOM_Y (row) > last_y))
24208 row = first;
24209 for ( ; row->enabled_p && MATRIX_ROW_BOTTOM_Y (row) <= last_y; row++)
24210 {
24211 struct glyph_row *next = row + 1;
24212
24213 if (!next->enabled_p
24214 || next >= MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w)
24215 /* The first row >= START whose range of displayed characters
24216 does NOT intersect the range [START_CHARPOS..END_CHARPOS]
24217 is the row END + 1. */
24218 || (start_charpos < MATRIX_ROW_START_CHARPOS (next)
24219 && end_charpos < MATRIX_ROW_START_CHARPOS (next))
24220 || ((start_charpos > MATRIX_ROW_END_CHARPOS (next)
24221 || (start_charpos == MATRIX_ROW_END_CHARPOS (next)
24222 && !next->ends_at_zv_p
24223 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (next)))
24224 && (end_charpos > MATRIX_ROW_END_CHARPOS (next)
24225 || (end_charpos == MATRIX_ROW_END_CHARPOS (next)
24226 && !next->ends_at_zv_p
24227 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (next)))))
24228 {
24229 *end = row;
24230 break;
24231 }
24232 else
24233 {
24234 /* If the next row's edges intersect [START_CHARPOS..END_CHARPOS],
24235 but none of the characters it displays are in the range, it is
24236 also END + 1. */
24237 struct glyph *g = next->glyphs[TEXT_AREA];
24238 struct glyph *e = g + next->used[TEXT_AREA];
24239
24240 while (g < e)
24241 {
24242 if (BUFFERP (g->object)
24243 && start_charpos <= g->charpos && g->charpos < end_charpos)
24244 break;
24245 g++;
24246 }
24247 if (g == e)
24248 {
24249 *end = row;
24250 break;
24251 }
24252 }
24253 }
24254 }
24255
24256 /* This function sets the mouse_face_* elements of HLINFO, assuming
24257 the mouse cursor is on a glyph with buffer charpos MOUSE_CHARPOS in
24258 window WINDOW. START_CHARPOS and END_CHARPOS are buffer positions
24259 for the overlay or run of text properties specifying the mouse
24260 face. BEFORE_STRING and AFTER_STRING, if non-nil, are a
24261 before-string and after-string that must also be highlighted.
24262 COVER_STRING, if non-nil, is a display string that may cover some
24263 or all of the highlighted text. */
24264
24265 static void
24266 mouse_face_from_buffer_pos (Lisp_Object window,
24267 Mouse_HLInfo *hlinfo,
24268 EMACS_INT mouse_charpos,
24269 EMACS_INT start_charpos,
24270 EMACS_INT end_charpos,
24271 Lisp_Object before_string,
24272 Lisp_Object after_string,
24273 Lisp_Object cover_string)
24274 {
24275 struct window *w = XWINDOW (window);
24276 struct glyph_row *first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
24277 struct glyph_row *r1, *r2;
24278 struct glyph *glyph, *end;
24279 EMACS_INT ignore, pos;
24280 int x;
24281
24282 xassert (NILP (cover_string) || STRINGP (cover_string));
24283 xassert (NILP (before_string) || STRINGP (before_string));
24284 xassert (NILP (after_string) || STRINGP (after_string));
24285
24286 /* Find the rows corresponding to START_CHARPOS and END_CHARPOS. */
24287 rows_from_pos_range (w, start_charpos, end_charpos, &r1, &r2);
24288 if (r1 == NULL)
24289 r1 = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
24290 /* If the before-string or display-string contains newlines,
24291 rows_from_pos_range skips to its last row. Move back. */
24292 if (!NILP (before_string) || !NILP (cover_string))
24293 {
24294 struct glyph_row *prev;
24295 while ((prev = r1 - 1, prev >= first)
24296 && MATRIX_ROW_END_CHARPOS (prev) == start_charpos
24297 && prev->used[TEXT_AREA] > 0)
24298 {
24299 struct glyph *beg = prev->glyphs[TEXT_AREA];
24300 glyph = beg + prev->used[TEXT_AREA];
24301 while (--glyph >= beg && INTEGERP (glyph->object));
24302 if (glyph < beg
24303 || !(EQ (glyph->object, before_string)
24304 || EQ (glyph->object, cover_string)))
24305 break;
24306 r1 = prev;
24307 }
24308 }
24309 if (r2 == NULL)
24310 {
24311 r2 = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
24312 hlinfo->mouse_face_past_end = 1;
24313 }
24314 else if (!NILP (after_string))
24315 {
24316 /* If the after-string has newlines, advance to its last row. */
24317 struct glyph_row *next;
24318 struct glyph_row *last
24319 = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
24320
24321 for (next = r2 + 1;
24322 next <= last
24323 && next->used[TEXT_AREA] > 0
24324 && EQ (next->glyphs[TEXT_AREA]->object, after_string);
24325 ++next)
24326 r2 = next;
24327 }
24328 /* The rest of the display engine assumes that mouse_face_beg_row is
24329 either above below mouse_face_end_row or identical to it. But
24330 with bidi-reordered continued lines, the row for START_CHARPOS
24331 could be below the row for END_CHARPOS. If so, swap the rows and
24332 store them in correct order. */
24333 if (r1->y > r2->y)
24334 {
24335 struct glyph_row *tem = r2;
24336
24337 r2 = r1;
24338 r1 = tem;
24339 }
24340
24341 hlinfo->mouse_face_beg_y = r1->y;
24342 hlinfo->mouse_face_beg_row = MATRIX_ROW_VPOS (r1, w->current_matrix);
24343 hlinfo->mouse_face_end_y = r2->y;
24344 hlinfo->mouse_face_end_row = MATRIX_ROW_VPOS (r2, w->current_matrix);
24345
24346 /* For a bidi-reordered row, the positions of BEFORE_STRING,
24347 AFTER_STRING, COVER_STRING, START_CHARPOS, and END_CHARPOS
24348 could be anywhere in the row and in any order. The strategy
24349 below is to find the leftmost and the rightmost glyph that
24350 belongs to either of these 3 strings, or whose position is
24351 between START_CHARPOS and END_CHARPOS, and highlight all the
24352 glyphs between those two. This may cover more than just the text
24353 between START_CHARPOS and END_CHARPOS if the range of characters
24354 strides the bidi level boundary, e.g. if the beginning is in R2L
24355 text while the end is in L2R text or vice versa. */
24356 if (!r1->reversed_p)
24357 {
24358 /* This row is in a left to right paragraph. Scan it left to
24359 right. */
24360 glyph = r1->glyphs[TEXT_AREA];
24361 end = glyph + r1->used[TEXT_AREA];
24362 x = r1->x;
24363
24364 /* Skip truncation glyphs at the start of the glyph row. */
24365 if (r1->displays_text_p)
24366 for (; glyph < end
24367 && INTEGERP (glyph->object)
24368 && glyph->charpos < 0;
24369 ++glyph)
24370 x += glyph->pixel_width;
24371
24372 /* Scan the glyph row, looking for BEFORE_STRING, AFTER_STRING,
24373 or COVER_STRING, and the first glyph from buffer whose
24374 position is between START_CHARPOS and END_CHARPOS. */
24375 for (; glyph < end
24376 && !INTEGERP (glyph->object)
24377 && !EQ (glyph->object, cover_string)
24378 && !(BUFFERP (glyph->object)
24379 && (glyph->charpos >= start_charpos
24380 && glyph->charpos < end_charpos));
24381 ++glyph)
24382 {
24383 /* BEFORE_STRING or AFTER_STRING are only relevant if they
24384 are present at buffer positions between START_CHARPOS and
24385 END_CHARPOS, or if they come from an overlay. */
24386 if (EQ (glyph->object, before_string))
24387 {
24388 pos = string_buffer_position (before_string,
24389 start_charpos);
24390 /* If pos == 0, it means before_string came from an
24391 overlay, not from a buffer position. */
24392 if (!pos || (pos >= start_charpos && pos < end_charpos))
24393 break;
24394 }
24395 else if (EQ (glyph->object, after_string))
24396 {
24397 pos = string_buffer_position (after_string, end_charpos);
24398 if (!pos || (pos >= start_charpos && pos < end_charpos))
24399 break;
24400 }
24401 x += glyph->pixel_width;
24402 }
24403 hlinfo->mouse_face_beg_x = x;
24404 hlinfo->mouse_face_beg_col = glyph - r1->glyphs[TEXT_AREA];
24405 }
24406 else
24407 {
24408 /* This row is in a right to left paragraph. Scan it right to
24409 left. */
24410 struct glyph *g;
24411
24412 end = r1->glyphs[TEXT_AREA] - 1;
24413 glyph = end + r1->used[TEXT_AREA];
24414
24415 /* Skip truncation glyphs at the start of the glyph row. */
24416 if (r1->displays_text_p)
24417 for (; glyph > end
24418 && INTEGERP (glyph->object)
24419 && glyph->charpos < 0;
24420 --glyph)
24421 ;
24422
24423 /* Scan the glyph row, looking for BEFORE_STRING, AFTER_STRING,
24424 or COVER_STRING, and the first glyph from buffer whose
24425 position is between START_CHARPOS and END_CHARPOS. */
24426 for (; glyph > end
24427 && !INTEGERP (glyph->object)
24428 && !EQ (glyph->object, cover_string)
24429 && !(BUFFERP (glyph->object)
24430 && (glyph->charpos >= start_charpos
24431 && glyph->charpos < end_charpos));
24432 --glyph)
24433 {
24434 /* BEFORE_STRING or AFTER_STRING are only relevant if they
24435 are present at buffer positions between START_CHARPOS and
24436 END_CHARPOS, or if they come from an overlay. */
24437 if (EQ (glyph->object, before_string))
24438 {
24439 pos = string_buffer_position (before_string, start_charpos);
24440 /* If pos == 0, it means before_string came from an
24441 overlay, not from a buffer position. */
24442 if (!pos || (pos >= start_charpos && pos < end_charpos))
24443 break;
24444 }
24445 else if (EQ (glyph->object, after_string))
24446 {
24447 pos = string_buffer_position (after_string, end_charpos);
24448 if (!pos || (pos >= start_charpos && pos < end_charpos))
24449 break;
24450 }
24451 }
24452
24453 glyph++; /* first glyph to the right of the highlighted area */
24454 for (g = r1->glyphs[TEXT_AREA], x = r1->x; g < glyph; g++)
24455 x += g->pixel_width;
24456 hlinfo->mouse_face_beg_x = x;
24457 hlinfo->mouse_face_beg_col = glyph - r1->glyphs[TEXT_AREA];
24458 }
24459
24460 /* If the highlight ends in a different row, compute GLYPH and END
24461 for the end row. Otherwise, reuse the values computed above for
24462 the row where the highlight begins. */
24463 if (r2 != r1)
24464 {
24465 if (!r2->reversed_p)
24466 {
24467 glyph = r2->glyphs[TEXT_AREA];
24468 end = glyph + r2->used[TEXT_AREA];
24469 x = r2->x;
24470 }
24471 else
24472 {
24473 end = r2->glyphs[TEXT_AREA] - 1;
24474 glyph = end + r2->used[TEXT_AREA];
24475 }
24476 }
24477
24478 if (!r2->reversed_p)
24479 {
24480 /* Skip truncation and continuation glyphs near the end of the
24481 row, and also blanks and stretch glyphs inserted by
24482 extend_face_to_end_of_line. */
24483 while (end > glyph
24484 && INTEGERP ((end - 1)->object)
24485 && (end - 1)->charpos <= 0)
24486 --end;
24487 /* Scan the rest of the glyph row from the end, looking for the
24488 first glyph that comes from BEFORE_STRING, AFTER_STRING, or
24489 COVER_STRING, or whose position is between START_CHARPOS
24490 and END_CHARPOS */
24491 for (--end;
24492 end > glyph
24493 && !INTEGERP (end->object)
24494 && !EQ (end->object, cover_string)
24495 && !(BUFFERP (end->object)
24496 && (end->charpos >= start_charpos
24497 && end->charpos < end_charpos));
24498 --end)
24499 {
24500 /* BEFORE_STRING or AFTER_STRING are only relevant if they
24501 are present at buffer positions between START_CHARPOS and
24502 END_CHARPOS, or if they come from an overlay. */
24503 if (EQ (end->object, before_string))
24504 {
24505 pos = string_buffer_position (before_string, start_charpos);
24506 if (!pos || (pos >= start_charpos && pos < end_charpos))
24507 break;
24508 }
24509 else if (EQ (end->object, after_string))
24510 {
24511 pos = string_buffer_position (after_string, end_charpos);
24512 if (!pos || (pos >= start_charpos && pos < end_charpos))
24513 break;
24514 }
24515 }
24516 /* Find the X coordinate of the last glyph to be highlighted. */
24517 for (; glyph <= end; ++glyph)
24518 x += glyph->pixel_width;
24519
24520 hlinfo->mouse_face_end_x = x;
24521 hlinfo->mouse_face_end_col = glyph - r2->glyphs[TEXT_AREA];
24522 }
24523 else
24524 {
24525 /* Skip truncation and continuation glyphs near the end of the
24526 row, and also blanks and stretch glyphs inserted by
24527 extend_face_to_end_of_line. */
24528 x = r2->x;
24529 end++;
24530 while (end < glyph
24531 && INTEGERP (end->object)
24532 && end->charpos <= 0)
24533 {
24534 x += end->pixel_width;
24535 ++end;
24536 }
24537 /* Scan the rest of the glyph row from the end, looking for the
24538 first glyph that comes from BEFORE_STRING, AFTER_STRING, or
24539 COVER_STRING, or whose position is between START_CHARPOS
24540 and END_CHARPOS */
24541 for ( ;
24542 end < glyph
24543 && !INTEGERP (end->object)
24544 && !EQ (end->object, cover_string)
24545 && !(BUFFERP (end->object)
24546 && (end->charpos >= start_charpos
24547 && end->charpos < end_charpos));
24548 ++end)
24549 {
24550 /* BEFORE_STRING or AFTER_STRING are only relevant if they
24551 are present at buffer positions between START_CHARPOS and
24552 END_CHARPOS, or if they come from an overlay. */
24553 if (EQ (end->object, before_string))
24554 {
24555 pos = string_buffer_position (before_string, start_charpos);
24556 if (!pos || (pos >= start_charpos && pos < end_charpos))
24557 break;
24558 }
24559 else if (EQ (end->object, after_string))
24560 {
24561 pos = string_buffer_position (after_string, end_charpos);
24562 if (!pos || (pos >= start_charpos && pos < end_charpos))
24563 break;
24564 }
24565 x += end->pixel_width;
24566 }
24567 hlinfo->mouse_face_end_x = x;
24568 hlinfo->mouse_face_end_col = end - r2->glyphs[TEXT_AREA];
24569 }
24570
24571 hlinfo->mouse_face_window = window;
24572 hlinfo->mouse_face_face_id
24573 = face_at_buffer_position (w, mouse_charpos, 0, 0, &ignore,
24574 mouse_charpos + 1,
24575 !hlinfo->mouse_face_hidden, -1);
24576 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
24577 }
24578
24579 /* The following function is not used anymore (replaced with
24580 mouse_face_from_string_pos), but I leave it here for the time
24581 being, in case someone would. */
24582
24583 #if 0 /* not used */
24584
24585 /* Find the position of the glyph for position POS in OBJECT in
24586 window W's current matrix, and return in *X, *Y the pixel
24587 coordinates, and return in *HPOS, *VPOS the column/row of the glyph.
24588
24589 RIGHT_P non-zero means return the position of the right edge of the
24590 glyph, RIGHT_P zero means return the left edge position.
24591
24592 If no glyph for POS exists in the matrix, return the position of
24593 the glyph with the next smaller position that is in the matrix, if
24594 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS
24595 exists in the matrix, return the position of the glyph with the
24596 next larger position in OBJECT.
24597
24598 Value is non-zero if a glyph was found. */
24599
24600 static int
24601 fast_find_string_pos (struct window *w, EMACS_INT pos, Lisp_Object object,
24602 int *hpos, int *vpos, int *x, int *y, int right_p)
24603 {
24604 int yb = window_text_bottom_y (w);
24605 struct glyph_row *r;
24606 struct glyph *best_glyph = NULL;
24607 struct glyph_row *best_row = NULL;
24608 int best_x = 0;
24609
24610 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
24611 r->enabled_p && r->y < yb;
24612 ++r)
24613 {
24614 struct glyph *g = r->glyphs[TEXT_AREA];
24615 struct glyph *e = g + r->used[TEXT_AREA];
24616 int gx;
24617
24618 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
24619 if (EQ (g->object, object))
24620 {
24621 if (g->charpos == pos)
24622 {
24623 best_glyph = g;
24624 best_x = gx;
24625 best_row = r;
24626 goto found;
24627 }
24628 else if (best_glyph == NULL
24629 || ((eabs (g->charpos - pos)
24630 < eabs (best_glyph->charpos - pos))
24631 && (right_p
24632 ? g->charpos < pos
24633 : g->charpos > pos)))
24634 {
24635 best_glyph = g;
24636 best_x = gx;
24637 best_row = r;
24638 }
24639 }
24640 }
24641
24642 found:
24643
24644 if (best_glyph)
24645 {
24646 *x = best_x;
24647 *hpos = best_glyph - best_row->glyphs[TEXT_AREA];
24648
24649 if (right_p)
24650 {
24651 *x += best_glyph->pixel_width;
24652 ++*hpos;
24653 }
24654
24655 *y = best_row->y;
24656 *vpos = best_row - w->current_matrix->rows;
24657 }
24658
24659 return best_glyph != NULL;
24660 }
24661 #endif /* not used */
24662
24663 /* Find the positions of the first and the last glyphs in window W's
24664 current matrix that occlude positions [STARTPOS..ENDPOS] in OBJECT
24665 (assumed to be a string), and return in HLINFO's mouse_face_*
24666 members the pixel and column/row coordinates of those glyphs. */
24667
24668 static void
24669 mouse_face_from_string_pos (struct window *w, Mouse_HLInfo *hlinfo,
24670 Lisp_Object object,
24671 EMACS_INT startpos, EMACS_INT endpos)
24672 {
24673 int yb = window_text_bottom_y (w);
24674 struct glyph_row *r;
24675 struct glyph *g, *e;
24676 int gx;
24677 int found = 0;
24678
24679 /* Find the glyph row with at least one position in the range
24680 [STARTPOS..ENDPOS], and the first glyph in that row whose
24681 position belongs to that range. */
24682 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
24683 r->enabled_p && r->y < yb;
24684 ++r)
24685 {
24686 if (!r->reversed_p)
24687 {
24688 g = r->glyphs[TEXT_AREA];
24689 e = g + r->used[TEXT_AREA];
24690 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
24691 if (EQ (g->object, object)
24692 && startpos <= g->charpos && g->charpos <= endpos)
24693 {
24694 hlinfo->mouse_face_beg_row = r - w->current_matrix->rows;
24695 hlinfo->mouse_face_beg_y = r->y;
24696 hlinfo->mouse_face_beg_col = g - r->glyphs[TEXT_AREA];
24697 hlinfo->mouse_face_beg_x = gx;
24698 found = 1;
24699 break;
24700 }
24701 }
24702 else
24703 {
24704 struct glyph *g1;
24705
24706 e = r->glyphs[TEXT_AREA];
24707 g = e + r->used[TEXT_AREA];
24708 for ( ; g > e; --g)
24709 if (EQ ((g-1)->object, object)
24710 && startpos <= (g-1)->charpos && (g-1)->charpos <= endpos)
24711 {
24712 hlinfo->mouse_face_beg_row = r - w->current_matrix->rows;
24713 hlinfo->mouse_face_beg_y = r->y;
24714 hlinfo->mouse_face_beg_col = g - r->glyphs[TEXT_AREA];
24715 for (gx = r->x, g1 = r->glyphs[TEXT_AREA]; g1 < g; ++g1)
24716 gx += g1->pixel_width;
24717 hlinfo->mouse_face_beg_x = gx;
24718 found = 1;
24719 break;
24720 }
24721 }
24722 if (found)
24723 break;
24724 }
24725
24726 if (!found)
24727 return;
24728
24729 /* Starting with the next row, look for the first row which does NOT
24730 include any glyphs whose positions are in the range. */
24731 for (++r; r->enabled_p && r->y < yb; ++r)
24732 {
24733 g = r->glyphs[TEXT_AREA];
24734 e = g + r->used[TEXT_AREA];
24735 found = 0;
24736 for ( ; g < e; ++g)
24737 if (EQ (g->object, object)
24738 && startpos <= g->charpos && g->charpos <= endpos)
24739 {
24740 found = 1;
24741 break;
24742 }
24743 if (!found)
24744 break;
24745 }
24746
24747 /* The highlighted region ends on the previous row. */
24748 r--;
24749
24750 /* Set the end row and its vertical pixel coordinate. */
24751 hlinfo->mouse_face_end_row = r - w->current_matrix->rows;
24752 hlinfo->mouse_face_end_y = r->y;
24753
24754 /* Compute and set the end column and the end column's horizontal
24755 pixel coordinate. */
24756 if (!r->reversed_p)
24757 {
24758 g = r->glyphs[TEXT_AREA];
24759 e = g + r->used[TEXT_AREA];
24760 for ( ; e > g; --e)
24761 if (EQ ((e-1)->object, object)
24762 && startpos <= (e-1)->charpos && (e-1)->charpos <= endpos)
24763 break;
24764 hlinfo->mouse_face_end_col = e - g;
24765
24766 for (gx = r->x; g < e; ++g)
24767 gx += g->pixel_width;
24768 hlinfo->mouse_face_end_x = gx;
24769 }
24770 else
24771 {
24772 e = r->glyphs[TEXT_AREA];
24773 g = e + r->used[TEXT_AREA];
24774 for (gx = r->x ; e < g; ++e)
24775 {
24776 if (EQ (e->object, object)
24777 && startpos <= e->charpos && e->charpos <= endpos)
24778 break;
24779 gx += e->pixel_width;
24780 }
24781 hlinfo->mouse_face_end_col = e - r->glyphs[TEXT_AREA];
24782 hlinfo->mouse_face_end_x = gx;
24783 }
24784 }
24785
24786 #ifdef HAVE_WINDOW_SYSTEM
24787
24788 /* See if position X, Y is within a hot-spot of an image. */
24789
24790 static int
24791 on_hot_spot_p (Lisp_Object hot_spot, int x, int y)
24792 {
24793 if (!CONSP (hot_spot))
24794 return 0;
24795
24796 if (EQ (XCAR (hot_spot), Qrect))
24797 {
24798 /* CDR is (Top-Left . Bottom-Right) = ((x0 . y0) . (x1 . y1)) */
24799 Lisp_Object rect = XCDR (hot_spot);
24800 Lisp_Object tem;
24801 if (!CONSP (rect))
24802 return 0;
24803 if (!CONSP (XCAR (rect)))
24804 return 0;
24805 if (!CONSP (XCDR (rect)))
24806 return 0;
24807 if (!(tem = XCAR (XCAR (rect)), INTEGERP (tem) && x >= XINT (tem)))
24808 return 0;
24809 if (!(tem = XCDR (XCAR (rect)), INTEGERP (tem) && y >= XINT (tem)))
24810 return 0;
24811 if (!(tem = XCAR (XCDR (rect)), INTEGERP (tem) && x <= XINT (tem)))
24812 return 0;
24813 if (!(tem = XCDR (XCDR (rect)), INTEGERP (tem) && y <= XINT (tem)))
24814 return 0;
24815 return 1;
24816 }
24817 else if (EQ (XCAR (hot_spot), Qcircle))
24818 {
24819 /* CDR is (Center . Radius) = ((x0 . y0) . r) */
24820 Lisp_Object circ = XCDR (hot_spot);
24821 Lisp_Object lr, lx0, ly0;
24822 if (CONSP (circ)
24823 && CONSP (XCAR (circ))
24824 && (lr = XCDR (circ), INTEGERP (lr) || FLOATP (lr))
24825 && (lx0 = XCAR (XCAR (circ)), INTEGERP (lx0))
24826 && (ly0 = XCDR (XCAR (circ)), INTEGERP (ly0)))
24827 {
24828 double r = XFLOATINT (lr);
24829 double dx = XINT (lx0) - x;
24830 double dy = XINT (ly0) - y;
24831 return (dx * dx + dy * dy <= r * r);
24832 }
24833 }
24834 else if (EQ (XCAR (hot_spot), Qpoly))
24835 {
24836 /* CDR is [x0 y0 x1 y1 x2 y2 ...x(n-1) y(n-1)] */
24837 if (VECTORP (XCDR (hot_spot)))
24838 {
24839 struct Lisp_Vector *v = XVECTOR (XCDR (hot_spot));
24840 Lisp_Object *poly = v->contents;
24841 int n = v->size;
24842 int i;
24843 int inside = 0;
24844 Lisp_Object lx, ly;
24845 int x0, y0;
24846
24847 /* Need an even number of coordinates, and at least 3 edges. */
24848 if (n < 6 || n & 1)
24849 return 0;
24850
24851 /* Count edge segments intersecting line from (X,Y) to (X,infinity).
24852 If count is odd, we are inside polygon. Pixels on edges
24853 may or may not be included depending on actual geometry of the
24854 polygon. */
24855 if ((lx = poly[n-2], !INTEGERP (lx))
24856 || (ly = poly[n-1], !INTEGERP (lx)))
24857 return 0;
24858 x0 = XINT (lx), y0 = XINT (ly);
24859 for (i = 0; i < n; i += 2)
24860 {
24861 int x1 = x0, y1 = y0;
24862 if ((lx = poly[i], !INTEGERP (lx))
24863 || (ly = poly[i+1], !INTEGERP (ly)))
24864 return 0;
24865 x0 = XINT (lx), y0 = XINT (ly);
24866
24867 /* Does this segment cross the X line? */
24868 if (x0 >= x)
24869 {
24870 if (x1 >= x)
24871 continue;
24872 }
24873 else if (x1 < x)
24874 continue;
24875 if (y > y0 && y > y1)
24876 continue;
24877 if (y < y0 + ((y1 - y0) * (x - x0)) / (x1 - x0))
24878 inside = !inside;
24879 }
24880 return inside;
24881 }
24882 }
24883 return 0;
24884 }
24885
24886 Lisp_Object
24887 find_hot_spot (Lisp_Object map, int x, int y)
24888 {
24889 while (CONSP (map))
24890 {
24891 if (CONSP (XCAR (map))
24892 && on_hot_spot_p (XCAR (XCAR (map)), x, y))
24893 return XCAR (map);
24894 map = XCDR (map);
24895 }
24896
24897 return Qnil;
24898 }
24899
24900 DEFUN ("lookup-image-map", Flookup_image_map, Slookup_image_map,
24901 3, 3, 0,
24902 doc: /* Lookup in image map MAP coordinates X and Y.
24903 An image map is an alist where each element has the format (AREA ID PLIST).
24904 An AREA is specified as either a rectangle, a circle, or a polygon:
24905 A rectangle is a cons (rect . ((x0 . y0) . (x1 . y1))) specifying the
24906 pixel coordinates of the upper left and bottom right corners.
24907 A circle is a cons (circle . ((x0 . y0) . r)) specifying the center
24908 and the radius of the circle; r may be a float or integer.
24909 A polygon is a cons (poly . [x0 y0 x1 y1 ...]) where each pair in the
24910 vector describes one corner in the polygon.
24911 Returns the alist element for the first matching AREA in MAP. */)
24912 (Lisp_Object map, Lisp_Object x, Lisp_Object y)
24913 {
24914 if (NILP (map))
24915 return Qnil;
24916
24917 CHECK_NUMBER (x);
24918 CHECK_NUMBER (y);
24919
24920 return find_hot_spot (map, XINT (x), XINT (y));
24921 }
24922
24923
24924 /* Display frame CURSOR, optionally using shape defined by POINTER. */
24925 static void
24926 define_frame_cursor1 (struct frame *f, Cursor cursor, Lisp_Object pointer)
24927 {
24928 /* Do not change cursor shape while dragging mouse. */
24929 if (!NILP (do_mouse_tracking))
24930 return;
24931
24932 if (!NILP (pointer))
24933 {
24934 if (EQ (pointer, Qarrow))
24935 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
24936 else if (EQ (pointer, Qhand))
24937 cursor = FRAME_X_OUTPUT (f)->hand_cursor;
24938 else if (EQ (pointer, Qtext))
24939 cursor = FRAME_X_OUTPUT (f)->text_cursor;
24940 else if (EQ (pointer, intern ("hdrag")))
24941 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
24942 #ifdef HAVE_X_WINDOWS
24943 else if (EQ (pointer, intern ("vdrag")))
24944 cursor = FRAME_X_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
24945 #endif
24946 else if (EQ (pointer, intern ("hourglass")))
24947 cursor = FRAME_X_OUTPUT (f)->hourglass_cursor;
24948 else if (EQ (pointer, Qmodeline))
24949 cursor = FRAME_X_OUTPUT (f)->modeline_cursor;
24950 else
24951 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
24952 }
24953
24954 if (cursor != No_Cursor)
24955 FRAME_RIF (f)->define_frame_cursor (f, cursor);
24956 }
24957
24958 #endif /* HAVE_WINDOW_SYSTEM */
24959
24960 /* Take proper action when mouse has moved to the mode or header line
24961 or marginal area AREA of window W, x-position X and y-position Y.
24962 X is relative to the start of the text display area of W, so the
24963 width of bitmap areas and scroll bars must be subtracted to get a
24964 position relative to the start of the mode line. */
24965
24966 static void
24967 note_mode_line_or_margin_highlight (Lisp_Object window, int x, int y,
24968 enum window_part area)
24969 {
24970 struct window *w = XWINDOW (window);
24971 struct frame *f = XFRAME (w->frame);
24972 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
24973 #ifdef HAVE_WINDOW_SYSTEM
24974 Display_Info *dpyinfo;
24975 #endif
24976 Cursor cursor = No_Cursor;
24977 Lisp_Object pointer = Qnil;
24978 int dx, dy, width, height;
24979 EMACS_INT charpos;
24980 Lisp_Object string, object = Qnil;
24981 Lisp_Object pos, help;
24982
24983 Lisp_Object mouse_face;
24984 int original_x_pixel = x;
24985 struct glyph * glyph = NULL, * row_start_glyph = NULL;
24986 struct glyph_row *row;
24987
24988 if (area == ON_MODE_LINE || area == ON_HEADER_LINE)
24989 {
24990 int x0;
24991 struct glyph *end;
24992
24993 /* Kludge alert: mode_line_string takes X/Y in pixels, but
24994 returns them in row/column units! */
24995 string = mode_line_string (w, area, &x, &y, &charpos,
24996 &object, &dx, &dy, &width, &height);
24997
24998 row = (area == ON_MODE_LINE
24999 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
25000 : MATRIX_HEADER_LINE_ROW (w->current_matrix));
25001
25002 /* Find the glyph under the mouse pointer. */
25003 if (row->mode_line_p && row->enabled_p)
25004 {
25005 glyph = row_start_glyph = row->glyphs[TEXT_AREA];
25006 end = glyph + row->used[TEXT_AREA];
25007
25008 for (x0 = original_x_pixel;
25009 glyph < end && x0 >= glyph->pixel_width;
25010 ++glyph)
25011 x0 -= glyph->pixel_width;
25012
25013 if (glyph >= end)
25014 glyph = NULL;
25015 }
25016 }
25017 else
25018 {
25019 x -= WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
25020 /* Kludge alert: marginal_area_string takes X/Y in pixels, but
25021 returns them in row/column units! */
25022 string = marginal_area_string (w, area, &x, &y, &charpos,
25023 &object, &dx, &dy, &width, &height);
25024 }
25025
25026 help = Qnil;
25027
25028 #ifdef HAVE_WINDOW_SYSTEM
25029 if (IMAGEP (object))
25030 {
25031 Lisp_Object image_map, hotspot;
25032 if ((image_map = Fplist_get (XCDR (object), QCmap),
25033 !NILP (image_map))
25034 && (hotspot = find_hot_spot (image_map, dx, dy),
25035 CONSP (hotspot))
25036 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
25037 {
25038 Lisp_Object plist;
25039
25040 /* Could check XCAR (hotspot) to see if we enter/leave this hot-spot.
25041 If so, we could look for mouse-enter, mouse-leave
25042 properties in PLIST (and do something...). */
25043 hotspot = XCDR (hotspot);
25044 if (CONSP (hotspot)
25045 && (plist = XCAR (hotspot), CONSP (plist)))
25046 {
25047 pointer = Fplist_get (plist, Qpointer);
25048 if (NILP (pointer))
25049 pointer = Qhand;
25050 help = Fplist_get (plist, Qhelp_echo);
25051 if (!NILP (help))
25052 {
25053 help_echo_string = help;
25054 /* Is this correct? ++kfs */
25055 XSETWINDOW (help_echo_window, w);
25056 help_echo_object = w->buffer;
25057 help_echo_pos = charpos;
25058 }
25059 }
25060 }
25061 if (NILP (pointer))
25062 pointer = Fplist_get (XCDR (object), QCpointer);
25063 }
25064 #endif /* HAVE_WINDOW_SYSTEM */
25065
25066 if (STRINGP (string))
25067 {
25068 pos = make_number (charpos);
25069 /* If we're on a string with `help-echo' text property, arrange
25070 for the help to be displayed. This is done by setting the
25071 global variable help_echo_string to the help string. */
25072 if (NILP (help))
25073 {
25074 help = Fget_text_property (pos, Qhelp_echo, string);
25075 if (!NILP (help))
25076 {
25077 help_echo_string = help;
25078 XSETWINDOW (help_echo_window, w);
25079 help_echo_object = string;
25080 help_echo_pos = charpos;
25081 }
25082 }
25083
25084 #ifdef HAVE_WINDOW_SYSTEM
25085 if (FRAME_WINDOW_P (f))
25086 {
25087 dpyinfo = FRAME_X_DISPLAY_INFO (f);
25088 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
25089 if (NILP (pointer))
25090 pointer = Fget_text_property (pos, Qpointer, string);
25091
25092 /* Change the mouse pointer according to what is under X/Y. */
25093 if (NILP (pointer)
25094 && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE)))
25095 {
25096 Lisp_Object map;
25097 map = Fget_text_property (pos, Qlocal_map, string);
25098 if (!KEYMAPP (map))
25099 map = Fget_text_property (pos, Qkeymap, string);
25100 if (!KEYMAPP (map))
25101 cursor = dpyinfo->vertical_scroll_bar_cursor;
25102 }
25103 }
25104 #endif
25105
25106 /* Change the mouse face according to what is under X/Y. */
25107 mouse_face = Fget_text_property (pos, Qmouse_face, string);
25108 if (!NILP (mouse_face)
25109 && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE))
25110 && glyph)
25111 {
25112 Lisp_Object b, e;
25113
25114 struct glyph * tmp_glyph;
25115
25116 int gpos;
25117 int gseq_length;
25118 int total_pixel_width;
25119 EMACS_INT begpos, endpos, ignore;
25120
25121 int vpos, hpos;
25122
25123 b = Fprevious_single_property_change (make_number (charpos + 1),
25124 Qmouse_face, string, Qnil);
25125 if (NILP (b))
25126 begpos = 0;
25127 else
25128 begpos = XINT (b);
25129
25130 e = Fnext_single_property_change (pos, Qmouse_face, string, Qnil);
25131 if (NILP (e))
25132 endpos = SCHARS (string);
25133 else
25134 endpos = XINT (e);
25135
25136 /* Calculate the glyph position GPOS of GLYPH in the
25137 displayed string, relative to the beginning of the
25138 highlighted part of the string.
25139
25140 Note: GPOS is different from CHARPOS. CHARPOS is the
25141 position of GLYPH in the internal string object. A mode
25142 line string format has structures which are converted to
25143 a flattened string by the Emacs Lisp interpreter. The
25144 internal string is an element of those structures. The
25145 displayed string is the flattened string. */
25146 tmp_glyph = row_start_glyph;
25147 while (tmp_glyph < glyph
25148 && (!(EQ (tmp_glyph->object, glyph->object)
25149 && begpos <= tmp_glyph->charpos
25150 && tmp_glyph->charpos < endpos)))
25151 tmp_glyph++;
25152 gpos = glyph - tmp_glyph;
25153
25154 /* Calculate the length GSEQ_LENGTH of the glyph sequence of
25155 the highlighted part of the displayed string to which
25156 GLYPH belongs. Note: GSEQ_LENGTH is different from
25157 SCHARS (STRING), because the latter returns the length of
25158 the internal string. */
25159 for (tmp_glyph = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
25160 tmp_glyph > glyph
25161 && (!(EQ (tmp_glyph->object, glyph->object)
25162 && begpos <= tmp_glyph->charpos
25163 && tmp_glyph->charpos < endpos));
25164 tmp_glyph--)
25165 ;
25166 gseq_length = gpos + (tmp_glyph - glyph) + 1;
25167
25168 /* Calculate the total pixel width of all the glyphs between
25169 the beginning of the highlighted area and GLYPH. */
25170 total_pixel_width = 0;
25171 for (tmp_glyph = glyph - gpos; tmp_glyph != glyph; tmp_glyph++)
25172 total_pixel_width += tmp_glyph->pixel_width;
25173
25174 /* Pre calculation of re-rendering position. Note: X is in
25175 column units here, after the call to mode_line_string or
25176 marginal_area_string. */
25177 hpos = x - gpos;
25178 vpos = (area == ON_MODE_LINE
25179 ? (w->current_matrix)->nrows - 1
25180 : 0);
25181
25182 /* If GLYPH's position is included in the region that is
25183 already drawn in mouse face, we have nothing to do. */
25184 if ( EQ (window, hlinfo->mouse_face_window)
25185 && (!row->reversed_p
25186 ? (hlinfo->mouse_face_beg_col <= hpos
25187 && hpos < hlinfo->mouse_face_end_col)
25188 /* In R2L rows we swap BEG and END, see below. */
25189 : (hlinfo->mouse_face_end_col <= hpos
25190 && hpos < hlinfo->mouse_face_beg_col))
25191 && hlinfo->mouse_face_beg_row == vpos )
25192 return;
25193
25194 if (clear_mouse_face (hlinfo))
25195 cursor = No_Cursor;
25196
25197 if (!row->reversed_p)
25198 {
25199 hlinfo->mouse_face_beg_col = hpos;
25200 hlinfo->mouse_face_beg_x = original_x_pixel
25201 - (total_pixel_width + dx);
25202 hlinfo->mouse_face_end_col = hpos + gseq_length;
25203 hlinfo->mouse_face_end_x = 0;
25204 }
25205 else
25206 {
25207 /* In R2L rows, show_mouse_face expects BEG and END
25208 coordinates to be swapped. */
25209 hlinfo->mouse_face_end_col = hpos;
25210 hlinfo->mouse_face_end_x = original_x_pixel
25211 - (total_pixel_width + dx);
25212 hlinfo->mouse_face_beg_col = hpos + gseq_length;
25213 hlinfo->mouse_face_beg_x = 0;
25214 }
25215
25216 hlinfo->mouse_face_beg_row = vpos;
25217 hlinfo->mouse_face_end_row = hlinfo->mouse_face_beg_row;
25218 hlinfo->mouse_face_beg_y = 0;
25219 hlinfo->mouse_face_end_y = 0;
25220 hlinfo->mouse_face_past_end = 0;
25221 hlinfo->mouse_face_window = window;
25222
25223 hlinfo->mouse_face_face_id = face_at_string_position (w, string,
25224 charpos,
25225 0, 0, 0,
25226 &ignore,
25227 glyph->face_id,
25228 1);
25229 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
25230
25231 if (NILP (pointer))
25232 pointer = Qhand;
25233 }
25234 else if ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE))
25235 clear_mouse_face (hlinfo);
25236 }
25237 #ifdef HAVE_WINDOW_SYSTEM
25238 if (FRAME_WINDOW_P (f))
25239 define_frame_cursor1 (f, cursor, pointer);
25240 #endif
25241 }
25242
25243
25244 /* EXPORT:
25245 Take proper action when the mouse has moved to position X, Y on
25246 frame F as regards highlighting characters that have mouse-face
25247 properties. Also de-highlighting chars where the mouse was before.
25248 X and Y can be negative or out of range. */
25249
25250 void
25251 note_mouse_highlight (struct frame *f, int x, int y)
25252 {
25253 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
25254 enum window_part part;
25255 Lisp_Object window;
25256 struct window *w;
25257 Cursor cursor = No_Cursor;
25258 Lisp_Object pointer = Qnil; /* Takes precedence over cursor! */
25259 struct buffer *b;
25260
25261 /* When a menu is active, don't highlight because this looks odd. */
25262 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS) || defined (MSDOS)
25263 if (popup_activated ())
25264 return;
25265 #endif
25266
25267 if (NILP (Vmouse_highlight)
25268 || !f->glyphs_initialized_p
25269 || f->pointer_invisible)
25270 return;
25271
25272 hlinfo->mouse_face_mouse_x = x;
25273 hlinfo->mouse_face_mouse_y = y;
25274 hlinfo->mouse_face_mouse_frame = f;
25275
25276 if (hlinfo->mouse_face_defer)
25277 return;
25278
25279 if (gc_in_progress)
25280 {
25281 hlinfo->mouse_face_deferred_gc = 1;
25282 return;
25283 }
25284
25285 /* Which window is that in? */
25286 window = window_from_coordinates (f, x, y, &part, 1);
25287
25288 /* If we were displaying active text in another window, clear that.
25289 Also clear if we move out of text area in same window. */
25290 if (! EQ (window, hlinfo->mouse_face_window)
25291 || (part != ON_TEXT && part != ON_MODE_LINE && part != ON_HEADER_LINE
25292 && !NILP (hlinfo->mouse_face_window)))
25293 clear_mouse_face (hlinfo);
25294
25295 /* Not on a window -> return. */
25296 if (!WINDOWP (window))
25297 return;
25298
25299 /* Reset help_echo_string. It will get recomputed below. */
25300 help_echo_string = Qnil;
25301
25302 /* Convert to window-relative pixel coordinates. */
25303 w = XWINDOW (window);
25304 frame_to_window_pixel_xy (w, &x, &y);
25305
25306 #ifdef HAVE_WINDOW_SYSTEM
25307 /* Handle tool-bar window differently since it doesn't display a
25308 buffer. */
25309 if (EQ (window, f->tool_bar_window))
25310 {
25311 note_tool_bar_highlight (f, x, y);
25312 return;
25313 }
25314 #endif
25315
25316 /* Mouse is on the mode, header line or margin? */
25317 if (part == ON_MODE_LINE || part == ON_HEADER_LINE
25318 || part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
25319 {
25320 note_mode_line_or_margin_highlight (window, x, y, part);
25321 return;
25322 }
25323
25324 #ifdef HAVE_WINDOW_SYSTEM
25325 if (part == ON_VERTICAL_BORDER)
25326 {
25327 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
25328 help_echo_string = build_string ("drag-mouse-1: resize");
25329 }
25330 else if (part == ON_LEFT_FRINGE || part == ON_RIGHT_FRINGE
25331 || part == ON_SCROLL_BAR)
25332 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
25333 else
25334 cursor = FRAME_X_OUTPUT (f)->text_cursor;
25335 #endif
25336
25337 /* Are we in a window whose display is up to date?
25338 And verify the buffer's text has not changed. */
25339 b = XBUFFER (w->buffer);
25340 if (part == ON_TEXT
25341 && EQ (w->window_end_valid, w->buffer)
25342 && XFASTINT (w->last_modified) == BUF_MODIFF (b)
25343 && XFASTINT (w->last_overlay_modified) == BUF_OVERLAY_MODIFF (b))
25344 {
25345 int hpos, vpos, i, dx, dy, area;
25346 EMACS_INT pos;
25347 struct glyph *glyph;
25348 Lisp_Object object;
25349 Lisp_Object mouse_face = Qnil, position;
25350 Lisp_Object *overlay_vec = NULL;
25351 int noverlays;
25352 struct buffer *obuf;
25353 EMACS_INT obegv, ozv;
25354 int same_region;
25355
25356 /* Find the glyph under X/Y. */
25357 glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, &dx, &dy, &area);
25358
25359 #ifdef HAVE_WINDOW_SYSTEM
25360 /* Look for :pointer property on image. */
25361 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
25362 {
25363 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
25364 if (img != NULL && IMAGEP (img->spec))
25365 {
25366 Lisp_Object image_map, hotspot;
25367 if ((image_map = Fplist_get (XCDR (img->spec), QCmap),
25368 !NILP (image_map))
25369 && (hotspot = find_hot_spot (image_map,
25370 glyph->slice.img.x + dx,
25371 glyph->slice.img.y + dy),
25372 CONSP (hotspot))
25373 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
25374 {
25375 Lisp_Object plist;
25376
25377 /* Could check XCAR (hotspot) to see if we enter/leave
25378 this hot-spot.
25379 If so, we could look for mouse-enter, mouse-leave
25380 properties in PLIST (and do something...). */
25381 hotspot = XCDR (hotspot);
25382 if (CONSP (hotspot)
25383 && (plist = XCAR (hotspot), CONSP (plist)))
25384 {
25385 pointer = Fplist_get (plist, Qpointer);
25386 if (NILP (pointer))
25387 pointer = Qhand;
25388 help_echo_string = Fplist_get (plist, Qhelp_echo);
25389 if (!NILP (help_echo_string))
25390 {
25391 help_echo_window = window;
25392 help_echo_object = glyph->object;
25393 help_echo_pos = glyph->charpos;
25394 }
25395 }
25396 }
25397 if (NILP (pointer))
25398 pointer = Fplist_get (XCDR (img->spec), QCpointer);
25399 }
25400 }
25401 #endif /* HAVE_WINDOW_SYSTEM */
25402
25403 /* Clear mouse face if X/Y not over text. */
25404 if (glyph == NULL
25405 || area != TEXT_AREA
25406 || !MATRIX_ROW (w->current_matrix, vpos)->displays_text_p
25407 /* Glyph's OBJECT is an integer for glyphs inserted by the
25408 display engine for its internal purposes, like truncation
25409 and continuation glyphs and blanks beyond the end of
25410 line's text on text terminals. If we are over such a
25411 glyph, we are not over any text. */
25412 || INTEGERP (glyph->object)
25413 /* R2L rows have a stretch glyph at their front, which
25414 stands for no text, whereas L2R rows have no glyphs at
25415 all beyond the end of text. Treat such stretch glyphs
25416 like we do with NULL glyphs in L2R rows. */
25417 || (MATRIX_ROW (w->current_matrix, vpos)->reversed_p
25418 && glyph == MATRIX_ROW (w->current_matrix, vpos)->glyphs[TEXT_AREA]
25419 && glyph->type == STRETCH_GLYPH
25420 && glyph->avoid_cursor_p))
25421 {
25422 if (clear_mouse_face (hlinfo))
25423 cursor = No_Cursor;
25424 #ifdef HAVE_WINDOW_SYSTEM
25425 if (FRAME_WINDOW_P (f) && NILP (pointer))
25426 {
25427 if (area != TEXT_AREA)
25428 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
25429 else
25430 pointer = Vvoid_text_area_pointer;
25431 }
25432 #endif
25433 goto set_cursor;
25434 }
25435
25436 pos = glyph->charpos;
25437 object = glyph->object;
25438 if (!STRINGP (object) && !BUFFERP (object))
25439 goto set_cursor;
25440
25441 /* If we get an out-of-range value, return now; avoid an error. */
25442 if (BUFFERP (object) && pos > BUF_Z (b))
25443 goto set_cursor;
25444
25445 /* Make the window's buffer temporarily current for
25446 overlays_at and compute_char_face. */
25447 obuf = current_buffer;
25448 current_buffer = b;
25449 obegv = BEGV;
25450 ozv = ZV;
25451 BEGV = BEG;
25452 ZV = Z;
25453
25454 /* Is this char mouse-active or does it have help-echo? */
25455 position = make_number (pos);
25456
25457 if (BUFFERP (object))
25458 {
25459 /* Put all the overlays we want in a vector in overlay_vec. */
25460 GET_OVERLAYS_AT (pos, overlay_vec, noverlays, NULL, 0);
25461 /* Sort overlays into increasing priority order. */
25462 noverlays = sort_overlays (overlay_vec, noverlays, w);
25463 }
25464 else
25465 noverlays = 0;
25466
25467 same_region = coords_in_mouse_face_p (w, hpos, vpos);
25468
25469 if (same_region)
25470 cursor = No_Cursor;
25471
25472 /* Check mouse-face highlighting. */
25473 if (! same_region
25474 /* If there exists an overlay with mouse-face overlapping
25475 the one we are currently highlighting, we have to
25476 check if we enter the overlapping overlay, and then
25477 highlight only that. */
25478 || (OVERLAYP (hlinfo->mouse_face_overlay)
25479 && mouse_face_overlay_overlaps (hlinfo->mouse_face_overlay)))
25480 {
25481 /* Find the highest priority overlay with a mouse-face. */
25482 Lisp_Object overlay = Qnil;
25483 for (i = noverlays - 1; i >= 0 && NILP (overlay); --i)
25484 {
25485 mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face);
25486 if (!NILP (mouse_face))
25487 overlay = overlay_vec[i];
25488 }
25489
25490 /* If we're highlighting the same overlay as before, there's
25491 no need to do that again. */
25492 if (!NILP (overlay) && EQ (overlay, hlinfo->mouse_face_overlay))
25493 goto check_help_echo;
25494 hlinfo->mouse_face_overlay = overlay;
25495
25496 /* Clear the display of the old active region, if any. */
25497 if (clear_mouse_face (hlinfo))
25498 cursor = No_Cursor;
25499
25500 /* If no overlay applies, get a text property. */
25501 if (NILP (overlay))
25502 mouse_face = Fget_text_property (position, Qmouse_face, object);
25503
25504 /* Next, compute the bounds of the mouse highlighting and
25505 display it. */
25506 if (!NILP (mouse_face) && STRINGP (object))
25507 {
25508 /* The mouse-highlighting comes from a display string
25509 with a mouse-face. */
25510 Lisp_Object s, e;
25511 EMACS_INT ignore;
25512
25513 s = Fprevious_single_property_change
25514 (make_number (pos + 1), Qmouse_face, object, Qnil);
25515 e = Fnext_single_property_change
25516 (position, Qmouse_face, object, Qnil);
25517 if (NILP (s))
25518 s = make_number (0);
25519 if (NILP (e))
25520 e = make_number (SCHARS (object) - 1);
25521 mouse_face_from_string_pos (w, hlinfo, object,
25522 XINT (s), XINT (e));
25523 hlinfo->mouse_face_past_end = 0;
25524 hlinfo->mouse_face_window = window;
25525 hlinfo->mouse_face_face_id
25526 = face_at_string_position (w, object, pos, 0, 0, 0, &ignore,
25527 glyph->face_id, 1);
25528 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
25529 cursor = No_Cursor;
25530 }
25531 else
25532 {
25533 /* The mouse-highlighting, if any, comes from an overlay
25534 or text property in the buffer. */
25535 Lisp_Object buffer IF_LINT (= Qnil);
25536 Lisp_Object cover_string IF_LINT (= Qnil);
25537
25538 if (STRINGP (object))
25539 {
25540 /* If we are on a display string with no mouse-face,
25541 check if the text under it has one. */
25542 struct glyph_row *r = MATRIX_ROW (w->current_matrix, vpos);
25543 EMACS_INT start = MATRIX_ROW_START_CHARPOS (r);
25544 pos = string_buffer_position (object, start);
25545 if (pos > 0)
25546 {
25547 mouse_face = get_char_property_and_overlay
25548 (make_number (pos), Qmouse_face, w->buffer, &overlay);
25549 buffer = w->buffer;
25550 cover_string = object;
25551 }
25552 }
25553 else
25554 {
25555 buffer = object;
25556 cover_string = Qnil;
25557 }
25558
25559 if (!NILP (mouse_face))
25560 {
25561 Lisp_Object before, after;
25562 Lisp_Object before_string, after_string;
25563 /* To correctly find the limits of mouse highlight
25564 in a bidi-reordered buffer, we must not use the
25565 optimization of limiting the search in
25566 previous-single-property-change and
25567 next-single-property-change, because
25568 rows_from_pos_range needs the real start and end
25569 positions to DTRT in this case. That's because
25570 the first row visible in a window does not
25571 necessarily display the character whose position
25572 is the smallest. */
25573 Lisp_Object lim1 =
25574 NILP (BVAR (XBUFFER (buffer), bidi_display_reordering))
25575 ? Fmarker_position (w->start)
25576 : Qnil;
25577 Lisp_Object lim2 =
25578 NILP (BVAR (XBUFFER (buffer), bidi_display_reordering))
25579 ? make_number (BUF_Z (XBUFFER (buffer))
25580 - XFASTINT (w->window_end_pos))
25581 : Qnil;
25582
25583 if (NILP (overlay))
25584 {
25585 /* Handle the text property case. */
25586 before = Fprevious_single_property_change
25587 (make_number (pos + 1), Qmouse_face, buffer, lim1);
25588 after = Fnext_single_property_change
25589 (make_number (pos), Qmouse_face, buffer, lim2);
25590 before_string = after_string = Qnil;
25591 }
25592 else
25593 {
25594 /* Handle the overlay case. */
25595 before = Foverlay_start (overlay);
25596 after = Foverlay_end (overlay);
25597 before_string = Foverlay_get (overlay, Qbefore_string);
25598 after_string = Foverlay_get (overlay, Qafter_string);
25599
25600 if (!STRINGP (before_string)) before_string = Qnil;
25601 if (!STRINGP (after_string)) after_string = Qnil;
25602 }
25603
25604 mouse_face_from_buffer_pos (window, hlinfo, pos,
25605 XFASTINT (before),
25606 XFASTINT (after),
25607 before_string, after_string,
25608 cover_string);
25609 cursor = No_Cursor;
25610 }
25611 }
25612 }
25613
25614 check_help_echo:
25615
25616 /* Look for a `help-echo' property. */
25617 if (NILP (help_echo_string)) {
25618 Lisp_Object help, overlay;
25619
25620 /* Check overlays first. */
25621 help = overlay = Qnil;
25622 for (i = noverlays - 1; i >= 0 && NILP (help); --i)
25623 {
25624 overlay = overlay_vec[i];
25625 help = Foverlay_get (overlay, Qhelp_echo);
25626 }
25627
25628 if (!NILP (help))
25629 {
25630 help_echo_string = help;
25631 help_echo_window = window;
25632 help_echo_object = overlay;
25633 help_echo_pos = pos;
25634 }
25635 else
25636 {
25637 Lisp_Object obj = glyph->object;
25638 EMACS_INT charpos = glyph->charpos;
25639
25640 /* Try text properties. */
25641 if (STRINGP (obj)
25642 && charpos >= 0
25643 && charpos < SCHARS (obj))
25644 {
25645 help = Fget_text_property (make_number (charpos),
25646 Qhelp_echo, obj);
25647 if (NILP (help))
25648 {
25649 /* If the string itself doesn't specify a help-echo,
25650 see if the buffer text ``under'' it does. */
25651 struct glyph_row *r
25652 = MATRIX_ROW (w->current_matrix, vpos);
25653 EMACS_INT start = MATRIX_ROW_START_CHARPOS (r);
25654 EMACS_INT p = string_buffer_position (obj, start);
25655 if (p > 0)
25656 {
25657 help = Fget_char_property (make_number (p),
25658 Qhelp_echo, w->buffer);
25659 if (!NILP (help))
25660 {
25661 charpos = p;
25662 obj = w->buffer;
25663 }
25664 }
25665 }
25666 }
25667 else if (BUFFERP (obj)
25668 && charpos >= BEGV
25669 && charpos < ZV)
25670 help = Fget_text_property (make_number (charpos), Qhelp_echo,
25671 obj);
25672
25673 if (!NILP (help))
25674 {
25675 help_echo_string = help;
25676 help_echo_window = window;
25677 help_echo_object = obj;
25678 help_echo_pos = charpos;
25679 }
25680 }
25681 }
25682
25683 #ifdef HAVE_WINDOW_SYSTEM
25684 /* Look for a `pointer' property. */
25685 if (FRAME_WINDOW_P (f) && NILP (pointer))
25686 {
25687 /* Check overlays first. */
25688 for (i = noverlays - 1; i >= 0 && NILP (pointer); --i)
25689 pointer = Foverlay_get (overlay_vec[i], Qpointer);
25690
25691 if (NILP (pointer))
25692 {
25693 Lisp_Object obj = glyph->object;
25694 EMACS_INT charpos = glyph->charpos;
25695
25696 /* Try text properties. */
25697 if (STRINGP (obj)
25698 && charpos >= 0
25699 && charpos < SCHARS (obj))
25700 {
25701 pointer = Fget_text_property (make_number (charpos),
25702 Qpointer, obj);
25703 if (NILP (pointer))
25704 {
25705 /* If the string itself doesn't specify a pointer,
25706 see if the buffer text ``under'' it does. */
25707 struct glyph_row *r
25708 = MATRIX_ROW (w->current_matrix, vpos);
25709 EMACS_INT start = MATRIX_ROW_START_CHARPOS (r);
25710 EMACS_INT p = string_buffer_position (obj, start);
25711 if (p > 0)
25712 pointer = Fget_char_property (make_number (p),
25713 Qpointer, w->buffer);
25714 }
25715 }
25716 else if (BUFFERP (obj)
25717 && charpos >= BEGV
25718 && charpos < ZV)
25719 pointer = Fget_text_property (make_number (charpos),
25720 Qpointer, obj);
25721 }
25722 }
25723 #endif /* HAVE_WINDOW_SYSTEM */
25724
25725 BEGV = obegv;
25726 ZV = ozv;
25727 current_buffer = obuf;
25728 }
25729
25730 set_cursor:
25731
25732 #ifdef HAVE_WINDOW_SYSTEM
25733 if (FRAME_WINDOW_P (f))
25734 define_frame_cursor1 (f, cursor, pointer);
25735 #else
25736 /* This is here to prevent a compiler error, about "label at end of
25737 compound statement". */
25738 return;
25739 #endif
25740 }
25741
25742
25743 /* EXPORT for RIF:
25744 Clear any mouse-face on window W. This function is part of the
25745 redisplay interface, and is called from try_window_id and similar
25746 functions to ensure the mouse-highlight is off. */
25747
25748 void
25749 x_clear_window_mouse_face (struct window *w)
25750 {
25751 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame));
25752 Lisp_Object window;
25753
25754 BLOCK_INPUT;
25755 XSETWINDOW (window, w);
25756 if (EQ (window, hlinfo->mouse_face_window))
25757 clear_mouse_face (hlinfo);
25758 UNBLOCK_INPUT;
25759 }
25760
25761
25762 /* EXPORT:
25763 Just discard the mouse face information for frame F, if any.
25764 This is used when the size of F is changed. */
25765
25766 void
25767 cancel_mouse_face (struct frame *f)
25768 {
25769 Lisp_Object window;
25770 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
25771
25772 window = hlinfo->mouse_face_window;
25773 if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f)
25774 {
25775 hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
25776 hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
25777 hlinfo->mouse_face_window = Qnil;
25778 }
25779 }
25780
25781
25782 \f
25783 /***********************************************************************
25784 Exposure Events
25785 ***********************************************************************/
25786
25787 #ifdef HAVE_WINDOW_SYSTEM
25788
25789 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
25790 which intersects rectangle R. R is in window-relative coordinates. */
25791
25792 static void
25793 expose_area (struct window *w, struct glyph_row *row, XRectangle *r,
25794 enum glyph_row_area area)
25795 {
25796 struct glyph *first = row->glyphs[area];
25797 struct glyph *end = row->glyphs[area] + row->used[area];
25798 struct glyph *last;
25799 int first_x, start_x, x;
25800
25801 if (area == TEXT_AREA && row->fill_line_p)
25802 /* If row extends face to end of line write the whole line. */
25803 draw_glyphs (w, 0, row, area,
25804 0, row->used[area],
25805 DRAW_NORMAL_TEXT, 0);
25806 else
25807 {
25808 /* Set START_X to the window-relative start position for drawing glyphs of
25809 AREA. The first glyph of the text area can be partially visible.
25810 The first glyphs of other areas cannot. */
25811 start_x = window_box_left_offset (w, area);
25812 x = start_x;
25813 if (area == TEXT_AREA)
25814 x += row->x;
25815
25816 /* Find the first glyph that must be redrawn. */
25817 while (first < end
25818 && x + first->pixel_width < r->x)
25819 {
25820 x += first->pixel_width;
25821 ++first;
25822 }
25823
25824 /* Find the last one. */
25825 last = first;
25826 first_x = x;
25827 while (last < end
25828 && x < r->x + r->width)
25829 {
25830 x += last->pixel_width;
25831 ++last;
25832 }
25833
25834 /* Repaint. */
25835 if (last > first)
25836 draw_glyphs (w, first_x - start_x, row, area,
25837 first - row->glyphs[area], last - row->glyphs[area],
25838 DRAW_NORMAL_TEXT, 0);
25839 }
25840 }
25841
25842
25843 /* Redraw the parts of the glyph row ROW on window W intersecting
25844 rectangle R. R is in window-relative coordinates. Value is
25845 non-zero if mouse-face was overwritten. */
25846
25847 static int
25848 expose_line (struct window *w, struct glyph_row *row, XRectangle *r)
25849 {
25850 xassert (row->enabled_p);
25851
25852 if (row->mode_line_p || w->pseudo_window_p)
25853 draw_glyphs (w, 0, row, TEXT_AREA,
25854 0, row->used[TEXT_AREA],
25855 DRAW_NORMAL_TEXT, 0);
25856 else
25857 {
25858 if (row->used[LEFT_MARGIN_AREA])
25859 expose_area (w, row, r, LEFT_MARGIN_AREA);
25860 if (row->used[TEXT_AREA])
25861 expose_area (w, row, r, TEXT_AREA);
25862 if (row->used[RIGHT_MARGIN_AREA])
25863 expose_area (w, row, r, RIGHT_MARGIN_AREA);
25864 draw_row_fringe_bitmaps (w, row);
25865 }
25866
25867 return row->mouse_face_p;
25868 }
25869
25870
25871 /* Redraw those parts of glyphs rows during expose event handling that
25872 overlap other rows. Redrawing of an exposed line writes over parts
25873 of lines overlapping that exposed line; this function fixes that.
25874
25875 W is the window being exposed. FIRST_OVERLAPPING_ROW is the first
25876 row in W's current matrix that is exposed and overlaps other rows.
25877 LAST_OVERLAPPING_ROW is the last such row. */
25878
25879 static void
25880 expose_overlaps (struct window *w,
25881 struct glyph_row *first_overlapping_row,
25882 struct glyph_row *last_overlapping_row,
25883 XRectangle *r)
25884 {
25885 struct glyph_row *row;
25886
25887 for (row = first_overlapping_row; row <= last_overlapping_row; ++row)
25888 if (row->overlapping_p)
25889 {
25890 xassert (row->enabled_p && !row->mode_line_p);
25891
25892 row->clip = r;
25893 if (row->used[LEFT_MARGIN_AREA])
25894 x_fix_overlapping_area (w, row, LEFT_MARGIN_AREA, OVERLAPS_BOTH);
25895
25896 if (row->used[TEXT_AREA])
25897 x_fix_overlapping_area (w, row, TEXT_AREA, OVERLAPS_BOTH);
25898
25899 if (row->used[RIGHT_MARGIN_AREA])
25900 x_fix_overlapping_area (w, row, RIGHT_MARGIN_AREA, OVERLAPS_BOTH);
25901 row->clip = NULL;
25902 }
25903 }
25904
25905
25906 /* Return non-zero if W's cursor intersects rectangle R. */
25907
25908 static int
25909 phys_cursor_in_rect_p (struct window *w, XRectangle *r)
25910 {
25911 XRectangle cr, result;
25912 struct glyph *cursor_glyph;
25913 struct glyph_row *row;
25914
25915 if (w->phys_cursor.vpos >= 0
25916 && w->phys_cursor.vpos < w->current_matrix->nrows
25917 && (row = MATRIX_ROW (w->current_matrix, w->phys_cursor.vpos),
25918 row->enabled_p)
25919 && row->cursor_in_fringe_p)
25920 {
25921 /* Cursor is in the fringe. */
25922 cr.x = window_box_right_offset (w,
25923 (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
25924 ? RIGHT_MARGIN_AREA
25925 : TEXT_AREA));
25926 cr.y = row->y;
25927 cr.width = WINDOW_RIGHT_FRINGE_WIDTH (w);
25928 cr.height = row->height;
25929 return x_intersect_rectangles (&cr, r, &result);
25930 }
25931
25932 cursor_glyph = get_phys_cursor_glyph (w);
25933 if (cursor_glyph)
25934 {
25935 /* r is relative to W's box, but w->phys_cursor.x is relative
25936 to left edge of W's TEXT area. Adjust it. */
25937 cr.x = window_box_left_offset (w, TEXT_AREA) + w->phys_cursor.x;
25938 cr.y = w->phys_cursor.y;
25939 cr.width = cursor_glyph->pixel_width;
25940 cr.height = w->phys_cursor_height;
25941 /* ++KFS: W32 version used W32-specific IntersectRect here, but
25942 I assume the effect is the same -- and this is portable. */
25943 return x_intersect_rectangles (&cr, r, &result);
25944 }
25945 /* If we don't understand the format, pretend we're not in the hot-spot. */
25946 return 0;
25947 }
25948
25949
25950 /* EXPORT:
25951 Draw a vertical window border to the right of window W if W doesn't
25952 have vertical scroll bars. */
25953
25954 void
25955 x_draw_vertical_border (struct window *w)
25956 {
25957 struct frame *f = XFRAME (WINDOW_FRAME (w));
25958
25959 /* We could do better, if we knew what type of scroll-bar the adjacent
25960 windows (on either side) have... But we don't :-(
25961 However, I think this works ok. ++KFS 2003-04-25 */
25962
25963 /* Redraw borders between horizontally adjacent windows. Don't
25964 do it for frames with vertical scroll bars because either the
25965 right scroll bar of a window, or the left scroll bar of its
25966 neighbor will suffice as a border. */
25967 if (FRAME_HAS_VERTICAL_SCROLL_BARS (XFRAME (w->frame)))
25968 return;
25969
25970 if (!WINDOW_RIGHTMOST_P (w)
25971 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w))
25972 {
25973 int x0, x1, y0, y1;
25974
25975 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
25976 y1 -= 1;
25977
25978 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
25979 x1 -= 1;
25980
25981 FRAME_RIF (f)->draw_vertical_window_border (w, x1, y0, y1);
25982 }
25983 else if (!WINDOW_LEFTMOST_P (w)
25984 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
25985 {
25986 int x0, x1, y0, y1;
25987
25988 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
25989 y1 -= 1;
25990
25991 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
25992 x0 -= 1;
25993
25994 FRAME_RIF (f)->draw_vertical_window_border (w, x0, y0, y1);
25995 }
25996 }
25997
25998
25999 /* Redraw the part of window W intersection rectangle FR. Pixel
26000 coordinates in FR are frame-relative. Call this function with
26001 input blocked. Value is non-zero if the exposure overwrites
26002 mouse-face. */
26003
26004 static int
26005 expose_window (struct window *w, XRectangle *fr)
26006 {
26007 struct frame *f = XFRAME (w->frame);
26008 XRectangle wr, r;
26009 int mouse_face_overwritten_p = 0;
26010
26011 /* If window is not yet fully initialized, do nothing. This can
26012 happen when toolkit scroll bars are used and a window is split.
26013 Reconfiguring the scroll bar will generate an expose for a newly
26014 created window. */
26015 if (w->current_matrix == NULL)
26016 return 0;
26017
26018 /* When we're currently updating the window, display and current
26019 matrix usually don't agree. Arrange for a thorough display
26020 later. */
26021 if (w == updated_window)
26022 {
26023 SET_FRAME_GARBAGED (f);
26024 return 0;
26025 }
26026
26027 /* Frame-relative pixel rectangle of W. */
26028 wr.x = WINDOW_LEFT_EDGE_X (w);
26029 wr.y = WINDOW_TOP_EDGE_Y (w);
26030 wr.width = WINDOW_TOTAL_WIDTH (w);
26031 wr.height = WINDOW_TOTAL_HEIGHT (w);
26032
26033 if (x_intersect_rectangles (fr, &wr, &r))
26034 {
26035 int yb = window_text_bottom_y (w);
26036 struct glyph_row *row;
26037 int cursor_cleared_p;
26038 struct glyph_row *first_overlapping_row, *last_overlapping_row;
26039
26040 TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n",
26041 r.x, r.y, r.width, r.height));
26042
26043 /* Convert to window coordinates. */
26044 r.x -= WINDOW_LEFT_EDGE_X (w);
26045 r.y -= WINDOW_TOP_EDGE_Y (w);
26046
26047 /* Turn off the cursor. */
26048 if (!w->pseudo_window_p
26049 && phys_cursor_in_rect_p (w, &r))
26050 {
26051 x_clear_cursor (w);
26052 cursor_cleared_p = 1;
26053 }
26054 else
26055 cursor_cleared_p = 0;
26056
26057 /* Update lines intersecting rectangle R. */
26058 first_overlapping_row = last_overlapping_row = NULL;
26059 for (row = w->current_matrix->rows;
26060 row->enabled_p;
26061 ++row)
26062 {
26063 int y0 = row->y;
26064 int y1 = MATRIX_ROW_BOTTOM_Y (row);
26065
26066 if ((y0 >= r.y && y0 < r.y + r.height)
26067 || (y1 > r.y && y1 < r.y + r.height)
26068 || (r.y >= y0 && r.y < y1)
26069 || (r.y + r.height > y0 && r.y + r.height < y1))
26070 {
26071 /* A header line may be overlapping, but there is no need
26072 to fix overlapping areas for them. KFS 2005-02-12 */
26073 if (row->overlapping_p && !row->mode_line_p)
26074 {
26075 if (first_overlapping_row == NULL)
26076 first_overlapping_row = row;
26077 last_overlapping_row = row;
26078 }
26079
26080 row->clip = fr;
26081 if (expose_line (w, row, &r))
26082 mouse_face_overwritten_p = 1;
26083 row->clip = NULL;
26084 }
26085 else if (row->overlapping_p)
26086 {
26087 /* We must redraw a row overlapping the exposed area. */
26088 if (y0 < r.y
26089 ? y0 + row->phys_height > r.y
26090 : y0 + row->ascent - row->phys_ascent < r.y +r.height)
26091 {
26092 if (first_overlapping_row == NULL)
26093 first_overlapping_row = row;
26094 last_overlapping_row = row;
26095 }
26096 }
26097
26098 if (y1 >= yb)
26099 break;
26100 }
26101
26102 /* Display the mode line if there is one. */
26103 if (WINDOW_WANTS_MODELINE_P (w)
26104 && (row = MATRIX_MODE_LINE_ROW (w->current_matrix),
26105 row->enabled_p)
26106 && row->y < r.y + r.height)
26107 {
26108 if (expose_line (w, row, &r))
26109 mouse_face_overwritten_p = 1;
26110 }
26111
26112 if (!w->pseudo_window_p)
26113 {
26114 /* Fix the display of overlapping rows. */
26115 if (first_overlapping_row)
26116 expose_overlaps (w, first_overlapping_row, last_overlapping_row,
26117 fr);
26118
26119 /* Draw border between windows. */
26120 x_draw_vertical_border (w);
26121
26122 /* Turn the cursor on again. */
26123 if (cursor_cleared_p)
26124 update_window_cursor (w, 1);
26125 }
26126 }
26127
26128 return mouse_face_overwritten_p;
26129 }
26130
26131
26132
26133 /* Redraw (parts) of all windows in the window tree rooted at W that
26134 intersect R. R contains frame pixel coordinates. Value is
26135 non-zero if the exposure overwrites mouse-face. */
26136
26137 static int
26138 expose_window_tree (struct window *w, XRectangle *r)
26139 {
26140 struct frame *f = XFRAME (w->frame);
26141 int mouse_face_overwritten_p = 0;
26142
26143 while (w && !FRAME_GARBAGED_P (f))
26144 {
26145 if (!NILP (w->hchild))
26146 mouse_face_overwritten_p
26147 |= expose_window_tree (XWINDOW (w->hchild), r);
26148 else if (!NILP (w->vchild))
26149 mouse_face_overwritten_p
26150 |= expose_window_tree (XWINDOW (w->vchild), r);
26151 else
26152 mouse_face_overwritten_p |= expose_window (w, r);
26153
26154 w = NILP (w->next) ? NULL : XWINDOW (w->next);
26155 }
26156
26157 return mouse_face_overwritten_p;
26158 }
26159
26160
26161 /* EXPORT:
26162 Redisplay an exposed area of frame F. X and Y are the upper-left
26163 corner of the exposed rectangle. W and H are width and height of
26164 the exposed area. All are pixel values. W or H zero means redraw
26165 the entire frame. */
26166
26167 void
26168 expose_frame (struct frame *f, int x, int y, int w, int h)
26169 {
26170 XRectangle r;
26171 int mouse_face_overwritten_p = 0;
26172
26173 TRACE ((stderr, "expose_frame "));
26174
26175 /* No need to redraw if frame will be redrawn soon. */
26176 if (FRAME_GARBAGED_P (f))
26177 {
26178 TRACE ((stderr, " garbaged\n"));
26179 return;
26180 }
26181
26182 /* If basic faces haven't been realized yet, there is no point in
26183 trying to redraw anything. This can happen when we get an expose
26184 event while Emacs is starting, e.g. by moving another window. */
26185 if (FRAME_FACE_CACHE (f) == NULL
26186 || FRAME_FACE_CACHE (f)->used < BASIC_FACE_ID_SENTINEL)
26187 {
26188 TRACE ((stderr, " no faces\n"));
26189 return;
26190 }
26191
26192 if (w == 0 || h == 0)
26193 {
26194 r.x = r.y = 0;
26195 r.width = FRAME_COLUMN_WIDTH (f) * FRAME_COLS (f);
26196 r.height = FRAME_LINE_HEIGHT (f) * FRAME_LINES (f);
26197 }
26198 else
26199 {
26200 r.x = x;
26201 r.y = y;
26202 r.width = w;
26203 r.height = h;
26204 }
26205
26206 TRACE ((stderr, "(%d, %d, %d, %d)\n", r.x, r.y, r.width, r.height));
26207 mouse_face_overwritten_p = expose_window_tree (XWINDOW (f->root_window), &r);
26208
26209 if (WINDOWP (f->tool_bar_window))
26210 mouse_face_overwritten_p
26211 |= expose_window (XWINDOW (f->tool_bar_window), &r);
26212
26213 #ifdef HAVE_X_WINDOWS
26214 #ifndef MSDOS
26215 #ifndef USE_X_TOOLKIT
26216 if (WINDOWP (f->menu_bar_window))
26217 mouse_face_overwritten_p
26218 |= expose_window (XWINDOW (f->menu_bar_window), &r);
26219 #endif /* not USE_X_TOOLKIT */
26220 #endif
26221 #endif
26222
26223 /* Some window managers support a focus-follows-mouse style with
26224 delayed raising of frames. Imagine a partially obscured frame,
26225 and moving the mouse into partially obscured mouse-face on that
26226 frame. The visible part of the mouse-face will be highlighted,
26227 then the WM raises the obscured frame. With at least one WM, KDE
26228 2.1, Emacs is not getting any event for the raising of the frame
26229 (even tried with SubstructureRedirectMask), only Expose events.
26230 These expose events will draw text normally, i.e. not
26231 highlighted. Which means we must redo the highlight here.
26232 Subsume it under ``we love X''. --gerd 2001-08-15 */
26233 /* Included in Windows version because Windows most likely does not
26234 do the right thing if any third party tool offers
26235 focus-follows-mouse with delayed raise. --jason 2001-10-12 */
26236 if (mouse_face_overwritten_p && !FRAME_GARBAGED_P (f))
26237 {
26238 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
26239 if (f == hlinfo->mouse_face_mouse_frame)
26240 {
26241 int mouse_x = hlinfo->mouse_face_mouse_x;
26242 int mouse_y = hlinfo->mouse_face_mouse_y;
26243 clear_mouse_face (hlinfo);
26244 note_mouse_highlight (f, mouse_x, mouse_y);
26245 }
26246 }
26247 }
26248
26249
26250 /* EXPORT:
26251 Determine the intersection of two rectangles R1 and R2. Return
26252 the intersection in *RESULT. Value is non-zero if RESULT is not
26253 empty. */
26254
26255 int
26256 x_intersect_rectangles (XRectangle *r1, XRectangle *r2, XRectangle *result)
26257 {
26258 XRectangle *left, *right;
26259 XRectangle *upper, *lower;
26260 int intersection_p = 0;
26261
26262 /* Rearrange so that R1 is the left-most rectangle. */
26263 if (r1->x < r2->x)
26264 left = r1, right = r2;
26265 else
26266 left = r2, right = r1;
26267
26268 /* X0 of the intersection is right.x0, if this is inside R1,
26269 otherwise there is no intersection. */
26270 if (right->x <= left->x + left->width)
26271 {
26272 result->x = right->x;
26273
26274 /* The right end of the intersection is the minimum of the
26275 the right ends of left and right. */
26276 result->width = (min (left->x + left->width, right->x + right->width)
26277 - result->x);
26278
26279 /* Same game for Y. */
26280 if (r1->y < r2->y)
26281 upper = r1, lower = r2;
26282 else
26283 upper = r2, lower = r1;
26284
26285 /* The upper end of the intersection is lower.y0, if this is inside
26286 of upper. Otherwise, there is no intersection. */
26287 if (lower->y <= upper->y + upper->height)
26288 {
26289 result->y = lower->y;
26290
26291 /* The lower end of the intersection is the minimum of the lower
26292 ends of upper and lower. */
26293 result->height = (min (lower->y + lower->height,
26294 upper->y + upper->height)
26295 - result->y);
26296 intersection_p = 1;
26297 }
26298 }
26299
26300 return intersection_p;
26301 }
26302
26303 #endif /* HAVE_WINDOW_SYSTEM */
26304
26305 \f
26306 /***********************************************************************
26307 Initialization
26308 ***********************************************************************/
26309
26310 void
26311 syms_of_xdisp (void)
26312 {
26313 Vwith_echo_area_save_vector = Qnil;
26314 staticpro (&Vwith_echo_area_save_vector);
26315
26316 Vmessage_stack = Qnil;
26317 staticpro (&Vmessage_stack);
26318
26319 Qinhibit_redisplay = intern_c_string ("inhibit-redisplay");
26320 staticpro (&Qinhibit_redisplay);
26321
26322 message_dolog_marker1 = Fmake_marker ();
26323 staticpro (&message_dolog_marker1);
26324 message_dolog_marker2 = Fmake_marker ();
26325 staticpro (&message_dolog_marker2);
26326 message_dolog_marker3 = Fmake_marker ();
26327 staticpro (&message_dolog_marker3);
26328
26329 #if GLYPH_DEBUG
26330 defsubr (&Sdump_frame_glyph_matrix);
26331 defsubr (&Sdump_glyph_matrix);
26332 defsubr (&Sdump_glyph_row);
26333 defsubr (&Sdump_tool_bar_row);
26334 defsubr (&Strace_redisplay);
26335 defsubr (&Strace_to_stderr);
26336 #endif
26337 #ifdef HAVE_WINDOW_SYSTEM
26338 defsubr (&Stool_bar_lines_needed);
26339 defsubr (&Slookup_image_map);
26340 #endif
26341 defsubr (&Sformat_mode_line);
26342 defsubr (&Sinvisible_p);
26343 defsubr (&Scurrent_bidi_paragraph_direction);
26344
26345 staticpro (&Qmenu_bar_update_hook);
26346 Qmenu_bar_update_hook = intern_c_string ("menu-bar-update-hook");
26347
26348 staticpro (&Qoverriding_terminal_local_map);
26349 Qoverriding_terminal_local_map = intern_c_string ("overriding-terminal-local-map");
26350
26351 staticpro (&Qoverriding_local_map);
26352 Qoverriding_local_map = intern_c_string ("overriding-local-map");
26353
26354 staticpro (&Qwindow_scroll_functions);
26355 Qwindow_scroll_functions = intern_c_string ("window-scroll-functions");
26356
26357 staticpro (&Qwindow_text_change_functions);
26358 Qwindow_text_change_functions = intern_c_string ("window-text-change-functions");
26359
26360 staticpro (&Qredisplay_end_trigger_functions);
26361 Qredisplay_end_trigger_functions = intern_c_string ("redisplay-end-trigger-functions");
26362
26363 staticpro (&Qinhibit_point_motion_hooks);
26364 Qinhibit_point_motion_hooks = intern_c_string ("inhibit-point-motion-hooks");
26365
26366 Qeval = intern_c_string ("eval");
26367 staticpro (&Qeval);
26368
26369 QCdata = intern_c_string (":data");
26370 staticpro (&QCdata);
26371 Qdisplay = intern_c_string ("display");
26372 staticpro (&Qdisplay);
26373 Qspace_width = intern_c_string ("space-width");
26374 staticpro (&Qspace_width);
26375 Qraise = intern_c_string ("raise");
26376 staticpro (&Qraise);
26377 Qslice = intern_c_string ("slice");
26378 staticpro (&Qslice);
26379 Qspace = intern_c_string ("space");
26380 staticpro (&Qspace);
26381 Qmargin = intern_c_string ("margin");
26382 staticpro (&Qmargin);
26383 Qpointer = intern_c_string ("pointer");
26384 staticpro (&Qpointer);
26385 Qleft_margin = intern_c_string ("left-margin");
26386 staticpro (&Qleft_margin);
26387 Qright_margin = intern_c_string ("right-margin");
26388 staticpro (&Qright_margin);
26389 Qcenter = intern_c_string ("center");
26390 staticpro (&Qcenter);
26391 Qline_height = intern_c_string ("line-height");
26392 staticpro (&Qline_height);
26393 QCalign_to = intern_c_string (":align-to");
26394 staticpro (&QCalign_to);
26395 QCrelative_width = intern_c_string (":relative-width");
26396 staticpro (&QCrelative_width);
26397 QCrelative_height = intern_c_string (":relative-height");
26398 staticpro (&QCrelative_height);
26399 QCeval = intern_c_string (":eval");
26400 staticpro (&QCeval);
26401 QCpropertize = intern_c_string (":propertize");
26402 staticpro (&QCpropertize);
26403 QCfile = intern_c_string (":file");
26404 staticpro (&QCfile);
26405 Qfontified = intern_c_string ("fontified");
26406 staticpro (&Qfontified);
26407 Qfontification_functions = intern_c_string ("fontification-functions");
26408 staticpro (&Qfontification_functions);
26409 Qtrailing_whitespace = intern_c_string ("trailing-whitespace");
26410 staticpro (&Qtrailing_whitespace);
26411 Qescape_glyph = intern_c_string ("escape-glyph");
26412 staticpro (&Qescape_glyph);
26413 Qnobreak_space = intern_c_string ("nobreak-space");
26414 staticpro (&Qnobreak_space);
26415 Qimage = intern_c_string ("image");
26416 staticpro (&Qimage);
26417 Qtext = intern_c_string ("text");
26418 staticpro (&Qtext);
26419 Qboth = intern_c_string ("both");
26420 staticpro (&Qboth);
26421 Qboth_horiz = intern_c_string ("both-horiz");
26422 staticpro (&Qboth_horiz);
26423 Qtext_image_horiz = intern_c_string ("text-image-horiz");
26424 staticpro (&Qtext_image_horiz);
26425 QCmap = intern_c_string (":map");
26426 staticpro (&QCmap);
26427 QCpointer = intern_c_string (":pointer");
26428 staticpro (&QCpointer);
26429 Qrect = intern_c_string ("rect");
26430 staticpro (&Qrect);
26431 Qcircle = intern_c_string ("circle");
26432 staticpro (&Qcircle);
26433 Qpoly = intern_c_string ("poly");
26434 staticpro (&Qpoly);
26435 Qmessage_truncate_lines = intern_c_string ("message-truncate-lines");
26436 staticpro (&Qmessage_truncate_lines);
26437 Qgrow_only = intern_c_string ("grow-only");
26438 staticpro (&Qgrow_only);
26439 Qinhibit_menubar_update = intern_c_string ("inhibit-menubar-update");
26440 staticpro (&Qinhibit_menubar_update);
26441 Qinhibit_eval_during_redisplay = intern_c_string ("inhibit-eval-during-redisplay");
26442 staticpro (&Qinhibit_eval_during_redisplay);
26443 Qposition = intern_c_string ("position");
26444 staticpro (&Qposition);
26445 Qbuffer_position = intern_c_string ("buffer-position");
26446 staticpro (&Qbuffer_position);
26447 Qobject = intern_c_string ("object");
26448 staticpro (&Qobject);
26449 Qbar = intern_c_string ("bar");
26450 staticpro (&Qbar);
26451 Qhbar = intern_c_string ("hbar");
26452 staticpro (&Qhbar);
26453 Qbox = intern_c_string ("box");
26454 staticpro (&Qbox);
26455 Qhollow = intern_c_string ("hollow");
26456 staticpro (&Qhollow);
26457 Qhand = intern_c_string ("hand");
26458 staticpro (&Qhand);
26459 Qarrow = intern_c_string ("arrow");
26460 staticpro (&Qarrow);
26461 Qtext = intern_c_string ("text");
26462 staticpro (&Qtext);
26463 Qinhibit_free_realized_faces = intern_c_string ("inhibit-free-realized-faces");
26464 staticpro (&Qinhibit_free_realized_faces);
26465
26466 list_of_error = Fcons (Fcons (intern_c_string ("error"),
26467 Fcons (intern_c_string ("void-variable"), Qnil)),
26468 Qnil);
26469 staticpro (&list_of_error);
26470
26471 Qlast_arrow_position = intern_c_string ("last-arrow-position");
26472 staticpro (&Qlast_arrow_position);
26473 Qlast_arrow_string = intern_c_string ("last-arrow-string");
26474 staticpro (&Qlast_arrow_string);
26475
26476 Qoverlay_arrow_string = intern_c_string ("overlay-arrow-string");
26477 staticpro (&Qoverlay_arrow_string);
26478 Qoverlay_arrow_bitmap = intern_c_string ("overlay-arrow-bitmap");
26479 staticpro (&Qoverlay_arrow_bitmap);
26480
26481 echo_buffer[0] = echo_buffer[1] = Qnil;
26482 staticpro (&echo_buffer[0]);
26483 staticpro (&echo_buffer[1]);
26484
26485 echo_area_buffer[0] = echo_area_buffer[1] = Qnil;
26486 staticpro (&echo_area_buffer[0]);
26487 staticpro (&echo_area_buffer[1]);
26488
26489 Vmessages_buffer_name = make_pure_c_string ("*Messages*");
26490 staticpro (&Vmessages_buffer_name);
26491
26492 mode_line_proptrans_alist = Qnil;
26493 staticpro (&mode_line_proptrans_alist);
26494 mode_line_string_list = Qnil;
26495 staticpro (&mode_line_string_list);
26496 mode_line_string_face = Qnil;
26497 staticpro (&mode_line_string_face);
26498 mode_line_string_face_prop = Qnil;
26499 staticpro (&mode_line_string_face_prop);
26500 Vmode_line_unwind_vector = Qnil;
26501 staticpro (&Vmode_line_unwind_vector);
26502
26503 help_echo_string = Qnil;
26504 staticpro (&help_echo_string);
26505 help_echo_object = Qnil;
26506 staticpro (&help_echo_object);
26507 help_echo_window = Qnil;
26508 staticpro (&help_echo_window);
26509 previous_help_echo_string = Qnil;
26510 staticpro (&previous_help_echo_string);
26511 help_echo_pos = -1;
26512
26513 Qright_to_left = intern_c_string ("right-to-left");
26514 staticpro (&Qright_to_left);
26515 Qleft_to_right = intern_c_string ("left-to-right");
26516 staticpro (&Qleft_to_right);
26517
26518 #ifdef HAVE_WINDOW_SYSTEM
26519 DEFVAR_BOOL ("x-stretch-cursor", x_stretch_cursor_p,
26520 doc: /* *Non-nil means draw block cursor as wide as the glyph under it.
26521 For example, if a block cursor is over a tab, it will be drawn as
26522 wide as that tab on the display. */);
26523 x_stretch_cursor_p = 0;
26524 #endif
26525
26526 DEFVAR_LISP ("show-trailing-whitespace", Vshow_trailing_whitespace,
26527 doc: /* *Non-nil means highlight trailing whitespace.
26528 The face used for trailing whitespace is `trailing-whitespace'. */);
26529 Vshow_trailing_whitespace = Qnil;
26530
26531 DEFVAR_LISP ("nobreak-char-display", Vnobreak_char_display,
26532 doc: /* *Control highlighting of nobreak space and soft hyphen.
26533 A value of t means highlight the character itself (for nobreak space,
26534 use face `nobreak-space').
26535 A value of nil means no highlighting.
26536 Other values mean display the escape glyph followed by an ordinary
26537 space or ordinary hyphen. */);
26538 Vnobreak_char_display = Qt;
26539
26540 DEFVAR_LISP ("void-text-area-pointer", Vvoid_text_area_pointer,
26541 doc: /* *The pointer shape to show in void text areas.
26542 A value of nil means to show the text pointer. Other options are `arrow',
26543 `text', `hand', `vdrag', `hdrag', `modeline', and `hourglass'. */);
26544 Vvoid_text_area_pointer = Qarrow;
26545
26546 DEFVAR_LISP ("inhibit-redisplay", Vinhibit_redisplay,
26547 doc: /* Non-nil means don't actually do any redisplay.
26548 This is used for internal purposes. */);
26549 Vinhibit_redisplay = Qnil;
26550
26551 DEFVAR_LISP ("global-mode-string", Vglobal_mode_string,
26552 doc: /* String (or mode line construct) included (normally) in `mode-line-format'. */);
26553 Vglobal_mode_string = Qnil;
26554
26555 DEFVAR_LISP ("overlay-arrow-position", Voverlay_arrow_position,
26556 doc: /* Marker for where to display an arrow on top of the buffer text.
26557 This must be the beginning of a line in order to work.
26558 See also `overlay-arrow-string'. */);
26559 Voverlay_arrow_position = Qnil;
26560
26561 DEFVAR_LISP ("overlay-arrow-string", Voverlay_arrow_string,
26562 doc: /* String to display as an arrow in non-window frames.
26563 See also `overlay-arrow-position'. */);
26564 Voverlay_arrow_string = make_pure_c_string ("=>");
26565
26566 DEFVAR_LISP ("overlay-arrow-variable-list", Voverlay_arrow_variable_list,
26567 doc: /* List of variables (symbols) which hold markers for overlay arrows.
26568 The symbols on this list are examined during redisplay to determine
26569 where to display overlay arrows. */);
26570 Voverlay_arrow_variable_list
26571 = Fcons (intern_c_string ("overlay-arrow-position"), Qnil);
26572
26573 DEFVAR_INT ("scroll-step", emacs_scroll_step,
26574 doc: /* *The number of lines to try scrolling a window by when point moves out.
26575 If that fails to bring point back on frame, point is centered instead.
26576 If this is zero, point is always centered after it moves off frame.
26577 If you want scrolling to always be a line at a time, you should set
26578 `scroll-conservatively' to a large value rather than set this to 1. */);
26579
26580 DEFVAR_INT ("scroll-conservatively", scroll_conservatively,
26581 doc: /* *Scroll up to this many lines, to bring point back on screen.
26582 If point moves off-screen, redisplay will scroll by up to
26583 `scroll-conservatively' lines in order to bring point just barely
26584 onto the screen again. If that cannot be done, then redisplay
26585 recenters point as usual.
26586
26587 If the value is greater than 100, redisplay will never recenter point,
26588 but will always scroll just enough text to bring point into view, even
26589 if you move far away.
26590
26591 A value of zero means always recenter point if it moves off screen. */);
26592 scroll_conservatively = 0;
26593
26594 DEFVAR_INT ("scroll-margin", scroll_margin,
26595 doc: /* *Number of lines of margin at the top and bottom of a window.
26596 Recenter the window whenever point gets within this many lines
26597 of the top or bottom of the window. */);
26598 scroll_margin = 0;
26599
26600 DEFVAR_LISP ("display-pixels-per-inch", Vdisplay_pixels_per_inch,
26601 doc: /* Pixels per inch value for non-window system displays.
26602 Value is a number or a cons (WIDTH-DPI . HEIGHT-DPI). */);
26603 Vdisplay_pixels_per_inch = make_float (72.0);
26604
26605 #if GLYPH_DEBUG
26606 DEFVAR_INT ("debug-end-pos", debug_end_pos, doc: /* Don't ask. */);
26607 #endif
26608
26609 DEFVAR_LISP ("truncate-partial-width-windows",
26610 Vtruncate_partial_width_windows,
26611 doc: /* Non-nil means truncate lines in windows narrower than the frame.
26612 For an integer value, truncate lines in each window narrower than the
26613 full frame width, provided the window width is less than that integer;
26614 otherwise, respect the value of `truncate-lines'.
26615
26616 For any other non-nil value, truncate lines in all windows that do
26617 not span the full frame width.
26618
26619 A value of nil means to respect the value of `truncate-lines'.
26620
26621 If `word-wrap' is enabled, you might want to reduce this. */);
26622 Vtruncate_partial_width_windows = make_number (50);
26623
26624 DEFVAR_BOOL ("mode-line-inverse-video", mode_line_inverse_video,
26625 doc: /* When nil, display the mode-line/header-line/menu-bar in the default face.
26626 Any other value means to use the appropriate face, `mode-line',
26627 `header-line', or `menu' respectively. */);
26628 mode_line_inverse_video = 1;
26629
26630 DEFVAR_LISP ("line-number-display-limit", Vline_number_display_limit,
26631 doc: /* *Maximum buffer size for which line number should be displayed.
26632 If the buffer is bigger than this, the line number does not appear
26633 in the mode line. A value of nil means no limit. */);
26634 Vline_number_display_limit = Qnil;
26635
26636 DEFVAR_INT ("line-number-display-limit-width",
26637 line_number_display_limit_width,
26638 doc: /* *Maximum line width (in characters) for line number display.
26639 If the average length of the lines near point is bigger than this, then the
26640 line number may be omitted from the mode line. */);
26641 line_number_display_limit_width = 200;
26642
26643 DEFVAR_BOOL ("highlight-nonselected-windows", highlight_nonselected_windows,
26644 doc: /* *Non-nil means highlight region even in nonselected windows. */);
26645 highlight_nonselected_windows = 0;
26646
26647 DEFVAR_BOOL ("multiple-frames", multiple_frames,
26648 doc: /* Non-nil if more than one frame is visible on this display.
26649 Minibuffer-only frames don't count, but iconified frames do.
26650 This variable is not guaranteed to be accurate except while processing
26651 `frame-title-format' and `icon-title-format'. */);
26652
26653 DEFVAR_LISP ("frame-title-format", Vframe_title_format,
26654 doc: /* Template for displaying the title bar of visible frames.
26655 \(Assuming the window manager supports this feature.)
26656
26657 This variable has the same structure as `mode-line-format', except that
26658 the %c and %l constructs are ignored. It is used only on frames for
26659 which no explicit name has been set \(see `modify-frame-parameters'). */);
26660
26661 DEFVAR_LISP ("icon-title-format", Vicon_title_format,
26662 doc: /* Template for displaying the title bar of an iconified frame.
26663 \(Assuming the window manager supports this feature.)
26664 This variable has the same structure as `mode-line-format' (which see),
26665 and is used only on frames for which no explicit name has been set
26666 \(see `modify-frame-parameters'). */);
26667 Vicon_title_format
26668 = Vframe_title_format
26669 = pure_cons (intern_c_string ("multiple-frames"),
26670 pure_cons (make_pure_c_string ("%b"),
26671 pure_cons (pure_cons (empty_unibyte_string,
26672 pure_cons (intern_c_string ("invocation-name"),
26673 pure_cons (make_pure_c_string ("@"),
26674 pure_cons (intern_c_string ("system-name"),
26675 Qnil)))),
26676 Qnil)));
26677
26678 DEFVAR_LISP ("message-log-max", Vmessage_log_max,
26679 doc: /* Maximum number of lines to keep in the message log buffer.
26680 If nil, disable message logging. If t, log messages but don't truncate
26681 the buffer when it becomes large. */);
26682 Vmessage_log_max = make_number (100);
26683
26684 DEFVAR_LISP ("window-size-change-functions", Vwindow_size_change_functions,
26685 doc: /* Functions called before redisplay, if window sizes have changed.
26686 The value should be a list of functions that take one argument.
26687 Just before redisplay, for each frame, if any of its windows have changed
26688 size since the last redisplay, or have been split or deleted,
26689 all the functions in the list are called, with the frame as argument. */);
26690 Vwindow_size_change_functions = Qnil;
26691
26692 DEFVAR_LISP ("window-scroll-functions", Vwindow_scroll_functions,
26693 doc: /* List of functions to call before redisplaying a window with scrolling.
26694 Each function is called with two arguments, the window and its new
26695 display-start position. Note that these functions are also called by
26696 `set-window-buffer'. Also note that the value of `window-end' is not
26697 valid when these functions are called. */);
26698 Vwindow_scroll_functions = Qnil;
26699
26700 DEFVAR_LISP ("window-text-change-functions",
26701 Vwindow_text_change_functions,
26702 doc: /* Functions to call in redisplay when text in the window might change. */);
26703 Vwindow_text_change_functions = Qnil;
26704
26705 DEFVAR_LISP ("redisplay-end-trigger-functions", Vredisplay_end_trigger_functions,
26706 doc: /* Functions called when redisplay of a window reaches the end trigger.
26707 Each function is called with two arguments, the window and the end trigger value.
26708 See `set-window-redisplay-end-trigger'. */);
26709 Vredisplay_end_trigger_functions = Qnil;
26710
26711 DEFVAR_LISP ("mouse-autoselect-window", Vmouse_autoselect_window,
26712 doc: /* *Non-nil means autoselect window with mouse pointer.
26713 If nil, do not autoselect windows.
26714 A positive number means delay autoselection by that many seconds: a
26715 window is autoselected only after the mouse has remained in that
26716 window for the duration of the delay.
26717 A negative number has a similar effect, but causes windows to be
26718 autoselected only after the mouse has stopped moving. \(Because of
26719 the way Emacs compares mouse events, you will occasionally wait twice
26720 that time before the window gets selected.\)
26721 Any other value means to autoselect window instantaneously when the
26722 mouse pointer enters it.
26723
26724 Autoselection selects the minibuffer only if it is active, and never
26725 unselects the minibuffer if it is active.
26726
26727 When customizing this variable make sure that the actual value of
26728 `focus-follows-mouse' matches the behavior of your window manager. */);
26729 Vmouse_autoselect_window = Qnil;
26730
26731 DEFVAR_LISP ("auto-resize-tool-bars", Vauto_resize_tool_bars,
26732 doc: /* *Non-nil means automatically resize tool-bars.
26733 This dynamically changes the tool-bar's height to the minimum height
26734 that is needed to make all tool-bar items visible.
26735 If value is `grow-only', the tool-bar's height is only increased
26736 automatically; to decrease the tool-bar height, use \\[recenter]. */);
26737 Vauto_resize_tool_bars = Qt;
26738
26739 DEFVAR_BOOL ("auto-raise-tool-bar-buttons", auto_raise_tool_bar_buttons_p,
26740 doc: /* *Non-nil means raise tool-bar buttons when the mouse moves over them. */);
26741 auto_raise_tool_bar_buttons_p = 1;
26742
26743 DEFVAR_BOOL ("make-cursor-line-fully-visible", make_cursor_line_fully_visible_p,
26744 doc: /* *Non-nil means to scroll (recenter) cursor line if it is not fully visible. */);
26745 make_cursor_line_fully_visible_p = 1;
26746
26747 DEFVAR_LISP ("tool-bar-border", Vtool_bar_border,
26748 doc: /* *Border below tool-bar in pixels.
26749 If an integer, use it as the height of the border.
26750 If it is one of `internal-border-width' or `border-width', use the
26751 value of the corresponding frame parameter.
26752 Otherwise, no border is added below the tool-bar. */);
26753 Vtool_bar_border = Qinternal_border_width;
26754
26755 DEFVAR_LISP ("tool-bar-button-margin", Vtool_bar_button_margin,
26756 doc: /* *Margin around tool-bar buttons in pixels.
26757 If an integer, use that for both horizontal and vertical margins.
26758 Otherwise, value should be a pair of integers `(HORZ . VERT)' with
26759 HORZ specifying the horizontal margin, and VERT specifying the
26760 vertical margin. */);
26761 Vtool_bar_button_margin = make_number (DEFAULT_TOOL_BAR_BUTTON_MARGIN);
26762
26763 DEFVAR_INT ("tool-bar-button-relief", tool_bar_button_relief,
26764 doc: /* *Relief thickness of tool-bar buttons. */);
26765 tool_bar_button_relief = DEFAULT_TOOL_BAR_BUTTON_RELIEF;
26766
26767 DEFVAR_LISP ("tool-bar-style", Vtool_bar_style,
26768 doc: /* Tool bar style to use.
26769 It can be one of
26770 image - show images only
26771 text - show text only
26772 both - show both, text below image
26773 both-horiz - show text to the right of the image
26774 text-image-horiz - show text to the left of the image
26775 any other - use system default or image if no system default. */);
26776 Vtool_bar_style = Qnil;
26777
26778 DEFVAR_INT ("tool-bar-max-label-size", tool_bar_max_label_size,
26779 doc: /* *Maximum number of characters a label can have to be shown.
26780 The tool bar style must also show labels for this to have any effect, see
26781 `tool-bar-style'. */);
26782 tool_bar_max_label_size = DEFAULT_TOOL_BAR_LABEL_SIZE;
26783
26784 DEFVAR_LISP ("fontification-functions", Vfontification_functions,
26785 doc: /* List of functions to call to fontify regions of text.
26786 Each function is called with one argument POS. Functions must
26787 fontify a region starting at POS in the current buffer, and give
26788 fontified regions the property `fontified'. */);
26789 Vfontification_functions = Qnil;
26790 Fmake_variable_buffer_local (Qfontification_functions);
26791
26792 DEFVAR_BOOL ("unibyte-display-via-language-environment",
26793 unibyte_display_via_language_environment,
26794 doc: /* *Non-nil means display unibyte text according to language environment.
26795 Specifically, this means that raw bytes in the range 160-255 decimal
26796 are displayed by converting them to the equivalent multibyte characters
26797 according to the current language environment. As a result, they are
26798 displayed according to the current fontset.
26799
26800 Note that this variable affects only how these bytes are displayed,
26801 but does not change the fact they are interpreted as raw bytes. */);
26802 unibyte_display_via_language_environment = 0;
26803
26804 DEFVAR_LISP ("max-mini-window-height", Vmax_mini_window_height,
26805 doc: /* *Maximum height for resizing mini-windows.
26806 If a float, it specifies a fraction of the mini-window frame's height.
26807 If an integer, it specifies a number of lines. */);
26808 Vmax_mini_window_height = make_float (0.25);
26809
26810 DEFVAR_LISP ("resize-mini-windows", Vresize_mini_windows,
26811 doc: /* *How to resize mini-windows.
26812 A value of nil means don't automatically resize mini-windows.
26813 A value of t means resize them to fit the text displayed in them.
26814 A value of `grow-only', the default, means let mini-windows grow
26815 only, until their display becomes empty, at which point the windows
26816 go back to their normal size. */);
26817 Vresize_mini_windows = Qgrow_only;
26818
26819 DEFVAR_LISP ("blink-cursor-alist", Vblink_cursor_alist,
26820 doc: /* Alist specifying how to blink the cursor off.
26821 Each element has the form (ON-STATE . OFF-STATE). Whenever the
26822 `cursor-type' frame-parameter or variable equals ON-STATE,
26823 comparing using `equal', Emacs uses OFF-STATE to specify
26824 how to blink it off. ON-STATE and OFF-STATE are values for
26825 the `cursor-type' frame parameter.
26826
26827 If a frame's ON-STATE has no entry in this list,
26828 the frame's other specifications determine how to blink the cursor off. */);
26829 Vblink_cursor_alist = Qnil;
26830
26831 DEFVAR_BOOL ("auto-hscroll-mode", automatic_hscrolling_p,
26832 doc: /* Allow or disallow automatic horizontal scrolling of windows.
26833 If non-nil, windows are automatically scrolled horizontally to make
26834 point visible. */);
26835 automatic_hscrolling_p = 1;
26836 Qauto_hscroll_mode = intern_c_string ("auto-hscroll-mode");
26837 staticpro (&Qauto_hscroll_mode);
26838
26839 DEFVAR_INT ("hscroll-margin", hscroll_margin,
26840 doc: /* *How many columns away from the window edge point is allowed to get
26841 before automatic hscrolling will horizontally scroll the window. */);
26842 hscroll_margin = 5;
26843
26844 DEFVAR_LISP ("hscroll-step", Vhscroll_step,
26845 doc: /* *How many columns to scroll the window when point gets too close to the edge.
26846 When point is less than `hscroll-margin' columns from the window
26847 edge, automatic hscrolling will scroll the window by the amount of columns
26848 determined by this variable. If its value is a positive integer, scroll that
26849 many columns. If it's a positive floating-point number, it specifies the
26850 fraction of the window's width to scroll. If it's nil or zero, point will be
26851 centered horizontally after the scroll. Any other value, including negative
26852 numbers, are treated as if the value were zero.
26853
26854 Automatic hscrolling always moves point outside the scroll margin, so if
26855 point was more than scroll step columns inside the margin, the window will
26856 scroll more than the value given by the scroll step.
26857
26858 Note that the lower bound for automatic hscrolling specified by `scroll-left'
26859 and `scroll-right' overrides this variable's effect. */);
26860 Vhscroll_step = make_number (0);
26861
26862 DEFVAR_BOOL ("message-truncate-lines", message_truncate_lines,
26863 doc: /* If non-nil, messages are truncated instead of resizing the echo area.
26864 Bind this around calls to `message' to let it take effect. */);
26865 message_truncate_lines = 0;
26866
26867 DEFVAR_LISP ("menu-bar-update-hook", Vmenu_bar_update_hook,
26868 doc: /* Normal hook run to update the menu bar definitions.
26869 Redisplay runs this hook before it redisplays the menu bar.
26870 This is used to update submenus such as Buffers,
26871 whose contents depend on various data. */);
26872 Vmenu_bar_update_hook = Qnil;
26873
26874 DEFVAR_LISP ("menu-updating-frame", Vmenu_updating_frame,
26875 doc: /* Frame for which we are updating a menu.
26876 The enable predicate for a menu binding should check this variable. */);
26877 Vmenu_updating_frame = Qnil;
26878
26879 DEFVAR_BOOL ("inhibit-menubar-update", inhibit_menubar_update,
26880 doc: /* Non-nil means don't update menu bars. Internal use only. */);
26881 inhibit_menubar_update = 0;
26882
26883 DEFVAR_LISP ("wrap-prefix", Vwrap_prefix,
26884 doc: /* Prefix prepended to all continuation lines at display time.
26885 The value may be a string, an image, or a stretch-glyph; it is
26886 interpreted in the same way as the value of a `display' text property.
26887
26888 This variable is overridden by any `wrap-prefix' text or overlay
26889 property.
26890
26891 To add a prefix to non-continuation lines, use `line-prefix'. */);
26892 Vwrap_prefix = Qnil;
26893 staticpro (&Qwrap_prefix);
26894 Qwrap_prefix = intern_c_string ("wrap-prefix");
26895 Fmake_variable_buffer_local (Qwrap_prefix);
26896
26897 DEFVAR_LISP ("line-prefix", Vline_prefix,
26898 doc: /* Prefix prepended to all non-continuation lines at display time.
26899 The value may be a string, an image, or a stretch-glyph; it is
26900 interpreted in the same way as the value of a `display' text property.
26901
26902 This variable is overridden by any `line-prefix' text or overlay
26903 property.
26904
26905 To add a prefix to continuation lines, use `wrap-prefix'. */);
26906 Vline_prefix = Qnil;
26907 staticpro (&Qline_prefix);
26908 Qline_prefix = intern_c_string ("line-prefix");
26909 Fmake_variable_buffer_local (Qline_prefix);
26910
26911 DEFVAR_BOOL ("inhibit-eval-during-redisplay", inhibit_eval_during_redisplay,
26912 doc: /* Non-nil means don't eval Lisp during redisplay. */);
26913 inhibit_eval_during_redisplay = 0;
26914
26915 DEFVAR_BOOL ("inhibit-free-realized-faces", inhibit_free_realized_faces,
26916 doc: /* Non-nil means don't free realized faces. Internal use only. */);
26917 inhibit_free_realized_faces = 0;
26918
26919 #if GLYPH_DEBUG
26920 DEFVAR_BOOL ("inhibit-try-window-id", inhibit_try_window_id,
26921 doc: /* Inhibit try_window_id display optimization. */);
26922 inhibit_try_window_id = 0;
26923
26924 DEFVAR_BOOL ("inhibit-try-window-reusing", inhibit_try_window_reusing,
26925 doc: /* Inhibit try_window_reusing display optimization. */);
26926 inhibit_try_window_reusing = 0;
26927
26928 DEFVAR_BOOL ("inhibit-try-cursor-movement", inhibit_try_cursor_movement,
26929 doc: /* Inhibit try_cursor_movement display optimization. */);
26930 inhibit_try_cursor_movement = 0;
26931 #endif /* GLYPH_DEBUG */
26932
26933 DEFVAR_INT ("overline-margin", overline_margin,
26934 doc: /* *Space between overline and text, in pixels.
26935 The default value is 2: the height of the overline (1 pixel) plus 1 pixel
26936 margin to the caracter height. */);
26937 overline_margin = 2;
26938
26939 DEFVAR_INT ("underline-minimum-offset",
26940 underline_minimum_offset,
26941 doc: /* Minimum distance between baseline and underline.
26942 This can improve legibility of underlined text at small font sizes,
26943 particularly when using variable `x-use-underline-position-properties'
26944 with fonts that specify an UNDERLINE_POSITION relatively close to the
26945 baseline. The default value is 1. */);
26946 underline_minimum_offset = 1;
26947
26948 DEFVAR_BOOL ("display-hourglass", display_hourglass_p,
26949 doc: /* Non-nil means show an hourglass pointer, when Emacs is busy.
26950 This feature only works when on a window system that can change
26951 cursor shapes. */);
26952 display_hourglass_p = 1;
26953
26954 DEFVAR_LISP ("hourglass-delay", Vhourglass_delay,
26955 doc: /* *Seconds to wait before displaying an hourglass pointer when Emacs is busy. */);
26956 Vhourglass_delay = make_number (DEFAULT_HOURGLASS_DELAY);
26957
26958 hourglass_atimer = NULL;
26959 hourglass_shown_p = 0;
26960
26961 DEFSYM (Qglyphless_char, "glyphless-char");
26962 DEFSYM (Qhex_code, "hex-code");
26963 DEFSYM (Qempty_box, "empty-box");
26964 DEFSYM (Qthin_space, "thin-space");
26965 DEFSYM (Qzero_width, "zero-width");
26966
26967 DEFSYM (Qglyphless_char_display, "glyphless-char-display");
26968 /* Intern this now in case it isn't already done.
26969 Setting this variable twice is harmless.
26970 But don't staticpro it here--that is done in alloc.c. */
26971 Qchar_table_extra_slots = intern_c_string ("char-table-extra-slots");
26972 Fput (Qglyphless_char_display, Qchar_table_extra_slots, make_number (1));
26973
26974 DEFVAR_LISP ("glyphless-char-display", Vglyphless_char_display,
26975 doc: /* Char-table to control displaying of glyphless characters.
26976 Each element, if non-nil, is an ASCII acronym string (displayed in a box)
26977 or one of these symbols:
26978 hex-code: display the hexadecimal code of a character in a box
26979 empty-box: display as an empty box
26980 thin-space: display as 1-pixel width space
26981 zero-width: don't display
26982
26983 It has one extra slot to control the display of a character for which
26984 no font is found. The value of the slot is `hex-code' or `empty-box'.
26985 The default is `empty-box'. */);
26986 Vglyphless_char_display = Fmake_char_table (Qglyphless_char_display, Qnil);
26987 Fset_char_table_extra_slot (Vglyphless_char_display, make_number (0),
26988 Qempty_box);
26989 }
26990
26991
26992 /* Initialize this module when Emacs starts. */
26993
26994 void
26995 init_xdisp (void)
26996 {
26997 Lisp_Object root_window;
26998 struct window *mini_w;
26999
27000 current_header_line_height = current_mode_line_height = -1;
27001
27002 CHARPOS (this_line_start_pos) = 0;
27003
27004 mini_w = XWINDOW (minibuf_window);
27005 root_window = FRAME_ROOT_WINDOW (XFRAME (WINDOW_FRAME (mini_w)));
27006
27007 if (!noninteractive)
27008 {
27009 struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (root_window)));
27010 int i;
27011
27012 XWINDOW (root_window)->top_line = make_number (FRAME_TOP_MARGIN (f));
27013 set_window_height (root_window,
27014 FRAME_LINES (f) - 1 - FRAME_TOP_MARGIN (f),
27015 0);
27016 mini_w->top_line = make_number (FRAME_LINES (f) - 1);
27017 set_window_height (minibuf_window, 1, 0);
27018
27019 XWINDOW (root_window)->total_cols = make_number (FRAME_COLS (f));
27020 mini_w->total_cols = make_number (FRAME_COLS (f));
27021
27022 scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs;
27023 scratch_glyph_row.glyphs[TEXT_AREA + 1]
27024 = scratch_glyphs + MAX_SCRATCH_GLYPHS;
27025
27026 /* The default ellipsis glyphs `...'. */
27027 for (i = 0; i < 3; ++i)
27028 default_invis_vector[i] = make_number ('.');
27029 }
27030
27031 {
27032 /* Allocate the buffer for frame titles.
27033 Also used for `format-mode-line'. */
27034 int size = 100;
27035 mode_line_noprop_buf = (char *) xmalloc (size);
27036 mode_line_noprop_buf_end = mode_line_noprop_buf + size;
27037 mode_line_noprop_ptr = mode_line_noprop_buf;
27038 mode_line_target = MODE_LINE_DISPLAY;
27039 }
27040
27041 help_echo_showing_p = 0;
27042 }
27043
27044 /* Since w32 does not support atimers, it defines its own implementation of
27045 the following three functions in w32fns.c. */
27046 #ifndef WINDOWSNT
27047
27048 /* Platform-independent portion of hourglass implementation. */
27049
27050 /* Return non-zero if houglass timer has been started or hourglass is shown. */
27051 int
27052 hourglass_started (void)
27053 {
27054 return hourglass_shown_p || hourglass_atimer != NULL;
27055 }
27056
27057 /* Cancel a currently active hourglass timer, and start a new one. */
27058 void
27059 start_hourglass (void)
27060 {
27061 #if defined (HAVE_WINDOW_SYSTEM)
27062 EMACS_TIME delay;
27063 int secs, usecs = 0;
27064
27065 cancel_hourglass ();
27066
27067 if (INTEGERP (Vhourglass_delay)
27068 && XINT (Vhourglass_delay) > 0)
27069 secs = XFASTINT (Vhourglass_delay);
27070 else if (FLOATP (Vhourglass_delay)
27071 && XFLOAT_DATA (Vhourglass_delay) > 0)
27072 {
27073 Lisp_Object tem;
27074 tem = Ftruncate (Vhourglass_delay, Qnil);
27075 secs = XFASTINT (tem);
27076 usecs = (XFLOAT_DATA (Vhourglass_delay) - secs) * 1000000;
27077 }
27078 else
27079 secs = DEFAULT_HOURGLASS_DELAY;
27080
27081 EMACS_SET_SECS_USECS (delay, secs, usecs);
27082 hourglass_atimer = start_atimer (ATIMER_RELATIVE, delay,
27083 show_hourglass, NULL);
27084 #endif
27085 }
27086
27087
27088 /* Cancel the hourglass cursor timer if active, hide a busy cursor if
27089 shown. */
27090 void
27091 cancel_hourglass (void)
27092 {
27093 #if defined (HAVE_WINDOW_SYSTEM)
27094 if (hourglass_atimer)
27095 {
27096 cancel_atimer (hourglass_atimer);
27097 hourglass_atimer = NULL;
27098 }
27099
27100 if (hourglass_shown_p)
27101 hide_hourglass ();
27102 #endif
27103 }
27104 #endif /* ! WINDOWSNT */