Fix beg_col calculation when painting from window start.
[bpt/emacs.git] / src / xdisp.c
1 /* Display generation from window structure and buffer text.
2 Copyright (C) 1985, 1986, 1987, 1988, 1993, 1994, 1995,
3 1997, 1998, 1999, 2000, 2001, 2002, 2003,
4 2004, 2005, 2006, 2007, 2008, 2009, 2010
5 Free Software Foundation, Inc.
6
7 This file is part of GNU Emacs.
8
9 GNU Emacs is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13
14 GNU Emacs is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
21
22 /* New redisplay written by Gerd Moellmann <gerd@gnu.org>.
23
24 Redisplay.
25
26 Emacs separates the task of updating the display from code
27 modifying global state, e.g. buffer text. This way functions
28 operating on buffers don't also have to be concerned with updating
29 the display.
30
31 Updating the display is triggered by the Lisp interpreter when it
32 decides it's time to do it. This is done either automatically for
33 you as part of the interpreter's command loop or as the result of
34 calling Lisp functions like `sit-for'. The C function `redisplay'
35 in xdisp.c is the only entry into the inner redisplay code.
36
37 The following diagram shows how redisplay code is invoked. As you
38 can see, Lisp calls redisplay and vice versa. Under window systems
39 like X, some portions of the redisplay code are also called
40 asynchronously during mouse movement or expose events. It is very
41 important that these code parts do NOT use the C library (malloc,
42 free) because many C libraries under Unix are not reentrant. They
43 may also NOT call functions of the Lisp interpreter which could
44 change the interpreter's state. If you don't follow these rules,
45 you will encounter bugs which are very hard to explain.
46
47 +--------------+ redisplay +----------------+
48 | Lisp machine |---------------->| Redisplay code |<--+
49 +--------------+ (xdisp.c) +----------------+ |
50 ^ | |
51 +----------------------------------+ |
52 Don't use this path when called |
53 asynchronously! |
54 |
55 expose_window (asynchronous) |
56 |
57 X expose events -----+
58
59 What does redisplay do? Obviously, it has to figure out somehow what
60 has been changed since the last time the display has been updated,
61 and to make these changes visible. Preferably it would do that in
62 a moderately intelligent way, i.e. fast.
63
64 Changes in buffer text can be deduced from window and buffer
65 structures, and from some global variables like `beg_unchanged' and
66 `end_unchanged'. The contents of the display are additionally
67 recorded in a `glyph matrix', a two-dimensional matrix of glyph
68 structures. Each row in such a matrix corresponds to a line on the
69 display, and each glyph in a row corresponds to a column displaying
70 a character, an image, or what else. This matrix is called the
71 `current glyph matrix' or `current matrix' in redisplay
72 terminology.
73
74 For buffer parts that have been changed since the last update, a
75 second glyph matrix is constructed, the so called `desired glyph
76 matrix' or short `desired matrix'. Current and desired matrix are
77 then compared to find a cheap way to update the display, e.g. by
78 reusing part of the display by scrolling lines.
79
80 You will find a lot of redisplay optimizations when you start
81 looking at the innards of redisplay. The overall goal of all these
82 optimizations is to make redisplay fast because it is done
83 frequently. Some of these optimizations are implemented by the
84 following functions:
85
86 . try_cursor_movement
87
88 This function tries to update the display if the text in the
89 window did not change and did not scroll, only point moved, and
90 it did not move off the displayed portion of the text.
91
92 . try_window_reusing_current_matrix
93
94 This function reuses the current matrix of a window when text
95 has not changed, but the window start changed (e.g., due to
96 scrolling).
97
98 . try_window_id
99
100 This function attempts to redisplay a window by reusing parts of
101 its existing display. It finds and reuses the part that was not
102 changed, and redraws the rest.
103
104 . try_window
105
106 This function performs the full redisplay of a single window
107 assuming that its fonts were not changed and that the cursor
108 will not end up in the scroll margins. (Loading fonts requires
109 re-adjustment of dimensions of glyph matrices, which makes this
110 method impossible to use.)
111
112 These optimizations are tried in sequence (some can be skipped if
113 it is known that they are not applicable). If none of the
114 optimizations were successful, redisplay calls redisplay_windows,
115 which performs a full redisplay of all windows.
116
117 Desired matrices.
118
119 Desired matrices are always built per Emacs window. The function
120 `display_line' is the central function to look at if you are
121 interested. It constructs one row in a desired matrix given an
122 iterator structure containing both a buffer position and a
123 description of the environment in which the text is to be
124 displayed. But this is too early, read on.
125
126 Characters and pixmaps displayed for a range of buffer text depend
127 on various settings of buffers and windows, on overlays and text
128 properties, on display tables, on selective display. The good news
129 is that all this hairy stuff is hidden behind a small set of
130 interface functions taking an iterator structure (struct it)
131 argument.
132
133 Iteration over things to be displayed is then simple. It is
134 started by initializing an iterator with a call to init_iterator.
135 Calls to get_next_display_element fill the iterator structure with
136 relevant information about the next thing to display. Calls to
137 set_iterator_to_next move the iterator to the next thing.
138
139 Besides this, an iterator also contains information about the
140 display environment in which glyphs for display elements are to be
141 produced. It has fields for the width and height of the display,
142 the information whether long lines are truncated or continued, a
143 current X and Y position, and lots of other stuff you can better
144 see in dispextern.h.
145
146 Glyphs in a desired matrix are normally constructed in a loop
147 calling get_next_display_element and then PRODUCE_GLYPHS. The call
148 to PRODUCE_GLYPHS will fill the iterator structure with pixel
149 information about the element being displayed and at the same time
150 produce glyphs for it. If the display element fits on the line
151 being displayed, set_iterator_to_next is called next, otherwise the
152 glyphs produced are discarded. The function display_line is the
153 workhorse of filling glyph rows in the desired matrix with glyphs.
154 In addition to producing glyphs, it also handles line truncation
155 and continuation, word wrap, and cursor positioning (for the
156 latter, see also set_cursor_from_row).
157
158 Frame matrices.
159
160 That just couldn't be all, could it? What about terminal types not
161 supporting operations on sub-windows of the screen? To update the
162 display on such a terminal, window-based glyph matrices are not
163 well suited. To be able to reuse part of the display (scrolling
164 lines up and down), we must instead have a view of the whole
165 screen. This is what `frame matrices' are for. They are a trick.
166
167 Frames on terminals like above have a glyph pool. Windows on such
168 a frame sub-allocate their glyph memory from their frame's glyph
169 pool. The frame itself is given its own glyph matrices. By
170 coincidence---or maybe something else---rows in window glyph
171 matrices are slices of corresponding rows in frame matrices. Thus
172 writing to window matrices implicitly updates a frame matrix which
173 provides us with the view of the whole screen that we originally
174 wanted to have without having to move many bytes around. To be
175 honest, there is a little bit more done, but not much more. If you
176 plan to extend that code, take a look at dispnew.c. The function
177 build_frame_matrix is a good starting point.
178
179 Bidirectional display.
180
181 Bidirectional display adds quite some hair to this already complex
182 design. The good news are that a large portion of that hairy stuff
183 is hidden in bidi.c behind only 3 interfaces. bidi.c implements a
184 reordering engine which is called by set_iterator_to_next and
185 returns the next character to display in the visual order. See
186 commentary on bidi.c for more details. As far as redisplay is
187 concerned, the effect of calling bidi_move_to_visually_next, the
188 main interface of the reordering engine, is that the iterator gets
189 magically placed on the buffer or string position that is to be
190 displayed next. In other words, a linear iteration through the
191 buffer/string is replaced with a non-linear one. All the rest of
192 the redisplay is oblivious to the bidi reordering.
193
194 Well, almost oblivious---there are still complications, most of
195 them due to the fact that buffer and string positions no longer
196 change monotonously with glyph indices in a glyph row. Moreover,
197 for continued lines, the buffer positions may not even be
198 monotonously changing with vertical positions. Also, accounting
199 for face changes, overlays, etc. becomes more complex because
200 non-linear iteration could potentially skip many positions with
201 changes, and then cross them again on the way back...
202
203 One other prominent effect of bidirectional display is that some
204 paragraphs of text need to be displayed starting at the right
205 margin of the window---the so-called right-to-left, or R2L
206 paragraphs. R2L paragraphs are displayed with R2L glyph rows,
207 which have their reversed_p flag set. The bidi reordering engine
208 produces characters in such rows starting from the character which
209 should be the rightmost on display. PRODUCE_GLYPHS then reverses
210 the order, when it fills up the glyph row whose reversed_p flag is
211 set, by prepending each new glyph to what is already there, instead
212 of appending it. When the glyph row is complete, the function
213 extend_face_to_end_of_line fills the empty space to the left of the
214 leftmost character with special glyphs, which will display as,
215 well, empty. On text terminals, these special glyphs are simply
216 blank characters. On graphics terminals, there's a single stretch
217 glyph with suitably computed width. Both the blanks and the
218 stretch glyph are given the face of the background of the line.
219 This way, the terminal-specific back-end can still draw the glyphs
220 left to right, even for R2L lines.
221
222 Note one important detail mentioned above: that the bidi reordering
223 engine, driven by the iterator, produces characters in R2L rows
224 starting at the character that will be the rightmost on display.
225 As far as the iterator is concerned, the geometry of such rows is
226 still left to right, i.e. the iterator "thinks" the first character
227 is at the leftmost pixel position. The iterator does not know that
228 PRODUCE_GLYPHS reverses the order of the glyphs that the iterator
229 delivers. This is important when functions from the the move_it_*
230 family are used to get to certain screen position or to match
231 screen coordinates with buffer coordinates: these functions use the
232 iterator geometry, which is left to right even in R2L paragraphs.
233 This works well with most callers of move_it_*, because they need
234 to get to a specific column, and columns are still numbered in the
235 reading order, i.e. the rightmost character in a R2L paragraph is
236 still column zero. But some callers do not get well with this; a
237 notable example is mouse clicks that need to find the character
238 that corresponds to certain pixel coordinates. See
239 buffer_posn_from_coords in dispnew.c for how this is handled. */
240
241 #include <config.h>
242 #include <stdio.h>
243 #include <limits.h>
244 #include <setjmp.h>
245
246 #include "lisp.h"
247 #include "keyboard.h"
248 #include "frame.h"
249 #include "window.h"
250 #include "termchar.h"
251 #include "dispextern.h"
252 #include "buffer.h"
253 #include "character.h"
254 #include "charset.h"
255 #include "indent.h"
256 #include "commands.h"
257 #include "keymap.h"
258 #include "macros.h"
259 #include "disptab.h"
260 #include "termhooks.h"
261 #include "termopts.h"
262 #include "intervals.h"
263 #include "coding.h"
264 #include "process.h"
265 #include "region-cache.h"
266 #include "font.h"
267 #include "fontset.h"
268 #include "blockinput.h"
269
270 #ifdef HAVE_X_WINDOWS
271 #include "xterm.h"
272 #endif
273 #ifdef WINDOWSNT
274 #include "w32term.h"
275 #endif
276 #ifdef HAVE_NS
277 #include "nsterm.h"
278 #endif
279 #ifdef USE_GTK
280 #include "gtkutil.h"
281 #endif
282
283 #include "font.h"
284
285 #ifndef FRAME_X_OUTPUT
286 #define FRAME_X_OUTPUT(f) ((f)->output_data.x)
287 #endif
288
289 #define INFINITY 10000000
290
291 Lisp_Object Qoverriding_local_map, Qoverriding_terminal_local_map;
292 Lisp_Object Qwindow_scroll_functions, Vwindow_scroll_functions;
293 Lisp_Object Qwindow_text_change_functions, Vwindow_text_change_functions;
294 Lisp_Object Qredisplay_end_trigger_functions, Vredisplay_end_trigger_functions;
295 Lisp_Object Qinhibit_point_motion_hooks;
296 Lisp_Object QCeval, QCfile, QCdata, QCpropertize;
297 Lisp_Object Qfontified;
298 Lisp_Object Qgrow_only;
299 Lisp_Object Qinhibit_eval_during_redisplay;
300 Lisp_Object Qbuffer_position, Qposition, Qobject;
301 Lisp_Object Qright_to_left, Qleft_to_right;
302
303 /* Cursor shapes */
304 Lisp_Object Qbar, Qhbar, Qbox, Qhollow;
305
306 /* Pointer shapes */
307 Lisp_Object Qarrow, Qhand, Qtext;
308
309 Lisp_Object Qrisky_local_variable;
310
311 /* Holds the list (error). */
312 Lisp_Object list_of_error;
313
314 /* Functions called to fontify regions of text. */
315
316 Lisp_Object Vfontification_functions;
317 Lisp_Object Qfontification_functions;
318
319 /* Non-nil means automatically select any window when the mouse
320 cursor moves into it. */
321 Lisp_Object Vmouse_autoselect_window;
322
323 Lisp_Object Vwrap_prefix, Qwrap_prefix;
324 Lisp_Object Vline_prefix, Qline_prefix;
325
326 /* Non-zero means draw tool bar buttons raised when the mouse moves
327 over them. */
328
329 int auto_raise_tool_bar_buttons_p;
330
331 /* Non-zero means to reposition window if cursor line is only partially visible. */
332
333 int make_cursor_line_fully_visible_p;
334
335 /* Margin below tool bar in pixels. 0 or nil means no margin.
336 If value is `internal-border-width' or `border-width',
337 the corresponding frame parameter is used. */
338
339 Lisp_Object Vtool_bar_border;
340
341 /* Margin around tool bar buttons in pixels. */
342
343 Lisp_Object Vtool_bar_button_margin;
344
345 /* Thickness of shadow to draw around tool bar buttons. */
346
347 EMACS_INT tool_bar_button_relief;
348
349 /* Non-nil means automatically resize tool-bars so that all tool-bar
350 items are visible, and no blank lines remain.
351
352 If value is `grow-only', only make tool-bar bigger. */
353
354 Lisp_Object Vauto_resize_tool_bars;
355
356 /* Type of tool bar. Can be symbols image, text, both or both-hroiz. */
357
358 Lisp_Object Vtool_bar_style;
359
360 /* Maximum number of characters a label can have to be shown. */
361
362 EMACS_INT tool_bar_max_label_size;
363
364 /* Non-zero means draw block and hollow cursor as wide as the glyph
365 under it. For example, if a block cursor is over a tab, it will be
366 drawn as wide as that tab on the display. */
367
368 int x_stretch_cursor_p;
369
370 /* Non-nil means don't actually do any redisplay. */
371
372 Lisp_Object Vinhibit_redisplay, Qinhibit_redisplay;
373
374 /* Non-zero means Lisp evaluation during redisplay is inhibited. */
375
376 int inhibit_eval_during_redisplay;
377
378 /* Names of text properties relevant for redisplay. */
379
380 Lisp_Object Qdisplay;
381
382 /* Symbols used in text property values. */
383
384 Lisp_Object Vdisplay_pixels_per_inch;
385 Lisp_Object Qspace, QCalign_to, QCrelative_width, QCrelative_height;
386 Lisp_Object Qleft_margin, Qright_margin, Qspace_width, Qraise;
387 Lisp_Object Qslice;
388 Lisp_Object Qcenter;
389 Lisp_Object Qmargin, Qpointer;
390 Lisp_Object Qline_height;
391
392 /* Non-nil means highlight trailing whitespace. */
393
394 Lisp_Object Vshow_trailing_whitespace;
395
396 /* Non-nil means escape non-break space and hyphens. */
397
398 Lisp_Object Vnobreak_char_display;
399
400 #ifdef HAVE_WINDOW_SYSTEM
401
402 /* Test if overflow newline into fringe. Called with iterator IT
403 at or past right window margin, and with IT->current_x set. */
404
405 #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(IT) \
406 (!NILP (Voverflow_newline_into_fringe) \
407 && FRAME_WINDOW_P ((IT)->f) \
408 && ((IT)->bidi_it.paragraph_dir == R2L \
409 ? (WINDOW_LEFT_FRINGE_WIDTH ((IT)->w) > 0) \
410 : (WINDOW_RIGHT_FRINGE_WIDTH ((IT)->w) > 0)) \
411 && (IT)->current_x == (IT)->last_visible_x \
412 && (IT)->line_wrap != WORD_WRAP)
413
414 #else /* !HAVE_WINDOW_SYSTEM */
415 #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(it) 0
416 #endif /* HAVE_WINDOW_SYSTEM */
417
418 /* Test if the display element loaded in IT is a space or tab
419 character. This is used to determine word wrapping. */
420
421 #define IT_DISPLAYING_WHITESPACE(it) \
422 (it->what == IT_CHARACTER && (it->c == ' ' || it->c == '\t'))
423
424 /* Non-nil means show the text cursor in void text areas
425 i.e. in blank areas after eol and eob. This used to be
426 the default in 21.3. */
427
428 Lisp_Object Vvoid_text_area_pointer;
429
430 /* Name of the face used to highlight trailing whitespace. */
431
432 Lisp_Object Qtrailing_whitespace;
433
434 /* Name and number of the face used to highlight escape glyphs. */
435
436 Lisp_Object Qescape_glyph;
437
438 /* Name and number of the face used to highlight non-breaking spaces. */
439
440 Lisp_Object Qnobreak_space;
441
442 /* The symbol `image' which is the car of the lists used to represent
443 images in Lisp. Also a tool bar style. */
444
445 Lisp_Object Qimage;
446
447 /* The image map types. */
448 Lisp_Object QCmap, QCpointer;
449 Lisp_Object Qrect, Qcircle, Qpoly;
450
451 /* Tool bar styles */
452 Lisp_Object Qboth, Qboth_horiz, Qtext_image_horiz;
453
454 /* Non-zero means print newline to stdout before next mini-buffer
455 message. */
456
457 int noninteractive_need_newline;
458
459 /* Non-zero means print newline to message log before next message. */
460
461 static int message_log_need_newline;
462
463 /* Three markers that message_dolog uses.
464 It could allocate them itself, but that causes trouble
465 in handling memory-full errors. */
466 static Lisp_Object message_dolog_marker1;
467 static Lisp_Object message_dolog_marker2;
468 static Lisp_Object message_dolog_marker3;
469 \f
470 /* The buffer position of the first character appearing entirely or
471 partially on the line of the selected window which contains the
472 cursor; <= 0 if not known. Set by set_cursor_from_row, used for
473 redisplay optimization in redisplay_internal. */
474
475 static struct text_pos this_line_start_pos;
476
477 /* Number of characters past the end of the line above, including the
478 terminating newline. */
479
480 static struct text_pos this_line_end_pos;
481
482 /* The vertical positions and the height of this line. */
483
484 static int this_line_vpos;
485 static int this_line_y;
486 static int this_line_pixel_height;
487
488 /* X position at which this display line starts. Usually zero;
489 negative if first character is partially visible. */
490
491 static int this_line_start_x;
492
493 /* Buffer that this_line_.* variables are referring to. */
494
495 static struct buffer *this_line_buffer;
496
497 /* Nonzero means truncate lines in all windows less wide than the
498 frame. */
499
500 Lisp_Object Vtruncate_partial_width_windows;
501
502 /* A flag to control how to display unibyte 8-bit character. */
503
504 int unibyte_display_via_language_environment;
505
506 /* Nonzero means we have more than one non-mini-buffer-only frame.
507 Not guaranteed to be accurate except while parsing
508 frame-title-format. */
509
510 int multiple_frames;
511
512 Lisp_Object Vglobal_mode_string;
513
514
515 /* List of variables (symbols) which hold markers for overlay arrows.
516 The symbols on this list are examined during redisplay to determine
517 where to display overlay arrows. */
518
519 Lisp_Object Voverlay_arrow_variable_list;
520
521 /* Marker for where to display an arrow on top of the buffer text. */
522
523 Lisp_Object Voverlay_arrow_position;
524
525 /* String to display for the arrow. Only used on terminal frames. */
526
527 Lisp_Object Voverlay_arrow_string;
528
529 /* Values of those variables at last redisplay are stored as
530 properties on `overlay-arrow-position' symbol. However, if
531 Voverlay_arrow_position is a marker, last-arrow-position is its
532 numerical position. */
533
534 Lisp_Object Qlast_arrow_position, Qlast_arrow_string;
535
536 /* Alternative overlay-arrow-string and overlay-arrow-bitmap
537 properties on a symbol in overlay-arrow-variable-list. */
538
539 Lisp_Object Qoverlay_arrow_string, Qoverlay_arrow_bitmap;
540
541 /* Like mode-line-format, but for the title bar on a visible frame. */
542
543 Lisp_Object Vframe_title_format;
544
545 /* Like mode-line-format, but for the title bar on an iconified frame. */
546
547 Lisp_Object Vicon_title_format;
548
549 /* List of functions to call when a window's size changes. These
550 functions get one arg, a frame on which one or more windows' sizes
551 have changed. */
552
553 static Lisp_Object Vwindow_size_change_functions;
554
555 Lisp_Object Qmenu_bar_update_hook, Vmenu_bar_update_hook;
556
557 /* Nonzero if an overlay arrow has been displayed in this window. */
558
559 static int overlay_arrow_seen;
560
561 /* Nonzero means highlight the region even in nonselected windows. */
562
563 int highlight_nonselected_windows;
564
565 /* If cursor motion alone moves point off frame, try scrolling this
566 many lines up or down if that will bring it back. */
567
568 static EMACS_INT scroll_step;
569
570 /* Nonzero means scroll just far enough to bring point back on the
571 screen, when appropriate. */
572
573 static EMACS_INT scroll_conservatively;
574
575 /* Recenter the window whenever point gets within this many lines of
576 the top or bottom of the window. This value is translated into a
577 pixel value by multiplying it with FRAME_LINE_HEIGHT, which means
578 that there is really a fixed pixel height scroll margin. */
579
580 EMACS_INT scroll_margin;
581
582 /* Number of windows showing the buffer of the selected window (or
583 another buffer with the same base buffer). keyboard.c refers to
584 this. */
585
586 int buffer_shared;
587
588 /* Vector containing glyphs for an ellipsis `...'. */
589
590 static Lisp_Object default_invis_vector[3];
591
592 /* Zero means display the mode-line/header-line/menu-bar in the default face
593 (this slightly odd definition is for compatibility with previous versions
594 of emacs), non-zero means display them using their respective faces.
595
596 This variable is deprecated. */
597
598 int mode_line_inverse_video;
599
600 /* Prompt to display in front of the mini-buffer contents. */
601
602 Lisp_Object minibuf_prompt;
603
604 /* Width of current mini-buffer prompt. Only set after display_line
605 of the line that contains the prompt. */
606
607 int minibuf_prompt_width;
608
609 /* This is the window where the echo area message was displayed. It
610 is always a mini-buffer window, but it may not be the same window
611 currently active as a mini-buffer. */
612
613 Lisp_Object echo_area_window;
614
615 /* List of pairs (MESSAGE . MULTIBYTE). The function save_message
616 pushes the current message and the value of
617 message_enable_multibyte on the stack, the function restore_message
618 pops the stack and displays MESSAGE again. */
619
620 Lisp_Object Vmessage_stack;
621
622 /* Nonzero means multibyte characters were enabled when the echo area
623 message was specified. */
624
625 int message_enable_multibyte;
626
627 /* Nonzero if we should redraw the mode lines on the next redisplay. */
628
629 int update_mode_lines;
630
631 /* Nonzero if window sizes or contents have changed since last
632 redisplay that finished. */
633
634 int windows_or_buffers_changed;
635
636 /* Nonzero means a frame's cursor type has been changed. */
637
638 int cursor_type_changed;
639
640 /* Nonzero after display_mode_line if %l was used and it displayed a
641 line number. */
642
643 int line_number_displayed;
644
645 /* Maximum buffer size for which to display line numbers. */
646
647 Lisp_Object Vline_number_display_limit;
648
649 /* Line width to consider when repositioning for line number display. */
650
651 static EMACS_INT line_number_display_limit_width;
652
653 /* Number of lines to keep in the message log buffer. t means
654 infinite. nil means don't log at all. */
655
656 Lisp_Object Vmessage_log_max;
657
658 /* The name of the *Messages* buffer, a string. */
659
660 static Lisp_Object Vmessages_buffer_name;
661
662 /* Current, index 0, and last displayed echo area message. Either
663 buffers from echo_buffers, or nil to indicate no message. */
664
665 Lisp_Object echo_area_buffer[2];
666
667 /* The buffers referenced from echo_area_buffer. */
668
669 static Lisp_Object echo_buffer[2];
670
671 /* A vector saved used in with_area_buffer to reduce consing. */
672
673 static Lisp_Object Vwith_echo_area_save_vector;
674
675 /* Non-zero means display_echo_area should display the last echo area
676 message again. Set by redisplay_preserve_echo_area. */
677
678 static int display_last_displayed_message_p;
679
680 /* Nonzero if echo area is being used by print; zero if being used by
681 message. */
682
683 int message_buf_print;
684
685 /* The symbol `inhibit-menubar-update' and its DEFVAR_BOOL variable. */
686
687 Lisp_Object Qinhibit_menubar_update;
688 int inhibit_menubar_update;
689
690 /* When evaluating expressions from menu bar items (enable conditions,
691 for instance), this is the frame they are being processed for. */
692
693 Lisp_Object Vmenu_updating_frame;
694
695 /* Maximum height for resizing mini-windows. Either a float
696 specifying a fraction of the available height, or an integer
697 specifying a number of lines. */
698
699 Lisp_Object Vmax_mini_window_height;
700
701 /* Non-zero means messages should be displayed with truncated
702 lines instead of being continued. */
703
704 int message_truncate_lines;
705 Lisp_Object Qmessage_truncate_lines;
706
707 /* Set to 1 in clear_message to make redisplay_internal aware
708 of an emptied echo area. */
709
710 static int message_cleared_p;
711
712 /* How to blink the default frame cursor off. */
713 Lisp_Object Vblink_cursor_alist;
714
715 /* A scratch glyph row with contents used for generating truncation
716 glyphs. Also used in direct_output_for_insert. */
717
718 #define MAX_SCRATCH_GLYPHS 100
719 struct glyph_row scratch_glyph_row;
720 static struct glyph scratch_glyphs[MAX_SCRATCH_GLYPHS];
721
722 /* Ascent and height of the last line processed by move_it_to. */
723
724 static int last_max_ascent, last_height;
725
726 /* Non-zero if there's a help-echo in the echo area. */
727
728 int help_echo_showing_p;
729
730 /* If >= 0, computed, exact values of mode-line and header-line height
731 to use in the macros CURRENT_MODE_LINE_HEIGHT and
732 CURRENT_HEADER_LINE_HEIGHT. */
733
734 int current_mode_line_height, current_header_line_height;
735
736 /* The maximum distance to look ahead for text properties. Values
737 that are too small let us call compute_char_face and similar
738 functions too often which is expensive. Values that are too large
739 let us call compute_char_face and alike too often because we
740 might not be interested in text properties that far away. */
741
742 #define TEXT_PROP_DISTANCE_LIMIT 100
743
744 #if GLYPH_DEBUG
745
746 /* Variables to turn off display optimizations from Lisp. */
747
748 int inhibit_try_window_id, inhibit_try_window_reusing;
749 int inhibit_try_cursor_movement;
750
751 /* Non-zero means print traces of redisplay if compiled with
752 GLYPH_DEBUG != 0. */
753
754 int trace_redisplay_p;
755
756 #endif /* GLYPH_DEBUG */
757
758 #ifdef DEBUG_TRACE_MOVE
759 /* Non-zero means trace with TRACE_MOVE to stderr. */
760 int trace_move;
761
762 #define TRACE_MOVE(x) if (trace_move) fprintf x; else (void) 0
763 #else
764 #define TRACE_MOVE(x) (void) 0
765 #endif
766
767 /* Non-zero means automatically scroll windows horizontally to make
768 point visible. */
769
770 int automatic_hscrolling_p;
771 Lisp_Object Qauto_hscroll_mode;
772
773 /* How close to the margin can point get before the window is scrolled
774 horizontally. */
775 EMACS_INT hscroll_margin;
776
777 /* How much to scroll horizontally when point is inside the above margin. */
778 Lisp_Object Vhscroll_step;
779
780 /* The variable `resize-mini-windows'. If nil, don't resize
781 mini-windows. If t, always resize them to fit the text they
782 display. If `grow-only', let mini-windows grow only until they
783 become empty. */
784
785 Lisp_Object Vresize_mini_windows;
786
787 /* Buffer being redisplayed -- for redisplay_window_error. */
788
789 struct buffer *displayed_buffer;
790
791 /* Space between overline and text. */
792
793 EMACS_INT overline_margin;
794
795 /* Require underline to be at least this many screen pixels below baseline
796 This to avoid underline "merging" with the base of letters at small
797 font sizes, particularly when x_use_underline_position_properties is on. */
798
799 EMACS_INT underline_minimum_offset;
800
801 /* Value returned from text property handlers (see below). */
802
803 enum prop_handled
804 {
805 HANDLED_NORMALLY,
806 HANDLED_RECOMPUTE_PROPS,
807 HANDLED_OVERLAY_STRING_CONSUMED,
808 HANDLED_RETURN
809 };
810
811 /* A description of text properties that redisplay is interested
812 in. */
813
814 struct props
815 {
816 /* The name of the property. */
817 Lisp_Object *name;
818
819 /* A unique index for the property. */
820 enum prop_idx idx;
821
822 /* A handler function called to set up iterator IT from the property
823 at IT's current position. Value is used to steer handle_stop. */
824 enum prop_handled (*handler) (struct it *it);
825 };
826
827 static enum prop_handled handle_face_prop (struct it *);
828 static enum prop_handled handle_invisible_prop (struct it *);
829 static enum prop_handled handle_display_prop (struct it *);
830 static enum prop_handled handle_composition_prop (struct it *);
831 static enum prop_handled handle_overlay_change (struct it *);
832 static enum prop_handled handle_fontified_prop (struct it *);
833
834 /* Properties handled by iterators. */
835
836 static struct props it_props[] =
837 {
838 {&Qfontified, FONTIFIED_PROP_IDX, handle_fontified_prop},
839 /* Handle `face' before `display' because some sub-properties of
840 `display' need to know the face. */
841 {&Qface, FACE_PROP_IDX, handle_face_prop},
842 {&Qdisplay, DISPLAY_PROP_IDX, handle_display_prop},
843 {&Qinvisible, INVISIBLE_PROP_IDX, handle_invisible_prop},
844 {&Qcomposition, COMPOSITION_PROP_IDX, handle_composition_prop},
845 {NULL, 0, NULL}
846 };
847
848 /* Value is the position described by X. If X is a marker, value is
849 the marker_position of X. Otherwise, value is X. */
850
851 #define COERCE_MARKER(X) (MARKERP ((X)) ? Fmarker_position (X) : (X))
852
853 /* Enumeration returned by some move_it_.* functions internally. */
854
855 enum move_it_result
856 {
857 /* Not used. Undefined value. */
858 MOVE_UNDEFINED,
859
860 /* Move ended at the requested buffer position or ZV. */
861 MOVE_POS_MATCH_OR_ZV,
862
863 /* Move ended at the requested X pixel position. */
864 MOVE_X_REACHED,
865
866 /* Move within a line ended at the end of a line that must be
867 continued. */
868 MOVE_LINE_CONTINUED,
869
870 /* Move within a line ended at the end of a line that would
871 be displayed truncated. */
872 MOVE_LINE_TRUNCATED,
873
874 /* Move within a line ended at a line end. */
875 MOVE_NEWLINE_OR_CR
876 };
877
878 /* This counter is used to clear the face cache every once in a while
879 in redisplay_internal. It is incremented for each redisplay.
880 Every CLEAR_FACE_CACHE_COUNT full redisplays, the face cache is
881 cleared. */
882
883 #define CLEAR_FACE_CACHE_COUNT 500
884 static int clear_face_cache_count;
885
886 /* Similarly for the image cache. */
887
888 #ifdef HAVE_WINDOW_SYSTEM
889 #define CLEAR_IMAGE_CACHE_COUNT 101
890 static int clear_image_cache_count;
891 #endif
892
893 /* Non-zero while redisplay_internal is in progress. */
894
895 int redisplaying_p;
896
897 /* Non-zero means don't free realized faces. Bound while freeing
898 realized faces is dangerous because glyph matrices might still
899 reference them. */
900
901 int inhibit_free_realized_faces;
902 Lisp_Object Qinhibit_free_realized_faces;
903
904 /* If a string, XTread_socket generates an event to display that string.
905 (The display is done in read_char.) */
906
907 Lisp_Object help_echo_string;
908 Lisp_Object help_echo_window;
909 Lisp_Object help_echo_object;
910 int help_echo_pos;
911
912 /* Temporary variable for XTread_socket. */
913
914 Lisp_Object previous_help_echo_string;
915
916 /* Null glyph slice */
917
918 static struct glyph_slice null_glyph_slice = { 0, 0, 0, 0 };
919
920 /* Platform-independent portion of hourglass implementation. */
921
922 /* Non-zero means we're allowed to display a hourglass pointer. */
923 int display_hourglass_p;
924
925 /* Non-zero means an hourglass cursor is currently shown. */
926 int hourglass_shown_p;
927
928 /* If non-null, an asynchronous timer that, when it expires, displays
929 an hourglass cursor on all frames. */
930 struct atimer *hourglass_atimer;
931
932 /* Number of seconds to wait before displaying an hourglass cursor. */
933 Lisp_Object Vhourglass_delay;
934
935 /* Default number of seconds to wait before displaying an hourglass
936 cursor. */
937 #define DEFAULT_HOURGLASS_DELAY 1
938
939 \f
940 /* Function prototypes. */
941
942 static void setup_for_ellipsis (struct it *, int);
943 static void mark_window_display_accurate_1 (struct window *, int);
944 static int single_display_spec_string_p (Lisp_Object, Lisp_Object);
945 static int display_prop_string_p (Lisp_Object, Lisp_Object);
946 static int cursor_row_p (struct window *, struct glyph_row *);
947 static int redisplay_mode_lines (Lisp_Object, int);
948 static char *decode_mode_spec_coding (Lisp_Object, char *, int);
949
950 static Lisp_Object get_it_property (struct it *it, Lisp_Object prop);
951
952 static void handle_line_prefix (struct it *);
953
954 static void pint2str (char *, int, int);
955 static void pint2hrstr (char *, int, int);
956 static struct text_pos run_window_scroll_functions (Lisp_Object,
957 struct text_pos);
958 static void reconsider_clip_changes (struct window *, struct buffer *);
959 static int text_outside_line_unchanged_p (struct window *, int, int);
960 static void store_mode_line_noprop_char (char);
961 static int store_mode_line_noprop (const unsigned char *, int, int);
962 static void x_consider_frame_title (Lisp_Object);
963 static void handle_stop (struct it *);
964 static void handle_stop_backwards (struct it *, EMACS_INT);
965 static int tool_bar_lines_needed (struct frame *, int *);
966 static int single_display_spec_intangible_p (Lisp_Object);
967 static void ensure_echo_area_buffers (void);
968 static Lisp_Object unwind_with_echo_area_buffer (Lisp_Object);
969 static Lisp_Object with_echo_area_buffer_unwind_data (struct window *);
970 static int with_echo_area_buffer (struct window *, int,
971 int (*) (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT),
972 EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT);
973 static void clear_garbaged_frames (void);
974 static int current_message_1 (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT);
975 static int truncate_message_1 (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT);
976 static int set_message_1 (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT);
977 static int display_echo_area (struct window *);
978 static int display_echo_area_1 (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT);
979 static int resize_mini_window_1 (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT);
980 static Lisp_Object unwind_redisplay (Lisp_Object);
981 static int string_char_and_length (const unsigned char *, int *);
982 static struct text_pos display_prop_end (struct it *, Lisp_Object,
983 struct text_pos);
984 static int compute_window_start_on_continuation_line (struct window *);
985 static Lisp_Object safe_eval_handler (Lisp_Object);
986 static void insert_left_trunc_glyphs (struct it *);
987 static struct glyph_row *get_overlay_arrow_glyph_row (struct window *,
988 Lisp_Object);
989 static void extend_face_to_end_of_line (struct it *);
990 static int append_space_for_newline (struct it *, int);
991 static int cursor_row_fully_visible_p (struct window *, int, int);
992 static int try_scrolling (Lisp_Object, int, EMACS_INT, EMACS_INT, int, int);
993 static int try_cursor_movement (Lisp_Object, struct text_pos, int *);
994 static int trailing_whitespace_p (int);
995 static int message_log_check_duplicate (int, int, int, int);
996 static void push_it (struct it *);
997 static void pop_it (struct it *);
998 static void sync_frame_with_window_matrix_rows (struct window *);
999 static void select_frame_for_redisplay (Lisp_Object);
1000 static void redisplay_internal (int);
1001 static int echo_area_display (int);
1002 static void redisplay_windows (Lisp_Object);
1003 static void redisplay_window (Lisp_Object, int);
1004 static Lisp_Object redisplay_window_error (Lisp_Object);
1005 static Lisp_Object redisplay_window_0 (Lisp_Object);
1006 static Lisp_Object redisplay_window_1 (Lisp_Object);
1007 static int update_menu_bar (struct frame *, int, int);
1008 static int try_window_reusing_current_matrix (struct window *);
1009 static int try_window_id (struct window *);
1010 static int display_line (struct it *);
1011 static int display_mode_lines (struct window *);
1012 static int display_mode_line (struct window *, enum face_id, Lisp_Object);
1013 static int display_mode_element (struct it *, int, int, int, Lisp_Object, Lisp_Object, int);
1014 static int store_mode_line_string (const char *, Lisp_Object, int, int, int, Lisp_Object);
1015 static const char *decode_mode_spec (struct window *, int, int, int,
1016 Lisp_Object *);
1017 static void display_menu_bar (struct window *);
1018 static int display_count_lines (int, int, int, int, int *);
1019 static int display_string (const unsigned char *, Lisp_Object, Lisp_Object,
1020 EMACS_INT, EMACS_INT, struct it *, int, int, int, int);
1021 static void compute_line_metrics (struct it *);
1022 static void run_redisplay_end_trigger_hook (struct it *);
1023 static int get_overlay_strings (struct it *, int);
1024 static int get_overlay_strings_1 (struct it *, int, int);
1025 static void next_overlay_string (struct it *);
1026 static void reseat (struct it *, struct text_pos, int);
1027 static void reseat_1 (struct it *, struct text_pos, int);
1028 static void back_to_previous_visible_line_start (struct it *);
1029 void reseat_at_previous_visible_line_start (struct it *);
1030 static void reseat_at_next_visible_line_start (struct it *, int);
1031 static int next_element_from_ellipsis (struct it *);
1032 static int next_element_from_display_vector (struct it *);
1033 static int next_element_from_string (struct it *);
1034 static int next_element_from_c_string (struct it *);
1035 static int next_element_from_buffer (struct it *);
1036 static int next_element_from_composition (struct it *);
1037 static int next_element_from_image (struct it *);
1038 static int next_element_from_stretch (struct it *);
1039 static void load_overlay_strings (struct it *, int);
1040 static int init_from_display_pos (struct it *, struct window *,
1041 struct display_pos *);
1042 static void reseat_to_string (struct it *, const unsigned char *,
1043 Lisp_Object, int, int, int, int);
1044 static enum move_it_result
1045 move_it_in_display_line_to (struct it *, EMACS_INT, int,
1046 enum move_operation_enum);
1047 void move_it_vertically_backward (struct it *, int);
1048 static void init_to_row_start (struct it *, struct window *,
1049 struct glyph_row *);
1050 static int init_to_row_end (struct it *, struct window *,
1051 struct glyph_row *);
1052 static void back_to_previous_line_start (struct it *);
1053 static int forward_to_next_line_start (struct it *, int *);
1054 static struct text_pos string_pos_nchars_ahead (struct text_pos,
1055 Lisp_Object, int);
1056 static struct text_pos string_pos (int, Lisp_Object);
1057 static struct text_pos c_string_pos (int, const unsigned char *, int);
1058 static int number_of_chars (const unsigned char *, int);
1059 static void compute_stop_pos (struct it *);
1060 static void compute_string_pos (struct text_pos *, struct text_pos,
1061 Lisp_Object);
1062 static int face_before_or_after_it_pos (struct it *, int);
1063 static EMACS_INT next_overlay_change (EMACS_INT);
1064 static int handle_single_display_spec (struct it *, Lisp_Object,
1065 Lisp_Object, Lisp_Object,
1066 struct text_pos *, int);
1067 static int underlying_face_id (struct it *);
1068 static int in_ellipses_for_invisible_text_p (struct display_pos *,
1069 struct window *);
1070
1071 #define face_before_it_pos(IT) face_before_or_after_it_pos ((IT), 1)
1072 #define face_after_it_pos(IT) face_before_or_after_it_pos ((IT), 0)
1073
1074 #ifdef HAVE_WINDOW_SYSTEM
1075
1076 static void update_tool_bar (struct frame *, int);
1077 static void build_desired_tool_bar_string (struct frame *f);
1078 static int redisplay_tool_bar (struct frame *);
1079 static void display_tool_bar_line (struct it *, int);
1080 static void notice_overwritten_cursor (struct window *,
1081 enum glyph_row_area,
1082 int, int, int, int);
1083 static void append_stretch_glyph (struct it *, Lisp_Object,
1084 int, int, int);
1085 static int coords_in_mouse_face_p (struct window *, int, int);
1086
1087
1088
1089 #endif /* HAVE_WINDOW_SYSTEM */
1090
1091 \f
1092 /***********************************************************************
1093 Window display dimensions
1094 ***********************************************************************/
1095
1096 /* Return the bottom boundary y-position for text lines in window W.
1097 This is the first y position at which a line cannot start.
1098 It is relative to the top of the window.
1099
1100 This is the height of W minus the height of a mode line, if any. */
1101
1102 INLINE int
1103 window_text_bottom_y (struct window *w)
1104 {
1105 int height = WINDOW_TOTAL_HEIGHT (w);
1106
1107 if (WINDOW_WANTS_MODELINE_P (w))
1108 height -= CURRENT_MODE_LINE_HEIGHT (w);
1109 return height;
1110 }
1111
1112 /* Return the pixel width of display area AREA of window W. AREA < 0
1113 means return the total width of W, not including fringes to
1114 the left and right of the window. */
1115
1116 INLINE int
1117 window_box_width (struct window *w, int area)
1118 {
1119 int cols = XFASTINT (w->total_cols);
1120 int pixels = 0;
1121
1122 if (!w->pseudo_window_p)
1123 {
1124 cols -= WINDOW_SCROLL_BAR_COLS (w);
1125
1126 if (area == TEXT_AREA)
1127 {
1128 if (INTEGERP (w->left_margin_cols))
1129 cols -= XFASTINT (w->left_margin_cols);
1130 if (INTEGERP (w->right_margin_cols))
1131 cols -= XFASTINT (w->right_margin_cols);
1132 pixels = -WINDOW_TOTAL_FRINGE_WIDTH (w);
1133 }
1134 else if (area == LEFT_MARGIN_AREA)
1135 {
1136 cols = (INTEGERP (w->left_margin_cols)
1137 ? XFASTINT (w->left_margin_cols) : 0);
1138 pixels = 0;
1139 }
1140 else if (area == RIGHT_MARGIN_AREA)
1141 {
1142 cols = (INTEGERP (w->right_margin_cols)
1143 ? XFASTINT (w->right_margin_cols) : 0);
1144 pixels = 0;
1145 }
1146 }
1147
1148 return cols * WINDOW_FRAME_COLUMN_WIDTH (w) + pixels;
1149 }
1150
1151
1152 /* Return the pixel height of the display area of window W, not
1153 including mode lines of W, if any. */
1154
1155 INLINE int
1156 window_box_height (struct window *w)
1157 {
1158 struct frame *f = XFRAME (w->frame);
1159 int height = WINDOW_TOTAL_HEIGHT (w);
1160
1161 xassert (height >= 0);
1162
1163 /* Note: the code below that determines the mode-line/header-line
1164 height is essentially the same as that contained in the macro
1165 CURRENT_{MODE,HEADER}_LINE_HEIGHT, except that it checks whether
1166 the appropriate glyph row has its `mode_line_p' flag set,
1167 and if it doesn't, uses estimate_mode_line_height instead. */
1168
1169 if (WINDOW_WANTS_MODELINE_P (w))
1170 {
1171 struct glyph_row *ml_row
1172 = (w->current_matrix && w->current_matrix->rows
1173 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
1174 : 0);
1175 if (ml_row && ml_row->mode_line_p)
1176 height -= ml_row->height;
1177 else
1178 height -= estimate_mode_line_height (f, CURRENT_MODE_LINE_FACE_ID (w));
1179 }
1180
1181 if (WINDOW_WANTS_HEADER_LINE_P (w))
1182 {
1183 struct glyph_row *hl_row
1184 = (w->current_matrix && w->current_matrix->rows
1185 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
1186 : 0);
1187 if (hl_row && hl_row->mode_line_p)
1188 height -= hl_row->height;
1189 else
1190 height -= estimate_mode_line_height (f, HEADER_LINE_FACE_ID);
1191 }
1192
1193 /* With a very small font and a mode-line that's taller than
1194 default, we might end up with a negative height. */
1195 return max (0, height);
1196 }
1197
1198 /* Return the window-relative coordinate of the left edge of display
1199 area AREA of window W. AREA < 0 means return the left edge of the
1200 whole window, to the right of the left fringe of W. */
1201
1202 INLINE int
1203 window_box_left_offset (struct window *w, int area)
1204 {
1205 int x;
1206
1207 if (w->pseudo_window_p)
1208 return 0;
1209
1210 x = WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
1211
1212 if (area == TEXT_AREA)
1213 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1214 + window_box_width (w, LEFT_MARGIN_AREA));
1215 else if (area == RIGHT_MARGIN_AREA)
1216 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1217 + window_box_width (w, LEFT_MARGIN_AREA)
1218 + window_box_width (w, TEXT_AREA)
1219 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
1220 ? 0
1221 : WINDOW_RIGHT_FRINGE_WIDTH (w)));
1222 else if (area == LEFT_MARGIN_AREA
1223 && WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w))
1224 x += WINDOW_LEFT_FRINGE_WIDTH (w);
1225
1226 return x;
1227 }
1228
1229
1230 /* Return the window-relative coordinate of the right edge of display
1231 area AREA of window W. AREA < 0 means return the right edge of the
1232 whole window, to the left of the right fringe of W. */
1233
1234 INLINE int
1235 window_box_right_offset (struct window *w, int area)
1236 {
1237 return window_box_left_offset (w, area) + window_box_width (w, area);
1238 }
1239
1240 /* Return the frame-relative coordinate of the left edge of display
1241 area AREA of window W. AREA < 0 means return the left edge of the
1242 whole window, to the right of the left fringe of W. */
1243
1244 INLINE int
1245 window_box_left (struct window *w, int area)
1246 {
1247 struct frame *f = XFRAME (w->frame);
1248 int x;
1249
1250 if (w->pseudo_window_p)
1251 return FRAME_INTERNAL_BORDER_WIDTH (f);
1252
1253 x = (WINDOW_LEFT_EDGE_X (w)
1254 + window_box_left_offset (w, area));
1255
1256 return x;
1257 }
1258
1259
1260 /* Return the frame-relative coordinate of the right edge of display
1261 area AREA of window W. AREA < 0 means return the right edge of the
1262 whole window, to the left of the right fringe of W. */
1263
1264 INLINE int
1265 window_box_right (struct window *w, int area)
1266 {
1267 return window_box_left (w, area) + window_box_width (w, area);
1268 }
1269
1270 /* Get the bounding box of the display area AREA of window W, without
1271 mode lines, in frame-relative coordinates. AREA < 0 means the
1272 whole window, not including the left and right fringes of
1273 the window. Return in *BOX_X and *BOX_Y the frame-relative pixel
1274 coordinates of the upper-left corner of the box. Return in
1275 *BOX_WIDTH, and *BOX_HEIGHT the pixel width and height of the box. */
1276
1277 INLINE void
1278 window_box (struct window *w, int area, int *box_x, int *box_y,
1279 int *box_width, int *box_height)
1280 {
1281 if (box_width)
1282 *box_width = window_box_width (w, area);
1283 if (box_height)
1284 *box_height = window_box_height (w);
1285 if (box_x)
1286 *box_x = window_box_left (w, area);
1287 if (box_y)
1288 {
1289 *box_y = WINDOW_TOP_EDGE_Y (w);
1290 if (WINDOW_WANTS_HEADER_LINE_P (w))
1291 *box_y += CURRENT_HEADER_LINE_HEIGHT (w);
1292 }
1293 }
1294
1295
1296 /* Get the bounding box of the display area AREA of window W, without
1297 mode lines. AREA < 0 means the whole window, not including the
1298 left and right fringe of the window. Return in *TOP_LEFT_X
1299 and TOP_LEFT_Y the frame-relative pixel coordinates of the
1300 upper-left corner of the box. Return in *BOTTOM_RIGHT_X, and
1301 *BOTTOM_RIGHT_Y the coordinates of the bottom-right corner of the
1302 box. */
1303
1304 INLINE void
1305 window_box_edges (struct window *w, int area, int *top_left_x, int *top_left_y,
1306 int *bottom_right_x, int *bottom_right_y)
1307 {
1308 window_box (w, area, top_left_x, top_left_y, bottom_right_x,
1309 bottom_right_y);
1310 *bottom_right_x += *top_left_x;
1311 *bottom_right_y += *top_left_y;
1312 }
1313
1314
1315 \f
1316 /***********************************************************************
1317 Utilities
1318 ***********************************************************************/
1319
1320 /* Return the bottom y-position of the line the iterator IT is in.
1321 This can modify IT's settings. */
1322
1323 int
1324 line_bottom_y (struct it *it)
1325 {
1326 int line_height = it->max_ascent + it->max_descent;
1327 int line_top_y = it->current_y;
1328
1329 if (line_height == 0)
1330 {
1331 if (last_height)
1332 line_height = last_height;
1333 else if (IT_CHARPOS (*it) < ZV)
1334 {
1335 move_it_by_lines (it, 1, 1);
1336 line_height = (it->max_ascent || it->max_descent
1337 ? it->max_ascent + it->max_descent
1338 : last_height);
1339 }
1340 else
1341 {
1342 struct glyph_row *row = it->glyph_row;
1343
1344 /* Use the default character height. */
1345 it->glyph_row = NULL;
1346 it->what = IT_CHARACTER;
1347 it->c = ' ';
1348 it->len = 1;
1349 PRODUCE_GLYPHS (it);
1350 line_height = it->ascent + it->descent;
1351 it->glyph_row = row;
1352 }
1353 }
1354
1355 return line_top_y + line_height;
1356 }
1357
1358
1359 /* Return 1 if position CHARPOS is visible in window W.
1360 CHARPOS < 0 means return info about WINDOW_END position.
1361 If visible, set *X and *Y to pixel coordinates of top left corner.
1362 Set *RTOP and *RBOT to pixel height of an invisible area of glyph at POS.
1363 Set *ROWH and *VPOS to row's visible height and VPOS (row number). */
1364
1365 int
1366 pos_visible_p (struct window *w, int charpos, int *x, int *y,
1367 int *rtop, int *rbot, int *rowh, int *vpos)
1368 {
1369 struct it it;
1370 struct text_pos top;
1371 int visible_p = 0;
1372 struct buffer *old_buffer = NULL;
1373
1374 if (FRAME_INITIAL_P (XFRAME (WINDOW_FRAME (w))))
1375 return visible_p;
1376
1377 if (XBUFFER (w->buffer) != current_buffer)
1378 {
1379 old_buffer = current_buffer;
1380 set_buffer_internal_1 (XBUFFER (w->buffer));
1381 }
1382
1383 SET_TEXT_POS_FROM_MARKER (top, w->start);
1384
1385 /* Compute exact mode line heights. */
1386 if (WINDOW_WANTS_MODELINE_P (w))
1387 current_mode_line_height
1388 = display_mode_line (w, CURRENT_MODE_LINE_FACE_ID (w),
1389 current_buffer->mode_line_format);
1390
1391 if (WINDOW_WANTS_HEADER_LINE_P (w))
1392 current_header_line_height
1393 = display_mode_line (w, HEADER_LINE_FACE_ID,
1394 current_buffer->header_line_format);
1395
1396 start_display (&it, w, top);
1397 move_it_to (&it, charpos, -1, it.last_visible_y-1, -1,
1398 (charpos >= 0 ? MOVE_TO_POS : 0) | MOVE_TO_Y);
1399
1400 if (charpos >= 0 && IT_CHARPOS (it) >= charpos)
1401 {
1402 /* We have reached CHARPOS, or passed it. How the call to
1403 move_it_to can overshoot: (i) If CHARPOS is on invisible
1404 text, move_it_to stops at the end of the invisible text,
1405 after CHARPOS. (ii) If CHARPOS is in a display vector,
1406 move_it_to stops on its last glyph. */
1407 int top_x = it.current_x;
1408 int top_y = it.current_y;
1409 enum it_method it_method = it.method;
1410 /* Calling line_bottom_y may change it.method, it.position, etc. */
1411 int bottom_y = (last_height = 0, line_bottom_y (&it));
1412 int window_top_y = WINDOW_HEADER_LINE_HEIGHT (w);
1413
1414 if (top_y < window_top_y)
1415 visible_p = bottom_y > window_top_y;
1416 else if (top_y < it.last_visible_y)
1417 visible_p = 1;
1418 if (visible_p)
1419 {
1420 if (it_method == GET_FROM_DISPLAY_VECTOR)
1421 {
1422 /* We stopped on the last glyph of a display vector.
1423 Try and recompute. Hack alert! */
1424 if (charpos < 2 || top.charpos >= charpos)
1425 top_x = it.glyph_row->x;
1426 else
1427 {
1428 struct it it2;
1429 start_display (&it2, w, top);
1430 move_it_to (&it2, charpos - 1, -1, -1, -1, MOVE_TO_POS);
1431 get_next_display_element (&it2);
1432 PRODUCE_GLYPHS (&it2);
1433 if (ITERATOR_AT_END_OF_LINE_P (&it2)
1434 || it2.current_x > it2.last_visible_x)
1435 top_x = it.glyph_row->x;
1436 else
1437 {
1438 top_x = it2.current_x;
1439 top_y = it2.current_y;
1440 }
1441 }
1442 }
1443
1444 *x = top_x;
1445 *y = max (top_y + max (0, it.max_ascent - it.ascent), window_top_y);
1446 *rtop = max (0, window_top_y - top_y);
1447 *rbot = max (0, bottom_y - it.last_visible_y);
1448 *rowh = max (0, (min (bottom_y, it.last_visible_y)
1449 - max (top_y, window_top_y)));
1450 *vpos = it.vpos;
1451 }
1452 }
1453 else
1454 {
1455 struct it it2;
1456
1457 it2 = it;
1458 if (IT_CHARPOS (it) < ZV && FETCH_BYTE (IT_BYTEPOS (it)) != '\n')
1459 move_it_by_lines (&it, 1, 0);
1460 if (charpos < IT_CHARPOS (it)
1461 || (it.what == IT_EOB && charpos == IT_CHARPOS (it)))
1462 {
1463 visible_p = 1;
1464 move_it_to (&it2, charpos, -1, -1, -1, MOVE_TO_POS);
1465 *x = it2.current_x;
1466 *y = it2.current_y + it2.max_ascent - it2.ascent;
1467 *rtop = max (0, -it2.current_y);
1468 *rbot = max (0, ((it2.current_y + it2.max_ascent + it2.max_descent)
1469 - it.last_visible_y));
1470 *rowh = max (0, (min (it2.current_y + it2.max_ascent + it2.max_descent,
1471 it.last_visible_y)
1472 - max (it2.current_y,
1473 WINDOW_HEADER_LINE_HEIGHT (w))));
1474 *vpos = it2.vpos;
1475 }
1476 }
1477
1478 if (old_buffer)
1479 set_buffer_internal_1 (old_buffer);
1480
1481 current_header_line_height = current_mode_line_height = -1;
1482
1483 if (visible_p && XFASTINT (w->hscroll) > 0)
1484 *x -= XFASTINT (w->hscroll) * WINDOW_FRAME_COLUMN_WIDTH (w);
1485
1486 #if 0
1487 /* Debugging code. */
1488 if (visible_p)
1489 fprintf (stderr, "+pv pt=%d vs=%d --> x=%d y=%d rt=%d rb=%d rh=%d vp=%d\n",
1490 charpos, w->vscroll, *x, *y, *rtop, *rbot, *rowh, *vpos);
1491 else
1492 fprintf (stderr, "-pv pt=%d vs=%d\n", charpos, w->vscroll);
1493 #endif
1494
1495 return visible_p;
1496 }
1497
1498
1499 /* Return the next character from STR which is MAXLEN bytes long.
1500 Return in *LEN the length of the character. This is like
1501 STRING_CHAR_AND_LENGTH but never returns an invalid character. If
1502 we find one, we return a `?', but with the length of the invalid
1503 character. */
1504
1505 static INLINE int
1506 string_char_and_length (const unsigned char *str, int *len)
1507 {
1508 int c;
1509
1510 c = STRING_CHAR_AND_LENGTH (str, *len);
1511 if (!CHAR_VALID_P (c, 1))
1512 /* We may not change the length here because other places in Emacs
1513 don't use this function, i.e. they silently accept invalid
1514 characters. */
1515 c = '?';
1516
1517 return c;
1518 }
1519
1520
1521
1522 /* Given a position POS containing a valid character and byte position
1523 in STRING, return the position NCHARS ahead (NCHARS >= 0). */
1524
1525 static struct text_pos
1526 string_pos_nchars_ahead (struct text_pos pos, Lisp_Object string, int nchars)
1527 {
1528 xassert (STRINGP (string) && nchars >= 0);
1529
1530 if (STRING_MULTIBYTE (string))
1531 {
1532 int rest = SBYTES (string) - BYTEPOS (pos);
1533 const unsigned char *p = SDATA (string) + BYTEPOS (pos);
1534 int len;
1535
1536 while (nchars--)
1537 {
1538 string_char_and_length (p, &len);
1539 p += len, rest -= len;
1540 xassert (rest >= 0);
1541 CHARPOS (pos) += 1;
1542 BYTEPOS (pos) += len;
1543 }
1544 }
1545 else
1546 SET_TEXT_POS (pos, CHARPOS (pos) + nchars, BYTEPOS (pos) + nchars);
1547
1548 return pos;
1549 }
1550
1551
1552 /* Value is the text position, i.e. character and byte position,
1553 for character position CHARPOS in STRING. */
1554
1555 static INLINE struct text_pos
1556 string_pos (int charpos, Lisp_Object string)
1557 {
1558 struct text_pos pos;
1559 xassert (STRINGP (string));
1560 xassert (charpos >= 0);
1561 SET_TEXT_POS (pos, charpos, string_char_to_byte (string, charpos));
1562 return pos;
1563 }
1564
1565
1566 /* Value is a text position, i.e. character and byte position, for
1567 character position CHARPOS in C string S. MULTIBYTE_P non-zero
1568 means recognize multibyte characters. */
1569
1570 static struct text_pos
1571 c_string_pos (int charpos, const unsigned char *s, int multibyte_p)
1572 {
1573 struct text_pos pos;
1574
1575 xassert (s != NULL);
1576 xassert (charpos >= 0);
1577
1578 if (multibyte_p)
1579 {
1580 int rest = strlen (s), len;
1581
1582 SET_TEXT_POS (pos, 0, 0);
1583 while (charpos--)
1584 {
1585 string_char_and_length (s, &len);
1586 s += len, rest -= len;
1587 xassert (rest >= 0);
1588 CHARPOS (pos) += 1;
1589 BYTEPOS (pos) += len;
1590 }
1591 }
1592 else
1593 SET_TEXT_POS (pos, charpos, charpos);
1594
1595 return pos;
1596 }
1597
1598
1599 /* Value is the number of characters in C string S. MULTIBYTE_P
1600 non-zero means recognize multibyte characters. */
1601
1602 static int
1603 number_of_chars (const unsigned char *s, int multibyte_p)
1604 {
1605 int nchars;
1606
1607 if (multibyte_p)
1608 {
1609 int rest = strlen (s), len;
1610 unsigned char *p = (unsigned char *) s;
1611
1612 for (nchars = 0; rest > 0; ++nchars)
1613 {
1614 string_char_and_length (p, &len);
1615 rest -= len, p += len;
1616 }
1617 }
1618 else
1619 nchars = strlen (s);
1620
1621 return nchars;
1622 }
1623
1624
1625 /* Compute byte position NEWPOS->bytepos corresponding to
1626 NEWPOS->charpos. POS is a known position in string STRING.
1627 NEWPOS->charpos must be >= POS.charpos. */
1628
1629 static void
1630 compute_string_pos (struct text_pos *newpos, struct text_pos pos, Lisp_Object string)
1631 {
1632 xassert (STRINGP (string));
1633 xassert (CHARPOS (*newpos) >= CHARPOS (pos));
1634
1635 if (STRING_MULTIBYTE (string))
1636 *newpos = string_pos_nchars_ahead (pos, string,
1637 CHARPOS (*newpos) - CHARPOS (pos));
1638 else
1639 BYTEPOS (*newpos) = CHARPOS (*newpos);
1640 }
1641
1642 /* EXPORT:
1643 Return an estimation of the pixel height of mode or header lines on
1644 frame F. FACE_ID specifies what line's height to estimate. */
1645
1646 int
1647 estimate_mode_line_height (struct frame *f, enum face_id face_id)
1648 {
1649 #ifdef HAVE_WINDOW_SYSTEM
1650 if (FRAME_WINDOW_P (f))
1651 {
1652 int height = FONT_HEIGHT (FRAME_FONT (f));
1653
1654 /* This function is called so early when Emacs starts that the face
1655 cache and mode line face are not yet initialized. */
1656 if (FRAME_FACE_CACHE (f))
1657 {
1658 struct face *face = FACE_FROM_ID (f, face_id);
1659 if (face)
1660 {
1661 if (face->font)
1662 height = FONT_HEIGHT (face->font);
1663 if (face->box_line_width > 0)
1664 height += 2 * face->box_line_width;
1665 }
1666 }
1667
1668 return height;
1669 }
1670 #endif
1671
1672 return 1;
1673 }
1674
1675 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
1676 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
1677 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
1678 not force the value into range. */
1679
1680 void
1681 pixel_to_glyph_coords (FRAME_PTR f, register int pix_x, register int pix_y,
1682 int *x, int *y, NativeRectangle *bounds, int noclip)
1683 {
1684
1685 #ifdef HAVE_WINDOW_SYSTEM
1686 if (FRAME_WINDOW_P (f))
1687 {
1688 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to round down
1689 even for negative values. */
1690 if (pix_x < 0)
1691 pix_x -= FRAME_COLUMN_WIDTH (f) - 1;
1692 if (pix_y < 0)
1693 pix_y -= FRAME_LINE_HEIGHT (f) - 1;
1694
1695 pix_x = FRAME_PIXEL_X_TO_COL (f, pix_x);
1696 pix_y = FRAME_PIXEL_Y_TO_LINE (f, pix_y);
1697
1698 if (bounds)
1699 STORE_NATIVE_RECT (*bounds,
1700 FRAME_COL_TO_PIXEL_X (f, pix_x),
1701 FRAME_LINE_TO_PIXEL_Y (f, pix_y),
1702 FRAME_COLUMN_WIDTH (f) - 1,
1703 FRAME_LINE_HEIGHT (f) - 1);
1704
1705 if (!noclip)
1706 {
1707 if (pix_x < 0)
1708 pix_x = 0;
1709 else if (pix_x > FRAME_TOTAL_COLS (f))
1710 pix_x = FRAME_TOTAL_COLS (f);
1711
1712 if (pix_y < 0)
1713 pix_y = 0;
1714 else if (pix_y > FRAME_LINES (f))
1715 pix_y = FRAME_LINES (f);
1716 }
1717 }
1718 #endif
1719
1720 *x = pix_x;
1721 *y = pix_y;
1722 }
1723
1724
1725 /* Given HPOS/VPOS in the current matrix of W, return corresponding
1726 frame-relative pixel positions in *FRAME_X and *FRAME_Y. If we
1727 can't tell the positions because W's display is not up to date,
1728 return 0. */
1729
1730 int
1731 glyph_to_pixel_coords (struct window *w, int hpos, int vpos,
1732 int *frame_x, int *frame_y)
1733 {
1734 #ifdef HAVE_WINDOW_SYSTEM
1735 if (FRAME_WINDOW_P (XFRAME (WINDOW_FRAME (w))))
1736 {
1737 int success_p;
1738
1739 xassert (hpos >= 0 && hpos < w->current_matrix->matrix_w);
1740 xassert (vpos >= 0 && vpos < w->current_matrix->matrix_h);
1741
1742 if (display_completed)
1743 {
1744 struct glyph_row *row = MATRIX_ROW (w->current_matrix, vpos);
1745 struct glyph *glyph = row->glyphs[TEXT_AREA];
1746 struct glyph *end = glyph + min (hpos, row->used[TEXT_AREA]);
1747
1748 hpos = row->x;
1749 vpos = row->y;
1750 while (glyph < end)
1751 {
1752 hpos += glyph->pixel_width;
1753 ++glyph;
1754 }
1755
1756 /* If first glyph is partially visible, its first visible position is still 0. */
1757 if (hpos < 0)
1758 hpos = 0;
1759
1760 success_p = 1;
1761 }
1762 else
1763 {
1764 hpos = vpos = 0;
1765 success_p = 0;
1766 }
1767
1768 *frame_x = WINDOW_TO_FRAME_PIXEL_X (w, hpos);
1769 *frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, vpos);
1770 return success_p;
1771 }
1772 #endif
1773
1774 *frame_x = hpos;
1775 *frame_y = vpos;
1776 return 1;
1777 }
1778
1779
1780 #ifdef HAVE_WINDOW_SYSTEM
1781
1782 /* Find the glyph under window-relative coordinates X/Y in window W.
1783 Consider only glyphs from buffer text, i.e. no glyphs from overlay
1784 strings. Return in *HPOS and *VPOS the row and column number of
1785 the glyph found. Return in *AREA the glyph area containing X.
1786 Value is a pointer to the glyph found or null if X/Y is not on
1787 text, or we can't tell because W's current matrix is not up to
1788 date. */
1789
1790 static
1791 struct glyph *
1792 x_y_to_hpos_vpos (struct window *w, int x, int y, int *hpos, int *vpos,
1793 int *dx, int *dy, int *area)
1794 {
1795 struct glyph *glyph, *end;
1796 struct glyph_row *row = NULL;
1797 int x0, i;
1798
1799 /* Find row containing Y. Give up if some row is not enabled. */
1800 for (i = 0; i < w->current_matrix->nrows; ++i)
1801 {
1802 row = MATRIX_ROW (w->current_matrix, i);
1803 if (!row->enabled_p)
1804 return NULL;
1805 if (y >= row->y && y < MATRIX_ROW_BOTTOM_Y (row))
1806 break;
1807 }
1808
1809 *vpos = i;
1810 *hpos = 0;
1811
1812 /* Give up if Y is not in the window. */
1813 if (i == w->current_matrix->nrows)
1814 return NULL;
1815
1816 /* Get the glyph area containing X. */
1817 if (w->pseudo_window_p)
1818 {
1819 *area = TEXT_AREA;
1820 x0 = 0;
1821 }
1822 else
1823 {
1824 if (x < window_box_left_offset (w, TEXT_AREA))
1825 {
1826 *area = LEFT_MARGIN_AREA;
1827 x0 = window_box_left_offset (w, LEFT_MARGIN_AREA);
1828 }
1829 else if (x < window_box_right_offset (w, TEXT_AREA))
1830 {
1831 *area = TEXT_AREA;
1832 x0 = window_box_left_offset (w, TEXT_AREA) + min (row->x, 0);
1833 }
1834 else
1835 {
1836 *area = RIGHT_MARGIN_AREA;
1837 x0 = window_box_left_offset (w, RIGHT_MARGIN_AREA);
1838 }
1839 }
1840
1841 /* Find glyph containing X. */
1842 glyph = row->glyphs[*area];
1843 end = glyph + row->used[*area];
1844 x -= x0;
1845 while (glyph < end && x >= glyph->pixel_width)
1846 {
1847 x -= glyph->pixel_width;
1848 ++glyph;
1849 }
1850
1851 if (glyph == end)
1852 return NULL;
1853
1854 if (dx)
1855 {
1856 *dx = x;
1857 *dy = y - (row->y + row->ascent - glyph->ascent);
1858 }
1859
1860 *hpos = glyph - row->glyphs[*area];
1861 return glyph;
1862 }
1863
1864
1865 /* EXPORT:
1866 Convert frame-relative x/y to coordinates relative to window W.
1867 Takes pseudo-windows into account. */
1868
1869 void
1870 frame_to_window_pixel_xy (struct window *w, int *x, int *y)
1871 {
1872 if (w->pseudo_window_p)
1873 {
1874 /* A pseudo-window is always full-width, and starts at the
1875 left edge of the frame, plus a frame border. */
1876 struct frame *f = XFRAME (w->frame);
1877 *x -= FRAME_INTERNAL_BORDER_WIDTH (f);
1878 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1879 }
1880 else
1881 {
1882 *x -= WINDOW_LEFT_EDGE_X (w);
1883 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1884 }
1885 }
1886
1887 /* EXPORT:
1888 Return in RECTS[] at most N clipping rectangles for glyph string S.
1889 Return the number of stored rectangles. */
1890
1891 int
1892 get_glyph_string_clip_rects (struct glyph_string *s, NativeRectangle *rects, int n)
1893 {
1894 XRectangle r;
1895
1896 if (n <= 0)
1897 return 0;
1898
1899 if (s->row->full_width_p)
1900 {
1901 /* Draw full-width. X coordinates are relative to S->w->left_col. */
1902 r.x = WINDOW_LEFT_EDGE_X (s->w);
1903 r.width = WINDOW_TOTAL_WIDTH (s->w);
1904
1905 /* Unless displaying a mode or menu bar line, which are always
1906 fully visible, clip to the visible part of the row. */
1907 if (s->w->pseudo_window_p)
1908 r.height = s->row->visible_height;
1909 else
1910 r.height = s->height;
1911 }
1912 else
1913 {
1914 /* This is a text line that may be partially visible. */
1915 r.x = window_box_left (s->w, s->area);
1916 r.width = window_box_width (s->w, s->area);
1917 r.height = s->row->visible_height;
1918 }
1919
1920 if (s->clip_head)
1921 if (r.x < s->clip_head->x)
1922 {
1923 if (r.width >= s->clip_head->x - r.x)
1924 r.width -= s->clip_head->x - r.x;
1925 else
1926 r.width = 0;
1927 r.x = s->clip_head->x;
1928 }
1929 if (s->clip_tail)
1930 if (r.x + r.width > s->clip_tail->x + s->clip_tail->background_width)
1931 {
1932 if (s->clip_tail->x + s->clip_tail->background_width >= r.x)
1933 r.width = s->clip_tail->x + s->clip_tail->background_width - r.x;
1934 else
1935 r.width = 0;
1936 }
1937
1938 /* If S draws overlapping rows, it's sufficient to use the top and
1939 bottom of the window for clipping because this glyph string
1940 intentionally draws over other lines. */
1941 if (s->for_overlaps)
1942 {
1943 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
1944 r.height = window_text_bottom_y (s->w) - r.y;
1945
1946 /* Alas, the above simple strategy does not work for the
1947 environments with anti-aliased text: if the same text is
1948 drawn onto the same place multiple times, it gets thicker.
1949 If the overlap we are processing is for the erased cursor, we
1950 take the intersection with the rectagle of the cursor. */
1951 if (s->for_overlaps & OVERLAPS_ERASED_CURSOR)
1952 {
1953 XRectangle rc, r_save = r;
1954
1955 rc.x = WINDOW_TEXT_TO_FRAME_PIXEL_X (s->w, s->w->phys_cursor.x);
1956 rc.y = s->w->phys_cursor.y;
1957 rc.width = s->w->phys_cursor_width;
1958 rc.height = s->w->phys_cursor_height;
1959
1960 x_intersect_rectangles (&r_save, &rc, &r);
1961 }
1962 }
1963 else
1964 {
1965 /* Don't use S->y for clipping because it doesn't take partially
1966 visible lines into account. For example, it can be negative for
1967 partially visible lines at the top of a window. */
1968 if (!s->row->full_width_p
1969 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s->w, s->row))
1970 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
1971 else
1972 r.y = max (0, s->row->y);
1973 }
1974
1975 r.y = WINDOW_TO_FRAME_PIXEL_Y (s->w, r.y);
1976
1977 /* If drawing the cursor, don't let glyph draw outside its
1978 advertised boundaries. Cleartype does this under some circumstances. */
1979 if (s->hl == DRAW_CURSOR)
1980 {
1981 struct glyph *glyph = s->first_glyph;
1982 int height, max_y;
1983
1984 if (s->x > r.x)
1985 {
1986 r.width -= s->x - r.x;
1987 r.x = s->x;
1988 }
1989 r.width = min (r.width, glyph->pixel_width);
1990
1991 /* If r.y is below window bottom, ensure that we still see a cursor. */
1992 height = min (glyph->ascent + glyph->descent,
1993 min (FRAME_LINE_HEIGHT (s->f), s->row->visible_height));
1994 max_y = window_text_bottom_y (s->w) - height;
1995 max_y = WINDOW_TO_FRAME_PIXEL_Y (s->w, max_y);
1996 if (s->ybase - glyph->ascent > max_y)
1997 {
1998 r.y = max_y;
1999 r.height = height;
2000 }
2001 else
2002 {
2003 /* Don't draw cursor glyph taller than our actual glyph. */
2004 height = max (FRAME_LINE_HEIGHT (s->f), glyph->ascent + glyph->descent);
2005 if (height < r.height)
2006 {
2007 max_y = r.y + r.height;
2008 r.y = min (max_y, max (r.y, s->ybase + glyph->descent - height));
2009 r.height = min (max_y - r.y, height);
2010 }
2011 }
2012 }
2013
2014 if (s->row->clip)
2015 {
2016 XRectangle r_save = r;
2017
2018 if (! x_intersect_rectangles (&r_save, s->row->clip, &r))
2019 r.width = 0;
2020 }
2021
2022 if ((s->for_overlaps & OVERLAPS_BOTH) == 0
2023 || ((s->for_overlaps & OVERLAPS_BOTH) == OVERLAPS_BOTH && n == 1))
2024 {
2025 #ifdef CONVERT_FROM_XRECT
2026 CONVERT_FROM_XRECT (r, *rects);
2027 #else
2028 *rects = r;
2029 #endif
2030 return 1;
2031 }
2032 else
2033 {
2034 /* If we are processing overlapping and allowed to return
2035 multiple clipping rectangles, we exclude the row of the glyph
2036 string from the clipping rectangle. This is to avoid drawing
2037 the same text on the environment with anti-aliasing. */
2038 #ifdef CONVERT_FROM_XRECT
2039 XRectangle rs[2];
2040 #else
2041 XRectangle *rs = rects;
2042 #endif
2043 int i = 0, row_y = WINDOW_TO_FRAME_PIXEL_Y (s->w, s->row->y);
2044
2045 if (s->for_overlaps & OVERLAPS_PRED)
2046 {
2047 rs[i] = r;
2048 if (r.y + r.height > row_y)
2049 {
2050 if (r.y < row_y)
2051 rs[i].height = row_y - r.y;
2052 else
2053 rs[i].height = 0;
2054 }
2055 i++;
2056 }
2057 if (s->for_overlaps & OVERLAPS_SUCC)
2058 {
2059 rs[i] = r;
2060 if (r.y < row_y + s->row->visible_height)
2061 {
2062 if (r.y + r.height > row_y + s->row->visible_height)
2063 {
2064 rs[i].y = row_y + s->row->visible_height;
2065 rs[i].height = r.y + r.height - rs[i].y;
2066 }
2067 else
2068 rs[i].height = 0;
2069 }
2070 i++;
2071 }
2072
2073 n = i;
2074 #ifdef CONVERT_FROM_XRECT
2075 for (i = 0; i < n; i++)
2076 CONVERT_FROM_XRECT (rs[i], rects[i]);
2077 #endif
2078 return n;
2079 }
2080 }
2081
2082 /* EXPORT:
2083 Return in *NR the clipping rectangle for glyph string S. */
2084
2085 void
2086 get_glyph_string_clip_rect (struct glyph_string *s, NativeRectangle *nr)
2087 {
2088 get_glyph_string_clip_rects (s, nr, 1);
2089 }
2090
2091
2092 /* EXPORT:
2093 Return the position and height of the phys cursor in window W.
2094 Set w->phys_cursor_width to width of phys cursor.
2095 */
2096
2097 void
2098 get_phys_cursor_geometry (struct window *w, struct glyph_row *row,
2099 struct glyph *glyph, int *xp, int *yp, int *heightp)
2100 {
2101 struct frame *f = XFRAME (WINDOW_FRAME (w));
2102 int x, y, wd, h, h0, y0;
2103
2104 /* Compute the width of the rectangle to draw. If on a stretch
2105 glyph, and `x-stretch-block-cursor' is nil, don't draw a
2106 rectangle as wide as the glyph, but use a canonical character
2107 width instead. */
2108 wd = glyph->pixel_width - 1;
2109 #if defined(HAVE_NTGUI) || defined(HAVE_NS)
2110 wd++; /* Why? */
2111 #endif
2112
2113 x = w->phys_cursor.x;
2114 if (x < 0)
2115 {
2116 wd += x;
2117 x = 0;
2118 }
2119
2120 if (glyph->type == STRETCH_GLYPH
2121 && !x_stretch_cursor_p)
2122 wd = min (FRAME_COLUMN_WIDTH (f), wd);
2123 w->phys_cursor_width = wd;
2124
2125 y = w->phys_cursor.y + row->ascent - glyph->ascent;
2126
2127 /* If y is below window bottom, ensure that we still see a cursor. */
2128 h0 = min (FRAME_LINE_HEIGHT (f), row->visible_height);
2129
2130 h = max (h0, glyph->ascent + glyph->descent);
2131 h0 = min (h0, glyph->ascent + glyph->descent);
2132
2133 y0 = WINDOW_HEADER_LINE_HEIGHT (w);
2134 if (y < y0)
2135 {
2136 h = max (h - (y0 - y) + 1, h0);
2137 y = y0 - 1;
2138 }
2139 else
2140 {
2141 y0 = window_text_bottom_y (w) - h0;
2142 if (y > y0)
2143 {
2144 h += y - y0;
2145 y = y0;
2146 }
2147 }
2148
2149 *xp = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, x);
2150 *yp = WINDOW_TO_FRAME_PIXEL_Y (w, y);
2151 *heightp = h;
2152 }
2153
2154 /*
2155 * Remember which glyph the mouse is over.
2156 */
2157
2158 void
2159 remember_mouse_glyph (struct frame *f, int gx, int gy, NativeRectangle *rect)
2160 {
2161 Lisp_Object window;
2162 struct window *w;
2163 struct glyph_row *r, *gr, *end_row;
2164 enum window_part part;
2165 enum glyph_row_area area;
2166 int x, y, width, height;
2167
2168 /* Try to determine frame pixel position and size of the glyph under
2169 frame pixel coordinates X/Y on frame F. */
2170
2171 if (!f->glyphs_initialized_p
2172 || (window = window_from_coordinates (f, gx, gy, &part, &x, &y, 0),
2173 NILP (window)))
2174 {
2175 width = FRAME_SMALLEST_CHAR_WIDTH (f);
2176 height = FRAME_SMALLEST_FONT_HEIGHT (f);
2177 goto virtual_glyph;
2178 }
2179
2180 w = XWINDOW (window);
2181 width = WINDOW_FRAME_COLUMN_WIDTH (w);
2182 height = WINDOW_FRAME_LINE_HEIGHT (w);
2183
2184 r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
2185 end_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
2186
2187 if (w->pseudo_window_p)
2188 {
2189 area = TEXT_AREA;
2190 part = ON_MODE_LINE; /* Don't adjust margin. */
2191 goto text_glyph;
2192 }
2193
2194 switch (part)
2195 {
2196 case ON_LEFT_MARGIN:
2197 area = LEFT_MARGIN_AREA;
2198 goto text_glyph;
2199
2200 case ON_RIGHT_MARGIN:
2201 area = RIGHT_MARGIN_AREA;
2202 goto text_glyph;
2203
2204 case ON_HEADER_LINE:
2205 case ON_MODE_LINE:
2206 gr = (part == ON_HEADER_LINE
2207 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
2208 : MATRIX_MODE_LINE_ROW (w->current_matrix));
2209 gy = gr->y;
2210 area = TEXT_AREA;
2211 goto text_glyph_row_found;
2212
2213 case ON_TEXT:
2214 area = TEXT_AREA;
2215
2216 text_glyph:
2217 gr = 0; gy = 0;
2218 for (; r <= end_row && r->enabled_p; ++r)
2219 if (r->y + r->height > y)
2220 {
2221 gr = r; gy = r->y;
2222 break;
2223 }
2224
2225 text_glyph_row_found:
2226 if (gr && gy <= y)
2227 {
2228 struct glyph *g = gr->glyphs[area];
2229 struct glyph *end = g + gr->used[area];
2230
2231 height = gr->height;
2232 for (gx = gr->x; g < end; gx += g->pixel_width, ++g)
2233 if (gx + g->pixel_width > x)
2234 break;
2235
2236 if (g < end)
2237 {
2238 if (g->type == IMAGE_GLYPH)
2239 {
2240 /* Don't remember when mouse is over image, as
2241 image may have hot-spots. */
2242 STORE_NATIVE_RECT (*rect, 0, 0, 0, 0);
2243 return;
2244 }
2245 width = g->pixel_width;
2246 }
2247 else
2248 {
2249 /* Use nominal char spacing at end of line. */
2250 x -= gx;
2251 gx += (x / width) * width;
2252 }
2253
2254 if (part != ON_MODE_LINE && part != ON_HEADER_LINE)
2255 gx += window_box_left_offset (w, area);
2256 }
2257 else
2258 {
2259 /* Use nominal line height at end of window. */
2260 gx = (x / width) * width;
2261 y -= gy;
2262 gy += (y / height) * height;
2263 }
2264 break;
2265
2266 case ON_LEFT_FRINGE:
2267 gx = (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2268 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w)
2269 : window_box_right_offset (w, LEFT_MARGIN_AREA));
2270 width = WINDOW_LEFT_FRINGE_WIDTH (w);
2271 goto row_glyph;
2272
2273 case ON_RIGHT_FRINGE:
2274 gx = (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2275 ? window_box_right_offset (w, RIGHT_MARGIN_AREA)
2276 : window_box_right_offset (w, TEXT_AREA));
2277 width = WINDOW_RIGHT_FRINGE_WIDTH (w);
2278 goto row_glyph;
2279
2280 case ON_SCROLL_BAR:
2281 gx = (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w)
2282 ? 0
2283 : (window_box_right_offset (w, RIGHT_MARGIN_AREA)
2284 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2285 ? WINDOW_RIGHT_FRINGE_WIDTH (w)
2286 : 0)));
2287 width = WINDOW_SCROLL_BAR_AREA_WIDTH (w);
2288
2289 row_glyph:
2290 gr = 0, gy = 0;
2291 for (; r <= end_row && r->enabled_p; ++r)
2292 if (r->y + r->height > y)
2293 {
2294 gr = r; gy = r->y;
2295 break;
2296 }
2297
2298 if (gr && gy <= y)
2299 height = gr->height;
2300 else
2301 {
2302 /* Use nominal line height at end of window. */
2303 y -= gy;
2304 gy += (y / height) * height;
2305 }
2306 break;
2307
2308 default:
2309 ;
2310 virtual_glyph:
2311 /* If there is no glyph under the mouse, then we divide the screen
2312 into a grid of the smallest glyph in the frame, and use that
2313 as our "glyph". */
2314
2315 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to
2316 round down even for negative values. */
2317 if (gx < 0)
2318 gx -= width - 1;
2319 if (gy < 0)
2320 gy -= height - 1;
2321
2322 gx = (gx / width) * width;
2323 gy = (gy / height) * height;
2324
2325 goto store_rect;
2326 }
2327
2328 gx += WINDOW_LEFT_EDGE_X (w);
2329 gy += WINDOW_TOP_EDGE_Y (w);
2330
2331 store_rect:
2332 STORE_NATIVE_RECT (*rect, gx, gy, width, height);
2333
2334 /* Visible feedback for debugging. */
2335 #if 0
2336 #if HAVE_X_WINDOWS
2337 XDrawRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
2338 f->output_data.x->normal_gc,
2339 gx, gy, width, height);
2340 #endif
2341 #endif
2342 }
2343
2344
2345 #endif /* HAVE_WINDOW_SYSTEM */
2346
2347 \f
2348 /***********************************************************************
2349 Lisp form evaluation
2350 ***********************************************************************/
2351
2352 /* Error handler for safe_eval and safe_call. */
2353
2354 static Lisp_Object
2355 safe_eval_handler (Lisp_Object arg)
2356 {
2357 add_to_log ("Error during redisplay: %s", arg, Qnil);
2358 return Qnil;
2359 }
2360
2361
2362 /* Evaluate SEXPR and return the result, or nil if something went
2363 wrong. Prevent redisplay during the evaluation. */
2364
2365 /* Call function ARGS[0] with arguments ARGS[1] to ARGS[NARGS - 1].
2366 Return the result, or nil if something went wrong. Prevent
2367 redisplay during the evaluation. */
2368
2369 Lisp_Object
2370 safe_call (int nargs, Lisp_Object *args)
2371 {
2372 Lisp_Object val;
2373
2374 if (inhibit_eval_during_redisplay)
2375 val = Qnil;
2376 else
2377 {
2378 int count = SPECPDL_INDEX ();
2379 struct gcpro gcpro1;
2380
2381 GCPRO1 (args[0]);
2382 gcpro1.nvars = nargs;
2383 specbind (Qinhibit_redisplay, Qt);
2384 /* Use Qt to ensure debugger does not run,
2385 so there is no possibility of wanting to redisplay. */
2386 val = internal_condition_case_n (Ffuncall, nargs, args, Qt,
2387 safe_eval_handler);
2388 UNGCPRO;
2389 val = unbind_to (count, val);
2390 }
2391
2392 return val;
2393 }
2394
2395
2396 /* Call function FN with one argument ARG.
2397 Return the result, or nil if something went wrong. */
2398
2399 Lisp_Object
2400 safe_call1 (Lisp_Object fn, Lisp_Object arg)
2401 {
2402 Lisp_Object args[2];
2403 args[0] = fn;
2404 args[1] = arg;
2405 return safe_call (2, args);
2406 }
2407
2408 static Lisp_Object Qeval;
2409
2410 Lisp_Object
2411 safe_eval (Lisp_Object sexpr)
2412 {
2413 return safe_call1 (Qeval, sexpr);
2414 }
2415
2416 /* Call function FN with one argument ARG.
2417 Return the result, or nil if something went wrong. */
2418
2419 Lisp_Object
2420 safe_call2 (Lisp_Object fn, Lisp_Object arg1, Lisp_Object arg2)
2421 {
2422 Lisp_Object args[3];
2423 args[0] = fn;
2424 args[1] = arg1;
2425 args[2] = arg2;
2426 return safe_call (3, args);
2427 }
2428
2429
2430 \f
2431 /***********************************************************************
2432 Debugging
2433 ***********************************************************************/
2434
2435 #if 0
2436
2437 /* Define CHECK_IT to perform sanity checks on iterators.
2438 This is for debugging. It is too slow to do unconditionally. */
2439
2440 static void
2441 check_it (it)
2442 struct it *it;
2443 {
2444 if (it->method == GET_FROM_STRING)
2445 {
2446 xassert (STRINGP (it->string));
2447 xassert (IT_STRING_CHARPOS (*it) >= 0);
2448 }
2449 else
2450 {
2451 xassert (IT_STRING_CHARPOS (*it) < 0);
2452 if (it->method == GET_FROM_BUFFER)
2453 {
2454 /* Check that character and byte positions agree. */
2455 xassert (IT_CHARPOS (*it) == BYTE_TO_CHAR (IT_BYTEPOS (*it)));
2456 }
2457 }
2458
2459 if (it->dpvec)
2460 xassert (it->current.dpvec_index >= 0);
2461 else
2462 xassert (it->current.dpvec_index < 0);
2463 }
2464
2465 #define CHECK_IT(IT) check_it ((IT))
2466
2467 #else /* not 0 */
2468
2469 #define CHECK_IT(IT) (void) 0
2470
2471 #endif /* not 0 */
2472
2473
2474 #if GLYPH_DEBUG
2475
2476 /* Check that the window end of window W is what we expect it
2477 to be---the last row in the current matrix displaying text. */
2478
2479 static void
2480 check_window_end (w)
2481 struct window *w;
2482 {
2483 if (!MINI_WINDOW_P (w)
2484 && !NILP (w->window_end_valid))
2485 {
2486 struct glyph_row *row;
2487 xassert ((row = MATRIX_ROW (w->current_matrix,
2488 XFASTINT (w->window_end_vpos)),
2489 !row->enabled_p
2490 || MATRIX_ROW_DISPLAYS_TEXT_P (row)
2491 || MATRIX_ROW_VPOS (row, w->current_matrix) == 0));
2492 }
2493 }
2494
2495 #define CHECK_WINDOW_END(W) check_window_end ((W))
2496
2497 #else /* not GLYPH_DEBUG */
2498
2499 #define CHECK_WINDOW_END(W) (void) 0
2500
2501 #endif /* not GLYPH_DEBUG */
2502
2503
2504 \f
2505 /***********************************************************************
2506 Iterator initialization
2507 ***********************************************************************/
2508
2509 /* Initialize IT for displaying current_buffer in window W, starting
2510 at character position CHARPOS. CHARPOS < 0 means that no buffer
2511 position is specified which is useful when the iterator is assigned
2512 a position later. BYTEPOS is the byte position corresponding to
2513 CHARPOS. BYTEPOS < 0 means compute it from CHARPOS.
2514
2515 If ROW is not null, calls to produce_glyphs with IT as parameter
2516 will produce glyphs in that row.
2517
2518 BASE_FACE_ID is the id of a base face to use. It must be one of
2519 DEFAULT_FACE_ID for normal text, MODE_LINE_FACE_ID,
2520 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID for displaying
2521 mode lines, or TOOL_BAR_FACE_ID for displaying the tool-bar.
2522
2523 If ROW is null and BASE_FACE_ID is equal to MODE_LINE_FACE_ID,
2524 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID, the iterator
2525 will be initialized to use the corresponding mode line glyph row of
2526 the desired matrix of W. */
2527
2528 void
2529 init_iterator (struct it *it, struct window *w,
2530 EMACS_INT charpos, EMACS_INT bytepos,
2531 struct glyph_row *row, enum face_id base_face_id)
2532 {
2533 int highlight_region_p;
2534 enum face_id remapped_base_face_id = base_face_id;
2535
2536 /* Some precondition checks. */
2537 xassert (w != NULL && it != NULL);
2538 xassert (charpos < 0 || (charpos >= BUF_BEG (current_buffer)
2539 && charpos <= ZV));
2540
2541 /* If face attributes have been changed since the last redisplay,
2542 free realized faces now because they depend on face definitions
2543 that might have changed. Don't free faces while there might be
2544 desired matrices pending which reference these faces. */
2545 if (face_change_count && !inhibit_free_realized_faces)
2546 {
2547 face_change_count = 0;
2548 free_all_realized_faces (Qnil);
2549 }
2550
2551 /* Perhaps remap BASE_FACE_ID to a user-specified alternative. */
2552 if (! NILP (Vface_remapping_alist))
2553 remapped_base_face_id = lookup_basic_face (XFRAME (w->frame), base_face_id);
2554
2555 /* Use one of the mode line rows of W's desired matrix if
2556 appropriate. */
2557 if (row == NULL)
2558 {
2559 if (base_face_id == MODE_LINE_FACE_ID
2560 || base_face_id == MODE_LINE_INACTIVE_FACE_ID)
2561 row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
2562 else if (base_face_id == HEADER_LINE_FACE_ID)
2563 row = MATRIX_HEADER_LINE_ROW (w->desired_matrix);
2564 }
2565
2566 /* Clear IT. */
2567 memset (it, 0, sizeof *it);
2568 it->current.overlay_string_index = -1;
2569 it->current.dpvec_index = -1;
2570 it->base_face_id = remapped_base_face_id;
2571 it->string = Qnil;
2572 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
2573
2574 /* The window in which we iterate over current_buffer: */
2575 XSETWINDOW (it->window, w);
2576 it->w = w;
2577 it->f = XFRAME (w->frame);
2578
2579 it->cmp_it.id = -1;
2580
2581 /* Extra space between lines (on window systems only). */
2582 if (base_face_id == DEFAULT_FACE_ID
2583 && FRAME_WINDOW_P (it->f))
2584 {
2585 if (NATNUMP (current_buffer->extra_line_spacing))
2586 it->extra_line_spacing = XFASTINT (current_buffer->extra_line_spacing);
2587 else if (FLOATP (current_buffer->extra_line_spacing))
2588 it->extra_line_spacing = (XFLOAT_DATA (current_buffer->extra_line_spacing)
2589 * FRAME_LINE_HEIGHT (it->f));
2590 else if (it->f->extra_line_spacing > 0)
2591 it->extra_line_spacing = it->f->extra_line_spacing;
2592 it->max_extra_line_spacing = 0;
2593 }
2594
2595 /* If realized faces have been removed, e.g. because of face
2596 attribute changes of named faces, recompute them. When running
2597 in batch mode, the face cache of the initial frame is null. If
2598 we happen to get called, make a dummy face cache. */
2599 if (FRAME_FACE_CACHE (it->f) == NULL)
2600 init_frame_faces (it->f);
2601 if (FRAME_FACE_CACHE (it->f)->used == 0)
2602 recompute_basic_faces (it->f);
2603
2604 /* Current value of the `slice', `space-width', and 'height' properties. */
2605 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
2606 it->space_width = Qnil;
2607 it->font_height = Qnil;
2608 it->override_ascent = -1;
2609
2610 /* Are control characters displayed as `^C'? */
2611 it->ctl_arrow_p = !NILP (current_buffer->ctl_arrow);
2612
2613 /* -1 means everything between a CR and the following line end
2614 is invisible. >0 means lines indented more than this value are
2615 invisible. */
2616 it->selective = (INTEGERP (current_buffer->selective_display)
2617 ? XFASTINT (current_buffer->selective_display)
2618 : (!NILP (current_buffer->selective_display)
2619 ? -1 : 0));
2620 it->selective_display_ellipsis_p
2621 = !NILP (current_buffer->selective_display_ellipses);
2622
2623 /* Display table to use. */
2624 it->dp = window_display_table (w);
2625
2626 /* Are multibyte characters enabled in current_buffer? */
2627 it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
2628
2629 /* Do we need to reorder bidirectional text? Not if this is a
2630 unibyte buffer: by definition, none of the single-byte characters
2631 are strong R2L, so no reordering is needed. And bidi.c doesn't
2632 support unibyte buffers anyway. */
2633 it->bidi_p
2634 = !NILP (current_buffer->bidi_display_reordering) && it->multibyte_p;
2635
2636 /* Non-zero if we should highlight the region. */
2637 highlight_region_p
2638 = (!NILP (Vtransient_mark_mode)
2639 && !NILP (current_buffer->mark_active)
2640 && XMARKER (current_buffer->mark)->buffer != 0);
2641
2642 /* Set IT->region_beg_charpos and IT->region_end_charpos to the
2643 start and end of a visible region in window IT->w. Set both to
2644 -1 to indicate no region. */
2645 if (highlight_region_p
2646 /* Maybe highlight only in selected window. */
2647 && (/* Either show region everywhere. */
2648 highlight_nonselected_windows
2649 /* Or show region in the selected window. */
2650 || w == XWINDOW (selected_window)
2651 /* Or show the region if we are in the mini-buffer and W is
2652 the window the mini-buffer refers to. */
2653 || (MINI_WINDOW_P (XWINDOW (selected_window))
2654 && WINDOWP (minibuf_selected_window)
2655 && w == XWINDOW (minibuf_selected_window))))
2656 {
2657 int charpos = marker_position (current_buffer->mark);
2658 it->region_beg_charpos = min (PT, charpos);
2659 it->region_end_charpos = max (PT, charpos);
2660 }
2661 else
2662 it->region_beg_charpos = it->region_end_charpos = -1;
2663
2664 /* Get the position at which the redisplay_end_trigger hook should
2665 be run, if it is to be run at all. */
2666 if (MARKERP (w->redisplay_end_trigger)
2667 && XMARKER (w->redisplay_end_trigger)->buffer != 0)
2668 it->redisplay_end_trigger_charpos
2669 = marker_position (w->redisplay_end_trigger);
2670 else if (INTEGERP (w->redisplay_end_trigger))
2671 it->redisplay_end_trigger_charpos = XINT (w->redisplay_end_trigger);
2672
2673 /* Correct bogus values of tab_width. */
2674 it->tab_width = XINT (current_buffer->tab_width);
2675 if (it->tab_width <= 0 || it->tab_width > 1000)
2676 it->tab_width = 8;
2677
2678 /* Are lines in the display truncated? */
2679 if (base_face_id != DEFAULT_FACE_ID
2680 || XINT (it->w->hscroll)
2681 || (! WINDOW_FULL_WIDTH_P (it->w)
2682 && ((!NILP (Vtruncate_partial_width_windows)
2683 && !INTEGERP (Vtruncate_partial_width_windows))
2684 || (INTEGERP (Vtruncate_partial_width_windows)
2685 && (WINDOW_TOTAL_COLS (it->w)
2686 < XINT (Vtruncate_partial_width_windows))))))
2687 it->line_wrap = TRUNCATE;
2688 else if (NILP (current_buffer->truncate_lines))
2689 it->line_wrap = NILP (current_buffer->word_wrap)
2690 ? WINDOW_WRAP : WORD_WRAP;
2691 else
2692 it->line_wrap = TRUNCATE;
2693
2694 /* Get dimensions of truncation and continuation glyphs. These are
2695 displayed as fringe bitmaps under X, so we don't need them for such
2696 frames. */
2697 if (!FRAME_WINDOW_P (it->f))
2698 {
2699 if (it->line_wrap == TRUNCATE)
2700 {
2701 /* We will need the truncation glyph. */
2702 xassert (it->glyph_row == NULL);
2703 produce_special_glyphs (it, IT_TRUNCATION);
2704 it->truncation_pixel_width = it->pixel_width;
2705 }
2706 else
2707 {
2708 /* We will need the continuation glyph. */
2709 xassert (it->glyph_row == NULL);
2710 produce_special_glyphs (it, IT_CONTINUATION);
2711 it->continuation_pixel_width = it->pixel_width;
2712 }
2713
2714 /* Reset these values to zero because the produce_special_glyphs
2715 above has changed them. */
2716 it->pixel_width = it->ascent = it->descent = 0;
2717 it->phys_ascent = it->phys_descent = 0;
2718 }
2719
2720 /* Set this after getting the dimensions of truncation and
2721 continuation glyphs, so that we don't produce glyphs when calling
2722 produce_special_glyphs, above. */
2723 it->glyph_row = row;
2724 it->area = TEXT_AREA;
2725
2726 /* Forget any previous info about this row being reversed. */
2727 if (it->glyph_row)
2728 it->glyph_row->reversed_p = 0;
2729
2730 /* Get the dimensions of the display area. The display area
2731 consists of the visible window area plus a horizontally scrolled
2732 part to the left of the window. All x-values are relative to the
2733 start of this total display area. */
2734 if (base_face_id != DEFAULT_FACE_ID)
2735 {
2736 /* Mode lines, menu bar in terminal frames. */
2737 it->first_visible_x = 0;
2738 it->last_visible_x = WINDOW_TOTAL_WIDTH (w);
2739 }
2740 else
2741 {
2742 it->first_visible_x
2743 = XFASTINT (it->w->hscroll) * FRAME_COLUMN_WIDTH (it->f);
2744 it->last_visible_x = (it->first_visible_x
2745 + window_box_width (w, TEXT_AREA));
2746
2747 /* If we truncate lines, leave room for the truncator glyph(s) at
2748 the right margin. Otherwise, leave room for the continuation
2749 glyph(s). Truncation and continuation glyphs are not inserted
2750 for window-based redisplay. */
2751 if (!FRAME_WINDOW_P (it->f))
2752 {
2753 if (it->line_wrap == TRUNCATE)
2754 it->last_visible_x -= it->truncation_pixel_width;
2755 else
2756 it->last_visible_x -= it->continuation_pixel_width;
2757 }
2758
2759 it->header_line_p = WINDOW_WANTS_HEADER_LINE_P (w);
2760 it->current_y = WINDOW_HEADER_LINE_HEIGHT (w) + w->vscroll;
2761 }
2762
2763 /* Leave room for a border glyph. */
2764 if (!FRAME_WINDOW_P (it->f)
2765 && !WINDOW_RIGHTMOST_P (it->w))
2766 it->last_visible_x -= 1;
2767
2768 it->last_visible_y = window_text_bottom_y (w);
2769
2770 /* For mode lines and alike, arrange for the first glyph having a
2771 left box line if the face specifies a box. */
2772 if (base_face_id != DEFAULT_FACE_ID)
2773 {
2774 struct face *face;
2775
2776 it->face_id = remapped_base_face_id;
2777
2778 /* If we have a boxed mode line, make the first character appear
2779 with a left box line. */
2780 face = FACE_FROM_ID (it->f, remapped_base_face_id);
2781 if (face->box != FACE_NO_BOX)
2782 it->start_of_box_run_p = 1;
2783 }
2784
2785 /* If we are to reorder bidirectional text, init the bidi
2786 iterator. */
2787 if (it->bidi_p)
2788 {
2789 /* Note the paragraph direction that this buffer wants to
2790 use. */
2791 if (EQ (current_buffer->bidi_paragraph_direction, Qleft_to_right))
2792 it->paragraph_embedding = L2R;
2793 else if (EQ (current_buffer->bidi_paragraph_direction, Qright_to_left))
2794 it->paragraph_embedding = R2L;
2795 else
2796 it->paragraph_embedding = NEUTRAL_DIR;
2797 bidi_init_it (charpos, bytepos, &it->bidi_it);
2798 }
2799
2800 /* If a buffer position was specified, set the iterator there,
2801 getting overlays and face properties from that position. */
2802 if (charpos >= BUF_BEG (current_buffer))
2803 {
2804 it->end_charpos = ZV;
2805 it->face_id = -1;
2806 IT_CHARPOS (*it) = charpos;
2807
2808 /* Compute byte position if not specified. */
2809 if (bytepos < charpos)
2810 IT_BYTEPOS (*it) = CHAR_TO_BYTE (charpos);
2811 else
2812 IT_BYTEPOS (*it) = bytepos;
2813
2814 it->start = it->current;
2815
2816 /* Compute faces etc. */
2817 reseat (it, it->current.pos, 1);
2818 }
2819
2820 CHECK_IT (it);
2821 }
2822
2823
2824 /* Initialize IT for the display of window W with window start POS. */
2825
2826 void
2827 start_display (struct it *it, struct window *w, struct text_pos pos)
2828 {
2829 struct glyph_row *row;
2830 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
2831
2832 row = w->desired_matrix->rows + first_vpos;
2833 init_iterator (it, w, CHARPOS (pos), BYTEPOS (pos), row, DEFAULT_FACE_ID);
2834 it->first_vpos = first_vpos;
2835
2836 /* Don't reseat to previous visible line start if current start
2837 position is in a string or image. */
2838 if (it->method == GET_FROM_BUFFER && it->line_wrap != TRUNCATE)
2839 {
2840 int start_at_line_beg_p;
2841 int first_y = it->current_y;
2842
2843 /* If window start is not at a line start, skip forward to POS to
2844 get the correct continuation lines width. */
2845 start_at_line_beg_p = (CHARPOS (pos) == BEGV
2846 || FETCH_BYTE (BYTEPOS (pos) - 1) == '\n');
2847 if (!start_at_line_beg_p)
2848 {
2849 int new_x;
2850
2851 reseat_at_previous_visible_line_start (it);
2852 move_it_to (it, CHARPOS (pos), -1, -1, -1, MOVE_TO_POS);
2853
2854 new_x = it->current_x + it->pixel_width;
2855
2856 /* If lines are continued, this line may end in the middle
2857 of a multi-glyph character (e.g. a control character
2858 displayed as \003, or in the middle of an overlay
2859 string). In this case move_it_to above will not have
2860 taken us to the start of the continuation line but to the
2861 end of the continued line. */
2862 if (it->current_x > 0
2863 && it->line_wrap != TRUNCATE /* Lines are continued. */
2864 && (/* And glyph doesn't fit on the line. */
2865 new_x > it->last_visible_x
2866 /* Or it fits exactly and we're on a window
2867 system frame. */
2868 || (new_x == it->last_visible_x
2869 && FRAME_WINDOW_P (it->f))))
2870 {
2871 if (it->current.dpvec_index >= 0
2872 || it->current.overlay_string_index >= 0)
2873 {
2874 set_iterator_to_next (it, 1);
2875 move_it_in_display_line_to (it, -1, -1, 0);
2876 }
2877
2878 it->continuation_lines_width += it->current_x;
2879 }
2880
2881 /* We're starting a new display line, not affected by the
2882 height of the continued line, so clear the appropriate
2883 fields in the iterator structure. */
2884 it->max_ascent = it->max_descent = 0;
2885 it->max_phys_ascent = it->max_phys_descent = 0;
2886
2887 it->current_y = first_y;
2888 it->vpos = 0;
2889 it->current_x = it->hpos = 0;
2890 }
2891 }
2892 }
2893
2894
2895 /* Return 1 if POS is a position in ellipses displayed for invisible
2896 text. W is the window we display, for text property lookup. */
2897
2898 static int
2899 in_ellipses_for_invisible_text_p (struct display_pos *pos, struct window *w)
2900 {
2901 Lisp_Object prop, window;
2902 int ellipses_p = 0;
2903 int charpos = CHARPOS (pos->pos);
2904
2905 /* If POS specifies a position in a display vector, this might
2906 be for an ellipsis displayed for invisible text. We won't
2907 get the iterator set up for delivering that ellipsis unless
2908 we make sure that it gets aware of the invisible text. */
2909 if (pos->dpvec_index >= 0
2910 && pos->overlay_string_index < 0
2911 && CHARPOS (pos->string_pos) < 0
2912 && charpos > BEGV
2913 && (XSETWINDOW (window, w),
2914 prop = Fget_char_property (make_number (charpos),
2915 Qinvisible, window),
2916 !TEXT_PROP_MEANS_INVISIBLE (prop)))
2917 {
2918 prop = Fget_char_property (make_number (charpos - 1), Qinvisible,
2919 window);
2920 ellipses_p = 2 == TEXT_PROP_MEANS_INVISIBLE (prop);
2921 }
2922
2923 return ellipses_p;
2924 }
2925
2926
2927 /* Initialize IT for stepping through current_buffer in window W,
2928 starting at position POS that includes overlay string and display
2929 vector/ control character translation position information. Value
2930 is zero if there are overlay strings with newlines at POS. */
2931
2932 static int
2933 init_from_display_pos (struct it *it, struct window *w, struct display_pos *pos)
2934 {
2935 EMACS_INT charpos = CHARPOS (pos->pos), bytepos = BYTEPOS (pos->pos);
2936 int i, overlay_strings_with_newlines = 0;
2937
2938 /* If POS specifies a position in a display vector, this might
2939 be for an ellipsis displayed for invisible text. We won't
2940 get the iterator set up for delivering that ellipsis unless
2941 we make sure that it gets aware of the invisible text. */
2942 if (in_ellipses_for_invisible_text_p (pos, w))
2943 {
2944 --charpos;
2945 bytepos = 0;
2946 }
2947
2948 /* Keep in mind: the call to reseat in init_iterator skips invisible
2949 text, so we might end up at a position different from POS. This
2950 is only a problem when POS is a row start after a newline and an
2951 overlay starts there with an after-string, and the overlay has an
2952 invisible property. Since we don't skip invisible text in
2953 display_line and elsewhere immediately after consuming the
2954 newline before the row start, such a POS will not be in a string,
2955 but the call to init_iterator below will move us to the
2956 after-string. */
2957 init_iterator (it, w, charpos, bytepos, NULL, DEFAULT_FACE_ID);
2958
2959 /* This only scans the current chunk -- it should scan all chunks.
2960 However, OVERLAY_STRING_CHUNK_SIZE has been increased from 3 in 21.1
2961 to 16 in 22.1 to make this a lesser problem. */
2962 for (i = 0; i < it->n_overlay_strings && i < OVERLAY_STRING_CHUNK_SIZE; ++i)
2963 {
2964 const char *s = SDATA (it->overlay_strings[i]);
2965 const char *e = s + SBYTES (it->overlay_strings[i]);
2966
2967 while (s < e && *s != '\n')
2968 ++s;
2969
2970 if (s < e)
2971 {
2972 overlay_strings_with_newlines = 1;
2973 break;
2974 }
2975 }
2976
2977 /* If position is within an overlay string, set up IT to the right
2978 overlay string. */
2979 if (pos->overlay_string_index >= 0)
2980 {
2981 int relative_index;
2982
2983 /* If the first overlay string happens to have a `display'
2984 property for an image, the iterator will be set up for that
2985 image, and we have to undo that setup first before we can
2986 correct the overlay string index. */
2987 if (it->method == GET_FROM_IMAGE)
2988 pop_it (it);
2989
2990 /* We already have the first chunk of overlay strings in
2991 IT->overlay_strings. Load more until the one for
2992 pos->overlay_string_index is in IT->overlay_strings. */
2993 if (pos->overlay_string_index >= OVERLAY_STRING_CHUNK_SIZE)
2994 {
2995 int n = pos->overlay_string_index / OVERLAY_STRING_CHUNK_SIZE;
2996 it->current.overlay_string_index = 0;
2997 while (n--)
2998 {
2999 load_overlay_strings (it, 0);
3000 it->current.overlay_string_index += OVERLAY_STRING_CHUNK_SIZE;
3001 }
3002 }
3003
3004 it->current.overlay_string_index = pos->overlay_string_index;
3005 relative_index = (it->current.overlay_string_index
3006 % OVERLAY_STRING_CHUNK_SIZE);
3007 it->string = it->overlay_strings[relative_index];
3008 xassert (STRINGP (it->string));
3009 it->current.string_pos = pos->string_pos;
3010 it->method = GET_FROM_STRING;
3011 }
3012
3013 if (CHARPOS (pos->string_pos) >= 0)
3014 {
3015 /* Recorded position is not in an overlay string, but in another
3016 string. This can only be a string from a `display' property.
3017 IT should already be filled with that string. */
3018 it->current.string_pos = pos->string_pos;
3019 xassert (STRINGP (it->string));
3020 }
3021
3022 /* Restore position in display vector translations, control
3023 character translations or ellipses. */
3024 if (pos->dpvec_index >= 0)
3025 {
3026 if (it->dpvec == NULL)
3027 get_next_display_element (it);
3028 xassert (it->dpvec && it->current.dpvec_index == 0);
3029 it->current.dpvec_index = pos->dpvec_index;
3030 }
3031
3032 CHECK_IT (it);
3033 return !overlay_strings_with_newlines;
3034 }
3035
3036
3037 /* Initialize IT for stepping through current_buffer in window W
3038 starting at ROW->start. */
3039
3040 static void
3041 init_to_row_start (struct it *it, struct window *w, struct glyph_row *row)
3042 {
3043 init_from_display_pos (it, w, &row->start);
3044 it->start = row->start;
3045 it->continuation_lines_width = row->continuation_lines_width;
3046 CHECK_IT (it);
3047 }
3048
3049
3050 /* Initialize IT for stepping through current_buffer in window W
3051 starting in the line following ROW, i.e. starting at ROW->end.
3052 Value is zero if there are overlay strings with newlines at ROW's
3053 end position. */
3054
3055 static int
3056 init_to_row_end (struct it *it, struct window *w, struct glyph_row *row)
3057 {
3058 int success = 0;
3059
3060 if (init_from_display_pos (it, w, &row->end))
3061 {
3062 if (row->continued_p)
3063 it->continuation_lines_width
3064 = row->continuation_lines_width + row->pixel_width;
3065 CHECK_IT (it);
3066 success = 1;
3067 }
3068
3069 return success;
3070 }
3071
3072
3073
3074 \f
3075 /***********************************************************************
3076 Text properties
3077 ***********************************************************************/
3078
3079 /* Called when IT reaches IT->stop_charpos. Handle text property and
3080 overlay changes. Set IT->stop_charpos to the next position where
3081 to stop. */
3082
3083 static void
3084 handle_stop (struct it *it)
3085 {
3086 enum prop_handled handled;
3087 int handle_overlay_change_p;
3088 struct props *p;
3089
3090 it->dpvec = NULL;
3091 it->current.dpvec_index = -1;
3092 handle_overlay_change_p = !it->ignore_overlay_strings_at_pos_p;
3093 it->ignore_overlay_strings_at_pos_p = 0;
3094 it->ellipsis_p = 0;
3095
3096 /* Use face of preceding text for ellipsis (if invisible) */
3097 if (it->selective_display_ellipsis_p)
3098 it->saved_face_id = it->face_id;
3099
3100 do
3101 {
3102 handled = HANDLED_NORMALLY;
3103
3104 /* Call text property handlers. */
3105 for (p = it_props; p->handler; ++p)
3106 {
3107 handled = p->handler (it);
3108
3109 if (handled == HANDLED_RECOMPUTE_PROPS)
3110 break;
3111 else if (handled == HANDLED_RETURN)
3112 {
3113 /* We still want to show before and after strings from
3114 overlays even if the actual buffer text is replaced. */
3115 if (!handle_overlay_change_p
3116 || it->sp > 1
3117 || !get_overlay_strings_1 (it, 0, 0))
3118 {
3119 if (it->ellipsis_p)
3120 setup_for_ellipsis (it, 0);
3121 /* When handling a display spec, we might load an
3122 empty string. In that case, discard it here. We
3123 used to discard it in handle_single_display_spec,
3124 but that causes get_overlay_strings_1, above, to
3125 ignore overlay strings that we must check. */
3126 if (STRINGP (it->string) && !SCHARS (it->string))
3127 pop_it (it);
3128 return;
3129 }
3130 else if (STRINGP (it->string) && !SCHARS (it->string))
3131 pop_it (it);
3132 else
3133 {
3134 it->ignore_overlay_strings_at_pos_p = 1;
3135 it->string_from_display_prop_p = 0;
3136 handle_overlay_change_p = 0;
3137 }
3138 handled = HANDLED_RECOMPUTE_PROPS;
3139 break;
3140 }
3141 else if (handled == HANDLED_OVERLAY_STRING_CONSUMED)
3142 handle_overlay_change_p = 0;
3143 }
3144
3145 if (handled != HANDLED_RECOMPUTE_PROPS)
3146 {
3147 /* Don't check for overlay strings below when set to deliver
3148 characters from a display vector. */
3149 if (it->method == GET_FROM_DISPLAY_VECTOR)
3150 handle_overlay_change_p = 0;
3151
3152 /* Handle overlay changes.
3153 This sets HANDLED to HANDLED_RECOMPUTE_PROPS
3154 if it finds overlays. */
3155 if (handle_overlay_change_p)
3156 handled = handle_overlay_change (it);
3157 }
3158
3159 if (it->ellipsis_p)
3160 {
3161 setup_for_ellipsis (it, 0);
3162 break;
3163 }
3164 }
3165 while (handled == HANDLED_RECOMPUTE_PROPS);
3166
3167 /* Determine where to stop next. */
3168 if (handled == HANDLED_NORMALLY)
3169 compute_stop_pos (it);
3170 }
3171
3172
3173 /* Compute IT->stop_charpos from text property and overlay change
3174 information for IT's current position. */
3175
3176 static void
3177 compute_stop_pos (struct it *it)
3178 {
3179 register INTERVAL iv, next_iv;
3180 Lisp_Object object, limit, position;
3181 EMACS_INT charpos, bytepos;
3182
3183 /* If nowhere else, stop at the end. */
3184 it->stop_charpos = it->end_charpos;
3185
3186 if (STRINGP (it->string))
3187 {
3188 /* Strings are usually short, so don't limit the search for
3189 properties. */
3190 object = it->string;
3191 limit = Qnil;
3192 charpos = IT_STRING_CHARPOS (*it);
3193 bytepos = IT_STRING_BYTEPOS (*it);
3194 }
3195 else
3196 {
3197 EMACS_INT pos;
3198
3199 /* If next overlay change is in front of the current stop pos
3200 (which is IT->end_charpos), stop there. Note: value of
3201 next_overlay_change is point-max if no overlay change
3202 follows. */
3203 charpos = IT_CHARPOS (*it);
3204 bytepos = IT_BYTEPOS (*it);
3205 pos = next_overlay_change (charpos);
3206 if (pos < it->stop_charpos)
3207 it->stop_charpos = pos;
3208
3209 /* If showing the region, we have to stop at the region
3210 start or end because the face might change there. */
3211 if (it->region_beg_charpos > 0)
3212 {
3213 if (IT_CHARPOS (*it) < it->region_beg_charpos)
3214 it->stop_charpos = min (it->stop_charpos, it->region_beg_charpos);
3215 else if (IT_CHARPOS (*it) < it->region_end_charpos)
3216 it->stop_charpos = min (it->stop_charpos, it->region_end_charpos);
3217 }
3218
3219 /* Set up variables for computing the stop position from text
3220 property changes. */
3221 XSETBUFFER (object, current_buffer);
3222 limit = make_number (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT);
3223 }
3224
3225 /* Get the interval containing IT's position. Value is a null
3226 interval if there isn't such an interval. */
3227 position = make_number (charpos);
3228 iv = validate_interval_range (object, &position, &position, 0);
3229 if (!NULL_INTERVAL_P (iv))
3230 {
3231 Lisp_Object values_here[LAST_PROP_IDX];
3232 struct props *p;
3233
3234 /* Get properties here. */
3235 for (p = it_props; p->handler; ++p)
3236 values_here[p->idx] = textget (iv->plist, *p->name);
3237
3238 /* Look for an interval following iv that has different
3239 properties. */
3240 for (next_iv = next_interval (iv);
3241 (!NULL_INTERVAL_P (next_iv)
3242 && (NILP (limit)
3243 || XFASTINT (limit) > next_iv->position));
3244 next_iv = next_interval (next_iv))
3245 {
3246 for (p = it_props; p->handler; ++p)
3247 {
3248 Lisp_Object new_value;
3249
3250 new_value = textget (next_iv->plist, *p->name);
3251 if (!EQ (values_here[p->idx], new_value))
3252 break;
3253 }
3254
3255 if (p->handler)
3256 break;
3257 }
3258
3259 if (!NULL_INTERVAL_P (next_iv))
3260 {
3261 if (INTEGERP (limit)
3262 && next_iv->position >= XFASTINT (limit))
3263 /* No text property change up to limit. */
3264 it->stop_charpos = min (XFASTINT (limit), it->stop_charpos);
3265 else
3266 /* Text properties change in next_iv. */
3267 it->stop_charpos = min (it->stop_charpos, next_iv->position);
3268 }
3269 }
3270
3271 composition_compute_stop_pos (&it->cmp_it, charpos, bytepos,
3272 it->stop_charpos, it->string);
3273
3274 xassert (STRINGP (it->string)
3275 || (it->stop_charpos >= BEGV
3276 && it->stop_charpos >= IT_CHARPOS (*it)));
3277 }
3278
3279
3280 /* Return the position of the next overlay change after POS in
3281 current_buffer. Value is point-max if no overlay change
3282 follows. This is like `next-overlay-change' but doesn't use
3283 xmalloc. */
3284
3285 static EMACS_INT
3286 next_overlay_change (EMACS_INT pos)
3287 {
3288 int noverlays;
3289 EMACS_INT endpos;
3290 Lisp_Object *overlays;
3291 int i;
3292
3293 /* Get all overlays at the given position. */
3294 GET_OVERLAYS_AT (pos, overlays, noverlays, &endpos, 1);
3295
3296 /* If any of these overlays ends before endpos,
3297 use its ending point instead. */
3298 for (i = 0; i < noverlays; ++i)
3299 {
3300 Lisp_Object oend;
3301 EMACS_INT oendpos;
3302
3303 oend = OVERLAY_END (overlays[i]);
3304 oendpos = OVERLAY_POSITION (oend);
3305 endpos = min (endpos, oendpos);
3306 }
3307
3308 return endpos;
3309 }
3310
3311
3312 \f
3313 /***********************************************************************
3314 Fontification
3315 ***********************************************************************/
3316
3317 /* Handle changes in the `fontified' property of the current buffer by
3318 calling hook functions from Qfontification_functions to fontify
3319 regions of text. */
3320
3321 static enum prop_handled
3322 handle_fontified_prop (struct it *it)
3323 {
3324 Lisp_Object prop, pos;
3325 enum prop_handled handled = HANDLED_NORMALLY;
3326
3327 if (!NILP (Vmemory_full))
3328 return handled;
3329
3330 /* Get the value of the `fontified' property at IT's current buffer
3331 position. (The `fontified' property doesn't have a special
3332 meaning in strings.) If the value is nil, call functions from
3333 Qfontification_functions. */
3334 if (!STRINGP (it->string)
3335 && it->s == NULL
3336 && !NILP (Vfontification_functions)
3337 && !NILP (Vrun_hooks)
3338 && (pos = make_number (IT_CHARPOS (*it)),
3339 prop = Fget_char_property (pos, Qfontified, Qnil),
3340 /* Ignore the special cased nil value always present at EOB since
3341 no amount of fontifying will be able to change it. */
3342 NILP (prop) && IT_CHARPOS (*it) < Z))
3343 {
3344 int count = SPECPDL_INDEX ();
3345 Lisp_Object val;
3346
3347 val = Vfontification_functions;
3348 specbind (Qfontification_functions, Qnil);
3349
3350 if (!CONSP (val) || EQ (XCAR (val), Qlambda))
3351 safe_call1 (val, pos);
3352 else
3353 {
3354 Lisp_Object globals, fn;
3355 struct gcpro gcpro1, gcpro2;
3356
3357 globals = Qnil;
3358 GCPRO2 (val, globals);
3359
3360 for (; CONSP (val); val = XCDR (val))
3361 {
3362 fn = XCAR (val);
3363
3364 if (EQ (fn, Qt))
3365 {
3366 /* A value of t indicates this hook has a local
3367 binding; it means to run the global binding too.
3368 In a global value, t should not occur. If it
3369 does, we must ignore it to avoid an endless
3370 loop. */
3371 for (globals = Fdefault_value (Qfontification_functions);
3372 CONSP (globals);
3373 globals = XCDR (globals))
3374 {
3375 fn = XCAR (globals);
3376 if (!EQ (fn, Qt))
3377 safe_call1 (fn, pos);
3378 }
3379 }
3380 else
3381 safe_call1 (fn, pos);
3382 }
3383
3384 UNGCPRO;
3385 }
3386
3387 unbind_to (count, Qnil);
3388
3389 /* Return HANDLED_RECOMPUTE_PROPS only if function fontified
3390 something. This avoids an endless loop if they failed to
3391 fontify the text for which reason ever. */
3392 if (!NILP (Fget_char_property (pos, Qfontified, Qnil)))
3393 handled = HANDLED_RECOMPUTE_PROPS;
3394 }
3395
3396 return handled;
3397 }
3398
3399
3400 \f
3401 /***********************************************************************
3402 Faces
3403 ***********************************************************************/
3404
3405 /* Set up iterator IT from face properties at its current position.
3406 Called from handle_stop. */
3407
3408 static enum prop_handled
3409 handle_face_prop (struct it *it)
3410 {
3411 int new_face_id;
3412 EMACS_INT next_stop;
3413
3414 if (!STRINGP (it->string))
3415 {
3416 new_face_id
3417 = face_at_buffer_position (it->w,
3418 IT_CHARPOS (*it),
3419 it->region_beg_charpos,
3420 it->region_end_charpos,
3421 &next_stop,
3422 (IT_CHARPOS (*it)
3423 + TEXT_PROP_DISTANCE_LIMIT),
3424 0, it->base_face_id);
3425
3426 /* Is this a start of a run of characters with box face?
3427 Caveat: this can be called for a freshly initialized
3428 iterator; face_id is -1 in this case. We know that the new
3429 face will not change until limit, i.e. if the new face has a
3430 box, all characters up to limit will have one. But, as
3431 usual, we don't know whether limit is really the end. */
3432 if (new_face_id != it->face_id)
3433 {
3434 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
3435
3436 /* If new face has a box but old face has not, this is
3437 the start of a run of characters with box, i.e. it has
3438 a shadow on the left side. The value of face_id of the
3439 iterator will be -1 if this is the initial call that gets
3440 the face. In this case, we have to look in front of IT's
3441 position and see whether there is a face != new_face_id. */
3442 it->start_of_box_run_p
3443 = (new_face->box != FACE_NO_BOX
3444 && (it->face_id >= 0
3445 || IT_CHARPOS (*it) == BEG
3446 || new_face_id != face_before_it_pos (it)));
3447 it->face_box_p = new_face->box != FACE_NO_BOX;
3448 }
3449 }
3450 else
3451 {
3452 int base_face_id, bufpos;
3453 int i;
3454 Lisp_Object from_overlay
3455 = (it->current.overlay_string_index >= 0
3456 ? it->string_overlays[it->current.overlay_string_index]
3457 : Qnil);
3458
3459 /* See if we got to this string directly or indirectly from
3460 an overlay property. That includes the before-string or
3461 after-string of an overlay, strings in display properties
3462 provided by an overlay, their text properties, etc.
3463
3464 FROM_OVERLAY is the overlay that brought us here, or nil if none. */
3465 if (! NILP (from_overlay))
3466 for (i = it->sp - 1; i >= 0; i--)
3467 {
3468 if (it->stack[i].current.overlay_string_index >= 0)
3469 from_overlay
3470 = it->string_overlays[it->stack[i].current.overlay_string_index];
3471 else if (! NILP (it->stack[i].from_overlay))
3472 from_overlay = it->stack[i].from_overlay;
3473
3474 if (!NILP (from_overlay))
3475 break;
3476 }
3477
3478 if (! NILP (from_overlay))
3479 {
3480 bufpos = IT_CHARPOS (*it);
3481 /* For a string from an overlay, the base face depends
3482 only on text properties and ignores overlays. */
3483 base_face_id
3484 = face_for_overlay_string (it->w,
3485 IT_CHARPOS (*it),
3486 it->region_beg_charpos,
3487 it->region_end_charpos,
3488 &next_stop,
3489 (IT_CHARPOS (*it)
3490 + TEXT_PROP_DISTANCE_LIMIT),
3491 0,
3492 from_overlay);
3493 }
3494 else
3495 {
3496 bufpos = 0;
3497
3498 /* For strings from a `display' property, use the face at
3499 IT's current buffer position as the base face to merge
3500 with, so that overlay strings appear in the same face as
3501 surrounding text, unless they specify their own
3502 faces. */
3503 base_face_id = underlying_face_id (it);
3504 }
3505
3506 new_face_id = face_at_string_position (it->w,
3507 it->string,
3508 IT_STRING_CHARPOS (*it),
3509 bufpos,
3510 it->region_beg_charpos,
3511 it->region_end_charpos,
3512 &next_stop,
3513 base_face_id, 0);
3514
3515 /* Is this a start of a run of characters with box? Caveat:
3516 this can be called for a freshly allocated iterator; face_id
3517 is -1 is this case. We know that the new face will not
3518 change until the next check pos, i.e. if the new face has a
3519 box, all characters up to that position will have a
3520 box. But, as usual, we don't know whether that position
3521 is really the end. */
3522 if (new_face_id != it->face_id)
3523 {
3524 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
3525 struct face *old_face = FACE_FROM_ID (it->f, it->face_id);
3526
3527 /* If new face has a box but old face hasn't, this is the
3528 start of a run of characters with box, i.e. it has a
3529 shadow on the left side. */
3530 it->start_of_box_run_p
3531 = new_face->box && (old_face == NULL || !old_face->box);
3532 it->face_box_p = new_face->box != FACE_NO_BOX;
3533 }
3534 }
3535
3536 it->face_id = new_face_id;
3537 return HANDLED_NORMALLY;
3538 }
3539
3540
3541 /* Return the ID of the face ``underlying'' IT's current position,
3542 which is in a string. If the iterator is associated with a
3543 buffer, return the face at IT's current buffer position.
3544 Otherwise, use the iterator's base_face_id. */
3545
3546 static int
3547 underlying_face_id (struct it *it)
3548 {
3549 int face_id = it->base_face_id, i;
3550
3551 xassert (STRINGP (it->string));
3552
3553 for (i = it->sp - 1; i >= 0; --i)
3554 if (NILP (it->stack[i].string))
3555 face_id = it->stack[i].face_id;
3556
3557 return face_id;
3558 }
3559
3560
3561 /* Compute the face one character before or after the current position
3562 of IT. BEFORE_P non-zero means get the face in front of IT's
3563 position. Value is the id of the face. */
3564
3565 static int
3566 face_before_or_after_it_pos (struct it *it, int before_p)
3567 {
3568 int face_id, limit;
3569 EMACS_INT next_check_charpos;
3570 struct text_pos pos;
3571
3572 xassert (it->s == NULL);
3573
3574 if (STRINGP (it->string))
3575 {
3576 int bufpos, base_face_id;
3577
3578 /* No face change past the end of the string (for the case
3579 we are padding with spaces). No face change before the
3580 string start. */
3581 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string)
3582 || (IT_STRING_CHARPOS (*it) == 0 && before_p))
3583 return it->face_id;
3584
3585 /* Set pos to the position before or after IT's current position. */
3586 if (before_p)
3587 pos = string_pos (IT_STRING_CHARPOS (*it) - 1, it->string);
3588 else
3589 /* For composition, we must check the character after the
3590 composition. */
3591 pos = (it->what == IT_COMPOSITION
3592 ? string_pos (IT_STRING_CHARPOS (*it)
3593 + it->cmp_it.nchars, it->string)
3594 : string_pos (IT_STRING_CHARPOS (*it) + 1, it->string));
3595
3596 if (it->current.overlay_string_index >= 0)
3597 bufpos = IT_CHARPOS (*it);
3598 else
3599 bufpos = 0;
3600
3601 base_face_id = underlying_face_id (it);
3602
3603 /* Get the face for ASCII, or unibyte. */
3604 face_id = face_at_string_position (it->w,
3605 it->string,
3606 CHARPOS (pos),
3607 bufpos,
3608 it->region_beg_charpos,
3609 it->region_end_charpos,
3610 &next_check_charpos,
3611 base_face_id, 0);
3612
3613 /* Correct the face for charsets different from ASCII. Do it
3614 for the multibyte case only. The face returned above is
3615 suitable for unibyte text if IT->string is unibyte. */
3616 if (STRING_MULTIBYTE (it->string))
3617 {
3618 const unsigned char *p = SDATA (it->string) + BYTEPOS (pos);
3619 int rest = SBYTES (it->string) - BYTEPOS (pos);
3620 int c, len;
3621 struct face *face = FACE_FROM_ID (it->f, face_id);
3622
3623 c = string_char_and_length (p, &len);
3624 face_id = FACE_FOR_CHAR (it->f, face, c, CHARPOS (pos), it->string);
3625 }
3626 }
3627 else
3628 {
3629 if ((IT_CHARPOS (*it) >= ZV && !before_p)
3630 || (IT_CHARPOS (*it) <= BEGV && before_p))
3631 return it->face_id;
3632
3633 limit = IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT;
3634 pos = it->current.pos;
3635
3636 if (before_p)
3637 DEC_TEXT_POS (pos, it->multibyte_p);
3638 else
3639 {
3640 if (it->what == IT_COMPOSITION)
3641 /* For composition, we must check the position after the
3642 composition. */
3643 pos.charpos += it->cmp_it.nchars, pos.bytepos += it->len;
3644 else
3645 INC_TEXT_POS (pos, it->multibyte_p);
3646 }
3647
3648 /* Determine face for CHARSET_ASCII, or unibyte. */
3649 face_id = face_at_buffer_position (it->w,
3650 CHARPOS (pos),
3651 it->region_beg_charpos,
3652 it->region_end_charpos,
3653 &next_check_charpos,
3654 limit, 0, -1);
3655
3656 /* Correct the face for charsets different from ASCII. Do it
3657 for the multibyte case only. The face returned above is
3658 suitable for unibyte text if current_buffer is unibyte. */
3659 if (it->multibyte_p)
3660 {
3661 int c = FETCH_MULTIBYTE_CHAR (BYTEPOS (pos));
3662 struct face *face = FACE_FROM_ID (it->f, face_id);
3663 face_id = FACE_FOR_CHAR (it->f, face, c, CHARPOS (pos), Qnil);
3664 }
3665 }
3666
3667 return face_id;
3668 }
3669
3670
3671 \f
3672 /***********************************************************************
3673 Invisible text
3674 ***********************************************************************/
3675
3676 /* Set up iterator IT from invisible properties at its current
3677 position. Called from handle_stop. */
3678
3679 static enum prop_handled
3680 handle_invisible_prop (struct it *it)
3681 {
3682 enum prop_handled handled = HANDLED_NORMALLY;
3683
3684 if (STRINGP (it->string))
3685 {
3686 Lisp_Object prop, end_charpos, limit, charpos;
3687
3688 /* Get the value of the invisible text property at the
3689 current position. Value will be nil if there is no such
3690 property. */
3691 charpos = make_number (IT_STRING_CHARPOS (*it));
3692 prop = Fget_text_property (charpos, Qinvisible, it->string);
3693
3694 if (!NILP (prop)
3695 && IT_STRING_CHARPOS (*it) < it->end_charpos)
3696 {
3697 handled = HANDLED_RECOMPUTE_PROPS;
3698
3699 /* Get the position at which the next change of the
3700 invisible text property can be found in IT->string.
3701 Value will be nil if the property value is the same for
3702 all the rest of IT->string. */
3703 XSETINT (limit, SCHARS (it->string));
3704 end_charpos = Fnext_single_property_change (charpos, Qinvisible,
3705 it->string, limit);
3706
3707 /* Text at current position is invisible. The next
3708 change in the property is at position end_charpos.
3709 Move IT's current position to that position. */
3710 if (INTEGERP (end_charpos)
3711 && XFASTINT (end_charpos) < XFASTINT (limit))
3712 {
3713 struct text_pos old;
3714 old = it->current.string_pos;
3715 IT_STRING_CHARPOS (*it) = XFASTINT (end_charpos);
3716 compute_string_pos (&it->current.string_pos, old, it->string);
3717 }
3718 else
3719 {
3720 /* The rest of the string is invisible. If this is an
3721 overlay string, proceed with the next overlay string
3722 or whatever comes and return a character from there. */
3723 if (it->current.overlay_string_index >= 0)
3724 {
3725 next_overlay_string (it);
3726 /* Don't check for overlay strings when we just
3727 finished processing them. */
3728 handled = HANDLED_OVERLAY_STRING_CONSUMED;
3729 }
3730 else
3731 {
3732 IT_STRING_CHARPOS (*it) = SCHARS (it->string);
3733 IT_STRING_BYTEPOS (*it) = SBYTES (it->string);
3734 }
3735 }
3736 }
3737 }
3738 else
3739 {
3740 int invis_p;
3741 EMACS_INT newpos, next_stop, start_charpos, tem;
3742 Lisp_Object pos, prop, overlay;
3743
3744 /* First of all, is there invisible text at this position? */
3745 tem = start_charpos = IT_CHARPOS (*it);
3746 pos = make_number (tem);
3747 prop = get_char_property_and_overlay (pos, Qinvisible, it->window,
3748 &overlay);
3749 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
3750
3751 /* If we are on invisible text, skip over it. */
3752 if (invis_p && start_charpos < it->end_charpos)
3753 {
3754 /* Record whether we have to display an ellipsis for the
3755 invisible text. */
3756 int display_ellipsis_p = invis_p == 2;
3757
3758 handled = HANDLED_RECOMPUTE_PROPS;
3759
3760 /* Loop skipping over invisible text. The loop is left at
3761 ZV or with IT on the first char being visible again. */
3762 do
3763 {
3764 /* Try to skip some invisible text. Return value is the
3765 position reached which can be equal to where we start
3766 if there is nothing invisible there. This skips both
3767 over invisible text properties and overlays with
3768 invisible property. */
3769 newpos = skip_invisible (tem, &next_stop, ZV, it->window);
3770
3771 /* If we skipped nothing at all we weren't at invisible
3772 text in the first place. If everything to the end of
3773 the buffer was skipped, end the loop. */
3774 if (newpos == tem || newpos >= ZV)
3775 invis_p = 0;
3776 else
3777 {
3778 /* We skipped some characters but not necessarily
3779 all there are. Check if we ended up on visible
3780 text. Fget_char_property returns the property of
3781 the char before the given position, i.e. if we
3782 get invis_p = 0, this means that the char at
3783 newpos is visible. */
3784 pos = make_number (newpos);
3785 prop = Fget_char_property (pos, Qinvisible, it->window);
3786 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
3787 }
3788
3789 /* If we ended up on invisible text, proceed to
3790 skip starting with next_stop. */
3791 if (invis_p)
3792 tem = next_stop;
3793
3794 /* If there are adjacent invisible texts, don't lose the
3795 second one's ellipsis. */
3796 if (invis_p == 2)
3797 display_ellipsis_p = 1;
3798 }
3799 while (invis_p);
3800
3801 /* The position newpos is now either ZV or on visible text. */
3802 if (it->bidi_p && newpos < ZV)
3803 {
3804 /* With bidi iteration, the region of invisible text
3805 could start and/or end in the middle of a non-base
3806 embedding level. Therefore, we need to skip
3807 invisible text using the bidi iterator, starting at
3808 IT's current position, until we find ourselves
3809 outside the invisible text. Skipping invisible text
3810 _after_ bidi iteration avoids affecting the visual
3811 order of the displayed text when invisible properties
3812 are added or removed. */
3813 if (it->bidi_it.first_elt)
3814 {
3815 /* If we were `reseat'ed to a new paragraph,
3816 determine the paragraph base direction. We need
3817 to do it now because next_element_from_buffer may
3818 not have a chance to do it, if we are going to
3819 skip any text at the beginning, which resets the
3820 FIRST_ELT flag. */
3821 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it);
3822 }
3823 do
3824 {
3825 bidi_move_to_visually_next (&it->bidi_it);
3826 }
3827 while (it->stop_charpos <= it->bidi_it.charpos
3828 && it->bidi_it.charpos < newpos);
3829 IT_CHARPOS (*it) = it->bidi_it.charpos;
3830 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
3831 /* If we overstepped NEWPOS, record its position in the
3832 iterator, so that we skip invisible text if later the
3833 bidi iteration lands us in the invisible region
3834 again. */
3835 if (IT_CHARPOS (*it) >= newpos)
3836 it->prev_stop = newpos;
3837 }
3838 else
3839 {
3840 IT_CHARPOS (*it) = newpos;
3841 IT_BYTEPOS (*it) = CHAR_TO_BYTE (newpos);
3842 }
3843
3844 /* If there are before-strings at the start of invisible
3845 text, and the text is invisible because of a text
3846 property, arrange to show before-strings because 20.x did
3847 it that way. (If the text is invisible because of an
3848 overlay property instead of a text property, this is
3849 already handled in the overlay code.) */
3850 if (NILP (overlay)
3851 && get_overlay_strings (it, it->stop_charpos))
3852 {
3853 handled = HANDLED_RECOMPUTE_PROPS;
3854 it->stack[it->sp - 1].display_ellipsis_p = display_ellipsis_p;
3855 }
3856 else if (display_ellipsis_p)
3857 {
3858 /* Make sure that the glyphs of the ellipsis will get
3859 correct `charpos' values. If we would not update
3860 it->position here, the glyphs would belong to the
3861 last visible character _before_ the invisible
3862 text, which confuses `set_cursor_from_row'.
3863
3864 We use the last invisible position instead of the
3865 first because this way the cursor is always drawn on
3866 the first "." of the ellipsis, whenever PT is inside
3867 the invisible text. Otherwise the cursor would be
3868 placed _after_ the ellipsis when the point is after the
3869 first invisible character. */
3870 if (!STRINGP (it->object))
3871 {
3872 it->position.charpos = newpos - 1;
3873 it->position.bytepos = CHAR_TO_BYTE (it->position.charpos);
3874 }
3875 it->ellipsis_p = 1;
3876 /* Let the ellipsis display before
3877 considering any properties of the following char.
3878 Fixes jasonr@gnu.org 01 Oct 07 bug. */
3879 handled = HANDLED_RETURN;
3880 }
3881 }
3882 }
3883
3884 return handled;
3885 }
3886
3887
3888 /* Make iterator IT return `...' next.
3889 Replaces LEN characters from buffer. */
3890
3891 static void
3892 setup_for_ellipsis (struct it *it, int len)
3893 {
3894 /* Use the display table definition for `...'. Invalid glyphs
3895 will be handled by the method returning elements from dpvec. */
3896 if (it->dp && VECTORP (DISP_INVIS_VECTOR (it->dp)))
3897 {
3898 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
3899 it->dpvec = v->contents;
3900 it->dpend = v->contents + v->size;
3901 }
3902 else
3903 {
3904 /* Default `...'. */
3905 it->dpvec = default_invis_vector;
3906 it->dpend = default_invis_vector + 3;
3907 }
3908
3909 it->dpvec_char_len = len;
3910 it->current.dpvec_index = 0;
3911 it->dpvec_face_id = -1;
3912
3913 /* Remember the current face id in case glyphs specify faces.
3914 IT's face is restored in set_iterator_to_next.
3915 saved_face_id was set to preceding char's face in handle_stop. */
3916 if (it->saved_face_id < 0 || it->saved_face_id != it->face_id)
3917 it->saved_face_id = it->face_id = DEFAULT_FACE_ID;
3918
3919 it->method = GET_FROM_DISPLAY_VECTOR;
3920 it->ellipsis_p = 1;
3921 }
3922
3923
3924 \f
3925 /***********************************************************************
3926 'display' property
3927 ***********************************************************************/
3928
3929 /* Set up iterator IT from `display' property at its current position.
3930 Called from handle_stop.
3931 We return HANDLED_RETURN if some part of the display property
3932 overrides the display of the buffer text itself.
3933 Otherwise we return HANDLED_NORMALLY. */
3934
3935 static enum prop_handled
3936 handle_display_prop (struct it *it)
3937 {
3938 Lisp_Object prop, object, overlay;
3939 struct text_pos *position;
3940 /* Nonzero if some property replaces the display of the text itself. */
3941 int display_replaced_p = 0;
3942
3943 if (STRINGP (it->string))
3944 {
3945 object = it->string;
3946 position = &it->current.string_pos;
3947 }
3948 else
3949 {
3950 XSETWINDOW (object, it->w);
3951 position = &it->current.pos;
3952 }
3953
3954 /* Reset those iterator values set from display property values. */
3955 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
3956 it->space_width = Qnil;
3957 it->font_height = Qnil;
3958 it->voffset = 0;
3959
3960 /* We don't support recursive `display' properties, i.e. string
3961 values that have a string `display' property, that have a string
3962 `display' property etc. */
3963 if (!it->string_from_display_prop_p)
3964 it->area = TEXT_AREA;
3965
3966 prop = get_char_property_and_overlay (make_number (position->charpos),
3967 Qdisplay, object, &overlay);
3968 if (NILP (prop))
3969 return HANDLED_NORMALLY;
3970 /* Now OVERLAY is the overlay that gave us this property, or nil
3971 if it was a text property. */
3972
3973 if (!STRINGP (it->string))
3974 object = it->w->buffer;
3975
3976 if (CONSP (prop)
3977 /* Simple properties. */
3978 && !EQ (XCAR (prop), Qimage)
3979 && !EQ (XCAR (prop), Qspace)
3980 && !EQ (XCAR (prop), Qwhen)
3981 && !EQ (XCAR (prop), Qslice)
3982 && !EQ (XCAR (prop), Qspace_width)
3983 && !EQ (XCAR (prop), Qheight)
3984 && !EQ (XCAR (prop), Qraise)
3985 /* Marginal area specifications. */
3986 && !(CONSP (XCAR (prop)) && EQ (XCAR (XCAR (prop)), Qmargin))
3987 && !EQ (XCAR (prop), Qleft_fringe)
3988 && !EQ (XCAR (prop), Qright_fringe)
3989 && !NILP (XCAR (prop)))
3990 {
3991 for (; CONSP (prop); prop = XCDR (prop))
3992 {
3993 if (handle_single_display_spec (it, XCAR (prop), object, overlay,
3994 position, display_replaced_p))
3995 {
3996 display_replaced_p = 1;
3997 /* If some text in a string is replaced, `position' no
3998 longer points to the position of `object'. */
3999 if (STRINGP (object))
4000 break;
4001 }
4002 }
4003 }
4004 else if (VECTORP (prop))
4005 {
4006 int i;
4007 for (i = 0; i < ASIZE (prop); ++i)
4008 if (handle_single_display_spec (it, AREF (prop, i), object, overlay,
4009 position, display_replaced_p))
4010 {
4011 display_replaced_p = 1;
4012 /* If some text in a string is replaced, `position' no
4013 longer points to the position of `object'. */
4014 if (STRINGP (object))
4015 break;
4016 }
4017 }
4018 else
4019 {
4020 if (handle_single_display_spec (it, prop, object, overlay,
4021 position, 0))
4022 display_replaced_p = 1;
4023 }
4024
4025 return display_replaced_p ? HANDLED_RETURN : HANDLED_NORMALLY;
4026 }
4027
4028
4029 /* Value is the position of the end of the `display' property starting
4030 at START_POS in OBJECT. */
4031
4032 static struct text_pos
4033 display_prop_end (struct it *it, Lisp_Object object, struct text_pos start_pos)
4034 {
4035 Lisp_Object end;
4036 struct text_pos end_pos;
4037
4038 end = Fnext_single_char_property_change (make_number (CHARPOS (start_pos)),
4039 Qdisplay, object, Qnil);
4040 CHARPOS (end_pos) = XFASTINT (end);
4041 if (STRINGP (object))
4042 compute_string_pos (&end_pos, start_pos, it->string);
4043 else
4044 BYTEPOS (end_pos) = CHAR_TO_BYTE (XFASTINT (end));
4045
4046 return end_pos;
4047 }
4048
4049
4050 /* Set up IT from a single `display' specification PROP. OBJECT
4051 is the object in which the `display' property was found. *POSITION
4052 is the position at which it was found. DISPLAY_REPLACED_P non-zero
4053 means that we previously saw a display specification which already
4054 replaced text display with something else, for example an image;
4055 we ignore such properties after the first one has been processed.
4056
4057 OVERLAY is the overlay this `display' property came from,
4058 or nil if it was a text property.
4059
4060 If PROP is a `space' or `image' specification, and in some other
4061 cases too, set *POSITION to the position where the `display'
4062 property ends.
4063
4064 Value is non-zero if something was found which replaces the display
4065 of buffer or string text. */
4066
4067 static int
4068 handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
4069 Lisp_Object overlay, struct text_pos *position,
4070 int display_replaced_before_p)
4071 {
4072 Lisp_Object form;
4073 Lisp_Object location, value;
4074 struct text_pos start_pos, save_pos;
4075 int valid_p;
4076
4077 /* If SPEC is a list of the form `(when FORM . VALUE)', evaluate FORM.
4078 If the result is non-nil, use VALUE instead of SPEC. */
4079 form = Qt;
4080 if (CONSP (spec) && EQ (XCAR (spec), Qwhen))
4081 {
4082 spec = XCDR (spec);
4083 if (!CONSP (spec))
4084 return 0;
4085 form = XCAR (spec);
4086 spec = XCDR (spec);
4087 }
4088
4089 if (!NILP (form) && !EQ (form, Qt))
4090 {
4091 int count = SPECPDL_INDEX ();
4092 struct gcpro gcpro1;
4093
4094 /* Bind `object' to the object having the `display' property, a
4095 buffer or string. Bind `position' to the position in the
4096 object where the property was found, and `buffer-position'
4097 to the current position in the buffer. */
4098 specbind (Qobject, object);
4099 specbind (Qposition, make_number (CHARPOS (*position)));
4100 specbind (Qbuffer_position,
4101 make_number (STRINGP (object)
4102 ? IT_CHARPOS (*it) : CHARPOS (*position)));
4103 GCPRO1 (form);
4104 form = safe_eval (form);
4105 UNGCPRO;
4106 unbind_to (count, Qnil);
4107 }
4108
4109 if (NILP (form))
4110 return 0;
4111
4112 /* Handle `(height HEIGHT)' specifications. */
4113 if (CONSP (spec)
4114 && EQ (XCAR (spec), Qheight)
4115 && CONSP (XCDR (spec)))
4116 {
4117 if (!FRAME_WINDOW_P (it->f))
4118 return 0;
4119
4120 it->font_height = XCAR (XCDR (spec));
4121 if (!NILP (it->font_height))
4122 {
4123 struct face *face = FACE_FROM_ID (it->f, it->face_id);
4124 int new_height = -1;
4125
4126 if (CONSP (it->font_height)
4127 && (EQ (XCAR (it->font_height), Qplus)
4128 || EQ (XCAR (it->font_height), Qminus))
4129 && CONSP (XCDR (it->font_height))
4130 && INTEGERP (XCAR (XCDR (it->font_height))))
4131 {
4132 /* `(+ N)' or `(- N)' where N is an integer. */
4133 int steps = XINT (XCAR (XCDR (it->font_height)));
4134 if (EQ (XCAR (it->font_height), Qplus))
4135 steps = - steps;
4136 it->face_id = smaller_face (it->f, it->face_id, steps);
4137 }
4138 else if (FUNCTIONP (it->font_height))
4139 {
4140 /* Call function with current height as argument.
4141 Value is the new height. */
4142 Lisp_Object height;
4143 height = safe_call1 (it->font_height,
4144 face->lface[LFACE_HEIGHT_INDEX]);
4145 if (NUMBERP (height))
4146 new_height = XFLOATINT (height);
4147 }
4148 else if (NUMBERP (it->font_height))
4149 {
4150 /* Value is a multiple of the canonical char height. */
4151 struct face *face;
4152
4153 face = FACE_FROM_ID (it->f,
4154 lookup_basic_face (it->f, DEFAULT_FACE_ID));
4155 new_height = (XFLOATINT (it->font_height)
4156 * XINT (face->lface[LFACE_HEIGHT_INDEX]));
4157 }
4158 else
4159 {
4160 /* Evaluate IT->font_height with `height' bound to the
4161 current specified height to get the new height. */
4162 int count = SPECPDL_INDEX ();
4163
4164 specbind (Qheight, face->lface[LFACE_HEIGHT_INDEX]);
4165 value = safe_eval (it->font_height);
4166 unbind_to (count, Qnil);
4167
4168 if (NUMBERP (value))
4169 new_height = XFLOATINT (value);
4170 }
4171
4172 if (new_height > 0)
4173 it->face_id = face_with_height (it->f, it->face_id, new_height);
4174 }
4175
4176 return 0;
4177 }
4178
4179 /* Handle `(space-width WIDTH)'. */
4180 if (CONSP (spec)
4181 && EQ (XCAR (spec), Qspace_width)
4182 && CONSP (XCDR (spec)))
4183 {
4184 if (!FRAME_WINDOW_P (it->f))
4185 return 0;
4186
4187 value = XCAR (XCDR (spec));
4188 if (NUMBERP (value) && XFLOATINT (value) > 0)
4189 it->space_width = value;
4190
4191 return 0;
4192 }
4193
4194 /* Handle `(slice X Y WIDTH HEIGHT)'. */
4195 if (CONSP (spec)
4196 && EQ (XCAR (spec), Qslice))
4197 {
4198 Lisp_Object tem;
4199
4200 if (!FRAME_WINDOW_P (it->f))
4201 return 0;
4202
4203 if (tem = XCDR (spec), CONSP (tem))
4204 {
4205 it->slice.x = XCAR (tem);
4206 if (tem = XCDR (tem), CONSP (tem))
4207 {
4208 it->slice.y = XCAR (tem);
4209 if (tem = XCDR (tem), CONSP (tem))
4210 {
4211 it->slice.width = XCAR (tem);
4212 if (tem = XCDR (tem), CONSP (tem))
4213 it->slice.height = XCAR (tem);
4214 }
4215 }
4216 }
4217
4218 return 0;
4219 }
4220
4221 /* Handle `(raise FACTOR)'. */
4222 if (CONSP (spec)
4223 && EQ (XCAR (spec), Qraise)
4224 && CONSP (XCDR (spec)))
4225 {
4226 if (!FRAME_WINDOW_P (it->f))
4227 return 0;
4228
4229 #ifdef HAVE_WINDOW_SYSTEM
4230 value = XCAR (XCDR (spec));
4231 if (NUMBERP (value))
4232 {
4233 struct face *face = FACE_FROM_ID (it->f, it->face_id);
4234 it->voffset = - (XFLOATINT (value)
4235 * (FONT_HEIGHT (face->font)));
4236 }
4237 #endif /* HAVE_WINDOW_SYSTEM */
4238
4239 return 0;
4240 }
4241
4242 /* Don't handle the other kinds of display specifications
4243 inside a string that we got from a `display' property. */
4244 if (it->string_from_display_prop_p)
4245 return 0;
4246
4247 /* Characters having this form of property are not displayed, so
4248 we have to find the end of the property. */
4249 start_pos = *position;
4250 *position = display_prop_end (it, object, start_pos);
4251 value = Qnil;
4252
4253 /* Stop the scan at that end position--we assume that all
4254 text properties change there. */
4255 it->stop_charpos = position->charpos;
4256
4257 /* Handle `(left-fringe BITMAP [FACE])'
4258 and `(right-fringe BITMAP [FACE])'. */
4259 if (CONSP (spec)
4260 && (EQ (XCAR (spec), Qleft_fringe)
4261 || EQ (XCAR (spec), Qright_fringe))
4262 && CONSP (XCDR (spec)))
4263 {
4264 int face_id = lookup_basic_face (it->f, DEFAULT_FACE_ID);
4265 int fringe_bitmap;
4266
4267 if (!FRAME_WINDOW_P (it->f))
4268 /* If we return here, POSITION has been advanced
4269 across the text with this property. */
4270 return 0;
4271
4272 #ifdef HAVE_WINDOW_SYSTEM
4273 value = XCAR (XCDR (spec));
4274 if (!SYMBOLP (value)
4275 || !(fringe_bitmap = lookup_fringe_bitmap (value)))
4276 /* If we return here, POSITION has been advanced
4277 across the text with this property. */
4278 return 0;
4279
4280 if (CONSP (XCDR (XCDR (spec))))
4281 {
4282 Lisp_Object face_name = XCAR (XCDR (XCDR (spec)));
4283 int face_id2 = lookup_derived_face (it->f, face_name,
4284 FRINGE_FACE_ID, 0);
4285 if (face_id2 >= 0)
4286 face_id = face_id2;
4287 }
4288
4289 /* Save current settings of IT so that we can restore them
4290 when we are finished with the glyph property value. */
4291
4292 save_pos = it->position;
4293 it->position = *position;
4294 push_it (it);
4295 it->position = save_pos;
4296
4297 it->area = TEXT_AREA;
4298 it->what = IT_IMAGE;
4299 it->image_id = -1; /* no image */
4300 it->position = start_pos;
4301 it->object = NILP (object) ? it->w->buffer : object;
4302 it->method = GET_FROM_IMAGE;
4303 it->from_overlay = Qnil;
4304 it->face_id = face_id;
4305
4306 /* Say that we haven't consumed the characters with
4307 `display' property yet. The call to pop_it in
4308 set_iterator_to_next will clean this up. */
4309 *position = start_pos;
4310
4311 if (EQ (XCAR (spec), Qleft_fringe))
4312 {
4313 it->left_user_fringe_bitmap = fringe_bitmap;
4314 it->left_user_fringe_face_id = face_id;
4315 }
4316 else
4317 {
4318 it->right_user_fringe_bitmap = fringe_bitmap;
4319 it->right_user_fringe_face_id = face_id;
4320 }
4321 #endif /* HAVE_WINDOW_SYSTEM */
4322 return 1;
4323 }
4324
4325 /* Prepare to handle `((margin left-margin) ...)',
4326 `((margin right-margin) ...)' and `((margin nil) ...)'
4327 prefixes for display specifications. */
4328 location = Qunbound;
4329 if (CONSP (spec) && CONSP (XCAR (spec)))
4330 {
4331 Lisp_Object tem;
4332
4333 value = XCDR (spec);
4334 if (CONSP (value))
4335 value = XCAR (value);
4336
4337 tem = XCAR (spec);
4338 if (EQ (XCAR (tem), Qmargin)
4339 && (tem = XCDR (tem),
4340 tem = CONSP (tem) ? XCAR (tem) : Qnil,
4341 (NILP (tem)
4342 || EQ (tem, Qleft_margin)
4343 || EQ (tem, Qright_margin))))
4344 location = tem;
4345 }
4346
4347 if (EQ (location, Qunbound))
4348 {
4349 location = Qnil;
4350 value = spec;
4351 }
4352
4353 /* After this point, VALUE is the property after any
4354 margin prefix has been stripped. It must be a string,
4355 an image specification, or `(space ...)'.
4356
4357 LOCATION specifies where to display: `left-margin',
4358 `right-margin' or nil. */
4359
4360 valid_p = (STRINGP (value)
4361 #ifdef HAVE_WINDOW_SYSTEM
4362 || (FRAME_WINDOW_P (it->f) && valid_image_p (value))
4363 #endif /* not HAVE_WINDOW_SYSTEM */
4364 || (CONSP (value) && EQ (XCAR (value), Qspace)));
4365
4366 if (valid_p && !display_replaced_before_p)
4367 {
4368 /* Save current settings of IT so that we can restore them
4369 when we are finished with the glyph property value. */
4370 save_pos = it->position;
4371 it->position = *position;
4372 push_it (it);
4373 it->position = save_pos;
4374 it->from_overlay = overlay;
4375
4376 if (NILP (location))
4377 it->area = TEXT_AREA;
4378 else if (EQ (location, Qleft_margin))
4379 it->area = LEFT_MARGIN_AREA;
4380 else
4381 it->area = RIGHT_MARGIN_AREA;
4382
4383 if (STRINGP (value))
4384 {
4385 it->string = value;
4386 it->multibyte_p = STRING_MULTIBYTE (it->string);
4387 it->current.overlay_string_index = -1;
4388 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
4389 it->end_charpos = it->string_nchars = SCHARS (it->string);
4390 it->method = GET_FROM_STRING;
4391 it->stop_charpos = 0;
4392 it->string_from_display_prop_p = 1;
4393 /* Say that we haven't consumed the characters with
4394 `display' property yet. The call to pop_it in
4395 set_iterator_to_next will clean this up. */
4396 if (BUFFERP (object))
4397 *position = start_pos;
4398 }
4399 else if (CONSP (value) && EQ (XCAR (value), Qspace))
4400 {
4401 it->method = GET_FROM_STRETCH;
4402 it->object = value;
4403 *position = it->position = start_pos;
4404 }
4405 #ifdef HAVE_WINDOW_SYSTEM
4406 else
4407 {
4408 it->what = IT_IMAGE;
4409 it->image_id = lookup_image (it->f, value);
4410 it->position = start_pos;
4411 it->object = NILP (object) ? it->w->buffer : object;
4412 it->method = GET_FROM_IMAGE;
4413
4414 /* Say that we haven't consumed the characters with
4415 `display' property yet. The call to pop_it in
4416 set_iterator_to_next will clean this up. */
4417 *position = start_pos;
4418 }
4419 #endif /* HAVE_WINDOW_SYSTEM */
4420
4421 return 1;
4422 }
4423
4424 /* Invalid property or property not supported. Restore
4425 POSITION to what it was before. */
4426 *position = start_pos;
4427 return 0;
4428 }
4429
4430
4431 /* Check if SPEC is a display sub-property value whose text should be
4432 treated as intangible. */
4433
4434 static int
4435 single_display_spec_intangible_p (Lisp_Object prop)
4436 {
4437 /* Skip over `when FORM'. */
4438 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
4439 {
4440 prop = XCDR (prop);
4441 if (!CONSP (prop))
4442 return 0;
4443 prop = XCDR (prop);
4444 }
4445
4446 if (STRINGP (prop))
4447 return 1;
4448
4449 if (!CONSP (prop))
4450 return 0;
4451
4452 /* Skip over `margin LOCATION'. If LOCATION is in the margins,
4453 we don't need to treat text as intangible. */
4454 if (EQ (XCAR (prop), Qmargin))
4455 {
4456 prop = XCDR (prop);
4457 if (!CONSP (prop))
4458 return 0;
4459
4460 prop = XCDR (prop);
4461 if (!CONSP (prop)
4462 || EQ (XCAR (prop), Qleft_margin)
4463 || EQ (XCAR (prop), Qright_margin))
4464 return 0;
4465 }
4466
4467 return (CONSP (prop)
4468 && (EQ (XCAR (prop), Qimage)
4469 || EQ (XCAR (prop), Qspace)));
4470 }
4471
4472
4473 /* Check if PROP is a display property value whose text should be
4474 treated as intangible. */
4475
4476 int
4477 display_prop_intangible_p (Lisp_Object prop)
4478 {
4479 if (CONSP (prop)
4480 && CONSP (XCAR (prop))
4481 && !EQ (Qmargin, XCAR (XCAR (prop))))
4482 {
4483 /* A list of sub-properties. */
4484 while (CONSP (prop))
4485 {
4486 if (single_display_spec_intangible_p (XCAR (prop)))
4487 return 1;
4488 prop = XCDR (prop);
4489 }
4490 }
4491 else if (VECTORP (prop))
4492 {
4493 /* A vector of sub-properties. */
4494 int i;
4495 for (i = 0; i < ASIZE (prop); ++i)
4496 if (single_display_spec_intangible_p (AREF (prop, i)))
4497 return 1;
4498 }
4499 else
4500 return single_display_spec_intangible_p (prop);
4501
4502 return 0;
4503 }
4504
4505
4506 /* Return 1 if PROP is a display sub-property value containing STRING. */
4507
4508 static int
4509 single_display_spec_string_p (Lisp_Object prop, Lisp_Object string)
4510 {
4511 if (EQ (string, prop))
4512 return 1;
4513
4514 /* Skip over `when FORM'. */
4515 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
4516 {
4517 prop = XCDR (prop);
4518 if (!CONSP (prop))
4519 return 0;
4520 prop = XCDR (prop);
4521 }
4522
4523 if (CONSP (prop))
4524 /* Skip over `margin LOCATION'. */
4525 if (EQ (XCAR (prop), Qmargin))
4526 {
4527 prop = XCDR (prop);
4528 if (!CONSP (prop))
4529 return 0;
4530
4531 prop = XCDR (prop);
4532 if (!CONSP (prop))
4533 return 0;
4534 }
4535
4536 return CONSP (prop) && EQ (XCAR (prop), string);
4537 }
4538
4539
4540 /* Return 1 if STRING appears in the `display' property PROP. */
4541
4542 static int
4543 display_prop_string_p (Lisp_Object prop, Lisp_Object string)
4544 {
4545 if (CONSP (prop)
4546 && CONSP (XCAR (prop))
4547 && !EQ (Qmargin, XCAR (XCAR (prop))))
4548 {
4549 /* A list of sub-properties. */
4550 while (CONSP (prop))
4551 {
4552 if (single_display_spec_string_p (XCAR (prop), string))
4553 return 1;
4554 prop = XCDR (prop);
4555 }
4556 }
4557 else if (VECTORP (prop))
4558 {
4559 /* A vector of sub-properties. */
4560 int i;
4561 for (i = 0; i < ASIZE (prop); ++i)
4562 if (single_display_spec_string_p (AREF (prop, i), string))
4563 return 1;
4564 }
4565 else
4566 return single_display_spec_string_p (prop, string);
4567
4568 return 0;
4569 }
4570
4571 /* Look for STRING in overlays and text properties in W's buffer,
4572 between character positions FROM and TO (excluding TO).
4573 BACK_P non-zero means look back (in this case, TO is supposed to be
4574 less than FROM).
4575 Value is the first character position where STRING was found, or
4576 zero if it wasn't found before hitting TO.
4577
4578 W's buffer must be current.
4579
4580 This function may only use code that doesn't eval because it is
4581 called asynchronously from note_mouse_highlight. */
4582
4583 static EMACS_INT
4584 string_buffer_position_lim (struct window *w, Lisp_Object string,
4585 EMACS_INT from, EMACS_INT to, int back_p)
4586 {
4587 Lisp_Object limit, prop, pos;
4588 int found = 0;
4589
4590 pos = make_number (from);
4591
4592 if (!back_p) /* looking forward */
4593 {
4594 limit = make_number (min (to, ZV));
4595 while (!found && !EQ (pos, limit))
4596 {
4597 prop = Fget_char_property (pos, Qdisplay, Qnil);
4598 if (!NILP (prop) && display_prop_string_p (prop, string))
4599 found = 1;
4600 else
4601 pos = Fnext_single_char_property_change (pos, Qdisplay, Qnil,
4602 limit);
4603 }
4604 }
4605 else /* looking back */
4606 {
4607 limit = make_number (max (to, BEGV));
4608 while (!found && !EQ (pos, limit))
4609 {
4610 prop = Fget_char_property (pos, Qdisplay, Qnil);
4611 if (!NILP (prop) && display_prop_string_p (prop, string))
4612 found = 1;
4613 else
4614 pos = Fprevious_single_char_property_change (pos, Qdisplay, Qnil,
4615 limit);
4616 }
4617 }
4618
4619 return found ? XINT (pos) : 0;
4620 }
4621
4622 /* Determine which buffer position in W's buffer STRING comes from.
4623 AROUND_CHARPOS is an approximate position where it could come from.
4624 Value is the buffer position or 0 if it couldn't be determined.
4625
4626 W's buffer must be current.
4627
4628 This function is necessary because we don't record buffer positions
4629 in glyphs generated from strings (to keep struct glyph small).
4630 This function may only use code that doesn't eval because it is
4631 called asynchronously from note_mouse_highlight. */
4632
4633 EMACS_INT
4634 string_buffer_position (struct window *w, Lisp_Object string, EMACS_INT around_charpos)
4635 {
4636 Lisp_Object limit, prop, pos;
4637 const int MAX_DISTANCE = 1000;
4638 EMACS_INT found = string_buffer_position_lim (w, string, around_charpos,
4639 around_charpos + MAX_DISTANCE,
4640 0);
4641
4642 if (!found)
4643 found = string_buffer_position_lim (w, string, around_charpos,
4644 around_charpos - MAX_DISTANCE, 1);
4645 return found;
4646 }
4647
4648
4649 \f
4650 /***********************************************************************
4651 `composition' property
4652 ***********************************************************************/
4653
4654 /* Set up iterator IT from `composition' property at its current
4655 position. Called from handle_stop. */
4656
4657 static enum prop_handled
4658 handle_composition_prop (struct it *it)
4659 {
4660 Lisp_Object prop, string;
4661 EMACS_INT pos, pos_byte, start, end;
4662
4663 if (STRINGP (it->string))
4664 {
4665 unsigned char *s;
4666
4667 pos = IT_STRING_CHARPOS (*it);
4668 pos_byte = IT_STRING_BYTEPOS (*it);
4669 string = it->string;
4670 s = SDATA (string) + pos_byte;
4671 it->c = STRING_CHAR (s);
4672 }
4673 else
4674 {
4675 pos = IT_CHARPOS (*it);
4676 pos_byte = IT_BYTEPOS (*it);
4677 string = Qnil;
4678 it->c = FETCH_CHAR (pos_byte);
4679 }
4680
4681 /* If there's a valid composition and point is not inside of the
4682 composition (in the case that the composition is from the current
4683 buffer), draw a glyph composed from the composition components. */
4684 if (find_composition (pos, -1, &start, &end, &prop, string)
4685 && COMPOSITION_VALID_P (start, end, prop)
4686 && (STRINGP (it->string) || (PT <= start || PT >= end)))
4687 {
4688 if (start != pos)
4689 {
4690 if (STRINGP (it->string))
4691 pos_byte = string_char_to_byte (it->string, start);
4692 else
4693 pos_byte = CHAR_TO_BYTE (start);
4694 }
4695 it->cmp_it.id = get_composition_id (start, pos_byte, end - start,
4696 prop, string);
4697
4698 if (it->cmp_it.id >= 0)
4699 {
4700 it->cmp_it.ch = -1;
4701 it->cmp_it.nchars = COMPOSITION_LENGTH (prop);
4702 it->cmp_it.nglyphs = -1;
4703 }
4704 }
4705
4706 return HANDLED_NORMALLY;
4707 }
4708
4709
4710 \f
4711 /***********************************************************************
4712 Overlay strings
4713 ***********************************************************************/
4714
4715 /* The following structure is used to record overlay strings for
4716 later sorting in load_overlay_strings. */
4717
4718 struct overlay_entry
4719 {
4720 Lisp_Object overlay;
4721 Lisp_Object string;
4722 int priority;
4723 int after_string_p;
4724 };
4725
4726
4727 /* Set up iterator IT from overlay strings at its current position.
4728 Called from handle_stop. */
4729
4730 static enum prop_handled
4731 handle_overlay_change (struct it *it)
4732 {
4733 if (!STRINGP (it->string) && get_overlay_strings (it, 0))
4734 return HANDLED_RECOMPUTE_PROPS;
4735 else
4736 return HANDLED_NORMALLY;
4737 }
4738
4739
4740 /* Set up the next overlay string for delivery by IT, if there is an
4741 overlay string to deliver. Called by set_iterator_to_next when the
4742 end of the current overlay string is reached. If there are more
4743 overlay strings to display, IT->string and
4744 IT->current.overlay_string_index are set appropriately here.
4745 Otherwise IT->string is set to nil. */
4746
4747 static void
4748 next_overlay_string (struct it *it)
4749 {
4750 ++it->current.overlay_string_index;
4751 if (it->current.overlay_string_index == it->n_overlay_strings)
4752 {
4753 /* No more overlay strings. Restore IT's settings to what
4754 they were before overlay strings were processed, and
4755 continue to deliver from current_buffer. */
4756
4757 it->ellipsis_p = (it->stack[it->sp - 1].display_ellipsis_p != 0);
4758 pop_it (it);
4759 xassert (it->sp > 0
4760 || (NILP (it->string)
4761 && it->method == GET_FROM_BUFFER
4762 && it->stop_charpos >= BEGV
4763 && it->stop_charpos <= it->end_charpos));
4764 it->current.overlay_string_index = -1;
4765 it->n_overlay_strings = 0;
4766
4767 /* If we're at the end of the buffer, record that we have
4768 processed the overlay strings there already, so that
4769 next_element_from_buffer doesn't try it again. */
4770 if (NILP (it->string) && IT_CHARPOS (*it) >= it->end_charpos)
4771 it->overlay_strings_at_end_processed_p = 1;
4772 }
4773 else
4774 {
4775 /* There are more overlay strings to process. If
4776 IT->current.overlay_string_index has advanced to a position
4777 where we must load IT->overlay_strings with more strings, do
4778 it. */
4779 int i = it->current.overlay_string_index % OVERLAY_STRING_CHUNK_SIZE;
4780
4781 if (it->current.overlay_string_index && i == 0)
4782 load_overlay_strings (it, 0);
4783
4784 /* Initialize IT to deliver display elements from the overlay
4785 string. */
4786 it->string = it->overlay_strings[i];
4787 it->multibyte_p = STRING_MULTIBYTE (it->string);
4788 SET_TEXT_POS (it->current.string_pos, 0, 0);
4789 it->method = GET_FROM_STRING;
4790 it->stop_charpos = 0;
4791 if (it->cmp_it.stop_pos >= 0)
4792 it->cmp_it.stop_pos = 0;
4793 }
4794
4795 CHECK_IT (it);
4796 }
4797
4798
4799 /* Compare two overlay_entry structures E1 and E2. Used as a
4800 comparison function for qsort in load_overlay_strings. Overlay
4801 strings for the same position are sorted so that
4802
4803 1. All after-strings come in front of before-strings, except
4804 when they come from the same overlay.
4805
4806 2. Within after-strings, strings are sorted so that overlay strings
4807 from overlays with higher priorities come first.
4808
4809 2. Within before-strings, strings are sorted so that overlay
4810 strings from overlays with higher priorities come last.
4811
4812 Value is analogous to strcmp. */
4813
4814
4815 static int
4816 compare_overlay_entries (const void *e1, const void *e2)
4817 {
4818 struct overlay_entry *entry1 = (struct overlay_entry *) e1;
4819 struct overlay_entry *entry2 = (struct overlay_entry *) e2;
4820 int result;
4821
4822 if (entry1->after_string_p != entry2->after_string_p)
4823 {
4824 /* Let after-strings appear in front of before-strings if
4825 they come from different overlays. */
4826 if (EQ (entry1->overlay, entry2->overlay))
4827 result = entry1->after_string_p ? 1 : -1;
4828 else
4829 result = entry1->after_string_p ? -1 : 1;
4830 }
4831 else if (entry1->after_string_p)
4832 /* After-strings sorted in order of decreasing priority. */
4833 result = entry2->priority - entry1->priority;
4834 else
4835 /* Before-strings sorted in order of increasing priority. */
4836 result = entry1->priority - entry2->priority;
4837
4838 return result;
4839 }
4840
4841
4842 /* Load the vector IT->overlay_strings with overlay strings from IT's
4843 current buffer position, or from CHARPOS if that is > 0. Set
4844 IT->n_overlays to the total number of overlay strings found.
4845
4846 Overlay strings are processed OVERLAY_STRING_CHUNK_SIZE strings at
4847 a time. On entry into load_overlay_strings,
4848 IT->current.overlay_string_index gives the number of overlay
4849 strings that have already been loaded by previous calls to this
4850 function.
4851
4852 IT->add_overlay_start contains an additional overlay start
4853 position to consider for taking overlay strings from, if non-zero.
4854 This position comes into play when the overlay has an `invisible'
4855 property, and both before and after-strings. When we've skipped to
4856 the end of the overlay, because of its `invisible' property, we
4857 nevertheless want its before-string to appear.
4858 IT->add_overlay_start will contain the overlay start position
4859 in this case.
4860
4861 Overlay strings are sorted so that after-string strings come in
4862 front of before-string strings. Within before and after-strings,
4863 strings are sorted by overlay priority. See also function
4864 compare_overlay_entries. */
4865
4866 static void
4867 load_overlay_strings (struct it *it, int charpos)
4868 {
4869 Lisp_Object overlay, window, str, invisible;
4870 struct Lisp_Overlay *ov;
4871 int start, end;
4872 int size = 20;
4873 int n = 0, i, j, invis_p;
4874 struct overlay_entry *entries
4875 = (struct overlay_entry *) alloca (size * sizeof *entries);
4876
4877 if (charpos <= 0)
4878 charpos = IT_CHARPOS (*it);
4879
4880 /* Append the overlay string STRING of overlay OVERLAY to vector
4881 `entries' which has size `size' and currently contains `n'
4882 elements. AFTER_P non-zero means STRING is an after-string of
4883 OVERLAY. */
4884 #define RECORD_OVERLAY_STRING(OVERLAY, STRING, AFTER_P) \
4885 do \
4886 { \
4887 Lisp_Object priority; \
4888 \
4889 if (n == size) \
4890 { \
4891 int new_size = 2 * size; \
4892 struct overlay_entry *old = entries; \
4893 entries = \
4894 (struct overlay_entry *) alloca (new_size \
4895 * sizeof *entries); \
4896 memcpy (entries, old, size * sizeof *entries); \
4897 size = new_size; \
4898 } \
4899 \
4900 entries[n].string = (STRING); \
4901 entries[n].overlay = (OVERLAY); \
4902 priority = Foverlay_get ((OVERLAY), Qpriority); \
4903 entries[n].priority = INTEGERP (priority) ? XINT (priority) : 0; \
4904 entries[n].after_string_p = (AFTER_P); \
4905 ++n; \
4906 } \
4907 while (0)
4908
4909 /* Process overlay before the overlay center. */
4910 for (ov = current_buffer->overlays_before; ov; ov = ov->next)
4911 {
4912 XSETMISC (overlay, ov);
4913 xassert (OVERLAYP (overlay));
4914 start = OVERLAY_POSITION (OVERLAY_START (overlay));
4915 end = OVERLAY_POSITION (OVERLAY_END (overlay));
4916
4917 if (end < charpos)
4918 break;
4919
4920 /* Skip this overlay if it doesn't start or end at IT's current
4921 position. */
4922 if (end != charpos && start != charpos)
4923 continue;
4924
4925 /* Skip this overlay if it doesn't apply to IT->w. */
4926 window = Foverlay_get (overlay, Qwindow);
4927 if (WINDOWP (window) && XWINDOW (window) != it->w)
4928 continue;
4929
4930 /* If the text ``under'' the overlay is invisible, both before-
4931 and after-strings from this overlay are visible; start and
4932 end position are indistinguishable. */
4933 invisible = Foverlay_get (overlay, Qinvisible);
4934 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
4935
4936 /* If overlay has a non-empty before-string, record it. */
4937 if ((start == charpos || (end == charpos && invis_p))
4938 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
4939 && SCHARS (str))
4940 RECORD_OVERLAY_STRING (overlay, str, 0);
4941
4942 /* If overlay has a non-empty after-string, record it. */
4943 if ((end == charpos || (start == charpos && invis_p))
4944 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
4945 && SCHARS (str))
4946 RECORD_OVERLAY_STRING (overlay, str, 1);
4947 }
4948
4949 /* Process overlays after the overlay center. */
4950 for (ov = current_buffer->overlays_after; ov; ov = ov->next)
4951 {
4952 XSETMISC (overlay, ov);
4953 xassert (OVERLAYP (overlay));
4954 start = OVERLAY_POSITION (OVERLAY_START (overlay));
4955 end = OVERLAY_POSITION (OVERLAY_END (overlay));
4956
4957 if (start > charpos)
4958 break;
4959
4960 /* Skip this overlay if it doesn't start or end at IT's current
4961 position. */
4962 if (end != charpos && start != charpos)
4963 continue;
4964
4965 /* Skip this overlay if it doesn't apply to IT->w. */
4966 window = Foverlay_get (overlay, Qwindow);
4967 if (WINDOWP (window) && XWINDOW (window) != it->w)
4968 continue;
4969
4970 /* If the text ``under'' the overlay is invisible, it has a zero
4971 dimension, and both before- and after-strings apply. */
4972 invisible = Foverlay_get (overlay, Qinvisible);
4973 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
4974
4975 /* If overlay has a non-empty before-string, record it. */
4976 if ((start == charpos || (end == charpos && invis_p))
4977 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
4978 && SCHARS (str))
4979 RECORD_OVERLAY_STRING (overlay, str, 0);
4980
4981 /* If overlay has a non-empty after-string, record it. */
4982 if ((end == charpos || (start == charpos && invis_p))
4983 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
4984 && SCHARS (str))
4985 RECORD_OVERLAY_STRING (overlay, str, 1);
4986 }
4987
4988 #undef RECORD_OVERLAY_STRING
4989
4990 /* Sort entries. */
4991 if (n > 1)
4992 qsort (entries, n, sizeof *entries, compare_overlay_entries);
4993
4994 /* Record the total number of strings to process. */
4995 it->n_overlay_strings = n;
4996
4997 /* IT->current.overlay_string_index is the number of overlay strings
4998 that have already been consumed by IT. Copy some of the
4999 remaining overlay strings to IT->overlay_strings. */
5000 i = 0;
5001 j = it->current.overlay_string_index;
5002 while (i < OVERLAY_STRING_CHUNK_SIZE && j < n)
5003 {
5004 it->overlay_strings[i] = entries[j].string;
5005 it->string_overlays[i++] = entries[j++].overlay;
5006 }
5007
5008 CHECK_IT (it);
5009 }
5010
5011
5012 /* Get the first chunk of overlay strings at IT's current buffer
5013 position, or at CHARPOS if that is > 0. Value is non-zero if at
5014 least one overlay string was found. */
5015
5016 static int
5017 get_overlay_strings_1 (struct it *it, int charpos, int compute_stop_p)
5018 {
5019 /* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to
5020 process. This fills IT->overlay_strings with strings, and sets
5021 IT->n_overlay_strings to the total number of strings to process.
5022 IT->pos.overlay_string_index has to be set temporarily to zero
5023 because load_overlay_strings needs this; it must be set to -1
5024 when no overlay strings are found because a zero value would
5025 indicate a position in the first overlay string. */
5026 it->current.overlay_string_index = 0;
5027 load_overlay_strings (it, charpos);
5028
5029 /* If we found overlay strings, set up IT to deliver display
5030 elements from the first one. Otherwise set up IT to deliver
5031 from current_buffer. */
5032 if (it->n_overlay_strings)
5033 {
5034 /* Make sure we know settings in current_buffer, so that we can
5035 restore meaningful values when we're done with the overlay
5036 strings. */
5037 if (compute_stop_p)
5038 compute_stop_pos (it);
5039 xassert (it->face_id >= 0);
5040
5041 /* Save IT's settings. They are restored after all overlay
5042 strings have been processed. */
5043 xassert (!compute_stop_p || it->sp == 0);
5044
5045 /* When called from handle_stop, there might be an empty display
5046 string loaded. In that case, don't bother saving it. */
5047 if (!STRINGP (it->string) || SCHARS (it->string))
5048 push_it (it);
5049
5050 /* Set up IT to deliver display elements from the first overlay
5051 string. */
5052 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
5053 it->string = it->overlay_strings[0];
5054 it->from_overlay = Qnil;
5055 it->stop_charpos = 0;
5056 xassert (STRINGP (it->string));
5057 it->end_charpos = SCHARS (it->string);
5058 it->multibyte_p = STRING_MULTIBYTE (it->string);
5059 it->method = GET_FROM_STRING;
5060 return 1;
5061 }
5062
5063 it->current.overlay_string_index = -1;
5064 return 0;
5065 }
5066
5067 static int
5068 get_overlay_strings (struct it *it, int charpos)
5069 {
5070 it->string = Qnil;
5071 it->method = GET_FROM_BUFFER;
5072
5073 (void) get_overlay_strings_1 (it, charpos, 1);
5074
5075 CHECK_IT (it);
5076
5077 /* Value is non-zero if we found at least one overlay string. */
5078 return STRINGP (it->string);
5079 }
5080
5081
5082 \f
5083 /***********************************************************************
5084 Saving and restoring state
5085 ***********************************************************************/
5086
5087 /* Save current settings of IT on IT->stack. Called, for example,
5088 before setting up IT for an overlay string, to be able to restore
5089 IT's settings to what they were after the overlay string has been
5090 processed. */
5091
5092 static void
5093 push_it (struct it *it)
5094 {
5095 struct iterator_stack_entry *p;
5096
5097 xassert (it->sp < IT_STACK_SIZE);
5098 p = it->stack + it->sp;
5099
5100 p->stop_charpos = it->stop_charpos;
5101 p->prev_stop = it->prev_stop;
5102 p->base_level_stop = it->base_level_stop;
5103 p->cmp_it = it->cmp_it;
5104 xassert (it->face_id >= 0);
5105 p->face_id = it->face_id;
5106 p->string = it->string;
5107 p->method = it->method;
5108 p->from_overlay = it->from_overlay;
5109 switch (p->method)
5110 {
5111 case GET_FROM_IMAGE:
5112 p->u.image.object = it->object;
5113 p->u.image.image_id = it->image_id;
5114 p->u.image.slice = it->slice;
5115 break;
5116 case GET_FROM_STRETCH:
5117 p->u.stretch.object = it->object;
5118 break;
5119 }
5120 p->position = it->position;
5121 p->current = it->current;
5122 p->end_charpos = it->end_charpos;
5123 p->string_nchars = it->string_nchars;
5124 p->area = it->area;
5125 p->multibyte_p = it->multibyte_p;
5126 p->avoid_cursor_p = it->avoid_cursor_p;
5127 p->space_width = it->space_width;
5128 p->font_height = it->font_height;
5129 p->voffset = it->voffset;
5130 p->string_from_display_prop_p = it->string_from_display_prop_p;
5131 p->display_ellipsis_p = 0;
5132 p->line_wrap = it->line_wrap;
5133 ++it->sp;
5134 }
5135
5136 static void
5137 iterate_out_of_display_property (struct it *it)
5138 {
5139 /* Maybe initialize paragraph direction. If we are at the beginning
5140 of a new paragraph, next_element_from_buffer may not have a
5141 chance to do that. */
5142 if (it->bidi_it.first_elt && it->bidi_it.charpos < ZV)
5143 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it);
5144 /* prev_stop can be zero, so check against BEGV as well. */
5145 while (it->bidi_it.charpos >= BEGV
5146 && it->prev_stop <= it->bidi_it.charpos
5147 && it->bidi_it.charpos < CHARPOS (it->position))
5148 bidi_move_to_visually_next (&it->bidi_it);
5149 /* Record the stop_pos we just crossed, for when we cross it
5150 back, maybe. */
5151 if (it->bidi_it.charpos > CHARPOS (it->position))
5152 it->prev_stop = CHARPOS (it->position);
5153 /* If we ended up not where pop_it put us, resync IT's
5154 positional members with the bidi iterator. */
5155 if (it->bidi_it.charpos != CHARPOS (it->position))
5156 {
5157 SET_TEXT_POS (it->position,
5158 it->bidi_it.charpos, it->bidi_it.bytepos);
5159 it->current.pos = it->position;
5160 }
5161 }
5162
5163 /* Restore IT's settings from IT->stack. Called, for example, when no
5164 more overlay strings must be processed, and we return to delivering
5165 display elements from a buffer, or when the end of a string from a
5166 `display' property is reached and we return to delivering display
5167 elements from an overlay string, or from a buffer. */
5168
5169 static void
5170 pop_it (struct it *it)
5171 {
5172 struct iterator_stack_entry *p;
5173
5174 xassert (it->sp > 0);
5175 --it->sp;
5176 p = it->stack + it->sp;
5177 it->stop_charpos = p->stop_charpos;
5178 it->prev_stop = p->prev_stop;
5179 it->base_level_stop = p->base_level_stop;
5180 it->cmp_it = p->cmp_it;
5181 it->face_id = p->face_id;
5182 it->current = p->current;
5183 it->position = p->position;
5184 it->string = p->string;
5185 it->from_overlay = p->from_overlay;
5186 if (NILP (it->string))
5187 SET_TEXT_POS (it->current.string_pos, -1, -1);
5188 it->method = p->method;
5189 switch (it->method)
5190 {
5191 case GET_FROM_IMAGE:
5192 it->image_id = p->u.image.image_id;
5193 it->object = p->u.image.object;
5194 it->slice = p->u.image.slice;
5195 break;
5196 case GET_FROM_STRETCH:
5197 it->object = p->u.comp.object;
5198 break;
5199 case GET_FROM_BUFFER:
5200 it->object = it->w->buffer;
5201 if (it->bidi_p)
5202 {
5203 /* Bidi-iterate until we get out of the portion of text, if
5204 any, covered by a `display' text property or an overlay
5205 with `display' property. (We cannot just jump there,
5206 because the internal coherency of the bidi iterator state
5207 can not be preserved across such jumps.) We also must
5208 determine the paragraph base direction if the overlay we
5209 just processed is at the beginning of a new
5210 paragraph. */
5211 iterate_out_of_display_property (it);
5212 }
5213 break;
5214 case GET_FROM_STRING:
5215 it->object = it->string;
5216 break;
5217 case GET_FROM_DISPLAY_VECTOR:
5218 if (it->s)
5219 it->method = GET_FROM_C_STRING;
5220 else if (STRINGP (it->string))
5221 it->method = GET_FROM_STRING;
5222 else
5223 {
5224 it->method = GET_FROM_BUFFER;
5225 it->object = it->w->buffer;
5226 }
5227 }
5228 it->end_charpos = p->end_charpos;
5229 it->string_nchars = p->string_nchars;
5230 it->area = p->area;
5231 it->multibyte_p = p->multibyte_p;
5232 it->avoid_cursor_p = p->avoid_cursor_p;
5233 it->space_width = p->space_width;
5234 it->font_height = p->font_height;
5235 it->voffset = p->voffset;
5236 it->string_from_display_prop_p = p->string_from_display_prop_p;
5237 it->line_wrap = p->line_wrap;
5238 }
5239
5240
5241 \f
5242 /***********************************************************************
5243 Moving over lines
5244 ***********************************************************************/
5245
5246 /* Set IT's current position to the previous line start. */
5247
5248 static void
5249 back_to_previous_line_start (struct it *it)
5250 {
5251 IT_CHARPOS (*it) = find_next_newline_no_quit (IT_CHARPOS (*it) - 1, -1);
5252 IT_BYTEPOS (*it) = CHAR_TO_BYTE (IT_CHARPOS (*it));
5253 }
5254
5255
5256 /* Move IT to the next line start.
5257
5258 Value is non-zero if a newline was found. Set *SKIPPED_P to 1 if
5259 we skipped over part of the text (as opposed to moving the iterator
5260 continuously over the text). Otherwise, don't change the value
5261 of *SKIPPED_P.
5262
5263 Newlines may come from buffer text, overlay strings, or strings
5264 displayed via the `display' property. That's the reason we can't
5265 simply use find_next_newline_no_quit.
5266
5267 Note that this function may not skip over invisible text that is so
5268 because of text properties and immediately follows a newline. If
5269 it would, function reseat_at_next_visible_line_start, when called
5270 from set_iterator_to_next, would effectively make invisible
5271 characters following a newline part of the wrong glyph row, which
5272 leads to wrong cursor motion. */
5273
5274 static int
5275 forward_to_next_line_start (struct it *it, int *skipped_p)
5276 {
5277 int old_selective, newline_found_p, n;
5278 const int MAX_NEWLINE_DISTANCE = 500;
5279
5280 /* If already on a newline, just consume it to avoid unintended
5281 skipping over invisible text below. */
5282 if (it->what == IT_CHARACTER
5283 && it->c == '\n'
5284 && CHARPOS (it->position) == IT_CHARPOS (*it))
5285 {
5286 set_iterator_to_next (it, 0);
5287 it->c = 0;
5288 return 1;
5289 }
5290
5291 /* Don't handle selective display in the following. It's (a)
5292 unnecessary because it's done by the caller, and (b) leads to an
5293 infinite recursion because next_element_from_ellipsis indirectly
5294 calls this function. */
5295 old_selective = it->selective;
5296 it->selective = 0;
5297
5298 /* Scan for a newline within MAX_NEWLINE_DISTANCE display elements
5299 from buffer text. */
5300 for (n = newline_found_p = 0;
5301 !newline_found_p && n < MAX_NEWLINE_DISTANCE;
5302 n += STRINGP (it->string) ? 0 : 1)
5303 {
5304 if (!get_next_display_element (it))
5305 return 0;
5306 newline_found_p = it->what == IT_CHARACTER && it->c == '\n';
5307 set_iterator_to_next (it, 0);
5308 }
5309
5310 /* If we didn't find a newline near enough, see if we can use a
5311 short-cut. */
5312 if (!newline_found_p)
5313 {
5314 int start = IT_CHARPOS (*it);
5315 int limit = find_next_newline_no_quit (start, 1);
5316 Lisp_Object pos;
5317
5318 xassert (!STRINGP (it->string));
5319
5320 /* If there isn't any `display' property in sight, and no
5321 overlays, we can just use the position of the newline in
5322 buffer text. */
5323 if (it->stop_charpos >= limit
5324 || ((pos = Fnext_single_property_change (make_number (start),
5325 Qdisplay,
5326 Qnil, make_number (limit)),
5327 NILP (pos))
5328 && next_overlay_change (start) == ZV))
5329 {
5330 IT_CHARPOS (*it) = limit;
5331 IT_BYTEPOS (*it) = CHAR_TO_BYTE (limit);
5332 *skipped_p = newline_found_p = 1;
5333 }
5334 else
5335 {
5336 while (get_next_display_element (it)
5337 && !newline_found_p)
5338 {
5339 newline_found_p = ITERATOR_AT_END_OF_LINE_P (it);
5340 set_iterator_to_next (it, 0);
5341 }
5342 }
5343 }
5344
5345 it->selective = old_selective;
5346 return newline_found_p;
5347 }
5348
5349
5350 /* Set IT's current position to the previous visible line start. Skip
5351 invisible text that is so either due to text properties or due to
5352 selective display. Caution: this does not change IT->current_x and
5353 IT->hpos. */
5354
5355 static void
5356 back_to_previous_visible_line_start (struct it *it)
5357 {
5358 while (IT_CHARPOS (*it) > BEGV)
5359 {
5360 back_to_previous_line_start (it);
5361
5362 if (IT_CHARPOS (*it) <= BEGV)
5363 break;
5364
5365 /* If selective > 0, then lines indented more than its value are
5366 invisible. */
5367 if (it->selective > 0
5368 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
5369 (double) it->selective)) /* iftc */
5370 continue;
5371
5372 /* Check the newline before point for invisibility. */
5373 {
5374 Lisp_Object prop;
5375 prop = Fget_char_property (make_number (IT_CHARPOS (*it) - 1),
5376 Qinvisible, it->window);
5377 if (TEXT_PROP_MEANS_INVISIBLE (prop))
5378 continue;
5379 }
5380
5381 if (IT_CHARPOS (*it) <= BEGV)
5382 break;
5383
5384 {
5385 struct it it2;
5386 int pos;
5387 EMACS_INT beg, end;
5388 Lisp_Object val, overlay;
5389
5390 /* If newline is part of a composition, continue from start of composition */
5391 if (find_composition (IT_CHARPOS (*it), -1, &beg, &end, &val, Qnil)
5392 && beg < IT_CHARPOS (*it))
5393 goto replaced;
5394
5395 /* If newline is replaced by a display property, find start of overlay
5396 or interval and continue search from that point. */
5397 it2 = *it;
5398 pos = --IT_CHARPOS (it2);
5399 --IT_BYTEPOS (it2);
5400 it2.sp = 0;
5401 it2.string_from_display_prop_p = 0;
5402 if (handle_display_prop (&it2) == HANDLED_RETURN
5403 && !NILP (val = get_char_property_and_overlay
5404 (make_number (pos), Qdisplay, Qnil, &overlay))
5405 && (OVERLAYP (overlay)
5406 ? (beg = OVERLAY_POSITION (OVERLAY_START (overlay)))
5407 : get_property_and_range (pos, Qdisplay, &val, &beg, &end, Qnil)))
5408 goto replaced;
5409
5410 /* Newline is not replaced by anything -- so we are done. */
5411 break;
5412
5413 replaced:
5414 if (beg < BEGV)
5415 beg = BEGV;
5416 IT_CHARPOS (*it) = beg;
5417 IT_BYTEPOS (*it) = buf_charpos_to_bytepos (current_buffer, beg);
5418 }
5419 }
5420
5421 it->continuation_lines_width = 0;
5422
5423 xassert (IT_CHARPOS (*it) >= BEGV);
5424 xassert (IT_CHARPOS (*it) == BEGV
5425 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
5426 CHECK_IT (it);
5427 }
5428
5429
5430 /* Reseat iterator IT at the previous visible line start. Skip
5431 invisible text that is so either due to text properties or due to
5432 selective display. At the end, update IT's overlay information,
5433 face information etc. */
5434
5435 void
5436 reseat_at_previous_visible_line_start (struct it *it)
5437 {
5438 back_to_previous_visible_line_start (it);
5439 reseat (it, it->current.pos, 1);
5440 CHECK_IT (it);
5441 }
5442
5443
5444 /* Reseat iterator IT on the next visible line start in the current
5445 buffer. ON_NEWLINE_P non-zero means position IT on the newline
5446 preceding the line start. Skip over invisible text that is so
5447 because of selective display. Compute faces, overlays etc at the
5448 new position. Note that this function does not skip over text that
5449 is invisible because of text properties. */
5450
5451 static void
5452 reseat_at_next_visible_line_start (struct it *it, int on_newline_p)
5453 {
5454 int newline_found_p, skipped_p = 0;
5455
5456 newline_found_p = forward_to_next_line_start (it, &skipped_p);
5457
5458 /* Skip over lines that are invisible because they are indented
5459 more than the value of IT->selective. */
5460 if (it->selective > 0)
5461 while (IT_CHARPOS (*it) < ZV
5462 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
5463 (double) it->selective)) /* iftc */
5464 {
5465 xassert (IT_BYTEPOS (*it) == BEGV
5466 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
5467 newline_found_p = forward_to_next_line_start (it, &skipped_p);
5468 }
5469
5470 /* Position on the newline if that's what's requested. */
5471 if (on_newline_p && newline_found_p)
5472 {
5473 if (STRINGP (it->string))
5474 {
5475 if (IT_STRING_CHARPOS (*it) > 0)
5476 {
5477 --IT_STRING_CHARPOS (*it);
5478 --IT_STRING_BYTEPOS (*it);
5479 }
5480 }
5481 else if (IT_CHARPOS (*it) > BEGV)
5482 {
5483 --IT_CHARPOS (*it);
5484 --IT_BYTEPOS (*it);
5485 reseat (it, it->current.pos, 0);
5486 }
5487 }
5488 else if (skipped_p)
5489 reseat (it, it->current.pos, 0);
5490
5491 CHECK_IT (it);
5492 }
5493
5494
5495 \f
5496 /***********************************************************************
5497 Changing an iterator's position
5498 ***********************************************************************/
5499
5500 /* Change IT's current position to POS in current_buffer. If FORCE_P
5501 is non-zero, always check for text properties at the new position.
5502 Otherwise, text properties are only looked up if POS >=
5503 IT->check_charpos of a property. */
5504
5505 static void
5506 reseat (struct it *it, struct text_pos pos, int force_p)
5507 {
5508 int original_pos = IT_CHARPOS (*it);
5509
5510 reseat_1 (it, pos, 0);
5511
5512 /* Determine where to check text properties. Avoid doing it
5513 where possible because text property lookup is very expensive. */
5514 if (force_p
5515 || CHARPOS (pos) > it->stop_charpos
5516 || CHARPOS (pos) < original_pos)
5517 {
5518 if (it->bidi_p)
5519 {
5520 /* For bidi iteration, we need to prime prev_stop and
5521 base_level_stop with our best estimations. */
5522 if (CHARPOS (pos) < it->prev_stop)
5523 {
5524 handle_stop_backwards (it, BEGV);
5525 if (CHARPOS (pos) < it->base_level_stop)
5526 it->base_level_stop = 0;
5527 }
5528 else if (CHARPOS (pos) > it->stop_charpos
5529 && it->stop_charpos >= BEGV)
5530 handle_stop_backwards (it, it->stop_charpos);
5531 else /* force_p */
5532 handle_stop (it);
5533 }
5534 else
5535 {
5536 handle_stop (it);
5537 it->prev_stop = it->base_level_stop = 0;
5538 }
5539
5540 }
5541
5542 CHECK_IT (it);
5543 }
5544
5545
5546 /* Change IT's buffer position to POS. SET_STOP_P non-zero means set
5547 IT->stop_pos to POS, also. */
5548
5549 static void
5550 reseat_1 (struct it *it, struct text_pos pos, int set_stop_p)
5551 {
5552 /* Don't call this function when scanning a C string. */
5553 xassert (it->s == NULL);
5554
5555 /* POS must be a reasonable value. */
5556 xassert (CHARPOS (pos) >= BEGV && CHARPOS (pos) <= ZV);
5557
5558 it->current.pos = it->position = pos;
5559 it->end_charpos = ZV;
5560 it->dpvec = NULL;
5561 it->current.dpvec_index = -1;
5562 it->current.overlay_string_index = -1;
5563 IT_STRING_CHARPOS (*it) = -1;
5564 IT_STRING_BYTEPOS (*it) = -1;
5565 it->string = Qnil;
5566 it->string_from_display_prop_p = 0;
5567 it->method = GET_FROM_BUFFER;
5568 it->object = it->w->buffer;
5569 it->area = TEXT_AREA;
5570 it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
5571 it->sp = 0;
5572 it->string_from_display_prop_p = 0;
5573 it->face_before_selective_p = 0;
5574 if (it->bidi_p)
5575 it->bidi_it.first_elt = 1;
5576
5577 if (set_stop_p)
5578 {
5579 it->stop_charpos = CHARPOS (pos);
5580 it->base_level_stop = CHARPOS (pos);
5581 }
5582 }
5583
5584
5585 /* Set up IT for displaying a string, starting at CHARPOS in window W.
5586 If S is non-null, it is a C string to iterate over. Otherwise,
5587 STRING gives a Lisp string to iterate over.
5588
5589 If PRECISION > 0, don't return more then PRECISION number of
5590 characters from the string.
5591
5592 If FIELD_WIDTH > 0, return padding spaces until FIELD_WIDTH
5593 characters have been returned. FIELD_WIDTH < 0 means an infinite
5594 field width.
5595
5596 MULTIBYTE = 0 means disable processing of multibyte characters,
5597 MULTIBYTE > 0 means enable it,
5598 MULTIBYTE < 0 means use IT->multibyte_p.
5599
5600 IT must be initialized via a prior call to init_iterator before
5601 calling this function. */
5602
5603 static void
5604 reseat_to_string (struct it *it, const unsigned char *s, Lisp_Object string,
5605 int charpos, int precision, int field_width, int multibyte)
5606 {
5607 /* No region in strings. */
5608 it->region_beg_charpos = it->region_end_charpos = -1;
5609
5610 /* No text property checks performed by default, but see below. */
5611 it->stop_charpos = -1;
5612
5613 /* Set iterator position and end position. */
5614 memset (&it->current, 0, sizeof it->current);
5615 it->current.overlay_string_index = -1;
5616 it->current.dpvec_index = -1;
5617 xassert (charpos >= 0);
5618
5619 /* If STRING is specified, use its multibyteness, otherwise use the
5620 setting of MULTIBYTE, if specified. */
5621 if (multibyte >= 0)
5622 it->multibyte_p = multibyte > 0;
5623
5624 if (s == NULL)
5625 {
5626 xassert (STRINGP (string));
5627 it->string = string;
5628 it->s = NULL;
5629 it->end_charpos = it->string_nchars = SCHARS (string);
5630 it->method = GET_FROM_STRING;
5631 it->current.string_pos = string_pos (charpos, string);
5632 }
5633 else
5634 {
5635 it->s = s;
5636 it->string = Qnil;
5637
5638 /* Note that we use IT->current.pos, not it->current.string_pos,
5639 for displaying C strings. */
5640 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
5641 if (it->multibyte_p)
5642 {
5643 it->current.pos = c_string_pos (charpos, s, 1);
5644 it->end_charpos = it->string_nchars = number_of_chars (s, 1);
5645 }
5646 else
5647 {
5648 IT_CHARPOS (*it) = IT_BYTEPOS (*it) = charpos;
5649 it->end_charpos = it->string_nchars = strlen (s);
5650 }
5651
5652 it->method = GET_FROM_C_STRING;
5653 }
5654
5655 /* PRECISION > 0 means don't return more than PRECISION characters
5656 from the string. */
5657 if (precision > 0 && it->end_charpos - charpos > precision)
5658 it->end_charpos = it->string_nchars = charpos + precision;
5659
5660 /* FIELD_WIDTH > 0 means pad with spaces until FIELD_WIDTH
5661 characters have been returned. FIELD_WIDTH == 0 means don't pad,
5662 FIELD_WIDTH < 0 means infinite field width. This is useful for
5663 padding with `-' at the end of a mode line. */
5664 if (field_width < 0)
5665 field_width = INFINITY;
5666 if (field_width > it->end_charpos - charpos)
5667 it->end_charpos = charpos + field_width;
5668
5669 /* Use the standard display table for displaying strings. */
5670 if (DISP_TABLE_P (Vstandard_display_table))
5671 it->dp = XCHAR_TABLE (Vstandard_display_table);
5672
5673 it->stop_charpos = charpos;
5674 if (s == NULL && it->multibyte_p)
5675 {
5676 EMACS_INT endpos = SCHARS (it->string);
5677 if (endpos > it->end_charpos)
5678 endpos = it->end_charpos;
5679 composition_compute_stop_pos (&it->cmp_it, charpos, -1, endpos,
5680 it->string);
5681 }
5682 CHECK_IT (it);
5683 }
5684
5685
5686 \f
5687 /***********************************************************************
5688 Iteration
5689 ***********************************************************************/
5690
5691 /* Map enum it_method value to corresponding next_element_from_* function. */
5692
5693 static int (* get_next_element[NUM_IT_METHODS]) (struct it *it) =
5694 {
5695 next_element_from_buffer,
5696 next_element_from_display_vector,
5697 next_element_from_string,
5698 next_element_from_c_string,
5699 next_element_from_image,
5700 next_element_from_stretch
5701 };
5702
5703 #define GET_NEXT_DISPLAY_ELEMENT(it) (*get_next_element[(it)->method]) (it)
5704
5705
5706 /* Return 1 iff a character at CHARPOS (and BYTEPOS) is composed
5707 (possibly with the following characters). */
5708
5709 #define CHAR_COMPOSED_P(IT,CHARPOS,BYTEPOS,END_CHARPOS) \
5710 ((IT)->cmp_it.id >= 0 \
5711 || ((IT)->cmp_it.stop_pos == (CHARPOS) \
5712 && composition_reseat_it (&(IT)->cmp_it, CHARPOS, BYTEPOS, \
5713 END_CHARPOS, (IT)->w, \
5714 FACE_FROM_ID ((IT)->f, (IT)->face_id), \
5715 (IT)->string)))
5716
5717
5718 /* Load IT's display element fields with information about the next
5719 display element from the current position of IT. Value is zero if
5720 end of buffer (or C string) is reached. */
5721
5722 static struct frame *last_escape_glyph_frame = NULL;
5723 static unsigned last_escape_glyph_face_id = (1 << FACE_ID_BITS);
5724 static int last_escape_glyph_merged_face_id = 0;
5725
5726 int
5727 get_next_display_element (struct it *it)
5728 {
5729 /* Non-zero means that we found a display element. Zero means that
5730 we hit the end of what we iterate over. Performance note: the
5731 function pointer `method' used here turns out to be faster than
5732 using a sequence of if-statements. */
5733 int success_p;
5734
5735 get_next:
5736 success_p = GET_NEXT_DISPLAY_ELEMENT (it);
5737
5738 if (it->what == IT_CHARACTER)
5739 {
5740 /* UAX#9, L4: "A character is depicted by a mirrored glyph if
5741 and only if (a) the resolved directionality of that character
5742 is R..." */
5743 /* FIXME: Do we need an exception for characters from display
5744 tables? */
5745 if (it->bidi_p && it->bidi_it.type == STRONG_R)
5746 it->c = bidi_mirror_char (it->c);
5747 /* Map via display table or translate control characters.
5748 IT->c, IT->len etc. have been set to the next character by
5749 the function call above. If we have a display table, and it
5750 contains an entry for IT->c, translate it. Don't do this if
5751 IT->c itself comes from a display table, otherwise we could
5752 end up in an infinite recursion. (An alternative could be to
5753 count the recursion depth of this function and signal an
5754 error when a certain maximum depth is reached.) Is it worth
5755 it? */
5756 if (success_p && it->dpvec == NULL)
5757 {
5758 Lisp_Object dv;
5759 struct charset *unibyte = CHARSET_FROM_ID (charset_unibyte);
5760 enum { char_is_other = 0, char_is_nbsp, char_is_soft_hyphen }
5761 nbsp_or_shy = char_is_other;
5762 int decoded = it->c;
5763
5764 if (it->dp
5765 && (dv = DISP_CHAR_VECTOR (it->dp, it->c),
5766 VECTORP (dv)))
5767 {
5768 struct Lisp_Vector *v = XVECTOR (dv);
5769
5770 /* Return the first character from the display table
5771 entry, if not empty. If empty, don't display the
5772 current character. */
5773 if (v->size)
5774 {
5775 it->dpvec_char_len = it->len;
5776 it->dpvec = v->contents;
5777 it->dpend = v->contents + v->size;
5778 it->current.dpvec_index = 0;
5779 it->dpvec_face_id = -1;
5780 it->saved_face_id = it->face_id;
5781 it->method = GET_FROM_DISPLAY_VECTOR;
5782 it->ellipsis_p = 0;
5783 }
5784 else
5785 {
5786 set_iterator_to_next (it, 0);
5787 }
5788 goto get_next;
5789 }
5790
5791 if (unibyte_display_via_language_environment
5792 && !ASCII_CHAR_P (it->c))
5793 decoded = DECODE_CHAR (unibyte, it->c);
5794
5795 if (it->c >= 0x80 && ! NILP (Vnobreak_char_display))
5796 {
5797 if (it->multibyte_p)
5798 nbsp_or_shy = (it->c == 0xA0 ? char_is_nbsp
5799 : it->c == 0xAD ? char_is_soft_hyphen
5800 : char_is_other);
5801 else if (unibyte_display_via_language_environment)
5802 nbsp_or_shy = (decoded == 0xA0 ? char_is_nbsp
5803 : decoded == 0xAD ? char_is_soft_hyphen
5804 : char_is_other);
5805 }
5806
5807 /* Translate control characters into `\003' or `^C' form.
5808 Control characters coming from a display table entry are
5809 currently not translated because we use IT->dpvec to hold
5810 the translation. This could easily be changed but I
5811 don't believe that it is worth doing.
5812
5813 If it->multibyte_p is nonzero, non-printable non-ASCII
5814 characters are also translated to octal form.
5815
5816 If it->multibyte_p is zero, eight-bit characters that
5817 don't have corresponding multibyte char code are also
5818 translated to octal form. */
5819 if ((it->c < ' '
5820 ? (it->area != TEXT_AREA
5821 /* In mode line, treat \n, \t like other crl chars. */
5822 || (it->c != '\t'
5823 && it->glyph_row
5824 && (it->glyph_row->mode_line_p || it->avoid_cursor_p))
5825 || (it->c != '\n' && it->c != '\t'))
5826 : (nbsp_or_shy
5827 || (it->multibyte_p
5828 ? ! CHAR_PRINTABLE_P (it->c)
5829 : (! unibyte_display_via_language_environment
5830 ? it->c >= 0x80
5831 : (decoded >= 0x80 && decoded < 0xA0))))))
5832 {
5833 /* IT->c is a control character which must be displayed
5834 either as '\003' or as `^C' where the '\\' and '^'
5835 can be defined in the display table. Fill
5836 IT->ctl_chars with glyphs for what we have to
5837 display. Then, set IT->dpvec to these glyphs. */
5838 Lisp_Object gc;
5839 int ctl_len;
5840 int face_id, lface_id = 0 ;
5841 int escape_glyph;
5842
5843 /* Handle control characters with ^. */
5844
5845 if (it->c < 128 && it->ctl_arrow_p)
5846 {
5847 int g;
5848
5849 g = '^'; /* default glyph for Control */
5850 /* Set IT->ctl_chars[0] to the glyph for `^'. */
5851 if (it->dp
5852 && (gc = DISP_CTRL_GLYPH (it->dp), GLYPH_CODE_P (gc))
5853 && GLYPH_CODE_CHAR_VALID_P (gc))
5854 {
5855 g = GLYPH_CODE_CHAR (gc);
5856 lface_id = GLYPH_CODE_FACE (gc);
5857 }
5858 if (lface_id)
5859 {
5860 face_id = merge_faces (it->f, Qt, lface_id, it->face_id);
5861 }
5862 else if (it->f == last_escape_glyph_frame
5863 && it->face_id == last_escape_glyph_face_id)
5864 {
5865 face_id = last_escape_glyph_merged_face_id;
5866 }
5867 else
5868 {
5869 /* Merge the escape-glyph face into the current face. */
5870 face_id = merge_faces (it->f, Qescape_glyph, 0,
5871 it->face_id);
5872 last_escape_glyph_frame = it->f;
5873 last_escape_glyph_face_id = it->face_id;
5874 last_escape_glyph_merged_face_id = face_id;
5875 }
5876
5877 XSETINT (it->ctl_chars[0], g);
5878 XSETINT (it->ctl_chars[1], it->c ^ 0100);
5879 ctl_len = 2;
5880 goto display_control;
5881 }
5882
5883 /* Handle non-break space in the mode where it only gets
5884 highlighting. */
5885
5886 if (EQ (Vnobreak_char_display, Qt)
5887 && nbsp_or_shy == char_is_nbsp)
5888 {
5889 /* Merge the no-break-space face into the current face. */
5890 face_id = merge_faces (it->f, Qnobreak_space, 0,
5891 it->face_id);
5892
5893 it->c = ' ';
5894 XSETINT (it->ctl_chars[0], ' ');
5895 ctl_len = 1;
5896 goto display_control;
5897 }
5898
5899 /* Handle sequences that start with the "escape glyph". */
5900
5901 /* the default escape glyph is \. */
5902 escape_glyph = '\\';
5903
5904 if (it->dp
5905 && (gc = DISP_ESCAPE_GLYPH (it->dp), GLYPH_CODE_P (gc))
5906 && GLYPH_CODE_CHAR_VALID_P (gc))
5907 {
5908 escape_glyph = GLYPH_CODE_CHAR (gc);
5909 lface_id = GLYPH_CODE_FACE (gc);
5910 }
5911 if (lface_id)
5912 {
5913 /* The display table specified a face.
5914 Merge it into face_id and also into escape_glyph. */
5915 face_id = merge_faces (it->f, Qt, lface_id,
5916 it->face_id);
5917 }
5918 else if (it->f == last_escape_glyph_frame
5919 && it->face_id == last_escape_glyph_face_id)
5920 {
5921 face_id = last_escape_glyph_merged_face_id;
5922 }
5923 else
5924 {
5925 /* Merge the escape-glyph face into the current face. */
5926 face_id = merge_faces (it->f, Qescape_glyph, 0,
5927 it->face_id);
5928 last_escape_glyph_frame = it->f;
5929 last_escape_glyph_face_id = it->face_id;
5930 last_escape_glyph_merged_face_id = face_id;
5931 }
5932
5933 /* Handle soft hyphens in the mode where they only get
5934 highlighting. */
5935
5936 if (EQ (Vnobreak_char_display, Qt)
5937 && nbsp_or_shy == char_is_soft_hyphen)
5938 {
5939 it->c = '-';
5940 XSETINT (it->ctl_chars[0], '-');
5941 ctl_len = 1;
5942 goto display_control;
5943 }
5944
5945 /* Handle non-break space and soft hyphen
5946 with the escape glyph. */
5947
5948 if (nbsp_or_shy)
5949 {
5950 XSETINT (it->ctl_chars[0], escape_glyph);
5951 it->c = (nbsp_or_shy == char_is_nbsp ? ' ' : '-');
5952 XSETINT (it->ctl_chars[1], it->c);
5953 ctl_len = 2;
5954 goto display_control;
5955 }
5956
5957 {
5958 unsigned char str[MAX_MULTIBYTE_LENGTH];
5959 int len;
5960 int i;
5961
5962 /* Set IT->ctl_chars[0] to the glyph for `\\'. */
5963 if (CHAR_BYTE8_P (it->c))
5964 {
5965 str[0] = CHAR_TO_BYTE8 (it->c);
5966 len = 1;
5967 }
5968 else if (it->c < 256)
5969 {
5970 str[0] = it->c;
5971 len = 1;
5972 }
5973 else
5974 {
5975 /* It's an invalid character, which shouldn't
5976 happen actually, but due to bugs it may
5977 happen. Let's print the char as is, there's
5978 not much meaningful we can do with it. */
5979 str[0] = it->c;
5980 str[1] = it->c >> 8;
5981 str[2] = it->c >> 16;
5982 str[3] = it->c >> 24;
5983 len = 4;
5984 }
5985
5986 for (i = 0; i < len; i++)
5987 {
5988 int g;
5989 XSETINT (it->ctl_chars[i * 4], escape_glyph);
5990 /* Insert three more glyphs into IT->ctl_chars for
5991 the octal display of the character. */
5992 g = ((str[i] >> 6) & 7) + '0';
5993 XSETINT (it->ctl_chars[i * 4 + 1], g);
5994 g = ((str[i] >> 3) & 7) + '0';
5995 XSETINT (it->ctl_chars[i * 4 + 2], g);
5996 g = (str[i] & 7) + '0';
5997 XSETINT (it->ctl_chars[i * 4 + 3], g);
5998 }
5999 ctl_len = len * 4;
6000 }
6001
6002 display_control:
6003 /* Set up IT->dpvec and return first character from it. */
6004 it->dpvec_char_len = it->len;
6005 it->dpvec = it->ctl_chars;
6006 it->dpend = it->dpvec + ctl_len;
6007 it->current.dpvec_index = 0;
6008 it->dpvec_face_id = face_id;
6009 it->saved_face_id = it->face_id;
6010 it->method = GET_FROM_DISPLAY_VECTOR;
6011 it->ellipsis_p = 0;
6012 goto get_next;
6013 }
6014 }
6015 }
6016
6017 #ifdef HAVE_WINDOW_SYSTEM
6018 /* Adjust face id for a multibyte character. There are no multibyte
6019 character in unibyte text. */
6020 if ((it->what == IT_CHARACTER || it->what == IT_COMPOSITION)
6021 && it->multibyte_p
6022 && success_p
6023 && FRAME_WINDOW_P (it->f))
6024 {
6025 struct face *face = FACE_FROM_ID (it->f, it->face_id);
6026
6027 if (it->what == IT_COMPOSITION && it->cmp_it.ch >= 0)
6028 {
6029 /* Automatic composition with glyph-string. */
6030 Lisp_Object gstring = composition_gstring_from_id (it->cmp_it.id);
6031
6032 it->face_id = face_for_font (it->f, LGSTRING_FONT (gstring), face);
6033 }
6034 else
6035 {
6036 int pos = (it->s ? -1
6037 : STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
6038 : IT_CHARPOS (*it));
6039
6040 it->face_id = FACE_FOR_CHAR (it->f, face, it->c, pos, it->string);
6041 }
6042 }
6043 #endif
6044
6045 /* Is this character the last one of a run of characters with
6046 box? If yes, set IT->end_of_box_run_p to 1. */
6047 if (it->face_box_p
6048 && it->s == NULL)
6049 {
6050 if (it->method == GET_FROM_STRING && it->sp)
6051 {
6052 int face_id = underlying_face_id (it);
6053 struct face *face = FACE_FROM_ID (it->f, face_id);
6054
6055 if (face)
6056 {
6057 if (face->box == FACE_NO_BOX)
6058 {
6059 /* If the box comes from face properties in a
6060 display string, check faces in that string. */
6061 int string_face_id = face_after_it_pos (it);
6062 it->end_of_box_run_p
6063 = (FACE_FROM_ID (it->f, string_face_id)->box
6064 == FACE_NO_BOX);
6065 }
6066 /* Otherwise, the box comes from the underlying face.
6067 If this is the last string character displayed, check
6068 the next buffer location. */
6069 else if ((IT_STRING_CHARPOS (*it) >= SCHARS (it->string) - 1)
6070 && (it->current.overlay_string_index
6071 == it->n_overlay_strings - 1))
6072 {
6073 EMACS_INT ignore;
6074 int next_face_id;
6075 struct text_pos pos = it->current.pos;
6076 INC_TEXT_POS (pos, it->multibyte_p);
6077
6078 next_face_id = face_at_buffer_position
6079 (it->w, CHARPOS (pos), it->region_beg_charpos,
6080 it->region_end_charpos, &ignore,
6081 (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT), 0,
6082 -1);
6083 it->end_of_box_run_p
6084 = (FACE_FROM_ID (it->f, next_face_id)->box
6085 == FACE_NO_BOX);
6086 }
6087 }
6088 }
6089 else
6090 {
6091 int face_id = face_after_it_pos (it);
6092 it->end_of_box_run_p
6093 = (face_id != it->face_id
6094 && FACE_FROM_ID (it->f, face_id)->box == FACE_NO_BOX);
6095 }
6096 }
6097
6098 /* Value is 0 if end of buffer or string reached. */
6099 return success_p;
6100 }
6101
6102
6103 /* Move IT to the next display element.
6104
6105 RESEAT_P non-zero means if called on a newline in buffer text,
6106 skip to the next visible line start.
6107
6108 Functions get_next_display_element and set_iterator_to_next are
6109 separate because I find this arrangement easier to handle than a
6110 get_next_display_element function that also increments IT's
6111 position. The way it is we can first look at an iterator's current
6112 display element, decide whether it fits on a line, and if it does,
6113 increment the iterator position. The other way around we probably
6114 would either need a flag indicating whether the iterator has to be
6115 incremented the next time, or we would have to implement a
6116 decrement position function which would not be easy to write. */
6117
6118 void
6119 set_iterator_to_next (struct it *it, int reseat_p)
6120 {
6121 /* Reset flags indicating start and end of a sequence of characters
6122 with box. Reset them at the start of this function because
6123 moving the iterator to a new position might set them. */
6124 it->start_of_box_run_p = it->end_of_box_run_p = 0;
6125
6126 switch (it->method)
6127 {
6128 case GET_FROM_BUFFER:
6129 /* The current display element of IT is a character from
6130 current_buffer. Advance in the buffer, and maybe skip over
6131 invisible lines that are so because of selective display. */
6132 if (ITERATOR_AT_END_OF_LINE_P (it) && reseat_p)
6133 reseat_at_next_visible_line_start (it, 0);
6134 else if (it->cmp_it.id >= 0)
6135 {
6136 /* We are currently getting glyphs from a composition. */
6137 int i;
6138
6139 if (! it->bidi_p)
6140 {
6141 IT_CHARPOS (*it) += it->cmp_it.nchars;
6142 IT_BYTEPOS (*it) += it->cmp_it.nbytes;
6143 if (it->cmp_it.to < it->cmp_it.nglyphs)
6144 {
6145 it->cmp_it.from = it->cmp_it.to;
6146 }
6147 else
6148 {
6149 it->cmp_it.id = -1;
6150 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
6151 IT_BYTEPOS (*it),
6152 it->stop_charpos, Qnil);
6153 }
6154 }
6155 else if (! it->cmp_it.reversed_p)
6156 {
6157 /* Composition created while scanning forward. */
6158 /* Update IT's char/byte positions to point to the first
6159 character of the next grapheme cluster, or to the
6160 character visually after the current composition. */
6161 for (i = 0; i < it->cmp_it.nchars; i++)
6162 bidi_move_to_visually_next (&it->bidi_it);
6163 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
6164 IT_CHARPOS (*it) = it->bidi_it.charpos;
6165
6166 if (it->cmp_it.to < it->cmp_it.nglyphs)
6167 {
6168 /* Proceed to the next grapheme cluster. */
6169 it->cmp_it.from = it->cmp_it.to;
6170 }
6171 else
6172 {
6173 /* No more grapheme clusters in this composition.
6174 Find the next stop position. */
6175 EMACS_INT stop = it->stop_charpos;
6176 if (it->bidi_it.scan_dir < 0)
6177 /* Now we are scanning backward and don't know
6178 where to stop. */
6179 stop = -1;
6180 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
6181 IT_BYTEPOS (*it), stop, Qnil);
6182 }
6183 }
6184 else
6185 {
6186 /* Composition created while scanning backward. */
6187 /* Update IT's char/byte positions to point to the last
6188 character of the previous grapheme cluster, or the
6189 character visually after the current composition. */
6190 for (i = 0; i < it->cmp_it.nchars; i++)
6191 bidi_move_to_visually_next (&it->bidi_it);
6192 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
6193 IT_CHARPOS (*it) = it->bidi_it.charpos;
6194 if (it->cmp_it.from > 0)
6195 {
6196 /* Proceed to the previous grapheme cluster. */
6197 it->cmp_it.to = it->cmp_it.from;
6198 }
6199 else
6200 {
6201 /* No more grapheme clusters in this composition.
6202 Find the next stop position. */
6203 EMACS_INT stop = it->stop_charpos;
6204 if (it->bidi_it.scan_dir < 0)
6205 /* Now we are scanning backward and don't know
6206 where to stop. */
6207 stop = -1;
6208 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
6209 IT_BYTEPOS (*it), stop, Qnil);
6210 }
6211 }
6212 }
6213 else
6214 {
6215 xassert (it->len != 0);
6216
6217 if (!it->bidi_p)
6218 {
6219 IT_BYTEPOS (*it) += it->len;
6220 IT_CHARPOS (*it) += 1;
6221 }
6222 else
6223 {
6224 int prev_scan_dir = it->bidi_it.scan_dir;
6225 /* If this is a new paragraph, determine its base
6226 direction (a.k.a. its base embedding level). */
6227 if (it->bidi_it.new_paragraph)
6228 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it);
6229 bidi_move_to_visually_next (&it->bidi_it);
6230 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
6231 IT_CHARPOS (*it) = it->bidi_it.charpos;
6232 if (prev_scan_dir != it->bidi_it.scan_dir)
6233 {
6234 /* As the scan direction was changed, we must
6235 re-compute the stop position for composition. */
6236 EMACS_INT stop = it->stop_charpos;
6237 if (it->bidi_it.scan_dir < 0)
6238 stop = -1;
6239 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
6240 IT_BYTEPOS (*it), stop, Qnil);
6241 }
6242 }
6243 xassert (IT_BYTEPOS (*it) == CHAR_TO_BYTE (IT_CHARPOS (*it)));
6244 }
6245 break;
6246
6247 case GET_FROM_C_STRING:
6248 /* Current display element of IT is from a C string. */
6249 IT_BYTEPOS (*it) += it->len;
6250 IT_CHARPOS (*it) += 1;
6251 break;
6252
6253 case GET_FROM_DISPLAY_VECTOR:
6254 /* Current display element of IT is from a display table entry.
6255 Advance in the display table definition. Reset it to null if
6256 end reached, and continue with characters from buffers/
6257 strings. */
6258 ++it->current.dpvec_index;
6259
6260 /* Restore face of the iterator to what they were before the
6261 display vector entry (these entries may contain faces). */
6262 it->face_id = it->saved_face_id;
6263
6264 if (it->dpvec + it->current.dpvec_index == it->dpend)
6265 {
6266 int recheck_faces = it->ellipsis_p;
6267
6268 if (it->s)
6269 it->method = GET_FROM_C_STRING;
6270 else if (STRINGP (it->string))
6271 it->method = GET_FROM_STRING;
6272 else
6273 {
6274 it->method = GET_FROM_BUFFER;
6275 it->object = it->w->buffer;
6276 }
6277
6278 it->dpvec = NULL;
6279 it->current.dpvec_index = -1;
6280
6281 /* Skip over characters which were displayed via IT->dpvec. */
6282 if (it->dpvec_char_len < 0)
6283 reseat_at_next_visible_line_start (it, 1);
6284 else if (it->dpvec_char_len > 0)
6285 {
6286 if (it->method == GET_FROM_STRING
6287 && it->n_overlay_strings > 0)
6288 it->ignore_overlay_strings_at_pos_p = 1;
6289 it->len = it->dpvec_char_len;
6290 set_iterator_to_next (it, reseat_p);
6291 }
6292
6293 /* Maybe recheck faces after display vector */
6294 if (recheck_faces)
6295 it->stop_charpos = IT_CHARPOS (*it);
6296 }
6297 break;
6298
6299 case GET_FROM_STRING:
6300 /* Current display element is a character from a Lisp string. */
6301 xassert (it->s == NULL && STRINGP (it->string));
6302 if (it->cmp_it.id >= 0)
6303 {
6304 IT_STRING_CHARPOS (*it) += it->cmp_it.nchars;
6305 IT_STRING_BYTEPOS (*it) += it->cmp_it.nbytes;
6306 if (it->cmp_it.to < it->cmp_it.nglyphs)
6307 it->cmp_it.from = it->cmp_it.to;
6308 else
6309 {
6310 it->cmp_it.id = -1;
6311 composition_compute_stop_pos (&it->cmp_it,
6312 IT_STRING_CHARPOS (*it),
6313 IT_STRING_BYTEPOS (*it),
6314 it->stop_charpos, it->string);
6315 }
6316 }
6317 else
6318 {
6319 IT_STRING_BYTEPOS (*it) += it->len;
6320 IT_STRING_CHARPOS (*it) += 1;
6321 }
6322
6323 consider_string_end:
6324
6325 if (it->current.overlay_string_index >= 0)
6326 {
6327 /* IT->string is an overlay string. Advance to the
6328 next, if there is one. */
6329 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
6330 {
6331 it->ellipsis_p = 0;
6332 next_overlay_string (it);
6333 if (it->ellipsis_p)
6334 setup_for_ellipsis (it, 0);
6335 }
6336 }
6337 else
6338 {
6339 /* IT->string is not an overlay string. If we reached
6340 its end, and there is something on IT->stack, proceed
6341 with what is on the stack. This can be either another
6342 string, this time an overlay string, or a buffer. */
6343 if (IT_STRING_CHARPOS (*it) == SCHARS (it->string)
6344 && it->sp > 0)
6345 {
6346 pop_it (it);
6347 if (it->method == GET_FROM_STRING)
6348 goto consider_string_end;
6349 }
6350 }
6351 break;
6352
6353 case GET_FROM_IMAGE:
6354 case GET_FROM_STRETCH:
6355 /* The position etc with which we have to proceed are on
6356 the stack. The position may be at the end of a string,
6357 if the `display' property takes up the whole string. */
6358 xassert (it->sp > 0);
6359 pop_it (it);
6360 if (it->method == GET_FROM_STRING)
6361 goto consider_string_end;
6362 break;
6363
6364 default:
6365 /* There are no other methods defined, so this should be a bug. */
6366 abort ();
6367 }
6368
6369 xassert (it->method != GET_FROM_STRING
6370 || (STRINGP (it->string)
6371 && IT_STRING_CHARPOS (*it) >= 0));
6372 }
6373
6374 /* Load IT's display element fields with information about the next
6375 display element which comes from a display table entry or from the
6376 result of translating a control character to one of the forms `^C'
6377 or `\003'.
6378
6379 IT->dpvec holds the glyphs to return as characters.
6380 IT->saved_face_id holds the face id before the display vector--it
6381 is restored into IT->face_id in set_iterator_to_next. */
6382
6383 static int
6384 next_element_from_display_vector (struct it *it)
6385 {
6386 Lisp_Object gc;
6387
6388 /* Precondition. */
6389 xassert (it->dpvec && it->current.dpvec_index >= 0);
6390
6391 it->face_id = it->saved_face_id;
6392
6393 /* KFS: This code used to check ip->dpvec[0] instead of the current element.
6394 That seemed totally bogus - so I changed it... */
6395 gc = it->dpvec[it->current.dpvec_index];
6396
6397 if (GLYPH_CODE_P (gc) && GLYPH_CODE_CHAR_VALID_P (gc))
6398 {
6399 it->c = GLYPH_CODE_CHAR (gc);
6400 it->len = CHAR_BYTES (it->c);
6401
6402 /* The entry may contain a face id to use. Such a face id is
6403 the id of a Lisp face, not a realized face. A face id of
6404 zero means no face is specified. */
6405 if (it->dpvec_face_id >= 0)
6406 it->face_id = it->dpvec_face_id;
6407 else
6408 {
6409 int lface_id = GLYPH_CODE_FACE (gc);
6410 if (lface_id > 0)
6411 it->face_id = merge_faces (it->f, Qt, lface_id,
6412 it->saved_face_id);
6413 }
6414 }
6415 else
6416 /* Display table entry is invalid. Return a space. */
6417 it->c = ' ', it->len = 1;
6418
6419 /* Don't change position and object of the iterator here. They are
6420 still the values of the character that had this display table
6421 entry or was translated, and that's what we want. */
6422 it->what = IT_CHARACTER;
6423 return 1;
6424 }
6425
6426
6427 /* Load IT with the next display element from Lisp string IT->string.
6428 IT->current.string_pos is the current position within the string.
6429 If IT->current.overlay_string_index >= 0, the Lisp string is an
6430 overlay string. */
6431
6432 static int
6433 next_element_from_string (struct it *it)
6434 {
6435 struct text_pos position;
6436
6437 xassert (STRINGP (it->string));
6438 xassert (IT_STRING_CHARPOS (*it) >= 0);
6439 position = it->current.string_pos;
6440
6441 /* Time to check for invisible text? */
6442 if (IT_STRING_CHARPOS (*it) < it->end_charpos
6443 && IT_STRING_CHARPOS (*it) == it->stop_charpos)
6444 {
6445 handle_stop (it);
6446
6447 /* Since a handler may have changed IT->method, we must
6448 recurse here. */
6449 return GET_NEXT_DISPLAY_ELEMENT (it);
6450 }
6451
6452 if (it->current.overlay_string_index >= 0)
6453 {
6454 /* Get the next character from an overlay string. In overlay
6455 strings, There is no field width or padding with spaces to
6456 do. */
6457 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
6458 {
6459 it->what = IT_EOB;
6460 return 0;
6461 }
6462 else if (CHAR_COMPOSED_P (it, IT_STRING_CHARPOS (*it),
6463 IT_STRING_BYTEPOS (*it), SCHARS (it->string))
6464 && next_element_from_composition (it))
6465 {
6466 return 1;
6467 }
6468 else if (STRING_MULTIBYTE (it->string))
6469 {
6470 int remaining = SBYTES (it->string) - IT_STRING_BYTEPOS (*it);
6471 const unsigned char *s = (SDATA (it->string)
6472 + IT_STRING_BYTEPOS (*it));
6473 it->c = string_char_and_length (s, &it->len);
6474 }
6475 else
6476 {
6477 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
6478 it->len = 1;
6479 }
6480 }
6481 else
6482 {
6483 /* Get the next character from a Lisp string that is not an
6484 overlay string. Such strings come from the mode line, for
6485 example. We may have to pad with spaces, or truncate the
6486 string. See also next_element_from_c_string. */
6487 if (IT_STRING_CHARPOS (*it) >= it->end_charpos)
6488 {
6489 it->what = IT_EOB;
6490 return 0;
6491 }
6492 else if (IT_STRING_CHARPOS (*it) >= it->string_nchars)
6493 {
6494 /* Pad with spaces. */
6495 it->c = ' ', it->len = 1;
6496 CHARPOS (position) = BYTEPOS (position) = -1;
6497 }
6498 else if (CHAR_COMPOSED_P (it, IT_STRING_CHARPOS (*it),
6499 IT_STRING_BYTEPOS (*it), it->string_nchars)
6500 && next_element_from_composition (it))
6501 {
6502 return 1;
6503 }
6504 else if (STRING_MULTIBYTE (it->string))
6505 {
6506 int maxlen = SBYTES (it->string) - IT_STRING_BYTEPOS (*it);
6507 const unsigned char *s = (SDATA (it->string)
6508 + IT_STRING_BYTEPOS (*it));
6509 it->c = string_char_and_length (s, &it->len);
6510 }
6511 else
6512 {
6513 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
6514 it->len = 1;
6515 }
6516 }
6517
6518 /* Record what we have and where it came from. */
6519 it->what = IT_CHARACTER;
6520 it->object = it->string;
6521 it->position = position;
6522 return 1;
6523 }
6524
6525
6526 /* Load IT with next display element from C string IT->s.
6527 IT->string_nchars is the maximum number of characters to return
6528 from the string. IT->end_charpos may be greater than
6529 IT->string_nchars when this function is called, in which case we
6530 may have to return padding spaces. Value is zero if end of string
6531 reached, including padding spaces. */
6532
6533 static int
6534 next_element_from_c_string (struct it *it)
6535 {
6536 int success_p = 1;
6537
6538 xassert (it->s);
6539 it->what = IT_CHARACTER;
6540 BYTEPOS (it->position) = CHARPOS (it->position) = 0;
6541 it->object = Qnil;
6542
6543 /* IT's position can be greater IT->string_nchars in case a field
6544 width or precision has been specified when the iterator was
6545 initialized. */
6546 if (IT_CHARPOS (*it) >= it->end_charpos)
6547 {
6548 /* End of the game. */
6549 it->what = IT_EOB;
6550 success_p = 0;
6551 }
6552 else if (IT_CHARPOS (*it) >= it->string_nchars)
6553 {
6554 /* Pad with spaces. */
6555 it->c = ' ', it->len = 1;
6556 BYTEPOS (it->position) = CHARPOS (it->position) = -1;
6557 }
6558 else if (it->multibyte_p)
6559 {
6560 /* Implementation note: The calls to strlen apparently aren't a
6561 performance problem because there is no noticeable performance
6562 difference between Emacs running in unibyte or multibyte mode. */
6563 int maxlen = strlen (it->s) - IT_BYTEPOS (*it);
6564 it->c = string_char_and_length (it->s + IT_BYTEPOS (*it), &it->len);
6565 }
6566 else
6567 it->c = it->s[IT_BYTEPOS (*it)], it->len = 1;
6568
6569 return success_p;
6570 }
6571
6572
6573 /* Set up IT to return characters from an ellipsis, if appropriate.
6574 The definition of the ellipsis glyphs may come from a display table
6575 entry. This function fills IT with the first glyph from the
6576 ellipsis if an ellipsis is to be displayed. */
6577
6578 static int
6579 next_element_from_ellipsis (struct it *it)
6580 {
6581 if (it->selective_display_ellipsis_p)
6582 setup_for_ellipsis (it, it->len);
6583 else
6584 {
6585 /* The face at the current position may be different from the
6586 face we find after the invisible text. Remember what it
6587 was in IT->saved_face_id, and signal that it's there by
6588 setting face_before_selective_p. */
6589 it->saved_face_id = it->face_id;
6590 it->method = GET_FROM_BUFFER;
6591 it->object = it->w->buffer;
6592 reseat_at_next_visible_line_start (it, 1);
6593 it->face_before_selective_p = 1;
6594 }
6595
6596 return GET_NEXT_DISPLAY_ELEMENT (it);
6597 }
6598
6599
6600 /* Deliver an image display element. The iterator IT is already
6601 filled with image information (done in handle_display_prop). Value
6602 is always 1. */
6603
6604
6605 static int
6606 next_element_from_image (struct it *it)
6607 {
6608 it->what = IT_IMAGE;
6609 it->ignore_overlay_strings_at_pos_p = 0;
6610 return 1;
6611 }
6612
6613
6614 /* Fill iterator IT with next display element from a stretch glyph
6615 property. IT->object is the value of the text property. Value is
6616 always 1. */
6617
6618 static int
6619 next_element_from_stretch (struct it *it)
6620 {
6621 it->what = IT_STRETCH;
6622 return 1;
6623 }
6624
6625 /* Scan forward from CHARPOS in the current buffer, until we find a
6626 stop position > current IT's position. Then handle the stop
6627 position before that. This is called when we bump into a stop
6628 position while reordering bidirectional text. CHARPOS should be
6629 the last previously processed stop_pos (or BEGV, if none were
6630 processed yet) whose position is less that IT's current
6631 position. */
6632
6633 static void
6634 handle_stop_backwards (struct it *it, EMACS_INT charpos)
6635 {
6636 EMACS_INT where_we_are = IT_CHARPOS (*it);
6637 struct display_pos save_current = it->current;
6638 struct text_pos save_position = it->position;
6639 struct text_pos pos1;
6640 EMACS_INT next_stop;
6641
6642 /* Scan in strict logical order. */
6643 it->bidi_p = 0;
6644 do
6645 {
6646 it->prev_stop = charpos;
6647 SET_TEXT_POS (pos1, charpos, CHAR_TO_BYTE (charpos));
6648 reseat_1 (it, pos1, 0);
6649 compute_stop_pos (it);
6650 /* We must advance forward, right? */
6651 if (it->stop_charpos <= it->prev_stop)
6652 abort ();
6653 charpos = it->stop_charpos;
6654 }
6655 while (charpos <= where_we_are);
6656
6657 next_stop = it->stop_charpos;
6658 it->stop_charpos = it->prev_stop;
6659 it->bidi_p = 1;
6660 it->current = save_current;
6661 it->position = save_position;
6662 handle_stop (it);
6663 it->stop_charpos = next_stop;
6664 }
6665
6666 /* Load IT with the next display element from current_buffer. Value
6667 is zero if end of buffer reached. IT->stop_charpos is the next
6668 position at which to stop and check for text properties or buffer
6669 end. */
6670
6671 static int
6672 next_element_from_buffer (struct it *it)
6673 {
6674 int success_p = 1;
6675
6676 xassert (IT_CHARPOS (*it) >= BEGV);
6677
6678 /* With bidi reordering, the character to display might not be the
6679 character at IT_CHARPOS. BIDI_IT.FIRST_ELT non-zero means that
6680 we were reseat()ed to a new buffer position, which is potentially
6681 a different paragraph. */
6682 if (it->bidi_p && it->bidi_it.first_elt)
6683 {
6684 it->bidi_it.charpos = IT_CHARPOS (*it);
6685 it->bidi_it.bytepos = IT_BYTEPOS (*it);
6686 if (it->bidi_it.bytepos == ZV_BYTE)
6687 {
6688 /* Nothing to do, but reset the FIRST_ELT flag, like
6689 bidi_paragraph_init does, because we are not going to
6690 call it. */
6691 it->bidi_it.first_elt = 0;
6692 }
6693 else if (it->bidi_it.bytepos == BEGV_BYTE
6694 /* FIXME: Should support all Unicode line separators. */
6695 || FETCH_CHAR (it->bidi_it.bytepos - 1) == '\n'
6696 || FETCH_CHAR (it->bidi_it.bytepos) == '\n')
6697 {
6698 /* If we are at the beginning of a line, we can produce the
6699 next element right away. */
6700 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it);
6701 bidi_move_to_visually_next (&it->bidi_it);
6702 }
6703 else
6704 {
6705 int orig_bytepos = IT_BYTEPOS (*it);
6706
6707 /* We need to prime the bidi iterator starting at the line's
6708 beginning, before we will be able to produce the next
6709 element. */
6710 IT_CHARPOS (*it) = find_next_newline_no_quit (IT_CHARPOS (*it), -1);
6711 IT_BYTEPOS (*it) = CHAR_TO_BYTE (IT_CHARPOS (*it));
6712 it->bidi_it.charpos = IT_CHARPOS (*it);
6713 it->bidi_it.bytepos = IT_BYTEPOS (*it);
6714 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it);
6715 do
6716 {
6717 /* Now return to buffer position where we were asked to
6718 get the next display element, and produce that. */
6719 bidi_move_to_visually_next (&it->bidi_it);
6720 }
6721 while (it->bidi_it.bytepos != orig_bytepos
6722 && it->bidi_it.bytepos < ZV_BYTE);
6723 }
6724
6725 it->bidi_it.first_elt = 0; /* paranoia: bidi.c does this */
6726 /* Adjust IT's position information to where we ended up. */
6727 IT_CHARPOS (*it) = it->bidi_it.charpos;
6728 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
6729 SET_TEXT_POS (it->position, IT_CHARPOS (*it), IT_BYTEPOS (*it));
6730 {
6731 EMACS_INT stop = it->stop_charpos;
6732 if (it->bidi_it.scan_dir < 0)
6733 stop = -1;
6734 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
6735 IT_BYTEPOS (*it), stop, Qnil);
6736 }
6737 }
6738
6739 if (IT_CHARPOS (*it) >= it->stop_charpos)
6740 {
6741 if (IT_CHARPOS (*it) >= it->end_charpos)
6742 {
6743 int overlay_strings_follow_p;
6744
6745 /* End of the game, except when overlay strings follow that
6746 haven't been returned yet. */
6747 if (it->overlay_strings_at_end_processed_p)
6748 overlay_strings_follow_p = 0;
6749 else
6750 {
6751 it->overlay_strings_at_end_processed_p = 1;
6752 overlay_strings_follow_p = get_overlay_strings (it, 0);
6753 }
6754
6755 if (overlay_strings_follow_p)
6756 success_p = GET_NEXT_DISPLAY_ELEMENT (it);
6757 else
6758 {
6759 it->what = IT_EOB;
6760 it->position = it->current.pos;
6761 success_p = 0;
6762 }
6763 }
6764 else if (!(!it->bidi_p
6765 || BIDI_AT_BASE_LEVEL (it->bidi_it)
6766 || IT_CHARPOS (*it) == it->stop_charpos))
6767 {
6768 /* With bidi non-linear iteration, we could find ourselves
6769 far beyond the last computed stop_charpos, with several
6770 other stop positions in between that we missed. Scan
6771 them all now, in buffer's logical order, until we find
6772 and handle the last stop_charpos that precedes our
6773 current position. */
6774 handle_stop_backwards (it, it->stop_charpos);
6775 return GET_NEXT_DISPLAY_ELEMENT (it);
6776 }
6777 else
6778 {
6779 if (it->bidi_p)
6780 {
6781 /* Take note of the stop position we just moved across,
6782 for when we will move back across it. */
6783 it->prev_stop = it->stop_charpos;
6784 /* If we are at base paragraph embedding level, take
6785 note of the last stop position seen at this
6786 level. */
6787 if (BIDI_AT_BASE_LEVEL (it->bidi_it))
6788 it->base_level_stop = it->stop_charpos;
6789 }
6790 handle_stop (it);
6791 return GET_NEXT_DISPLAY_ELEMENT (it);
6792 }
6793 }
6794 else if (it->bidi_p
6795 /* We can sometimes back up for reasons that have nothing
6796 to do with bidi reordering. E.g., compositions. The
6797 code below is only needed when we are above the base
6798 embedding level, so test for that explicitly. */
6799 && !BIDI_AT_BASE_LEVEL (it->bidi_it)
6800 && IT_CHARPOS (*it) < it->prev_stop)
6801 {
6802 if (it->base_level_stop <= 0)
6803 it->base_level_stop = BEGV;
6804 if (IT_CHARPOS (*it) < it->base_level_stop)
6805 abort ();
6806 handle_stop_backwards (it, it->base_level_stop);
6807 return GET_NEXT_DISPLAY_ELEMENT (it);
6808 }
6809 else
6810 {
6811 /* No face changes, overlays etc. in sight, so just return a
6812 character from current_buffer. */
6813 unsigned char *p;
6814 EMACS_INT stop;
6815
6816 /* Maybe run the redisplay end trigger hook. Performance note:
6817 This doesn't seem to cost measurable time. */
6818 if (it->redisplay_end_trigger_charpos
6819 && it->glyph_row
6820 && IT_CHARPOS (*it) >= it->redisplay_end_trigger_charpos)
6821 run_redisplay_end_trigger_hook (it);
6822
6823 stop = it->bidi_it.scan_dir < 0 ? -1 : it->end_charpos;
6824 if (CHAR_COMPOSED_P (it, IT_CHARPOS (*it), IT_BYTEPOS (*it),
6825 stop)
6826 && next_element_from_composition (it))
6827 {
6828 return 1;
6829 }
6830
6831 /* Get the next character, maybe multibyte. */
6832 p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
6833 if (it->multibyte_p && !ASCII_BYTE_P (*p))
6834 it->c = STRING_CHAR_AND_LENGTH (p, it->len);
6835 else
6836 it->c = *p, it->len = 1;
6837
6838 /* Record what we have and where it came from. */
6839 it->what = IT_CHARACTER;
6840 it->object = it->w->buffer;
6841 it->position = it->current.pos;
6842
6843 /* Normally we return the character found above, except when we
6844 really want to return an ellipsis for selective display. */
6845 if (it->selective)
6846 {
6847 if (it->c == '\n')
6848 {
6849 /* A value of selective > 0 means hide lines indented more
6850 than that number of columns. */
6851 if (it->selective > 0
6852 && IT_CHARPOS (*it) + 1 < ZV
6853 && indented_beyond_p (IT_CHARPOS (*it) + 1,
6854 IT_BYTEPOS (*it) + 1,
6855 (double) it->selective)) /* iftc */
6856 {
6857 success_p = next_element_from_ellipsis (it);
6858 it->dpvec_char_len = -1;
6859 }
6860 }
6861 else if (it->c == '\r' && it->selective == -1)
6862 {
6863 /* A value of selective == -1 means that everything from the
6864 CR to the end of the line is invisible, with maybe an
6865 ellipsis displayed for it. */
6866 success_p = next_element_from_ellipsis (it);
6867 it->dpvec_char_len = -1;
6868 }
6869 }
6870 }
6871
6872 /* Value is zero if end of buffer reached. */
6873 xassert (!success_p || it->what != IT_CHARACTER || it->len > 0);
6874 return success_p;
6875 }
6876
6877
6878 /* Run the redisplay end trigger hook for IT. */
6879
6880 static void
6881 run_redisplay_end_trigger_hook (struct it *it)
6882 {
6883 Lisp_Object args[3];
6884
6885 /* IT->glyph_row should be non-null, i.e. we should be actually
6886 displaying something, or otherwise we should not run the hook. */
6887 xassert (it->glyph_row);
6888
6889 /* Set up hook arguments. */
6890 args[0] = Qredisplay_end_trigger_functions;
6891 args[1] = it->window;
6892 XSETINT (args[2], it->redisplay_end_trigger_charpos);
6893 it->redisplay_end_trigger_charpos = 0;
6894
6895 /* Since we are *trying* to run these functions, don't try to run
6896 them again, even if they get an error. */
6897 it->w->redisplay_end_trigger = Qnil;
6898 Frun_hook_with_args (3, args);
6899
6900 /* Notice if it changed the face of the character we are on. */
6901 handle_face_prop (it);
6902 }
6903
6904
6905 /* Deliver a composition display element. Unlike the other
6906 next_element_from_XXX, this function is not registered in the array
6907 get_next_element[]. It is called from next_element_from_buffer and
6908 next_element_from_string when necessary. */
6909
6910 static int
6911 next_element_from_composition (struct it *it)
6912 {
6913 it->what = IT_COMPOSITION;
6914 it->len = it->cmp_it.nbytes;
6915 if (STRINGP (it->string))
6916 {
6917 if (it->c < 0)
6918 {
6919 IT_STRING_CHARPOS (*it) += it->cmp_it.nchars;
6920 IT_STRING_BYTEPOS (*it) += it->cmp_it.nbytes;
6921 return 0;
6922 }
6923 it->position = it->current.string_pos;
6924 it->object = it->string;
6925 it->c = composition_update_it (&it->cmp_it, IT_STRING_CHARPOS (*it),
6926 IT_STRING_BYTEPOS (*it), it->string);
6927 }
6928 else
6929 {
6930 if (it->c < 0)
6931 {
6932 IT_CHARPOS (*it) += it->cmp_it.nchars;
6933 IT_BYTEPOS (*it) += it->cmp_it.nbytes;
6934 if (it->bidi_p)
6935 {
6936 if (it->bidi_it.new_paragraph)
6937 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it);
6938 /* Resync the bidi iterator with IT's new position.
6939 FIXME: this doesn't support bidirectional text. */
6940 while (it->bidi_it.charpos < IT_CHARPOS (*it))
6941 bidi_move_to_visually_next (&it->bidi_it);
6942 }
6943 return 0;
6944 }
6945 it->position = it->current.pos;
6946 it->object = it->w->buffer;
6947 it->c = composition_update_it (&it->cmp_it, IT_CHARPOS (*it),
6948 IT_BYTEPOS (*it), Qnil);
6949 }
6950 return 1;
6951 }
6952
6953
6954 \f
6955 /***********************************************************************
6956 Moving an iterator without producing glyphs
6957 ***********************************************************************/
6958
6959 /* Check if iterator is at a position corresponding to a valid buffer
6960 position after some move_it_ call. */
6961
6962 #define IT_POS_VALID_AFTER_MOVE_P(it) \
6963 ((it)->method == GET_FROM_STRING \
6964 ? IT_STRING_CHARPOS (*it) == 0 \
6965 : 1)
6966
6967
6968 /* Move iterator IT to a specified buffer or X position within one
6969 line on the display without producing glyphs.
6970
6971 OP should be a bit mask including some or all of these bits:
6972 MOVE_TO_X: Stop upon reaching x-position TO_X.
6973 MOVE_TO_POS: Stop upon reaching buffer or string position TO_CHARPOS.
6974 Regardless of OP's value, stop upon reaching the end of the display line.
6975
6976 TO_X is normally a value 0 <= TO_X <= IT->last_visible_x.
6977 This means, in particular, that TO_X includes window's horizontal
6978 scroll amount.
6979
6980 The return value has several possible values that
6981 say what condition caused the scan to stop:
6982
6983 MOVE_POS_MATCH_OR_ZV
6984 - when TO_POS or ZV was reached.
6985
6986 MOVE_X_REACHED
6987 -when TO_X was reached before TO_POS or ZV were reached.
6988
6989 MOVE_LINE_CONTINUED
6990 - when we reached the end of the display area and the line must
6991 be continued.
6992
6993 MOVE_LINE_TRUNCATED
6994 - when we reached the end of the display area and the line is
6995 truncated.
6996
6997 MOVE_NEWLINE_OR_CR
6998 - when we stopped at a line end, i.e. a newline or a CR and selective
6999 display is on. */
7000
7001 static enum move_it_result
7002 move_it_in_display_line_to (struct it *it,
7003 EMACS_INT to_charpos, int to_x,
7004 enum move_operation_enum op)
7005 {
7006 enum move_it_result result = MOVE_UNDEFINED;
7007 struct glyph_row *saved_glyph_row;
7008 struct it wrap_it, atpos_it, atx_it;
7009 int may_wrap = 0;
7010 enum it_method prev_method = it->method;
7011 EMACS_INT prev_pos = IT_CHARPOS (*it);
7012
7013 /* Don't produce glyphs in produce_glyphs. */
7014 saved_glyph_row = it->glyph_row;
7015 it->glyph_row = NULL;
7016
7017 /* Use wrap_it to save a copy of IT wherever a word wrap could
7018 occur. Use atpos_it to save a copy of IT at the desired buffer
7019 position, if found, so that we can scan ahead and check if the
7020 word later overshoots the window edge. Use atx_it similarly, for
7021 pixel positions. */
7022 wrap_it.sp = -1;
7023 atpos_it.sp = -1;
7024 atx_it.sp = -1;
7025
7026 #define BUFFER_POS_REACHED_P() \
7027 ((op & MOVE_TO_POS) != 0 \
7028 && BUFFERP (it->object) \
7029 && (IT_CHARPOS (*it) == to_charpos \
7030 || (!it->bidi_p && IT_CHARPOS (*it) > to_charpos)) \
7031 && (it->method == GET_FROM_BUFFER \
7032 || (it->method == GET_FROM_DISPLAY_VECTOR \
7033 && it->dpvec + it->current.dpvec_index + 1 >= it->dpend)))
7034
7035 /* If there's a line-/wrap-prefix, handle it. */
7036 if (it->hpos == 0 && it->method == GET_FROM_BUFFER
7037 && it->current_y < it->last_visible_y)
7038 handle_line_prefix (it);
7039
7040 while (1)
7041 {
7042 int x, i, ascent = 0, descent = 0;
7043
7044 /* Utility macro to reset an iterator with x, ascent, and descent. */
7045 #define IT_RESET_X_ASCENT_DESCENT(IT) \
7046 ((IT)->current_x = x, (IT)->max_ascent = ascent, \
7047 (IT)->max_descent = descent)
7048
7049 /* Stop if we move beyond TO_CHARPOS (after an image or stretch
7050 glyph). */
7051 if ((op & MOVE_TO_POS) != 0
7052 && BUFFERP (it->object)
7053 && it->method == GET_FROM_BUFFER
7054 && ((!it->bidi_p && IT_CHARPOS (*it) > to_charpos)
7055 || (it->bidi_p
7056 && (prev_method == GET_FROM_IMAGE
7057 || prev_method == GET_FROM_STRETCH)
7058 /* Passed TO_CHARPOS from left to right. */
7059 && ((prev_pos < to_charpos
7060 && IT_CHARPOS (*it) > to_charpos)
7061 /* Passed TO_CHARPOS from right to left. */
7062 || (prev_pos > to_charpos
7063 && IT_CHARPOS (*it) < to_charpos)))))
7064 {
7065 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
7066 {
7067 result = MOVE_POS_MATCH_OR_ZV;
7068 break;
7069 }
7070 else if (it->line_wrap == WORD_WRAP && atpos_it.sp < 0)
7071 /* If wrap_it is valid, the current position might be in a
7072 word that is wrapped. So, save the iterator in
7073 atpos_it and continue to see if wrapping happens. */
7074 atpos_it = *it;
7075 }
7076
7077 prev_method = it->method;
7078 if (it->method == GET_FROM_BUFFER)
7079 prev_pos = IT_CHARPOS (*it);
7080 /* Stop when ZV reached.
7081 We used to stop here when TO_CHARPOS reached as well, but that is
7082 too soon if this glyph does not fit on this line. So we handle it
7083 explicitly below. */
7084 if (!get_next_display_element (it))
7085 {
7086 result = MOVE_POS_MATCH_OR_ZV;
7087 break;
7088 }
7089
7090 if (it->line_wrap == TRUNCATE)
7091 {
7092 if (BUFFER_POS_REACHED_P ())
7093 {
7094 result = MOVE_POS_MATCH_OR_ZV;
7095 break;
7096 }
7097 }
7098 else
7099 {
7100 if (it->line_wrap == WORD_WRAP)
7101 {
7102 if (IT_DISPLAYING_WHITESPACE (it))
7103 may_wrap = 1;
7104 else if (may_wrap)
7105 {
7106 /* We have reached a glyph that follows one or more
7107 whitespace characters. If the position is
7108 already found, we are done. */
7109 if (atpos_it.sp >= 0)
7110 {
7111 *it = atpos_it;
7112 result = MOVE_POS_MATCH_OR_ZV;
7113 goto done;
7114 }
7115 if (atx_it.sp >= 0)
7116 {
7117 *it = atx_it;
7118 result = MOVE_X_REACHED;
7119 goto done;
7120 }
7121 /* Otherwise, we can wrap here. */
7122 wrap_it = *it;
7123 may_wrap = 0;
7124 }
7125 }
7126 }
7127
7128 /* Remember the line height for the current line, in case
7129 the next element doesn't fit on the line. */
7130 ascent = it->max_ascent;
7131 descent = it->max_descent;
7132
7133 /* The call to produce_glyphs will get the metrics of the
7134 display element IT is loaded with. Record the x-position
7135 before this display element, in case it doesn't fit on the
7136 line. */
7137 x = it->current_x;
7138
7139 PRODUCE_GLYPHS (it);
7140
7141 if (it->area != TEXT_AREA)
7142 {
7143 set_iterator_to_next (it, 1);
7144 continue;
7145 }
7146
7147 /* The number of glyphs we get back in IT->nglyphs will normally
7148 be 1 except when IT->c is (i) a TAB, or (ii) a multi-glyph
7149 character on a terminal frame, or (iii) a line end. For the
7150 second case, IT->nglyphs - 1 padding glyphs will be present.
7151 (On X frames, there is only one glyph produced for a
7152 composite character.)
7153
7154 The behavior implemented below means, for continuation lines,
7155 that as many spaces of a TAB as fit on the current line are
7156 displayed there. For terminal frames, as many glyphs of a
7157 multi-glyph character are displayed in the current line, too.
7158 This is what the old redisplay code did, and we keep it that
7159 way. Under X, the whole shape of a complex character must
7160 fit on the line or it will be completely displayed in the
7161 next line.
7162
7163 Note that both for tabs and padding glyphs, all glyphs have
7164 the same width. */
7165 if (it->nglyphs)
7166 {
7167 /* More than one glyph or glyph doesn't fit on line. All
7168 glyphs have the same width. */
7169 int single_glyph_width = it->pixel_width / it->nglyphs;
7170 int new_x;
7171 int x_before_this_char = x;
7172 int hpos_before_this_char = it->hpos;
7173
7174 for (i = 0; i < it->nglyphs; ++i, x = new_x)
7175 {
7176 new_x = x + single_glyph_width;
7177
7178 /* We want to leave anything reaching TO_X to the caller. */
7179 if ((op & MOVE_TO_X) && new_x > to_x)
7180 {
7181 if (BUFFER_POS_REACHED_P ())
7182 {
7183 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
7184 goto buffer_pos_reached;
7185 if (atpos_it.sp < 0)
7186 {
7187 atpos_it = *it;
7188 IT_RESET_X_ASCENT_DESCENT (&atpos_it);
7189 }
7190 }
7191 else
7192 {
7193 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
7194 {
7195 it->current_x = x;
7196 result = MOVE_X_REACHED;
7197 break;
7198 }
7199 if (atx_it.sp < 0)
7200 {
7201 atx_it = *it;
7202 IT_RESET_X_ASCENT_DESCENT (&atx_it);
7203 }
7204 }
7205 }
7206
7207 if (/* Lines are continued. */
7208 it->line_wrap != TRUNCATE
7209 && (/* And glyph doesn't fit on the line. */
7210 new_x > it->last_visible_x
7211 /* Or it fits exactly and we're on a window
7212 system frame. */
7213 || (new_x == it->last_visible_x
7214 && FRAME_WINDOW_P (it->f))))
7215 {
7216 if (/* IT->hpos == 0 means the very first glyph
7217 doesn't fit on the line, e.g. a wide image. */
7218 it->hpos == 0
7219 || (new_x == it->last_visible_x
7220 && FRAME_WINDOW_P (it->f)))
7221 {
7222 ++it->hpos;
7223 it->current_x = new_x;
7224
7225 /* The character's last glyph just barely fits
7226 in this row. */
7227 if (i == it->nglyphs - 1)
7228 {
7229 /* If this is the destination position,
7230 return a position *before* it in this row,
7231 now that we know it fits in this row. */
7232 if (BUFFER_POS_REACHED_P ())
7233 {
7234 if (it->line_wrap != WORD_WRAP
7235 || wrap_it.sp < 0)
7236 {
7237 it->hpos = hpos_before_this_char;
7238 it->current_x = x_before_this_char;
7239 result = MOVE_POS_MATCH_OR_ZV;
7240 break;
7241 }
7242 if (it->line_wrap == WORD_WRAP
7243 && atpos_it.sp < 0)
7244 {
7245 atpos_it = *it;
7246 atpos_it.current_x = x_before_this_char;
7247 atpos_it.hpos = hpos_before_this_char;
7248 }
7249 }
7250
7251 set_iterator_to_next (it, 1);
7252 /* On graphical terminals, newlines may
7253 "overflow" into the fringe if
7254 overflow-newline-into-fringe is non-nil.
7255 On text-only terminals, newlines may
7256 overflow into the last glyph on the
7257 display line.*/
7258 if (!FRAME_WINDOW_P (it->f)
7259 || IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
7260 {
7261 if (!get_next_display_element (it))
7262 {
7263 result = MOVE_POS_MATCH_OR_ZV;
7264 break;
7265 }
7266 if (BUFFER_POS_REACHED_P ())
7267 {
7268 if (ITERATOR_AT_END_OF_LINE_P (it))
7269 result = MOVE_POS_MATCH_OR_ZV;
7270 else
7271 result = MOVE_LINE_CONTINUED;
7272 break;
7273 }
7274 if (ITERATOR_AT_END_OF_LINE_P (it))
7275 {
7276 result = MOVE_NEWLINE_OR_CR;
7277 break;
7278 }
7279 }
7280 }
7281 }
7282 else
7283 IT_RESET_X_ASCENT_DESCENT (it);
7284
7285 if (wrap_it.sp >= 0)
7286 {
7287 *it = wrap_it;
7288 atpos_it.sp = -1;
7289 atx_it.sp = -1;
7290 }
7291
7292 TRACE_MOVE ((stderr, "move_it_in: continued at %d\n",
7293 IT_CHARPOS (*it)));
7294 result = MOVE_LINE_CONTINUED;
7295 break;
7296 }
7297
7298 if (BUFFER_POS_REACHED_P ())
7299 {
7300 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
7301 goto buffer_pos_reached;
7302 if (it->line_wrap == WORD_WRAP && atpos_it.sp < 0)
7303 {
7304 atpos_it = *it;
7305 IT_RESET_X_ASCENT_DESCENT (&atpos_it);
7306 }
7307 }
7308
7309 if (new_x > it->first_visible_x)
7310 {
7311 /* Glyph is visible. Increment number of glyphs that
7312 would be displayed. */
7313 ++it->hpos;
7314 }
7315 }
7316
7317 if (result != MOVE_UNDEFINED)
7318 break;
7319 }
7320 else if (BUFFER_POS_REACHED_P ())
7321 {
7322 buffer_pos_reached:
7323 IT_RESET_X_ASCENT_DESCENT (it);
7324 result = MOVE_POS_MATCH_OR_ZV;
7325 break;
7326 }
7327 else if ((op & MOVE_TO_X) && it->current_x >= to_x)
7328 {
7329 /* Stop when TO_X specified and reached. This check is
7330 necessary here because of lines consisting of a line end,
7331 only. The line end will not produce any glyphs and we
7332 would never get MOVE_X_REACHED. */
7333 xassert (it->nglyphs == 0);
7334 result = MOVE_X_REACHED;
7335 break;
7336 }
7337
7338 /* Is this a line end? If yes, we're done. */
7339 if (ITERATOR_AT_END_OF_LINE_P (it))
7340 {
7341 result = MOVE_NEWLINE_OR_CR;
7342 break;
7343 }
7344
7345 if (it->method == GET_FROM_BUFFER)
7346 prev_pos = IT_CHARPOS (*it);
7347 /* The current display element has been consumed. Advance
7348 to the next. */
7349 set_iterator_to_next (it, 1);
7350
7351 /* Stop if lines are truncated and IT's current x-position is
7352 past the right edge of the window now. */
7353 if (it->line_wrap == TRUNCATE
7354 && it->current_x >= it->last_visible_x)
7355 {
7356 if (!FRAME_WINDOW_P (it->f)
7357 || IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
7358 {
7359 if (!get_next_display_element (it)
7360 || BUFFER_POS_REACHED_P ())
7361 {
7362 result = MOVE_POS_MATCH_OR_ZV;
7363 break;
7364 }
7365 if (ITERATOR_AT_END_OF_LINE_P (it))
7366 {
7367 result = MOVE_NEWLINE_OR_CR;
7368 break;
7369 }
7370 }
7371 result = MOVE_LINE_TRUNCATED;
7372 break;
7373 }
7374 #undef IT_RESET_X_ASCENT_DESCENT
7375 }
7376
7377 #undef BUFFER_POS_REACHED_P
7378
7379 /* If we scanned beyond to_pos and didn't find a point to wrap at,
7380 restore the saved iterator. */
7381 if (atpos_it.sp >= 0)
7382 *it = atpos_it;
7383 else if (atx_it.sp >= 0)
7384 *it = atx_it;
7385
7386 done:
7387
7388 /* Restore the iterator settings altered at the beginning of this
7389 function. */
7390 it->glyph_row = saved_glyph_row;
7391 return result;
7392 }
7393
7394 /* For external use. */
7395 void
7396 move_it_in_display_line (struct it *it,
7397 EMACS_INT to_charpos, int to_x,
7398 enum move_operation_enum op)
7399 {
7400 if (it->line_wrap == WORD_WRAP
7401 && (op & MOVE_TO_X))
7402 {
7403 struct it save_it = *it;
7404 int skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
7405 /* When word-wrap is on, TO_X may lie past the end
7406 of a wrapped line. Then it->current is the
7407 character on the next line, so backtrack to the
7408 space before the wrap point. */
7409 if (skip == MOVE_LINE_CONTINUED)
7410 {
7411 int prev_x = max (it->current_x - 1, 0);
7412 *it = save_it;
7413 move_it_in_display_line_to
7414 (it, -1, prev_x, MOVE_TO_X);
7415 }
7416 }
7417 else
7418 move_it_in_display_line_to (it, to_charpos, to_x, op);
7419 }
7420
7421
7422 /* Move IT forward until it satisfies one or more of the criteria in
7423 TO_CHARPOS, TO_X, TO_Y, and TO_VPOS.
7424
7425 OP is a bit-mask that specifies where to stop, and in particular,
7426 which of those four position arguments makes a difference. See the
7427 description of enum move_operation_enum.
7428
7429 If TO_CHARPOS is in invisible text, e.g. a truncated part of a
7430 screen line, this function will set IT to the next position >
7431 TO_CHARPOS. */
7432
7433 void
7434 move_it_to (struct it *it, int to_charpos, int to_x, int to_y, int to_vpos, int op)
7435 {
7436 enum move_it_result skip, skip2 = MOVE_X_REACHED;
7437 int line_height, line_start_x = 0, reached = 0;
7438
7439 for (;;)
7440 {
7441 if (op & MOVE_TO_VPOS)
7442 {
7443 /* If no TO_CHARPOS and no TO_X specified, stop at the
7444 start of the line TO_VPOS. */
7445 if ((op & (MOVE_TO_X | MOVE_TO_POS)) == 0)
7446 {
7447 if (it->vpos == to_vpos)
7448 {
7449 reached = 1;
7450 break;
7451 }
7452 else
7453 skip = move_it_in_display_line_to (it, -1, -1, 0);
7454 }
7455 else
7456 {
7457 /* TO_VPOS >= 0 means stop at TO_X in the line at
7458 TO_VPOS, or at TO_POS, whichever comes first. */
7459 if (it->vpos == to_vpos)
7460 {
7461 reached = 2;
7462 break;
7463 }
7464
7465 skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
7466
7467 if (skip == MOVE_POS_MATCH_OR_ZV || it->vpos == to_vpos)
7468 {
7469 reached = 3;
7470 break;
7471 }
7472 else if (skip == MOVE_X_REACHED && it->vpos != to_vpos)
7473 {
7474 /* We have reached TO_X but not in the line we want. */
7475 skip = move_it_in_display_line_to (it, to_charpos,
7476 -1, MOVE_TO_POS);
7477 if (skip == MOVE_POS_MATCH_OR_ZV)
7478 {
7479 reached = 4;
7480 break;
7481 }
7482 }
7483 }
7484 }
7485 else if (op & MOVE_TO_Y)
7486 {
7487 struct it it_backup;
7488
7489 if (it->line_wrap == WORD_WRAP)
7490 it_backup = *it;
7491
7492 /* TO_Y specified means stop at TO_X in the line containing
7493 TO_Y---or at TO_CHARPOS if this is reached first. The
7494 problem is that we can't really tell whether the line
7495 contains TO_Y before we have completely scanned it, and
7496 this may skip past TO_X. What we do is to first scan to
7497 TO_X.
7498
7499 If TO_X is not specified, use a TO_X of zero. The reason
7500 is to make the outcome of this function more predictable.
7501 If we didn't use TO_X == 0, we would stop at the end of
7502 the line which is probably not what a caller would expect
7503 to happen. */
7504 skip = move_it_in_display_line_to
7505 (it, to_charpos, ((op & MOVE_TO_X) ? to_x : 0),
7506 (MOVE_TO_X | (op & MOVE_TO_POS)));
7507
7508 /* If TO_CHARPOS is reached or ZV, we don't have to do more. */
7509 if (skip == MOVE_POS_MATCH_OR_ZV)
7510 reached = 5;
7511 else if (skip == MOVE_X_REACHED)
7512 {
7513 /* If TO_X was reached, we want to know whether TO_Y is
7514 in the line. We know this is the case if the already
7515 scanned glyphs make the line tall enough. Otherwise,
7516 we must check by scanning the rest of the line. */
7517 line_height = it->max_ascent + it->max_descent;
7518 if (to_y >= it->current_y
7519 && to_y < it->current_y + line_height)
7520 {
7521 reached = 6;
7522 break;
7523 }
7524 it_backup = *it;
7525 TRACE_MOVE ((stderr, "move_it: from %d\n", IT_CHARPOS (*it)));
7526 skip2 = move_it_in_display_line_to (it, to_charpos, -1,
7527 op & MOVE_TO_POS);
7528 TRACE_MOVE ((stderr, "move_it: to %d\n", IT_CHARPOS (*it)));
7529 line_height = it->max_ascent + it->max_descent;
7530 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
7531
7532 if (to_y >= it->current_y
7533 && to_y < it->current_y + line_height)
7534 {
7535 /* If TO_Y is in this line and TO_X was reached
7536 above, we scanned too far. We have to restore
7537 IT's settings to the ones before skipping. */
7538 *it = it_backup;
7539 reached = 6;
7540 }
7541 else
7542 {
7543 skip = skip2;
7544 if (skip == MOVE_POS_MATCH_OR_ZV)
7545 reached = 7;
7546 }
7547 }
7548 else
7549 {
7550 /* Check whether TO_Y is in this line. */
7551 line_height = it->max_ascent + it->max_descent;
7552 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
7553
7554 if (to_y >= it->current_y
7555 && to_y < it->current_y + line_height)
7556 {
7557 /* When word-wrap is on, TO_X may lie past the end
7558 of a wrapped line. Then it->current is the
7559 character on the next line, so backtrack to the
7560 space before the wrap point. */
7561 if (skip == MOVE_LINE_CONTINUED
7562 && it->line_wrap == WORD_WRAP)
7563 {
7564 int prev_x = max (it->current_x - 1, 0);
7565 *it = it_backup;
7566 skip = move_it_in_display_line_to
7567 (it, -1, prev_x, MOVE_TO_X);
7568 }
7569 reached = 6;
7570 }
7571 }
7572
7573 if (reached)
7574 break;
7575 }
7576 else if (BUFFERP (it->object)
7577 && (it->method == GET_FROM_BUFFER
7578 || it->method == GET_FROM_STRETCH)
7579 && IT_CHARPOS (*it) >= to_charpos)
7580 skip = MOVE_POS_MATCH_OR_ZV;
7581 else
7582 skip = move_it_in_display_line_to (it, to_charpos, -1, MOVE_TO_POS);
7583
7584 switch (skip)
7585 {
7586 case MOVE_POS_MATCH_OR_ZV:
7587 reached = 8;
7588 goto out;
7589
7590 case MOVE_NEWLINE_OR_CR:
7591 set_iterator_to_next (it, 1);
7592 it->continuation_lines_width = 0;
7593 break;
7594
7595 case MOVE_LINE_TRUNCATED:
7596 it->continuation_lines_width = 0;
7597 reseat_at_next_visible_line_start (it, 0);
7598 if ((op & MOVE_TO_POS) != 0
7599 && IT_CHARPOS (*it) > to_charpos)
7600 {
7601 reached = 9;
7602 goto out;
7603 }
7604 break;
7605
7606 case MOVE_LINE_CONTINUED:
7607 /* For continued lines ending in a tab, some of the glyphs
7608 associated with the tab are displayed on the current
7609 line. Since it->current_x does not include these glyphs,
7610 we use it->last_visible_x instead. */
7611 if (it->c == '\t')
7612 {
7613 it->continuation_lines_width += it->last_visible_x;
7614 /* When moving by vpos, ensure that the iterator really
7615 advances to the next line (bug#847, bug#969). Fixme:
7616 do we need to do this in other circumstances? */
7617 if (it->current_x != it->last_visible_x
7618 && (op & MOVE_TO_VPOS)
7619 && !(op & (MOVE_TO_X | MOVE_TO_POS)))
7620 {
7621 line_start_x = it->current_x + it->pixel_width
7622 - it->last_visible_x;
7623 set_iterator_to_next (it, 0);
7624 }
7625 }
7626 else
7627 it->continuation_lines_width += it->current_x;
7628 break;
7629
7630 default:
7631 abort ();
7632 }
7633
7634 /* Reset/increment for the next run. */
7635 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
7636 it->current_x = line_start_x;
7637 line_start_x = 0;
7638 it->hpos = 0;
7639 it->current_y += it->max_ascent + it->max_descent;
7640 ++it->vpos;
7641 last_height = it->max_ascent + it->max_descent;
7642 last_max_ascent = it->max_ascent;
7643 it->max_ascent = it->max_descent = 0;
7644 }
7645
7646 out:
7647
7648 /* On text terminals, we may stop at the end of a line in the middle
7649 of a multi-character glyph. If the glyph itself is continued,
7650 i.e. it is actually displayed on the next line, don't treat this
7651 stopping point as valid; move to the next line instead (unless
7652 that brings us offscreen). */
7653 if (!FRAME_WINDOW_P (it->f)
7654 && op & MOVE_TO_POS
7655 && IT_CHARPOS (*it) == to_charpos
7656 && it->what == IT_CHARACTER
7657 && it->nglyphs > 1
7658 && it->line_wrap == WINDOW_WRAP
7659 && it->current_x == it->last_visible_x - 1
7660 && it->c != '\n'
7661 && it->c != '\t'
7662 && it->vpos < XFASTINT (it->w->window_end_vpos))
7663 {
7664 it->continuation_lines_width += it->current_x;
7665 it->current_x = it->hpos = it->max_ascent = it->max_descent = 0;
7666 it->current_y += it->max_ascent + it->max_descent;
7667 ++it->vpos;
7668 last_height = it->max_ascent + it->max_descent;
7669 last_max_ascent = it->max_ascent;
7670 }
7671
7672 TRACE_MOVE ((stderr, "move_it_to: reached %d\n", reached));
7673 }
7674
7675
7676 /* Move iterator IT backward by a specified y-distance DY, DY >= 0.
7677
7678 If DY > 0, move IT backward at least that many pixels. DY = 0
7679 means move IT backward to the preceding line start or BEGV. This
7680 function may move over more than DY pixels if IT->current_y - DY
7681 ends up in the middle of a line; in this case IT->current_y will be
7682 set to the top of the line moved to. */
7683
7684 void
7685 move_it_vertically_backward (struct it *it, int dy)
7686 {
7687 int nlines, h;
7688 struct it it2, it3;
7689 int start_pos;
7690
7691 move_further_back:
7692 xassert (dy >= 0);
7693
7694 start_pos = IT_CHARPOS (*it);
7695
7696 /* Estimate how many newlines we must move back. */
7697 nlines = max (1, dy / FRAME_LINE_HEIGHT (it->f));
7698
7699 /* Set the iterator's position that many lines back. */
7700 while (nlines-- && IT_CHARPOS (*it) > BEGV)
7701 back_to_previous_visible_line_start (it);
7702
7703 /* Reseat the iterator here. When moving backward, we don't want
7704 reseat to skip forward over invisible text, set up the iterator
7705 to deliver from overlay strings at the new position etc. So,
7706 use reseat_1 here. */
7707 reseat_1 (it, it->current.pos, 1);
7708
7709 /* We are now surely at a line start. */
7710 it->current_x = it->hpos = 0;
7711 it->continuation_lines_width = 0;
7712
7713 /* Move forward and see what y-distance we moved. First move to the
7714 start of the next line so that we get its height. We need this
7715 height to be able to tell whether we reached the specified
7716 y-distance. */
7717 it2 = *it;
7718 it2.max_ascent = it2.max_descent = 0;
7719 do
7720 {
7721 move_it_to (&it2, start_pos, -1, -1, it2.vpos + 1,
7722 MOVE_TO_POS | MOVE_TO_VPOS);
7723 }
7724 while (!IT_POS_VALID_AFTER_MOVE_P (&it2));
7725 xassert (IT_CHARPOS (*it) >= BEGV);
7726 it3 = it2;
7727
7728 move_it_to (&it2, start_pos, -1, -1, -1, MOVE_TO_POS);
7729 xassert (IT_CHARPOS (*it) >= BEGV);
7730 /* H is the actual vertical distance from the position in *IT
7731 and the starting position. */
7732 h = it2.current_y - it->current_y;
7733 /* NLINES is the distance in number of lines. */
7734 nlines = it2.vpos - it->vpos;
7735
7736 /* Correct IT's y and vpos position
7737 so that they are relative to the starting point. */
7738 it->vpos -= nlines;
7739 it->current_y -= h;
7740
7741 if (dy == 0)
7742 {
7743 /* DY == 0 means move to the start of the screen line. The
7744 value of nlines is > 0 if continuation lines were involved. */
7745 if (nlines > 0)
7746 move_it_by_lines (it, nlines, 1);
7747 }
7748 else
7749 {
7750 /* The y-position we try to reach, relative to *IT.
7751 Note that H has been subtracted in front of the if-statement. */
7752 int target_y = it->current_y + h - dy;
7753 int y0 = it3.current_y;
7754 int y1 = line_bottom_y (&it3);
7755 int line_height = y1 - y0;
7756
7757 /* If we did not reach target_y, try to move further backward if
7758 we can. If we moved too far backward, try to move forward. */
7759 if (target_y < it->current_y
7760 /* This is heuristic. In a window that's 3 lines high, with
7761 a line height of 13 pixels each, recentering with point
7762 on the bottom line will try to move -39/2 = 19 pixels
7763 backward. Try to avoid moving into the first line. */
7764 && (it->current_y - target_y
7765 > min (window_box_height (it->w), line_height * 2 / 3))
7766 && IT_CHARPOS (*it) > BEGV)
7767 {
7768 TRACE_MOVE ((stderr, " not far enough -> move_vert %d\n",
7769 target_y - it->current_y));
7770 dy = it->current_y - target_y;
7771 goto move_further_back;
7772 }
7773 else if (target_y >= it->current_y + line_height
7774 && IT_CHARPOS (*it) < ZV)
7775 {
7776 /* Should move forward by at least one line, maybe more.
7777
7778 Note: Calling move_it_by_lines can be expensive on
7779 terminal frames, where compute_motion is used (via
7780 vmotion) to do the job, when there are very long lines
7781 and truncate-lines is nil. That's the reason for
7782 treating terminal frames specially here. */
7783
7784 if (!FRAME_WINDOW_P (it->f))
7785 move_it_vertically (it, target_y - (it->current_y + line_height));
7786 else
7787 {
7788 do
7789 {
7790 move_it_by_lines (it, 1, 1);
7791 }
7792 while (target_y >= line_bottom_y (it) && IT_CHARPOS (*it) < ZV);
7793 }
7794 }
7795 }
7796 }
7797
7798
7799 /* Move IT by a specified amount of pixel lines DY. DY negative means
7800 move backwards. DY = 0 means move to start of screen line. At the
7801 end, IT will be on the start of a screen line. */
7802
7803 void
7804 move_it_vertically (struct it *it, int dy)
7805 {
7806 if (dy <= 0)
7807 move_it_vertically_backward (it, -dy);
7808 else
7809 {
7810 TRACE_MOVE ((stderr, "move_it_v: from %d, %d\n", IT_CHARPOS (*it), dy));
7811 move_it_to (it, ZV, -1, it->current_y + dy, -1,
7812 MOVE_TO_POS | MOVE_TO_Y);
7813 TRACE_MOVE ((stderr, "move_it_v: to %d\n", IT_CHARPOS (*it)));
7814
7815 /* If buffer ends in ZV without a newline, move to the start of
7816 the line to satisfy the post-condition. */
7817 if (IT_CHARPOS (*it) == ZV
7818 && ZV > BEGV
7819 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
7820 move_it_by_lines (it, 0, 0);
7821 }
7822 }
7823
7824
7825 /* Move iterator IT past the end of the text line it is in. */
7826
7827 void
7828 move_it_past_eol (struct it *it)
7829 {
7830 enum move_it_result rc;
7831
7832 rc = move_it_in_display_line_to (it, Z, 0, MOVE_TO_POS);
7833 if (rc == MOVE_NEWLINE_OR_CR)
7834 set_iterator_to_next (it, 0);
7835 }
7836
7837
7838 /* Move IT by a specified number DVPOS of screen lines down. DVPOS
7839 negative means move up. DVPOS == 0 means move to the start of the
7840 screen line. NEED_Y_P non-zero means calculate IT->current_y. If
7841 NEED_Y_P is zero, IT->current_y will be left unchanged.
7842
7843 Further optimization ideas: If we would know that IT->f doesn't use
7844 a face with proportional font, we could be faster for
7845 truncate-lines nil. */
7846
7847 void
7848 move_it_by_lines (struct it *it, int dvpos, int need_y_p)
7849 {
7850 struct position pos;
7851
7852 /* The commented-out optimization uses vmotion on terminals. This
7853 gives bad results, because elements like it->what, on which
7854 callers such as pos_visible_p rely, aren't updated. */
7855 /* if (!FRAME_WINDOW_P (it->f))
7856 {
7857 struct text_pos textpos;
7858
7859 pos = *vmotion (IT_CHARPOS (*it), dvpos, it->w);
7860 SET_TEXT_POS (textpos, pos.bufpos, pos.bytepos);
7861 reseat (it, textpos, 1);
7862 it->vpos += pos.vpos;
7863 it->current_y += pos.vpos;
7864 }
7865 else */
7866
7867 if (dvpos == 0)
7868 {
7869 /* DVPOS == 0 means move to the start of the screen line. */
7870 move_it_vertically_backward (it, 0);
7871 xassert (it->current_x == 0 && it->hpos == 0);
7872 /* Let next call to line_bottom_y calculate real line height */
7873 last_height = 0;
7874 }
7875 else if (dvpos > 0)
7876 {
7877 move_it_to (it, -1, -1, -1, it->vpos + dvpos, MOVE_TO_VPOS);
7878 if (!IT_POS_VALID_AFTER_MOVE_P (it))
7879 move_it_to (it, IT_CHARPOS (*it) + 1, -1, -1, -1, MOVE_TO_POS);
7880 }
7881 else
7882 {
7883 struct it it2;
7884 int start_charpos, i;
7885
7886 /* Start at the beginning of the screen line containing IT's
7887 position. This may actually move vertically backwards,
7888 in case of overlays, so adjust dvpos accordingly. */
7889 dvpos += it->vpos;
7890 move_it_vertically_backward (it, 0);
7891 dvpos -= it->vpos;
7892
7893 /* Go back -DVPOS visible lines and reseat the iterator there. */
7894 start_charpos = IT_CHARPOS (*it);
7895 for (i = -dvpos; i > 0 && IT_CHARPOS (*it) > BEGV; --i)
7896 back_to_previous_visible_line_start (it);
7897 reseat (it, it->current.pos, 1);
7898
7899 /* Move further back if we end up in a string or an image. */
7900 while (!IT_POS_VALID_AFTER_MOVE_P (it))
7901 {
7902 /* First try to move to start of display line. */
7903 dvpos += it->vpos;
7904 move_it_vertically_backward (it, 0);
7905 dvpos -= it->vpos;
7906 if (IT_POS_VALID_AFTER_MOVE_P (it))
7907 break;
7908 /* If start of line is still in string or image,
7909 move further back. */
7910 back_to_previous_visible_line_start (it);
7911 reseat (it, it->current.pos, 1);
7912 dvpos--;
7913 }
7914
7915 it->current_x = it->hpos = 0;
7916
7917 /* Above call may have moved too far if continuation lines
7918 are involved. Scan forward and see if it did. */
7919 it2 = *it;
7920 it2.vpos = it2.current_y = 0;
7921 move_it_to (&it2, start_charpos, -1, -1, -1, MOVE_TO_POS);
7922 it->vpos -= it2.vpos;
7923 it->current_y -= it2.current_y;
7924 it->current_x = it->hpos = 0;
7925
7926 /* If we moved too far back, move IT some lines forward. */
7927 if (it2.vpos > -dvpos)
7928 {
7929 int delta = it2.vpos + dvpos;
7930 it2 = *it;
7931 move_it_to (it, -1, -1, -1, it->vpos + delta, MOVE_TO_VPOS);
7932 /* Move back again if we got too far ahead. */
7933 if (IT_CHARPOS (*it) >= start_charpos)
7934 *it = it2;
7935 }
7936 }
7937 }
7938
7939 /* Return 1 if IT points into the middle of a display vector. */
7940
7941 int
7942 in_display_vector_p (struct it *it)
7943 {
7944 return (it->method == GET_FROM_DISPLAY_VECTOR
7945 && it->current.dpvec_index > 0
7946 && it->dpvec + it->current.dpvec_index != it->dpend);
7947 }
7948
7949 \f
7950 /***********************************************************************
7951 Messages
7952 ***********************************************************************/
7953
7954
7955 /* Add a message with format string FORMAT and arguments ARG1 and ARG2
7956 to *Messages*. */
7957
7958 void
7959 add_to_log (const char *format, Lisp_Object arg1, Lisp_Object arg2)
7960 {
7961 Lisp_Object args[3];
7962 Lisp_Object msg, fmt;
7963 char *buffer;
7964 int len;
7965 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
7966 USE_SAFE_ALLOCA;
7967
7968 /* Do nothing if called asynchronously. Inserting text into
7969 a buffer may call after-change-functions and alike and
7970 that would means running Lisp asynchronously. */
7971 if (handling_signal)
7972 return;
7973
7974 fmt = msg = Qnil;
7975 GCPRO4 (fmt, msg, arg1, arg2);
7976
7977 args[0] = fmt = build_string (format);
7978 args[1] = arg1;
7979 args[2] = arg2;
7980 msg = Fformat (3, args);
7981
7982 len = SBYTES (msg) + 1;
7983 SAFE_ALLOCA (buffer, char *, len);
7984 memcpy (buffer, SDATA (msg), len);
7985
7986 message_dolog (buffer, len - 1, 1, 0);
7987 SAFE_FREE ();
7988
7989 UNGCPRO;
7990 }
7991
7992
7993 /* Output a newline in the *Messages* buffer if "needs" one. */
7994
7995 void
7996 message_log_maybe_newline (void)
7997 {
7998 if (message_log_need_newline)
7999 message_dolog ("", 0, 1, 0);
8000 }
8001
8002
8003 /* Add a string M of length NBYTES to the message log, optionally
8004 terminated with a newline when NLFLAG is non-zero. MULTIBYTE, if
8005 nonzero, means interpret the contents of M as multibyte. This
8006 function calls low-level routines in order to bypass text property
8007 hooks, etc. which might not be safe to run.
8008
8009 This may GC (insert may run before/after change hooks),
8010 so the buffer M must NOT point to a Lisp string. */
8011
8012 void
8013 message_dolog (const char *m, int nbytes, int nlflag, int multibyte)
8014 {
8015 if (!NILP (Vmemory_full))
8016 return;
8017
8018 if (!NILP (Vmessage_log_max))
8019 {
8020 struct buffer *oldbuf;
8021 Lisp_Object oldpoint, oldbegv, oldzv;
8022 int old_windows_or_buffers_changed = windows_or_buffers_changed;
8023 int point_at_end = 0;
8024 int zv_at_end = 0;
8025 Lisp_Object old_deactivate_mark, tem;
8026 struct gcpro gcpro1;
8027
8028 old_deactivate_mark = Vdeactivate_mark;
8029 oldbuf = current_buffer;
8030 Fset_buffer (Fget_buffer_create (Vmessages_buffer_name));
8031 current_buffer->undo_list = Qt;
8032
8033 oldpoint = message_dolog_marker1;
8034 set_marker_restricted (oldpoint, make_number (PT), Qnil);
8035 oldbegv = message_dolog_marker2;
8036 set_marker_restricted (oldbegv, make_number (BEGV), Qnil);
8037 oldzv = message_dolog_marker3;
8038 set_marker_restricted (oldzv, make_number (ZV), Qnil);
8039 GCPRO1 (old_deactivate_mark);
8040
8041 if (PT == Z)
8042 point_at_end = 1;
8043 if (ZV == Z)
8044 zv_at_end = 1;
8045
8046 BEGV = BEG;
8047 BEGV_BYTE = BEG_BYTE;
8048 ZV = Z;
8049 ZV_BYTE = Z_BYTE;
8050 TEMP_SET_PT_BOTH (Z, Z_BYTE);
8051
8052 /* Insert the string--maybe converting multibyte to single byte
8053 or vice versa, so that all the text fits the buffer. */
8054 if (multibyte
8055 && NILP (current_buffer->enable_multibyte_characters))
8056 {
8057 int i, c, char_bytes;
8058 unsigned char work[1];
8059
8060 /* Convert a multibyte string to single-byte
8061 for the *Message* buffer. */
8062 for (i = 0; i < nbytes; i += char_bytes)
8063 {
8064 c = string_char_and_length (m + i, &char_bytes);
8065 work[0] = (ASCII_CHAR_P (c)
8066 ? c
8067 : multibyte_char_to_unibyte (c, Qnil));
8068 insert_1_both (work, 1, 1, 1, 0, 0);
8069 }
8070 }
8071 else if (! multibyte
8072 && ! NILP (current_buffer->enable_multibyte_characters))
8073 {
8074 int i, c, char_bytes;
8075 unsigned char *msg = (unsigned char *) m;
8076 unsigned char str[MAX_MULTIBYTE_LENGTH];
8077 /* Convert a single-byte string to multibyte
8078 for the *Message* buffer. */
8079 for (i = 0; i < nbytes; i++)
8080 {
8081 c = msg[i];
8082 MAKE_CHAR_MULTIBYTE (c);
8083 char_bytes = CHAR_STRING (c, str);
8084 insert_1_both (str, 1, char_bytes, 1, 0, 0);
8085 }
8086 }
8087 else if (nbytes)
8088 insert_1 (m, nbytes, 1, 0, 0);
8089
8090 if (nlflag)
8091 {
8092 int this_bol, this_bol_byte, prev_bol, prev_bol_byte, dup;
8093 insert_1 ("\n", 1, 1, 0, 0);
8094
8095 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE, -2, 0);
8096 this_bol = PT;
8097 this_bol_byte = PT_BYTE;
8098
8099 /* See if this line duplicates the previous one.
8100 If so, combine duplicates. */
8101 if (this_bol > BEG)
8102 {
8103 scan_newline (PT, PT_BYTE, BEG, BEG_BYTE, -2, 0);
8104 prev_bol = PT;
8105 prev_bol_byte = PT_BYTE;
8106
8107 dup = message_log_check_duplicate (prev_bol, prev_bol_byte,
8108 this_bol, this_bol_byte);
8109 if (dup)
8110 {
8111 del_range_both (prev_bol, prev_bol_byte,
8112 this_bol, this_bol_byte, 0);
8113 if (dup > 1)
8114 {
8115 char dupstr[40];
8116 int duplen;
8117
8118 /* If you change this format, don't forget to also
8119 change message_log_check_duplicate. */
8120 sprintf (dupstr, " [%d times]", dup);
8121 duplen = strlen (dupstr);
8122 TEMP_SET_PT_BOTH (Z - 1, Z_BYTE - 1);
8123 insert_1 (dupstr, duplen, 1, 0, 1);
8124 }
8125 }
8126 }
8127
8128 /* If we have more than the desired maximum number of lines
8129 in the *Messages* buffer now, delete the oldest ones.
8130 This is safe because we don't have undo in this buffer. */
8131
8132 if (NATNUMP (Vmessage_log_max))
8133 {
8134 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE,
8135 -XFASTINT (Vmessage_log_max) - 1, 0);
8136 del_range_both (BEG, BEG_BYTE, PT, PT_BYTE, 0);
8137 }
8138 }
8139 BEGV = XMARKER (oldbegv)->charpos;
8140 BEGV_BYTE = marker_byte_position (oldbegv);
8141
8142 if (zv_at_end)
8143 {
8144 ZV = Z;
8145 ZV_BYTE = Z_BYTE;
8146 }
8147 else
8148 {
8149 ZV = XMARKER (oldzv)->charpos;
8150 ZV_BYTE = marker_byte_position (oldzv);
8151 }
8152
8153 if (point_at_end)
8154 TEMP_SET_PT_BOTH (Z, Z_BYTE);
8155 else
8156 /* We can't do Fgoto_char (oldpoint) because it will run some
8157 Lisp code. */
8158 TEMP_SET_PT_BOTH (XMARKER (oldpoint)->charpos,
8159 XMARKER (oldpoint)->bytepos);
8160
8161 UNGCPRO;
8162 unchain_marker (XMARKER (oldpoint));
8163 unchain_marker (XMARKER (oldbegv));
8164 unchain_marker (XMARKER (oldzv));
8165
8166 tem = Fget_buffer_window (Fcurrent_buffer (), Qt);
8167 set_buffer_internal (oldbuf);
8168 if (NILP (tem))
8169 windows_or_buffers_changed = old_windows_or_buffers_changed;
8170 message_log_need_newline = !nlflag;
8171 Vdeactivate_mark = old_deactivate_mark;
8172 }
8173 }
8174
8175
8176 /* We are at the end of the buffer after just having inserted a newline.
8177 (Note: We depend on the fact we won't be crossing the gap.)
8178 Check to see if the most recent message looks a lot like the previous one.
8179 Return 0 if different, 1 if the new one should just replace it, or a
8180 value N > 1 if we should also append " [N times]". */
8181
8182 static int
8183 message_log_check_duplicate (int prev_bol, int prev_bol_byte,
8184 int this_bol, int this_bol_byte)
8185 {
8186 int i;
8187 int len = Z_BYTE - 1 - this_bol_byte;
8188 int seen_dots = 0;
8189 unsigned char *p1 = BUF_BYTE_ADDRESS (current_buffer, prev_bol_byte);
8190 unsigned char *p2 = BUF_BYTE_ADDRESS (current_buffer, this_bol_byte);
8191
8192 for (i = 0; i < len; i++)
8193 {
8194 if (i >= 3 && p1[i-3] == '.' && p1[i-2] == '.' && p1[i-1] == '.')
8195 seen_dots = 1;
8196 if (p1[i] != p2[i])
8197 return seen_dots;
8198 }
8199 p1 += len;
8200 if (*p1 == '\n')
8201 return 2;
8202 if (*p1++ == ' ' && *p1++ == '[')
8203 {
8204 int n = 0;
8205 while (*p1 >= '0' && *p1 <= '9')
8206 n = n * 10 + *p1++ - '0';
8207 if (strncmp (p1, " times]\n", 8) == 0)
8208 return n+1;
8209 }
8210 return 0;
8211 }
8212 \f
8213
8214 /* Display an echo area message M with a specified length of NBYTES
8215 bytes. The string may include null characters. If M is 0, clear
8216 out any existing message, and let the mini-buffer text show
8217 through.
8218
8219 This may GC, so the buffer M must NOT point to a Lisp string. */
8220
8221 void
8222 message2 (const char *m, int nbytes, int multibyte)
8223 {
8224 /* First flush out any partial line written with print. */
8225 message_log_maybe_newline ();
8226 if (m)
8227 message_dolog (m, nbytes, 1, multibyte);
8228 message2_nolog (m, nbytes, multibyte);
8229 }
8230
8231
8232 /* The non-logging counterpart of message2. */
8233
8234 void
8235 message2_nolog (const char *m, int nbytes, int multibyte)
8236 {
8237 struct frame *sf = SELECTED_FRAME ();
8238 message_enable_multibyte = multibyte;
8239
8240 if (FRAME_INITIAL_P (sf))
8241 {
8242 if (noninteractive_need_newline)
8243 putc ('\n', stderr);
8244 noninteractive_need_newline = 0;
8245 if (m)
8246 fwrite (m, nbytes, 1, stderr);
8247 if (cursor_in_echo_area == 0)
8248 fprintf (stderr, "\n");
8249 fflush (stderr);
8250 }
8251 /* A null message buffer means that the frame hasn't really been
8252 initialized yet. Error messages get reported properly by
8253 cmd_error, so this must be just an informative message; toss it. */
8254 else if (INTERACTIVE
8255 && sf->glyphs_initialized_p
8256 && FRAME_MESSAGE_BUF (sf))
8257 {
8258 Lisp_Object mini_window;
8259 struct frame *f;
8260
8261 /* Get the frame containing the mini-buffer
8262 that the selected frame is using. */
8263 mini_window = FRAME_MINIBUF_WINDOW (sf);
8264 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
8265
8266 FRAME_SAMPLE_VISIBILITY (f);
8267 if (FRAME_VISIBLE_P (sf)
8268 && ! FRAME_VISIBLE_P (f))
8269 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (mini_window)));
8270
8271 if (m)
8272 {
8273 set_message (m, Qnil, nbytes, multibyte);
8274 if (minibuffer_auto_raise)
8275 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
8276 }
8277 else
8278 clear_message (1, 1);
8279
8280 do_pending_window_change (0);
8281 echo_area_display (1);
8282 do_pending_window_change (0);
8283 if (FRAME_TERMINAL (f)->frame_up_to_date_hook != 0 && ! gc_in_progress)
8284 (*FRAME_TERMINAL (f)->frame_up_to_date_hook) (f);
8285 }
8286 }
8287
8288
8289 /* Display an echo area message M with a specified length of NBYTES
8290 bytes. The string may include null characters. If M is not a
8291 string, clear out any existing message, and let the mini-buffer
8292 text show through.
8293
8294 This function cancels echoing. */
8295
8296 void
8297 message3 (Lisp_Object m, int nbytes, int multibyte)
8298 {
8299 struct gcpro gcpro1;
8300
8301 GCPRO1 (m);
8302 clear_message (1,1);
8303 cancel_echoing ();
8304
8305 /* First flush out any partial line written with print. */
8306 message_log_maybe_newline ();
8307 if (STRINGP (m))
8308 {
8309 char *buffer;
8310 USE_SAFE_ALLOCA;
8311
8312 SAFE_ALLOCA (buffer, char *, nbytes);
8313 memcpy (buffer, SDATA (m), nbytes);
8314 message_dolog (buffer, nbytes, 1, multibyte);
8315 SAFE_FREE ();
8316 }
8317 message3_nolog (m, nbytes, multibyte);
8318
8319 UNGCPRO;
8320 }
8321
8322
8323 /* The non-logging version of message3.
8324 This does not cancel echoing, because it is used for echoing.
8325 Perhaps we need to make a separate function for echoing
8326 and make this cancel echoing. */
8327
8328 void
8329 message3_nolog (Lisp_Object m, int nbytes, int multibyte)
8330 {
8331 struct frame *sf = SELECTED_FRAME ();
8332 message_enable_multibyte = multibyte;
8333
8334 if (FRAME_INITIAL_P (sf))
8335 {
8336 if (noninteractive_need_newline)
8337 putc ('\n', stderr);
8338 noninteractive_need_newline = 0;
8339 if (STRINGP (m))
8340 fwrite (SDATA (m), nbytes, 1, stderr);
8341 if (cursor_in_echo_area == 0)
8342 fprintf (stderr, "\n");
8343 fflush (stderr);
8344 }
8345 /* A null message buffer means that the frame hasn't really been
8346 initialized yet. Error messages get reported properly by
8347 cmd_error, so this must be just an informative message; toss it. */
8348 else if (INTERACTIVE
8349 && sf->glyphs_initialized_p
8350 && FRAME_MESSAGE_BUF (sf))
8351 {
8352 Lisp_Object mini_window;
8353 Lisp_Object frame;
8354 struct frame *f;
8355
8356 /* Get the frame containing the mini-buffer
8357 that the selected frame is using. */
8358 mini_window = FRAME_MINIBUF_WINDOW (sf);
8359 frame = XWINDOW (mini_window)->frame;
8360 f = XFRAME (frame);
8361
8362 FRAME_SAMPLE_VISIBILITY (f);
8363 if (FRAME_VISIBLE_P (sf)
8364 && !FRAME_VISIBLE_P (f))
8365 Fmake_frame_visible (frame);
8366
8367 if (STRINGP (m) && SCHARS (m) > 0)
8368 {
8369 set_message (NULL, m, nbytes, multibyte);
8370 if (minibuffer_auto_raise)
8371 Fraise_frame (frame);
8372 /* Assume we are not echoing.
8373 (If we are, echo_now will override this.) */
8374 echo_message_buffer = Qnil;
8375 }
8376 else
8377 clear_message (1, 1);
8378
8379 do_pending_window_change (0);
8380 echo_area_display (1);
8381 do_pending_window_change (0);
8382 if (FRAME_TERMINAL (f)->frame_up_to_date_hook != 0 && ! gc_in_progress)
8383 (*FRAME_TERMINAL (f)->frame_up_to_date_hook) (f);
8384 }
8385 }
8386
8387
8388 /* Display a null-terminated echo area message M. If M is 0, clear
8389 out any existing message, and let the mini-buffer text show through.
8390
8391 The buffer M must continue to exist until after the echo area gets
8392 cleared or some other message gets displayed there. Do not pass
8393 text that is stored in a Lisp string. Do not pass text in a buffer
8394 that was alloca'd. */
8395
8396 void
8397 message1 (const char *m)
8398 {
8399 message2 (m, (m ? strlen (m) : 0), 0);
8400 }
8401
8402
8403 /* The non-logging counterpart of message1. */
8404
8405 void
8406 message1_nolog (const char *m)
8407 {
8408 message2_nolog (m, (m ? strlen (m) : 0), 0);
8409 }
8410
8411 /* Display a message M which contains a single %s
8412 which gets replaced with STRING. */
8413
8414 void
8415 message_with_string (const char *m, Lisp_Object string, int log)
8416 {
8417 CHECK_STRING (string);
8418
8419 if (noninteractive)
8420 {
8421 if (m)
8422 {
8423 if (noninteractive_need_newline)
8424 putc ('\n', stderr);
8425 noninteractive_need_newline = 0;
8426 fprintf (stderr, m, SDATA (string));
8427 if (!cursor_in_echo_area)
8428 fprintf (stderr, "\n");
8429 fflush (stderr);
8430 }
8431 }
8432 else if (INTERACTIVE)
8433 {
8434 /* The frame whose minibuffer we're going to display the message on.
8435 It may be larger than the selected frame, so we need
8436 to use its buffer, not the selected frame's buffer. */
8437 Lisp_Object mini_window;
8438 struct frame *f, *sf = SELECTED_FRAME ();
8439
8440 /* Get the frame containing the minibuffer
8441 that the selected frame is using. */
8442 mini_window = FRAME_MINIBUF_WINDOW (sf);
8443 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
8444
8445 /* A null message buffer means that the frame hasn't really been
8446 initialized yet. Error messages get reported properly by
8447 cmd_error, so this must be just an informative message; toss it. */
8448 if (FRAME_MESSAGE_BUF (f))
8449 {
8450 Lisp_Object args[2], message;
8451 struct gcpro gcpro1, gcpro2;
8452
8453 args[0] = build_string (m);
8454 args[1] = message = string;
8455 GCPRO2 (args[0], message);
8456 gcpro1.nvars = 2;
8457
8458 message = Fformat (2, args);
8459
8460 if (log)
8461 message3 (message, SBYTES (message), STRING_MULTIBYTE (message));
8462 else
8463 message3_nolog (message, SBYTES (message), STRING_MULTIBYTE (message));
8464
8465 UNGCPRO;
8466
8467 /* Print should start at the beginning of the message
8468 buffer next time. */
8469 message_buf_print = 0;
8470 }
8471 }
8472 }
8473
8474
8475 /* Dump an informative message to the minibuf. If M is 0, clear out
8476 any existing message, and let the mini-buffer text show through. */
8477
8478 static void
8479 vmessage (const char *m, va_list ap)
8480 {
8481 if (noninteractive)
8482 {
8483 if (m)
8484 {
8485 if (noninteractive_need_newline)
8486 putc ('\n', stderr);
8487 noninteractive_need_newline = 0;
8488 vfprintf (stderr, m, ap);
8489 if (cursor_in_echo_area == 0)
8490 fprintf (stderr, "\n");
8491 fflush (stderr);
8492 }
8493 }
8494 else if (INTERACTIVE)
8495 {
8496 /* The frame whose mini-buffer we're going to display the message
8497 on. It may be larger than the selected frame, so we need to
8498 use its buffer, not the selected frame's buffer. */
8499 Lisp_Object mini_window;
8500 struct frame *f, *sf = SELECTED_FRAME ();
8501
8502 /* Get the frame containing the mini-buffer
8503 that the selected frame is using. */
8504 mini_window = FRAME_MINIBUF_WINDOW (sf);
8505 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
8506
8507 /* A null message buffer means that the frame hasn't really been
8508 initialized yet. Error messages get reported properly by
8509 cmd_error, so this must be just an informative message; toss
8510 it. */
8511 if (FRAME_MESSAGE_BUF (f))
8512 {
8513 if (m)
8514 {
8515 int len;
8516
8517 len = doprnt (FRAME_MESSAGE_BUF (f),
8518 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, ap);
8519
8520 message2 (FRAME_MESSAGE_BUF (f), len, 0);
8521 }
8522 else
8523 message1 (0);
8524
8525 /* Print should start at the beginning of the message
8526 buffer next time. */
8527 message_buf_print = 0;
8528 }
8529 }
8530 }
8531
8532 void
8533 message (const char *m, ...)
8534 {
8535 va_list ap;
8536 va_start (ap, m);
8537 vmessage (m, ap);
8538 va_end (ap);
8539 }
8540
8541
8542 /* The non-logging version of message. */
8543
8544 void
8545 message_nolog (const char *m, ...)
8546 {
8547 Lisp_Object old_log_max;
8548 va_list ap;
8549 va_start (ap, m);
8550 old_log_max = Vmessage_log_max;
8551 Vmessage_log_max = Qnil;
8552 vmessage (m, ap);
8553 Vmessage_log_max = old_log_max;
8554 va_end (ap);
8555 }
8556
8557
8558 /* Display the current message in the current mini-buffer. This is
8559 only called from error handlers in process.c, and is not time
8560 critical. */
8561
8562 void
8563 update_echo_area (void)
8564 {
8565 if (!NILP (echo_area_buffer[0]))
8566 {
8567 Lisp_Object string;
8568 string = Fcurrent_message ();
8569 message3 (string, SBYTES (string),
8570 !NILP (current_buffer->enable_multibyte_characters));
8571 }
8572 }
8573
8574
8575 /* Make sure echo area buffers in `echo_buffers' are live.
8576 If they aren't, make new ones. */
8577
8578 static void
8579 ensure_echo_area_buffers (void)
8580 {
8581 int i;
8582
8583 for (i = 0; i < 2; ++i)
8584 if (!BUFFERP (echo_buffer[i])
8585 || NILP (XBUFFER (echo_buffer[i])->name))
8586 {
8587 char name[30];
8588 Lisp_Object old_buffer;
8589 int j;
8590
8591 old_buffer = echo_buffer[i];
8592 sprintf (name, " *Echo Area %d*", i);
8593 echo_buffer[i] = Fget_buffer_create (build_string (name));
8594 XBUFFER (echo_buffer[i])->truncate_lines = Qnil;
8595 /* to force word wrap in echo area -
8596 it was decided to postpone this*/
8597 /* XBUFFER (echo_buffer[i])->word_wrap = Qt; */
8598
8599 for (j = 0; j < 2; ++j)
8600 if (EQ (old_buffer, echo_area_buffer[j]))
8601 echo_area_buffer[j] = echo_buffer[i];
8602 }
8603 }
8604
8605
8606 /* Call FN with args A1..A4 with either the current or last displayed
8607 echo_area_buffer as current buffer.
8608
8609 WHICH zero means use the current message buffer
8610 echo_area_buffer[0]. If that is nil, choose a suitable buffer
8611 from echo_buffer[] and clear it.
8612
8613 WHICH > 0 means use echo_area_buffer[1]. If that is nil, choose a
8614 suitable buffer from echo_buffer[] and clear it.
8615
8616 If WHICH < 0, set echo_area_buffer[1] to echo_area_buffer[0], so
8617 that the current message becomes the last displayed one, make
8618 choose a suitable buffer for echo_area_buffer[0], and clear it.
8619
8620 Value is what FN returns. */
8621
8622 static int
8623 with_echo_area_buffer (struct window *w, int which,
8624 int (*fn) (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT),
8625 EMACS_INT a1, Lisp_Object a2, EMACS_INT a3, EMACS_INT a4)
8626 {
8627 Lisp_Object buffer;
8628 int this_one, the_other, clear_buffer_p, rc;
8629 int count = SPECPDL_INDEX ();
8630
8631 /* If buffers aren't live, make new ones. */
8632 ensure_echo_area_buffers ();
8633
8634 clear_buffer_p = 0;
8635
8636 if (which == 0)
8637 this_one = 0, the_other = 1;
8638 else if (which > 0)
8639 this_one = 1, the_other = 0;
8640 else
8641 {
8642 this_one = 0, the_other = 1;
8643 clear_buffer_p = 1;
8644
8645 /* We need a fresh one in case the current echo buffer equals
8646 the one containing the last displayed echo area message. */
8647 if (!NILP (echo_area_buffer[this_one])
8648 && EQ (echo_area_buffer[this_one], echo_area_buffer[the_other]))
8649 echo_area_buffer[this_one] = Qnil;
8650 }
8651
8652 /* Choose a suitable buffer from echo_buffer[] is we don't
8653 have one. */
8654 if (NILP (echo_area_buffer[this_one]))
8655 {
8656 echo_area_buffer[this_one]
8657 = (EQ (echo_area_buffer[the_other], echo_buffer[this_one])
8658 ? echo_buffer[the_other]
8659 : echo_buffer[this_one]);
8660 clear_buffer_p = 1;
8661 }
8662
8663 buffer = echo_area_buffer[this_one];
8664
8665 /* Don't get confused by reusing the buffer used for echoing
8666 for a different purpose. */
8667 if (echo_kboard == NULL && EQ (buffer, echo_message_buffer))
8668 cancel_echoing ();
8669
8670 record_unwind_protect (unwind_with_echo_area_buffer,
8671 with_echo_area_buffer_unwind_data (w));
8672
8673 /* Make the echo area buffer current. Note that for display
8674 purposes, it is not necessary that the displayed window's buffer
8675 == current_buffer, except for text property lookup. So, let's
8676 only set that buffer temporarily here without doing a full
8677 Fset_window_buffer. We must also change w->pointm, though,
8678 because otherwise an assertions in unshow_buffer fails, and Emacs
8679 aborts. */
8680 set_buffer_internal_1 (XBUFFER (buffer));
8681 if (w)
8682 {
8683 w->buffer = buffer;
8684 set_marker_both (w->pointm, buffer, BEG, BEG_BYTE);
8685 }
8686
8687 current_buffer->undo_list = Qt;
8688 current_buffer->read_only = Qnil;
8689 specbind (Qinhibit_read_only, Qt);
8690 specbind (Qinhibit_modification_hooks, Qt);
8691
8692 if (clear_buffer_p && Z > BEG)
8693 del_range (BEG, Z);
8694
8695 xassert (BEGV >= BEG);
8696 xassert (ZV <= Z && ZV >= BEGV);
8697
8698 rc = fn (a1, a2, a3, a4);
8699
8700 xassert (BEGV >= BEG);
8701 xassert (ZV <= Z && ZV >= BEGV);
8702
8703 unbind_to (count, Qnil);
8704 return rc;
8705 }
8706
8707
8708 /* Save state that should be preserved around the call to the function
8709 FN called in with_echo_area_buffer. */
8710
8711 static Lisp_Object
8712 with_echo_area_buffer_unwind_data (struct window *w)
8713 {
8714 int i = 0;
8715 Lisp_Object vector, tmp;
8716
8717 /* Reduce consing by keeping one vector in
8718 Vwith_echo_area_save_vector. */
8719 vector = Vwith_echo_area_save_vector;
8720 Vwith_echo_area_save_vector = Qnil;
8721
8722 if (NILP (vector))
8723 vector = Fmake_vector (make_number (7), Qnil);
8724
8725 XSETBUFFER (tmp, current_buffer); ASET (vector, i, tmp); ++i;
8726 ASET (vector, i, Vdeactivate_mark); ++i;
8727 ASET (vector, i, make_number (windows_or_buffers_changed)); ++i;
8728
8729 if (w)
8730 {
8731 XSETWINDOW (tmp, w); ASET (vector, i, tmp); ++i;
8732 ASET (vector, i, w->buffer); ++i;
8733 ASET (vector, i, make_number (XMARKER (w->pointm)->charpos)); ++i;
8734 ASET (vector, i, make_number (XMARKER (w->pointm)->bytepos)); ++i;
8735 }
8736 else
8737 {
8738 int end = i + 4;
8739 for (; i < end; ++i)
8740 ASET (vector, i, Qnil);
8741 }
8742
8743 xassert (i == ASIZE (vector));
8744 return vector;
8745 }
8746
8747
8748 /* Restore global state from VECTOR which was created by
8749 with_echo_area_buffer_unwind_data. */
8750
8751 static Lisp_Object
8752 unwind_with_echo_area_buffer (Lisp_Object vector)
8753 {
8754 set_buffer_internal_1 (XBUFFER (AREF (vector, 0)));
8755 Vdeactivate_mark = AREF (vector, 1);
8756 windows_or_buffers_changed = XFASTINT (AREF (vector, 2));
8757
8758 if (WINDOWP (AREF (vector, 3)))
8759 {
8760 struct window *w;
8761 Lisp_Object buffer, charpos, bytepos;
8762
8763 w = XWINDOW (AREF (vector, 3));
8764 buffer = AREF (vector, 4);
8765 charpos = AREF (vector, 5);
8766 bytepos = AREF (vector, 6);
8767
8768 w->buffer = buffer;
8769 set_marker_both (w->pointm, buffer,
8770 XFASTINT (charpos), XFASTINT (bytepos));
8771 }
8772
8773 Vwith_echo_area_save_vector = vector;
8774 return Qnil;
8775 }
8776
8777
8778 /* Set up the echo area for use by print functions. MULTIBYTE_P
8779 non-zero means we will print multibyte. */
8780
8781 void
8782 setup_echo_area_for_printing (int multibyte_p)
8783 {
8784 /* If we can't find an echo area any more, exit. */
8785 if (! FRAME_LIVE_P (XFRAME (selected_frame)))
8786 Fkill_emacs (Qnil);
8787
8788 ensure_echo_area_buffers ();
8789
8790 if (!message_buf_print)
8791 {
8792 /* A message has been output since the last time we printed.
8793 Choose a fresh echo area buffer. */
8794 if (EQ (echo_area_buffer[1], echo_buffer[0]))
8795 echo_area_buffer[0] = echo_buffer[1];
8796 else
8797 echo_area_buffer[0] = echo_buffer[0];
8798
8799 /* Switch to that buffer and clear it. */
8800 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
8801 current_buffer->truncate_lines = Qnil;
8802
8803 if (Z > BEG)
8804 {
8805 int count = SPECPDL_INDEX ();
8806 specbind (Qinhibit_read_only, Qt);
8807 /* Note that undo recording is always disabled. */
8808 del_range (BEG, Z);
8809 unbind_to (count, Qnil);
8810 }
8811 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
8812
8813 /* Set up the buffer for the multibyteness we need. */
8814 if (multibyte_p
8815 != !NILP (current_buffer->enable_multibyte_characters))
8816 Fset_buffer_multibyte (multibyte_p ? Qt : Qnil);
8817
8818 /* Raise the frame containing the echo area. */
8819 if (minibuffer_auto_raise)
8820 {
8821 struct frame *sf = SELECTED_FRAME ();
8822 Lisp_Object mini_window;
8823 mini_window = FRAME_MINIBUF_WINDOW (sf);
8824 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
8825 }
8826
8827 message_log_maybe_newline ();
8828 message_buf_print = 1;
8829 }
8830 else
8831 {
8832 if (NILP (echo_area_buffer[0]))
8833 {
8834 if (EQ (echo_area_buffer[1], echo_buffer[0]))
8835 echo_area_buffer[0] = echo_buffer[1];
8836 else
8837 echo_area_buffer[0] = echo_buffer[0];
8838 }
8839
8840 if (current_buffer != XBUFFER (echo_area_buffer[0]))
8841 {
8842 /* Someone switched buffers between print requests. */
8843 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
8844 current_buffer->truncate_lines = Qnil;
8845 }
8846 }
8847 }
8848
8849
8850 /* Display an echo area message in window W. Value is non-zero if W's
8851 height is changed. If display_last_displayed_message_p is
8852 non-zero, display the message that was last displayed, otherwise
8853 display the current message. */
8854
8855 static int
8856 display_echo_area (struct window *w)
8857 {
8858 int i, no_message_p, window_height_changed_p, count;
8859
8860 /* Temporarily disable garbage collections while displaying the echo
8861 area. This is done because a GC can print a message itself.
8862 That message would modify the echo area buffer's contents while a
8863 redisplay of the buffer is going on, and seriously confuse
8864 redisplay. */
8865 count = inhibit_garbage_collection ();
8866
8867 /* If there is no message, we must call display_echo_area_1
8868 nevertheless because it resizes the window. But we will have to
8869 reset the echo_area_buffer in question to nil at the end because
8870 with_echo_area_buffer will sets it to an empty buffer. */
8871 i = display_last_displayed_message_p ? 1 : 0;
8872 no_message_p = NILP (echo_area_buffer[i]);
8873
8874 window_height_changed_p
8875 = with_echo_area_buffer (w, display_last_displayed_message_p,
8876 display_echo_area_1,
8877 (EMACS_INT) w, Qnil, 0, 0);
8878
8879 if (no_message_p)
8880 echo_area_buffer[i] = Qnil;
8881
8882 unbind_to (count, Qnil);
8883 return window_height_changed_p;
8884 }
8885
8886
8887 /* Helper for display_echo_area. Display the current buffer which
8888 contains the current echo area message in window W, a mini-window,
8889 a pointer to which is passed in A1. A2..A4 are currently not used.
8890 Change the height of W so that all of the message is displayed.
8891 Value is non-zero if height of W was changed. */
8892
8893 static int
8894 display_echo_area_1 (EMACS_INT a1, Lisp_Object a2, EMACS_INT a3, EMACS_INT a4)
8895 {
8896 struct window *w = (struct window *) a1;
8897 Lisp_Object window;
8898 struct text_pos start;
8899 int window_height_changed_p = 0;
8900
8901 /* Do this before displaying, so that we have a large enough glyph
8902 matrix for the display. If we can't get enough space for the
8903 whole text, display the last N lines. That works by setting w->start. */
8904 window_height_changed_p = resize_mini_window (w, 0);
8905
8906 /* Use the starting position chosen by resize_mini_window. */
8907 SET_TEXT_POS_FROM_MARKER (start, w->start);
8908
8909 /* Display. */
8910 clear_glyph_matrix (w->desired_matrix);
8911 XSETWINDOW (window, w);
8912 try_window (window, start, 0);
8913
8914 return window_height_changed_p;
8915 }
8916
8917
8918 /* Resize the echo area window to exactly the size needed for the
8919 currently displayed message, if there is one. If a mini-buffer
8920 is active, don't shrink it. */
8921
8922 void
8923 resize_echo_area_exactly (void)
8924 {
8925 if (BUFFERP (echo_area_buffer[0])
8926 && WINDOWP (echo_area_window))
8927 {
8928 struct window *w = XWINDOW (echo_area_window);
8929 int resized_p;
8930 Lisp_Object resize_exactly;
8931
8932 if (minibuf_level == 0)
8933 resize_exactly = Qt;
8934 else
8935 resize_exactly = Qnil;
8936
8937 resized_p = with_echo_area_buffer (w, 0, resize_mini_window_1,
8938 (EMACS_INT) w, resize_exactly, 0, 0);
8939 if (resized_p)
8940 {
8941 ++windows_or_buffers_changed;
8942 ++update_mode_lines;
8943 redisplay_internal (0);
8944 }
8945 }
8946 }
8947
8948
8949 /* Callback function for with_echo_area_buffer, when used from
8950 resize_echo_area_exactly. A1 contains a pointer to the window to
8951 resize, EXACTLY non-nil means resize the mini-window exactly to the
8952 size of the text displayed. A3 and A4 are not used. Value is what
8953 resize_mini_window returns. */
8954
8955 static int
8956 resize_mini_window_1 (EMACS_INT a1, Lisp_Object exactly, EMACS_INT a3, EMACS_INT a4)
8957 {
8958 return resize_mini_window ((struct window *) a1, !NILP (exactly));
8959 }
8960
8961
8962 /* Resize mini-window W to fit the size of its contents. EXACT_P
8963 means size the window exactly to the size needed. Otherwise, it's
8964 only enlarged until W's buffer is empty.
8965
8966 Set W->start to the right place to begin display. If the whole
8967 contents fit, start at the beginning. Otherwise, start so as
8968 to make the end of the contents appear. This is particularly
8969 important for y-or-n-p, but seems desirable generally.
8970
8971 Value is non-zero if the window height has been changed. */
8972
8973 int
8974 resize_mini_window (struct window *w, int exact_p)
8975 {
8976 struct frame *f = XFRAME (w->frame);
8977 int window_height_changed_p = 0;
8978
8979 xassert (MINI_WINDOW_P (w));
8980
8981 /* By default, start display at the beginning. */
8982 set_marker_both (w->start, w->buffer,
8983 BUF_BEGV (XBUFFER (w->buffer)),
8984 BUF_BEGV_BYTE (XBUFFER (w->buffer)));
8985
8986 /* Don't resize windows while redisplaying a window; it would
8987 confuse redisplay functions when the size of the window they are
8988 displaying changes from under them. Such a resizing can happen,
8989 for instance, when which-func prints a long message while
8990 we are running fontification-functions. We're running these
8991 functions with safe_call which binds inhibit-redisplay to t. */
8992 if (!NILP (Vinhibit_redisplay))
8993 return 0;
8994
8995 /* Nil means don't try to resize. */
8996 if (NILP (Vresize_mini_windows)
8997 || (FRAME_X_P (f) && FRAME_X_OUTPUT (f) == NULL))
8998 return 0;
8999
9000 if (!FRAME_MINIBUF_ONLY_P (f))
9001 {
9002 struct it it;
9003 struct window *root = XWINDOW (FRAME_ROOT_WINDOW (f));
9004 int total_height = WINDOW_TOTAL_LINES (root) + WINDOW_TOTAL_LINES (w);
9005 int height, max_height;
9006 int unit = FRAME_LINE_HEIGHT (f);
9007 struct text_pos start;
9008 struct buffer *old_current_buffer = NULL;
9009
9010 if (current_buffer != XBUFFER (w->buffer))
9011 {
9012 old_current_buffer = current_buffer;
9013 set_buffer_internal (XBUFFER (w->buffer));
9014 }
9015
9016 init_iterator (&it, w, BEGV, BEGV_BYTE, NULL, DEFAULT_FACE_ID);
9017
9018 /* Compute the max. number of lines specified by the user. */
9019 if (FLOATP (Vmax_mini_window_height))
9020 max_height = XFLOATINT (Vmax_mini_window_height) * FRAME_LINES (f);
9021 else if (INTEGERP (Vmax_mini_window_height))
9022 max_height = XINT (Vmax_mini_window_height);
9023 else
9024 max_height = total_height / 4;
9025
9026 /* Correct that max. height if it's bogus. */
9027 max_height = max (1, max_height);
9028 max_height = min (total_height, max_height);
9029
9030 /* Find out the height of the text in the window. */
9031 if (it.line_wrap == TRUNCATE)
9032 height = 1;
9033 else
9034 {
9035 last_height = 0;
9036 move_it_to (&it, ZV, -1, -1, -1, MOVE_TO_POS);
9037 if (it.max_ascent == 0 && it.max_descent == 0)
9038 height = it.current_y + last_height;
9039 else
9040 height = it.current_y + it.max_ascent + it.max_descent;
9041 height -= min (it.extra_line_spacing, it.max_extra_line_spacing);
9042 height = (height + unit - 1) / unit;
9043 }
9044
9045 /* Compute a suitable window start. */
9046 if (height > max_height)
9047 {
9048 height = max_height;
9049 init_iterator (&it, w, ZV, ZV_BYTE, NULL, DEFAULT_FACE_ID);
9050 move_it_vertically_backward (&it, (height - 1) * unit);
9051 start = it.current.pos;
9052 }
9053 else
9054 SET_TEXT_POS (start, BEGV, BEGV_BYTE);
9055 SET_MARKER_FROM_TEXT_POS (w->start, start);
9056
9057 if (EQ (Vresize_mini_windows, Qgrow_only))
9058 {
9059 /* Let it grow only, until we display an empty message, in which
9060 case the window shrinks again. */
9061 if (height > WINDOW_TOTAL_LINES (w))
9062 {
9063 int old_height = WINDOW_TOTAL_LINES (w);
9064 freeze_window_starts (f, 1);
9065 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
9066 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
9067 }
9068 else if (height < WINDOW_TOTAL_LINES (w)
9069 && (exact_p || BEGV == ZV))
9070 {
9071 int old_height = WINDOW_TOTAL_LINES (w);
9072 freeze_window_starts (f, 0);
9073 shrink_mini_window (w);
9074 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
9075 }
9076 }
9077 else
9078 {
9079 /* Always resize to exact size needed. */
9080 if (height > WINDOW_TOTAL_LINES (w))
9081 {
9082 int old_height = WINDOW_TOTAL_LINES (w);
9083 freeze_window_starts (f, 1);
9084 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
9085 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
9086 }
9087 else if (height < WINDOW_TOTAL_LINES (w))
9088 {
9089 int old_height = WINDOW_TOTAL_LINES (w);
9090 freeze_window_starts (f, 0);
9091 shrink_mini_window (w);
9092
9093 if (height)
9094 {
9095 freeze_window_starts (f, 1);
9096 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
9097 }
9098
9099 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
9100 }
9101 }
9102
9103 if (old_current_buffer)
9104 set_buffer_internal (old_current_buffer);
9105 }
9106
9107 return window_height_changed_p;
9108 }
9109
9110
9111 /* Value is the current message, a string, or nil if there is no
9112 current message. */
9113
9114 Lisp_Object
9115 current_message (void)
9116 {
9117 Lisp_Object msg;
9118
9119 if (!BUFFERP (echo_area_buffer[0]))
9120 msg = Qnil;
9121 else
9122 {
9123 with_echo_area_buffer (0, 0, current_message_1,
9124 (EMACS_INT) &msg, Qnil, 0, 0);
9125 if (NILP (msg))
9126 echo_area_buffer[0] = Qnil;
9127 }
9128
9129 return msg;
9130 }
9131
9132
9133 static int
9134 current_message_1 (EMACS_INT a1, Lisp_Object a2, EMACS_INT a3, EMACS_INT a4)
9135 {
9136 Lisp_Object *msg = (Lisp_Object *) a1;
9137
9138 if (Z > BEG)
9139 *msg = make_buffer_string (BEG, Z, 1);
9140 else
9141 *msg = Qnil;
9142 return 0;
9143 }
9144
9145
9146 /* Push the current message on Vmessage_stack for later restauration
9147 by restore_message. Value is non-zero if the current message isn't
9148 empty. This is a relatively infrequent operation, so it's not
9149 worth optimizing. */
9150
9151 int
9152 push_message (void)
9153 {
9154 Lisp_Object msg;
9155 msg = current_message ();
9156 Vmessage_stack = Fcons (msg, Vmessage_stack);
9157 return STRINGP (msg);
9158 }
9159
9160
9161 /* Restore message display from the top of Vmessage_stack. */
9162
9163 void
9164 restore_message (void)
9165 {
9166 Lisp_Object msg;
9167
9168 xassert (CONSP (Vmessage_stack));
9169 msg = XCAR (Vmessage_stack);
9170 if (STRINGP (msg))
9171 message3_nolog (msg, SBYTES (msg), STRING_MULTIBYTE (msg));
9172 else
9173 message3_nolog (msg, 0, 0);
9174 }
9175
9176
9177 /* Handler for record_unwind_protect calling pop_message. */
9178
9179 Lisp_Object
9180 pop_message_unwind (Lisp_Object dummy)
9181 {
9182 pop_message ();
9183 return Qnil;
9184 }
9185
9186 /* Pop the top-most entry off Vmessage_stack. */
9187
9188 void
9189 pop_message (void)
9190 {
9191 xassert (CONSP (Vmessage_stack));
9192 Vmessage_stack = XCDR (Vmessage_stack);
9193 }
9194
9195
9196 /* Check that Vmessage_stack is nil. Called from emacs.c when Emacs
9197 exits. If the stack is not empty, we have a missing pop_message
9198 somewhere. */
9199
9200 void
9201 check_message_stack (void)
9202 {
9203 if (!NILP (Vmessage_stack))
9204 abort ();
9205 }
9206
9207
9208 /* Truncate to NCHARS what will be displayed in the echo area the next
9209 time we display it---but don't redisplay it now. */
9210
9211 void
9212 truncate_echo_area (int nchars)
9213 {
9214 if (nchars == 0)
9215 echo_area_buffer[0] = Qnil;
9216 /* A null message buffer means that the frame hasn't really been
9217 initialized yet. Error messages get reported properly by
9218 cmd_error, so this must be just an informative message; toss it. */
9219 else if (!noninteractive
9220 && INTERACTIVE
9221 && !NILP (echo_area_buffer[0]))
9222 {
9223 struct frame *sf = SELECTED_FRAME ();
9224 if (FRAME_MESSAGE_BUF (sf))
9225 with_echo_area_buffer (0, 0, truncate_message_1, nchars, Qnil, 0, 0);
9226 }
9227 }
9228
9229
9230 /* Helper function for truncate_echo_area. Truncate the current
9231 message to at most NCHARS characters. */
9232
9233 static int
9234 truncate_message_1 (EMACS_INT nchars, Lisp_Object a2, EMACS_INT a3, EMACS_INT a4)
9235 {
9236 if (BEG + nchars < Z)
9237 del_range (BEG + nchars, Z);
9238 if (Z == BEG)
9239 echo_area_buffer[0] = Qnil;
9240 return 0;
9241 }
9242
9243
9244 /* Set the current message to a substring of S or STRING.
9245
9246 If STRING is a Lisp string, set the message to the first NBYTES
9247 bytes from STRING. NBYTES zero means use the whole string. If
9248 STRING is multibyte, the message will be displayed multibyte.
9249
9250 If S is not null, set the message to the first LEN bytes of S. LEN
9251 zero means use the whole string. MULTIBYTE_P non-zero means S is
9252 multibyte. Display the message multibyte in that case.
9253
9254 Doesn't GC, as with_echo_area_buffer binds Qinhibit_modification_hooks
9255 to t before calling set_message_1 (which calls insert).
9256 */
9257
9258 void
9259 set_message (const char *s, Lisp_Object string, int nbytes, int multibyte_p)
9260 {
9261 message_enable_multibyte
9262 = ((s && multibyte_p)
9263 || (STRINGP (string) && STRING_MULTIBYTE (string)));
9264
9265 with_echo_area_buffer (0, -1, set_message_1,
9266 (EMACS_INT) s, string, nbytes, multibyte_p);
9267 message_buf_print = 0;
9268 help_echo_showing_p = 0;
9269 }
9270
9271
9272 /* Helper function for set_message. Arguments have the same meaning
9273 as there, with A1 corresponding to S and A2 corresponding to STRING
9274 This function is called with the echo area buffer being
9275 current. */
9276
9277 static int
9278 set_message_1 (EMACS_INT a1, Lisp_Object a2, EMACS_INT nbytes, EMACS_INT multibyte_p)
9279 {
9280 const char *s = (const char *) a1;
9281 Lisp_Object string = a2;
9282
9283 /* Change multibyteness of the echo buffer appropriately. */
9284 if (message_enable_multibyte
9285 != !NILP (current_buffer->enable_multibyte_characters))
9286 Fset_buffer_multibyte (message_enable_multibyte ? Qt : Qnil);
9287
9288 current_buffer->truncate_lines = message_truncate_lines ? Qt : Qnil;
9289
9290 /* Insert new message at BEG. */
9291 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
9292
9293 if (STRINGP (string))
9294 {
9295 int nchars;
9296
9297 if (nbytes == 0)
9298 nbytes = SBYTES (string);
9299 nchars = string_byte_to_char (string, nbytes);
9300
9301 /* This function takes care of single/multibyte conversion. We
9302 just have to ensure that the echo area buffer has the right
9303 setting of enable_multibyte_characters. */
9304 insert_from_string (string, 0, 0, nchars, nbytes, 1);
9305 }
9306 else if (s)
9307 {
9308 if (nbytes == 0)
9309 nbytes = strlen (s);
9310
9311 if (multibyte_p && NILP (current_buffer->enable_multibyte_characters))
9312 {
9313 /* Convert from multi-byte to single-byte. */
9314 int i, c, n;
9315 unsigned char work[1];
9316
9317 /* Convert a multibyte string to single-byte. */
9318 for (i = 0; i < nbytes; i += n)
9319 {
9320 c = string_char_and_length (s + i, &n);
9321 work[0] = (ASCII_CHAR_P (c)
9322 ? c
9323 : multibyte_char_to_unibyte (c, Qnil));
9324 insert_1_both (work, 1, 1, 1, 0, 0);
9325 }
9326 }
9327 else if (!multibyte_p
9328 && !NILP (current_buffer->enable_multibyte_characters))
9329 {
9330 /* Convert from single-byte to multi-byte. */
9331 int i, c, n;
9332 const unsigned char *msg = (const unsigned char *) s;
9333 unsigned char str[MAX_MULTIBYTE_LENGTH];
9334
9335 /* Convert a single-byte string to multibyte. */
9336 for (i = 0; i < nbytes; i++)
9337 {
9338 c = msg[i];
9339 MAKE_CHAR_MULTIBYTE (c);
9340 n = CHAR_STRING (c, str);
9341 insert_1_both (str, 1, n, 1, 0, 0);
9342 }
9343 }
9344 else
9345 insert_1 (s, nbytes, 1, 0, 0);
9346 }
9347
9348 return 0;
9349 }
9350
9351
9352 /* Clear messages. CURRENT_P non-zero means clear the current
9353 message. LAST_DISPLAYED_P non-zero means clear the message
9354 last displayed. */
9355
9356 void
9357 clear_message (int current_p, int last_displayed_p)
9358 {
9359 if (current_p)
9360 {
9361 echo_area_buffer[0] = Qnil;
9362 message_cleared_p = 1;
9363 }
9364
9365 if (last_displayed_p)
9366 echo_area_buffer[1] = Qnil;
9367
9368 message_buf_print = 0;
9369 }
9370
9371 /* Clear garbaged frames.
9372
9373 This function is used where the old redisplay called
9374 redraw_garbaged_frames which in turn called redraw_frame which in
9375 turn called clear_frame. The call to clear_frame was a source of
9376 flickering. I believe a clear_frame is not necessary. It should
9377 suffice in the new redisplay to invalidate all current matrices,
9378 and ensure a complete redisplay of all windows. */
9379
9380 static void
9381 clear_garbaged_frames (void)
9382 {
9383 if (frame_garbaged)
9384 {
9385 Lisp_Object tail, frame;
9386 int changed_count = 0;
9387
9388 FOR_EACH_FRAME (tail, frame)
9389 {
9390 struct frame *f = XFRAME (frame);
9391
9392 if (FRAME_VISIBLE_P (f) && FRAME_GARBAGED_P (f))
9393 {
9394 if (f->resized_p)
9395 {
9396 Fredraw_frame (frame);
9397 f->force_flush_display_p = 1;
9398 }
9399 clear_current_matrices (f);
9400 changed_count++;
9401 f->garbaged = 0;
9402 f->resized_p = 0;
9403 }
9404 }
9405
9406 frame_garbaged = 0;
9407 if (changed_count)
9408 ++windows_or_buffers_changed;
9409 }
9410 }
9411
9412
9413 /* Redisplay the echo area of the selected frame. If UPDATE_FRAME_P
9414 is non-zero update selected_frame. Value is non-zero if the
9415 mini-windows height has been changed. */
9416
9417 static int
9418 echo_area_display (int update_frame_p)
9419 {
9420 Lisp_Object mini_window;
9421 struct window *w;
9422 struct frame *f;
9423 int window_height_changed_p = 0;
9424 struct frame *sf = SELECTED_FRAME ();
9425
9426 mini_window = FRAME_MINIBUF_WINDOW (sf);
9427 w = XWINDOW (mini_window);
9428 f = XFRAME (WINDOW_FRAME (w));
9429
9430 /* Don't display if frame is invisible or not yet initialized. */
9431 if (!FRAME_VISIBLE_P (f) || !f->glyphs_initialized_p)
9432 return 0;
9433
9434 #ifdef HAVE_WINDOW_SYSTEM
9435 /* When Emacs starts, selected_frame may be the initial terminal
9436 frame. If we let this through, a message would be displayed on
9437 the terminal. */
9438 if (FRAME_INITIAL_P (XFRAME (selected_frame)))
9439 return 0;
9440 #endif /* HAVE_WINDOW_SYSTEM */
9441
9442 /* Redraw garbaged frames. */
9443 if (frame_garbaged)
9444 clear_garbaged_frames ();
9445
9446 if (!NILP (echo_area_buffer[0]) || minibuf_level == 0)
9447 {
9448 echo_area_window = mini_window;
9449 window_height_changed_p = display_echo_area (w);
9450 w->must_be_updated_p = 1;
9451
9452 /* Update the display, unless called from redisplay_internal.
9453 Also don't update the screen during redisplay itself. The
9454 update will happen at the end of redisplay, and an update
9455 here could cause confusion. */
9456 if (update_frame_p && !redisplaying_p)
9457 {
9458 int n = 0;
9459
9460 /* If the display update has been interrupted by pending
9461 input, update mode lines in the frame. Due to the
9462 pending input, it might have been that redisplay hasn't
9463 been called, so that mode lines above the echo area are
9464 garbaged. This looks odd, so we prevent it here. */
9465 if (!display_completed)
9466 n = redisplay_mode_lines (FRAME_ROOT_WINDOW (f), 0);
9467
9468 if (window_height_changed_p
9469 /* Don't do this if Emacs is shutting down. Redisplay
9470 needs to run hooks. */
9471 && !NILP (Vrun_hooks))
9472 {
9473 /* Must update other windows. Likewise as in other
9474 cases, don't let this update be interrupted by
9475 pending input. */
9476 int count = SPECPDL_INDEX ();
9477 specbind (Qredisplay_dont_pause, Qt);
9478 windows_or_buffers_changed = 1;
9479 redisplay_internal (0);
9480 unbind_to (count, Qnil);
9481 }
9482 else if (FRAME_WINDOW_P (f) && n == 0)
9483 {
9484 /* Window configuration is the same as before.
9485 Can do with a display update of the echo area,
9486 unless we displayed some mode lines. */
9487 update_single_window (w, 1);
9488 FRAME_RIF (f)->flush_display (f);
9489 }
9490 else
9491 update_frame (f, 1, 1);
9492
9493 /* If cursor is in the echo area, make sure that the next
9494 redisplay displays the minibuffer, so that the cursor will
9495 be replaced with what the minibuffer wants. */
9496 if (cursor_in_echo_area)
9497 ++windows_or_buffers_changed;
9498 }
9499 }
9500 else if (!EQ (mini_window, selected_window))
9501 windows_or_buffers_changed++;
9502
9503 /* Last displayed message is now the current message. */
9504 echo_area_buffer[1] = echo_area_buffer[0];
9505 /* Inform read_char that we're not echoing. */
9506 echo_message_buffer = Qnil;
9507
9508 /* Prevent redisplay optimization in redisplay_internal by resetting
9509 this_line_start_pos. This is done because the mini-buffer now
9510 displays the message instead of its buffer text. */
9511 if (EQ (mini_window, selected_window))
9512 CHARPOS (this_line_start_pos) = 0;
9513
9514 return window_height_changed_p;
9515 }
9516
9517
9518 \f
9519 /***********************************************************************
9520 Mode Lines and Frame Titles
9521 ***********************************************************************/
9522
9523 /* A buffer for constructing non-propertized mode-line strings and
9524 frame titles in it; allocated from the heap in init_xdisp and
9525 resized as needed in store_mode_line_noprop_char. */
9526
9527 static char *mode_line_noprop_buf;
9528
9529 /* The buffer's end, and a current output position in it. */
9530
9531 static char *mode_line_noprop_buf_end;
9532 static char *mode_line_noprop_ptr;
9533
9534 #define MODE_LINE_NOPROP_LEN(start) \
9535 ((mode_line_noprop_ptr - mode_line_noprop_buf) - start)
9536
9537 static enum {
9538 MODE_LINE_DISPLAY = 0,
9539 MODE_LINE_TITLE,
9540 MODE_LINE_NOPROP,
9541 MODE_LINE_STRING
9542 } mode_line_target;
9543
9544 /* Alist that caches the results of :propertize.
9545 Each element is (PROPERTIZED-STRING . PROPERTY-LIST). */
9546 static Lisp_Object mode_line_proptrans_alist;
9547
9548 /* List of strings making up the mode-line. */
9549 static Lisp_Object mode_line_string_list;
9550
9551 /* Base face property when building propertized mode line string. */
9552 static Lisp_Object mode_line_string_face;
9553 static Lisp_Object mode_line_string_face_prop;
9554
9555
9556 /* Unwind data for mode line strings */
9557
9558 static Lisp_Object Vmode_line_unwind_vector;
9559
9560 static Lisp_Object
9561 format_mode_line_unwind_data (struct buffer *obuf,
9562 Lisp_Object owin,
9563 int save_proptrans)
9564 {
9565 Lisp_Object vector, tmp;
9566
9567 /* Reduce consing by keeping one vector in
9568 Vwith_echo_area_save_vector. */
9569 vector = Vmode_line_unwind_vector;
9570 Vmode_line_unwind_vector = Qnil;
9571
9572 if (NILP (vector))
9573 vector = Fmake_vector (make_number (8), Qnil);
9574
9575 ASET (vector, 0, make_number (mode_line_target));
9576 ASET (vector, 1, make_number (MODE_LINE_NOPROP_LEN (0)));
9577 ASET (vector, 2, mode_line_string_list);
9578 ASET (vector, 3, save_proptrans ? mode_line_proptrans_alist : Qt);
9579 ASET (vector, 4, mode_line_string_face);
9580 ASET (vector, 5, mode_line_string_face_prop);
9581
9582 if (obuf)
9583 XSETBUFFER (tmp, obuf);
9584 else
9585 tmp = Qnil;
9586 ASET (vector, 6, tmp);
9587 ASET (vector, 7, owin);
9588
9589 return vector;
9590 }
9591
9592 static Lisp_Object
9593 unwind_format_mode_line (Lisp_Object vector)
9594 {
9595 mode_line_target = XINT (AREF (vector, 0));
9596 mode_line_noprop_ptr = mode_line_noprop_buf + XINT (AREF (vector, 1));
9597 mode_line_string_list = AREF (vector, 2);
9598 if (! EQ (AREF (vector, 3), Qt))
9599 mode_line_proptrans_alist = AREF (vector, 3);
9600 mode_line_string_face = AREF (vector, 4);
9601 mode_line_string_face_prop = AREF (vector, 5);
9602
9603 if (!NILP (AREF (vector, 7)))
9604 /* Select window before buffer, since it may change the buffer. */
9605 Fselect_window (AREF (vector, 7), Qt);
9606
9607 if (!NILP (AREF (vector, 6)))
9608 {
9609 set_buffer_internal_1 (XBUFFER (AREF (vector, 6)));
9610 ASET (vector, 6, Qnil);
9611 }
9612
9613 Vmode_line_unwind_vector = vector;
9614 return Qnil;
9615 }
9616
9617
9618 /* Store a single character C for the frame title in mode_line_noprop_buf.
9619 Re-allocate mode_line_noprop_buf if necessary. */
9620
9621 static void
9622 store_mode_line_noprop_char (char c)
9623 {
9624 /* If output position has reached the end of the allocated buffer,
9625 double the buffer's size. */
9626 if (mode_line_noprop_ptr == mode_line_noprop_buf_end)
9627 {
9628 int len = MODE_LINE_NOPROP_LEN (0);
9629 int new_size = 2 * len * sizeof *mode_line_noprop_buf;
9630 mode_line_noprop_buf = (char *) xrealloc (mode_line_noprop_buf, new_size);
9631 mode_line_noprop_buf_end = mode_line_noprop_buf + new_size;
9632 mode_line_noprop_ptr = mode_line_noprop_buf + len;
9633 }
9634
9635 *mode_line_noprop_ptr++ = c;
9636 }
9637
9638
9639 /* Store part of a frame title in mode_line_noprop_buf, beginning at
9640 mode_line_noprop_ptr. STR is the string to store. Do not copy
9641 characters that yield more columns than PRECISION; PRECISION <= 0
9642 means copy the whole string. Pad with spaces until FIELD_WIDTH
9643 number of characters have been copied; FIELD_WIDTH <= 0 means don't
9644 pad. Called from display_mode_element when it is used to build a
9645 frame title. */
9646
9647 static int
9648 store_mode_line_noprop (const unsigned char *str, int field_width, int precision)
9649 {
9650 int n = 0;
9651 int dummy, nbytes;
9652
9653 /* Copy at most PRECISION chars from STR. */
9654 nbytes = strlen (str);
9655 n += c_string_width (str, nbytes, precision, &dummy, &nbytes);
9656 while (nbytes--)
9657 store_mode_line_noprop_char (*str++);
9658
9659 /* Fill up with spaces until FIELD_WIDTH reached. */
9660 while (field_width > 0
9661 && n < field_width)
9662 {
9663 store_mode_line_noprop_char (' ');
9664 ++n;
9665 }
9666
9667 return n;
9668 }
9669
9670 /***********************************************************************
9671 Frame Titles
9672 ***********************************************************************/
9673
9674 #ifdef HAVE_WINDOW_SYSTEM
9675
9676 /* Set the title of FRAME, if it has changed. The title format is
9677 Vicon_title_format if FRAME is iconified, otherwise it is
9678 frame_title_format. */
9679
9680 static void
9681 x_consider_frame_title (Lisp_Object frame)
9682 {
9683 struct frame *f = XFRAME (frame);
9684
9685 if (FRAME_WINDOW_P (f)
9686 || FRAME_MINIBUF_ONLY_P (f)
9687 || f->explicit_name)
9688 {
9689 /* Do we have more than one visible frame on this X display? */
9690 Lisp_Object tail;
9691 Lisp_Object fmt;
9692 int title_start;
9693 char *title;
9694 int len;
9695 struct it it;
9696 int count = SPECPDL_INDEX ();
9697
9698 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
9699 {
9700 Lisp_Object other_frame = XCAR (tail);
9701 struct frame *tf = XFRAME (other_frame);
9702
9703 if (tf != f
9704 && FRAME_KBOARD (tf) == FRAME_KBOARD (f)
9705 && !FRAME_MINIBUF_ONLY_P (tf)
9706 && !EQ (other_frame, tip_frame)
9707 && (FRAME_VISIBLE_P (tf) || FRAME_ICONIFIED_P (tf)))
9708 break;
9709 }
9710
9711 /* Set global variable indicating that multiple frames exist. */
9712 multiple_frames = CONSP (tail);
9713
9714 /* Switch to the buffer of selected window of the frame. Set up
9715 mode_line_target so that display_mode_element will output into
9716 mode_line_noprop_buf; then display the title. */
9717 record_unwind_protect (unwind_format_mode_line,
9718 format_mode_line_unwind_data
9719 (current_buffer, selected_window, 0));
9720
9721 Fselect_window (f->selected_window, Qt);
9722 set_buffer_internal_1 (XBUFFER (XWINDOW (f->selected_window)->buffer));
9723 fmt = FRAME_ICONIFIED_P (f) ? Vicon_title_format : Vframe_title_format;
9724
9725 mode_line_target = MODE_LINE_TITLE;
9726 title_start = MODE_LINE_NOPROP_LEN (0);
9727 init_iterator (&it, XWINDOW (f->selected_window), -1, -1,
9728 NULL, DEFAULT_FACE_ID);
9729 display_mode_element (&it, 0, -1, -1, fmt, Qnil, 0);
9730 len = MODE_LINE_NOPROP_LEN (title_start);
9731 title = mode_line_noprop_buf + title_start;
9732 unbind_to (count, Qnil);
9733
9734 /* Set the title only if it's changed. This avoids consing in
9735 the common case where it hasn't. (If it turns out that we've
9736 already wasted too much time by walking through the list with
9737 display_mode_element, then we might need to optimize at a
9738 higher level than this.) */
9739 if (! STRINGP (f->name)
9740 || SBYTES (f->name) != len
9741 || memcmp (title, SDATA (f->name), len) != 0)
9742 x_implicitly_set_name (f, make_string (title, len), Qnil);
9743 }
9744 }
9745
9746 #endif /* not HAVE_WINDOW_SYSTEM */
9747
9748
9749
9750 \f
9751 /***********************************************************************
9752 Menu Bars
9753 ***********************************************************************/
9754
9755
9756 /* Prepare for redisplay by updating menu-bar item lists when
9757 appropriate. This can call eval. */
9758
9759 void
9760 prepare_menu_bars (void)
9761 {
9762 int all_windows;
9763 struct gcpro gcpro1, gcpro2;
9764 struct frame *f;
9765 Lisp_Object tooltip_frame;
9766
9767 #ifdef HAVE_WINDOW_SYSTEM
9768 tooltip_frame = tip_frame;
9769 #else
9770 tooltip_frame = Qnil;
9771 #endif
9772
9773 /* Update all frame titles based on their buffer names, etc. We do
9774 this before the menu bars so that the buffer-menu will show the
9775 up-to-date frame titles. */
9776 #ifdef HAVE_WINDOW_SYSTEM
9777 if (windows_or_buffers_changed || update_mode_lines)
9778 {
9779 Lisp_Object tail, frame;
9780
9781 FOR_EACH_FRAME (tail, frame)
9782 {
9783 f = XFRAME (frame);
9784 if (!EQ (frame, tooltip_frame)
9785 && (FRAME_VISIBLE_P (f) || FRAME_ICONIFIED_P (f)))
9786 x_consider_frame_title (frame);
9787 }
9788 }
9789 #endif /* HAVE_WINDOW_SYSTEM */
9790
9791 /* Update the menu bar item lists, if appropriate. This has to be
9792 done before any actual redisplay or generation of display lines. */
9793 all_windows = (update_mode_lines
9794 || buffer_shared > 1
9795 || windows_or_buffers_changed);
9796 if (all_windows)
9797 {
9798 Lisp_Object tail, frame;
9799 int count = SPECPDL_INDEX ();
9800 /* 1 means that update_menu_bar has run its hooks
9801 so any further calls to update_menu_bar shouldn't do so again. */
9802 int menu_bar_hooks_run = 0;
9803
9804 record_unwind_save_match_data ();
9805
9806 FOR_EACH_FRAME (tail, frame)
9807 {
9808 f = XFRAME (frame);
9809
9810 /* Ignore tooltip frame. */
9811 if (EQ (frame, tooltip_frame))
9812 continue;
9813
9814 /* If a window on this frame changed size, report that to
9815 the user and clear the size-change flag. */
9816 if (FRAME_WINDOW_SIZES_CHANGED (f))
9817 {
9818 Lisp_Object functions;
9819
9820 /* Clear flag first in case we get an error below. */
9821 FRAME_WINDOW_SIZES_CHANGED (f) = 0;
9822 functions = Vwindow_size_change_functions;
9823 GCPRO2 (tail, functions);
9824
9825 while (CONSP (functions))
9826 {
9827 if (!EQ (XCAR (functions), Qt))
9828 call1 (XCAR (functions), frame);
9829 functions = XCDR (functions);
9830 }
9831 UNGCPRO;
9832 }
9833
9834 GCPRO1 (tail);
9835 menu_bar_hooks_run = update_menu_bar (f, 0, menu_bar_hooks_run);
9836 #ifdef HAVE_WINDOW_SYSTEM
9837 update_tool_bar (f, 0);
9838 #endif
9839 #ifdef HAVE_NS
9840 if (windows_or_buffers_changed
9841 && FRAME_NS_P (f))
9842 ns_set_doc_edited (f, Fbuffer_modified_p
9843 (XWINDOW (f->selected_window)->buffer));
9844 #endif
9845 UNGCPRO;
9846 }
9847
9848 unbind_to (count, Qnil);
9849 }
9850 else
9851 {
9852 struct frame *sf = SELECTED_FRAME ();
9853 update_menu_bar (sf, 1, 0);
9854 #ifdef HAVE_WINDOW_SYSTEM
9855 update_tool_bar (sf, 1);
9856 #endif
9857 }
9858 }
9859
9860
9861 /* Update the menu bar item list for frame F. This has to be done
9862 before we start to fill in any display lines, because it can call
9863 eval.
9864
9865 If SAVE_MATCH_DATA is non-zero, we must save and restore it here.
9866
9867 If HOOKS_RUN is 1, that means a previous call to update_menu_bar
9868 already ran the menu bar hooks for this redisplay, so there
9869 is no need to run them again. The return value is the
9870 updated value of this flag, to pass to the next call. */
9871
9872 static int
9873 update_menu_bar (struct frame *f, int save_match_data, int hooks_run)
9874 {
9875 Lisp_Object window;
9876 register struct window *w;
9877
9878 /* If called recursively during a menu update, do nothing. This can
9879 happen when, for instance, an activate-menubar-hook causes a
9880 redisplay. */
9881 if (inhibit_menubar_update)
9882 return hooks_run;
9883
9884 window = FRAME_SELECTED_WINDOW (f);
9885 w = XWINDOW (window);
9886
9887 if (FRAME_WINDOW_P (f)
9888 ?
9889 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
9890 || defined (HAVE_NS) || defined (USE_GTK)
9891 FRAME_EXTERNAL_MENU_BAR (f)
9892 #else
9893 FRAME_MENU_BAR_LINES (f) > 0
9894 #endif
9895 : FRAME_MENU_BAR_LINES (f) > 0)
9896 {
9897 /* If the user has switched buffers or windows, we need to
9898 recompute to reflect the new bindings. But we'll
9899 recompute when update_mode_lines is set too; that means
9900 that people can use force-mode-line-update to request
9901 that the menu bar be recomputed. The adverse effect on
9902 the rest of the redisplay algorithm is about the same as
9903 windows_or_buffers_changed anyway. */
9904 if (windows_or_buffers_changed
9905 /* This used to test w->update_mode_line, but we believe
9906 there is no need to recompute the menu in that case. */
9907 || update_mode_lines
9908 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
9909 < BUF_MODIFF (XBUFFER (w->buffer)))
9910 != !NILP (w->last_had_star))
9911 || ((!NILP (Vtransient_mark_mode)
9912 && !NILP (XBUFFER (w->buffer)->mark_active))
9913 != !NILP (w->region_showing)))
9914 {
9915 struct buffer *prev = current_buffer;
9916 int count = SPECPDL_INDEX ();
9917
9918 specbind (Qinhibit_menubar_update, Qt);
9919
9920 set_buffer_internal_1 (XBUFFER (w->buffer));
9921 if (save_match_data)
9922 record_unwind_save_match_data ();
9923 if (NILP (Voverriding_local_map_menu_flag))
9924 {
9925 specbind (Qoverriding_terminal_local_map, Qnil);
9926 specbind (Qoverriding_local_map, Qnil);
9927 }
9928
9929 if (!hooks_run)
9930 {
9931 /* Run the Lucid hook. */
9932 safe_run_hooks (Qactivate_menubar_hook);
9933
9934 /* If it has changed current-menubar from previous value,
9935 really recompute the menu-bar from the value. */
9936 if (! NILP (Vlucid_menu_bar_dirty_flag))
9937 call0 (Qrecompute_lucid_menubar);
9938
9939 safe_run_hooks (Qmenu_bar_update_hook);
9940
9941 hooks_run = 1;
9942 }
9943
9944 XSETFRAME (Vmenu_updating_frame, f);
9945 FRAME_MENU_BAR_ITEMS (f) = menu_bar_items (FRAME_MENU_BAR_ITEMS (f));
9946
9947 /* Redisplay the menu bar in case we changed it. */
9948 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
9949 || defined (HAVE_NS) || defined (USE_GTK)
9950 if (FRAME_WINDOW_P (f))
9951 {
9952 #if defined (HAVE_NS)
9953 /* All frames on Mac OS share the same menubar. So only
9954 the selected frame should be allowed to set it. */
9955 if (f == SELECTED_FRAME ())
9956 #endif
9957 set_frame_menubar (f, 0, 0);
9958 }
9959 else
9960 /* On a terminal screen, the menu bar is an ordinary screen
9961 line, and this makes it get updated. */
9962 w->update_mode_line = Qt;
9963 #else /* ! (USE_X_TOOLKIT || HAVE_NTGUI || HAVE_NS || USE_GTK) */
9964 /* In the non-toolkit version, the menu bar is an ordinary screen
9965 line, and this makes it get updated. */
9966 w->update_mode_line = Qt;
9967 #endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI || HAVE_NS || USE_GTK) */
9968
9969 unbind_to (count, Qnil);
9970 set_buffer_internal_1 (prev);
9971 }
9972 }
9973
9974 return hooks_run;
9975 }
9976
9977
9978 \f
9979 /***********************************************************************
9980 Output Cursor
9981 ***********************************************************************/
9982
9983 #ifdef HAVE_WINDOW_SYSTEM
9984
9985 /* EXPORT:
9986 Nominal cursor position -- where to draw output.
9987 HPOS and VPOS are window relative glyph matrix coordinates.
9988 X and Y are window relative pixel coordinates. */
9989
9990 struct cursor_pos output_cursor;
9991
9992
9993 /* EXPORT:
9994 Set the global variable output_cursor to CURSOR. All cursor
9995 positions are relative to updated_window. */
9996
9997 void
9998 set_output_cursor (struct cursor_pos *cursor)
9999 {
10000 output_cursor.hpos = cursor->hpos;
10001 output_cursor.vpos = cursor->vpos;
10002 output_cursor.x = cursor->x;
10003 output_cursor.y = cursor->y;
10004 }
10005
10006
10007 /* EXPORT for RIF:
10008 Set a nominal cursor position.
10009
10010 HPOS and VPOS are column/row positions in a window glyph matrix. X
10011 and Y are window text area relative pixel positions.
10012
10013 If this is done during an update, updated_window will contain the
10014 window that is being updated and the position is the future output
10015 cursor position for that window. If updated_window is null, use
10016 selected_window and display the cursor at the given position. */
10017
10018 void
10019 x_cursor_to (int vpos, int hpos, int y, int x)
10020 {
10021 struct window *w;
10022
10023 /* If updated_window is not set, work on selected_window. */
10024 if (updated_window)
10025 w = updated_window;
10026 else
10027 w = XWINDOW (selected_window);
10028
10029 /* Set the output cursor. */
10030 output_cursor.hpos = hpos;
10031 output_cursor.vpos = vpos;
10032 output_cursor.x = x;
10033 output_cursor.y = y;
10034
10035 /* If not called as part of an update, really display the cursor.
10036 This will also set the cursor position of W. */
10037 if (updated_window == NULL)
10038 {
10039 BLOCK_INPUT;
10040 display_and_set_cursor (w, 1, hpos, vpos, x, y);
10041 if (FRAME_RIF (SELECTED_FRAME ())->flush_display_optional)
10042 FRAME_RIF (SELECTED_FRAME ())->flush_display_optional (SELECTED_FRAME ());
10043 UNBLOCK_INPUT;
10044 }
10045 }
10046
10047 #endif /* HAVE_WINDOW_SYSTEM */
10048
10049 \f
10050 /***********************************************************************
10051 Tool-bars
10052 ***********************************************************************/
10053
10054 #ifdef HAVE_WINDOW_SYSTEM
10055
10056 /* Where the mouse was last time we reported a mouse event. */
10057
10058 FRAME_PTR last_mouse_frame;
10059
10060 /* Tool-bar item index of the item on which a mouse button was pressed
10061 or -1. */
10062
10063 int last_tool_bar_item;
10064
10065
10066 static Lisp_Object
10067 update_tool_bar_unwind (Lisp_Object frame)
10068 {
10069 selected_frame = frame;
10070 return Qnil;
10071 }
10072
10073 /* Update the tool-bar item list for frame F. This has to be done
10074 before we start to fill in any display lines. Called from
10075 prepare_menu_bars. If SAVE_MATCH_DATA is non-zero, we must save
10076 and restore it here. */
10077
10078 static void
10079 update_tool_bar (struct frame *f, int save_match_data)
10080 {
10081 #if defined (USE_GTK) || defined (HAVE_NS)
10082 int do_update = FRAME_EXTERNAL_TOOL_BAR (f);
10083 #else
10084 int do_update = WINDOWP (f->tool_bar_window)
10085 && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)) > 0;
10086 #endif
10087
10088 if (do_update)
10089 {
10090 Lisp_Object window;
10091 struct window *w;
10092
10093 window = FRAME_SELECTED_WINDOW (f);
10094 w = XWINDOW (window);
10095
10096 /* If the user has switched buffers or windows, we need to
10097 recompute to reflect the new bindings. But we'll
10098 recompute when update_mode_lines is set too; that means
10099 that people can use force-mode-line-update to request
10100 that the menu bar be recomputed. The adverse effect on
10101 the rest of the redisplay algorithm is about the same as
10102 windows_or_buffers_changed anyway. */
10103 if (windows_or_buffers_changed
10104 || !NILP (w->update_mode_line)
10105 || update_mode_lines
10106 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
10107 < BUF_MODIFF (XBUFFER (w->buffer)))
10108 != !NILP (w->last_had_star))
10109 || ((!NILP (Vtransient_mark_mode)
10110 && !NILP (XBUFFER (w->buffer)->mark_active))
10111 != !NILP (w->region_showing)))
10112 {
10113 struct buffer *prev = current_buffer;
10114 int count = SPECPDL_INDEX ();
10115 Lisp_Object frame, new_tool_bar;
10116 int new_n_tool_bar;
10117 struct gcpro gcpro1;
10118
10119 /* Set current_buffer to the buffer of the selected
10120 window of the frame, so that we get the right local
10121 keymaps. */
10122 set_buffer_internal_1 (XBUFFER (w->buffer));
10123
10124 /* Save match data, if we must. */
10125 if (save_match_data)
10126 record_unwind_save_match_data ();
10127
10128 /* Make sure that we don't accidentally use bogus keymaps. */
10129 if (NILP (Voverriding_local_map_menu_flag))
10130 {
10131 specbind (Qoverriding_terminal_local_map, Qnil);
10132 specbind (Qoverriding_local_map, Qnil);
10133 }
10134
10135 GCPRO1 (new_tool_bar);
10136
10137 /* We must temporarily set the selected frame to this frame
10138 before calling tool_bar_items, because the calculation of
10139 the tool-bar keymap uses the selected frame (see
10140 `tool-bar-make-keymap' in tool-bar.el). */
10141 record_unwind_protect (update_tool_bar_unwind, selected_frame);
10142 XSETFRAME (frame, f);
10143 selected_frame = frame;
10144
10145 /* Build desired tool-bar items from keymaps. */
10146 new_tool_bar = tool_bar_items (Fcopy_sequence (f->tool_bar_items),
10147 &new_n_tool_bar);
10148
10149 /* Redisplay the tool-bar if we changed it. */
10150 if (new_n_tool_bar != f->n_tool_bar_items
10151 || NILP (Fequal (new_tool_bar, f->tool_bar_items)))
10152 {
10153 /* Redisplay that happens asynchronously due to an expose event
10154 may access f->tool_bar_items. Make sure we update both
10155 variables within BLOCK_INPUT so no such event interrupts. */
10156 BLOCK_INPUT;
10157 f->tool_bar_items = new_tool_bar;
10158 f->n_tool_bar_items = new_n_tool_bar;
10159 w->update_mode_line = Qt;
10160 UNBLOCK_INPUT;
10161 }
10162
10163 UNGCPRO;
10164
10165 unbind_to (count, Qnil);
10166 set_buffer_internal_1 (prev);
10167 }
10168 }
10169 }
10170
10171
10172 /* Set F->desired_tool_bar_string to a Lisp string representing frame
10173 F's desired tool-bar contents. F->tool_bar_items must have
10174 been set up previously by calling prepare_menu_bars. */
10175
10176 static void
10177 build_desired_tool_bar_string (struct frame *f)
10178 {
10179 int i, size, size_needed;
10180 struct gcpro gcpro1, gcpro2, gcpro3;
10181 Lisp_Object image, plist, props;
10182
10183 image = plist = props = Qnil;
10184 GCPRO3 (image, plist, props);
10185
10186 /* Prepare F->desired_tool_bar_string. If we can reuse it, do so.
10187 Otherwise, make a new string. */
10188
10189 /* The size of the string we might be able to reuse. */
10190 size = (STRINGP (f->desired_tool_bar_string)
10191 ? SCHARS (f->desired_tool_bar_string)
10192 : 0);
10193
10194 /* We need one space in the string for each image. */
10195 size_needed = f->n_tool_bar_items;
10196
10197 /* Reuse f->desired_tool_bar_string, if possible. */
10198 if (size < size_needed || NILP (f->desired_tool_bar_string))
10199 f->desired_tool_bar_string = Fmake_string (make_number (size_needed),
10200 make_number (' '));
10201 else
10202 {
10203 props = list4 (Qdisplay, Qnil, Qmenu_item, Qnil);
10204 Fremove_text_properties (make_number (0), make_number (size),
10205 props, f->desired_tool_bar_string);
10206 }
10207
10208 /* Put a `display' property on the string for the images to display,
10209 put a `menu_item' property on tool-bar items with a value that
10210 is the index of the item in F's tool-bar item vector. */
10211 for (i = 0; i < f->n_tool_bar_items; ++i)
10212 {
10213 #define PROP(IDX) AREF (f->tool_bar_items, i * TOOL_BAR_ITEM_NSLOTS + (IDX))
10214
10215 int enabled_p = !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P));
10216 int selected_p = !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P));
10217 int hmargin, vmargin, relief, idx, end;
10218
10219 /* If image is a vector, choose the image according to the
10220 button state. */
10221 image = PROP (TOOL_BAR_ITEM_IMAGES);
10222 if (VECTORP (image))
10223 {
10224 if (enabled_p)
10225 idx = (selected_p
10226 ? TOOL_BAR_IMAGE_ENABLED_SELECTED
10227 : TOOL_BAR_IMAGE_ENABLED_DESELECTED);
10228 else
10229 idx = (selected_p
10230 ? TOOL_BAR_IMAGE_DISABLED_SELECTED
10231 : TOOL_BAR_IMAGE_DISABLED_DESELECTED);
10232
10233 xassert (ASIZE (image) >= idx);
10234 image = AREF (image, idx);
10235 }
10236 else
10237 idx = -1;
10238
10239 /* Ignore invalid image specifications. */
10240 if (!valid_image_p (image))
10241 continue;
10242
10243 /* Display the tool-bar button pressed, or depressed. */
10244 plist = Fcopy_sequence (XCDR (image));
10245
10246 /* Compute margin and relief to draw. */
10247 relief = (tool_bar_button_relief >= 0
10248 ? tool_bar_button_relief
10249 : DEFAULT_TOOL_BAR_BUTTON_RELIEF);
10250 hmargin = vmargin = relief;
10251
10252 if (INTEGERP (Vtool_bar_button_margin)
10253 && XINT (Vtool_bar_button_margin) > 0)
10254 {
10255 hmargin += XFASTINT (Vtool_bar_button_margin);
10256 vmargin += XFASTINT (Vtool_bar_button_margin);
10257 }
10258 else if (CONSP (Vtool_bar_button_margin))
10259 {
10260 if (INTEGERP (XCAR (Vtool_bar_button_margin))
10261 && XINT (XCAR (Vtool_bar_button_margin)) > 0)
10262 hmargin += XFASTINT (XCAR (Vtool_bar_button_margin));
10263
10264 if (INTEGERP (XCDR (Vtool_bar_button_margin))
10265 && XINT (XCDR (Vtool_bar_button_margin)) > 0)
10266 vmargin += XFASTINT (XCDR (Vtool_bar_button_margin));
10267 }
10268
10269 if (auto_raise_tool_bar_buttons_p)
10270 {
10271 /* Add a `:relief' property to the image spec if the item is
10272 selected. */
10273 if (selected_p)
10274 {
10275 plist = Fplist_put (plist, QCrelief, make_number (-relief));
10276 hmargin -= relief;
10277 vmargin -= relief;
10278 }
10279 }
10280 else
10281 {
10282 /* If image is selected, display it pressed, i.e. with a
10283 negative relief. If it's not selected, display it with a
10284 raised relief. */
10285 plist = Fplist_put (plist, QCrelief,
10286 (selected_p
10287 ? make_number (-relief)
10288 : make_number (relief)));
10289 hmargin -= relief;
10290 vmargin -= relief;
10291 }
10292
10293 /* Put a margin around the image. */
10294 if (hmargin || vmargin)
10295 {
10296 if (hmargin == vmargin)
10297 plist = Fplist_put (plist, QCmargin, make_number (hmargin));
10298 else
10299 plist = Fplist_put (plist, QCmargin,
10300 Fcons (make_number (hmargin),
10301 make_number (vmargin)));
10302 }
10303
10304 /* If button is not enabled, and we don't have special images
10305 for the disabled state, make the image appear disabled by
10306 applying an appropriate algorithm to it. */
10307 if (!enabled_p && idx < 0)
10308 plist = Fplist_put (plist, QCconversion, Qdisabled);
10309
10310 /* Put a `display' text property on the string for the image to
10311 display. Put a `menu-item' property on the string that gives
10312 the start of this item's properties in the tool-bar items
10313 vector. */
10314 image = Fcons (Qimage, plist);
10315 props = list4 (Qdisplay, image,
10316 Qmenu_item, make_number (i * TOOL_BAR_ITEM_NSLOTS));
10317
10318 /* Let the last image hide all remaining spaces in the tool bar
10319 string. The string can be longer than needed when we reuse a
10320 previous string. */
10321 if (i + 1 == f->n_tool_bar_items)
10322 end = SCHARS (f->desired_tool_bar_string);
10323 else
10324 end = i + 1;
10325 Fadd_text_properties (make_number (i), make_number (end),
10326 props, f->desired_tool_bar_string);
10327 #undef PROP
10328 }
10329
10330 UNGCPRO;
10331 }
10332
10333
10334 /* Display one line of the tool-bar of frame IT->f.
10335
10336 HEIGHT specifies the desired height of the tool-bar line.
10337 If the actual height of the glyph row is less than HEIGHT, the
10338 row's height is increased to HEIGHT, and the icons are centered
10339 vertically in the new height.
10340
10341 If HEIGHT is -1, we are counting needed tool-bar lines, so don't
10342 count a final empty row in case the tool-bar width exactly matches
10343 the window width.
10344 */
10345
10346 static void
10347 display_tool_bar_line (struct it *it, int height)
10348 {
10349 struct glyph_row *row = it->glyph_row;
10350 int max_x = it->last_visible_x;
10351 struct glyph *last;
10352
10353 prepare_desired_row (row);
10354 row->y = it->current_y;
10355
10356 /* Note that this isn't made use of if the face hasn't a box,
10357 so there's no need to check the face here. */
10358 it->start_of_box_run_p = 1;
10359
10360 while (it->current_x < max_x)
10361 {
10362 int x, n_glyphs_before, i, nglyphs;
10363 struct it it_before;
10364
10365 /* Get the next display element. */
10366 if (!get_next_display_element (it))
10367 {
10368 /* Don't count empty row if we are counting needed tool-bar lines. */
10369 if (height < 0 && !it->hpos)
10370 return;
10371 break;
10372 }
10373
10374 /* Produce glyphs. */
10375 n_glyphs_before = row->used[TEXT_AREA];
10376 it_before = *it;
10377
10378 PRODUCE_GLYPHS (it);
10379
10380 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
10381 i = 0;
10382 x = it_before.current_x;
10383 while (i < nglyphs)
10384 {
10385 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
10386
10387 if (x + glyph->pixel_width > max_x)
10388 {
10389 /* Glyph doesn't fit on line. Backtrack. */
10390 row->used[TEXT_AREA] = n_glyphs_before;
10391 *it = it_before;
10392 /* If this is the only glyph on this line, it will never fit on the
10393 toolbar, so skip it. But ensure there is at least one glyph,
10394 so we don't accidentally disable the tool-bar. */
10395 if (n_glyphs_before == 0
10396 && (it->vpos > 0 || IT_STRING_CHARPOS (*it) < it->end_charpos-1))
10397 break;
10398 goto out;
10399 }
10400
10401 ++it->hpos;
10402 x += glyph->pixel_width;
10403 ++i;
10404 }
10405
10406 /* Stop at line ends. */
10407 if (ITERATOR_AT_END_OF_LINE_P (it))
10408 break;
10409
10410 set_iterator_to_next (it, 1);
10411 }
10412
10413 out:;
10414
10415 row->displays_text_p = row->used[TEXT_AREA] != 0;
10416
10417 /* Use default face for the border below the tool bar.
10418
10419 FIXME: When auto-resize-tool-bars is grow-only, there is
10420 no additional border below the possibly empty tool-bar lines.
10421 So to make the extra empty lines look "normal", we have to
10422 use the tool-bar face for the border too. */
10423 if (!row->displays_text_p && !EQ (Vauto_resize_tool_bars, Qgrow_only))
10424 it->face_id = DEFAULT_FACE_ID;
10425
10426 extend_face_to_end_of_line (it);
10427 last = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
10428 last->right_box_line_p = 1;
10429 if (last == row->glyphs[TEXT_AREA])
10430 last->left_box_line_p = 1;
10431
10432 /* Make line the desired height and center it vertically. */
10433 if ((height -= it->max_ascent + it->max_descent) > 0)
10434 {
10435 /* Don't add more than one line height. */
10436 height %= FRAME_LINE_HEIGHT (it->f);
10437 it->max_ascent += height / 2;
10438 it->max_descent += (height + 1) / 2;
10439 }
10440
10441 compute_line_metrics (it);
10442
10443 /* If line is empty, make it occupy the rest of the tool-bar. */
10444 if (!row->displays_text_p)
10445 {
10446 row->height = row->phys_height = it->last_visible_y - row->y;
10447 row->visible_height = row->height;
10448 row->ascent = row->phys_ascent = 0;
10449 row->extra_line_spacing = 0;
10450 }
10451
10452 row->full_width_p = 1;
10453 row->continued_p = 0;
10454 row->truncated_on_left_p = 0;
10455 row->truncated_on_right_p = 0;
10456
10457 it->current_x = it->hpos = 0;
10458 it->current_y += row->height;
10459 ++it->vpos;
10460 ++it->glyph_row;
10461 }
10462
10463
10464 /* Max tool-bar height. */
10465
10466 #define MAX_FRAME_TOOL_BAR_HEIGHT(f) \
10467 ((FRAME_LINE_HEIGHT (f) * FRAME_LINES (f)))
10468
10469 /* Value is the number of screen lines needed to make all tool-bar
10470 items of frame F visible. The number of actual rows needed is
10471 returned in *N_ROWS if non-NULL. */
10472
10473 static int
10474 tool_bar_lines_needed (struct frame *f, int *n_rows)
10475 {
10476 struct window *w = XWINDOW (f->tool_bar_window);
10477 struct it it;
10478 /* tool_bar_lines_needed is called from redisplay_tool_bar after building
10479 the desired matrix, so use (unused) mode-line row as temporary row to
10480 avoid destroying the first tool-bar row. */
10481 struct glyph_row *temp_row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
10482
10483 /* Initialize an iterator for iteration over
10484 F->desired_tool_bar_string in the tool-bar window of frame F. */
10485 init_iterator (&it, w, -1, -1, temp_row, TOOL_BAR_FACE_ID);
10486 it.first_visible_x = 0;
10487 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
10488 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
10489
10490 while (!ITERATOR_AT_END_P (&it))
10491 {
10492 clear_glyph_row (temp_row);
10493 it.glyph_row = temp_row;
10494 display_tool_bar_line (&it, -1);
10495 }
10496 clear_glyph_row (temp_row);
10497
10498 /* f->n_tool_bar_rows == 0 means "unknown"; -1 means no tool-bar. */
10499 if (n_rows)
10500 *n_rows = it.vpos > 0 ? it.vpos : -1;
10501
10502 return (it.current_y + FRAME_LINE_HEIGHT (f) - 1) / FRAME_LINE_HEIGHT (f);
10503 }
10504
10505
10506 DEFUN ("tool-bar-lines-needed", Ftool_bar_lines_needed, Stool_bar_lines_needed,
10507 0, 1, 0,
10508 doc: /* Return the number of lines occupied by the tool bar of FRAME. */)
10509 (Lisp_Object frame)
10510 {
10511 struct frame *f;
10512 struct window *w;
10513 int nlines = 0;
10514
10515 if (NILP (frame))
10516 frame = selected_frame;
10517 else
10518 CHECK_FRAME (frame);
10519 f = XFRAME (frame);
10520
10521 if (WINDOWP (f->tool_bar_window)
10522 || (w = XWINDOW (f->tool_bar_window),
10523 WINDOW_TOTAL_LINES (w) > 0))
10524 {
10525 update_tool_bar (f, 1);
10526 if (f->n_tool_bar_items)
10527 {
10528 build_desired_tool_bar_string (f);
10529 nlines = tool_bar_lines_needed (f, NULL);
10530 }
10531 }
10532
10533 return make_number (nlines);
10534 }
10535
10536
10537 /* Display the tool-bar of frame F. Value is non-zero if tool-bar's
10538 height should be changed. */
10539
10540 static int
10541 redisplay_tool_bar (struct frame *f)
10542 {
10543 struct window *w;
10544 struct it it;
10545 struct glyph_row *row;
10546
10547 #if defined (USE_GTK) || defined (HAVE_NS)
10548 if (FRAME_EXTERNAL_TOOL_BAR (f))
10549 update_frame_tool_bar (f);
10550 return 0;
10551 #endif
10552
10553 /* If frame hasn't a tool-bar window or if it is zero-height, don't
10554 do anything. This means you must start with tool-bar-lines
10555 non-zero to get the auto-sizing effect. Or in other words, you
10556 can turn off tool-bars by specifying tool-bar-lines zero. */
10557 if (!WINDOWP (f->tool_bar_window)
10558 || (w = XWINDOW (f->tool_bar_window),
10559 WINDOW_TOTAL_LINES (w) == 0))
10560 return 0;
10561
10562 /* Set up an iterator for the tool-bar window. */
10563 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
10564 it.first_visible_x = 0;
10565 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
10566 row = it.glyph_row;
10567
10568 /* Build a string that represents the contents of the tool-bar. */
10569 build_desired_tool_bar_string (f);
10570 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
10571
10572 if (f->n_tool_bar_rows == 0)
10573 {
10574 int nlines;
10575
10576 if ((nlines = tool_bar_lines_needed (f, &f->n_tool_bar_rows),
10577 nlines != WINDOW_TOTAL_LINES (w)))
10578 {
10579 Lisp_Object frame;
10580 int old_height = WINDOW_TOTAL_LINES (w);
10581
10582 XSETFRAME (frame, f);
10583 Fmodify_frame_parameters (frame,
10584 Fcons (Fcons (Qtool_bar_lines,
10585 make_number (nlines)),
10586 Qnil));
10587 if (WINDOW_TOTAL_LINES (w) != old_height)
10588 {
10589 clear_glyph_matrix (w->desired_matrix);
10590 fonts_changed_p = 1;
10591 return 1;
10592 }
10593 }
10594 }
10595
10596 /* Display as many lines as needed to display all tool-bar items. */
10597
10598 if (f->n_tool_bar_rows > 0)
10599 {
10600 int border, rows, height, extra;
10601
10602 if (INTEGERP (Vtool_bar_border))
10603 border = XINT (Vtool_bar_border);
10604 else if (EQ (Vtool_bar_border, Qinternal_border_width))
10605 border = FRAME_INTERNAL_BORDER_WIDTH (f);
10606 else if (EQ (Vtool_bar_border, Qborder_width))
10607 border = f->border_width;
10608 else
10609 border = 0;
10610 if (border < 0)
10611 border = 0;
10612
10613 rows = f->n_tool_bar_rows;
10614 height = max (1, (it.last_visible_y - border) / rows);
10615 extra = it.last_visible_y - border - height * rows;
10616
10617 while (it.current_y < it.last_visible_y)
10618 {
10619 int h = 0;
10620 if (extra > 0 && rows-- > 0)
10621 {
10622 h = (extra + rows - 1) / rows;
10623 extra -= h;
10624 }
10625 display_tool_bar_line (&it, height + h);
10626 }
10627 }
10628 else
10629 {
10630 while (it.current_y < it.last_visible_y)
10631 display_tool_bar_line (&it, 0);
10632 }
10633
10634 /* It doesn't make much sense to try scrolling in the tool-bar
10635 window, so don't do it. */
10636 w->desired_matrix->no_scrolling_p = 1;
10637 w->must_be_updated_p = 1;
10638
10639 if (!NILP (Vauto_resize_tool_bars))
10640 {
10641 int max_tool_bar_height = MAX_FRAME_TOOL_BAR_HEIGHT (f);
10642 int change_height_p = 0;
10643
10644 /* If we couldn't display everything, change the tool-bar's
10645 height if there is room for more. */
10646 if (IT_STRING_CHARPOS (it) < it.end_charpos
10647 && it.current_y < max_tool_bar_height)
10648 change_height_p = 1;
10649
10650 row = it.glyph_row - 1;
10651
10652 /* If there are blank lines at the end, except for a partially
10653 visible blank line at the end that is smaller than
10654 FRAME_LINE_HEIGHT, change the tool-bar's height. */
10655 if (!row->displays_text_p
10656 && row->height >= FRAME_LINE_HEIGHT (f))
10657 change_height_p = 1;
10658
10659 /* If row displays tool-bar items, but is partially visible,
10660 change the tool-bar's height. */
10661 if (row->displays_text_p
10662 && MATRIX_ROW_BOTTOM_Y (row) > it.last_visible_y
10663 && MATRIX_ROW_BOTTOM_Y (row) < max_tool_bar_height)
10664 change_height_p = 1;
10665
10666 /* Resize windows as needed by changing the `tool-bar-lines'
10667 frame parameter. */
10668 if (change_height_p)
10669 {
10670 Lisp_Object frame;
10671 int old_height = WINDOW_TOTAL_LINES (w);
10672 int nrows;
10673 int nlines = tool_bar_lines_needed (f, &nrows);
10674
10675 change_height_p = ((EQ (Vauto_resize_tool_bars, Qgrow_only)
10676 && !f->minimize_tool_bar_window_p)
10677 ? (nlines > old_height)
10678 : (nlines != old_height));
10679 f->minimize_tool_bar_window_p = 0;
10680
10681 if (change_height_p)
10682 {
10683 XSETFRAME (frame, f);
10684 Fmodify_frame_parameters (frame,
10685 Fcons (Fcons (Qtool_bar_lines,
10686 make_number (nlines)),
10687 Qnil));
10688 if (WINDOW_TOTAL_LINES (w) != old_height)
10689 {
10690 clear_glyph_matrix (w->desired_matrix);
10691 f->n_tool_bar_rows = nrows;
10692 fonts_changed_p = 1;
10693 return 1;
10694 }
10695 }
10696 }
10697 }
10698
10699 f->minimize_tool_bar_window_p = 0;
10700 return 0;
10701 }
10702
10703
10704 /* Get information about the tool-bar item which is displayed in GLYPH
10705 on frame F. Return in *PROP_IDX the index where tool-bar item
10706 properties start in F->tool_bar_items. Value is zero if
10707 GLYPH doesn't display a tool-bar item. */
10708
10709 static int
10710 tool_bar_item_info (struct frame *f, struct glyph *glyph, int *prop_idx)
10711 {
10712 Lisp_Object prop;
10713 int success_p;
10714 int charpos;
10715
10716 /* This function can be called asynchronously, which means we must
10717 exclude any possibility that Fget_text_property signals an
10718 error. */
10719 charpos = min (SCHARS (f->current_tool_bar_string), glyph->charpos);
10720 charpos = max (0, charpos);
10721
10722 /* Get the text property `menu-item' at pos. The value of that
10723 property is the start index of this item's properties in
10724 F->tool_bar_items. */
10725 prop = Fget_text_property (make_number (charpos),
10726 Qmenu_item, f->current_tool_bar_string);
10727 if (INTEGERP (prop))
10728 {
10729 *prop_idx = XINT (prop);
10730 success_p = 1;
10731 }
10732 else
10733 success_p = 0;
10734
10735 return success_p;
10736 }
10737
10738 \f
10739 /* Get information about the tool-bar item at position X/Y on frame F.
10740 Return in *GLYPH a pointer to the glyph of the tool-bar item in
10741 the current matrix of the tool-bar window of F, or NULL if not
10742 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
10743 item in F->tool_bar_items. Value is
10744
10745 -1 if X/Y is not on a tool-bar item
10746 0 if X/Y is on the same item that was highlighted before.
10747 1 otherwise. */
10748
10749 static int
10750 get_tool_bar_item (struct frame *f, int x, int y, struct glyph **glyph,
10751 int *hpos, int *vpos, int *prop_idx)
10752 {
10753 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
10754 struct window *w = XWINDOW (f->tool_bar_window);
10755 int area;
10756
10757 /* Find the glyph under X/Y. */
10758 *glyph = x_y_to_hpos_vpos (w, x, y, hpos, vpos, 0, 0, &area);
10759 if (*glyph == NULL)
10760 return -1;
10761
10762 /* Get the start of this tool-bar item's properties in
10763 f->tool_bar_items. */
10764 if (!tool_bar_item_info (f, *glyph, prop_idx))
10765 return -1;
10766
10767 /* Is mouse on the highlighted item? */
10768 if (EQ (f->tool_bar_window, dpyinfo->mouse_face_window)
10769 && *vpos >= dpyinfo->mouse_face_beg_row
10770 && *vpos <= dpyinfo->mouse_face_end_row
10771 && (*vpos > dpyinfo->mouse_face_beg_row
10772 || *hpos >= dpyinfo->mouse_face_beg_col)
10773 && (*vpos < dpyinfo->mouse_face_end_row
10774 || *hpos < dpyinfo->mouse_face_end_col
10775 || dpyinfo->mouse_face_past_end))
10776 return 0;
10777
10778 return 1;
10779 }
10780
10781
10782 /* EXPORT:
10783 Handle mouse button event on the tool-bar of frame F, at
10784 frame-relative coordinates X/Y. DOWN_P is 1 for a button press,
10785 0 for button release. MODIFIERS is event modifiers for button
10786 release. */
10787
10788 void
10789 handle_tool_bar_click (struct frame *f, int x, int y, int down_p,
10790 unsigned int modifiers)
10791 {
10792 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
10793 struct window *w = XWINDOW (f->tool_bar_window);
10794 int hpos, vpos, prop_idx;
10795 struct glyph *glyph;
10796 Lisp_Object enabled_p;
10797
10798 /* If not on the highlighted tool-bar item, return. */
10799 frame_to_window_pixel_xy (w, &x, &y);
10800 if (get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx) != 0)
10801 return;
10802
10803 /* If item is disabled, do nothing. */
10804 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
10805 if (NILP (enabled_p))
10806 return;
10807
10808 if (down_p)
10809 {
10810 /* Show item in pressed state. */
10811 show_mouse_face (dpyinfo, DRAW_IMAGE_SUNKEN);
10812 dpyinfo->mouse_face_image_state = DRAW_IMAGE_SUNKEN;
10813 last_tool_bar_item = prop_idx;
10814 }
10815 else
10816 {
10817 Lisp_Object key, frame;
10818 struct input_event event;
10819 EVENT_INIT (event);
10820
10821 /* Show item in released state. */
10822 show_mouse_face (dpyinfo, DRAW_IMAGE_RAISED);
10823 dpyinfo->mouse_face_image_state = DRAW_IMAGE_RAISED;
10824
10825 key = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_KEY);
10826
10827 XSETFRAME (frame, f);
10828 event.kind = TOOL_BAR_EVENT;
10829 event.frame_or_window = frame;
10830 event.arg = frame;
10831 kbd_buffer_store_event (&event);
10832
10833 event.kind = TOOL_BAR_EVENT;
10834 event.frame_or_window = frame;
10835 event.arg = key;
10836 event.modifiers = modifiers;
10837 kbd_buffer_store_event (&event);
10838 last_tool_bar_item = -1;
10839 }
10840 }
10841
10842
10843 /* Possibly highlight a tool-bar item on frame F when mouse moves to
10844 tool-bar window-relative coordinates X/Y. Called from
10845 note_mouse_highlight. */
10846
10847 static void
10848 note_tool_bar_highlight (struct frame *f, int x, int y)
10849 {
10850 Lisp_Object window = f->tool_bar_window;
10851 struct window *w = XWINDOW (window);
10852 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
10853 int hpos, vpos;
10854 struct glyph *glyph;
10855 struct glyph_row *row;
10856 int i;
10857 Lisp_Object enabled_p;
10858 int prop_idx;
10859 enum draw_glyphs_face draw = DRAW_IMAGE_RAISED;
10860 int mouse_down_p, rc;
10861
10862 /* Function note_mouse_highlight is called with negative x(y
10863 values when mouse moves outside of the frame. */
10864 if (x <= 0 || y <= 0)
10865 {
10866 clear_mouse_face (dpyinfo);
10867 return;
10868 }
10869
10870 rc = get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx);
10871 if (rc < 0)
10872 {
10873 /* Not on tool-bar item. */
10874 clear_mouse_face (dpyinfo);
10875 return;
10876 }
10877 else if (rc == 0)
10878 /* On same tool-bar item as before. */
10879 goto set_help_echo;
10880
10881 clear_mouse_face (dpyinfo);
10882
10883 /* Mouse is down, but on different tool-bar item? */
10884 mouse_down_p = (dpyinfo->grabbed
10885 && f == last_mouse_frame
10886 && FRAME_LIVE_P (f));
10887 if (mouse_down_p
10888 && last_tool_bar_item != prop_idx)
10889 return;
10890
10891 dpyinfo->mouse_face_image_state = DRAW_NORMAL_TEXT;
10892 draw = mouse_down_p ? DRAW_IMAGE_SUNKEN : DRAW_IMAGE_RAISED;
10893
10894 /* If tool-bar item is not enabled, don't highlight it. */
10895 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
10896 if (!NILP (enabled_p))
10897 {
10898 /* Compute the x-position of the glyph. In front and past the
10899 image is a space. We include this in the highlighted area. */
10900 row = MATRIX_ROW (w->current_matrix, vpos);
10901 for (i = x = 0; i < hpos; ++i)
10902 x += row->glyphs[TEXT_AREA][i].pixel_width;
10903
10904 /* Record this as the current active region. */
10905 dpyinfo->mouse_face_beg_col = hpos;
10906 dpyinfo->mouse_face_beg_row = vpos;
10907 dpyinfo->mouse_face_beg_x = x;
10908 dpyinfo->mouse_face_beg_y = row->y;
10909 dpyinfo->mouse_face_past_end = 0;
10910
10911 dpyinfo->mouse_face_end_col = hpos + 1;
10912 dpyinfo->mouse_face_end_row = vpos;
10913 dpyinfo->mouse_face_end_x = x + glyph->pixel_width;
10914 dpyinfo->mouse_face_end_y = row->y;
10915 dpyinfo->mouse_face_window = window;
10916 dpyinfo->mouse_face_face_id = TOOL_BAR_FACE_ID;
10917
10918 /* Display it as active. */
10919 show_mouse_face (dpyinfo, draw);
10920 dpyinfo->mouse_face_image_state = draw;
10921 }
10922
10923 set_help_echo:
10924
10925 /* Set help_echo_string to a help string to display for this tool-bar item.
10926 XTread_socket does the rest. */
10927 help_echo_object = help_echo_window = Qnil;
10928 help_echo_pos = -1;
10929 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_HELP);
10930 if (NILP (help_echo_string))
10931 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_CAPTION);
10932 }
10933
10934 #endif /* HAVE_WINDOW_SYSTEM */
10935
10936
10937 \f
10938 /************************************************************************
10939 Horizontal scrolling
10940 ************************************************************************/
10941
10942 static int hscroll_window_tree (Lisp_Object);
10943 static int hscroll_windows (Lisp_Object);
10944
10945 /* For all leaf windows in the window tree rooted at WINDOW, set their
10946 hscroll value so that PT is (i) visible in the window, and (ii) so
10947 that it is not within a certain margin at the window's left and
10948 right border. Value is non-zero if any window's hscroll has been
10949 changed. */
10950
10951 static int
10952 hscroll_window_tree (Lisp_Object window)
10953 {
10954 int hscrolled_p = 0;
10955 int hscroll_relative_p = FLOATP (Vhscroll_step);
10956 int hscroll_step_abs = 0;
10957 double hscroll_step_rel = 0;
10958
10959 if (hscroll_relative_p)
10960 {
10961 hscroll_step_rel = XFLOAT_DATA (Vhscroll_step);
10962 if (hscroll_step_rel < 0)
10963 {
10964 hscroll_relative_p = 0;
10965 hscroll_step_abs = 0;
10966 }
10967 }
10968 else if (INTEGERP (Vhscroll_step))
10969 {
10970 hscroll_step_abs = XINT (Vhscroll_step);
10971 if (hscroll_step_abs < 0)
10972 hscroll_step_abs = 0;
10973 }
10974 else
10975 hscroll_step_abs = 0;
10976
10977 while (WINDOWP (window))
10978 {
10979 struct window *w = XWINDOW (window);
10980
10981 if (WINDOWP (w->hchild))
10982 hscrolled_p |= hscroll_window_tree (w->hchild);
10983 else if (WINDOWP (w->vchild))
10984 hscrolled_p |= hscroll_window_tree (w->vchild);
10985 else if (w->cursor.vpos >= 0)
10986 {
10987 int h_margin;
10988 int text_area_width;
10989 struct glyph_row *current_cursor_row
10990 = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
10991 struct glyph_row *desired_cursor_row
10992 = MATRIX_ROW (w->desired_matrix, w->cursor.vpos);
10993 struct glyph_row *cursor_row
10994 = (desired_cursor_row->enabled_p
10995 ? desired_cursor_row
10996 : current_cursor_row);
10997
10998 text_area_width = window_box_width (w, TEXT_AREA);
10999
11000 /* Scroll when cursor is inside this scroll margin. */
11001 h_margin = hscroll_margin * WINDOW_FRAME_COLUMN_WIDTH (w);
11002
11003 if (!NILP (Fbuffer_local_value (Qauto_hscroll_mode, w->buffer))
11004 && ((XFASTINT (w->hscroll)
11005 && w->cursor.x <= h_margin)
11006 || (cursor_row->enabled_p
11007 && cursor_row->truncated_on_right_p
11008 && (w->cursor.x >= text_area_width - h_margin))))
11009 {
11010 struct it it;
11011 int hscroll;
11012 struct buffer *saved_current_buffer;
11013 int pt;
11014 int wanted_x;
11015
11016 /* Find point in a display of infinite width. */
11017 saved_current_buffer = current_buffer;
11018 current_buffer = XBUFFER (w->buffer);
11019
11020 if (w == XWINDOW (selected_window))
11021 pt = BUF_PT (current_buffer);
11022 else
11023 {
11024 pt = marker_position (w->pointm);
11025 pt = max (BEGV, pt);
11026 pt = min (ZV, pt);
11027 }
11028
11029 /* Move iterator to pt starting at cursor_row->start in
11030 a line with infinite width. */
11031 init_to_row_start (&it, w, cursor_row);
11032 it.last_visible_x = INFINITY;
11033 move_it_in_display_line_to (&it, pt, -1, MOVE_TO_POS);
11034 current_buffer = saved_current_buffer;
11035
11036 /* Position cursor in window. */
11037 if (!hscroll_relative_p && hscroll_step_abs == 0)
11038 hscroll = max (0, (it.current_x
11039 - (ITERATOR_AT_END_OF_LINE_P (&it)
11040 ? (text_area_width - 4 * FRAME_COLUMN_WIDTH (it.f))
11041 : (text_area_width / 2))))
11042 / FRAME_COLUMN_WIDTH (it.f);
11043 else if (w->cursor.x >= text_area_width - h_margin)
11044 {
11045 if (hscroll_relative_p)
11046 wanted_x = text_area_width * (1 - hscroll_step_rel)
11047 - h_margin;
11048 else
11049 wanted_x = text_area_width
11050 - hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
11051 - h_margin;
11052 hscroll
11053 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
11054 }
11055 else
11056 {
11057 if (hscroll_relative_p)
11058 wanted_x = text_area_width * hscroll_step_rel
11059 + h_margin;
11060 else
11061 wanted_x = hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
11062 + h_margin;
11063 hscroll
11064 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
11065 }
11066 hscroll = max (hscroll, XFASTINT (w->min_hscroll));
11067
11068 /* Don't call Fset_window_hscroll if value hasn't
11069 changed because it will prevent redisplay
11070 optimizations. */
11071 if (XFASTINT (w->hscroll) != hscroll)
11072 {
11073 XBUFFER (w->buffer)->prevent_redisplay_optimizations_p = 1;
11074 w->hscroll = make_number (hscroll);
11075 hscrolled_p = 1;
11076 }
11077 }
11078 }
11079
11080 window = w->next;
11081 }
11082
11083 /* Value is non-zero if hscroll of any leaf window has been changed. */
11084 return hscrolled_p;
11085 }
11086
11087
11088 /* Set hscroll so that cursor is visible and not inside horizontal
11089 scroll margins for all windows in the tree rooted at WINDOW. See
11090 also hscroll_window_tree above. Value is non-zero if any window's
11091 hscroll has been changed. If it has, desired matrices on the frame
11092 of WINDOW are cleared. */
11093
11094 static int
11095 hscroll_windows (Lisp_Object window)
11096 {
11097 int hscrolled_p = hscroll_window_tree (window);
11098 if (hscrolled_p)
11099 clear_desired_matrices (XFRAME (WINDOW_FRAME (XWINDOW (window))));
11100 return hscrolled_p;
11101 }
11102
11103
11104 \f
11105 /************************************************************************
11106 Redisplay
11107 ************************************************************************/
11108
11109 /* Variables holding some state of redisplay if GLYPH_DEBUG is defined
11110 to a non-zero value. This is sometimes handy to have in a debugger
11111 session. */
11112
11113 #if GLYPH_DEBUG
11114
11115 /* First and last unchanged row for try_window_id. */
11116
11117 int debug_first_unchanged_at_end_vpos;
11118 int debug_last_unchanged_at_beg_vpos;
11119
11120 /* Delta vpos and y. */
11121
11122 int debug_dvpos, debug_dy;
11123
11124 /* Delta in characters and bytes for try_window_id. */
11125
11126 int debug_delta, debug_delta_bytes;
11127
11128 /* Values of window_end_pos and window_end_vpos at the end of
11129 try_window_id. */
11130
11131 EMACS_INT debug_end_pos, debug_end_vpos;
11132
11133 /* Append a string to W->desired_matrix->method. FMT is a printf
11134 format string. A1...A9 are a supplement for a variable-length
11135 argument list. If trace_redisplay_p is non-zero also printf the
11136 resulting string to stderr. */
11137
11138 static void
11139 debug_method_add (w, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9)
11140 struct window *w;
11141 char *fmt;
11142 int a1, a2, a3, a4, a5, a6, a7, a8, a9;
11143 {
11144 char buffer[512];
11145 char *method = w->desired_matrix->method;
11146 int len = strlen (method);
11147 int size = sizeof w->desired_matrix->method;
11148 int remaining = size - len - 1;
11149
11150 sprintf (buffer, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9);
11151 if (len && remaining)
11152 {
11153 method[len] = '|';
11154 --remaining, ++len;
11155 }
11156
11157 strncpy (method + len, buffer, remaining);
11158
11159 if (trace_redisplay_p)
11160 fprintf (stderr, "%p (%s): %s\n",
11161 w,
11162 ((BUFFERP (w->buffer)
11163 && STRINGP (XBUFFER (w->buffer)->name))
11164 ? (char *) SDATA (XBUFFER (w->buffer)->name)
11165 : "no buffer"),
11166 buffer);
11167 }
11168
11169 #endif /* GLYPH_DEBUG */
11170
11171
11172 /* Value is non-zero if all changes in window W, which displays
11173 current_buffer, are in the text between START and END. START is a
11174 buffer position, END is given as a distance from Z. Used in
11175 redisplay_internal for display optimization. */
11176
11177 static INLINE int
11178 text_outside_line_unchanged_p (struct window *w, int start, int end)
11179 {
11180 int unchanged_p = 1;
11181
11182 /* If text or overlays have changed, see where. */
11183 if (XFASTINT (w->last_modified) < MODIFF
11184 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
11185 {
11186 /* Gap in the line? */
11187 if (GPT < start || Z - GPT < end)
11188 unchanged_p = 0;
11189
11190 /* Changes start in front of the line, or end after it? */
11191 if (unchanged_p
11192 && (BEG_UNCHANGED < start - 1
11193 || END_UNCHANGED < end))
11194 unchanged_p = 0;
11195
11196 /* If selective display, can't optimize if changes start at the
11197 beginning of the line. */
11198 if (unchanged_p
11199 && INTEGERP (current_buffer->selective_display)
11200 && XINT (current_buffer->selective_display) > 0
11201 && (BEG_UNCHANGED < start || GPT <= start))
11202 unchanged_p = 0;
11203
11204 /* If there are overlays at the start or end of the line, these
11205 may have overlay strings with newlines in them. A change at
11206 START, for instance, may actually concern the display of such
11207 overlay strings as well, and they are displayed on different
11208 lines. So, quickly rule out this case. (For the future, it
11209 might be desirable to implement something more telling than
11210 just BEG/END_UNCHANGED.) */
11211 if (unchanged_p)
11212 {
11213 if (BEG + BEG_UNCHANGED == start
11214 && overlay_touches_p (start))
11215 unchanged_p = 0;
11216 if (END_UNCHANGED == end
11217 && overlay_touches_p (Z - end))
11218 unchanged_p = 0;
11219 }
11220
11221 /* Under bidi reordering, adding or deleting a character in the
11222 beginning of a paragraph, before the first strong directional
11223 character, can change the base direction of the paragraph (unless
11224 the buffer specifies a fixed paragraph direction), which will
11225 require to redisplay the whole paragraph. It might be worthwhile
11226 to find the paragraph limits and widen the range of redisplayed
11227 lines to that, but for now just give up this optimization. */
11228 if (!NILP (XBUFFER (w->buffer)->bidi_display_reordering)
11229 && NILP (XBUFFER (w->buffer)->bidi_paragraph_direction))
11230 unchanged_p = 0;
11231 }
11232
11233 return unchanged_p;
11234 }
11235
11236
11237 /* Do a frame update, taking possible shortcuts into account. This is
11238 the main external entry point for redisplay.
11239
11240 If the last redisplay displayed an echo area message and that message
11241 is no longer requested, we clear the echo area or bring back the
11242 mini-buffer if that is in use. */
11243
11244 void
11245 redisplay (void)
11246 {
11247 redisplay_internal (0);
11248 }
11249
11250
11251 static Lisp_Object
11252 overlay_arrow_string_or_property (Lisp_Object var)
11253 {
11254 Lisp_Object val;
11255
11256 if (val = Fget (var, Qoverlay_arrow_string), STRINGP (val))
11257 return val;
11258
11259 return Voverlay_arrow_string;
11260 }
11261
11262 /* Return 1 if there are any overlay-arrows in current_buffer. */
11263 static int
11264 overlay_arrow_in_current_buffer_p (void)
11265 {
11266 Lisp_Object vlist;
11267
11268 for (vlist = Voverlay_arrow_variable_list;
11269 CONSP (vlist);
11270 vlist = XCDR (vlist))
11271 {
11272 Lisp_Object var = XCAR (vlist);
11273 Lisp_Object val;
11274
11275 if (!SYMBOLP (var))
11276 continue;
11277 val = find_symbol_value (var);
11278 if (MARKERP (val)
11279 && current_buffer == XMARKER (val)->buffer)
11280 return 1;
11281 }
11282 return 0;
11283 }
11284
11285
11286 /* Return 1 if any overlay_arrows have moved or overlay-arrow-string
11287 has changed. */
11288
11289 static int
11290 overlay_arrows_changed_p (void)
11291 {
11292 Lisp_Object vlist;
11293
11294 for (vlist = Voverlay_arrow_variable_list;
11295 CONSP (vlist);
11296 vlist = XCDR (vlist))
11297 {
11298 Lisp_Object var = XCAR (vlist);
11299 Lisp_Object val, pstr;
11300
11301 if (!SYMBOLP (var))
11302 continue;
11303 val = find_symbol_value (var);
11304 if (!MARKERP (val))
11305 continue;
11306 if (! EQ (COERCE_MARKER (val),
11307 Fget (var, Qlast_arrow_position))
11308 || ! (pstr = overlay_arrow_string_or_property (var),
11309 EQ (pstr, Fget (var, Qlast_arrow_string))))
11310 return 1;
11311 }
11312 return 0;
11313 }
11314
11315 /* Mark overlay arrows to be updated on next redisplay. */
11316
11317 static void
11318 update_overlay_arrows (int up_to_date)
11319 {
11320 Lisp_Object vlist;
11321
11322 for (vlist = Voverlay_arrow_variable_list;
11323 CONSP (vlist);
11324 vlist = XCDR (vlist))
11325 {
11326 Lisp_Object var = XCAR (vlist);
11327
11328 if (!SYMBOLP (var))
11329 continue;
11330
11331 if (up_to_date > 0)
11332 {
11333 Lisp_Object val = find_symbol_value (var);
11334 Fput (var, Qlast_arrow_position,
11335 COERCE_MARKER (val));
11336 Fput (var, Qlast_arrow_string,
11337 overlay_arrow_string_or_property (var));
11338 }
11339 else if (up_to_date < 0
11340 || !NILP (Fget (var, Qlast_arrow_position)))
11341 {
11342 Fput (var, Qlast_arrow_position, Qt);
11343 Fput (var, Qlast_arrow_string, Qt);
11344 }
11345 }
11346 }
11347
11348
11349 /* Return overlay arrow string to display at row.
11350 Return integer (bitmap number) for arrow bitmap in left fringe.
11351 Return nil if no overlay arrow. */
11352
11353 static Lisp_Object
11354 overlay_arrow_at_row (struct it *it, struct glyph_row *row)
11355 {
11356 Lisp_Object vlist;
11357
11358 for (vlist = Voverlay_arrow_variable_list;
11359 CONSP (vlist);
11360 vlist = XCDR (vlist))
11361 {
11362 Lisp_Object var = XCAR (vlist);
11363 Lisp_Object val;
11364
11365 if (!SYMBOLP (var))
11366 continue;
11367
11368 val = find_symbol_value (var);
11369
11370 if (MARKERP (val)
11371 && current_buffer == XMARKER (val)->buffer
11372 && (MATRIX_ROW_START_CHARPOS (row) == marker_position (val)))
11373 {
11374 if (FRAME_WINDOW_P (it->f)
11375 /* FIXME: if ROW->reversed_p is set, this should test
11376 the right fringe, not the left one. */
11377 && WINDOW_LEFT_FRINGE_WIDTH (it->w) > 0)
11378 {
11379 #ifdef HAVE_WINDOW_SYSTEM
11380 if (val = Fget (var, Qoverlay_arrow_bitmap), SYMBOLP (val))
11381 {
11382 int fringe_bitmap;
11383 if ((fringe_bitmap = lookup_fringe_bitmap (val)) != 0)
11384 return make_number (fringe_bitmap);
11385 }
11386 #endif
11387 return make_number (-1); /* Use default arrow bitmap */
11388 }
11389 return overlay_arrow_string_or_property (var);
11390 }
11391 }
11392
11393 return Qnil;
11394 }
11395
11396 /* Return 1 if point moved out of or into a composition. Otherwise
11397 return 0. PREV_BUF and PREV_PT are the last point buffer and
11398 position. BUF and PT are the current point buffer and position. */
11399
11400 int
11401 check_point_in_composition (struct buffer *prev_buf, int prev_pt,
11402 struct buffer *buf, int pt)
11403 {
11404 EMACS_INT start, end;
11405 Lisp_Object prop;
11406 Lisp_Object buffer;
11407
11408 XSETBUFFER (buffer, buf);
11409 /* Check a composition at the last point if point moved within the
11410 same buffer. */
11411 if (prev_buf == buf)
11412 {
11413 if (prev_pt == pt)
11414 /* Point didn't move. */
11415 return 0;
11416
11417 if (prev_pt > BUF_BEGV (buf) && prev_pt < BUF_ZV (buf)
11418 && find_composition (prev_pt, -1, &start, &end, &prop, buffer)
11419 && COMPOSITION_VALID_P (start, end, prop)
11420 && start < prev_pt && end > prev_pt)
11421 /* The last point was within the composition. Return 1 iff
11422 point moved out of the composition. */
11423 return (pt <= start || pt >= end);
11424 }
11425
11426 /* Check a composition at the current point. */
11427 return (pt > BUF_BEGV (buf) && pt < BUF_ZV (buf)
11428 && find_composition (pt, -1, &start, &end, &prop, buffer)
11429 && COMPOSITION_VALID_P (start, end, prop)
11430 && start < pt && end > pt);
11431 }
11432
11433
11434 /* Reconsider the setting of B->clip_changed which is displayed
11435 in window W. */
11436
11437 static INLINE void
11438 reconsider_clip_changes (struct window *w, struct buffer *b)
11439 {
11440 if (b->clip_changed
11441 && !NILP (w->window_end_valid)
11442 && w->current_matrix->buffer == b
11443 && w->current_matrix->zv == BUF_ZV (b)
11444 && w->current_matrix->begv == BUF_BEGV (b))
11445 b->clip_changed = 0;
11446
11447 /* If display wasn't paused, and W is not a tool bar window, see if
11448 point has been moved into or out of a composition. In that case,
11449 we set b->clip_changed to 1 to force updating the screen. If
11450 b->clip_changed has already been set to 1, we can skip this
11451 check. */
11452 if (!b->clip_changed
11453 && BUFFERP (w->buffer) && !NILP (w->window_end_valid))
11454 {
11455 int pt;
11456
11457 if (w == XWINDOW (selected_window))
11458 pt = BUF_PT (current_buffer);
11459 else
11460 pt = marker_position (w->pointm);
11461
11462 if ((w->current_matrix->buffer != XBUFFER (w->buffer)
11463 || pt != XINT (w->last_point))
11464 && check_point_in_composition (w->current_matrix->buffer,
11465 XINT (w->last_point),
11466 XBUFFER (w->buffer), pt))
11467 b->clip_changed = 1;
11468 }
11469 }
11470 \f
11471
11472 /* Select FRAME to forward the values of frame-local variables into C
11473 variables so that the redisplay routines can access those values
11474 directly. */
11475
11476 static void
11477 select_frame_for_redisplay (Lisp_Object frame)
11478 {
11479 Lisp_Object tail, tem;
11480 Lisp_Object old = selected_frame;
11481 struct Lisp_Symbol *sym;
11482
11483 xassert (FRAMEP (frame) && FRAME_LIVE_P (XFRAME (frame)));
11484
11485 selected_frame = frame;
11486
11487 do {
11488 for (tail = XFRAME (frame)->param_alist; CONSP (tail); tail = XCDR (tail))
11489 if (CONSP (XCAR (tail))
11490 && (tem = XCAR (XCAR (tail)),
11491 SYMBOLP (tem))
11492 && (sym = indirect_variable (XSYMBOL (tem)),
11493 sym->redirect == SYMBOL_LOCALIZED)
11494 && sym->val.blv->frame_local)
11495 /* Use find_symbol_value rather than Fsymbol_value
11496 to avoid an error if it is void. */
11497 find_symbol_value (tem);
11498 } while (!EQ (frame, old) && (frame = old, 1));
11499 }
11500
11501
11502 #define STOP_POLLING \
11503 do { if (! polling_stopped_here) stop_polling (); \
11504 polling_stopped_here = 1; } while (0)
11505
11506 #define RESUME_POLLING \
11507 do { if (polling_stopped_here) start_polling (); \
11508 polling_stopped_here = 0; } while (0)
11509
11510
11511 /* If PRESERVE_ECHO_AREA is nonzero, it means this redisplay is not in
11512 response to any user action; therefore, we should preserve the echo
11513 area. (Actually, our caller does that job.) Perhaps in the future
11514 avoid recentering windows if it is not necessary; currently that
11515 causes some problems. */
11516
11517 static void
11518 redisplay_internal (int preserve_echo_area)
11519 {
11520 struct window *w = XWINDOW (selected_window);
11521 struct frame *f;
11522 int pause;
11523 int must_finish = 0;
11524 struct text_pos tlbufpos, tlendpos;
11525 int number_of_visible_frames;
11526 int count, count1;
11527 struct frame *sf;
11528 int polling_stopped_here = 0;
11529 Lisp_Object old_frame = selected_frame;
11530
11531 /* Non-zero means redisplay has to consider all windows on all
11532 frames. Zero means, only selected_window is considered. */
11533 int consider_all_windows_p;
11534
11535 TRACE ((stderr, "redisplay_internal %d\n", redisplaying_p));
11536
11537 /* No redisplay if running in batch mode or frame is not yet fully
11538 initialized, or redisplay is explicitly turned off by setting
11539 Vinhibit_redisplay. */
11540 if (FRAME_INITIAL_P (SELECTED_FRAME ())
11541 || !NILP (Vinhibit_redisplay))
11542 return;
11543
11544 /* Don't examine these until after testing Vinhibit_redisplay.
11545 When Emacs is shutting down, perhaps because its connection to
11546 X has dropped, we should not look at them at all. */
11547 f = XFRAME (w->frame);
11548 sf = SELECTED_FRAME ();
11549
11550 if (!f->glyphs_initialized_p)
11551 return;
11552
11553 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS)
11554 if (popup_activated ())
11555 return;
11556 #endif
11557
11558 /* I don't think this happens but let's be paranoid. */
11559 if (redisplaying_p)
11560 return;
11561
11562 /* Record a function that resets redisplaying_p to its old value
11563 when we leave this function. */
11564 count = SPECPDL_INDEX ();
11565 record_unwind_protect (unwind_redisplay,
11566 Fcons (make_number (redisplaying_p), selected_frame));
11567 ++redisplaying_p;
11568 specbind (Qinhibit_free_realized_faces, Qnil);
11569
11570 {
11571 Lisp_Object tail, frame;
11572
11573 FOR_EACH_FRAME (tail, frame)
11574 {
11575 struct frame *f = XFRAME (frame);
11576 f->already_hscrolled_p = 0;
11577 }
11578 }
11579
11580 retry:
11581 if (!EQ (old_frame, selected_frame)
11582 && FRAME_LIVE_P (XFRAME (old_frame)))
11583 /* When running redisplay, we play a bit fast-and-loose and allow e.g.
11584 selected_frame and selected_window to be temporarily out-of-sync so
11585 when we come back here via `goto retry', we need to resync because we
11586 may need to run Elisp code (via prepare_menu_bars). */
11587 select_frame_for_redisplay (old_frame);
11588
11589 pause = 0;
11590 reconsider_clip_changes (w, current_buffer);
11591 last_escape_glyph_frame = NULL;
11592 last_escape_glyph_face_id = (1 << FACE_ID_BITS);
11593
11594 /* If new fonts have been loaded that make a glyph matrix adjustment
11595 necessary, do it. */
11596 if (fonts_changed_p)
11597 {
11598 adjust_glyphs (NULL);
11599 ++windows_or_buffers_changed;
11600 fonts_changed_p = 0;
11601 }
11602
11603 /* If face_change_count is non-zero, init_iterator will free all
11604 realized faces, which includes the faces referenced from current
11605 matrices. So, we can't reuse current matrices in this case. */
11606 if (face_change_count)
11607 ++windows_or_buffers_changed;
11608
11609 if ((FRAME_TERMCAP_P (sf) || FRAME_MSDOS_P (sf))
11610 && FRAME_TTY (sf)->previous_frame != sf)
11611 {
11612 /* Since frames on a single ASCII terminal share the same
11613 display area, displaying a different frame means redisplay
11614 the whole thing. */
11615 windows_or_buffers_changed++;
11616 SET_FRAME_GARBAGED (sf);
11617 #ifndef DOS_NT
11618 set_tty_color_mode (FRAME_TTY (sf), sf);
11619 #endif
11620 FRAME_TTY (sf)->previous_frame = sf;
11621 }
11622
11623 /* Set the visible flags for all frames. Do this before checking
11624 for resized or garbaged frames; they want to know if their frames
11625 are visible. See the comment in frame.h for
11626 FRAME_SAMPLE_VISIBILITY. */
11627 {
11628 Lisp_Object tail, frame;
11629
11630 number_of_visible_frames = 0;
11631
11632 FOR_EACH_FRAME (tail, frame)
11633 {
11634 struct frame *f = XFRAME (frame);
11635
11636 FRAME_SAMPLE_VISIBILITY (f);
11637 if (FRAME_VISIBLE_P (f))
11638 ++number_of_visible_frames;
11639 clear_desired_matrices (f);
11640 }
11641 }
11642
11643 /* Notice any pending interrupt request to change frame size. */
11644 do_pending_window_change (1);
11645
11646 /* Clear frames marked as garbaged. */
11647 if (frame_garbaged)
11648 clear_garbaged_frames ();
11649
11650 /* Build menubar and tool-bar items. */
11651 if (NILP (Vmemory_full))
11652 prepare_menu_bars ();
11653
11654 if (windows_or_buffers_changed)
11655 update_mode_lines++;
11656
11657 /* Detect case that we need to write or remove a star in the mode line. */
11658 if ((SAVE_MODIFF < MODIFF) != !NILP (w->last_had_star))
11659 {
11660 w->update_mode_line = Qt;
11661 if (buffer_shared > 1)
11662 update_mode_lines++;
11663 }
11664
11665 /* Avoid invocation of point motion hooks by `current_column' below. */
11666 count1 = SPECPDL_INDEX ();
11667 specbind (Qinhibit_point_motion_hooks, Qt);
11668
11669 /* If %c is in the mode line, update it if needed. */
11670 if (!NILP (w->column_number_displayed)
11671 /* This alternative quickly identifies a common case
11672 where no change is needed. */
11673 && !(PT == XFASTINT (w->last_point)
11674 && XFASTINT (w->last_modified) >= MODIFF
11675 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
11676 && (XFASTINT (w->column_number_displayed)
11677 != (int) current_column ())) /* iftc */
11678 w->update_mode_line = Qt;
11679
11680 unbind_to (count1, Qnil);
11681
11682 FRAME_SCROLL_BOTTOM_VPOS (XFRAME (w->frame)) = -1;
11683
11684 /* The variable buffer_shared is set in redisplay_window and
11685 indicates that we redisplay a buffer in different windows. See
11686 there. */
11687 consider_all_windows_p = (update_mode_lines || buffer_shared > 1
11688 || cursor_type_changed);
11689
11690 /* If specs for an arrow have changed, do thorough redisplay
11691 to ensure we remove any arrow that should no longer exist. */
11692 if (overlay_arrows_changed_p ())
11693 consider_all_windows_p = windows_or_buffers_changed = 1;
11694
11695 /* Normally the message* functions will have already displayed and
11696 updated the echo area, but the frame may have been trashed, or
11697 the update may have been preempted, so display the echo area
11698 again here. Checking message_cleared_p captures the case that
11699 the echo area should be cleared. */
11700 if ((!NILP (echo_area_buffer[0]) && !display_last_displayed_message_p)
11701 || (!NILP (echo_area_buffer[1]) && display_last_displayed_message_p)
11702 || (message_cleared_p
11703 && minibuf_level == 0
11704 /* If the mini-window is currently selected, this means the
11705 echo-area doesn't show through. */
11706 && !MINI_WINDOW_P (XWINDOW (selected_window))))
11707 {
11708 int window_height_changed_p = echo_area_display (0);
11709 must_finish = 1;
11710
11711 /* If we don't display the current message, don't clear the
11712 message_cleared_p flag, because, if we did, we wouldn't clear
11713 the echo area in the next redisplay which doesn't preserve
11714 the echo area. */
11715 if (!display_last_displayed_message_p)
11716 message_cleared_p = 0;
11717
11718 if (fonts_changed_p)
11719 goto retry;
11720 else if (window_height_changed_p)
11721 {
11722 consider_all_windows_p = 1;
11723 ++update_mode_lines;
11724 ++windows_or_buffers_changed;
11725
11726 /* If window configuration was changed, frames may have been
11727 marked garbaged. Clear them or we will experience
11728 surprises wrt scrolling. */
11729 if (frame_garbaged)
11730 clear_garbaged_frames ();
11731 }
11732 }
11733 else if (EQ (selected_window, minibuf_window)
11734 && (current_buffer->clip_changed
11735 || XFASTINT (w->last_modified) < MODIFF
11736 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
11737 && resize_mini_window (w, 0))
11738 {
11739 /* Resized active mini-window to fit the size of what it is
11740 showing if its contents might have changed. */
11741 must_finish = 1;
11742 /* FIXME: this causes all frames to be updated, which seems unnecessary
11743 since only the current frame needs to be considered. This function needs
11744 to be rewritten with two variables, consider_all_windows and
11745 consider_all_frames. */
11746 consider_all_windows_p = 1;
11747 ++windows_or_buffers_changed;
11748 ++update_mode_lines;
11749
11750 /* If window configuration was changed, frames may have been
11751 marked garbaged. Clear them or we will experience
11752 surprises wrt scrolling. */
11753 if (frame_garbaged)
11754 clear_garbaged_frames ();
11755 }
11756
11757
11758 /* If showing the region, and mark has changed, we must redisplay
11759 the whole window. The assignment to this_line_start_pos prevents
11760 the optimization directly below this if-statement. */
11761 if (((!NILP (Vtransient_mark_mode)
11762 && !NILP (XBUFFER (w->buffer)->mark_active))
11763 != !NILP (w->region_showing))
11764 || (!NILP (w->region_showing)
11765 && !EQ (w->region_showing,
11766 Fmarker_position (XBUFFER (w->buffer)->mark))))
11767 CHARPOS (this_line_start_pos) = 0;
11768
11769 /* Optimize the case that only the line containing the cursor in the
11770 selected window has changed. Variables starting with this_ are
11771 set in display_line and record information about the line
11772 containing the cursor. */
11773 tlbufpos = this_line_start_pos;
11774 tlendpos = this_line_end_pos;
11775 if (!consider_all_windows_p
11776 && CHARPOS (tlbufpos) > 0
11777 && NILP (w->update_mode_line)
11778 && !current_buffer->clip_changed
11779 && !current_buffer->prevent_redisplay_optimizations_p
11780 && FRAME_VISIBLE_P (XFRAME (w->frame))
11781 && !FRAME_OBSCURED_P (XFRAME (w->frame))
11782 /* Make sure recorded data applies to current buffer, etc. */
11783 && this_line_buffer == current_buffer
11784 && current_buffer == XBUFFER (w->buffer)
11785 && NILP (w->force_start)
11786 && NILP (w->optional_new_start)
11787 /* Point must be on the line that we have info recorded about. */
11788 && PT >= CHARPOS (tlbufpos)
11789 && PT <= Z - CHARPOS (tlendpos)
11790 /* All text outside that line, including its final newline,
11791 must be unchanged. */
11792 && text_outside_line_unchanged_p (w, CHARPOS (tlbufpos),
11793 CHARPOS (tlendpos)))
11794 {
11795 if (CHARPOS (tlbufpos) > BEGV
11796 && FETCH_BYTE (BYTEPOS (tlbufpos) - 1) != '\n'
11797 && (CHARPOS (tlbufpos) == ZV
11798 || FETCH_BYTE (BYTEPOS (tlbufpos)) == '\n'))
11799 /* Former continuation line has disappeared by becoming empty. */
11800 goto cancel;
11801 else if (XFASTINT (w->last_modified) < MODIFF
11802 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF
11803 || MINI_WINDOW_P (w))
11804 {
11805 /* We have to handle the case of continuation around a
11806 wide-column character (see the comment in indent.c around
11807 line 1340).
11808
11809 For instance, in the following case:
11810
11811 -------- Insert --------
11812 K_A_N_\\ `a' K_A_N_a\ `X_' are wide-column chars.
11813 J_I_ ==> J_I_ `^^' are cursors.
11814 ^^ ^^
11815 -------- --------
11816
11817 As we have to redraw the line above, we cannot use this
11818 optimization. */
11819
11820 struct it it;
11821 int line_height_before = this_line_pixel_height;
11822
11823 /* Note that start_display will handle the case that the
11824 line starting at tlbufpos is a continuation line. */
11825 start_display (&it, w, tlbufpos);
11826
11827 /* Implementation note: It this still necessary? */
11828 if (it.current_x != this_line_start_x)
11829 goto cancel;
11830
11831 TRACE ((stderr, "trying display optimization 1\n"));
11832 w->cursor.vpos = -1;
11833 overlay_arrow_seen = 0;
11834 it.vpos = this_line_vpos;
11835 it.current_y = this_line_y;
11836 it.glyph_row = MATRIX_ROW (w->desired_matrix, this_line_vpos);
11837 display_line (&it);
11838
11839 /* If line contains point, is not continued,
11840 and ends at same distance from eob as before, we win. */
11841 if (w->cursor.vpos >= 0
11842 /* Line is not continued, otherwise this_line_start_pos
11843 would have been set to 0 in display_line. */
11844 && CHARPOS (this_line_start_pos)
11845 /* Line ends as before. */
11846 && CHARPOS (this_line_end_pos) == CHARPOS (tlendpos)
11847 /* Line has same height as before. Otherwise other lines
11848 would have to be shifted up or down. */
11849 && this_line_pixel_height == line_height_before)
11850 {
11851 /* If this is not the window's last line, we must adjust
11852 the charstarts of the lines below. */
11853 if (it.current_y < it.last_visible_y)
11854 {
11855 struct glyph_row *row
11856 = MATRIX_ROW (w->current_matrix, this_line_vpos + 1);
11857 int delta, delta_bytes;
11858
11859 /* We used to distinguish between two cases here,
11860 conditioned by Z - CHARPOS (tlendpos) == ZV, for
11861 when the line ends in a newline or the end of the
11862 buffer's accessible portion. But both cases did
11863 the same, so they were collapsed. */
11864 delta = (Z
11865 - CHARPOS (tlendpos)
11866 - MATRIX_ROW_START_CHARPOS (row));
11867 delta_bytes = (Z_BYTE
11868 - BYTEPOS (tlendpos)
11869 - MATRIX_ROW_START_BYTEPOS (row));
11870
11871 increment_matrix_positions (w->current_matrix,
11872 this_line_vpos + 1,
11873 w->current_matrix->nrows,
11874 delta, delta_bytes);
11875 }
11876
11877 /* If this row displays text now but previously didn't,
11878 or vice versa, w->window_end_vpos may have to be
11879 adjusted. */
11880 if ((it.glyph_row - 1)->displays_text_p)
11881 {
11882 if (XFASTINT (w->window_end_vpos) < this_line_vpos)
11883 XSETINT (w->window_end_vpos, this_line_vpos);
11884 }
11885 else if (XFASTINT (w->window_end_vpos) == this_line_vpos
11886 && this_line_vpos > 0)
11887 XSETINT (w->window_end_vpos, this_line_vpos - 1);
11888 w->window_end_valid = Qnil;
11889
11890 /* Update hint: No need to try to scroll in update_window. */
11891 w->desired_matrix->no_scrolling_p = 1;
11892
11893 #if GLYPH_DEBUG
11894 *w->desired_matrix->method = 0;
11895 debug_method_add (w, "optimization 1");
11896 #endif
11897 #ifdef HAVE_WINDOW_SYSTEM
11898 update_window_fringes (w, 0);
11899 #endif
11900 goto update;
11901 }
11902 else
11903 goto cancel;
11904 }
11905 else if (/* Cursor position hasn't changed. */
11906 PT == XFASTINT (w->last_point)
11907 /* Make sure the cursor was last displayed
11908 in this window. Otherwise we have to reposition it. */
11909 && 0 <= w->cursor.vpos
11910 && WINDOW_TOTAL_LINES (w) > w->cursor.vpos)
11911 {
11912 if (!must_finish)
11913 {
11914 do_pending_window_change (1);
11915
11916 /* We used to always goto end_of_redisplay here, but this
11917 isn't enough if we have a blinking cursor. */
11918 if (w->cursor_off_p == w->last_cursor_off_p)
11919 goto end_of_redisplay;
11920 }
11921 goto update;
11922 }
11923 /* If highlighting the region, or if the cursor is in the echo area,
11924 then we can't just move the cursor. */
11925 else if (! (!NILP (Vtransient_mark_mode)
11926 && !NILP (current_buffer->mark_active))
11927 && (EQ (selected_window, current_buffer->last_selected_window)
11928 || highlight_nonselected_windows)
11929 && NILP (w->region_showing)
11930 && NILP (Vshow_trailing_whitespace)
11931 && !cursor_in_echo_area)
11932 {
11933 struct it it;
11934 struct glyph_row *row;
11935
11936 /* Skip from tlbufpos to PT and see where it is. Note that
11937 PT may be in invisible text. If so, we will end at the
11938 next visible position. */
11939 init_iterator (&it, w, CHARPOS (tlbufpos), BYTEPOS (tlbufpos),
11940 NULL, DEFAULT_FACE_ID);
11941 it.current_x = this_line_start_x;
11942 it.current_y = this_line_y;
11943 it.vpos = this_line_vpos;
11944
11945 /* The call to move_it_to stops in front of PT, but
11946 moves over before-strings. */
11947 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
11948
11949 if (it.vpos == this_line_vpos
11950 && (row = MATRIX_ROW (w->current_matrix, this_line_vpos),
11951 row->enabled_p))
11952 {
11953 xassert (this_line_vpos == it.vpos);
11954 xassert (this_line_y == it.current_y);
11955 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
11956 #if GLYPH_DEBUG
11957 *w->desired_matrix->method = 0;
11958 debug_method_add (w, "optimization 3");
11959 #endif
11960 goto update;
11961 }
11962 else
11963 goto cancel;
11964 }
11965
11966 cancel:
11967 /* Text changed drastically or point moved off of line. */
11968 SET_MATRIX_ROW_ENABLED_P (w->desired_matrix, this_line_vpos, 0);
11969 }
11970
11971 CHARPOS (this_line_start_pos) = 0;
11972 consider_all_windows_p |= buffer_shared > 1;
11973 ++clear_face_cache_count;
11974 #ifdef HAVE_WINDOW_SYSTEM
11975 ++clear_image_cache_count;
11976 #endif
11977
11978 /* Build desired matrices, and update the display. If
11979 consider_all_windows_p is non-zero, do it for all windows on all
11980 frames. Otherwise do it for selected_window, only. */
11981
11982 if (consider_all_windows_p)
11983 {
11984 Lisp_Object tail, frame;
11985
11986 FOR_EACH_FRAME (tail, frame)
11987 XFRAME (frame)->updated_p = 0;
11988
11989 /* Recompute # windows showing selected buffer. This will be
11990 incremented each time such a window is displayed. */
11991 buffer_shared = 0;
11992
11993 FOR_EACH_FRAME (tail, frame)
11994 {
11995 struct frame *f = XFRAME (frame);
11996
11997 if (FRAME_WINDOW_P (f) || FRAME_TERMCAP_P (f) || f == sf)
11998 {
11999 if (! EQ (frame, selected_frame))
12000 /* Select the frame, for the sake of frame-local
12001 variables. */
12002 select_frame_for_redisplay (frame);
12003
12004 /* Mark all the scroll bars to be removed; we'll redeem
12005 the ones we want when we redisplay their windows. */
12006 if (FRAME_TERMINAL (f)->condemn_scroll_bars_hook)
12007 FRAME_TERMINAL (f)->condemn_scroll_bars_hook (f);
12008
12009 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
12010 redisplay_windows (FRAME_ROOT_WINDOW (f));
12011
12012 /* The X error handler may have deleted that frame. */
12013 if (!FRAME_LIVE_P (f))
12014 continue;
12015
12016 /* Any scroll bars which redisplay_windows should have
12017 nuked should now go away. */
12018 if (FRAME_TERMINAL (f)->judge_scroll_bars_hook)
12019 FRAME_TERMINAL (f)->judge_scroll_bars_hook (f);
12020
12021 /* If fonts changed, display again. */
12022 /* ??? rms: I suspect it is a mistake to jump all the way
12023 back to retry here. It should just retry this frame. */
12024 if (fonts_changed_p)
12025 goto retry;
12026
12027 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
12028 {
12029 /* See if we have to hscroll. */
12030 if (!f->already_hscrolled_p)
12031 {
12032 f->already_hscrolled_p = 1;
12033 if (hscroll_windows (f->root_window))
12034 goto retry;
12035 }
12036
12037 /* Prevent various kinds of signals during display
12038 update. stdio is not robust about handling
12039 signals, which can cause an apparent I/O
12040 error. */
12041 if (interrupt_input)
12042 unrequest_sigio ();
12043 STOP_POLLING;
12044
12045 /* Update the display. */
12046 set_window_update_flags (XWINDOW (f->root_window), 1);
12047 pause |= update_frame (f, 0, 0);
12048 f->updated_p = 1;
12049 }
12050 }
12051 }
12052
12053 if (!EQ (old_frame, selected_frame)
12054 && FRAME_LIVE_P (XFRAME (old_frame)))
12055 /* We played a bit fast-and-loose above and allowed selected_frame
12056 and selected_window to be temporarily out-of-sync but let's make
12057 sure this stays contained. */
12058 select_frame_for_redisplay (old_frame);
12059 eassert (EQ (XFRAME (selected_frame)->selected_window, selected_window));
12060
12061 if (!pause)
12062 {
12063 /* Do the mark_window_display_accurate after all windows have
12064 been redisplayed because this call resets flags in buffers
12065 which are needed for proper redisplay. */
12066 FOR_EACH_FRAME (tail, frame)
12067 {
12068 struct frame *f = XFRAME (frame);
12069 if (f->updated_p)
12070 {
12071 mark_window_display_accurate (f->root_window, 1);
12072 if (FRAME_TERMINAL (f)->frame_up_to_date_hook)
12073 FRAME_TERMINAL (f)->frame_up_to_date_hook (f);
12074 }
12075 }
12076 }
12077 }
12078 else if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
12079 {
12080 Lisp_Object mini_window;
12081 struct frame *mini_frame;
12082
12083 displayed_buffer = XBUFFER (XWINDOW (selected_window)->buffer);
12084 /* Use list_of_error, not Qerror, so that
12085 we catch only errors and don't run the debugger. */
12086 internal_condition_case_1 (redisplay_window_1, selected_window,
12087 list_of_error,
12088 redisplay_window_error);
12089
12090 /* Compare desired and current matrices, perform output. */
12091
12092 update:
12093 /* If fonts changed, display again. */
12094 if (fonts_changed_p)
12095 goto retry;
12096
12097 /* Prevent various kinds of signals during display update.
12098 stdio is not robust about handling signals,
12099 which can cause an apparent I/O error. */
12100 if (interrupt_input)
12101 unrequest_sigio ();
12102 STOP_POLLING;
12103
12104 if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
12105 {
12106 if (hscroll_windows (selected_window))
12107 goto retry;
12108
12109 XWINDOW (selected_window)->must_be_updated_p = 1;
12110 pause = update_frame (sf, 0, 0);
12111 }
12112
12113 /* We may have called echo_area_display at the top of this
12114 function. If the echo area is on another frame, that may
12115 have put text on a frame other than the selected one, so the
12116 above call to update_frame would not have caught it. Catch
12117 it here. */
12118 mini_window = FRAME_MINIBUF_WINDOW (sf);
12119 mini_frame = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
12120
12121 if (mini_frame != sf && FRAME_WINDOW_P (mini_frame))
12122 {
12123 XWINDOW (mini_window)->must_be_updated_p = 1;
12124 pause |= update_frame (mini_frame, 0, 0);
12125 if (!pause && hscroll_windows (mini_window))
12126 goto retry;
12127 }
12128 }
12129
12130 /* If display was paused because of pending input, make sure we do a
12131 thorough update the next time. */
12132 if (pause)
12133 {
12134 /* Prevent the optimization at the beginning of
12135 redisplay_internal that tries a single-line update of the
12136 line containing the cursor in the selected window. */
12137 CHARPOS (this_line_start_pos) = 0;
12138
12139 /* Let the overlay arrow be updated the next time. */
12140 update_overlay_arrows (0);
12141
12142 /* If we pause after scrolling, some rows in the current
12143 matrices of some windows are not valid. */
12144 if (!WINDOW_FULL_WIDTH_P (w)
12145 && !FRAME_WINDOW_P (XFRAME (w->frame)))
12146 update_mode_lines = 1;
12147 }
12148 else
12149 {
12150 if (!consider_all_windows_p)
12151 {
12152 /* This has already been done above if
12153 consider_all_windows_p is set. */
12154 mark_window_display_accurate_1 (w, 1);
12155
12156 /* Say overlay arrows are up to date. */
12157 update_overlay_arrows (1);
12158
12159 if (FRAME_TERMINAL (sf)->frame_up_to_date_hook != 0)
12160 FRAME_TERMINAL (sf)->frame_up_to_date_hook (sf);
12161 }
12162
12163 update_mode_lines = 0;
12164 windows_or_buffers_changed = 0;
12165 cursor_type_changed = 0;
12166 }
12167
12168 /* Start SIGIO interrupts coming again. Having them off during the
12169 code above makes it less likely one will discard output, but not
12170 impossible, since there might be stuff in the system buffer here.
12171 But it is much hairier to try to do anything about that. */
12172 if (interrupt_input)
12173 request_sigio ();
12174 RESUME_POLLING;
12175
12176 /* If a frame has become visible which was not before, redisplay
12177 again, so that we display it. Expose events for such a frame
12178 (which it gets when becoming visible) don't call the parts of
12179 redisplay constructing glyphs, so simply exposing a frame won't
12180 display anything in this case. So, we have to display these
12181 frames here explicitly. */
12182 if (!pause)
12183 {
12184 Lisp_Object tail, frame;
12185 int new_count = 0;
12186
12187 FOR_EACH_FRAME (tail, frame)
12188 {
12189 int this_is_visible = 0;
12190
12191 if (XFRAME (frame)->visible)
12192 this_is_visible = 1;
12193 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
12194 if (XFRAME (frame)->visible)
12195 this_is_visible = 1;
12196
12197 if (this_is_visible)
12198 new_count++;
12199 }
12200
12201 if (new_count != number_of_visible_frames)
12202 windows_or_buffers_changed++;
12203 }
12204
12205 /* Change frame size now if a change is pending. */
12206 do_pending_window_change (1);
12207
12208 /* If we just did a pending size change, or have additional
12209 visible frames, redisplay again. */
12210 if (windows_or_buffers_changed && !pause)
12211 goto retry;
12212
12213 /* Clear the face and image caches.
12214
12215 We used to do this only if consider_all_windows_p. But the cache
12216 needs to be cleared if a timer creates images in the current
12217 buffer (e.g. the test case in Bug#6230). */
12218
12219 if (clear_face_cache_count > CLEAR_FACE_CACHE_COUNT)
12220 {
12221 clear_face_cache (0);
12222 clear_face_cache_count = 0;
12223 }
12224
12225 #ifdef HAVE_WINDOW_SYSTEM
12226 if (clear_image_cache_count > CLEAR_IMAGE_CACHE_COUNT)
12227 {
12228 clear_image_caches (Qnil);
12229 clear_image_cache_count = 0;
12230 }
12231 #endif /* HAVE_WINDOW_SYSTEM */
12232
12233 end_of_redisplay:
12234 unbind_to (count, Qnil);
12235 RESUME_POLLING;
12236 }
12237
12238
12239 /* Redisplay, but leave alone any recent echo area message unless
12240 another message has been requested in its place.
12241
12242 This is useful in situations where you need to redisplay but no
12243 user action has occurred, making it inappropriate for the message
12244 area to be cleared. See tracking_off and
12245 wait_reading_process_output for examples of these situations.
12246
12247 FROM_WHERE is an integer saying from where this function was
12248 called. This is useful for debugging. */
12249
12250 void
12251 redisplay_preserve_echo_area (int from_where)
12252 {
12253 TRACE ((stderr, "redisplay_preserve_echo_area (%d)\n", from_where));
12254
12255 if (!NILP (echo_area_buffer[1]))
12256 {
12257 /* We have a previously displayed message, but no current
12258 message. Redisplay the previous message. */
12259 display_last_displayed_message_p = 1;
12260 redisplay_internal (1);
12261 display_last_displayed_message_p = 0;
12262 }
12263 else
12264 redisplay_internal (1);
12265
12266 if (FRAME_RIF (SELECTED_FRAME ()) != NULL
12267 && FRAME_RIF (SELECTED_FRAME ())->flush_display_optional)
12268 FRAME_RIF (SELECTED_FRAME ())->flush_display_optional (NULL);
12269 }
12270
12271
12272 /* Function registered with record_unwind_protect in
12273 redisplay_internal. Reset redisplaying_p to the value it had
12274 before redisplay_internal was called, and clear
12275 prevent_freeing_realized_faces_p. It also selects the previously
12276 selected frame, unless it has been deleted (by an X connection
12277 failure during redisplay, for example). */
12278
12279 static Lisp_Object
12280 unwind_redisplay (Lisp_Object val)
12281 {
12282 Lisp_Object old_redisplaying_p, old_frame;
12283
12284 old_redisplaying_p = XCAR (val);
12285 redisplaying_p = XFASTINT (old_redisplaying_p);
12286 old_frame = XCDR (val);
12287 if (! EQ (old_frame, selected_frame)
12288 && FRAME_LIVE_P (XFRAME (old_frame)))
12289 select_frame_for_redisplay (old_frame);
12290 return Qnil;
12291 }
12292
12293
12294 /* Mark the display of window W as accurate or inaccurate. If
12295 ACCURATE_P is non-zero mark display of W as accurate. If
12296 ACCURATE_P is zero, arrange for W to be redisplayed the next time
12297 redisplay_internal is called. */
12298
12299 static void
12300 mark_window_display_accurate_1 (struct window *w, int accurate_p)
12301 {
12302 if (BUFFERP (w->buffer))
12303 {
12304 struct buffer *b = XBUFFER (w->buffer);
12305
12306 w->last_modified
12307 = make_number (accurate_p ? BUF_MODIFF (b) : 0);
12308 w->last_overlay_modified
12309 = make_number (accurate_p ? BUF_OVERLAY_MODIFF (b) : 0);
12310 w->last_had_star
12311 = BUF_MODIFF (b) > BUF_SAVE_MODIFF (b) ? Qt : Qnil;
12312
12313 if (accurate_p)
12314 {
12315 b->clip_changed = 0;
12316 b->prevent_redisplay_optimizations_p = 0;
12317
12318 BUF_UNCHANGED_MODIFIED (b) = BUF_MODIFF (b);
12319 BUF_OVERLAY_UNCHANGED_MODIFIED (b) = BUF_OVERLAY_MODIFF (b);
12320 BUF_BEG_UNCHANGED (b) = BUF_GPT (b) - BUF_BEG (b);
12321 BUF_END_UNCHANGED (b) = BUF_Z (b) - BUF_GPT (b);
12322
12323 w->current_matrix->buffer = b;
12324 w->current_matrix->begv = BUF_BEGV (b);
12325 w->current_matrix->zv = BUF_ZV (b);
12326
12327 w->last_cursor = w->cursor;
12328 w->last_cursor_off_p = w->cursor_off_p;
12329
12330 if (w == XWINDOW (selected_window))
12331 w->last_point = make_number (BUF_PT (b));
12332 else
12333 w->last_point = make_number (XMARKER (w->pointm)->charpos);
12334 }
12335 }
12336
12337 if (accurate_p)
12338 {
12339 w->window_end_valid = w->buffer;
12340 w->update_mode_line = Qnil;
12341 }
12342 }
12343
12344
12345 /* Mark the display of windows in the window tree rooted at WINDOW as
12346 accurate or inaccurate. If ACCURATE_P is non-zero mark display of
12347 windows as accurate. If ACCURATE_P is zero, arrange for windows to
12348 be redisplayed the next time redisplay_internal is called. */
12349
12350 void
12351 mark_window_display_accurate (Lisp_Object window, int accurate_p)
12352 {
12353 struct window *w;
12354
12355 for (; !NILP (window); window = w->next)
12356 {
12357 w = XWINDOW (window);
12358 mark_window_display_accurate_1 (w, accurate_p);
12359
12360 if (!NILP (w->vchild))
12361 mark_window_display_accurate (w->vchild, accurate_p);
12362 if (!NILP (w->hchild))
12363 mark_window_display_accurate (w->hchild, accurate_p);
12364 }
12365
12366 if (accurate_p)
12367 {
12368 update_overlay_arrows (1);
12369 }
12370 else
12371 {
12372 /* Force a thorough redisplay the next time by setting
12373 last_arrow_position and last_arrow_string to t, which is
12374 unequal to any useful value of Voverlay_arrow_... */
12375 update_overlay_arrows (-1);
12376 }
12377 }
12378
12379
12380 /* Return value in display table DP (Lisp_Char_Table *) for character
12381 C. Since a display table doesn't have any parent, we don't have to
12382 follow parent. Do not call this function directly but use the
12383 macro DISP_CHAR_VECTOR. */
12384
12385 Lisp_Object
12386 disp_char_vector (struct Lisp_Char_Table *dp, int c)
12387 {
12388 Lisp_Object val;
12389
12390 if (ASCII_CHAR_P (c))
12391 {
12392 val = dp->ascii;
12393 if (SUB_CHAR_TABLE_P (val))
12394 val = XSUB_CHAR_TABLE (val)->contents[c];
12395 }
12396 else
12397 {
12398 Lisp_Object table;
12399
12400 XSETCHAR_TABLE (table, dp);
12401 val = char_table_ref (table, c);
12402 }
12403 if (NILP (val))
12404 val = dp->defalt;
12405 return val;
12406 }
12407
12408
12409 \f
12410 /***********************************************************************
12411 Window Redisplay
12412 ***********************************************************************/
12413
12414 /* Redisplay all leaf windows in the window tree rooted at WINDOW. */
12415
12416 static void
12417 redisplay_windows (Lisp_Object window)
12418 {
12419 while (!NILP (window))
12420 {
12421 struct window *w = XWINDOW (window);
12422
12423 if (!NILP (w->hchild))
12424 redisplay_windows (w->hchild);
12425 else if (!NILP (w->vchild))
12426 redisplay_windows (w->vchild);
12427 else if (!NILP (w->buffer))
12428 {
12429 displayed_buffer = XBUFFER (w->buffer);
12430 /* Use list_of_error, not Qerror, so that
12431 we catch only errors and don't run the debugger. */
12432 internal_condition_case_1 (redisplay_window_0, window,
12433 list_of_error,
12434 redisplay_window_error);
12435 }
12436
12437 window = w->next;
12438 }
12439 }
12440
12441 static Lisp_Object
12442 redisplay_window_error (Lisp_Object ignore)
12443 {
12444 displayed_buffer->display_error_modiff = BUF_MODIFF (displayed_buffer);
12445 return Qnil;
12446 }
12447
12448 static Lisp_Object
12449 redisplay_window_0 (Lisp_Object window)
12450 {
12451 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
12452 redisplay_window (window, 0);
12453 return Qnil;
12454 }
12455
12456 static Lisp_Object
12457 redisplay_window_1 (Lisp_Object window)
12458 {
12459 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
12460 redisplay_window (window, 1);
12461 return Qnil;
12462 }
12463 \f
12464
12465 /* Increment GLYPH until it reaches END or CONDITION fails while
12466 adding (GLYPH)->pixel_width to X. */
12467
12468 #define SKIP_GLYPHS(glyph, end, x, condition) \
12469 do \
12470 { \
12471 (x) += (glyph)->pixel_width; \
12472 ++(glyph); \
12473 } \
12474 while ((glyph) < (end) && (condition))
12475
12476
12477 /* Set cursor position of W. PT is assumed to be displayed in ROW.
12478 DELTA and DELTA_BYTES are the numbers of characters and bytes by
12479 which positions recorded in ROW differ from current buffer
12480 positions.
12481
12482 Return 0 if cursor is not on this row, 1 otherwise. */
12483
12484 int
12485 set_cursor_from_row (struct window *w, struct glyph_row *row,
12486 struct glyph_matrix *matrix, int delta, int delta_bytes,
12487 int dy, int dvpos)
12488 {
12489 struct glyph *glyph = row->glyphs[TEXT_AREA];
12490 struct glyph *end = glyph + row->used[TEXT_AREA];
12491 struct glyph *cursor = NULL;
12492 /* The last known character position in row. */
12493 int last_pos = MATRIX_ROW_START_CHARPOS (row) + delta;
12494 int x = row->x;
12495 EMACS_INT pt_old = PT - delta;
12496 EMACS_INT pos_before = MATRIX_ROW_START_CHARPOS (row) + delta;
12497 EMACS_INT pos_after = MATRIX_ROW_END_CHARPOS (row) + delta;
12498 struct glyph *glyph_before = glyph - 1, *glyph_after = end;
12499 /* A glyph beyond the edge of TEXT_AREA which we should never
12500 touch. */
12501 struct glyph *glyphs_end = end;
12502 /* Non-zero means we've found a match for cursor position, but that
12503 glyph has the avoid_cursor_p flag set. */
12504 int match_with_avoid_cursor = 0;
12505 /* Non-zero means we've seen at least one glyph that came from a
12506 display string. */
12507 int string_seen = 0;
12508 /* Largest buffer position seen so far during scan of glyph row. */
12509 EMACS_INT bpos_max = last_pos;
12510 /* Last buffer position covered by an overlay string with an integer
12511 `cursor' property. */
12512 EMACS_INT bpos_covered = 0;
12513
12514 /* Skip over glyphs not having an object at the start and the end of
12515 the row. These are special glyphs like truncation marks on
12516 terminal frames. */
12517 if (row->displays_text_p)
12518 {
12519 if (!row->reversed_p)
12520 {
12521 while (glyph < end
12522 && INTEGERP (glyph->object)
12523 && glyph->charpos < 0)
12524 {
12525 x += glyph->pixel_width;
12526 ++glyph;
12527 }
12528 while (end > glyph
12529 && INTEGERP ((end - 1)->object)
12530 /* CHARPOS is zero for blanks and stretch glyphs
12531 inserted by extend_face_to_end_of_line. */
12532 && (end - 1)->charpos <= 0)
12533 --end;
12534 glyph_before = glyph - 1;
12535 glyph_after = end;
12536 }
12537 else
12538 {
12539 struct glyph *g;
12540
12541 /* If the glyph row is reversed, we need to process it from back
12542 to front, so swap the edge pointers. */
12543 glyphs_end = end = glyph - 1;
12544 glyph += row->used[TEXT_AREA] - 1;
12545
12546 while (glyph > end + 1
12547 && INTEGERP (glyph->object)
12548 && glyph->charpos < 0)
12549 {
12550 --glyph;
12551 x -= glyph->pixel_width;
12552 }
12553 if (INTEGERP (glyph->object) && glyph->charpos < 0)
12554 --glyph;
12555 /* By default, in reversed rows we put the cursor on the
12556 rightmost (first in the reading order) glyph. */
12557 for (g = end + 1; g < glyph; g++)
12558 x += g->pixel_width;
12559 while (end < glyph
12560 && INTEGERP ((end + 1)->object)
12561 && (end + 1)->charpos <= 0)
12562 ++end;
12563 glyph_before = glyph + 1;
12564 glyph_after = end;
12565 }
12566 }
12567 else if (row->reversed_p)
12568 {
12569 /* In R2L rows that don't display text, put the cursor on the
12570 rightmost glyph. Case in point: an empty last line that is
12571 part of an R2L paragraph. */
12572 cursor = end - 1;
12573 /* Avoid placing the cursor on the last glyph of the row, where
12574 on terminal frames we hold the vertical border between
12575 adjacent windows. */
12576 if (!FRAME_WINDOW_P (WINDOW_XFRAME (w))
12577 && !WINDOW_RIGHTMOST_P (w)
12578 && cursor == row->glyphs[LAST_AREA] - 1)
12579 cursor--;
12580 x = -1; /* will be computed below, at label compute_x */
12581 }
12582
12583 /* Step 1: Try to find the glyph whose character position
12584 corresponds to point. If that's not possible, find 2 glyphs
12585 whose character positions are the closest to point, one before
12586 point, the other after it. */
12587 if (!row->reversed_p)
12588 while (/* not marched to end of glyph row */
12589 glyph < end
12590 /* glyph was not inserted by redisplay for internal purposes */
12591 && !INTEGERP (glyph->object))
12592 {
12593 if (BUFFERP (glyph->object))
12594 {
12595 EMACS_INT dpos = glyph->charpos - pt_old;
12596
12597 if (glyph->charpos > bpos_max)
12598 bpos_max = glyph->charpos;
12599 if (!glyph->avoid_cursor_p)
12600 {
12601 /* If we hit point, we've found the glyph on which to
12602 display the cursor. */
12603 if (dpos == 0)
12604 {
12605 match_with_avoid_cursor = 0;
12606 break;
12607 }
12608 /* See if we've found a better approximation to
12609 POS_BEFORE or to POS_AFTER. Note that we want the
12610 first (leftmost) glyph of all those that are the
12611 closest from below, and the last (rightmost) of all
12612 those from above. */
12613 if (0 > dpos && dpos > pos_before - pt_old)
12614 {
12615 pos_before = glyph->charpos;
12616 glyph_before = glyph;
12617 }
12618 else if (0 < dpos && dpos <= pos_after - pt_old)
12619 {
12620 pos_after = glyph->charpos;
12621 glyph_after = glyph;
12622 }
12623 }
12624 else if (dpos == 0)
12625 match_with_avoid_cursor = 1;
12626 }
12627 else if (STRINGP (glyph->object))
12628 {
12629 Lisp_Object chprop;
12630 int glyph_pos = glyph->charpos;
12631
12632 chprop = Fget_char_property (make_number (glyph_pos), Qcursor,
12633 glyph->object);
12634 if (INTEGERP (chprop))
12635 {
12636 bpos_covered = bpos_max + XINT (chprop);
12637 /* If the `cursor' property covers buffer positions up
12638 to and including point, we should display cursor on
12639 this glyph. Note that overlays and text properties
12640 with string values stop bidi reordering, so every
12641 buffer position to the left of the string is always
12642 smaller than any position to the right of the
12643 string. Therefore, if a `cursor' property on one
12644 of the string's characters has an integer value, we
12645 will break out of the loop below _before_ we get to
12646 the position match above. IOW, integer values of
12647 the `cursor' property override the "exact match for
12648 point" strategy of positioning the cursor. */
12649 /* Implementation note: bpos_max == pt_old when, e.g.,
12650 we are in an empty line, where bpos_max is set to
12651 MATRIX_ROW_START_CHARPOS, see above. */
12652 if (bpos_max <= pt_old && bpos_covered >= pt_old)
12653 {
12654 cursor = glyph;
12655 break;
12656 }
12657 }
12658
12659 string_seen = 1;
12660 }
12661 x += glyph->pixel_width;
12662 ++glyph;
12663 }
12664 else if (glyph > end) /* row is reversed */
12665 while (!INTEGERP (glyph->object))
12666 {
12667 if (BUFFERP (glyph->object))
12668 {
12669 EMACS_INT dpos = glyph->charpos - pt_old;
12670
12671 if (glyph->charpos > bpos_max)
12672 bpos_max = glyph->charpos;
12673 if (!glyph->avoid_cursor_p)
12674 {
12675 if (dpos == 0)
12676 {
12677 match_with_avoid_cursor = 0;
12678 break;
12679 }
12680 if (0 > dpos && dpos > pos_before - pt_old)
12681 {
12682 pos_before = glyph->charpos;
12683 glyph_before = glyph;
12684 }
12685 else if (0 < dpos && dpos <= pos_after - pt_old)
12686 {
12687 pos_after = glyph->charpos;
12688 glyph_after = glyph;
12689 }
12690 }
12691 else if (dpos == 0)
12692 match_with_avoid_cursor = 1;
12693 }
12694 else if (STRINGP (glyph->object))
12695 {
12696 Lisp_Object chprop;
12697 int glyph_pos = glyph->charpos;
12698
12699 chprop = Fget_char_property (make_number (glyph_pos), Qcursor,
12700 glyph->object);
12701 if (INTEGERP (chprop))
12702 {
12703 bpos_covered = bpos_max + XINT (chprop);
12704 /* If the `cursor' property covers buffer positions up
12705 to and including point, we should display cursor on
12706 this glyph. */
12707 if (bpos_max <= pt_old && bpos_covered >= pt_old)
12708 {
12709 cursor = glyph;
12710 break;
12711 }
12712 }
12713 string_seen = 1;
12714 }
12715 --glyph;
12716 if (glyph == glyphs_end) /* don't dereference outside TEXT_AREA */
12717 {
12718 x--; /* can't use any pixel_width */
12719 break;
12720 }
12721 x -= glyph->pixel_width;
12722 }
12723
12724 /* Step 2: If we didn't find an exact match for point, we need to
12725 look for a proper place to put the cursor among glyphs between
12726 GLYPH_BEFORE and GLYPH_AFTER. */
12727 if (!((row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end)
12728 && BUFFERP (glyph->object) && glyph->charpos == pt_old)
12729 && bpos_covered < pt_old)
12730 {
12731 if (row->ends_in_ellipsis_p && pos_after == last_pos)
12732 {
12733 EMACS_INT ellipsis_pos;
12734
12735 /* Scan back over the ellipsis glyphs. */
12736 if (!row->reversed_p)
12737 {
12738 ellipsis_pos = (glyph - 1)->charpos;
12739 while (glyph > row->glyphs[TEXT_AREA]
12740 && (glyph - 1)->charpos == ellipsis_pos)
12741 glyph--, x -= glyph->pixel_width;
12742 /* That loop always goes one position too far, including
12743 the glyph before the ellipsis. So scan forward over
12744 that one. */
12745 x += glyph->pixel_width;
12746 glyph++;
12747 }
12748 else /* row is reversed */
12749 {
12750 ellipsis_pos = (glyph + 1)->charpos;
12751 while (glyph < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1
12752 && (glyph + 1)->charpos == ellipsis_pos)
12753 glyph++, x += glyph->pixel_width;
12754 x -= glyph->pixel_width;
12755 glyph--;
12756 }
12757 }
12758 else if (match_with_avoid_cursor
12759 /* zero-width characters produce no glyphs */
12760 || ((row->reversed_p
12761 ? glyph_after > glyphs_end
12762 : glyph_after < glyphs_end)
12763 && eabs (glyph_after - glyph_before) == 1))
12764 {
12765 cursor = glyph_after;
12766 x = -1;
12767 }
12768 else if (string_seen)
12769 {
12770 int incr = row->reversed_p ? -1 : +1;
12771
12772 /* Need to find the glyph that came out of a string which is
12773 present at point. That glyph is somewhere between
12774 GLYPH_BEFORE and GLYPH_AFTER, and it came from a string
12775 positioned between POS_BEFORE and POS_AFTER in the
12776 buffer. */
12777 struct glyph *stop = glyph_after;
12778 EMACS_INT pos = pos_before;
12779
12780 x = -1;
12781 for (glyph = glyph_before + incr;
12782 row->reversed_p ? glyph > stop : glyph < stop; )
12783 {
12784
12785 /* Any glyphs that come from the buffer are here because
12786 of bidi reordering. Skip them, and only pay
12787 attention to glyphs that came from some string. */
12788 if (STRINGP (glyph->object))
12789 {
12790 Lisp_Object str;
12791 EMACS_INT tem;
12792
12793 str = glyph->object;
12794 tem = string_buffer_position_lim (w, str, pos, pos_after, 0);
12795 if (tem == 0 /* from overlay */
12796 || pos <= tem)
12797 {
12798 /* If the string from which this glyph came is
12799 found in the buffer at point, then we've
12800 found the glyph we've been looking for. If
12801 it comes from an overlay (tem == 0), and it
12802 has the `cursor' property on one of its
12803 glyphs, record that glyph as a candidate for
12804 displaying the cursor. (As in the
12805 unidirectional version, we will display the
12806 cursor on the last candidate we find.) */
12807 if (tem == 0 || tem == pt_old)
12808 {
12809 /* The glyphs from this string could have
12810 been reordered. Find the one with the
12811 smallest string position. Or there could
12812 be a character in the string with the
12813 `cursor' property, which means display
12814 cursor on that character's glyph. */
12815 int strpos = glyph->charpos;
12816
12817 cursor = glyph;
12818 for (glyph += incr;
12819 (row->reversed_p ? glyph > stop : glyph < stop)
12820 && EQ (glyph->object, str);
12821 glyph += incr)
12822 {
12823 Lisp_Object cprop;
12824 int gpos = glyph->charpos;
12825
12826 cprop = Fget_char_property (make_number (gpos),
12827 Qcursor,
12828 glyph->object);
12829 if (!NILP (cprop))
12830 {
12831 cursor = glyph;
12832 break;
12833 }
12834 if (glyph->charpos < strpos)
12835 {
12836 strpos = glyph->charpos;
12837 cursor = glyph;
12838 }
12839 }
12840
12841 if (tem == pt_old)
12842 goto compute_x;
12843 }
12844 if (tem)
12845 pos = tem + 1; /* don't find previous instances */
12846 }
12847 /* This string is not what we want; skip all of the
12848 glyphs that came from it. */
12849 do
12850 glyph += incr;
12851 while ((row->reversed_p ? glyph > stop : glyph < stop)
12852 && EQ (glyph->object, str));
12853 }
12854 else
12855 glyph += incr;
12856 }
12857
12858 /* If we reached the end of the line, and END was from a string,
12859 the cursor is not on this line. */
12860 if (cursor == NULL
12861 && (row->reversed_p ? glyph <= end : glyph >= end)
12862 && STRINGP (end->object)
12863 && row->continued_p)
12864 return 0;
12865 }
12866 }
12867
12868 compute_x:
12869 if (cursor != NULL)
12870 glyph = cursor;
12871 if (x < 0)
12872 {
12873 struct glyph *g;
12874
12875 /* Need to compute x that corresponds to GLYPH. */
12876 for (g = row->glyphs[TEXT_AREA], x = row->x; g < glyph; g++)
12877 {
12878 if (g >= row->glyphs[TEXT_AREA] + row->used[TEXT_AREA])
12879 abort ();
12880 x += g->pixel_width;
12881 }
12882 }
12883
12884 /* ROW could be part of a continued line, which, under bidi
12885 reordering, might have other rows whose start and end charpos
12886 occlude point. Only set w->cursor if we found a better
12887 approximation to the cursor position than we have from previously
12888 examined candidate rows belonging to the same continued line. */
12889 if (/* we already have a candidate row */
12890 w->cursor.vpos >= 0
12891 /* that candidate is not the row we are processing */
12892 && MATRIX_ROW (matrix, w->cursor.vpos) != row
12893 /* the row we are processing is part of a continued line */
12894 && (row->continued_p || MATRIX_ROW_CONTINUATION_LINE_P (row))
12895 /* Make sure cursor.vpos specifies a row whose start and end
12896 charpos occlude point. This is because some callers of this
12897 function leave cursor.vpos at the row where the cursor was
12898 displayed during the last redisplay cycle. */
12899 && MATRIX_ROW_START_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos)) <= pt_old
12900 && pt_old < MATRIX_ROW_END_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos)))
12901 {
12902 struct glyph *g1 =
12903 MATRIX_ROW_GLYPH_START (matrix, w->cursor.vpos) + w->cursor.hpos;
12904
12905 /* Don't consider glyphs that are outside TEXT_AREA. */
12906 if (!(row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end))
12907 return 0;
12908 /* Keep the candidate whose buffer position is the closest to
12909 point. */
12910 if (/* previous candidate is a glyph in TEXT_AREA of that row */
12911 w->cursor.hpos >= 0
12912 && w->cursor.hpos < MATRIX_ROW_USED (matrix, w->cursor.vpos)
12913 && BUFFERP (g1->object)
12914 && (g1->charpos == pt_old /* an exact match always wins */
12915 || (BUFFERP (glyph->object)
12916 && eabs (g1->charpos - pt_old)
12917 < eabs (glyph->charpos - pt_old))))
12918 return 0;
12919 /* If this candidate gives an exact match, use that. */
12920 if (!(BUFFERP (glyph->object) && glyph->charpos == pt_old)
12921 /* Otherwise, keep the candidate that comes from a row
12922 spanning less buffer positions. This may win when one or
12923 both candidate positions are on glyphs that came from
12924 display strings, for which we cannot compare buffer
12925 positions. */
12926 && MATRIX_ROW_END_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))
12927 - MATRIX_ROW_START_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))
12928 < MATRIX_ROW_END_CHARPOS (row) - MATRIX_ROW_START_CHARPOS (row))
12929 return 0;
12930 }
12931 w->cursor.hpos = glyph - row->glyphs[TEXT_AREA];
12932 w->cursor.x = x;
12933 w->cursor.vpos = MATRIX_ROW_VPOS (row, matrix) + dvpos;
12934 w->cursor.y = row->y + dy;
12935
12936 if (w == XWINDOW (selected_window))
12937 {
12938 if (!row->continued_p
12939 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
12940 && row->x == 0)
12941 {
12942 this_line_buffer = XBUFFER (w->buffer);
12943
12944 CHARPOS (this_line_start_pos)
12945 = MATRIX_ROW_START_CHARPOS (row) + delta;
12946 BYTEPOS (this_line_start_pos)
12947 = MATRIX_ROW_START_BYTEPOS (row) + delta_bytes;
12948
12949 CHARPOS (this_line_end_pos)
12950 = Z - (MATRIX_ROW_END_CHARPOS (row) + delta);
12951 BYTEPOS (this_line_end_pos)
12952 = Z_BYTE - (MATRIX_ROW_END_BYTEPOS (row) + delta_bytes);
12953
12954 this_line_y = w->cursor.y;
12955 this_line_pixel_height = row->height;
12956 this_line_vpos = w->cursor.vpos;
12957 this_line_start_x = row->x;
12958 }
12959 else
12960 CHARPOS (this_line_start_pos) = 0;
12961 }
12962
12963 return 1;
12964 }
12965
12966
12967 /* Run window scroll functions, if any, for WINDOW with new window
12968 start STARTP. Sets the window start of WINDOW to that position.
12969
12970 We assume that the window's buffer is really current. */
12971
12972 static INLINE struct text_pos
12973 run_window_scroll_functions (Lisp_Object window, struct text_pos startp)
12974 {
12975 struct window *w = XWINDOW (window);
12976 SET_MARKER_FROM_TEXT_POS (w->start, startp);
12977
12978 if (current_buffer != XBUFFER (w->buffer))
12979 abort ();
12980
12981 if (!NILP (Vwindow_scroll_functions))
12982 {
12983 run_hook_with_args_2 (Qwindow_scroll_functions, window,
12984 make_number (CHARPOS (startp)));
12985 SET_TEXT_POS_FROM_MARKER (startp, w->start);
12986 /* In case the hook functions switch buffers. */
12987 if (current_buffer != XBUFFER (w->buffer))
12988 set_buffer_internal_1 (XBUFFER (w->buffer));
12989 }
12990
12991 return startp;
12992 }
12993
12994
12995 /* Make sure the line containing the cursor is fully visible.
12996 A value of 1 means there is nothing to be done.
12997 (Either the line is fully visible, or it cannot be made so,
12998 or we cannot tell.)
12999
13000 If FORCE_P is non-zero, return 0 even if partial visible cursor row
13001 is higher than window.
13002
13003 A value of 0 means the caller should do scrolling
13004 as if point had gone off the screen. */
13005
13006 static int
13007 cursor_row_fully_visible_p (struct window *w, int force_p, int current_matrix_p)
13008 {
13009 struct glyph_matrix *matrix;
13010 struct glyph_row *row;
13011 int window_height;
13012
13013 if (!make_cursor_line_fully_visible_p)
13014 return 1;
13015
13016 /* It's not always possible to find the cursor, e.g, when a window
13017 is full of overlay strings. Don't do anything in that case. */
13018 if (w->cursor.vpos < 0)
13019 return 1;
13020
13021 matrix = current_matrix_p ? w->current_matrix : w->desired_matrix;
13022 row = MATRIX_ROW (matrix, w->cursor.vpos);
13023
13024 /* If the cursor row is not partially visible, there's nothing to do. */
13025 if (!MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row))
13026 return 1;
13027
13028 /* If the row the cursor is in is taller than the window's height,
13029 it's not clear what to do, so do nothing. */
13030 window_height = window_box_height (w);
13031 if (row->height >= window_height)
13032 {
13033 if (!force_p || MINI_WINDOW_P (w)
13034 || w->vscroll || w->cursor.vpos == 0)
13035 return 1;
13036 }
13037 return 0;
13038 }
13039
13040
13041 /* Try scrolling PT into view in window WINDOW. JUST_THIS_ONE_P
13042 non-zero means only WINDOW is redisplayed in redisplay_internal.
13043 TEMP_SCROLL_STEP has the same meaning as scroll_step, and is used
13044 in redisplay_window to bring a partially visible line into view in
13045 the case that only the cursor has moved.
13046
13047 LAST_LINE_MISFIT should be nonzero if we're scrolling because the
13048 last screen line's vertical height extends past the end of the screen.
13049
13050 Value is
13051
13052 1 if scrolling succeeded
13053
13054 0 if scrolling didn't find point.
13055
13056 -1 if new fonts have been loaded so that we must interrupt
13057 redisplay, adjust glyph matrices, and try again. */
13058
13059 enum
13060 {
13061 SCROLLING_SUCCESS,
13062 SCROLLING_FAILED,
13063 SCROLLING_NEED_LARGER_MATRICES
13064 };
13065
13066 static int
13067 try_scrolling (Lisp_Object window, int just_this_one_p,
13068 EMACS_INT scroll_conservatively, EMACS_INT scroll_step,
13069 int temp_scroll_step, int last_line_misfit)
13070 {
13071 struct window *w = XWINDOW (window);
13072 struct frame *f = XFRAME (w->frame);
13073 struct text_pos pos, startp;
13074 struct it it;
13075 int this_scroll_margin, scroll_max, rc, height;
13076 int dy = 0, amount_to_scroll = 0, scroll_down_p = 0;
13077 int extra_scroll_margin_lines = last_line_misfit ? 1 : 0;
13078 Lisp_Object aggressive;
13079 int scroll_limit = INT_MAX / FRAME_LINE_HEIGHT (f);
13080
13081 #if GLYPH_DEBUG
13082 debug_method_add (w, "try_scrolling");
13083 #endif
13084
13085 SET_TEXT_POS_FROM_MARKER (startp, w->start);
13086
13087 /* Compute scroll margin height in pixels. We scroll when point is
13088 within this distance from the top or bottom of the window. */
13089 if (scroll_margin > 0)
13090 this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4)
13091 * FRAME_LINE_HEIGHT (f);
13092 else
13093 this_scroll_margin = 0;
13094
13095 /* Force scroll_conservatively to have a reasonable value, to avoid
13096 overflow while computing how much to scroll. Note that the user
13097 can supply scroll-conservatively equal to `most-positive-fixnum',
13098 which can be larger than INT_MAX. */
13099 if (scroll_conservatively > scroll_limit)
13100 {
13101 scroll_conservatively = scroll_limit;
13102 scroll_max = INT_MAX;
13103 }
13104 else if (scroll_step || scroll_conservatively || temp_scroll_step)
13105 /* Compute how much we should try to scroll maximally to bring
13106 point into view. */
13107 scroll_max = (max (scroll_step,
13108 max (scroll_conservatively, temp_scroll_step))
13109 * FRAME_LINE_HEIGHT (f));
13110 else if (NUMBERP (current_buffer->scroll_down_aggressively)
13111 || NUMBERP (current_buffer->scroll_up_aggressively))
13112 /* We're trying to scroll because of aggressive scrolling but no
13113 scroll_step is set. Choose an arbitrary one. */
13114 scroll_max = 10 * FRAME_LINE_HEIGHT (f);
13115 else
13116 scroll_max = 0;
13117
13118 too_near_end:
13119
13120 /* Decide whether to scroll down. */
13121 if (PT > CHARPOS (startp))
13122 {
13123 int scroll_margin_y;
13124
13125 /* Compute the pixel ypos of the scroll margin, then move it to
13126 either that ypos or PT, whichever comes first. */
13127 start_display (&it, w, startp);
13128 scroll_margin_y = it.last_visible_y - this_scroll_margin
13129 - FRAME_LINE_HEIGHT (f) * extra_scroll_margin_lines;
13130 move_it_to (&it, PT, -1, scroll_margin_y - 1, -1,
13131 (MOVE_TO_POS | MOVE_TO_Y));
13132
13133 if (PT > CHARPOS (it.current.pos))
13134 {
13135 int y0 = line_bottom_y (&it);
13136 /* Compute how many pixels below window bottom to stop searching
13137 for PT. This avoids costly search for PT that is far away if
13138 the user limited scrolling by a small number of lines, but
13139 always finds PT if scroll_conservatively is set to a large
13140 number, such as most-positive-fixnum. */
13141 int slack = max (scroll_max, 10 * FRAME_LINE_HEIGHT (f));
13142 int y_to_move =
13143 slack >= INT_MAX - it.last_visible_y
13144 ? INT_MAX
13145 : it.last_visible_y + slack;
13146
13147 /* Compute the distance from the scroll margin to PT or to
13148 the scroll limit, whichever comes first. This should
13149 include the height of the cursor line, to make that line
13150 fully visible. */
13151 move_it_to (&it, PT, -1, y_to_move,
13152 -1, MOVE_TO_POS | MOVE_TO_Y);
13153 dy = line_bottom_y (&it) - y0;
13154
13155 if (dy > scroll_max)
13156 return SCROLLING_FAILED;
13157
13158 scroll_down_p = 1;
13159 }
13160 }
13161
13162 if (scroll_down_p)
13163 {
13164 /* Point is in or below the bottom scroll margin, so move the
13165 window start down. If scrolling conservatively, move it just
13166 enough down to make point visible. If scroll_step is set,
13167 move it down by scroll_step. */
13168 if (scroll_conservatively)
13169 amount_to_scroll
13170 = min (max (dy, FRAME_LINE_HEIGHT (f)),
13171 FRAME_LINE_HEIGHT (f) * scroll_conservatively);
13172 else if (scroll_step || temp_scroll_step)
13173 amount_to_scroll = scroll_max;
13174 else
13175 {
13176 aggressive = current_buffer->scroll_up_aggressively;
13177 height = WINDOW_BOX_TEXT_HEIGHT (w);
13178 if (NUMBERP (aggressive))
13179 {
13180 double float_amount = XFLOATINT (aggressive) * height;
13181 amount_to_scroll = float_amount;
13182 if (amount_to_scroll == 0 && float_amount > 0)
13183 amount_to_scroll = 1;
13184 }
13185 }
13186
13187 if (amount_to_scroll <= 0)
13188 return SCROLLING_FAILED;
13189
13190 start_display (&it, w, startp);
13191 if (scroll_max < INT_MAX)
13192 move_it_vertically (&it, amount_to_scroll);
13193 else
13194 {
13195 /* Extra precision for users who set scroll-conservatively
13196 to most-positive-fixnum: make sure the amount we scroll
13197 the window start is never less than amount_to_scroll,
13198 which was computed as distance from window bottom to
13199 point. This matters when lines at window top and lines
13200 below window bottom have different height. */
13201 struct it it1 = it;
13202 /* We use a temporary it1 because line_bottom_y can modify
13203 its argument, if it moves one line down; see there. */
13204 int start_y = line_bottom_y (&it1);
13205
13206 do {
13207 move_it_by_lines (&it, 1, 1);
13208 it1 = it;
13209 } while (line_bottom_y (&it1) - start_y < amount_to_scroll);
13210 }
13211
13212 /* If STARTP is unchanged, move it down another screen line. */
13213 if (CHARPOS (it.current.pos) == CHARPOS (startp))
13214 move_it_by_lines (&it, 1, 1);
13215 startp = it.current.pos;
13216 }
13217 else
13218 {
13219 struct text_pos scroll_margin_pos = startp;
13220
13221 /* See if point is inside the scroll margin at the top of the
13222 window. */
13223 if (this_scroll_margin)
13224 {
13225 start_display (&it, w, startp);
13226 move_it_vertically (&it, this_scroll_margin);
13227 scroll_margin_pos = it.current.pos;
13228 }
13229
13230 if (PT < CHARPOS (scroll_margin_pos))
13231 {
13232 /* Point is in the scroll margin at the top of the window or
13233 above what is displayed in the window. */
13234 int y0;
13235
13236 /* Compute the vertical distance from PT to the scroll
13237 margin position. Give up if distance is greater than
13238 scroll_max. */
13239 SET_TEXT_POS (pos, PT, PT_BYTE);
13240 start_display (&it, w, pos);
13241 y0 = it.current_y;
13242 move_it_to (&it, CHARPOS (scroll_margin_pos), 0,
13243 it.last_visible_y, -1,
13244 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
13245 dy = it.current_y - y0;
13246 if (dy > scroll_max)
13247 return SCROLLING_FAILED;
13248
13249 /* Compute new window start. */
13250 start_display (&it, w, startp);
13251
13252 if (scroll_conservatively)
13253 amount_to_scroll
13254 = max (dy, FRAME_LINE_HEIGHT (f) * max (scroll_step, temp_scroll_step));
13255 else if (scroll_step || temp_scroll_step)
13256 amount_to_scroll = scroll_max;
13257 else
13258 {
13259 aggressive = current_buffer->scroll_down_aggressively;
13260 height = WINDOW_BOX_TEXT_HEIGHT (w);
13261 if (NUMBERP (aggressive))
13262 {
13263 double float_amount = XFLOATINT (aggressive) * height;
13264 amount_to_scroll = float_amount;
13265 if (amount_to_scroll == 0 && float_amount > 0)
13266 amount_to_scroll = 1;
13267 }
13268 }
13269
13270 if (amount_to_scroll <= 0)
13271 return SCROLLING_FAILED;
13272
13273 move_it_vertically_backward (&it, amount_to_scroll);
13274 startp = it.current.pos;
13275 }
13276 }
13277
13278 /* Run window scroll functions. */
13279 startp = run_window_scroll_functions (window, startp);
13280
13281 /* Display the window. Give up if new fonts are loaded, or if point
13282 doesn't appear. */
13283 if (!try_window (window, startp, 0))
13284 rc = SCROLLING_NEED_LARGER_MATRICES;
13285 else if (w->cursor.vpos < 0)
13286 {
13287 clear_glyph_matrix (w->desired_matrix);
13288 rc = SCROLLING_FAILED;
13289 }
13290 else
13291 {
13292 /* Maybe forget recorded base line for line number display. */
13293 if (!just_this_one_p
13294 || current_buffer->clip_changed
13295 || BEG_UNCHANGED < CHARPOS (startp))
13296 w->base_line_number = Qnil;
13297
13298 /* If cursor ends up on a partially visible line,
13299 treat that as being off the bottom of the screen. */
13300 if (! cursor_row_fully_visible_p (w, extra_scroll_margin_lines <= 1, 0))
13301 {
13302 clear_glyph_matrix (w->desired_matrix);
13303 ++extra_scroll_margin_lines;
13304 goto too_near_end;
13305 }
13306 rc = SCROLLING_SUCCESS;
13307 }
13308
13309 return rc;
13310 }
13311
13312
13313 /* Compute a suitable window start for window W if display of W starts
13314 on a continuation line. Value is non-zero if a new window start
13315 was computed.
13316
13317 The new window start will be computed, based on W's width, starting
13318 from the start of the continued line. It is the start of the
13319 screen line with the minimum distance from the old start W->start. */
13320
13321 static int
13322 compute_window_start_on_continuation_line (struct window *w)
13323 {
13324 struct text_pos pos, start_pos;
13325 int window_start_changed_p = 0;
13326
13327 SET_TEXT_POS_FROM_MARKER (start_pos, w->start);
13328
13329 /* If window start is on a continuation line... Window start may be
13330 < BEGV in case there's invisible text at the start of the
13331 buffer (M-x rmail, for example). */
13332 if (CHARPOS (start_pos) > BEGV
13333 && FETCH_BYTE (BYTEPOS (start_pos) - 1) != '\n')
13334 {
13335 struct it it;
13336 struct glyph_row *row;
13337
13338 /* Handle the case that the window start is out of range. */
13339 if (CHARPOS (start_pos) < BEGV)
13340 SET_TEXT_POS (start_pos, BEGV, BEGV_BYTE);
13341 else if (CHARPOS (start_pos) > ZV)
13342 SET_TEXT_POS (start_pos, ZV, ZV_BYTE);
13343
13344 /* Find the start of the continued line. This should be fast
13345 because scan_buffer is fast (newline cache). */
13346 row = w->desired_matrix->rows + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0);
13347 init_iterator (&it, w, CHARPOS (start_pos), BYTEPOS (start_pos),
13348 row, DEFAULT_FACE_ID);
13349 reseat_at_previous_visible_line_start (&it);
13350
13351 /* If the line start is "too far" away from the window start,
13352 say it takes too much time to compute a new window start. */
13353 if (CHARPOS (start_pos) - IT_CHARPOS (it)
13354 < WINDOW_TOTAL_LINES (w) * WINDOW_TOTAL_COLS (w))
13355 {
13356 int min_distance, distance;
13357
13358 /* Move forward by display lines to find the new window
13359 start. If window width was enlarged, the new start can
13360 be expected to be > the old start. If window width was
13361 decreased, the new window start will be < the old start.
13362 So, we're looking for the display line start with the
13363 minimum distance from the old window start. */
13364 pos = it.current.pos;
13365 min_distance = INFINITY;
13366 while ((distance = eabs (CHARPOS (start_pos) - IT_CHARPOS (it))),
13367 distance < min_distance)
13368 {
13369 min_distance = distance;
13370 pos = it.current.pos;
13371 move_it_by_lines (&it, 1, 0);
13372 }
13373
13374 /* Set the window start there. */
13375 SET_MARKER_FROM_TEXT_POS (w->start, pos);
13376 window_start_changed_p = 1;
13377 }
13378 }
13379
13380 return window_start_changed_p;
13381 }
13382
13383
13384 /* Try cursor movement in case text has not changed in window WINDOW,
13385 with window start STARTP. Value is
13386
13387 CURSOR_MOVEMENT_SUCCESS if successful
13388
13389 CURSOR_MOVEMENT_CANNOT_BE_USED if this method cannot be used
13390
13391 CURSOR_MOVEMENT_MUST_SCROLL if we know we have to scroll the
13392 display. *SCROLL_STEP is set to 1, under certain circumstances, if
13393 we want to scroll as if scroll-step were set to 1. See the code.
13394
13395 CURSOR_MOVEMENT_NEED_LARGER_MATRICES if we need larger matrices, in
13396 which case we have to abort this redisplay, and adjust matrices
13397 first. */
13398
13399 enum
13400 {
13401 CURSOR_MOVEMENT_SUCCESS,
13402 CURSOR_MOVEMENT_CANNOT_BE_USED,
13403 CURSOR_MOVEMENT_MUST_SCROLL,
13404 CURSOR_MOVEMENT_NEED_LARGER_MATRICES
13405 };
13406
13407 static int
13408 try_cursor_movement (Lisp_Object window, struct text_pos startp, int *scroll_step)
13409 {
13410 struct window *w = XWINDOW (window);
13411 struct frame *f = XFRAME (w->frame);
13412 int rc = CURSOR_MOVEMENT_CANNOT_BE_USED;
13413
13414 #if GLYPH_DEBUG
13415 if (inhibit_try_cursor_movement)
13416 return rc;
13417 #endif
13418
13419 /* Handle case where text has not changed, only point, and it has
13420 not moved off the frame. */
13421 if (/* Point may be in this window. */
13422 PT >= CHARPOS (startp)
13423 /* Selective display hasn't changed. */
13424 && !current_buffer->clip_changed
13425 /* Function force-mode-line-update is used to force a thorough
13426 redisplay. It sets either windows_or_buffers_changed or
13427 update_mode_lines. So don't take a shortcut here for these
13428 cases. */
13429 && !update_mode_lines
13430 && !windows_or_buffers_changed
13431 && !cursor_type_changed
13432 /* Can't use this case if highlighting a region. When a
13433 region exists, cursor movement has to do more than just
13434 set the cursor. */
13435 && !(!NILP (Vtransient_mark_mode)
13436 && !NILP (current_buffer->mark_active))
13437 && NILP (w->region_showing)
13438 && NILP (Vshow_trailing_whitespace)
13439 /* Right after splitting windows, last_point may be nil. */
13440 && INTEGERP (w->last_point)
13441 /* This code is not used for mini-buffer for the sake of the case
13442 of redisplaying to replace an echo area message; since in
13443 that case the mini-buffer contents per se are usually
13444 unchanged. This code is of no real use in the mini-buffer
13445 since the handling of this_line_start_pos, etc., in redisplay
13446 handles the same cases. */
13447 && !EQ (window, minibuf_window)
13448 /* When splitting windows or for new windows, it happens that
13449 redisplay is called with a nil window_end_vpos or one being
13450 larger than the window. This should really be fixed in
13451 window.c. I don't have this on my list, now, so we do
13452 approximately the same as the old redisplay code. --gerd. */
13453 && INTEGERP (w->window_end_vpos)
13454 && XFASTINT (w->window_end_vpos) < w->current_matrix->nrows
13455 && (FRAME_WINDOW_P (f)
13456 || !overlay_arrow_in_current_buffer_p ()))
13457 {
13458 int this_scroll_margin, top_scroll_margin;
13459 struct glyph_row *row = NULL;
13460
13461 #if GLYPH_DEBUG
13462 debug_method_add (w, "cursor movement");
13463 #endif
13464
13465 /* Scroll if point within this distance from the top or bottom
13466 of the window. This is a pixel value. */
13467 if (scroll_margin > 0)
13468 {
13469 this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
13470 this_scroll_margin *= FRAME_LINE_HEIGHT (f);
13471 }
13472 else
13473 this_scroll_margin = 0;
13474
13475 top_scroll_margin = this_scroll_margin;
13476 if (WINDOW_WANTS_HEADER_LINE_P (w))
13477 top_scroll_margin += CURRENT_HEADER_LINE_HEIGHT (w);
13478
13479 /* Start with the row the cursor was displayed during the last
13480 not paused redisplay. Give up if that row is not valid. */
13481 if (w->last_cursor.vpos < 0
13482 || w->last_cursor.vpos >= w->current_matrix->nrows)
13483 rc = CURSOR_MOVEMENT_MUST_SCROLL;
13484 else
13485 {
13486 row = MATRIX_ROW (w->current_matrix, w->last_cursor.vpos);
13487 if (row->mode_line_p)
13488 ++row;
13489 if (!row->enabled_p)
13490 rc = CURSOR_MOVEMENT_MUST_SCROLL;
13491 }
13492
13493 if (rc == CURSOR_MOVEMENT_CANNOT_BE_USED)
13494 {
13495 int scroll_p = 0, must_scroll = 0;
13496 int last_y = window_text_bottom_y (w) - this_scroll_margin;
13497
13498 if (PT > XFASTINT (w->last_point))
13499 {
13500 /* Point has moved forward. */
13501 while (MATRIX_ROW_END_CHARPOS (row) < PT
13502 && MATRIX_ROW_BOTTOM_Y (row) < last_y)
13503 {
13504 xassert (row->enabled_p);
13505 ++row;
13506 }
13507
13508 /* If the end position of a row equals the start
13509 position of the next row, and PT is at that position,
13510 we would rather display cursor in the next line. */
13511 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
13512 && MATRIX_ROW_END_CHARPOS (row) == PT
13513 && row < w->current_matrix->rows
13514 + w->current_matrix->nrows - 1
13515 && MATRIX_ROW_START_CHARPOS (row+1) == PT
13516 && !cursor_row_p (w, row))
13517 ++row;
13518
13519 /* If within the scroll margin, scroll. Note that
13520 MATRIX_ROW_BOTTOM_Y gives the pixel position at which
13521 the next line would be drawn, and that
13522 this_scroll_margin can be zero. */
13523 if (MATRIX_ROW_BOTTOM_Y (row) > last_y
13524 || PT > MATRIX_ROW_END_CHARPOS (row)
13525 /* Line is completely visible last line in window
13526 and PT is to be set in the next line. */
13527 || (MATRIX_ROW_BOTTOM_Y (row) == last_y
13528 && PT == MATRIX_ROW_END_CHARPOS (row)
13529 && !row->ends_at_zv_p
13530 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
13531 scroll_p = 1;
13532 }
13533 else if (PT < XFASTINT (w->last_point))
13534 {
13535 /* Cursor has to be moved backward. Note that PT >=
13536 CHARPOS (startp) because of the outer if-statement. */
13537 while (!row->mode_line_p
13538 && (MATRIX_ROW_START_CHARPOS (row) > PT
13539 || (MATRIX_ROW_START_CHARPOS (row) == PT
13540 && (MATRIX_ROW_STARTS_IN_MIDDLE_OF_CHAR_P (row)
13541 || (/* STARTS_IN_MIDDLE_OF_STRING_P (row) */
13542 row > w->current_matrix->rows
13543 && (row-1)->ends_in_newline_from_string_p))))
13544 && (row->y > top_scroll_margin
13545 || CHARPOS (startp) == BEGV))
13546 {
13547 xassert (row->enabled_p);
13548 --row;
13549 }
13550
13551 /* Consider the following case: Window starts at BEGV,
13552 there is invisible, intangible text at BEGV, so that
13553 display starts at some point START > BEGV. It can
13554 happen that we are called with PT somewhere between
13555 BEGV and START. Try to handle that case. */
13556 if (row < w->current_matrix->rows
13557 || row->mode_line_p)
13558 {
13559 row = w->current_matrix->rows;
13560 if (row->mode_line_p)
13561 ++row;
13562 }
13563
13564 /* Due to newlines in overlay strings, we may have to
13565 skip forward over overlay strings. */
13566 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
13567 && MATRIX_ROW_END_CHARPOS (row) == PT
13568 && !cursor_row_p (w, row))
13569 ++row;
13570
13571 /* If within the scroll margin, scroll. */
13572 if (row->y < top_scroll_margin
13573 && CHARPOS (startp) != BEGV)
13574 scroll_p = 1;
13575 }
13576 else
13577 {
13578 /* Cursor did not move. So don't scroll even if cursor line
13579 is partially visible, as it was so before. */
13580 rc = CURSOR_MOVEMENT_SUCCESS;
13581 }
13582
13583 if (PT < MATRIX_ROW_START_CHARPOS (row)
13584 || PT > MATRIX_ROW_END_CHARPOS (row))
13585 {
13586 /* if PT is not in the glyph row, give up. */
13587 rc = CURSOR_MOVEMENT_MUST_SCROLL;
13588 must_scroll = 1;
13589 }
13590 else if (rc != CURSOR_MOVEMENT_SUCCESS
13591 && !NILP (XBUFFER (w->buffer)->bidi_display_reordering))
13592 {
13593 /* If rows are bidi-reordered and point moved, back up
13594 until we find a row that does not belong to a
13595 continuation line. This is because we must consider
13596 all rows of a continued line as candidates for the
13597 new cursor positioning, since row start and end
13598 positions change non-linearly with vertical position
13599 in such rows. */
13600 /* FIXME: Revisit this when glyph ``spilling'' in
13601 continuation lines' rows is implemented for
13602 bidi-reordered rows. */
13603 while (MATRIX_ROW_CONTINUATION_LINE_P (row))
13604 {
13605 xassert (row->enabled_p);
13606 --row;
13607 /* If we hit the beginning of the displayed portion
13608 without finding the first row of a continued
13609 line, give up. */
13610 if (row <= w->current_matrix->rows)
13611 {
13612 rc = CURSOR_MOVEMENT_MUST_SCROLL;
13613 break;
13614 }
13615
13616 }
13617 }
13618 if (must_scroll)
13619 ;
13620 else if (rc != CURSOR_MOVEMENT_SUCCESS
13621 && MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row)
13622 && make_cursor_line_fully_visible_p)
13623 {
13624 if (PT == MATRIX_ROW_END_CHARPOS (row)
13625 && !row->ends_at_zv_p
13626 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
13627 rc = CURSOR_MOVEMENT_MUST_SCROLL;
13628 else if (row->height > window_box_height (w))
13629 {
13630 /* If we end up in a partially visible line, let's
13631 make it fully visible, except when it's taller
13632 than the window, in which case we can't do much
13633 about it. */
13634 *scroll_step = 1;
13635 rc = CURSOR_MOVEMENT_MUST_SCROLL;
13636 }
13637 else
13638 {
13639 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
13640 if (!cursor_row_fully_visible_p (w, 0, 1))
13641 rc = CURSOR_MOVEMENT_MUST_SCROLL;
13642 else
13643 rc = CURSOR_MOVEMENT_SUCCESS;
13644 }
13645 }
13646 else if (scroll_p)
13647 rc = CURSOR_MOVEMENT_MUST_SCROLL;
13648 else if (rc != CURSOR_MOVEMENT_SUCCESS
13649 && !NILP (XBUFFER (w->buffer)->bidi_display_reordering))
13650 {
13651 /* With bidi-reordered rows, there could be more than
13652 one candidate row whose start and end positions
13653 occlude point. We need to let set_cursor_from_row
13654 find the best candidate. */
13655 /* FIXME: Revisit this when glyph ``spilling'' in
13656 continuation lines' rows is implemented for
13657 bidi-reordered rows. */
13658 int rv = 0;
13659
13660 do
13661 {
13662 if (MATRIX_ROW_START_CHARPOS (row) <= PT
13663 && PT <= MATRIX_ROW_END_CHARPOS (row)
13664 && cursor_row_p (w, row))
13665 rv |= set_cursor_from_row (w, row, w->current_matrix,
13666 0, 0, 0, 0);
13667 /* As soon as we've found the first suitable row
13668 whose ends_at_zv_p flag is set, we are done. */
13669 if (rv
13670 && MATRIX_ROW (w->current_matrix, w->cursor.vpos)->ends_at_zv_p)
13671 {
13672 rc = CURSOR_MOVEMENT_SUCCESS;
13673 break;
13674 }
13675 ++row;
13676 }
13677 while ((MATRIX_ROW_CONTINUATION_LINE_P (row)
13678 && MATRIX_ROW_BOTTOM_Y (row) <= last_y)
13679 || (MATRIX_ROW_START_CHARPOS (row) == PT
13680 && MATRIX_ROW_BOTTOM_Y (row) < last_y));
13681 /* If we didn't find any candidate rows, or exited the
13682 loop before all the candidates were examined, signal
13683 to the caller that this method failed. */
13684 if (rc != CURSOR_MOVEMENT_SUCCESS
13685 && (!rv || MATRIX_ROW_CONTINUATION_LINE_P (row)))
13686 rc = CURSOR_MOVEMENT_MUST_SCROLL;
13687 else if (rv)
13688 rc = CURSOR_MOVEMENT_SUCCESS;
13689 }
13690 else
13691 {
13692 do
13693 {
13694 if (set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0))
13695 {
13696 rc = CURSOR_MOVEMENT_SUCCESS;
13697 break;
13698 }
13699 ++row;
13700 }
13701 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
13702 && MATRIX_ROW_START_CHARPOS (row) == PT
13703 && cursor_row_p (w, row));
13704 }
13705 }
13706 }
13707
13708 return rc;
13709 }
13710
13711 void
13712 set_vertical_scroll_bar (struct window *w)
13713 {
13714 int start, end, whole;
13715
13716 /* Calculate the start and end positions for the current window.
13717 At some point, it would be nice to choose between scrollbars
13718 which reflect the whole buffer size, with special markers
13719 indicating narrowing, and scrollbars which reflect only the
13720 visible region.
13721
13722 Note that mini-buffers sometimes aren't displaying any text. */
13723 if (!MINI_WINDOW_P (w)
13724 || (w == XWINDOW (minibuf_window)
13725 && NILP (echo_area_buffer[0])))
13726 {
13727 struct buffer *buf = XBUFFER (w->buffer);
13728 whole = BUF_ZV (buf) - BUF_BEGV (buf);
13729 start = marker_position (w->start) - BUF_BEGV (buf);
13730 /* I don't think this is guaranteed to be right. For the
13731 moment, we'll pretend it is. */
13732 end = BUF_Z (buf) - XFASTINT (w->window_end_pos) - BUF_BEGV (buf);
13733
13734 if (end < start)
13735 end = start;
13736 if (whole < (end - start))
13737 whole = end - start;
13738 }
13739 else
13740 start = end = whole = 0;
13741
13742 /* Indicate what this scroll bar ought to be displaying now. */
13743 if (FRAME_TERMINAL (XFRAME (w->frame))->set_vertical_scroll_bar_hook)
13744 (*FRAME_TERMINAL (XFRAME (w->frame))->set_vertical_scroll_bar_hook)
13745 (w, end - start, whole, start);
13746 }
13747
13748
13749 /* Redisplay leaf window WINDOW. JUST_THIS_ONE_P non-zero means only
13750 selected_window is redisplayed.
13751
13752 We can return without actually redisplaying the window if
13753 fonts_changed_p is nonzero. In that case, redisplay_internal will
13754 retry. */
13755
13756 static void
13757 redisplay_window (Lisp_Object window, int just_this_one_p)
13758 {
13759 struct window *w = XWINDOW (window);
13760 struct frame *f = XFRAME (w->frame);
13761 struct buffer *buffer = XBUFFER (w->buffer);
13762 struct buffer *old = current_buffer;
13763 struct text_pos lpoint, opoint, startp;
13764 int update_mode_line;
13765 int tem;
13766 struct it it;
13767 /* Record it now because it's overwritten. */
13768 int current_matrix_up_to_date_p = 0;
13769 int used_current_matrix_p = 0;
13770 /* This is less strict than current_matrix_up_to_date_p.
13771 It indictes that the buffer contents and narrowing are unchanged. */
13772 int buffer_unchanged_p = 0;
13773 int temp_scroll_step = 0;
13774 int count = SPECPDL_INDEX ();
13775 int rc;
13776 int centering_position = -1;
13777 int last_line_misfit = 0;
13778 int beg_unchanged, end_unchanged;
13779
13780 SET_TEXT_POS (lpoint, PT, PT_BYTE);
13781 opoint = lpoint;
13782
13783 /* W must be a leaf window here. */
13784 xassert (!NILP (w->buffer));
13785 #if GLYPH_DEBUG
13786 *w->desired_matrix->method = 0;
13787 #endif
13788
13789 restart:
13790 reconsider_clip_changes (w, buffer);
13791
13792 /* Has the mode line to be updated? */
13793 update_mode_line = (!NILP (w->update_mode_line)
13794 || update_mode_lines
13795 || buffer->clip_changed
13796 || buffer->prevent_redisplay_optimizations_p);
13797
13798 if (MINI_WINDOW_P (w))
13799 {
13800 if (w == XWINDOW (echo_area_window)
13801 && !NILP (echo_area_buffer[0]))
13802 {
13803 if (update_mode_line)
13804 /* We may have to update a tty frame's menu bar or a
13805 tool-bar. Example `M-x C-h C-h C-g'. */
13806 goto finish_menu_bars;
13807 else
13808 /* We've already displayed the echo area glyphs in this window. */
13809 goto finish_scroll_bars;
13810 }
13811 else if ((w != XWINDOW (minibuf_window)
13812 || minibuf_level == 0)
13813 /* When buffer is nonempty, redisplay window normally. */
13814 && BUF_Z (XBUFFER (w->buffer)) == BUF_BEG (XBUFFER (w->buffer))
13815 /* Quail displays non-mini buffers in minibuffer window.
13816 In that case, redisplay the window normally. */
13817 && !NILP (Fmemq (w->buffer, Vminibuffer_list)))
13818 {
13819 /* W is a mini-buffer window, but it's not active, so clear
13820 it. */
13821 int yb = window_text_bottom_y (w);
13822 struct glyph_row *row;
13823 int y;
13824
13825 for (y = 0, row = w->desired_matrix->rows;
13826 y < yb;
13827 y += row->height, ++row)
13828 blank_row (w, row, y);
13829 goto finish_scroll_bars;
13830 }
13831
13832 clear_glyph_matrix (w->desired_matrix);
13833 }
13834
13835 /* Otherwise set up data on this window; select its buffer and point
13836 value. */
13837 /* Really select the buffer, for the sake of buffer-local
13838 variables. */
13839 set_buffer_internal_1 (XBUFFER (w->buffer));
13840
13841 current_matrix_up_to_date_p
13842 = (!NILP (w->window_end_valid)
13843 && !current_buffer->clip_changed
13844 && !current_buffer->prevent_redisplay_optimizations_p
13845 && XFASTINT (w->last_modified) >= MODIFF
13846 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
13847
13848 /* Run the window-bottom-change-functions
13849 if it is possible that the text on the screen has changed
13850 (either due to modification of the text, or any other reason). */
13851 if (!current_matrix_up_to_date_p
13852 && !NILP (Vwindow_text_change_functions))
13853 {
13854 safe_run_hooks (Qwindow_text_change_functions);
13855 goto restart;
13856 }
13857
13858 beg_unchanged = BEG_UNCHANGED;
13859 end_unchanged = END_UNCHANGED;
13860
13861 SET_TEXT_POS (opoint, PT, PT_BYTE);
13862
13863 specbind (Qinhibit_point_motion_hooks, Qt);
13864
13865 buffer_unchanged_p
13866 = (!NILP (w->window_end_valid)
13867 && !current_buffer->clip_changed
13868 && XFASTINT (w->last_modified) >= MODIFF
13869 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
13870
13871 /* When windows_or_buffers_changed is non-zero, we can't rely on
13872 the window end being valid, so set it to nil there. */
13873 if (windows_or_buffers_changed)
13874 {
13875 /* If window starts on a continuation line, maybe adjust the
13876 window start in case the window's width changed. */
13877 if (XMARKER (w->start)->buffer == current_buffer)
13878 compute_window_start_on_continuation_line (w);
13879
13880 w->window_end_valid = Qnil;
13881 }
13882
13883 /* Some sanity checks. */
13884 CHECK_WINDOW_END (w);
13885 if (Z == Z_BYTE && CHARPOS (opoint) != BYTEPOS (opoint))
13886 abort ();
13887 if (BYTEPOS (opoint) < CHARPOS (opoint))
13888 abort ();
13889
13890 /* If %c is in mode line, update it if needed. */
13891 if (!NILP (w->column_number_displayed)
13892 /* This alternative quickly identifies a common case
13893 where no change is needed. */
13894 && !(PT == XFASTINT (w->last_point)
13895 && XFASTINT (w->last_modified) >= MODIFF
13896 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
13897 && (XFASTINT (w->column_number_displayed)
13898 != (int) current_column ())) /* iftc */
13899 update_mode_line = 1;
13900
13901 /* Count number of windows showing the selected buffer. An indirect
13902 buffer counts as its base buffer. */
13903 if (!just_this_one_p)
13904 {
13905 struct buffer *current_base, *window_base;
13906 current_base = current_buffer;
13907 window_base = XBUFFER (XWINDOW (selected_window)->buffer);
13908 if (current_base->base_buffer)
13909 current_base = current_base->base_buffer;
13910 if (window_base->base_buffer)
13911 window_base = window_base->base_buffer;
13912 if (current_base == window_base)
13913 buffer_shared++;
13914 }
13915
13916 /* Point refers normally to the selected window. For any other
13917 window, set up appropriate value. */
13918 if (!EQ (window, selected_window))
13919 {
13920 int new_pt = XMARKER (w->pointm)->charpos;
13921 int new_pt_byte = marker_byte_position (w->pointm);
13922 if (new_pt < BEGV)
13923 {
13924 new_pt = BEGV;
13925 new_pt_byte = BEGV_BYTE;
13926 set_marker_both (w->pointm, Qnil, BEGV, BEGV_BYTE);
13927 }
13928 else if (new_pt > (ZV - 1))
13929 {
13930 new_pt = ZV;
13931 new_pt_byte = ZV_BYTE;
13932 set_marker_both (w->pointm, Qnil, ZV, ZV_BYTE);
13933 }
13934
13935 /* We don't use SET_PT so that the point-motion hooks don't run. */
13936 TEMP_SET_PT_BOTH (new_pt, new_pt_byte);
13937 }
13938
13939 /* If any of the character widths specified in the display table
13940 have changed, invalidate the width run cache. It's true that
13941 this may be a bit late to catch such changes, but the rest of
13942 redisplay goes (non-fatally) haywire when the display table is
13943 changed, so why should we worry about doing any better? */
13944 if (current_buffer->width_run_cache)
13945 {
13946 struct Lisp_Char_Table *disptab = buffer_display_table ();
13947
13948 if (! disptab_matches_widthtab (disptab,
13949 XVECTOR (current_buffer->width_table)))
13950 {
13951 invalidate_region_cache (current_buffer,
13952 current_buffer->width_run_cache,
13953 BEG, Z);
13954 recompute_width_table (current_buffer, disptab);
13955 }
13956 }
13957
13958 /* If window-start is screwed up, choose a new one. */
13959 if (XMARKER (w->start)->buffer != current_buffer)
13960 goto recenter;
13961
13962 SET_TEXT_POS_FROM_MARKER (startp, w->start);
13963
13964 /* If someone specified a new starting point but did not insist,
13965 check whether it can be used. */
13966 if (!NILP (w->optional_new_start)
13967 && CHARPOS (startp) >= BEGV
13968 && CHARPOS (startp) <= ZV)
13969 {
13970 w->optional_new_start = Qnil;
13971 start_display (&it, w, startp);
13972 move_it_to (&it, PT, 0, it.last_visible_y, -1,
13973 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
13974 if (IT_CHARPOS (it) == PT)
13975 w->force_start = Qt;
13976 /* IT may overshoot PT if text at PT is invisible. */
13977 else if (IT_CHARPOS (it) > PT && CHARPOS (startp) <= PT)
13978 w->force_start = Qt;
13979 }
13980
13981 force_start:
13982
13983 /* Handle case where place to start displaying has been specified,
13984 unless the specified location is outside the accessible range. */
13985 if (!NILP (w->force_start)
13986 || w->frozen_window_start_p)
13987 {
13988 /* We set this later on if we have to adjust point. */
13989 int new_vpos = -1;
13990
13991 w->force_start = Qnil;
13992 w->vscroll = 0;
13993 w->window_end_valid = Qnil;
13994
13995 /* Forget any recorded base line for line number display. */
13996 if (!buffer_unchanged_p)
13997 w->base_line_number = Qnil;
13998
13999 /* Redisplay the mode line. Select the buffer properly for that.
14000 Also, run the hook window-scroll-functions
14001 because we have scrolled. */
14002 /* Note, we do this after clearing force_start because
14003 if there's an error, it is better to forget about force_start
14004 than to get into an infinite loop calling the hook functions
14005 and having them get more errors. */
14006 if (!update_mode_line
14007 || ! NILP (Vwindow_scroll_functions))
14008 {
14009 update_mode_line = 1;
14010 w->update_mode_line = Qt;
14011 startp = run_window_scroll_functions (window, startp);
14012 }
14013
14014 w->last_modified = make_number (0);
14015 w->last_overlay_modified = make_number (0);
14016 if (CHARPOS (startp) < BEGV)
14017 SET_TEXT_POS (startp, BEGV, BEGV_BYTE);
14018 else if (CHARPOS (startp) > ZV)
14019 SET_TEXT_POS (startp, ZV, ZV_BYTE);
14020
14021 /* Redisplay, then check if cursor has been set during the
14022 redisplay. Give up if new fonts were loaded. */
14023 /* We used to issue a CHECK_MARGINS argument to try_window here,
14024 but this causes scrolling to fail when point begins inside
14025 the scroll margin (bug#148) -- cyd */
14026 if (!try_window (window, startp, 0))
14027 {
14028 w->force_start = Qt;
14029 clear_glyph_matrix (w->desired_matrix);
14030 goto need_larger_matrices;
14031 }
14032
14033 if (w->cursor.vpos < 0 && !w->frozen_window_start_p)
14034 {
14035 /* If point does not appear, try to move point so it does
14036 appear. The desired matrix has been built above, so we
14037 can use it here. */
14038 new_vpos = window_box_height (w) / 2;
14039 }
14040
14041 if (!cursor_row_fully_visible_p (w, 0, 0))
14042 {
14043 /* Point does appear, but on a line partly visible at end of window.
14044 Move it back to a fully-visible line. */
14045 new_vpos = window_box_height (w);
14046 }
14047
14048 /* If we need to move point for either of the above reasons,
14049 now actually do it. */
14050 if (new_vpos >= 0)
14051 {
14052 struct glyph_row *row;
14053
14054 row = MATRIX_FIRST_TEXT_ROW (w->desired_matrix);
14055 while (MATRIX_ROW_BOTTOM_Y (row) < new_vpos)
14056 ++row;
14057
14058 TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row),
14059 MATRIX_ROW_START_BYTEPOS (row));
14060
14061 if (w != XWINDOW (selected_window))
14062 set_marker_both (w->pointm, Qnil, PT, PT_BYTE);
14063 else if (current_buffer == old)
14064 SET_TEXT_POS (lpoint, PT, PT_BYTE);
14065
14066 set_cursor_from_row (w, row, w->desired_matrix, 0, 0, 0, 0);
14067
14068 /* If we are highlighting the region, then we just changed
14069 the region, so redisplay to show it. */
14070 if (!NILP (Vtransient_mark_mode)
14071 && !NILP (current_buffer->mark_active))
14072 {
14073 clear_glyph_matrix (w->desired_matrix);
14074 if (!try_window (window, startp, 0))
14075 goto need_larger_matrices;
14076 }
14077 }
14078
14079 #if GLYPH_DEBUG
14080 debug_method_add (w, "forced window start");
14081 #endif
14082 goto done;
14083 }
14084
14085 /* Handle case where text has not changed, only point, and it has
14086 not moved off the frame, and we are not retrying after hscroll.
14087 (current_matrix_up_to_date_p is nonzero when retrying.) */
14088 if (current_matrix_up_to_date_p
14089 && (rc = try_cursor_movement (window, startp, &temp_scroll_step),
14090 rc != CURSOR_MOVEMENT_CANNOT_BE_USED))
14091 {
14092 switch (rc)
14093 {
14094 case CURSOR_MOVEMENT_SUCCESS:
14095 used_current_matrix_p = 1;
14096 goto done;
14097
14098 case CURSOR_MOVEMENT_MUST_SCROLL:
14099 goto try_to_scroll;
14100
14101 default:
14102 abort ();
14103 }
14104 }
14105 /* If current starting point was originally the beginning of a line
14106 but no longer is, find a new starting point. */
14107 else if (!NILP (w->start_at_line_beg)
14108 && !(CHARPOS (startp) <= BEGV
14109 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n'))
14110 {
14111 #if GLYPH_DEBUG
14112 debug_method_add (w, "recenter 1");
14113 #endif
14114 goto recenter;
14115 }
14116
14117 /* Try scrolling with try_window_id. Value is > 0 if update has
14118 been done, it is -1 if we know that the same window start will
14119 not work. It is 0 if unsuccessful for some other reason. */
14120 else if ((tem = try_window_id (w)) != 0)
14121 {
14122 #if GLYPH_DEBUG
14123 debug_method_add (w, "try_window_id %d", tem);
14124 #endif
14125
14126 if (fonts_changed_p)
14127 goto need_larger_matrices;
14128 if (tem > 0)
14129 goto done;
14130
14131 /* Otherwise try_window_id has returned -1 which means that we
14132 don't want the alternative below this comment to execute. */
14133 }
14134 else if (CHARPOS (startp) >= BEGV
14135 && CHARPOS (startp) <= ZV
14136 && PT >= CHARPOS (startp)
14137 && (CHARPOS (startp) < ZV
14138 /* Avoid starting at end of buffer. */
14139 || CHARPOS (startp) == BEGV
14140 || (XFASTINT (w->last_modified) >= MODIFF
14141 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)))
14142 {
14143
14144 /* If first window line is a continuation line, and window start
14145 is inside the modified region, but the first change is before
14146 current window start, we must select a new window start.
14147
14148 However, if this is the result of a down-mouse event (e.g. by
14149 extending the mouse-drag-overlay), we don't want to select a
14150 new window start, since that would change the position under
14151 the mouse, resulting in an unwanted mouse-movement rather
14152 than a simple mouse-click. */
14153 if (NILP (w->start_at_line_beg)
14154 && NILP (do_mouse_tracking)
14155 && CHARPOS (startp) > BEGV
14156 && CHARPOS (startp) > BEG + beg_unchanged
14157 && CHARPOS (startp) <= Z - end_unchanged
14158 /* Even if w->start_at_line_beg is nil, a new window may
14159 start at a line_beg, since that's how set_buffer_window
14160 sets it. So, we need to check the return value of
14161 compute_window_start_on_continuation_line. (See also
14162 bug#197). */
14163 && XMARKER (w->start)->buffer == current_buffer
14164 && compute_window_start_on_continuation_line (w))
14165 {
14166 w->force_start = Qt;
14167 SET_TEXT_POS_FROM_MARKER (startp, w->start);
14168 goto force_start;
14169 }
14170
14171 #if GLYPH_DEBUG
14172 debug_method_add (w, "same window start");
14173 #endif
14174
14175 /* Try to redisplay starting at same place as before.
14176 If point has not moved off frame, accept the results. */
14177 if (!current_matrix_up_to_date_p
14178 /* Don't use try_window_reusing_current_matrix in this case
14179 because a window scroll function can have changed the
14180 buffer. */
14181 || !NILP (Vwindow_scroll_functions)
14182 || MINI_WINDOW_P (w)
14183 || !(used_current_matrix_p
14184 = try_window_reusing_current_matrix (w)))
14185 {
14186 IF_DEBUG (debug_method_add (w, "1"));
14187 if (try_window (window, startp, TRY_WINDOW_CHECK_MARGINS) < 0)
14188 /* -1 means we need to scroll.
14189 0 means we need new matrices, but fonts_changed_p
14190 is set in that case, so we will detect it below. */
14191 goto try_to_scroll;
14192 }
14193
14194 if (fonts_changed_p)
14195 goto need_larger_matrices;
14196
14197 if (w->cursor.vpos >= 0)
14198 {
14199 if (!just_this_one_p
14200 || current_buffer->clip_changed
14201 || BEG_UNCHANGED < CHARPOS (startp))
14202 /* Forget any recorded base line for line number display. */
14203 w->base_line_number = Qnil;
14204
14205 if (!cursor_row_fully_visible_p (w, 1, 0))
14206 {
14207 clear_glyph_matrix (w->desired_matrix);
14208 last_line_misfit = 1;
14209 }
14210 /* Drop through and scroll. */
14211 else
14212 goto done;
14213 }
14214 else
14215 clear_glyph_matrix (w->desired_matrix);
14216 }
14217
14218 try_to_scroll:
14219
14220 w->last_modified = make_number (0);
14221 w->last_overlay_modified = make_number (0);
14222
14223 /* Redisplay the mode line. Select the buffer properly for that. */
14224 if (!update_mode_line)
14225 {
14226 update_mode_line = 1;
14227 w->update_mode_line = Qt;
14228 }
14229
14230 /* Try to scroll by specified few lines. */
14231 if ((scroll_conservatively
14232 || scroll_step
14233 || temp_scroll_step
14234 || NUMBERP (current_buffer->scroll_up_aggressively)
14235 || NUMBERP (current_buffer->scroll_down_aggressively))
14236 && !current_buffer->clip_changed
14237 && CHARPOS (startp) >= BEGV
14238 && CHARPOS (startp) <= ZV)
14239 {
14240 /* The function returns -1 if new fonts were loaded, 1 if
14241 successful, 0 if not successful. */
14242 int rc = try_scrolling (window, just_this_one_p,
14243 scroll_conservatively,
14244 scroll_step,
14245 temp_scroll_step, last_line_misfit);
14246 switch (rc)
14247 {
14248 case SCROLLING_SUCCESS:
14249 goto done;
14250
14251 case SCROLLING_NEED_LARGER_MATRICES:
14252 goto need_larger_matrices;
14253
14254 case SCROLLING_FAILED:
14255 break;
14256
14257 default:
14258 abort ();
14259 }
14260 }
14261
14262 /* Finally, just choose place to start which centers point */
14263
14264 recenter:
14265 if (centering_position < 0)
14266 centering_position = window_box_height (w) / 2;
14267
14268 #if GLYPH_DEBUG
14269 debug_method_add (w, "recenter");
14270 #endif
14271
14272 /* w->vscroll = 0; */
14273
14274 /* Forget any previously recorded base line for line number display. */
14275 if (!buffer_unchanged_p)
14276 w->base_line_number = Qnil;
14277
14278 /* Move backward half the height of the window. */
14279 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
14280 it.current_y = it.last_visible_y;
14281 move_it_vertically_backward (&it, centering_position);
14282 xassert (IT_CHARPOS (it) >= BEGV);
14283
14284 /* The function move_it_vertically_backward may move over more
14285 than the specified y-distance. If it->w is small, e.g. a
14286 mini-buffer window, we may end up in front of the window's
14287 display area. Start displaying at the start of the line
14288 containing PT in this case. */
14289 if (it.current_y <= 0)
14290 {
14291 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
14292 move_it_vertically_backward (&it, 0);
14293 it.current_y = 0;
14294 }
14295
14296 it.current_x = it.hpos = 0;
14297
14298 /* Set startp here explicitly in case that helps avoid an infinite loop
14299 in case the window-scroll-functions functions get errors. */
14300 set_marker_both (w->start, Qnil, IT_CHARPOS (it), IT_BYTEPOS (it));
14301
14302 /* Run scroll hooks. */
14303 startp = run_window_scroll_functions (window, it.current.pos);
14304
14305 /* Redisplay the window. */
14306 if (!current_matrix_up_to_date_p
14307 || windows_or_buffers_changed
14308 || cursor_type_changed
14309 /* Don't use try_window_reusing_current_matrix in this case
14310 because it can have changed the buffer. */
14311 || !NILP (Vwindow_scroll_functions)
14312 || !just_this_one_p
14313 || MINI_WINDOW_P (w)
14314 || !(used_current_matrix_p
14315 = try_window_reusing_current_matrix (w)))
14316 try_window (window, startp, 0);
14317
14318 /* If new fonts have been loaded (due to fontsets), give up. We
14319 have to start a new redisplay since we need to re-adjust glyph
14320 matrices. */
14321 if (fonts_changed_p)
14322 goto need_larger_matrices;
14323
14324 /* If cursor did not appear assume that the middle of the window is
14325 in the first line of the window. Do it again with the next line.
14326 (Imagine a window of height 100, displaying two lines of height
14327 60. Moving back 50 from it->last_visible_y will end in the first
14328 line.) */
14329 if (w->cursor.vpos < 0)
14330 {
14331 if (!NILP (w->window_end_valid)
14332 && PT >= Z - XFASTINT (w->window_end_pos))
14333 {
14334 clear_glyph_matrix (w->desired_matrix);
14335 move_it_by_lines (&it, 1, 0);
14336 try_window (window, it.current.pos, 0);
14337 }
14338 else if (PT < IT_CHARPOS (it))
14339 {
14340 clear_glyph_matrix (w->desired_matrix);
14341 move_it_by_lines (&it, -1, 0);
14342 try_window (window, it.current.pos, 0);
14343 }
14344 else
14345 {
14346 /* Not much we can do about it. */
14347 }
14348 }
14349
14350 /* Consider the following case: Window starts at BEGV, there is
14351 invisible, intangible text at BEGV, so that display starts at
14352 some point START > BEGV. It can happen that we are called with
14353 PT somewhere between BEGV and START. Try to handle that case. */
14354 if (w->cursor.vpos < 0)
14355 {
14356 struct glyph_row *row = w->current_matrix->rows;
14357 if (row->mode_line_p)
14358 ++row;
14359 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
14360 }
14361
14362 if (!cursor_row_fully_visible_p (w, 0, 0))
14363 {
14364 /* If vscroll is enabled, disable it and try again. */
14365 if (w->vscroll)
14366 {
14367 w->vscroll = 0;
14368 clear_glyph_matrix (w->desired_matrix);
14369 goto recenter;
14370 }
14371
14372 /* If centering point failed to make the whole line visible,
14373 put point at the top instead. That has to make the whole line
14374 visible, if it can be done. */
14375 if (centering_position == 0)
14376 goto done;
14377
14378 clear_glyph_matrix (w->desired_matrix);
14379 centering_position = 0;
14380 goto recenter;
14381 }
14382
14383 done:
14384
14385 SET_TEXT_POS_FROM_MARKER (startp, w->start);
14386 w->start_at_line_beg = ((CHARPOS (startp) == BEGV
14387 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n')
14388 ? Qt : Qnil);
14389
14390 /* Display the mode line, if we must. */
14391 if ((update_mode_line
14392 /* If window not full width, must redo its mode line
14393 if (a) the window to its side is being redone and
14394 (b) we do a frame-based redisplay. This is a consequence
14395 of how inverted lines are drawn in frame-based redisplay. */
14396 || (!just_this_one_p
14397 && !FRAME_WINDOW_P (f)
14398 && !WINDOW_FULL_WIDTH_P (w))
14399 /* Line number to display. */
14400 || INTEGERP (w->base_line_pos)
14401 /* Column number is displayed and different from the one displayed. */
14402 || (!NILP (w->column_number_displayed)
14403 && (XFASTINT (w->column_number_displayed)
14404 != (int) current_column ()))) /* iftc */
14405 /* This means that the window has a mode line. */
14406 && (WINDOW_WANTS_MODELINE_P (w)
14407 || WINDOW_WANTS_HEADER_LINE_P (w)))
14408 {
14409 display_mode_lines (w);
14410
14411 /* If mode line height has changed, arrange for a thorough
14412 immediate redisplay using the correct mode line height. */
14413 if (WINDOW_WANTS_MODELINE_P (w)
14414 && CURRENT_MODE_LINE_HEIGHT (w) != DESIRED_MODE_LINE_HEIGHT (w))
14415 {
14416 fonts_changed_p = 1;
14417 MATRIX_MODE_LINE_ROW (w->current_matrix)->height
14418 = DESIRED_MODE_LINE_HEIGHT (w);
14419 }
14420
14421 /* If header line height has changed, arrange for a thorough
14422 immediate redisplay using the correct header line height. */
14423 if (WINDOW_WANTS_HEADER_LINE_P (w)
14424 && CURRENT_HEADER_LINE_HEIGHT (w) != DESIRED_HEADER_LINE_HEIGHT (w))
14425 {
14426 fonts_changed_p = 1;
14427 MATRIX_HEADER_LINE_ROW (w->current_matrix)->height
14428 = DESIRED_HEADER_LINE_HEIGHT (w);
14429 }
14430
14431 if (fonts_changed_p)
14432 goto need_larger_matrices;
14433 }
14434
14435 if (!line_number_displayed
14436 && !BUFFERP (w->base_line_pos))
14437 {
14438 w->base_line_pos = Qnil;
14439 w->base_line_number = Qnil;
14440 }
14441
14442 finish_menu_bars:
14443
14444 /* When we reach a frame's selected window, redo the frame's menu bar. */
14445 if (update_mode_line
14446 && EQ (FRAME_SELECTED_WINDOW (f), window))
14447 {
14448 int redisplay_menu_p = 0;
14449 int redisplay_tool_bar_p = 0;
14450
14451 if (FRAME_WINDOW_P (f))
14452 {
14453 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
14454 || defined (HAVE_NS) || defined (USE_GTK)
14455 redisplay_menu_p = FRAME_EXTERNAL_MENU_BAR (f);
14456 #else
14457 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
14458 #endif
14459 }
14460 else
14461 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
14462
14463 if (redisplay_menu_p)
14464 display_menu_bar (w);
14465
14466 #ifdef HAVE_WINDOW_SYSTEM
14467 if (FRAME_WINDOW_P (f))
14468 {
14469 #if defined (USE_GTK) || defined (HAVE_NS)
14470 redisplay_tool_bar_p = FRAME_EXTERNAL_TOOL_BAR (f);
14471 #else
14472 redisplay_tool_bar_p = WINDOWP (f->tool_bar_window)
14473 && (FRAME_TOOL_BAR_LINES (f) > 0
14474 || !NILP (Vauto_resize_tool_bars));
14475 #endif
14476
14477 if (redisplay_tool_bar_p && redisplay_tool_bar (f))
14478 {
14479 ignore_mouse_drag_p = 1;
14480 }
14481 }
14482 #endif
14483 }
14484
14485 #ifdef HAVE_WINDOW_SYSTEM
14486 if (FRAME_WINDOW_P (f)
14487 && update_window_fringes (w, (just_this_one_p
14488 || (!used_current_matrix_p && !overlay_arrow_seen)
14489 || w->pseudo_window_p)))
14490 {
14491 update_begin (f);
14492 BLOCK_INPUT;
14493 if (draw_window_fringes (w, 1))
14494 x_draw_vertical_border (w);
14495 UNBLOCK_INPUT;
14496 update_end (f);
14497 }
14498 #endif /* HAVE_WINDOW_SYSTEM */
14499
14500 /* We go to this label, with fonts_changed_p nonzero,
14501 if it is necessary to try again using larger glyph matrices.
14502 We have to redeem the scroll bar even in this case,
14503 because the loop in redisplay_internal expects that. */
14504 need_larger_matrices:
14505 ;
14506 finish_scroll_bars:
14507
14508 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
14509 {
14510 /* Set the thumb's position and size. */
14511 set_vertical_scroll_bar (w);
14512
14513 /* Note that we actually used the scroll bar attached to this
14514 window, so it shouldn't be deleted at the end of redisplay. */
14515 if (FRAME_TERMINAL (f)->redeem_scroll_bar_hook)
14516 (*FRAME_TERMINAL (f)->redeem_scroll_bar_hook) (w);
14517 }
14518
14519 /* Restore current_buffer and value of point in it. The window
14520 update may have changed the buffer, so first make sure `opoint'
14521 is still valid (Bug#6177). */
14522 if (CHARPOS (opoint) < BEGV)
14523 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
14524 else if (CHARPOS (opoint) > ZV)
14525 TEMP_SET_PT_BOTH (Z, Z_BYTE);
14526 else
14527 TEMP_SET_PT_BOTH (CHARPOS (opoint), BYTEPOS (opoint));
14528
14529 set_buffer_internal_1 (old);
14530 /* Avoid an abort in TEMP_SET_PT_BOTH if the buffer has become
14531 shorter. This can be caused by log truncation in *Messages*. */
14532 if (CHARPOS (lpoint) <= ZV)
14533 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
14534
14535 unbind_to (count, Qnil);
14536 }
14537
14538
14539 /* Build the complete desired matrix of WINDOW with a window start
14540 buffer position POS.
14541
14542 Value is 1 if successful. It is zero if fonts were loaded during
14543 redisplay which makes re-adjusting glyph matrices necessary, and -1
14544 if point would appear in the scroll margins.
14545 (We check the former only if TRY_WINDOW_IGNORE_FONTS_CHANGE is
14546 unset in FLAGS, and the latter only if TRY_WINDOW_CHECK_MARGINS is
14547 set in FLAGS.) */
14548
14549 int
14550 try_window (Lisp_Object window, struct text_pos pos, int flags)
14551 {
14552 struct window *w = XWINDOW (window);
14553 struct it it;
14554 struct glyph_row *last_text_row = NULL;
14555 struct frame *f = XFRAME (w->frame);
14556
14557 /* Make POS the new window start. */
14558 set_marker_both (w->start, Qnil, CHARPOS (pos), BYTEPOS (pos));
14559
14560 /* Mark cursor position as unknown. No overlay arrow seen. */
14561 w->cursor.vpos = -1;
14562 overlay_arrow_seen = 0;
14563
14564 /* Initialize iterator and info to start at POS. */
14565 start_display (&it, w, pos);
14566
14567 /* Display all lines of W. */
14568 while (it.current_y < it.last_visible_y)
14569 {
14570 if (display_line (&it))
14571 last_text_row = it.glyph_row - 1;
14572 if (fonts_changed_p && !(flags & TRY_WINDOW_IGNORE_FONTS_CHANGE))
14573 return 0;
14574 }
14575
14576 /* Don't let the cursor end in the scroll margins. */
14577 if ((flags & TRY_WINDOW_CHECK_MARGINS)
14578 && !MINI_WINDOW_P (w))
14579 {
14580 int this_scroll_margin;
14581
14582 if (scroll_margin > 0)
14583 {
14584 this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
14585 this_scroll_margin *= FRAME_LINE_HEIGHT (f);
14586 }
14587 else
14588 this_scroll_margin = 0;
14589
14590 if ((w->cursor.y >= 0 /* not vscrolled */
14591 && w->cursor.y < this_scroll_margin
14592 && CHARPOS (pos) > BEGV
14593 && IT_CHARPOS (it) < ZV)
14594 /* rms: considering make_cursor_line_fully_visible_p here
14595 seems to give wrong results. We don't want to recenter
14596 when the last line is partly visible, we want to allow
14597 that case to be handled in the usual way. */
14598 || w->cursor.y > it.last_visible_y - this_scroll_margin - 1)
14599 {
14600 w->cursor.vpos = -1;
14601 clear_glyph_matrix (w->desired_matrix);
14602 return -1;
14603 }
14604 }
14605
14606 /* If bottom moved off end of frame, change mode line percentage. */
14607 if (XFASTINT (w->window_end_pos) <= 0
14608 && Z != IT_CHARPOS (it))
14609 w->update_mode_line = Qt;
14610
14611 /* Set window_end_pos to the offset of the last character displayed
14612 on the window from the end of current_buffer. Set
14613 window_end_vpos to its row number. */
14614 if (last_text_row)
14615 {
14616 xassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row));
14617 w->window_end_bytepos
14618 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
14619 w->window_end_pos
14620 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
14621 w->window_end_vpos
14622 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
14623 xassert (MATRIX_ROW (w->desired_matrix, XFASTINT (w->window_end_vpos))
14624 ->displays_text_p);
14625 }
14626 else
14627 {
14628 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
14629 w->window_end_pos = make_number (Z - ZV);
14630 w->window_end_vpos = make_number (0);
14631 }
14632
14633 /* But that is not valid info until redisplay finishes. */
14634 w->window_end_valid = Qnil;
14635 return 1;
14636 }
14637
14638
14639 \f
14640 /************************************************************************
14641 Window redisplay reusing current matrix when buffer has not changed
14642 ************************************************************************/
14643
14644 /* Try redisplay of window W showing an unchanged buffer with a
14645 different window start than the last time it was displayed by
14646 reusing its current matrix. Value is non-zero if successful.
14647 W->start is the new window start. */
14648
14649 static int
14650 try_window_reusing_current_matrix (struct window *w)
14651 {
14652 struct frame *f = XFRAME (w->frame);
14653 struct glyph_row *row, *bottom_row;
14654 struct it it;
14655 struct run run;
14656 struct text_pos start, new_start;
14657 int nrows_scrolled, i;
14658 struct glyph_row *last_text_row;
14659 struct glyph_row *last_reused_text_row;
14660 struct glyph_row *start_row;
14661 int start_vpos, min_y, max_y;
14662
14663 #if GLYPH_DEBUG
14664 if (inhibit_try_window_reusing)
14665 return 0;
14666 #endif
14667
14668 if (/* This function doesn't handle terminal frames. */
14669 !FRAME_WINDOW_P (f)
14670 /* Don't try to reuse the display if windows have been split
14671 or such. */
14672 || windows_or_buffers_changed
14673 || cursor_type_changed)
14674 return 0;
14675
14676 /* Can't do this if region may have changed. */
14677 if ((!NILP (Vtransient_mark_mode)
14678 && !NILP (current_buffer->mark_active))
14679 || !NILP (w->region_showing)
14680 || !NILP (Vshow_trailing_whitespace))
14681 return 0;
14682
14683 /* If top-line visibility has changed, give up. */
14684 if (WINDOW_WANTS_HEADER_LINE_P (w)
14685 != MATRIX_HEADER_LINE_ROW (w->current_matrix)->mode_line_p)
14686 return 0;
14687
14688 /* Give up if old or new display is scrolled vertically. We could
14689 make this function handle this, but right now it doesn't. */
14690 start_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
14691 if (w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row))
14692 return 0;
14693
14694 /* The variable new_start now holds the new window start. The old
14695 start `start' can be determined from the current matrix. */
14696 SET_TEXT_POS_FROM_MARKER (new_start, w->start);
14697 start = start_row->minpos;
14698 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
14699
14700 /* Clear the desired matrix for the display below. */
14701 clear_glyph_matrix (w->desired_matrix);
14702
14703 if (CHARPOS (new_start) <= CHARPOS (start))
14704 {
14705 int first_row_y;
14706
14707 /* Don't use this method if the display starts with an ellipsis
14708 displayed for invisible text. It's not easy to handle that case
14709 below, and it's certainly not worth the effort since this is
14710 not a frequent case. */
14711 if (in_ellipses_for_invisible_text_p (&start_row->start, w))
14712 return 0;
14713
14714 IF_DEBUG (debug_method_add (w, "twu1"));
14715
14716 /* Display up to a row that can be reused. The variable
14717 last_text_row is set to the last row displayed that displays
14718 text. Note that it.vpos == 0 if or if not there is a
14719 header-line; it's not the same as the MATRIX_ROW_VPOS! */
14720 start_display (&it, w, new_start);
14721 first_row_y = it.current_y;
14722 w->cursor.vpos = -1;
14723 last_text_row = last_reused_text_row = NULL;
14724
14725 while (it.current_y < it.last_visible_y
14726 && !fonts_changed_p)
14727 {
14728 /* If we have reached into the characters in the START row,
14729 that means the line boundaries have changed. So we
14730 can't start copying with the row START. Maybe it will
14731 work to start copying with the following row. */
14732 while (IT_CHARPOS (it) > CHARPOS (start))
14733 {
14734 /* Advance to the next row as the "start". */
14735 start_row++;
14736 start = start_row->minpos;
14737 /* If there are no more rows to try, or just one, give up. */
14738 if (start_row == MATRIX_MODE_LINE_ROW (w->current_matrix) - 1
14739 || w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row)
14740 || CHARPOS (start) == ZV)
14741 {
14742 clear_glyph_matrix (w->desired_matrix);
14743 return 0;
14744 }
14745
14746 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
14747 }
14748 /* If we have reached alignment,
14749 we can copy the rest of the rows. */
14750 if (IT_CHARPOS (it) == CHARPOS (start))
14751 break;
14752
14753 if (display_line (&it))
14754 last_text_row = it.glyph_row - 1;
14755 }
14756
14757 /* A value of current_y < last_visible_y means that we stopped
14758 at the previous window start, which in turn means that we
14759 have at least one reusable row. */
14760 if (it.current_y < it.last_visible_y)
14761 {
14762 /* IT.vpos always starts from 0; it counts text lines. */
14763 nrows_scrolled = it.vpos - (start_row - MATRIX_FIRST_TEXT_ROW (w->current_matrix));
14764
14765 /* Find PT if not already found in the lines displayed. */
14766 if (w->cursor.vpos < 0)
14767 {
14768 int dy = it.current_y - start_row->y;
14769
14770 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
14771 row = row_containing_pos (w, PT, row, NULL, dy);
14772 if (row)
14773 set_cursor_from_row (w, row, w->current_matrix, 0, 0,
14774 dy, nrows_scrolled);
14775 else
14776 {
14777 clear_glyph_matrix (w->desired_matrix);
14778 return 0;
14779 }
14780 }
14781
14782 /* Scroll the display. Do it before the current matrix is
14783 changed. The problem here is that update has not yet
14784 run, i.e. part of the current matrix is not up to date.
14785 scroll_run_hook will clear the cursor, and use the
14786 current matrix to get the height of the row the cursor is
14787 in. */
14788 run.current_y = start_row->y;
14789 run.desired_y = it.current_y;
14790 run.height = it.last_visible_y - it.current_y;
14791
14792 if (run.height > 0 && run.current_y != run.desired_y)
14793 {
14794 update_begin (f);
14795 FRAME_RIF (f)->update_window_begin_hook (w);
14796 FRAME_RIF (f)->clear_window_mouse_face (w);
14797 FRAME_RIF (f)->scroll_run_hook (w, &run);
14798 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
14799 update_end (f);
14800 }
14801
14802 /* Shift current matrix down by nrows_scrolled lines. */
14803 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
14804 rotate_matrix (w->current_matrix,
14805 start_vpos,
14806 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
14807 nrows_scrolled);
14808
14809 /* Disable lines that must be updated. */
14810 for (i = 0; i < nrows_scrolled; ++i)
14811 (start_row + i)->enabled_p = 0;
14812
14813 /* Re-compute Y positions. */
14814 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
14815 max_y = it.last_visible_y;
14816 for (row = start_row + nrows_scrolled;
14817 row < bottom_row;
14818 ++row)
14819 {
14820 row->y = it.current_y;
14821 row->visible_height = row->height;
14822
14823 if (row->y < min_y)
14824 row->visible_height -= min_y - row->y;
14825 if (row->y + row->height > max_y)
14826 row->visible_height -= row->y + row->height - max_y;
14827 row->redraw_fringe_bitmaps_p = 1;
14828
14829 it.current_y += row->height;
14830
14831 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
14832 last_reused_text_row = row;
14833 if (MATRIX_ROW_BOTTOM_Y (row) >= it.last_visible_y)
14834 break;
14835 }
14836
14837 /* Disable lines in the current matrix which are now
14838 below the window. */
14839 for (++row; row < bottom_row; ++row)
14840 row->enabled_p = row->mode_line_p = 0;
14841 }
14842
14843 /* Update window_end_pos etc.; last_reused_text_row is the last
14844 reused row from the current matrix containing text, if any.
14845 The value of last_text_row is the last displayed line
14846 containing text. */
14847 if (last_reused_text_row)
14848 {
14849 w->window_end_bytepos
14850 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_reused_text_row);
14851 w->window_end_pos
14852 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_reused_text_row));
14853 w->window_end_vpos
14854 = make_number (MATRIX_ROW_VPOS (last_reused_text_row,
14855 w->current_matrix));
14856 }
14857 else if (last_text_row)
14858 {
14859 w->window_end_bytepos
14860 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
14861 w->window_end_pos
14862 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
14863 w->window_end_vpos
14864 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
14865 }
14866 else
14867 {
14868 /* This window must be completely empty. */
14869 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
14870 w->window_end_pos = make_number (Z - ZV);
14871 w->window_end_vpos = make_number (0);
14872 }
14873 w->window_end_valid = Qnil;
14874
14875 /* Update hint: don't try scrolling again in update_window. */
14876 w->desired_matrix->no_scrolling_p = 1;
14877
14878 #if GLYPH_DEBUG
14879 debug_method_add (w, "try_window_reusing_current_matrix 1");
14880 #endif
14881 return 1;
14882 }
14883 else if (CHARPOS (new_start) > CHARPOS (start))
14884 {
14885 struct glyph_row *pt_row, *row;
14886 struct glyph_row *first_reusable_row;
14887 struct glyph_row *first_row_to_display;
14888 int dy;
14889 int yb = window_text_bottom_y (w);
14890
14891 /* Find the row starting at new_start, if there is one. Don't
14892 reuse a partially visible line at the end. */
14893 first_reusable_row = start_row;
14894 while (first_reusable_row->enabled_p
14895 && MATRIX_ROW_BOTTOM_Y (first_reusable_row) < yb
14896 && (MATRIX_ROW_START_CHARPOS (first_reusable_row)
14897 < CHARPOS (new_start)))
14898 ++first_reusable_row;
14899
14900 /* Give up if there is no row to reuse. */
14901 if (MATRIX_ROW_BOTTOM_Y (first_reusable_row) >= yb
14902 || !first_reusable_row->enabled_p
14903 || (MATRIX_ROW_START_CHARPOS (first_reusable_row)
14904 != CHARPOS (new_start)))
14905 return 0;
14906
14907 /* We can reuse fully visible rows beginning with
14908 first_reusable_row to the end of the window. Set
14909 first_row_to_display to the first row that cannot be reused.
14910 Set pt_row to the row containing point, if there is any. */
14911 pt_row = NULL;
14912 for (first_row_to_display = first_reusable_row;
14913 MATRIX_ROW_BOTTOM_Y (first_row_to_display) < yb;
14914 ++first_row_to_display)
14915 {
14916 if (PT >= MATRIX_ROW_START_CHARPOS (first_row_to_display)
14917 && PT < MATRIX_ROW_END_CHARPOS (first_row_to_display))
14918 pt_row = first_row_to_display;
14919 }
14920
14921 /* Start displaying at the start of first_row_to_display. */
14922 xassert (first_row_to_display->y < yb);
14923 init_to_row_start (&it, w, first_row_to_display);
14924
14925 nrows_scrolled = (MATRIX_ROW_VPOS (first_reusable_row, w->current_matrix)
14926 - start_vpos);
14927 it.vpos = (MATRIX_ROW_VPOS (first_row_to_display, w->current_matrix)
14928 - nrows_scrolled);
14929 it.current_y = (first_row_to_display->y - first_reusable_row->y
14930 + WINDOW_HEADER_LINE_HEIGHT (w));
14931
14932 /* Display lines beginning with first_row_to_display in the
14933 desired matrix. Set last_text_row to the last row displayed
14934 that displays text. */
14935 it.glyph_row = MATRIX_ROW (w->desired_matrix, it.vpos);
14936 if (pt_row == NULL)
14937 w->cursor.vpos = -1;
14938 last_text_row = NULL;
14939 while (it.current_y < it.last_visible_y && !fonts_changed_p)
14940 if (display_line (&it))
14941 last_text_row = it.glyph_row - 1;
14942
14943 /* If point is in a reused row, adjust y and vpos of the cursor
14944 position. */
14945 if (pt_row)
14946 {
14947 w->cursor.vpos -= nrows_scrolled;
14948 w->cursor.y -= first_reusable_row->y - start_row->y;
14949 }
14950
14951 /* Give up if point isn't in a row displayed or reused. (This
14952 also handles the case where w->cursor.vpos < nrows_scrolled
14953 after the calls to display_line, which can happen with scroll
14954 margins. See bug#1295.) */
14955 if (w->cursor.vpos < 0)
14956 {
14957 clear_glyph_matrix (w->desired_matrix);
14958 return 0;
14959 }
14960
14961 /* Scroll the display. */
14962 run.current_y = first_reusable_row->y;
14963 run.desired_y = WINDOW_HEADER_LINE_HEIGHT (w);
14964 run.height = it.last_visible_y - run.current_y;
14965 dy = run.current_y - run.desired_y;
14966
14967 if (run.height)
14968 {
14969 update_begin (f);
14970 FRAME_RIF (f)->update_window_begin_hook (w);
14971 FRAME_RIF (f)->clear_window_mouse_face (w);
14972 FRAME_RIF (f)->scroll_run_hook (w, &run);
14973 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
14974 update_end (f);
14975 }
14976
14977 /* Adjust Y positions of reused rows. */
14978 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
14979 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
14980 max_y = it.last_visible_y;
14981 for (row = first_reusable_row; row < first_row_to_display; ++row)
14982 {
14983 row->y -= dy;
14984 row->visible_height = row->height;
14985 if (row->y < min_y)
14986 row->visible_height -= min_y - row->y;
14987 if (row->y + row->height > max_y)
14988 row->visible_height -= row->y + row->height - max_y;
14989 row->redraw_fringe_bitmaps_p = 1;
14990 }
14991
14992 /* Scroll the current matrix. */
14993 xassert (nrows_scrolled > 0);
14994 rotate_matrix (w->current_matrix,
14995 start_vpos,
14996 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
14997 -nrows_scrolled);
14998
14999 /* Disable rows not reused. */
15000 for (row -= nrows_scrolled; row < bottom_row; ++row)
15001 row->enabled_p = 0;
15002
15003 /* Point may have moved to a different line, so we cannot assume that
15004 the previous cursor position is valid; locate the correct row. */
15005 if (pt_row)
15006 {
15007 for (row = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
15008 row < bottom_row && PT >= MATRIX_ROW_END_CHARPOS (row);
15009 row++)
15010 {
15011 w->cursor.vpos++;
15012 w->cursor.y = row->y;
15013 }
15014 if (row < bottom_row)
15015 {
15016 struct glyph *glyph = row->glyphs[TEXT_AREA] + w->cursor.hpos;
15017 struct glyph *end = glyph + row->used[TEXT_AREA];
15018
15019 /* Can't use this optimization with bidi-reordered glyph
15020 rows, unless cursor is already at point. */
15021 if (!NILP (XBUFFER (w->buffer)->bidi_display_reordering))
15022 {
15023 if (!(w->cursor.hpos >= 0
15024 && w->cursor.hpos < row->used[TEXT_AREA]
15025 && BUFFERP (glyph->object)
15026 && glyph->charpos == PT))
15027 return 0;
15028 }
15029 else
15030 for (; glyph < end
15031 && (!BUFFERP (glyph->object)
15032 || glyph->charpos < PT);
15033 glyph++)
15034 {
15035 w->cursor.hpos++;
15036 w->cursor.x += glyph->pixel_width;
15037 }
15038 }
15039 }
15040
15041 /* Adjust window end. A null value of last_text_row means that
15042 the window end is in reused rows which in turn means that
15043 only its vpos can have changed. */
15044 if (last_text_row)
15045 {
15046 w->window_end_bytepos
15047 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
15048 w->window_end_pos
15049 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
15050 w->window_end_vpos
15051 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
15052 }
15053 else
15054 {
15055 w->window_end_vpos
15056 = make_number (XFASTINT (w->window_end_vpos) - nrows_scrolled);
15057 }
15058
15059 w->window_end_valid = Qnil;
15060 w->desired_matrix->no_scrolling_p = 1;
15061
15062 #if GLYPH_DEBUG
15063 debug_method_add (w, "try_window_reusing_current_matrix 2");
15064 #endif
15065 return 1;
15066 }
15067
15068 return 0;
15069 }
15070
15071
15072 \f
15073 /************************************************************************
15074 Window redisplay reusing current matrix when buffer has changed
15075 ************************************************************************/
15076
15077 static struct glyph_row *find_last_unchanged_at_beg_row (struct window *);
15078 static struct glyph_row *find_first_unchanged_at_end_row (struct window *,
15079 int *, int *);
15080 static struct glyph_row *
15081 find_last_row_displaying_text (struct glyph_matrix *, struct it *,
15082 struct glyph_row *);
15083
15084
15085 /* Return the last row in MATRIX displaying text. If row START is
15086 non-null, start searching with that row. IT gives the dimensions
15087 of the display. Value is null if matrix is empty; otherwise it is
15088 a pointer to the row found. */
15089
15090 static struct glyph_row *
15091 find_last_row_displaying_text (struct glyph_matrix *matrix, struct it *it,
15092 struct glyph_row *start)
15093 {
15094 struct glyph_row *row, *row_found;
15095
15096 /* Set row_found to the last row in IT->w's current matrix
15097 displaying text. The loop looks funny but think of partially
15098 visible lines. */
15099 row_found = NULL;
15100 row = start ? start : MATRIX_FIRST_TEXT_ROW (matrix);
15101 while (MATRIX_ROW_DISPLAYS_TEXT_P (row))
15102 {
15103 xassert (row->enabled_p);
15104 row_found = row;
15105 if (MATRIX_ROW_BOTTOM_Y (row) >= it->last_visible_y)
15106 break;
15107 ++row;
15108 }
15109
15110 return row_found;
15111 }
15112
15113
15114 /* Return the last row in the current matrix of W that is not affected
15115 by changes at the start of current_buffer that occurred since W's
15116 current matrix was built. Value is null if no such row exists.
15117
15118 BEG_UNCHANGED us the number of characters unchanged at the start of
15119 current_buffer. BEG + BEG_UNCHANGED is the buffer position of the
15120 first changed character in current_buffer. Characters at positions <
15121 BEG + BEG_UNCHANGED are at the same buffer positions as they were
15122 when the current matrix was built. */
15123
15124 static struct glyph_row *
15125 find_last_unchanged_at_beg_row (struct window *w)
15126 {
15127 int first_changed_pos = BEG + BEG_UNCHANGED;
15128 struct glyph_row *row;
15129 struct glyph_row *row_found = NULL;
15130 int yb = window_text_bottom_y (w);
15131
15132 /* Find the last row displaying unchanged text. */
15133 for (row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
15134 MATRIX_ROW_DISPLAYS_TEXT_P (row)
15135 && MATRIX_ROW_START_CHARPOS (row) < first_changed_pos;
15136 ++row)
15137 {
15138 if (/* If row ends before first_changed_pos, it is unchanged,
15139 except in some case. */
15140 MATRIX_ROW_END_CHARPOS (row) <= first_changed_pos
15141 /* When row ends in ZV and we write at ZV it is not
15142 unchanged. */
15143 && !row->ends_at_zv_p
15144 /* When first_changed_pos is the end of a continued line,
15145 row is not unchanged because it may be no longer
15146 continued. */
15147 && !(MATRIX_ROW_END_CHARPOS (row) == first_changed_pos
15148 && (row->continued_p
15149 || row->exact_window_width_line_p)))
15150 row_found = row;
15151
15152 /* Stop if last visible row. */
15153 if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
15154 break;
15155 }
15156
15157 return row_found;
15158 }
15159
15160
15161 /* Find the first glyph row in the current matrix of W that is not
15162 affected by changes at the end of current_buffer since the
15163 time W's current matrix was built.
15164
15165 Return in *DELTA the number of chars by which buffer positions in
15166 unchanged text at the end of current_buffer must be adjusted.
15167
15168 Return in *DELTA_BYTES the corresponding number of bytes.
15169
15170 Value is null if no such row exists, i.e. all rows are affected by
15171 changes. */
15172
15173 static struct glyph_row *
15174 find_first_unchanged_at_end_row (struct window *w, int *delta, int *delta_bytes)
15175 {
15176 struct glyph_row *row;
15177 struct glyph_row *row_found = NULL;
15178
15179 *delta = *delta_bytes = 0;
15180
15181 /* Display must not have been paused, otherwise the current matrix
15182 is not up to date. */
15183 eassert (!NILP (w->window_end_valid));
15184
15185 /* A value of window_end_pos >= END_UNCHANGED means that the window
15186 end is in the range of changed text. If so, there is no
15187 unchanged row at the end of W's current matrix. */
15188 if (XFASTINT (w->window_end_pos) >= END_UNCHANGED)
15189 return NULL;
15190
15191 /* Set row to the last row in W's current matrix displaying text. */
15192 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
15193
15194 /* If matrix is entirely empty, no unchanged row exists. */
15195 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
15196 {
15197 /* The value of row is the last glyph row in the matrix having a
15198 meaningful buffer position in it. The end position of row
15199 corresponds to window_end_pos. This allows us to translate
15200 buffer positions in the current matrix to current buffer
15201 positions for characters not in changed text. */
15202 int Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
15203 int Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
15204 int last_unchanged_pos, last_unchanged_pos_old;
15205 struct glyph_row *first_text_row
15206 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
15207
15208 *delta = Z - Z_old;
15209 *delta_bytes = Z_BYTE - Z_BYTE_old;
15210
15211 /* Set last_unchanged_pos to the buffer position of the last
15212 character in the buffer that has not been changed. Z is the
15213 index + 1 of the last character in current_buffer, i.e. by
15214 subtracting END_UNCHANGED we get the index of the last
15215 unchanged character, and we have to add BEG to get its buffer
15216 position. */
15217 last_unchanged_pos = Z - END_UNCHANGED + BEG;
15218 last_unchanged_pos_old = last_unchanged_pos - *delta;
15219
15220 /* Search backward from ROW for a row displaying a line that
15221 starts at a minimum position >= last_unchanged_pos_old. */
15222 for (; row > first_text_row; --row)
15223 {
15224 /* This used to abort, but it can happen.
15225 It is ok to just stop the search instead here. KFS. */
15226 if (!row->enabled_p || !MATRIX_ROW_DISPLAYS_TEXT_P (row))
15227 break;
15228
15229 if (MATRIX_ROW_START_CHARPOS (row) >= last_unchanged_pos_old)
15230 row_found = row;
15231 }
15232 }
15233
15234 eassert (!row_found || MATRIX_ROW_DISPLAYS_TEXT_P (row_found));
15235
15236 return row_found;
15237 }
15238
15239
15240 /* Make sure that glyph rows in the current matrix of window W
15241 reference the same glyph memory as corresponding rows in the
15242 frame's frame matrix. This function is called after scrolling W's
15243 current matrix on a terminal frame in try_window_id and
15244 try_window_reusing_current_matrix. */
15245
15246 static void
15247 sync_frame_with_window_matrix_rows (struct window *w)
15248 {
15249 struct frame *f = XFRAME (w->frame);
15250 struct glyph_row *window_row, *window_row_end, *frame_row;
15251
15252 /* Preconditions: W must be a leaf window and full-width. Its frame
15253 must have a frame matrix. */
15254 xassert (NILP (w->hchild) && NILP (w->vchild));
15255 xassert (WINDOW_FULL_WIDTH_P (w));
15256 xassert (!FRAME_WINDOW_P (f));
15257
15258 /* If W is a full-width window, glyph pointers in W's current matrix
15259 have, by definition, to be the same as glyph pointers in the
15260 corresponding frame matrix. Note that frame matrices have no
15261 marginal areas (see build_frame_matrix). */
15262 window_row = w->current_matrix->rows;
15263 window_row_end = window_row + w->current_matrix->nrows;
15264 frame_row = f->current_matrix->rows + WINDOW_TOP_EDGE_LINE (w);
15265 while (window_row < window_row_end)
15266 {
15267 struct glyph *start = window_row->glyphs[LEFT_MARGIN_AREA];
15268 struct glyph *end = window_row->glyphs[LAST_AREA];
15269
15270 frame_row->glyphs[LEFT_MARGIN_AREA] = start;
15271 frame_row->glyphs[TEXT_AREA] = start;
15272 frame_row->glyphs[RIGHT_MARGIN_AREA] = end;
15273 frame_row->glyphs[LAST_AREA] = end;
15274
15275 /* Disable frame rows whose corresponding window rows have
15276 been disabled in try_window_id. */
15277 if (!window_row->enabled_p)
15278 frame_row->enabled_p = 0;
15279
15280 ++window_row, ++frame_row;
15281 }
15282 }
15283
15284
15285 /* Find the glyph row in window W containing CHARPOS. Consider all
15286 rows between START and END (not inclusive). END null means search
15287 all rows to the end of the display area of W. Value is the row
15288 containing CHARPOS or null. */
15289
15290 struct glyph_row *
15291 row_containing_pos (struct window *w, int charpos, struct glyph_row *start,
15292 struct glyph_row *end, int dy)
15293 {
15294 struct glyph_row *row = start;
15295 struct glyph_row *best_row = NULL;
15296 EMACS_INT mindif = BUF_ZV (XBUFFER (w->buffer)) + 1;
15297 int last_y;
15298
15299 /* If we happen to start on a header-line, skip that. */
15300 if (row->mode_line_p)
15301 ++row;
15302
15303 if ((end && row >= end) || !row->enabled_p)
15304 return NULL;
15305
15306 last_y = window_text_bottom_y (w) - dy;
15307
15308 while (1)
15309 {
15310 /* Give up if we have gone too far. */
15311 if (end && row >= end)
15312 return NULL;
15313 /* This formerly returned if they were equal.
15314 I think that both quantities are of a "last plus one" type;
15315 if so, when they are equal, the row is within the screen. -- rms. */
15316 if (MATRIX_ROW_BOTTOM_Y (row) > last_y)
15317 return NULL;
15318
15319 /* If it is in this row, return this row. */
15320 if (! (MATRIX_ROW_END_CHARPOS (row) < charpos
15321 || (MATRIX_ROW_END_CHARPOS (row) == charpos
15322 /* The end position of a row equals the start
15323 position of the next row. If CHARPOS is there, we
15324 would rather display it in the next line, except
15325 when this line ends in ZV. */
15326 && !row->ends_at_zv_p
15327 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
15328 && charpos >= MATRIX_ROW_START_CHARPOS (row))
15329 {
15330 struct glyph *g;
15331
15332 if (NILP (XBUFFER (w->buffer)->bidi_display_reordering)
15333 || (!best_row && !row->continued_p))
15334 return row;
15335 /* In bidi-reordered rows, there could be several rows
15336 occluding point, all of them belonging to the same
15337 continued line. We need to find the row which fits
15338 CHARPOS the best. */
15339 for (g = row->glyphs[TEXT_AREA];
15340 g < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
15341 g++)
15342 {
15343 if (!STRINGP (g->object))
15344 {
15345 if (g->charpos > 0 && eabs (g->charpos - charpos) < mindif)
15346 {
15347 mindif = eabs (g->charpos - charpos);
15348 best_row = row;
15349 /* Exact match always wins. */
15350 if (mindif == 0)
15351 return best_row;
15352 }
15353 }
15354 }
15355 }
15356 else if (best_row && !row->continued_p)
15357 return best_row;
15358 ++row;
15359 }
15360 }
15361
15362
15363 /* Try to redisplay window W by reusing its existing display. W's
15364 current matrix must be up to date when this function is called,
15365 i.e. window_end_valid must not be nil.
15366
15367 Value is
15368
15369 1 if display has been updated
15370 0 if otherwise unsuccessful
15371 -1 if redisplay with same window start is known not to succeed
15372
15373 The following steps are performed:
15374
15375 1. Find the last row in the current matrix of W that is not
15376 affected by changes at the start of current_buffer. If no such row
15377 is found, give up.
15378
15379 2. Find the first row in W's current matrix that is not affected by
15380 changes at the end of current_buffer. Maybe there is no such row.
15381
15382 3. Display lines beginning with the row + 1 found in step 1 to the
15383 row found in step 2 or, if step 2 didn't find a row, to the end of
15384 the window.
15385
15386 4. If cursor is not known to appear on the window, give up.
15387
15388 5. If display stopped at the row found in step 2, scroll the
15389 display and current matrix as needed.
15390
15391 6. Maybe display some lines at the end of W, if we must. This can
15392 happen under various circumstances, like a partially visible line
15393 becoming fully visible, or because newly displayed lines are displayed
15394 in smaller font sizes.
15395
15396 7. Update W's window end information. */
15397
15398 static int
15399 try_window_id (struct window *w)
15400 {
15401 struct frame *f = XFRAME (w->frame);
15402 struct glyph_matrix *current_matrix = w->current_matrix;
15403 struct glyph_matrix *desired_matrix = w->desired_matrix;
15404 struct glyph_row *last_unchanged_at_beg_row;
15405 struct glyph_row *first_unchanged_at_end_row;
15406 struct glyph_row *row;
15407 struct glyph_row *bottom_row;
15408 int bottom_vpos;
15409 struct it it;
15410 int delta = 0, delta_bytes = 0, stop_pos, dvpos, dy;
15411 struct text_pos start_pos;
15412 struct run run;
15413 int first_unchanged_at_end_vpos = 0;
15414 struct glyph_row *last_text_row, *last_text_row_at_end;
15415 struct text_pos start;
15416 int first_changed_charpos, last_changed_charpos;
15417
15418 #if GLYPH_DEBUG
15419 if (inhibit_try_window_id)
15420 return 0;
15421 #endif
15422
15423 /* This is handy for debugging. */
15424 #if 0
15425 #define GIVE_UP(X) \
15426 do { \
15427 fprintf (stderr, "try_window_id give up %d\n", (X)); \
15428 return 0; \
15429 } while (0)
15430 #else
15431 #define GIVE_UP(X) return 0
15432 #endif
15433
15434 SET_TEXT_POS_FROM_MARKER (start, w->start);
15435
15436 /* Don't use this for mini-windows because these can show
15437 messages and mini-buffers, and we don't handle that here. */
15438 if (MINI_WINDOW_P (w))
15439 GIVE_UP (1);
15440
15441 /* This flag is used to prevent redisplay optimizations. */
15442 if (windows_or_buffers_changed || cursor_type_changed)
15443 GIVE_UP (2);
15444
15445 /* Verify that narrowing has not changed.
15446 Also verify that we were not told to prevent redisplay optimizations.
15447 It would be nice to further
15448 reduce the number of cases where this prevents try_window_id. */
15449 if (current_buffer->clip_changed
15450 || current_buffer->prevent_redisplay_optimizations_p)
15451 GIVE_UP (3);
15452
15453 /* Window must either use window-based redisplay or be full width. */
15454 if (!FRAME_WINDOW_P (f)
15455 && (!FRAME_LINE_INS_DEL_OK (f)
15456 || !WINDOW_FULL_WIDTH_P (w)))
15457 GIVE_UP (4);
15458
15459 /* Give up if point is known NOT to appear in W. */
15460 if (PT < CHARPOS (start))
15461 GIVE_UP (5);
15462
15463 /* Another way to prevent redisplay optimizations. */
15464 if (XFASTINT (w->last_modified) == 0)
15465 GIVE_UP (6);
15466
15467 /* Verify that window is not hscrolled. */
15468 if (XFASTINT (w->hscroll) != 0)
15469 GIVE_UP (7);
15470
15471 /* Verify that display wasn't paused. */
15472 if (NILP (w->window_end_valid))
15473 GIVE_UP (8);
15474
15475 /* Can't use this if highlighting a region because a cursor movement
15476 will do more than just set the cursor. */
15477 if (!NILP (Vtransient_mark_mode)
15478 && !NILP (current_buffer->mark_active))
15479 GIVE_UP (9);
15480
15481 /* Likewise if highlighting trailing whitespace. */
15482 if (!NILP (Vshow_trailing_whitespace))
15483 GIVE_UP (11);
15484
15485 /* Likewise if showing a region. */
15486 if (!NILP (w->region_showing))
15487 GIVE_UP (10);
15488
15489 /* Can't use this if overlay arrow position and/or string have
15490 changed. */
15491 if (overlay_arrows_changed_p ())
15492 GIVE_UP (12);
15493
15494 /* When word-wrap is on, adding a space to the first word of a
15495 wrapped line can change the wrap position, altering the line
15496 above it. It might be worthwhile to handle this more
15497 intelligently, but for now just redisplay from scratch. */
15498 if (!NILP (XBUFFER (w->buffer)->word_wrap))
15499 GIVE_UP (21);
15500
15501 /* Under bidi reordering, adding or deleting a character in the
15502 beginning of a paragraph, before the first strong directional
15503 character, can change the base direction of the paragraph (unless
15504 the buffer specifies a fixed paragraph direction), which will
15505 require to redisplay the whole paragraph. It might be worthwhile
15506 to find the paragraph limits and widen the range of redisplayed
15507 lines to that, but for now just give up this optimization and
15508 redisplay from scratch. */
15509 if (!NILP (XBUFFER (w->buffer)->bidi_display_reordering)
15510 && NILP (XBUFFER (w->buffer)->bidi_paragraph_direction))
15511 GIVE_UP (22);
15512
15513 /* Make sure beg_unchanged and end_unchanged are up to date. Do it
15514 only if buffer has really changed. The reason is that the gap is
15515 initially at Z for freshly visited files. The code below would
15516 set end_unchanged to 0 in that case. */
15517 if (MODIFF > SAVE_MODIFF
15518 /* This seems to happen sometimes after saving a buffer. */
15519 || BEG_UNCHANGED + END_UNCHANGED > Z_BYTE)
15520 {
15521 if (GPT - BEG < BEG_UNCHANGED)
15522 BEG_UNCHANGED = GPT - BEG;
15523 if (Z - GPT < END_UNCHANGED)
15524 END_UNCHANGED = Z - GPT;
15525 }
15526
15527 /* The position of the first and last character that has been changed. */
15528 first_changed_charpos = BEG + BEG_UNCHANGED;
15529 last_changed_charpos = Z - END_UNCHANGED;
15530
15531 /* If window starts after a line end, and the last change is in
15532 front of that newline, then changes don't affect the display.
15533 This case happens with stealth-fontification. Note that although
15534 the display is unchanged, glyph positions in the matrix have to
15535 be adjusted, of course. */
15536 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
15537 if (MATRIX_ROW_DISPLAYS_TEXT_P (row)
15538 && ((last_changed_charpos < CHARPOS (start)
15539 && CHARPOS (start) == BEGV)
15540 || (last_changed_charpos < CHARPOS (start) - 1
15541 && FETCH_BYTE (BYTEPOS (start) - 1) == '\n')))
15542 {
15543 int Z_old, delta, Z_BYTE_old, delta_bytes;
15544 struct glyph_row *r0;
15545
15546 /* Compute how many chars/bytes have been added to or removed
15547 from the buffer. */
15548 Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
15549 Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
15550 delta = Z - Z_old;
15551 delta_bytes = Z_BYTE - Z_BYTE_old;
15552
15553 /* Give up if PT is not in the window. Note that it already has
15554 been checked at the start of try_window_id that PT is not in
15555 front of the window start. */
15556 if (PT >= MATRIX_ROW_END_CHARPOS (row) + delta)
15557 GIVE_UP (13);
15558
15559 /* If window start is unchanged, we can reuse the whole matrix
15560 as is, after adjusting glyph positions. No need to compute
15561 the window end again, since its offset from Z hasn't changed. */
15562 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
15563 if (CHARPOS (start) == MATRIX_ROW_START_CHARPOS (r0) + delta
15564 && BYTEPOS (start) == MATRIX_ROW_START_BYTEPOS (r0) + delta_bytes
15565 /* PT must not be in a partially visible line. */
15566 && !(PT >= MATRIX_ROW_START_CHARPOS (row) + delta
15567 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
15568 {
15569 /* Adjust positions in the glyph matrix. */
15570 if (delta || delta_bytes)
15571 {
15572 struct glyph_row *r1
15573 = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
15574 increment_matrix_positions (w->current_matrix,
15575 MATRIX_ROW_VPOS (r0, current_matrix),
15576 MATRIX_ROW_VPOS (r1, current_matrix),
15577 delta, delta_bytes);
15578 }
15579
15580 /* Set the cursor. */
15581 row = row_containing_pos (w, PT, r0, NULL, 0);
15582 if (row)
15583 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
15584 else
15585 abort ();
15586 return 1;
15587 }
15588 }
15589
15590 /* Handle the case that changes are all below what is displayed in
15591 the window, and that PT is in the window. This shortcut cannot
15592 be taken if ZV is visible in the window, and text has been added
15593 there that is visible in the window. */
15594 if (first_changed_charpos >= MATRIX_ROW_END_CHARPOS (row)
15595 /* ZV is not visible in the window, or there are no
15596 changes at ZV, actually. */
15597 && (current_matrix->zv > MATRIX_ROW_END_CHARPOS (row)
15598 || first_changed_charpos == last_changed_charpos))
15599 {
15600 struct glyph_row *r0;
15601
15602 /* Give up if PT is not in the window. Note that it already has
15603 been checked at the start of try_window_id that PT is not in
15604 front of the window start. */
15605 if (PT >= MATRIX_ROW_END_CHARPOS (row))
15606 GIVE_UP (14);
15607
15608 /* If window start is unchanged, we can reuse the whole matrix
15609 as is, without changing glyph positions since no text has
15610 been added/removed in front of the window end. */
15611 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
15612 if (TEXT_POS_EQUAL_P (start, r0->minpos)
15613 /* PT must not be in a partially visible line. */
15614 && !(PT >= MATRIX_ROW_START_CHARPOS (row)
15615 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
15616 {
15617 /* We have to compute the window end anew since text
15618 could have been added/removed after it. */
15619 w->window_end_pos
15620 = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
15621 w->window_end_bytepos
15622 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
15623
15624 /* Set the cursor. */
15625 row = row_containing_pos (w, PT, r0, NULL, 0);
15626 if (row)
15627 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
15628 else
15629 abort ();
15630 return 2;
15631 }
15632 }
15633
15634 /* Give up if window start is in the changed area.
15635
15636 The condition used to read
15637
15638 (BEG_UNCHANGED + END_UNCHANGED != Z - BEG && ...)
15639
15640 but why that was tested escapes me at the moment. */
15641 if (CHARPOS (start) >= first_changed_charpos
15642 && CHARPOS (start) <= last_changed_charpos)
15643 GIVE_UP (15);
15644
15645 /* Check that window start agrees with the start of the first glyph
15646 row in its current matrix. Check this after we know the window
15647 start is not in changed text, otherwise positions would not be
15648 comparable. */
15649 row = MATRIX_FIRST_TEXT_ROW (current_matrix);
15650 if (!TEXT_POS_EQUAL_P (start, row->minpos))
15651 GIVE_UP (16);
15652
15653 /* Give up if the window ends in strings. Overlay strings
15654 at the end are difficult to handle, so don't try. */
15655 row = MATRIX_ROW (current_matrix, XFASTINT (w->window_end_vpos));
15656 if (MATRIX_ROW_START_CHARPOS (row) == MATRIX_ROW_END_CHARPOS (row))
15657 GIVE_UP (20);
15658
15659 /* Compute the position at which we have to start displaying new
15660 lines. Some of the lines at the top of the window might be
15661 reusable because they are not displaying changed text. Find the
15662 last row in W's current matrix not affected by changes at the
15663 start of current_buffer. Value is null if changes start in the
15664 first line of window. */
15665 last_unchanged_at_beg_row = find_last_unchanged_at_beg_row (w);
15666 if (last_unchanged_at_beg_row)
15667 {
15668 /* Avoid starting to display in the moddle of a character, a TAB
15669 for instance. This is easier than to set up the iterator
15670 exactly, and it's not a frequent case, so the additional
15671 effort wouldn't really pay off. */
15672 while ((MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row)
15673 || last_unchanged_at_beg_row->ends_in_newline_from_string_p)
15674 && last_unchanged_at_beg_row > w->current_matrix->rows)
15675 --last_unchanged_at_beg_row;
15676
15677 if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row))
15678 GIVE_UP (17);
15679
15680 if (init_to_row_end (&it, w, last_unchanged_at_beg_row) == 0)
15681 GIVE_UP (18);
15682 start_pos = it.current.pos;
15683
15684 /* Start displaying new lines in the desired matrix at the same
15685 vpos we would use in the current matrix, i.e. below
15686 last_unchanged_at_beg_row. */
15687 it.vpos = 1 + MATRIX_ROW_VPOS (last_unchanged_at_beg_row,
15688 current_matrix);
15689 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
15690 it.current_y = MATRIX_ROW_BOTTOM_Y (last_unchanged_at_beg_row);
15691
15692 xassert (it.hpos == 0 && it.current_x == 0);
15693 }
15694 else
15695 {
15696 /* There are no reusable lines at the start of the window.
15697 Start displaying in the first text line. */
15698 start_display (&it, w, start);
15699 it.vpos = it.first_vpos;
15700 start_pos = it.current.pos;
15701 }
15702
15703 /* Find the first row that is not affected by changes at the end of
15704 the buffer. Value will be null if there is no unchanged row, in
15705 which case we must redisplay to the end of the window. delta
15706 will be set to the value by which buffer positions beginning with
15707 first_unchanged_at_end_row have to be adjusted due to text
15708 changes. */
15709 first_unchanged_at_end_row
15710 = find_first_unchanged_at_end_row (w, &delta, &delta_bytes);
15711 IF_DEBUG (debug_delta = delta);
15712 IF_DEBUG (debug_delta_bytes = delta_bytes);
15713
15714 /* Set stop_pos to the buffer position up to which we will have to
15715 display new lines. If first_unchanged_at_end_row != NULL, this
15716 is the buffer position of the start of the line displayed in that
15717 row. For first_unchanged_at_end_row == NULL, use 0 to indicate
15718 that we don't stop at a buffer position. */
15719 stop_pos = 0;
15720 if (first_unchanged_at_end_row)
15721 {
15722 xassert (last_unchanged_at_beg_row == NULL
15723 || first_unchanged_at_end_row >= last_unchanged_at_beg_row);
15724
15725 /* If this is a continuation line, move forward to the next one
15726 that isn't. Changes in lines above affect this line.
15727 Caution: this may move first_unchanged_at_end_row to a row
15728 not displaying text. */
15729 while (MATRIX_ROW_CONTINUATION_LINE_P (first_unchanged_at_end_row)
15730 && MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
15731 && (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
15732 < it.last_visible_y))
15733 ++first_unchanged_at_end_row;
15734
15735 if (!MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
15736 || (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
15737 >= it.last_visible_y))
15738 first_unchanged_at_end_row = NULL;
15739 else
15740 {
15741 stop_pos = (MATRIX_ROW_START_CHARPOS (first_unchanged_at_end_row)
15742 + delta);
15743 first_unchanged_at_end_vpos
15744 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, current_matrix);
15745 xassert (stop_pos >= Z - END_UNCHANGED);
15746 }
15747 }
15748 else if (last_unchanged_at_beg_row == NULL)
15749 GIVE_UP (19);
15750
15751
15752 #if GLYPH_DEBUG
15753
15754 /* Either there is no unchanged row at the end, or the one we have
15755 now displays text. This is a necessary condition for the window
15756 end pos calculation at the end of this function. */
15757 xassert (first_unchanged_at_end_row == NULL
15758 || MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
15759
15760 debug_last_unchanged_at_beg_vpos
15761 = (last_unchanged_at_beg_row
15762 ? MATRIX_ROW_VPOS (last_unchanged_at_beg_row, current_matrix)
15763 : -1);
15764 debug_first_unchanged_at_end_vpos = first_unchanged_at_end_vpos;
15765
15766 #endif /* GLYPH_DEBUG != 0 */
15767
15768
15769 /* Display new lines. Set last_text_row to the last new line
15770 displayed which has text on it, i.e. might end up as being the
15771 line where the window_end_vpos is. */
15772 w->cursor.vpos = -1;
15773 last_text_row = NULL;
15774 overlay_arrow_seen = 0;
15775 while (it.current_y < it.last_visible_y
15776 && !fonts_changed_p
15777 && (first_unchanged_at_end_row == NULL
15778 || IT_CHARPOS (it) < stop_pos))
15779 {
15780 if (display_line (&it))
15781 last_text_row = it.glyph_row - 1;
15782 }
15783
15784 if (fonts_changed_p)
15785 return -1;
15786
15787
15788 /* Compute differences in buffer positions, y-positions etc. for
15789 lines reused at the bottom of the window. Compute what we can
15790 scroll. */
15791 if (first_unchanged_at_end_row
15792 /* No lines reused because we displayed everything up to the
15793 bottom of the window. */
15794 && it.current_y < it.last_visible_y)
15795 {
15796 dvpos = (it.vpos
15797 - MATRIX_ROW_VPOS (first_unchanged_at_end_row,
15798 current_matrix));
15799 dy = it.current_y - first_unchanged_at_end_row->y;
15800 run.current_y = first_unchanged_at_end_row->y;
15801 run.desired_y = run.current_y + dy;
15802 run.height = it.last_visible_y - max (run.current_y, run.desired_y);
15803 }
15804 else
15805 {
15806 delta = delta_bytes = dvpos = dy
15807 = run.current_y = run.desired_y = run.height = 0;
15808 first_unchanged_at_end_row = NULL;
15809 }
15810 IF_DEBUG (debug_dvpos = dvpos; debug_dy = dy);
15811
15812
15813 /* Find the cursor if not already found. We have to decide whether
15814 PT will appear on this window (it sometimes doesn't, but this is
15815 not a very frequent case.) This decision has to be made before
15816 the current matrix is altered. A value of cursor.vpos < 0 means
15817 that PT is either in one of the lines beginning at
15818 first_unchanged_at_end_row or below the window. Don't care for
15819 lines that might be displayed later at the window end; as
15820 mentioned, this is not a frequent case. */
15821 if (w->cursor.vpos < 0)
15822 {
15823 /* Cursor in unchanged rows at the top? */
15824 if (PT < CHARPOS (start_pos)
15825 && last_unchanged_at_beg_row)
15826 {
15827 row = row_containing_pos (w, PT,
15828 MATRIX_FIRST_TEXT_ROW (w->current_matrix),
15829 last_unchanged_at_beg_row + 1, 0);
15830 if (row)
15831 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
15832 }
15833
15834 /* Start from first_unchanged_at_end_row looking for PT. */
15835 else if (first_unchanged_at_end_row)
15836 {
15837 row = row_containing_pos (w, PT - delta,
15838 first_unchanged_at_end_row, NULL, 0);
15839 if (row)
15840 set_cursor_from_row (w, row, w->current_matrix, delta,
15841 delta_bytes, dy, dvpos);
15842 }
15843
15844 /* Give up if cursor was not found. */
15845 if (w->cursor.vpos < 0)
15846 {
15847 clear_glyph_matrix (w->desired_matrix);
15848 return -1;
15849 }
15850 }
15851
15852 /* Don't let the cursor end in the scroll margins. */
15853 {
15854 int this_scroll_margin, cursor_height;
15855
15856 this_scroll_margin = max (0, scroll_margin);
15857 this_scroll_margin = min (this_scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
15858 this_scroll_margin *= FRAME_LINE_HEIGHT (it.f);
15859 cursor_height = MATRIX_ROW (w->desired_matrix, w->cursor.vpos)->height;
15860
15861 if ((w->cursor.y < this_scroll_margin
15862 && CHARPOS (start) > BEGV)
15863 /* Old redisplay didn't take scroll margin into account at the bottom,
15864 but then global-hl-line-mode doesn't scroll. KFS 2004-06-14 */
15865 || (w->cursor.y + (make_cursor_line_fully_visible_p
15866 ? cursor_height + this_scroll_margin
15867 : 1)) > it.last_visible_y)
15868 {
15869 w->cursor.vpos = -1;
15870 clear_glyph_matrix (w->desired_matrix);
15871 return -1;
15872 }
15873 }
15874
15875 /* Scroll the display. Do it before changing the current matrix so
15876 that xterm.c doesn't get confused about where the cursor glyph is
15877 found. */
15878 if (dy && run.height)
15879 {
15880 update_begin (f);
15881
15882 if (FRAME_WINDOW_P (f))
15883 {
15884 FRAME_RIF (f)->update_window_begin_hook (w);
15885 FRAME_RIF (f)->clear_window_mouse_face (w);
15886 FRAME_RIF (f)->scroll_run_hook (w, &run);
15887 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
15888 }
15889 else
15890 {
15891 /* Terminal frame. In this case, dvpos gives the number of
15892 lines to scroll by; dvpos < 0 means scroll up. */
15893 int first_unchanged_at_end_vpos
15894 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, w->current_matrix);
15895 int from = WINDOW_TOP_EDGE_LINE (w) + first_unchanged_at_end_vpos;
15896 int end = (WINDOW_TOP_EDGE_LINE (w)
15897 + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0)
15898 + window_internal_height (w));
15899
15900 /* Perform the operation on the screen. */
15901 if (dvpos > 0)
15902 {
15903 /* Scroll last_unchanged_at_beg_row to the end of the
15904 window down dvpos lines. */
15905 set_terminal_window (f, end);
15906
15907 /* On dumb terminals delete dvpos lines at the end
15908 before inserting dvpos empty lines. */
15909 if (!FRAME_SCROLL_REGION_OK (f))
15910 ins_del_lines (f, end - dvpos, -dvpos);
15911
15912 /* Insert dvpos empty lines in front of
15913 last_unchanged_at_beg_row. */
15914 ins_del_lines (f, from, dvpos);
15915 }
15916 else if (dvpos < 0)
15917 {
15918 /* Scroll up last_unchanged_at_beg_vpos to the end of
15919 the window to last_unchanged_at_beg_vpos - |dvpos|. */
15920 set_terminal_window (f, end);
15921
15922 /* Delete dvpos lines in front of
15923 last_unchanged_at_beg_vpos. ins_del_lines will set
15924 the cursor to the given vpos and emit |dvpos| delete
15925 line sequences. */
15926 ins_del_lines (f, from + dvpos, dvpos);
15927
15928 /* On a dumb terminal insert dvpos empty lines at the
15929 end. */
15930 if (!FRAME_SCROLL_REGION_OK (f))
15931 ins_del_lines (f, end + dvpos, -dvpos);
15932 }
15933
15934 set_terminal_window (f, 0);
15935 }
15936
15937 update_end (f);
15938 }
15939
15940 /* Shift reused rows of the current matrix to the right position.
15941 BOTTOM_ROW is the last + 1 row in the current matrix reserved for
15942 text. */
15943 bottom_row = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
15944 bottom_vpos = MATRIX_ROW_VPOS (bottom_row, current_matrix);
15945 if (dvpos < 0)
15946 {
15947 rotate_matrix (current_matrix, first_unchanged_at_end_vpos + dvpos,
15948 bottom_vpos, dvpos);
15949 enable_glyph_matrix_rows (current_matrix, bottom_vpos + dvpos,
15950 bottom_vpos, 0);
15951 }
15952 else if (dvpos > 0)
15953 {
15954 rotate_matrix (current_matrix, first_unchanged_at_end_vpos,
15955 bottom_vpos, dvpos);
15956 enable_glyph_matrix_rows (current_matrix, first_unchanged_at_end_vpos,
15957 first_unchanged_at_end_vpos + dvpos, 0);
15958 }
15959
15960 /* For frame-based redisplay, make sure that current frame and window
15961 matrix are in sync with respect to glyph memory. */
15962 if (!FRAME_WINDOW_P (f))
15963 sync_frame_with_window_matrix_rows (w);
15964
15965 /* Adjust buffer positions in reused rows. */
15966 if (delta || delta_bytes)
15967 increment_matrix_positions (current_matrix,
15968 first_unchanged_at_end_vpos + dvpos,
15969 bottom_vpos, delta, delta_bytes);
15970
15971 /* Adjust Y positions. */
15972 if (dy)
15973 shift_glyph_matrix (w, current_matrix,
15974 first_unchanged_at_end_vpos + dvpos,
15975 bottom_vpos, dy);
15976
15977 if (first_unchanged_at_end_row)
15978 {
15979 first_unchanged_at_end_row += dvpos;
15980 if (first_unchanged_at_end_row->y >= it.last_visible_y
15981 || !MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row))
15982 first_unchanged_at_end_row = NULL;
15983 }
15984
15985 /* If scrolling up, there may be some lines to display at the end of
15986 the window. */
15987 last_text_row_at_end = NULL;
15988 if (dy < 0)
15989 {
15990 /* Scrolling up can leave for example a partially visible line
15991 at the end of the window to be redisplayed. */
15992 /* Set last_row to the glyph row in the current matrix where the
15993 window end line is found. It has been moved up or down in
15994 the matrix by dvpos. */
15995 int last_vpos = XFASTINT (w->window_end_vpos) + dvpos;
15996 struct glyph_row *last_row = MATRIX_ROW (current_matrix, last_vpos);
15997
15998 /* If last_row is the window end line, it should display text. */
15999 xassert (last_row->displays_text_p);
16000
16001 /* If window end line was partially visible before, begin
16002 displaying at that line. Otherwise begin displaying with the
16003 line following it. */
16004 if (MATRIX_ROW_BOTTOM_Y (last_row) - dy >= it.last_visible_y)
16005 {
16006 init_to_row_start (&it, w, last_row);
16007 it.vpos = last_vpos;
16008 it.current_y = last_row->y;
16009 }
16010 else
16011 {
16012 init_to_row_end (&it, w, last_row);
16013 it.vpos = 1 + last_vpos;
16014 it.current_y = MATRIX_ROW_BOTTOM_Y (last_row);
16015 ++last_row;
16016 }
16017
16018 /* We may start in a continuation line. If so, we have to
16019 get the right continuation_lines_width and current_x. */
16020 it.continuation_lines_width = last_row->continuation_lines_width;
16021 it.hpos = it.current_x = 0;
16022
16023 /* Display the rest of the lines at the window end. */
16024 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
16025 while (it.current_y < it.last_visible_y
16026 && !fonts_changed_p)
16027 {
16028 /* Is it always sure that the display agrees with lines in
16029 the current matrix? I don't think so, so we mark rows
16030 displayed invalid in the current matrix by setting their
16031 enabled_p flag to zero. */
16032 MATRIX_ROW (w->current_matrix, it.vpos)->enabled_p = 0;
16033 if (display_line (&it))
16034 last_text_row_at_end = it.glyph_row - 1;
16035 }
16036 }
16037
16038 /* Update window_end_pos and window_end_vpos. */
16039 if (first_unchanged_at_end_row
16040 && !last_text_row_at_end)
16041 {
16042 /* Window end line if one of the preserved rows from the current
16043 matrix. Set row to the last row displaying text in current
16044 matrix starting at first_unchanged_at_end_row, after
16045 scrolling. */
16046 xassert (first_unchanged_at_end_row->displays_text_p);
16047 row = find_last_row_displaying_text (w->current_matrix, &it,
16048 first_unchanged_at_end_row);
16049 xassert (row && MATRIX_ROW_DISPLAYS_TEXT_P (row));
16050
16051 w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
16052 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
16053 w->window_end_vpos
16054 = make_number (MATRIX_ROW_VPOS (row, w->current_matrix));
16055 xassert (w->window_end_bytepos >= 0);
16056 IF_DEBUG (debug_method_add (w, "A"));
16057 }
16058 else if (last_text_row_at_end)
16059 {
16060 w->window_end_pos
16061 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row_at_end));
16062 w->window_end_bytepos
16063 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row_at_end);
16064 w->window_end_vpos
16065 = make_number (MATRIX_ROW_VPOS (last_text_row_at_end, desired_matrix));
16066 xassert (w->window_end_bytepos >= 0);
16067 IF_DEBUG (debug_method_add (w, "B"));
16068 }
16069 else if (last_text_row)
16070 {
16071 /* We have displayed either to the end of the window or at the
16072 end of the window, i.e. the last row with text is to be found
16073 in the desired matrix. */
16074 w->window_end_pos
16075 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
16076 w->window_end_bytepos
16077 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
16078 w->window_end_vpos
16079 = make_number (MATRIX_ROW_VPOS (last_text_row, desired_matrix));
16080 xassert (w->window_end_bytepos >= 0);
16081 }
16082 else if (first_unchanged_at_end_row == NULL
16083 && last_text_row == NULL
16084 && last_text_row_at_end == NULL)
16085 {
16086 /* Displayed to end of window, but no line containing text was
16087 displayed. Lines were deleted at the end of the window. */
16088 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
16089 int vpos = XFASTINT (w->window_end_vpos);
16090 struct glyph_row *current_row = current_matrix->rows + vpos;
16091 struct glyph_row *desired_row = desired_matrix->rows + vpos;
16092
16093 for (row = NULL;
16094 row == NULL && vpos >= first_vpos;
16095 --vpos, --current_row, --desired_row)
16096 {
16097 if (desired_row->enabled_p)
16098 {
16099 if (desired_row->displays_text_p)
16100 row = desired_row;
16101 }
16102 else if (current_row->displays_text_p)
16103 row = current_row;
16104 }
16105
16106 xassert (row != NULL);
16107 w->window_end_vpos = make_number (vpos + 1);
16108 w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
16109 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
16110 xassert (w->window_end_bytepos >= 0);
16111 IF_DEBUG (debug_method_add (w, "C"));
16112 }
16113 else
16114 abort ();
16115
16116 IF_DEBUG (debug_end_pos = XFASTINT (w->window_end_pos);
16117 debug_end_vpos = XFASTINT (w->window_end_vpos));
16118
16119 /* Record that display has not been completed. */
16120 w->window_end_valid = Qnil;
16121 w->desired_matrix->no_scrolling_p = 1;
16122 return 3;
16123
16124 #undef GIVE_UP
16125 }
16126
16127
16128 \f
16129 /***********************************************************************
16130 More debugging support
16131 ***********************************************************************/
16132
16133 #if GLYPH_DEBUG
16134
16135 void dump_glyph_row (struct glyph_row *, int, int);
16136 void dump_glyph_matrix (struct glyph_matrix *, int);
16137 void dump_glyph (struct glyph_row *, struct glyph *, int);
16138
16139
16140 /* Dump the contents of glyph matrix MATRIX on stderr.
16141
16142 GLYPHS 0 means don't show glyph contents.
16143 GLYPHS 1 means show glyphs in short form
16144 GLYPHS > 1 means show glyphs in long form. */
16145
16146 void
16147 dump_glyph_matrix (matrix, glyphs)
16148 struct glyph_matrix *matrix;
16149 int glyphs;
16150 {
16151 int i;
16152 for (i = 0; i < matrix->nrows; ++i)
16153 dump_glyph_row (MATRIX_ROW (matrix, i), i, glyphs);
16154 }
16155
16156
16157 /* Dump contents of glyph GLYPH to stderr. ROW and AREA are
16158 the glyph row and area where the glyph comes from. */
16159
16160 void
16161 dump_glyph (row, glyph, area)
16162 struct glyph_row *row;
16163 struct glyph *glyph;
16164 int area;
16165 {
16166 if (glyph->type == CHAR_GLYPH)
16167 {
16168 fprintf (stderr,
16169 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
16170 glyph - row->glyphs[TEXT_AREA],
16171 'C',
16172 glyph->charpos,
16173 (BUFFERP (glyph->object)
16174 ? 'B'
16175 : (STRINGP (glyph->object)
16176 ? 'S'
16177 : '-')),
16178 glyph->pixel_width,
16179 glyph->u.ch,
16180 (glyph->u.ch < 0x80 && glyph->u.ch >= ' '
16181 ? glyph->u.ch
16182 : '.'),
16183 glyph->face_id,
16184 glyph->left_box_line_p,
16185 glyph->right_box_line_p);
16186 }
16187 else if (glyph->type == STRETCH_GLYPH)
16188 {
16189 fprintf (stderr,
16190 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
16191 glyph - row->glyphs[TEXT_AREA],
16192 'S',
16193 glyph->charpos,
16194 (BUFFERP (glyph->object)
16195 ? 'B'
16196 : (STRINGP (glyph->object)
16197 ? 'S'
16198 : '-')),
16199 glyph->pixel_width,
16200 0,
16201 '.',
16202 glyph->face_id,
16203 glyph->left_box_line_p,
16204 glyph->right_box_line_p);
16205 }
16206 else if (glyph->type == IMAGE_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 'I',
16212 glyph->charpos,
16213 (BUFFERP (glyph->object)
16214 ? 'B'
16215 : (STRINGP (glyph->object)
16216 ? 'S'
16217 : '-')),
16218 glyph->pixel_width,
16219 glyph->u.img_id,
16220 '.',
16221 glyph->face_id,
16222 glyph->left_box_line_p,
16223 glyph->right_box_line_p);
16224 }
16225 else if (glyph->type == COMPOSITE_GLYPH)
16226 {
16227 fprintf (stderr,
16228 " %5d %4c %6d %c %3d 0x%05x",
16229 glyph - row->glyphs[TEXT_AREA],
16230 '+',
16231 glyph->charpos,
16232 (BUFFERP (glyph->object)
16233 ? 'B'
16234 : (STRINGP (glyph->object)
16235 ? 'S'
16236 : '-')),
16237 glyph->pixel_width,
16238 glyph->u.cmp.id);
16239 if (glyph->u.cmp.automatic)
16240 fprintf (stderr,
16241 "[%d-%d]",
16242 glyph->u.cmp.from, glyph->u.cmp.to);
16243 fprintf (stderr, " . %4d %1.1d%1.1d\n",
16244 glyph->face_id,
16245 glyph->left_box_line_p,
16246 glyph->right_box_line_p);
16247 }
16248 }
16249
16250
16251 /* Dump the contents of glyph row at VPOS in MATRIX to stderr.
16252 GLYPHS 0 means don't show glyph contents.
16253 GLYPHS 1 means show glyphs in short form
16254 GLYPHS > 1 means show glyphs in long form. */
16255
16256 void
16257 dump_glyph_row (row, vpos, glyphs)
16258 struct glyph_row *row;
16259 int vpos, glyphs;
16260 {
16261 if (glyphs != 1)
16262 {
16263 fprintf (stderr, "Row Start End Used oE><\\CTZFesm X Y W H V A P\n");
16264 fprintf (stderr, "======================================================================\n");
16265
16266 fprintf (stderr, "%3d %5d %5d %4d %1.1d%1.1d%1.1d%1.1d\
16267 %1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d %4d %4d %4d %4d %4d %4d %4d\n",
16268 vpos,
16269 MATRIX_ROW_START_CHARPOS (row),
16270 MATRIX_ROW_END_CHARPOS (row),
16271 row->used[TEXT_AREA],
16272 row->contains_overlapping_glyphs_p,
16273 row->enabled_p,
16274 row->truncated_on_left_p,
16275 row->truncated_on_right_p,
16276 row->continued_p,
16277 MATRIX_ROW_CONTINUATION_LINE_P (row),
16278 row->displays_text_p,
16279 row->ends_at_zv_p,
16280 row->fill_line_p,
16281 row->ends_in_middle_of_char_p,
16282 row->starts_in_middle_of_char_p,
16283 row->mouse_face_p,
16284 row->x,
16285 row->y,
16286 row->pixel_width,
16287 row->height,
16288 row->visible_height,
16289 row->ascent,
16290 row->phys_ascent);
16291 fprintf (stderr, "%9d %5d\t%5d\n", row->start.overlay_string_index,
16292 row->end.overlay_string_index,
16293 row->continuation_lines_width);
16294 fprintf (stderr, "%9d %5d\n",
16295 CHARPOS (row->start.string_pos),
16296 CHARPOS (row->end.string_pos));
16297 fprintf (stderr, "%9d %5d\n", row->start.dpvec_index,
16298 row->end.dpvec_index);
16299 }
16300
16301 if (glyphs > 1)
16302 {
16303 int area;
16304
16305 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
16306 {
16307 struct glyph *glyph = row->glyphs[area];
16308 struct glyph *glyph_end = glyph + row->used[area];
16309
16310 /* Glyph for a line end in text. */
16311 if (area == TEXT_AREA && glyph == glyph_end && glyph->charpos > 0)
16312 ++glyph_end;
16313
16314 if (glyph < glyph_end)
16315 fprintf (stderr, " Glyph Type Pos O W Code C Face LR\n");
16316
16317 for (; glyph < glyph_end; ++glyph)
16318 dump_glyph (row, glyph, area);
16319 }
16320 }
16321 else if (glyphs == 1)
16322 {
16323 int area;
16324
16325 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
16326 {
16327 char *s = (char *) alloca (row->used[area] + 1);
16328 int i;
16329
16330 for (i = 0; i < row->used[area]; ++i)
16331 {
16332 struct glyph *glyph = row->glyphs[area] + i;
16333 if (glyph->type == CHAR_GLYPH
16334 && glyph->u.ch < 0x80
16335 && glyph->u.ch >= ' ')
16336 s[i] = glyph->u.ch;
16337 else
16338 s[i] = '.';
16339 }
16340
16341 s[i] = '\0';
16342 fprintf (stderr, "%3d: (%d) '%s'\n", vpos, row->enabled_p, s);
16343 }
16344 }
16345 }
16346
16347
16348 DEFUN ("dump-glyph-matrix", Fdump_glyph_matrix,
16349 Sdump_glyph_matrix, 0, 1, "p",
16350 doc: /* Dump the current matrix of the selected window to stderr.
16351 Shows contents of glyph row structures. With non-nil
16352 parameter GLYPHS, dump glyphs as well. If GLYPHS is 1 show
16353 glyphs in short form, otherwise show glyphs in long form. */)
16354 (Lisp_Object glyphs)
16355 {
16356 struct window *w = XWINDOW (selected_window);
16357 struct buffer *buffer = XBUFFER (w->buffer);
16358
16359 fprintf (stderr, "PT = %d, BEGV = %d. ZV = %d\n",
16360 BUF_PT (buffer), BUF_BEGV (buffer), BUF_ZV (buffer));
16361 fprintf (stderr, "Cursor x = %d, y = %d, hpos = %d, vpos = %d\n",
16362 w->cursor.x, w->cursor.y, w->cursor.hpos, w->cursor.vpos);
16363 fprintf (stderr, "=============================================\n");
16364 dump_glyph_matrix (w->current_matrix,
16365 NILP (glyphs) ? 0 : XINT (glyphs));
16366 return Qnil;
16367 }
16368
16369
16370 DEFUN ("dump-frame-glyph-matrix", Fdump_frame_glyph_matrix,
16371 Sdump_frame_glyph_matrix, 0, 0, "", doc: /* */)
16372 (void)
16373 {
16374 struct frame *f = XFRAME (selected_frame);
16375 dump_glyph_matrix (f->current_matrix, 1);
16376 return Qnil;
16377 }
16378
16379
16380 DEFUN ("dump-glyph-row", Fdump_glyph_row, Sdump_glyph_row, 1, 2, "",
16381 doc: /* Dump glyph row ROW to stderr.
16382 GLYPH 0 means don't dump glyphs.
16383 GLYPH 1 means dump glyphs in short form.
16384 GLYPH > 1 or omitted means dump glyphs in long form. */)
16385 (Lisp_Object row, Lisp_Object glyphs)
16386 {
16387 struct glyph_matrix *matrix;
16388 int vpos;
16389
16390 CHECK_NUMBER (row);
16391 matrix = XWINDOW (selected_window)->current_matrix;
16392 vpos = XINT (row);
16393 if (vpos >= 0 && vpos < matrix->nrows)
16394 dump_glyph_row (MATRIX_ROW (matrix, vpos),
16395 vpos,
16396 INTEGERP (glyphs) ? XINT (glyphs) : 2);
16397 return Qnil;
16398 }
16399
16400
16401 DEFUN ("dump-tool-bar-row", Fdump_tool_bar_row, Sdump_tool_bar_row, 1, 2, "",
16402 doc: /* Dump glyph row ROW of the tool-bar of the current frame to stderr.
16403 GLYPH 0 means don't dump glyphs.
16404 GLYPH 1 means dump glyphs in short form.
16405 GLYPH > 1 or omitted means dump glyphs in long form. */)
16406 (Lisp_Object row, Lisp_Object glyphs)
16407 {
16408 struct frame *sf = SELECTED_FRAME ();
16409 struct glyph_matrix *m = XWINDOW (sf->tool_bar_window)->current_matrix;
16410 int vpos;
16411
16412 CHECK_NUMBER (row);
16413 vpos = XINT (row);
16414 if (vpos >= 0 && vpos < m->nrows)
16415 dump_glyph_row (MATRIX_ROW (m, vpos), vpos,
16416 INTEGERP (glyphs) ? XINT (glyphs) : 2);
16417 return Qnil;
16418 }
16419
16420
16421 DEFUN ("trace-redisplay", Ftrace_redisplay, Strace_redisplay, 0, 1, "P",
16422 doc: /* Toggle tracing of redisplay.
16423 With ARG, turn tracing on if and only if ARG is positive. */)
16424 (Lisp_Object arg)
16425 {
16426 if (NILP (arg))
16427 trace_redisplay_p = !trace_redisplay_p;
16428 else
16429 {
16430 arg = Fprefix_numeric_value (arg);
16431 trace_redisplay_p = XINT (arg) > 0;
16432 }
16433
16434 return Qnil;
16435 }
16436
16437
16438 DEFUN ("trace-to-stderr", Ftrace_to_stderr, Strace_to_stderr, 1, MANY, "",
16439 doc: /* Like `format', but print result to stderr.
16440 usage: (trace-to-stderr STRING &rest OBJECTS) */)
16441 (int nargs, Lisp_Object *args)
16442 {
16443 Lisp_Object s = Fformat (nargs, args);
16444 fprintf (stderr, "%s", SDATA (s));
16445 return Qnil;
16446 }
16447
16448 #endif /* GLYPH_DEBUG */
16449
16450
16451 \f
16452 /***********************************************************************
16453 Building Desired Matrix Rows
16454 ***********************************************************************/
16455
16456 /* Return a temporary glyph row holding the glyphs of an overlay arrow.
16457 Used for non-window-redisplay windows, and for windows w/o left fringe. */
16458
16459 static struct glyph_row *
16460 get_overlay_arrow_glyph_row (struct window *w, Lisp_Object overlay_arrow_string)
16461 {
16462 struct frame *f = XFRAME (WINDOW_FRAME (w));
16463 struct buffer *buffer = XBUFFER (w->buffer);
16464 struct buffer *old = current_buffer;
16465 const unsigned char *arrow_string = SDATA (overlay_arrow_string);
16466 int arrow_len = SCHARS (overlay_arrow_string);
16467 const unsigned char *arrow_end = arrow_string + arrow_len;
16468 const unsigned char *p;
16469 struct it it;
16470 int multibyte_p;
16471 int n_glyphs_before;
16472
16473 set_buffer_temp (buffer);
16474 init_iterator (&it, w, -1, -1, &scratch_glyph_row, DEFAULT_FACE_ID);
16475 it.glyph_row->used[TEXT_AREA] = 0;
16476 SET_TEXT_POS (it.position, 0, 0);
16477
16478 multibyte_p = !NILP (buffer->enable_multibyte_characters);
16479 p = arrow_string;
16480 while (p < arrow_end)
16481 {
16482 Lisp_Object face, ilisp;
16483
16484 /* Get the next character. */
16485 if (multibyte_p)
16486 it.c = string_char_and_length (p, &it.len);
16487 else
16488 it.c = *p, it.len = 1;
16489 p += it.len;
16490
16491 /* Get its face. */
16492 ilisp = make_number (p - arrow_string);
16493 face = Fget_text_property (ilisp, Qface, overlay_arrow_string);
16494 it.face_id = compute_char_face (f, it.c, face);
16495
16496 /* Compute its width, get its glyphs. */
16497 n_glyphs_before = it.glyph_row->used[TEXT_AREA];
16498 SET_TEXT_POS (it.position, -1, -1);
16499 PRODUCE_GLYPHS (&it);
16500
16501 /* If this character doesn't fit any more in the line, we have
16502 to remove some glyphs. */
16503 if (it.current_x > it.last_visible_x)
16504 {
16505 it.glyph_row->used[TEXT_AREA] = n_glyphs_before;
16506 break;
16507 }
16508 }
16509
16510 set_buffer_temp (old);
16511 return it.glyph_row;
16512 }
16513
16514
16515 /* Insert truncation glyphs at the start of IT->glyph_row. Truncation
16516 glyphs are only inserted for terminal frames since we can't really
16517 win with truncation glyphs when partially visible glyphs are
16518 involved. Which glyphs to insert is determined by
16519 produce_special_glyphs. */
16520
16521 static void
16522 insert_left_trunc_glyphs (struct it *it)
16523 {
16524 struct it truncate_it;
16525 struct glyph *from, *end, *to, *toend;
16526
16527 xassert (!FRAME_WINDOW_P (it->f));
16528
16529 /* Get the truncation glyphs. */
16530 truncate_it = *it;
16531 truncate_it.current_x = 0;
16532 truncate_it.face_id = DEFAULT_FACE_ID;
16533 truncate_it.glyph_row = &scratch_glyph_row;
16534 truncate_it.glyph_row->used[TEXT_AREA] = 0;
16535 CHARPOS (truncate_it.position) = BYTEPOS (truncate_it.position) = -1;
16536 truncate_it.object = make_number (0);
16537 produce_special_glyphs (&truncate_it, IT_TRUNCATION);
16538
16539 /* Overwrite glyphs from IT with truncation glyphs. */
16540 if (!it->glyph_row->reversed_p)
16541 {
16542 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
16543 end = from + truncate_it.glyph_row->used[TEXT_AREA];
16544 to = it->glyph_row->glyphs[TEXT_AREA];
16545 toend = to + it->glyph_row->used[TEXT_AREA];
16546
16547 while (from < end)
16548 *to++ = *from++;
16549
16550 /* There may be padding glyphs left over. Overwrite them too. */
16551 while (to < toend && CHAR_GLYPH_PADDING_P (*to))
16552 {
16553 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
16554 while (from < end)
16555 *to++ = *from++;
16556 }
16557
16558 if (to > toend)
16559 it->glyph_row->used[TEXT_AREA] = to - it->glyph_row->glyphs[TEXT_AREA];
16560 }
16561 else
16562 {
16563 /* In R2L rows, overwrite the last (rightmost) glyphs, and do
16564 that back to front. */
16565 end = truncate_it.glyph_row->glyphs[TEXT_AREA];
16566 from = end + truncate_it.glyph_row->used[TEXT_AREA] - 1;
16567 toend = it->glyph_row->glyphs[TEXT_AREA];
16568 to = toend + it->glyph_row->used[TEXT_AREA] - 1;
16569
16570 while (from >= end && to >= toend)
16571 *to-- = *from--;
16572 while (to >= toend && CHAR_GLYPH_PADDING_P (*to))
16573 {
16574 from =
16575 truncate_it.glyph_row->glyphs[TEXT_AREA]
16576 + truncate_it.glyph_row->used[TEXT_AREA] - 1;
16577 while (from >= end && to >= toend)
16578 *to-- = *from--;
16579 }
16580 if (from >= end)
16581 {
16582 /* Need to free some room before prepending additional
16583 glyphs. */
16584 int move_by = from - end + 1;
16585 struct glyph *g0 = it->glyph_row->glyphs[TEXT_AREA];
16586 struct glyph *g = g0 + it->glyph_row->used[TEXT_AREA] - 1;
16587
16588 for ( ; g >= g0; g--)
16589 g[move_by] = *g;
16590 while (from >= end)
16591 *to-- = *from--;
16592 it->glyph_row->used[TEXT_AREA] += move_by;
16593 }
16594 }
16595 }
16596
16597
16598 /* Compute the pixel height and width of IT->glyph_row.
16599
16600 Most of the time, ascent and height of a display line will be equal
16601 to the max_ascent and max_height values of the display iterator
16602 structure. This is not the case if
16603
16604 1. We hit ZV without displaying anything. In this case, max_ascent
16605 and max_height will be zero.
16606
16607 2. We have some glyphs that don't contribute to the line height.
16608 (The glyph row flag contributes_to_line_height_p is for future
16609 pixmap extensions).
16610
16611 The first case is easily covered by using default values because in
16612 these cases, the line height does not really matter, except that it
16613 must not be zero. */
16614
16615 static void
16616 compute_line_metrics (struct it *it)
16617 {
16618 struct glyph_row *row = it->glyph_row;
16619 int area, i;
16620
16621 if (FRAME_WINDOW_P (it->f))
16622 {
16623 int i, min_y, max_y;
16624
16625 /* The line may consist of one space only, that was added to
16626 place the cursor on it. If so, the row's height hasn't been
16627 computed yet. */
16628 if (row->height == 0)
16629 {
16630 if (it->max_ascent + it->max_descent == 0)
16631 it->max_descent = it->max_phys_descent = FRAME_LINE_HEIGHT (it->f);
16632 row->ascent = it->max_ascent;
16633 row->height = it->max_ascent + it->max_descent;
16634 row->phys_ascent = it->max_phys_ascent;
16635 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
16636 row->extra_line_spacing = it->max_extra_line_spacing;
16637 }
16638
16639 /* Compute the width of this line. */
16640 row->pixel_width = row->x;
16641 for (i = 0; i < row->used[TEXT_AREA]; ++i)
16642 row->pixel_width += row->glyphs[TEXT_AREA][i].pixel_width;
16643
16644 xassert (row->pixel_width >= 0);
16645 xassert (row->ascent >= 0 && row->height > 0);
16646
16647 row->overlapping_p = (MATRIX_ROW_OVERLAPS_SUCC_P (row)
16648 || MATRIX_ROW_OVERLAPS_PRED_P (row));
16649
16650 /* If first line's physical ascent is larger than its logical
16651 ascent, use the physical ascent, and make the row taller.
16652 This makes accented characters fully visible. */
16653 if (row == MATRIX_FIRST_TEXT_ROW (it->w->desired_matrix)
16654 && row->phys_ascent > row->ascent)
16655 {
16656 row->height += row->phys_ascent - row->ascent;
16657 row->ascent = row->phys_ascent;
16658 }
16659
16660 /* Compute how much of the line is visible. */
16661 row->visible_height = row->height;
16662
16663 min_y = WINDOW_HEADER_LINE_HEIGHT (it->w);
16664 max_y = WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w);
16665
16666 if (row->y < min_y)
16667 row->visible_height -= min_y - row->y;
16668 if (row->y + row->height > max_y)
16669 row->visible_height -= row->y + row->height - max_y;
16670 }
16671 else
16672 {
16673 row->pixel_width = row->used[TEXT_AREA];
16674 if (row->continued_p)
16675 row->pixel_width -= it->continuation_pixel_width;
16676 else if (row->truncated_on_right_p)
16677 row->pixel_width -= it->truncation_pixel_width;
16678 row->ascent = row->phys_ascent = 0;
16679 row->height = row->phys_height = row->visible_height = 1;
16680 row->extra_line_spacing = 0;
16681 }
16682
16683 /* Compute a hash code for this row. */
16684 row->hash = 0;
16685 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
16686 for (i = 0; i < row->used[area]; ++i)
16687 row->hash = ((((row->hash << 4) + (row->hash >> 24)) & 0x0fffffff)
16688 + row->glyphs[area][i].u.val
16689 + row->glyphs[area][i].face_id
16690 + row->glyphs[area][i].padding_p
16691 + (row->glyphs[area][i].type << 2));
16692
16693 it->max_ascent = it->max_descent = 0;
16694 it->max_phys_ascent = it->max_phys_descent = 0;
16695 }
16696
16697
16698 /* Append one space to the glyph row of iterator IT if doing a
16699 window-based redisplay. The space has the same face as
16700 IT->face_id. Value is non-zero if a space was added.
16701
16702 This function is called to make sure that there is always one glyph
16703 at the end of a glyph row that the cursor can be set on under
16704 window-systems. (If there weren't such a glyph we would not know
16705 how wide and tall a box cursor should be displayed).
16706
16707 At the same time this space let's a nicely handle clearing to the
16708 end of the line if the row ends in italic text. */
16709
16710 static int
16711 append_space_for_newline (struct it *it, int default_face_p)
16712 {
16713 if (FRAME_WINDOW_P (it->f))
16714 {
16715 int n = it->glyph_row->used[TEXT_AREA];
16716
16717 if (it->glyph_row->glyphs[TEXT_AREA] + n
16718 < it->glyph_row->glyphs[1 + TEXT_AREA])
16719 {
16720 /* Save some values that must not be changed.
16721 Must save IT->c and IT->len because otherwise
16722 ITERATOR_AT_END_P wouldn't work anymore after
16723 append_space_for_newline has been called. */
16724 enum display_element_type saved_what = it->what;
16725 int saved_c = it->c, saved_len = it->len;
16726 int saved_x = it->current_x;
16727 int saved_face_id = it->face_id;
16728 struct text_pos saved_pos;
16729 Lisp_Object saved_object;
16730 struct face *face;
16731
16732 saved_object = it->object;
16733 saved_pos = it->position;
16734
16735 it->what = IT_CHARACTER;
16736 memset (&it->position, 0, sizeof it->position);
16737 it->object = make_number (0);
16738 it->c = ' ';
16739 it->len = 1;
16740
16741 if (default_face_p)
16742 it->face_id = DEFAULT_FACE_ID;
16743 else if (it->face_before_selective_p)
16744 it->face_id = it->saved_face_id;
16745 face = FACE_FROM_ID (it->f, it->face_id);
16746 it->face_id = FACE_FOR_CHAR (it->f, face, 0, -1, Qnil);
16747
16748 PRODUCE_GLYPHS (it);
16749
16750 it->override_ascent = -1;
16751 it->constrain_row_ascent_descent_p = 0;
16752 it->current_x = saved_x;
16753 it->object = saved_object;
16754 it->position = saved_pos;
16755 it->what = saved_what;
16756 it->face_id = saved_face_id;
16757 it->len = saved_len;
16758 it->c = saved_c;
16759 return 1;
16760 }
16761 }
16762
16763 return 0;
16764 }
16765
16766
16767 /* Extend the face of the last glyph in the text area of IT->glyph_row
16768 to the end of the display line. Called from display_line. If the
16769 glyph row is empty, add a space glyph to it so that we know the
16770 face to draw. Set the glyph row flag fill_line_p. If the glyph
16771 row is R2L, prepend a stretch glyph to cover the empty space to the
16772 left of the leftmost glyph. */
16773
16774 static void
16775 extend_face_to_end_of_line (struct it *it)
16776 {
16777 struct face *face;
16778 struct frame *f = it->f;
16779
16780 /* If line is already filled, do nothing. Non window-system frames
16781 get a grace of one more ``pixel'' because their characters are
16782 1-``pixel'' wide, so they hit the equality too early. This grace
16783 is needed only for R2L rows that are not continued, to produce
16784 one extra blank where we could display the cursor. */
16785 if (it->current_x >= it->last_visible_x
16786 + (!FRAME_WINDOW_P (f)
16787 && it->glyph_row->reversed_p
16788 && !it->glyph_row->continued_p))
16789 return;
16790
16791 /* Face extension extends the background and box of IT->face_id
16792 to the end of the line. If the background equals the background
16793 of the frame, we don't have to do anything. */
16794 if (it->face_before_selective_p)
16795 face = FACE_FROM_ID (f, it->saved_face_id);
16796 else
16797 face = FACE_FROM_ID (f, it->face_id);
16798
16799 if (FRAME_WINDOW_P (f)
16800 && it->glyph_row->displays_text_p
16801 && face->box == FACE_NO_BOX
16802 && face->background == FRAME_BACKGROUND_PIXEL (f)
16803 && !face->stipple
16804 && !it->glyph_row->reversed_p)
16805 return;
16806
16807 /* Set the glyph row flag indicating that the face of the last glyph
16808 in the text area has to be drawn to the end of the text area. */
16809 it->glyph_row->fill_line_p = 1;
16810
16811 /* If current character of IT is not ASCII, make sure we have the
16812 ASCII face. This will be automatically undone the next time
16813 get_next_display_element returns a multibyte character. Note
16814 that the character will always be single byte in unibyte
16815 text. */
16816 if (!ASCII_CHAR_P (it->c))
16817 {
16818 it->face_id = FACE_FOR_CHAR (f, face, 0, -1, Qnil);
16819 }
16820
16821 if (FRAME_WINDOW_P (f))
16822 {
16823 /* If the row is empty, add a space with the current face of IT,
16824 so that we know which face to draw. */
16825 if (it->glyph_row->used[TEXT_AREA] == 0)
16826 {
16827 it->glyph_row->glyphs[TEXT_AREA][0] = space_glyph;
16828 it->glyph_row->glyphs[TEXT_AREA][0].face_id = it->face_id;
16829 it->glyph_row->used[TEXT_AREA] = 1;
16830 }
16831 #ifdef HAVE_WINDOW_SYSTEM
16832 if (it->glyph_row->reversed_p)
16833 {
16834 /* Prepend a stretch glyph to the row, such that the
16835 rightmost glyph will be drawn flushed all the way to the
16836 right margin of the window. The stretch glyph that will
16837 occupy the empty space, if any, to the left of the
16838 glyphs. */
16839 struct font *font = face->font ? face->font : FRAME_FONT (f);
16840 struct glyph *row_start = it->glyph_row->glyphs[TEXT_AREA];
16841 struct glyph *row_end = row_start + it->glyph_row->used[TEXT_AREA];
16842 struct glyph *g;
16843 int row_width, stretch_ascent, stretch_width;
16844 struct text_pos saved_pos;
16845 int saved_face_id, saved_avoid_cursor;
16846
16847 for (row_width = 0, g = row_start; g < row_end; g++)
16848 row_width += g->pixel_width;
16849 stretch_width = window_box_width (it->w, TEXT_AREA) - row_width;
16850 if (stretch_width > 0)
16851 {
16852 stretch_ascent =
16853 (((it->ascent + it->descent)
16854 * FONT_BASE (font)) / FONT_HEIGHT (font));
16855 saved_pos = it->position;
16856 memset (&it->position, 0, sizeof it->position);
16857 saved_avoid_cursor = it->avoid_cursor_p;
16858 it->avoid_cursor_p = 1;
16859 saved_face_id = it->face_id;
16860 /* The last row's stretch glyph should get the default
16861 face, to avoid painting the rest of the window with
16862 the region face, if the region ends at ZV. */
16863 if (it->glyph_row->ends_at_zv_p)
16864 it->face_id = DEFAULT_FACE_ID;
16865 else
16866 it->face_id = face->id;
16867 append_stretch_glyph (it, make_number (0), stretch_width,
16868 it->ascent + it->descent, stretch_ascent);
16869 it->position = saved_pos;
16870 it->avoid_cursor_p = saved_avoid_cursor;
16871 it->face_id = saved_face_id;
16872 }
16873 }
16874 #endif /* HAVE_WINDOW_SYSTEM */
16875 }
16876 else
16877 {
16878 /* Save some values that must not be changed. */
16879 int saved_x = it->current_x;
16880 struct text_pos saved_pos;
16881 Lisp_Object saved_object;
16882 enum display_element_type saved_what = it->what;
16883 int saved_face_id = it->face_id;
16884
16885 saved_object = it->object;
16886 saved_pos = it->position;
16887
16888 it->what = IT_CHARACTER;
16889 memset (&it->position, 0, sizeof it->position);
16890 it->object = make_number (0);
16891 it->c = ' ';
16892 it->len = 1;
16893 /* The last row's blank glyphs should get the default face, to
16894 avoid painting the rest of the window with the region face,
16895 if the region ends at ZV. */
16896 if (it->glyph_row->ends_at_zv_p)
16897 it->face_id = DEFAULT_FACE_ID;
16898 else
16899 it->face_id = face->id;
16900
16901 PRODUCE_GLYPHS (it);
16902
16903 while (it->current_x <= it->last_visible_x)
16904 PRODUCE_GLYPHS (it);
16905
16906 /* Don't count these blanks really. It would let us insert a left
16907 truncation glyph below and make us set the cursor on them, maybe. */
16908 it->current_x = saved_x;
16909 it->object = saved_object;
16910 it->position = saved_pos;
16911 it->what = saved_what;
16912 it->face_id = saved_face_id;
16913 }
16914 }
16915
16916
16917 /* Value is non-zero if text starting at CHARPOS in current_buffer is
16918 trailing whitespace. */
16919
16920 static int
16921 trailing_whitespace_p (int charpos)
16922 {
16923 int bytepos = CHAR_TO_BYTE (charpos);
16924 int c = 0;
16925
16926 while (bytepos < ZV_BYTE
16927 && (c = FETCH_CHAR (bytepos),
16928 c == ' ' || c == '\t'))
16929 ++bytepos;
16930
16931 if (bytepos >= ZV_BYTE || c == '\n' || c == '\r')
16932 {
16933 if (bytepos != PT_BYTE)
16934 return 1;
16935 }
16936 return 0;
16937 }
16938
16939
16940 /* Highlight trailing whitespace, if any, in ROW. */
16941
16942 void
16943 highlight_trailing_whitespace (struct frame *f, struct glyph_row *row)
16944 {
16945 int used = row->used[TEXT_AREA];
16946
16947 if (used)
16948 {
16949 struct glyph *start = row->glyphs[TEXT_AREA];
16950 struct glyph *glyph = start + used - 1;
16951
16952 if (row->reversed_p)
16953 {
16954 /* Right-to-left rows need to be processed in the opposite
16955 direction, so swap the edge pointers. */
16956 glyph = start;
16957 start = row->glyphs[TEXT_AREA] + used - 1;
16958 }
16959
16960 /* Skip over glyphs inserted to display the cursor at the
16961 end of a line, for extending the face of the last glyph
16962 to the end of the line on terminals, and for truncation
16963 and continuation glyphs. */
16964 if (!row->reversed_p)
16965 {
16966 while (glyph >= start
16967 && glyph->type == CHAR_GLYPH
16968 && INTEGERP (glyph->object))
16969 --glyph;
16970 }
16971 else
16972 {
16973 while (glyph <= start
16974 && glyph->type == CHAR_GLYPH
16975 && INTEGERP (glyph->object))
16976 ++glyph;
16977 }
16978
16979 /* If last glyph is a space or stretch, and it's trailing
16980 whitespace, set the face of all trailing whitespace glyphs in
16981 IT->glyph_row to `trailing-whitespace'. */
16982 if ((row->reversed_p ? glyph <= start : glyph >= start)
16983 && BUFFERP (glyph->object)
16984 && (glyph->type == STRETCH_GLYPH
16985 || (glyph->type == CHAR_GLYPH
16986 && glyph->u.ch == ' '))
16987 && trailing_whitespace_p (glyph->charpos))
16988 {
16989 int face_id = lookup_named_face (f, Qtrailing_whitespace, 0);
16990 if (face_id < 0)
16991 return;
16992
16993 if (!row->reversed_p)
16994 {
16995 while (glyph >= start
16996 && BUFFERP (glyph->object)
16997 && (glyph->type == STRETCH_GLYPH
16998 || (glyph->type == CHAR_GLYPH
16999 && glyph->u.ch == ' ')))
17000 (glyph--)->face_id = face_id;
17001 }
17002 else
17003 {
17004 while (glyph <= start
17005 && BUFFERP (glyph->object)
17006 && (glyph->type == STRETCH_GLYPH
17007 || (glyph->type == CHAR_GLYPH
17008 && glyph->u.ch == ' ')))
17009 (glyph++)->face_id = face_id;
17010 }
17011 }
17012 }
17013 }
17014
17015
17016 /* Value is non-zero if glyph row ROW in window W should be
17017 used to hold the cursor. */
17018
17019 static int
17020 cursor_row_p (struct window *w, struct glyph_row *row)
17021 {
17022 int cursor_row_p = 1;
17023
17024 if (PT == CHARPOS (row->end.pos))
17025 {
17026 /* Suppose the row ends on a string.
17027 Unless the row is continued, that means it ends on a newline
17028 in the string. If it's anything other than a display string
17029 (e.g. a before-string from an overlay), we don't want the
17030 cursor there. (This heuristic seems to give the optimal
17031 behavior for the various types of multi-line strings.) */
17032 if (CHARPOS (row->end.string_pos) >= 0)
17033 {
17034 if (row->continued_p)
17035 cursor_row_p = 1;
17036 else
17037 {
17038 /* Check for `display' property. */
17039 struct glyph *beg = row->glyphs[TEXT_AREA];
17040 struct glyph *end = beg + row->used[TEXT_AREA] - 1;
17041 struct glyph *glyph;
17042
17043 cursor_row_p = 0;
17044 for (glyph = end; glyph >= beg; --glyph)
17045 if (STRINGP (glyph->object))
17046 {
17047 Lisp_Object prop
17048 = Fget_char_property (make_number (PT),
17049 Qdisplay, Qnil);
17050 cursor_row_p =
17051 (!NILP (prop)
17052 && display_prop_string_p (prop, glyph->object));
17053 break;
17054 }
17055 }
17056 }
17057 else if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
17058 {
17059 /* If the row ends in middle of a real character,
17060 and the line is continued, we want the cursor here.
17061 That's because CHARPOS (ROW->end.pos) would equal
17062 PT if PT is before the character. */
17063 if (!row->ends_in_ellipsis_p)
17064 cursor_row_p = row->continued_p;
17065 else
17066 /* If the row ends in an ellipsis, then
17067 CHARPOS (ROW->end.pos) will equal point after the
17068 invisible text. We want that position to be displayed
17069 after the ellipsis. */
17070 cursor_row_p = 0;
17071 }
17072 /* If the row ends at ZV, display the cursor at the end of that
17073 row instead of at the start of the row below. */
17074 else if (row->ends_at_zv_p)
17075 cursor_row_p = 1;
17076 else
17077 cursor_row_p = 0;
17078 }
17079
17080 return cursor_row_p;
17081 }
17082
17083 \f
17084
17085 /* Push the display property PROP so that it will be rendered at the
17086 current position in IT. Return 1 if PROP was successfully pushed,
17087 0 otherwise. */
17088
17089 static int
17090 push_display_prop (struct it *it, Lisp_Object prop)
17091 {
17092 push_it (it);
17093
17094 if (STRINGP (prop))
17095 {
17096 if (SCHARS (prop) == 0)
17097 {
17098 pop_it (it);
17099 return 0;
17100 }
17101
17102 it->string = prop;
17103 it->multibyte_p = STRING_MULTIBYTE (it->string);
17104 it->current.overlay_string_index = -1;
17105 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
17106 it->end_charpos = it->string_nchars = SCHARS (it->string);
17107 it->method = GET_FROM_STRING;
17108 it->stop_charpos = 0;
17109 }
17110 else if (CONSP (prop) && EQ (XCAR (prop), Qspace))
17111 {
17112 it->method = GET_FROM_STRETCH;
17113 it->object = prop;
17114 }
17115 #ifdef HAVE_WINDOW_SYSTEM
17116 else if (IMAGEP (prop))
17117 {
17118 it->what = IT_IMAGE;
17119 it->image_id = lookup_image (it->f, prop);
17120 it->method = GET_FROM_IMAGE;
17121 }
17122 #endif /* HAVE_WINDOW_SYSTEM */
17123 else
17124 {
17125 pop_it (it); /* bogus display property, give up */
17126 return 0;
17127 }
17128
17129 return 1;
17130 }
17131
17132 /* Return the character-property PROP at the current position in IT. */
17133
17134 static Lisp_Object
17135 get_it_property (struct it *it, Lisp_Object prop)
17136 {
17137 Lisp_Object position;
17138
17139 if (STRINGP (it->object))
17140 position = make_number (IT_STRING_CHARPOS (*it));
17141 else if (BUFFERP (it->object))
17142 position = make_number (IT_CHARPOS (*it));
17143 else
17144 return Qnil;
17145
17146 return Fget_char_property (position, prop, it->object);
17147 }
17148
17149 /* See if there's a line- or wrap-prefix, and if so, push it on IT. */
17150
17151 static void
17152 handle_line_prefix (struct it *it)
17153 {
17154 Lisp_Object prefix;
17155 if (it->continuation_lines_width > 0)
17156 {
17157 prefix = get_it_property (it, Qwrap_prefix);
17158 if (NILP (prefix))
17159 prefix = Vwrap_prefix;
17160 }
17161 else
17162 {
17163 prefix = get_it_property (it, Qline_prefix);
17164 if (NILP (prefix))
17165 prefix = Vline_prefix;
17166 }
17167 if (! NILP (prefix) && push_display_prop (it, prefix))
17168 {
17169 /* If the prefix is wider than the window, and we try to wrap
17170 it, it would acquire its own wrap prefix, and so on till the
17171 iterator stack overflows. So, don't wrap the prefix. */
17172 it->line_wrap = TRUNCATE;
17173 it->avoid_cursor_p = 1;
17174 }
17175 }
17176
17177 \f
17178
17179 /* Remove N glyphs at the start of a reversed IT->glyph_row. Called
17180 only for R2L lines from display_line, when it decides that too many
17181 glyphs were produced by PRODUCE_GLYPHS, and the line needs to be
17182 continued. */
17183 static void
17184 unproduce_glyphs (struct it *it, int n)
17185 {
17186 struct glyph *glyph, *end;
17187
17188 xassert (it->glyph_row);
17189 xassert (it->glyph_row->reversed_p);
17190 xassert (it->area == TEXT_AREA);
17191 xassert (n <= it->glyph_row->used[TEXT_AREA]);
17192
17193 if (n > it->glyph_row->used[TEXT_AREA])
17194 n = it->glyph_row->used[TEXT_AREA];
17195 glyph = it->glyph_row->glyphs[TEXT_AREA] + n;
17196 end = it->glyph_row->glyphs[TEXT_AREA] + it->glyph_row->used[TEXT_AREA];
17197 for ( ; glyph < end; glyph++)
17198 glyph[-n] = *glyph;
17199 }
17200
17201 /* Find the positions in a bidi-reordered ROW to serve as ROW->minpos
17202 and ROW->maxpos. */
17203 static void
17204 find_row_edges (struct it *it, struct glyph_row *row,
17205 EMACS_INT min_pos, EMACS_INT min_bpos,
17206 EMACS_INT max_pos, EMACS_INT max_bpos)
17207 {
17208 /* FIXME: Revisit this when glyph ``spilling'' in continuation
17209 lines' rows is implemented for bidi-reordered rows. */
17210
17211 /* ROW->minpos is the value of min_pos, the minimal buffer position
17212 we have in ROW. */
17213 if (min_pos <= ZV)
17214 SET_TEXT_POS (row->minpos, min_pos, min_bpos);
17215 else
17216 {
17217 /* We didn't find _any_ valid buffer positions in any of the
17218 glyphs, so we must trust the iterator's computed
17219 positions. */
17220 row->minpos = row->start.pos;
17221 max_pos = CHARPOS (it->current.pos);
17222 max_bpos = BYTEPOS (it->current.pos);
17223 }
17224
17225 if (!max_pos)
17226 abort ();
17227
17228 /* Here are the various use-cases for ending the row, and the
17229 corresponding values for ROW->maxpos:
17230
17231 Line ends in a newline from buffer eol_pos + 1
17232 Line is continued from buffer max_pos + 1
17233 Line is truncated on right it->current.pos
17234 Line ends in a newline from string max_pos
17235 Line is continued from string max_pos
17236 Line is continued from display vector max_pos
17237 Line is entirely from a string min_pos == max_pos
17238 Line is entirely from a display vector min_pos == max_pos
17239 Line that ends at ZV ZV
17240
17241 If you discover other use-cases, please add them here as
17242 appropriate. */
17243 if (row->ends_at_zv_p)
17244 row->maxpos = it->current.pos;
17245 else if (row->used[TEXT_AREA])
17246 {
17247 if (row->ends_in_newline_from_string_p)
17248 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
17249 else if (CHARPOS (it->eol_pos) > 0)
17250 SET_TEXT_POS (row->maxpos,
17251 CHARPOS (it->eol_pos) + 1, BYTEPOS (it->eol_pos) + 1);
17252 else if (row->continued_p)
17253 {
17254 /* If max_pos is different from IT's current position, it
17255 means IT->method does not belong to the display element
17256 at max_pos. However, it also means that the display
17257 element at max_pos was displayed in its entirety on this
17258 line, which is equivalent to saying that the next line
17259 starts at the next buffer position. */
17260 if (IT_CHARPOS (*it) == max_pos && it->method != GET_FROM_BUFFER)
17261 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
17262 else
17263 {
17264 INC_BOTH (max_pos, max_bpos);
17265 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
17266 }
17267 }
17268 else if (row->truncated_on_right_p)
17269 /* display_line already called reseat_at_next_visible_line_start,
17270 which puts the iterator at the beginning of the next line, in
17271 the logical order. */
17272 row->maxpos = it->current.pos;
17273 else if (max_pos == min_pos && it->method != GET_FROM_BUFFER)
17274 /* A line that is entirely from a string/image/stretch... */
17275 row->maxpos = row->minpos;
17276 else
17277 abort ();
17278 }
17279 else
17280 row->maxpos = it->current.pos;
17281 }
17282
17283 /* Construct the glyph row IT->glyph_row in the desired matrix of
17284 IT->w from text at the current position of IT. See dispextern.h
17285 for an overview of struct it. Value is non-zero if
17286 IT->glyph_row displays text, as opposed to a line displaying ZV
17287 only. */
17288
17289 static int
17290 display_line (struct it *it)
17291 {
17292 struct glyph_row *row = it->glyph_row;
17293 Lisp_Object overlay_arrow_string;
17294 struct it wrap_it;
17295 int may_wrap = 0, wrap_x;
17296 int wrap_row_used = -1, wrap_row_ascent, wrap_row_height;
17297 int wrap_row_phys_ascent, wrap_row_phys_height;
17298 int wrap_row_extra_line_spacing;
17299 EMACS_INT wrap_row_min_pos, wrap_row_min_bpos;
17300 EMACS_INT wrap_row_max_pos, wrap_row_max_bpos;
17301 int cvpos;
17302 EMACS_INT min_pos = ZV + 1, min_bpos, max_pos = 0, max_bpos;
17303
17304 /* We always start displaying at hpos zero even if hscrolled. */
17305 xassert (it->hpos == 0 && it->current_x == 0);
17306
17307 if (MATRIX_ROW_VPOS (row, it->w->desired_matrix)
17308 >= it->w->desired_matrix->nrows)
17309 {
17310 it->w->nrows_scale_factor++;
17311 fonts_changed_p = 1;
17312 return 0;
17313 }
17314
17315 /* Is IT->w showing the region? */
17316 it->w->region_showing = it->region_beg_charpos > 0 ? Qt : Qnil;
17317
17318 /* Clear the result glyph row and enable it. */
17319 prepare_desired_row (row);
17320
17321 row->y = it->current_y;
17322 row->start = it->start;
17323 row->continuation_lines_width = it->continuation_lines_width;
17324 row->displays_text_p = 1;
17325 row->starts_in_middle_of_char_p = it->starts_in_middle_of_char_p;
17326 it->starts_in_middle_of_char_p = 0;
17327
17328 /* Arrange the overlays nicely for our purposes. Usually, we call
17329 display_line on only one line at a time, in which case this
17330 can't really hurt too much, or we call it on lines which appear
17331 one after another in the buffer, in which case all calls to
17332 recenter_overlay_lists but the first will be pretty cheap. */
17333 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
17334
17335 /* Move over display elements that are not visible because we are
17336 hscrolled. This may stop at an x-position < IT->first_visible_x
17337 if the first glyph is partially visible or if we hit a line end. */
17338 if (it->current_x < it->first_visible_x)
17339 {
17340 move_it_in_display_line_to (it, ZV, it->first_visible_x,
17341 MOVE_TO_POS | MOVE_TO_X);
17342 }
17343 else
17344 {
17345 /* We only do this when not calling `move_it_in_display_line_to'
17346 above, because move_it_in_display_line_to calls
17347 handle_line_prefix itself. */
17348 handle_line_prefix (it);
17349 }
17350
17351 /* Get the initial row height. This is either the height of the
17352 text hscrolled, if there is any, or zero. */
17353 row->ascent = it->max_ascent;
17354 row->height = it->max_ascent + it->max_descent;
17355 row->phys_ascent = it->max_phys_ascent;
17356 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
17357 row->extra_line_spacing = it->max_extra_line_spacing;
17358
17359 /* Utility macro to record max and min buffer positions seen until now. */
17360 #define RECORD_MAX_MIN_POS(IT) \
17361 do \
17362 { \
17363 if (IT_CHARPOS (*(IT)) < min_pos) \
17364 { \
17365 min_pos = IT_CHARPOS (*(IT)); \
17366 min_bpos = IT_BYTEPOS (*(IT)); \
17367 } \
17368 if (IT_CHARPOS (*(IT)) > max_pos) \
17369 { \
17370 max_pos = IT_CHARPOS (*(IT)); \
17371 max_bpos = IT_BYTEPOS (*(IT)); \
17372 } \
17373 } \
17374 while (0)
17375
17376 /* Loop generating characters. The loop is left with IT on the next
17377 character to display. */
17378 while (1)
17379 {
17380 int n_glyphs_before, hpos_before, x_before;
17381 int x, i, nglyphs;
17382 int ascent = 0, descent = 0, phys_ascent = 0, phys_descent = 0;
17383
17384 /* Retrieve the next thing to display. Value is zero if end of
17385 buffer reached. */
17386 if (!get_next_display_element (it))
17387 {
17388 /* Maybe add a space at the end of this line that is used to
17389 display the cursor there under X. Set the charpos of the
17390 first glyph of blank lines not corresponding to any text
17391 to -1. */
17392 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
17393 row->exact_window_width_line_p = 1;
17394 else if ((append_space_for_newline (it, 1) && row->used[TEXT_AREA] == 1)
17395 || row->used[TEXT_AREA] == 0)
17396 {
17397 row->glyphs[TEXT_AREA]->charpos = -1;
17398 row->displays_text_p = 0;
17399
17400 if (!NILP (XBUFFER (it->w->buffer)->indicate_empty_lines)
17401 && (!MINI_WINDOW_P (it->w)
17402 || (minibuf_level && EQ (it->window, minibuf_window))))
17403 row->indicate_empty_line_p = 1;
17404 }
17405
17406 it->continuation_lines_width = 0;
17407 row->ends_at_zv_p = 1;
17408 /* A row that displays right-to-left text must always have
17409 its last face extended all the way to the end of line,
17410 even if this row ends in ZV, because we still write to
17411 the screen left to right. */
17412 if (row->reversed_p)
17413 extend_face_to_end_of_line (it);
17414 break;
17415 }
17416
17417 /* Now, get the metrics of what we want to display. This also
17418 generates glyphs in `row' (which is IT->glyph_row). */
17419 n_glyphs_before = row->used[TEXT_AREA];
17420 x = it->current_x;
17421
17422 /* Remember the line height so far in case the next element doesn't
17423 fit on the line. */
17424 if (it->line_wrap != TRUNCATE)
17425 {
17426 ascent = it->max_ascent;
17427 descent = it->max_descent;
17428 phys_ascent = it->max_phys_ascent;
17429 phys_descent = it->max_phys_descent;
17430
17431 if (it->line_wrap == WORD_WRAP && it->area == TEXT_AREA)
17432 {
17433 if (IT_DISPLAYING_WHITESPACE (it))
17434 may_wrap = 1;
17435 else if (may_wrap)
17436 {
17437 wrap_it = *it;
17438 wrap_x = x;
17439 wrap_row_used = row->used[TEXT_AREA];
17440 wrap_row_ascent = row->ascent;
17441 wrap_row_height = row->height;
17442 wrap_row_phys_ascent = row->phys_ascent;
17443 wrap_row_phys_height = row->phys_height;
17444 wrap_row_extra_line_spacing = row->extra_line_spacing;
17445 wrap_row_min_pos = min_pos;
17446 wrap_row_min_bpos = min_bpos;
17447 wrap_row_max_pos = max_pos;
17448 wrap_row_max_bpos = max_bpos;
17449 may_wrap = 0;
17450 }
17451 }
17452 }
17453
17454 PRODUCE_GLYPHS (it);
17455
17456 /* If this display element was in marginal areas, continue with
17457 the next one. */
17458 if (it->area != TEXT_AREA)
17459 {
17460 row->ascent = max (row->ascent, it->max_ascent);
17461 row->height = max (row->height, it->max_ascent + it->max_descent);
17462 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
17463 row->phys_height = max (row->phys_height,
17464 it->max_phys_ascent + it->max_phys_descent);
17465 row->extra_line_spacing = max (row->extra_line_spacing,
17466 it->max_extra_line_spacing);
17467 set_iterator_to_next (it, 1);
17468 continue;
17469 }
17470
17471 /* Does the display element fit on the line? If we truncate
17472 lines, we should draw past the right edge of the window. If
17473 we don't truncate, we want to stop so that we can display the
17474 continuation glyph before the right margin. If lines are
17475 continued, there are two possible strategies for characters
17476 resulting in more than 1 glyph (e.g. tabs): Display as many
17477 glyphs as possible in this line and leave the rest for the
17478 continuation line, or display the whole element in the next
17479 line. Original redisplay did the former, so we do it also. */
17480 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
17481 hpos_before = it->hpos;
17482 x_before = x;
17483
17484 if (/* Not a newline. */
17485 nglyphs > 0
17486 /* Glyphs produced fit entirely in the line. */
17487 && it->current_x < it->last_visible_x)
17488 {
17489 it->hpos += nglyphs;
17490 row->ascent = max (row->ascent, it->max_ascent);
17491 row->height = max (row->height, it->max_ascent + it->max_descent);
17492 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
17493 row->phys_height = max (row->phys_height,
17494 it->max_phys_ascent + it->max_phys_descent);
17495 row->extra_line_spacing = max (row->extra_line_spacing,
17496 it->max_extra_line_spacing);
17497 if (it->current_x - it->pixel_width < it->first_visible_x)
17498 row->x = x - it->first_visible_x;
17499 /* Record the maximum and minimum buffer positions seen so
17500 far in glyphs that will be displayed by this row. */
17501 if (it->bidi_p)
17502 RECORD_MAX_MIN_POS (it);
17503 }
17504 else
17505 {
17506 int new_x;
17507 struct glyph *glyph;
17508
17509 for (i = 0; i < nglyphs; ++i, x = new_x)
17510 {
17511 glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
17512 new_x = x + glyph->pixel_width;
17513
17514 if (/* Lines are continued. */
17515 it->line_wrap != TRUNCATE
17516 && (/* Glyph doesn't fit on the line. */
17517 new_x > it->last_visible_x
17518 /* Or it fits exactly on a window system frame. */
17519 || (new_x == it->last_visible_x
17520 && FRAME_WINDOW_P (it->f))))
17521 {
17522 /* End of a continued line. */
17523
17524 if (it->hpos == 0
17525 || (new_x == it->last_visible_x
17526 && FRAME_WINDOW_P (it->f)))
17527 {
17528 /* Current glyph is the only one on the line or
17529 fits exactly on the line. We must continue
17530 the line because we can't draw the cursor
17531 after the glyph. */
17532 row->continued_p = 1;
17533 it->current_x = new_x;
17534 it->continuation_lines_width += new_x;
17535 ++it->hpos;
17536 /* Record the maximum and minimum buffer
17537 positions seen so far in glyphs that will be
17538 displayed by this row. */
17539 if (it->bidi_p)
17540 RECORD_MAX_MIN_POS (it);
17541 if (i == nglyphs - 1)
17542 {
17543 /* If line-wrap is on, check if a previous
17544 wrap point was found. */
17545 if (wrap_row_used > 0
17546 /* Even if there is a previous wrap
17547 point, continue the line here as
17548 usual, if (i) the previous character
17549 was a space or tab AND (ii) the
17550 current character is not. */
17551 && (!may_wrap
17552 || IT_DISPLAYING_WHITESPACE (it)))
17553 goto back_to_wrap;
17554
17555 set_iterator_to_next (it, 1);
17556 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
17557 {
17558 if (!get_next_display_element (it))
17559 {
17560 row->exact_window_width_line_p = 1;
17561 it->continuation_lines_width = 0;
17562 row->continued_p = 0;
17563 row->ends_at_zv_p = 1;
17564 }
17565 else if (ITERATOR_AT_END_OF_LINE_P (it))
17566 {
17567 row->continued_p = 0;
17568 row->exact_window_width_line_p = 1;
17569 }
17570 }
17571 }
17572 }
17573 else if (CHAR_GLYPH_PADDING_P (*glyph)
17574 && !FRAME_WINDOW_P (it->f))
17575 {
17576 /* A padding glyph that doesn't fit on this line.
17577 This means the whole character doesn't fit
17578 on the line. */
17579 if (row->reversed_p)
17580 unproduce_glyphs (it, row->used[TEXT_AREA]
17581 - n_glyphs_before);
17582 row->used[TEXT_AREA] = n_glyphs_before;
17583
17584 /* Fill the rest of the row with continuation
17585 glyphs like in 20.x. */
17586 while (row->glyphs[TEXT_AREA] + row->used[TEXT_AREA]
17587 < row->glyphs[1 + TEXT_AREA])
17588 produce_special_glyphs (it, IT_CONTINUATION);
17589
17590 row->continued_p = 1;
17591 it->current_x = x_before;
17592 it->continuation_lines_width += x_before;
17593
17594 /* Restore the height to what it was before the
17595 element not fitting on the line. */
17596 it->max_ascent = ascent;
17597 it->max_descent = descent;
17598 it->max_phys_ascent = phys_ascent;
17599 it->max_phys_descent = phys_descent;
17600 }
17601 else if (wrap_row_used > 0)
17602 {
17603 back_to_wrap:
17604 if (row->reversed_p)
17605 unproduce_glyphs (it,
17606 row->used[TEXT_AREA] - wrap_row_used);
17607 *it = wrap_it;
17608 it->continuation_lines_width += wrap_x;
17609 row->used[TEXT_AREA] = wrap_row_used;
17610 row->ascent = wrap_row_ascent;
17611 row->height = wrap_row_height;
17612 row->phys_ascent = wrap_row_phys_ascent;
17613 row->phys_height = wrap_row_phys_height;
17614 row->extra_line_spacing = wrap_row_extra_line_spacing;
17615 min_pos = wrap_row_min_pos;
17616 min_bpos = wrap_row_min_bpos;
17617 max_pos = wrap_row_max_pos;
17618 max_bpos = wrap_row_max_bpos;
17619 row->continued_p = 1;
17620 row->ends_at_zv_p = 0;
17621 row->exact_window_width_line_p = 0;
17622 it->continuation_lines_width += x;
17623
17624 /* Make sure that a non-default face is extended
17625 up to the right margin of the window. */
17626 extend_face_to_end_of_line (it);
17627 }
17628 else if (it->c == '\t' && FRAME_WINDOW_P (it->f))
17629 {
17630 /* A TAB that extends past the right edge of the
17631 window. This produces a single glyph on
17632 window system frames. We leave the glyph in
17633 this row and let it fill the row, but don't
17634 consume the TAB. */
17635 it->continuation_lines_width += it->last_visible_x;
17636 row->ends_in_middle_of_char_p = 1;
17637 row->continued_p = 1;
17638 glyph->pixel_width = it->last_visible_x - x;
17639 it->starts_in_middle_of_char_p = 1;
17640 }
17641 else
17642 {
17643 /* Something other than a TAB that draws past
17644 the right edge of the window. Restore
17645 positions to values before the element. */
17646 if (row->reversed_p)
17647 unproduce_glyphs (it, row->used[TEXT_AREA]
17648 - (n_glyphs_before + i));
17649 row->used[TEXT_AREA] = n_glyphs_before + i;
17650
17651 /* Display continuation glyphs. */
17652 if (!FRAME_WINDOW_P (it->f))
17653 produce_special_glyphs (it, IT_CONTINUATION);
17654 row->continued_p = 1;
17655
17656 it->current_x = x_before;
17657 it->continuation_lines_width += x;
17658 extend_face_to_end_of_line (it);
17659
17660 if (nglyphs > 1 && i > 0)
17661 {
17662 row->ends_in_middle_of_char_p = 1;
17663 it->starts_in_middle_of_char_p = 1;
17664 }
17665
17666 /* Restore the height to what it was before the
17667 element not fitting on the line. */
17668 it->max_ascent = ascent;
17669 it->max_descent = descent;
17670 it->max_phys_ascent = phys_ascent;
17671 it->max_phys_descent = phys_descent;
17672 }
17673
17674 break;
17675 }
17676 else if (new_x > it->first_visible_x)
17677 {
17678 /* Increment number of glyphs actually displayed. */
17679 ++it->hpos;
17680
17681 /* Record the maximum and minimum buffer positions
17682 seen so far in glyphs that will be displayed by
17683 this row. */
17684 if (it->bidi_p)
17685 RECORD_MAX_MIN_POS (it);
17686
17687 if (x < it->first_visible_x)
17688 /* Glyph is partially visible, i.e. row starts at
17689 negative X position. */
17690 row->x = x - it->first_visible_x;
17691 }
17692 else
17693 {
17694 /* Glyph is completely off the left margin of the
17695 window. This should not happen because of the
17696 move_it_in_display_line at the start of this
17697 function, unless the text display area of the
17698 window is empty. */
17699 xassert (it->first_visible_x <= it->last_visible_x);
17700 }
17701 }
17702
17703 row->ascent = max (row->ascent, it->max_ascent);
17704 row->height = max (row->height, it->max_ascent + it->max_descent);
17705 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
17706 row->phys_height = max (row->phys_height,
17707 it->max_phys_ascent + it->max_phys_descent);
17708 row->extra_line_spacing = max (row->extra_line_spacing,
17709 it->max_extra_line_spacing);
17710
17711 /* End of this display line if row is continued. */
17712 if (row->continued_p || row->ends_at_zv_p)
17713 break;
17714 }
17715
17716 at_end_of_line:
17717 /* Is this a line end? If yes, we're also done, after making
17718 sure that a non-default face is extended up to the right
17719 margin of the window. */
17720 if (ITERATOR_AT_END_OF_LINE_P (it))
17721 {
17722 int used_before = row->used[TEXT_AREA];
17723
17724 row->ends_in_newline_from_string_p = STRINGP (it->object);
17725
17726 /* Add a space at the end of the line that is used to
17727 display the cursor there. */
17728 if (!IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
17729 append_space_for_newline (it, 0);
17730
17731 /* Extend the face to the end of the line. */
17732 extend_face_to_end_of_line (it);
17733
17734 /* Make sure we have the position. */
17735 if (used_before == 0)
17736 row->glyphs[TEXT_AREA]->charpos = CHARPOS (it->position);
17737
17738 /* Record the position of the newline, for use in
17739 find_row_edges. */
17740 it->eol_pos = it->current.pos;
17741
17742 /* Consume the line end. This skips over invisible lines. */
17743 set_iterator_to_next (it, 1);
17744 it->continuation_lines_width = 0;
17745 break;
17746 }
17747
17748 /* Proceed with next display element. Note that this skips
17749 over lines invisible because of selective display. */
17750 set_iterator_to_next (it, 1);
17751
17752 /* If we truncate lines, we are done when the last displayed
17753 glyphs reach past the right margin of the window. */
17754 if (it->line_wrap == TRUNCATE
17755 && (FRAME_WINDOW_P (it->f)
17756 ? (it->current_x >= it->last_visible_x)
17757 : (it->current_x > it->last_visible_x)))
17758 {
17759 /* Maybe add truncation glyphs. */
17760 if (!FRAME_WINDOW_P (it->f))
17761 {
17762 int i, n;
17763
17764 if (!row->reversed_p)
17765 {
17766 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
17767 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
17768 break;
17769 }
17770 else
17771 {
17772 for (i = 0; i < row->used[TEXT_AREA]; i++)
17773 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
17774 break;
17775 /* Remove any padding glyphs at the front of ROW, to
17776 make room for the truncation glyphs we will be
17777 adding below. The loop below always inserts at
17778 least one truncation glyph, so also remove the
17779 last glyph added to ROW. */
17780 unproduce_glyphs (it, i + 1);
17781 /* Adjust i for the loop below. */
17782 i = row->used[TEXT_AREA] - (i + 1);
17783 }
17784
17785 for (n = row->used[TEXT_AREA]; i < n; ++i)
17786 {
17787 row->used[TEXT_AREA] = i;
17788 produce_special_glyphs (it, IT_TRUNCATION);
17789 }
17790 }
17791 else if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
17792 {
17793 /* Don't truncate if we can overflow newline into fringe. */
17794 if (!get_next_display_element (it))
17795 {
17796 it->continuation_lines_width = 0;
17797 row->ends_at_zv_p = 1;
17798 row->exact_window_width_line_p = 1;
17799 break;
17800 }
17801 if (ITERATOR_AT_END_OF_LINE_P (it))
17802 {
17803 row->exact_window_width_line_p = 1;
17804 goto at_end_of_line;
17805 }
17806 }
17807
17808 row->truncated_on_right_p = 1;
17809 it->continuation_lines_width = 0;
17810 reseat_at_next_visible_line_start (it, 0);
17811 row->ends_at_zv_p = FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n';
17812 it->hpos = hpos_before;
17813 it->current_x = x_before;
17814 break;
17815 }
17816 }
17817
17818 /* If line is not empty and hscrolled, maybe insert truncation glyphs
17819 at the left window margin. */
17820 if (it->first_visible_x
17821 && IT_CHARPOS (*it) != CHARPOS (row->start.pos))
17822 {
17823 if (!FRAME_WINDOW_P (it->f))
17824 insert_left_trunc_glyphs (it);
17825 row->truncated_on_left_p = 1;
17826 }
17827
17828 /* Remember the position at which this line ends.
17829
17830 BIDI Note: any code that needs MATRIX_ROW_START/END_CHARPOS
17831 cannot be before the call to find_row_edges below, since that is
17832 where these positions are determined. */
17833 row->end = it->current;
17834 if (!it->bidi_p)
17835 {
17836 row->minpos = row->start.pos;
17837 row->maxpos = row->end.pos;
17838 }
17839 else
17840 {
17841 /* ROW->minpos and ROW->maxpos must be the smallest and
17842 `1 + the largest' buffer positions in ROW. But if ROW was
17843 bidi-reordered, these two positions can be anywhere in the
17844 row, so we must determine them now. */
17845 find_row_edges (it, row, min_pos, min_bpos, max_pos, max_bpos);
17846 }
17847
17848 /* If the start of this line is the overlay arrow-position, then
17849 mark this glyph row as the one containing the overlay arrow.
17850 This is clearly a mess with variable size fonts. It would be
17851 better to let it be displayed like cursors under X. */
17852 if ((row->displays_text_p || !overlay_arrow_seen)
17853 && (overlay_arrow_string = overlay_arrow_at_row (it, row),
17854 !NILP (overlay_arrow_string)))
17855 {
17856 /* Overlay arrow in window redisplay is a fringe bitmap. */
17857 if (STRINGP (overlay_arrow_string))
17858 {
17859 struct glyph_row *arrow_row
17860 = get_overlay_arrow_glyph_row (it->w, overlay_arrow_string);
17861 struct glyph *glyph = arrow_row->glyphs[TEXT_AREA];
17862 struct glyph *arrow_end = glyph + arrow_row->used[TEXT_AREA];
17863 struct glyph *p = row->glyphs[TEXT_AREA];
17864 struct glyph *p2, *end;
17865
17866 /* Copy the arrow glyphs. */
17867 while (glyph < arrow_end)
17868 *p++ = *glyph++;
17869
17870 /* Throw away padding glyphs. */
17871 p2 = p;
17872 end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
17873 while (p2 < end && CHAR_GLYPH_PADDING_P (*p2))
17874 ++p2;
17875 if (p2 > p)
17876 {
17877 while (p2 < end)
17878 *p++ = *p2++;
17879 row->used[TEXT_AREA] = p2 - row->glyphs[TEXT_AREA];
17880 }
17881 }
17882 else
17883 {
17884 xassert (INTEGERP (overlay_arrow_string));
17885 row->overlay_arrow_bitmap = XINT (overlay_arrow_string);
17886 }
17887 overlay_arrow_seen = 1;
17888 }
17889
17890 /* Compute pixel dimensions of this line. */
17891 compute_line_metrics (it);
17892
17893 /* Record whether this row ends inside an ellipsis. */
17894 row->ends_in_ellipsis_p
17895 = (it->method == GET_FROM_DISPLAY_VECTOR
17896 && it->ellipsis_p);
17897
17898 /* Save fringe bitmaps in this row. */
17899 row->left_user_fringe_bitmap = it->left_user_fringe_bitmap;
17900 row->left_user_fringe_face_id = it->left_user_fringe_face_id;
17901 row->right_user_fringe_bitmap = it->right_user_fringe_bitmap;
17902 row->right_user_fringe_face_id = it->right_user_fringe_face_id;
17903
17904 it->left_user_fringe_bitmap = 0;
17905 it->left_user_fringe_face_id = 0;
17906 it->right_user_fringe_bitmap = 0;
17907 it->right_user_fringe_face_id = 0;
17908
17909 /* Maybe set the cursor. */
17910 cvpos = it->w->cursor.vpos;
17911 if ((cvpos < 0
17912 /* In bidi-reordered rows, keep checking for proper cursor
17913 position even if one has been found already, because buffer
17914 positions in such rows change non-linearly with ROW->VPOS,
17915 when a line is continued. One exception: when we are at ZV,
17916 display cursor on the first suitable glyph row, since all
17917 the empty rows after that also have their position set to ZV. */
17918 /* FIXME: Revisit this when glyph ``spilling'' in continuation
17919 lines' rows is implemented for bidi-reordered rows. */
17920 || (it->bidi_p
17921 && !MATRIX_ROW (it->w->desired_matrix, cvpos)->ends_at_zv_p))
17922 && PT >= MATRIX_ROW_START_CHARPOS (row)
17923 && PT <= MATRIX_ROW_END_CHARPOS (row)
17924 && cursor_row_p (it->w, row))
17925 set_cursor_from_row (it->w, row, it->w->desired_matrix, 0, 0, 0, 0);
17926
17927 /* Highlight trailing whitespace. */
17928 if (!NILP (Vshow_trailing_whitespace))
17929 highlight_trailing_whitespace (it->f, it->glyph_row);
17930
17931 /* Prepare for the next line. This line starts horizontally at (X
17932 HPOS) = (0 0). Vertical positions are incremented. As a
17933 convenience for the caller, IT->glyph_row is set to the next
17934 row to be used. */
17935 it->current_x = it->hpos = 0;
17936 it->current_y += row->height;
17937 SET_TEXT_POS (it->eol_pos, 0, 0);
17938 ++it->vpos;
17939 ++it->glyph_row;
17940 /* The next row should by default use the same value of the
17941 reversed_p flag as this one. set_iterator_to_next decides when
17942 it's a new paragraph, and PRODUCE_GLYPHS recomputes the value of
17943 the flag accordingly. */
17944 if (it->glyph_row < MATRIX_BOTTOM_TEXT_ROW (it->w->desired_matrix, it->w))
17945 it->glyph_row->reversed_p = row->reversed_p;
17946 it->start = row->end;
17947 return row->displays_text_p;
17948
17949 #undef RECORD_MAX_MIN_POS
17950 }
17951
17952 DEFUN ("current-bidi-paragraph-direction", Fcurrent_bidi_paragraph_direction,
17953 Scurrent_bidi_paragraph_direction, 0, 1, 0,
17954 doc: /* Return paragraph direction at point in BUFFER.
17955 Value is either `left-to-right' or `right-to-left'.
17956 If BUFFER is omitted or nil, it defaults to the current buffer.
17957
17958 Paragraph direction determines how the text in the paragraph is displayed.
17959 In left-to-right paragraphs, text begins at the left margin of the window
17960 and the reading direction is generally left to right. In right-to-left
17961 paragraphs, text begins at the right margin and is read from right to left.
17962
17963 See also `bidi-paragraph-direction'. */)
17964 (Lisp_Object buffer)
17965 {
17966 struct buffer *buf;
17967 struct buffer *old;
17968
17969 if (NILP (buffer))
17970 buf = current_buffer;
17971 else
17972 {
17973 CHECK_BUFFER (buffer);
17974 buf = XBUFFER (buffer);
17975 old = current_buffer;
17976 }
17977
17978 if (NILP (buf->bidi_display_reordering))
17979 return Qleft_to_right;
17980 else if (!NILP (buf->bidi_paragraph_direction))
17981 return buf->bidi_paragraph_direction;
17982 else
17983 {
17984 /* Determine the direction from buffer text. We could try to
17985 use current_matrix if it is up to date, but this seems fast
17986 enough as it is. */
17987 struct bidi_it itb;
17988 EMACS_INT pos = BUF_PT (buf);
17989 EMACS_INT bytepos = BUF_PT_BYTE (buf);
17990 int c;
17991
17992 if (buf != current_buffer)
17993 set_buffer_temp (buf);
17994 /* bidi_paragraph_init finds the base direction of the paragraph
17995 by searching forward from paragraph start. We need the base
17996 direction of the current or _previous_ paragraph, so we need
17997 to make sure we are within that paragraph. To that end, find
17998 the previous non-empty line. */
17999 if (pos >= ZV && pos > BEGV)
18000 {
18001 pos--;
18002 bytepos = CHAR_TO_BYTE (pos);
18003 }
18004 while ((c = FETCH_BYTE (bytepos)) == '\n'
18005 || c == ' ' || c == '\t' || c == '\f')
18006 {
18007 if (bytepos <= BEGV_BYTE)
18008 break;
18009 bytepos--;
18010 pos--;
18011 }
18012 while (!CHAR_HEAD_P (FETCH_BYTE (bytepos)))
18013 bytepos--;
18014 itb.charpos = pos;
18015 itb.bytepos = bytepos;
18016 itb.first_elt = 1;
18017 itb.separator_limit = -1;
18018
18019 bidi_paragraph_init (NEUTRAL_DIR, &itb);
18020 if (buf != current_buffer)
18021 set_buffer_temp (old);
18022 switch (itb.paragraph_dir)
18023 {
18024 case L2R:
18025 return Qleft_to_right;
18026 break;
18027 case R2L:
18028 return Qright_to_left;
18029 break;
18030 default:
18031 abort ();
18032 }
18033 }
18034 }
18035
18036
18037 \f
18038 /***********************************************************************
18039 Menu Bar
18040 ***********************************************************************/
18041
18042 /* Redisplay the menu bar in the frame for window W.
18043
18044 The menu bar of X frames that don't have X toolkit support is
18045 displayed in a special window W->frame->menu_bar_window.
18046
18047 The menu bar of terminal frames is treated specially as far as
18048 glyph matrices are concerned. Menu bar lines are not part of
18049 windows, so the update is done directly on the frame matrix rows
18050 for the menu bar. */
18051
18052 static void
18053 display_menu_bar (struct window *w)
18054 {
18055 struct frame *f = XFRAME (WINDOW_FRAME (w));
18056 struct it it;
18057 Lisp_Object items;
18058 int i;
18059
18060 /* Don't do all this for graphical frames. */
18061 #ifdef HAVE_NTGUI
18062 if (FRAME_W32_P (f))
18063 return;
18064 #endif
18065 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
18066 if (FRAME_X_P (f))
18067 return;
18068 #endif
18069
18070 #ifdef HAVE_NS
18071 if (FRAME_NS_P (f))
18072 return;
18073 #endif /* HAVE_NS */
18074
18075 #ifdef USE_X_TOOLKIT
18076 xassert (!FRAME_WINDOW_P (f));
18077 init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MENU_FACE_ID);
18078 it.first_visible_x = 0;
18079 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
18080 #else /* not USE_X_TOOLKIT */
18081 if (FRAME_WINDOW_P (f))
18082 {
18083 /* Menu bar lines are displayed in the desired matrix of the
18084 dummy window menu_bar_window. */
18085 struct window *menu_w;
18086 xassert (WINDOWP (f->menu_bar_window));
18087 menu_w = XWINDOW (f->menu_bar_window);
18088 init_iterator (&it, menu_w, -1, -1, menu_w->desired_matrix->rows,
18089 MENU_FACE_ID);
18090 it.first_visible_x = 0;
18091 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
18092 }
18093 else
18094 {
18095 /* This is a TTY frame, i.e. character hpos/vpos are used as
18096 pixel x/y. */
18097 init_iterator (&it, w, -1, -1, f->desired_matrix->rows,
18098 MENU_FACE_ID);
18099 it.first_visible_x = 0;
18100 it.last_visible_x = FRAME_COLS (f);
18101 }
18102 #endif /* not USE_X_TOOLKIT */
18103
18104 if (! mode_line_inverse_video)
18105 /* Force the menu-bar to be displayed in the default face. */
18106 it.base_face_id = it.face_id = DEFAULT_FACE_ID;
18107
18108 /* Clear all rows of the menu bar. */
18109 for (i = 0; i < FRAME_MENU_BAR_LINES (f); ++i)
18110 {
18111 struct glyph_row *row = it.glyph_row + i;
18112 clear_glyph_row (row);
18113 row->enabled_p = 1;
18114 row->full_width_p = 1;
18115 }
18116
18117 /* Display all items of the menu bar. */
18118 items = FRAME_MENU_BAR_ITEMS (it.f);
18119 for (i = 0; i < XVECTOR (items)->size; i += 4)
18120 {
18121 Lisp_Object string;
18122
18123 /* Stop at nil string. */
18124 string = AREF (items, i + 1);
18125 if (NILP (string))
18126 break;
18127
18128 /* Remember where item was displayed. */
18129 ASET (items, i + 3, make_number (it.hpos));
18130
18131 /* Display the item, pad with one space. */
18132 if (it.current_x < it.last_visible_x)
18133 display_string (NULL, string, Qnil, 0, 0, &it,
18134 SCHARS (string) + 1, 0, 0, -1);
18135 }
18136
18137 /* Fill out the line with spaces. */
18138 if (it.current_x < it.last_visible_x)
18139 display_string ("", Qnil, Qnil, 0, 0, &it, -1, 0, 0, -1);
18140
18141 /* Compute the total height of the lines. */
18142 compute_line_metrics (&it);
18143 }
18144
18145
18146 \f
18147 /***********************************************************************
18148 Mode Line
18149 ***********************************************************************/
18150
18151 /* Redisplay mode lines in the window tree whose root is WINDOW. If
18152 FORCE is non-zero, redisplay mode lines unconditionally.
18153 Otherwise, redisplay only mode lines that are garbaged. Value is
18154 the number of windows whose mode lines were redisplayed. */
18155
18156 static int
18157 redisplay_mode_lines (Lisp_Object window, int force)
18158 {
18159 int nwindows = 0;
18160
18161 while (!NILP (window))
18162 {
18163 struct window *w = XWINDOW (window);
18164
18165 if (WINDOWP (w->hchild))
18166 nwindows += redisplay_mode_lines (w->hchild, force);
18167 else if (WINDOWP (w->vchild))
18168 nwindows += redisplay_mode_lines (w->vchild, force);
18169 else if (force
18170 || FRAME_GARBAGED_P (XFRAME (w->frame))
18171 || !MATRIX_MODE_LINE_ROW (w->current_matrix)->enabled_p)
18172 {
18173 struct text_pos lpoint;
18174 struct buffer *old = current_buffer;
18175
18176 /* Set the window's buffer for the mode line display. */
18177 SET_TEXT_POS (lpoint, PT, PT_BYTE);
18178 set_buffer_internal_1 (XBUFFER (w->buffer));
18179
18180 /* Point refers normally to the selected window. For any
18181 other window, set up appropriate value. */
18182 if (!EQ (window, selected_window))
18183 {
18184 struct text_pos pt;
18185
18186 SET_TEXT_POS_FROM_MARKER (pt, w->pointm);
18187 if (CHARPOS (pt) < BEGV)
18188 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
18189 else if (CHARPOS (pt) > (ZV - 1))
18190 TEMP_SET_PT_BOTH (ZV, ZV_BYTE);
18191 else
18192 TEMP_SET_PT_BOTH (CHARPOS (pt), BYTEPOS (pt));
18193 }
18194
18195 /* Display mode lines. */
18196 clear_glyph_matrix (w->desired_matrix);
18197 if (display_mode_lines (w))
18198 {
18199 ++nwindows;
18200 w->must_be_updated_p = 1;
18201 }
18202
18203 /* Restore old settings. */
18204 set_buffer_internal_1 (old);
18205 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
18206 }
18207
18208 window = w->next;
18209 }
18210
18211 return nwindows;
18212 }
18213
18214
18215 /* Display the mode and/or header line of window W. Value is the
18216 sum number of mode lines and header lines displayed. */
18217
18218 static int
18219 display_mode_lines (struct window *w)
18220 {
18221 Lisp_Object old_selected_window, old_selected_frame;
18222 int n = 0;
18223
18224 old_selected_frame = selected_frame;
18225 selected_frame = w->frame;
18226 old_selected_window = selected_window;
18227 XSETWINDOW (selected_window, w);
18228
18229 /* These will be set while the mode line specs are processed. */
18230 line_number_displayed = 0;
18231 w->column_number_displayed = Qnil;
18232
18233 if (WINDOW_WANTS_MODELINE_P (w))
18234 {
18235 struct window *sel_w = XWINDOW (old_selected_window);
18236
18237 /* Select mode line face based on the real selected window. */
18238 display_mode_line (w, CURRENT_MODE_LINE_FACE_ID_3 (sel_w, sel_w, w),
18239 current_buffer->mode_line_format);
18240 ++n;
18241 }
18242
18243 if (WINDOW_WANTS_HEADER_LINE_P (w))
18244 {
18245 display_mode_line (w, HEADER_LINE_FACE_ID,
18246 current_buffer->header_line_format);
18247 ++n;
18248 }
18249
18250 selected_frame = old_selected_frame;
18251 selected_window = old_selected_window;
18252 return n;
18253 }
18254
18255
18256 /* Display mode or header line of window W. FACE_ID specifies which
18257 line to display; it is either MODE_LINE_FACE_ID or
18258 HEADER_LINE_FACE_ID. FORMAT is the mode/header line format to
18259 display. Value is the pixel height of the mode/header line
18260 displayed. */
18261
18262 static int
18263 display_mode_line (struct window *w, enum face_id face_id, Lisp_Object format)
18264 {
18265 struct it it;
18266 struct face *face;
18267 int count = SPECPDL_INDEX ();
18268
18269 init_iterator (&it, w, -1, -1, NULL, face_id);
18270 /* Don't extend on a previously drawn mode-line.
18271 This may happen if called from pos_visible_p. */
18272 it.glyph_row->enabled_p = 0;
18273 prepare_desired_row (it.glyph_row);
18274
18275 it.glyph_row->mode_line_p = 1;
18276
18277 if (! mode_line_inverse_video)
18278 /* Force the mode-line to be displayed in the default face. */
18279 it.base_face_id = it.face_id = DEFAULT_FACE_ID;
18280
18281 record_unwind_protect (unwind_format_mode_line,
18282 format_mode_line_unwind_data (NULL, Qnil, 0));
18283
18284 mode_line_target = MODE_LINE_DISPLAY;
18285
18286 /* Temporarily make frame's keyboard the current kboard so that
18287 kboard-local variables in the mode_line_format will get the right
18288 values. */
18289 push_kboard (FRAME_KBOARD (it.f));
18290 record_unwind_save_match_data ();
18291 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
18292 pop_kboard ();
18293
18294 unbind_to (count, Qnil);
18295
18296 /* Fill up with spaces. */
18297 display_string (" ", Qnil, Qnil, 0, 0, &it, 10000, -1, -1, 0);
18298
18299 compute_line_metrics (&it);
18300 it.glyph_row->full_width_p = 1;
18301 it.glyph_row->continued_p = 0;
18302 it.glyph_row->truncated_on_left_p = 0;
18303 it.glyph_row->truncated_on_right_p = 0;
18304
18305 /* Make a 3D mode-line have a shadow at its right end. */
18306 face = FACE_FROM_ID (it.f, face_id);
18307 extend_face_to_end_of_line (&it);
18308 if (face->box != FACE_NO_BOX)
18309 {
18310 struct glyph *last = (it.glyph_row->glyphs[TEXT_AREA]
18311 + it.glyph_row->used[TEXT_AREA] - 1);
18312 last->right_box_line_p = 1;
18313 }
18314
18315 return it.glyph_row->height;
18316 }
18317
18318 /* Move element ELT in LIST to the front of LIST.
18319 Return the updated list. */
18320
18321 static Lisp_Object
18322 move_elt_to_front (Lisp_Object elt, Lisp_Object list)
18323 {
18324 register Lisp_Object tail, prev;
18325 register Lisp_Object tem;
18326
18327 tail = list;
18328 prev = Qnil;
18329 while (CONSP (tail))
18330 {
18331 tem = XCAR (tail);
18332
18333 if (EQ (elt, tem))
18334 {
18335 /* Splice out the link TAIL. */
18336 if (NILP (prev))
18337 list = XCDR (tail);
18338 else
18339 Fsetcdr (prev, XCDR (tail));
18340
18341 /* Now make it the first. */
18342 Fsetcdr (tail, list);
18343 return tail;
18344 }
18345 else
18346 prev = tail;
18347 tail = XCDR (tail);
18348 QUIT;
18349 }
18350
18351 /* Not found--return unchanged LIST. */
18352 return list;
18353 }
18354
18355 /* Contribute ELT to the mode line for window IT->w. How it
18356 translates into text depends on its data type.
18357
18358 IT describes the display environment in which we display, as usual.
18359
18360 DEPTH is the depth in recursion. It is used to prevent
18361 infinite recursion here.
18362
18363 FIELD_WIDTH is the number of characters the display of ELT should
18364 occupy in the mode line, and PRECISION is the maximum number of
18365 characters to display from ELT's representation. See
18366 display_string for details.
18367
18368 Returns the hpos of the end of the text generated by ELT.
18369
18370 PROPS is a property list to add to any string we encounter.
18371
18372 If RISKY is nonzero, remove (disregard) any properties in any string
18373 we encounter, and ignore :eval and :propertize.
18374
18375 The global variable `mode_line_target' determines whether the
18376 output is passed to `store_mode_line_noprop',
18377 `store_mode_line_string', or `display_string'. */
18378
18379 static int
18380 display_mode_element (struct it *it, int depth, int field_width, int precision,
18381 Lisp_Object elt, Lisp_Object props, int risky)
18382 {
18383 int n = 0, field, prec;
18384 int literal = 0;
18385
18386 tail_recurse:
18387 if (depth > 100)
18388 elt = build_string ("*too-deep*");
18389
18390 depth++;
18391
18392 switch (SWITCH_ENUM_CAST (XTYPE (elt)))
18393 {
18394 case Lisp_String:
18395 {
18396 /* A string: output it and check for %-constructs within it. */
18397 unsigned char c;
18398 int offset = 0;
18399
18400 if (SCHARS (elt) > 0
18401 && (!NILP (props) || risky))
18402 {
18403 Lisp_Object oprops, aelt;
18404 oprops = Ftext_properties_at (make_number (0), elt);
18405
18406 /* If the starting string's properties are not what
18407 we want, translate the string. Also, if the string
18408 is risky, do that anyway. */
18409
18410 if (NILP (Fequal (props, oprops)) || risky)
18411 {
18412 /* If the starting string has properties,
18413 merge the specified ones onto the existing ones. */
18414 if (! NILP (oprops) && !risky)
18415 {
18416 Lisp_Object tem;
18417
18418 oprops = Fcopy_sequence (oprops);
18419 tem = props;
18420 while (CONSP (tem))
18421 {
18422 oprops = Fplist_put (oprops, XCAR (tem),
18423 XCAR (XCDR (tem)));
18424 tem = XCDR (XCDR (tem));
18425 }
18426 props = oprops;
18427 }
18428
18429 aelt = Fassoc (elt, mode_line_proptrans_alist);
18430 if (! NILP (aelt) && !NILP (Fequal (props, XCDR (aelt))))
18431 {
18432 /* AELT is what we want. Move it to the front
18433 without consing. */
18434 elt = XCAR (aelt);
18435 mode_line_proptrans_alist
18436 = move_elt_to_front (aelt, mode_line_proptrans_alist);
18437 }
18438 else
18439 {
18440 Lisp_Object tem;
18441
18442 /* If AELT has the wrong props, it is useless.
18443 so get rid of it. */
18444 if (! NILP (aelt))
18445 mode_line_proptrans_alist
18446 = Fdelq (aelt, mode_line_proptrans_alist);
18447
18448 elt = Fcopy_sequence (elt);
18449 Fset_text_properties (make_number (0), Flength (elt),
18450 props, elt);
18451 /* Add this item to mode_line_proptrans_alist. */
18452 mode_line_proptrans_alist
18453 = Fcons (Fcons (elt, props),
18454 mode_line_proptrans_alist);
18455 /* Truncate mode_line_proptrans_alist
18456 to at most 50 elements. */
18457 tem = Fnthcdr (make_number (50),
18458 mode_line_proptrans_alist);
18459 if (! NILP (tem))
18460 XSETCDR (tem, Qnil);
18461 }
18462 }
18463 }
18464
18465 offset = 0;
18466
18467 if (literal)
18468 {
18469 prec = precision - n;
18470 switch (mode_line_target)
18471 {
18472 case MODE_LINE_NOPROP:
18473 case MODE_LINE_TITLE:
18474 n += store_mode_line_noprop (SDATA (elt), -1, prec);
18475 break;
18476 case MODE_LINE_STRING:
18477 n += store_mode_line_string (NULL, elt, 1, 0, prec, Qnil);
18478 break;
18479 case MODE_LINE_DISPLAY:
18480 n += display_string (NULL, elt, Qnil, 0, 0, it,
18481 0, prec, 0, STRING_MULTIBYTE (elt));
18482 break;
18483 }
18484
18485 break;
18486 }
18487
18488 /* Handle the non-literal case. */
18489
18490 while ((precision <= 0 || n < precision)
18491 && SREF (elt, offset) != 0
18492 && (mode_line_target != MODE_LINE_DISPLAY
18493 || it->current_x < it->last_visible_x))
18494 {
18495 int last_offset = offset;
18496
18497 /* Advance to end of string or next format specifier. */
18498 while ((c = SREF (elt, offset++)) != '\0' && c != '%')
18499 ;
18500
18501 if (offset - 1 != last_offset)
18502 {
18503 int nchars, nbytes;
18504
18505 /* Output to end of string or up to '%'. Field width
18506 is length of string. Don't output more than
18507 PRECISION allows us. */
18508 offset--;
18509
18510 prec = c_string_width (SDATA (elt) + last_offset,
18511 offset - last_offset, precision - n,
18512 &nchars, &nbytes);
18513
18514 switch (mode_line_target)
18515 {
18516 case MODE_LINE_NOPROP:
18517 case MODE_LINE_TITLE:
18518 n += store_mode_line_noprop (SDATA (elt) + last_offset, 0, prec);
18519 break;
18520 case MODE_LINE_STRING:
18521 {
18522 int bytepos = last_offset;
18523 int charpos = string_byte_to_char (elt, bytepos);
18524 int endpos = (precision <= 0
18525 ? string_byte_to_char (elt, offset)
18526 : charpos + nchars);
18527
18528 n += store_mode_line_string (NULL,
18529 Fsubstring (elt, make_number (charpos),
18530 make_number (endpos)),
18531 0, 0, 0, Qnil);
18532 }
18533 break;
18534 case MODE_LINE_DISPLAY:
18535 {
18536 int bytepos = last_offset;
18537 int charpos = string_byte_to_char (elt, bytepos);
18538
18539 if (precision <= 0)
18540 nchars = string_byte_to_char (elt, offset) - charpos;
18541 n += display_string (NULL, elt, Qnil, 0, charpos,
18542 it, 0, nchars, 0,
18543 STRING_MULTIBYTE (elt));
18544 }
18545 break;
18546 }
18547 }
18548 else /* c == '%' */
18549 {
18550 int percent_position = offset;
18551
18552 /* Get the specified minimum width. Zero means
18553 don't pad. */
18554 field = 0;
18555 while ((c = SREF (elt, offset++)) >= '0' && c <= '9')
18556 field = field * 10 + c - '0';
18557
18558 /* Don't pad beyond the total padding allowed. */
18559 if (field_width - n > 0 && field > field_width - n)
18560 field = field_width - n;
18561
18562 /* Note that either PRECISION <= 0 or N < PRECISION. */
18563 prec = precision - n;
18564
18565 if (c == 'M')
18566 n += display_mode_element (it, depth, field, prec,
18567 Vglobal_mode_string, props,
18568 risky);
18569 else if (c != 0)
18570 {
18571 int multibyte;
18572 int bytepos, charpos;
18573 const unsigned char *spec;
18574 Lisp_Object string;
18575
18576 bytepos = percent_position;
18577 charpos = (STRING_MULTIBYTE (elt)
18578 ? string_byte_to_char (elt, bytepos)
18579 : bytepos);
18580 spec = decode_mode_spec (it->w, c, field, prec, &string);
18581 multibyte = STRINGP (string) && STRING_MULTIBYTE (string);
18582
18583 switch (mode_line_target)
18584 {
18585 case MODE_LINE_NOPROP:
18586 case MODE_LINE_TITLE:
18587 n += store_mode_line_noprop (spec, field, prec);
18588 break;
18589 case MODE_LINE_STRING:
18590 {
18591 int len = strlen (spec);
18592 Lisp_Object tem = make_string (spec, len);
18593 props = Ftext_properties_at (make_number (charpos), elt);
18594 /* Should only keep face property in props */
18595 n += store_mode_line_string (NULL, tem, 0, field, prec, props);
18596 }
18597 break;
18598 case MODE_LINE_DISPLAY:
18599 {
18600 int nglyphs_before, nwritten;
18601
18602 nglyphs_before = it->glyph_row->used[TEXT_AREA];
18603 nwritten = display_string (spec, string, elt,
18604 charpos, 0, it,
18605 field, prec, 0,
18606 multibyte);
18607
18608 /* Assign to the glyphs written above the
18609 string where the `%x' came from, position
18610 of the `%'. */
18611 if (nwritten > 0)
18612 {
18613 struct glyph *glyph
18614 = (it->glyph_row->glyphs[TEXT_AREA]
18615 + nglyphs_before);
18616 int i;
18617
18618 for (i = 0; i < nwritten; ++i)
18619 {
18620 glyph[i].object = elt;
18621 glyph[i].charpos = charpos;
18622 }
18623
18624 n += nwritten;
18625 }
18626 }
18627 break;
18628 }
18629 }
18630 else /* c == 0 */
18631 break;
18632 }
18633 }
18634 }
18635 break;
18636
18637 case Lisp_Symbol:
18638 /* A symbol: process the value of the symbol recursively
18639 as if it appeared here directly. Avoid error if symbol void.
18640 Special case: if value of symbol is a string, output the string
18641 literally. */
18642 {
18643 register Lisp_Object tem;
18644
18645 /* If the variable is not marked as risky to set
18646 then its contents are risky to use. */
18647 if (NILP (Fget (elt, Qrisky_local_variable)))
18648 risky = 1;
18649
18650 tem = Fboundp (elt);
18651 if (!NILP (tem))
18652 {
18653 tem = Fsymbol_value (elt);
18654 /* If value is a string, output that string literally:
18655 don't check for % within it. */
18656 if (STRINGP (tem))
18657 literal = 1;
18658
18659 if (!EQ (tem, elt))
18660 {
18661 /* Give up right away for nil or t. */
18662 elt = tem;
18663 goto tail_recurse;
18664 }
18665 }
18666 }
18667 break;
18668
18669 case Lisp_Cons:
18670 {
18671 register Lisp_Object car, tem;
18672
18673 /* A cons cell: five distinct cases.
18674 If first element is :eval or :propertize, do something special.
18675 If first element is a string or a cons, process all the elements
18676 and effectively concatenate them.
18677 If first element is a negative number, truncate displaying cdr to
18678 at most that many characters. If positive, pad (with spaces)
18679 to at least that many characters.
18680 If first element is a symbol, process the cadr or caddr recursively
18681 according to whether the symbol's value is non-nil or nil. */
18682 car = XCAR (elt);
18683 if (EQ (car, QCeval))
18684 {
18685 /* An element of the form (:eval FORM) means evaluate FORM
18686 and use the result as mode line elements. */
18687
18688 if (risky)
18689 break;
18690
18691 if (CONSP (XCDR (elt)))
18692 {
18693 Lisp_Object spec;
18694 spec = safe_eval (XCAR (XCDR (elt)));
18695 n += display_mode_element (it, depth, field_width - n,
18696 precision - n, spec, props,
18697 risky);
18698 }
18699 }
18700 else if (EQ (car, QCpropertize))
18701 {
18702 /* An element of the form (:propertize ELT PROPS...)
18703 means display ELT but applying properties PROPS. */
18704
18705 if (risky)
18706 break;
18707
18708 if (CONSP (XCDR (elt)))
18709 n += display_mode_element (it, depth, field_width - n,
18710 precision - n, XCAR (XCDR (elt)),
18711 XCDR (XCDR (elt)), risky);
18712 }
18713 else if (SYMBOLP (car))
18714 {
18715 tem = Fboundp (car);
18716 elt = XCDR (elt);
18717 if (!CONSP (elt))
18718 goto invalid;
18719 /* elt is now the cdr, and we know it is a cons cell.
18720 Use its car if CAR has a non-nil value. */
18721 if (!NILP (tem))
18722 {
18723 tem = Fsymbol_value (car);
18724 if (!NILP (tem))
18725 {
18726 elt = XCAR (elt);
18727 goto tail_recurse;
18728 }
18729 }
18730 /* Symbol's value is nil (or symbol is unbound)
18731 Get the cddr of the original list
18732 and if possible find the caddr and use that. */
18733 elt = XCDR (elt);
18734 if (NILP (elt))
18735 break;
18736 else if (!CONSP (elt))
18737 goto invalid;
18738 elt = XCAR (elt);
18739 goto tail_recurse;
18740 }
18741 else if (INTEGERP (car))
18742 {
18743 register int lim = XINT (car);
18744 elt = XCDR (elt);
18745 if (lim < 0)
18746 {
18747 /* Negative int means reduce maximum width. */
18748 if (precision <= 0)
18749 precision = -lim;
18750 else
18751 precision = min (precision, -lim);
18752 }
18753 else if (lim > 0)
18754 {
18755 /* Padding specified. Don't let it be more than
18756 current maximum. */
18757 if (precision > 0)
18758 lim = min (precision, lim);
18759
18760 /* If that's more padding than already wanted, queue it.
18761 But don't reduce padding already specified even if
18762 that is beyond the current truncation point. */
18763 field_width = max (lim, field_width);
18764 }
18765 goto tail_recurse;
18766 }
18767 else if (STRINGP (car) || CONSP (car))
18768 {
18769 Lisp_Object halftail = elt;
18770 int len = 0;
18771
18772 while (CONSP (elt)
18773 && (precision <= 0 || n < precision))
18774 {
18775 n += display_mode_element (it, depth,
18776 /* Do padding only after the last
18777 element in the list. */
18778 (! CONSP (XCDR (elt))
18779 ? field_width - n
18780 : 0),
18781 precision - n, XCAR (elt),
18782 props, risky);
18783 elt = XCDR (elt);
18784 len++;
18785 if ((len & 1) == 0)
18786 halftail = XCDR (halftail);
18787 /* Check for cycle. */
18788 if (EQ (halftail, elt))
18789 break;
18790 }
18791 }
18792 }
18793 break;
18794
18795 default:
18796 invalid:
18797 elt = build_string ("*invalid*");
18798 goto tail_recurse;
18799 }
18800
18801 /* Pad to FIELD_WIDTH. */
18802 if (field_width > 0 && n < field_width)
18803 {
18804 switch (mode_line_target)
18805 {
18806 case MODE_LINE_NOPROP:
18807 case MODE_LINE_TITLE:
18808 n += store_mode_line_noprop ("", field_width - n, 0);
18809 break;
18810 case MODE_LINE_STRING:
18811 n += store_mode_line_string ("", Qnil, 0, field_width - n, 0, Qnil);
18812 break;
18813 case MODE_LINE_DISPLAY:
18814 n += display_string ("", Qnil, Qnil, 0, 0, it, field_width - n,
18815 0, 0, 0);
18816 break;
18817 }
18818 }
18819
18820 return n;
18821 }
18822
18823 /* Store a mode-line string element in mode_line_string_list.
18824
18825 If STRING is non-null, display that C string. Otherwise, the Lisp
18826 string LISP_STRING is displayed.
18827
18828 FIELD_WIDTH is the minimum number of output glyphs to produce.
18829 If STRING has fewer characters than FIELD_WIDTH, pad to the right
18830 with spaces. FIELD_WIDTH <= 0 means don't pad.
18831
18832 PRECISION is the maximum number of characters to output from
18833 STRING. PRECISION <= 0 means don't truncate the string.
18834
18835 If COPY_STRING is non-zero, make a copy of LISP_STRING before adding
18836 properties to the string.
18837
18838 PROPS are the properties to add to the string.
18839 The mode_line_string_face face property is always added to the string.
18840 */
18841
18842 static int
18843 store_mode_line_string (const char *string, Lisp_Object lisp_string, int copy_string,
18844 int field_width, int precision, Lisp_Object props)
18845 {
18846 int len;
18847 int n = 0;
18848
18849 if (string != NULL)
18850 {
18851 len = strlen (string);
18852 if (precision > 0 && len > precision)
18853 len = precision;
18854 lisp_string = make_string (string, len);
18855 if (NILP (props))
18856 props = mode_line_string_face_prop;
18857 else if (!NILP (mode_line_string_face))
18858 {
18859 Lisp_Object face = Fplist_get (props, Qface);
18860 props = Fcopy_sequence (props);
18861 if (NILP (face))
18862 face = mode_line_string_face;
18863 else
18864 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
18865 props = Fplist_put (props, Qface, face);
18866 }
18867 Fadd_text_properties (make_number (0), make_number (len),
18868 props, lisp_string);
18869 }
18870 else
18871 {
18872 len = XFASTINT (Flength (lisp_string));
18873 if (precision > 0 && len > precision)
18874 {
18875 len = precision;
18876 lisp_string = Fsubstring (lisp_string, make_number (0), make_number (len));
18877 precision = -1;
18878 }
18879 if (!NILP (mode_line_string_face))
18880 {
18881 Lisp_Object face;
18882 if (NILP (props))
18883 props = Ftext_properties_at (make_number (0), lisp_string);
18884 face = Fplist_get (props, Qface);
18885 if (NILP (face))
18886 face = mode_line_string_face;
18887 else
18888 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
18889 props = Fcons (Qface, Fcons (face, Qnil));
18890 if (copy_string)
18891 lisp_string = Fcopy_sequence (lisp_string);
18892 }
18893 if (!NILP (props))
18894 Fadd_text_properties (make_number (0), make_number (len),
18895 props, lisp_string);
18896 }
18897
18898 if (len > 0)
18899 {
18900 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
18901 n += len;
18902 }
18903
18904 if (field_width > len)
18905 {
18906 field_width -= len;
18907 lisp_string = Fmake_string (make_number (field_width), make_number (' '));
18908 if (!NILP (props))
18909 Fadd_text_properties (make_number (0), make_number (field_width),
18910 props, lisp_string);
18911 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
18912 n += field_width;
18913 }
18914
18915 return n;
18916 }
18917
18918
18919 DEFUN ("format-mode-line", Fformat_mode_line, Sformat_mode_line,
18920 1, 4, 0,
18921 doc: /* Format a string out of a mode line format specification.
18922 First arg FORMAT specifies the mode line format (see `mode-line-format'
18923 for details) to use.
18924
18925 Optional second arg FACE specifies the face property to put
18926 on all characters for which no face is specified.
18927 The value t means whatever face the window's mode line currently uses
18928 \(either `mode-line' or `mode-line-inactive', depending).
18929 A value of nil means the default is no face property.
18930 If FACE is an integer, the value string has no text properties.
18931
18932 Optional third and fourth args WINDOW and BUFFER specify the window
18933 and buffer to use as the context for the formatting (defaults
18934 are the selected window and the window's buffer). */)
18935 (Lisp_Object format, Lisp_Object face, Lisp_Object window, Lisp_Object buffer)
18936 {
18937 struct it it;
18938 int len;
18939 struct window *w;
18940 struct buffer *old_buffer = NULL;
18941 int face_id = -1;
18942 int no_props = INTEGERP (face);
18943 int count = SPECPDL_INDEX ();
18944 Lisp_Object str;
18945 int string_start = 0;
18946
18947 if (NILP (window))
18948 window = selected_window;
18949 CHECK_WINDOW (window);
18950 w = XWINDOW (window);
18951
18952 if (NILP (buffer))
18953 buffer = w->buffer;
18954 CHECK_BUFFER (buffer);
18955
18956 /* Make formatting the modeline a non-op when noninteractive, otherwise
18957 there will be problems later caused by a partially initialized frame. */
18958 if (NILP (format) || noninteractive)
18959 return empty_unibyte_string;
18960
18961 if (no_props)
18962 face = Qnil;
18963
18964 if (!NILP (face))
18965 {
18966 if (EQ (face, Qt))
18967 face = (EQ (window, selected_window) ? Qmode_line : Qmode_line_inactive);
18968 face_id = lookup_named_face (XFRAME (WINDOW_FRAME (w)), face, 0);
18969 }
18970
18971 if (face_id < 0)
18972 face_id = DEFAULT_FACE_ID;
18973
18974 if (XBUFFER (buffer) != current_buffer)
18975 old_buffer = current_buffer;
18976
18977 /* Save things including mode_line_proptrans_alist,
18978 and set that to nil so that we don't alter the outer value. */
18979 record_unwind_protect (unwind_format_mode_line,
18980 format_mode_line_unwind_data
18981 (old_buffer, selected_window, 1));
18982 mode_line_proptrans_alist = Qnil;
18983
18984 Fselect_window (window, Qt);
18985 if (old_buffer)
18986 set_buffer_internal_1 (XBUFFER (buffer));
18987
18988 init_iterator (&it, w, -1, -1, NULL, face_id);
18989
18990 if (no_props)
18991 {
18992 mode_line_target = MODE_LINE_NOPROP;
18993 mode_line_string_face_prop = Qnil;
18994 mode_line_string_list = Qnil;
18995 string_start = MODE_LINE_NOPROP_LEN (0);
18996 }
18997 else
18998 {
18999 mode_line_target = MODE_LINE_STRING;
19000 mode_line_string_list = Qnil;
19001 mode_line_string_face = face;
19002 mode_line_string_face_prop
19003 = (NILP (face) ? Qnil : Fcons (Qface, Fcons (face, Qnil)));
19004 }
19005
19006 push_kboard (FRAME_KBOARD (it.f));
19007 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
19008 pop_kboard ();
19009
19010 if (no_props)
19011 {
19012 len = MODE_LINE_NOPROP_LEN (string_start);
19013 str = make_string (mode_line_noprop_buf + string_start, len);
19014 }
19015 else
19016 {
19017 mode_line_string_list = Fnreverse (mode_line_string_list);
19018 str = Fmapconcat (intern ("identity"), mode_line_string_list,
19019 empty_unibyte_string);
19020 }
19021
19022 unbind_to (count, Qnil);
19023 return str;
19024 }
19025
19026 /* Write a null-terminated, right justified decimal representation of
19027 the positive integer D to BUF using a minimal field width WIDTH. */
19028
19029 static void
19030 pint2str (register char *buf, register int width, register int d)
19031 {
19032 register char *p = buf;
19033
19034 if (d <= 0)
19035 *p++ = '0';
19036 else
19037 {
19038 while (d > 0)
19039 {
19040 *p++ = d % 10 + '0';
19041 d /= 10;
19042 }
19043 }
19044
19045 for (width -= (int) (p - buf); width > 0; --width)
19046 *p++ = ' ';
19047 *p-- = '\0';
19048 while (p > buf)
19049 {
19050 d = *buf;
19051 *buf++ = *p;
19052 *p-- = d;
19053 }
19054 }
19055
19056 /* Write a null-terminated, right justified decimal and "human
19057 readable" representation of the nonnegative integer D to BUF using
19058 a minimal field width WIDTH. D should be smaller than 999.5e24. */
19059
19060 static const char power_letter[] =
19061 {
19062 0, /* not used */
19063 'k', /* kilo */
19064 'M', /* mega */
19065 'G', /* giga */
19066 'T', /* tera */
19067 'P', /* peta */
19068 'E', /* exa */
19069 'Z', /* zetta */
19070 'Y' /* yotta */
19071 };
19072
19073 static void
19074 pint2hrstr (char *buf, int width, int d)
19075 {
19076 /* We aim to represent the nonnegative integer D as
19077 QUOTIENT.TENTHS * 10 ^ (3 * EXPONENT). */
19078 int quotient = d;
19079 int remainder = 0;
19080 /* -1 means: do not use TENTHS. */
19081 int tenths = -1;
19082 int exponent = 0;
19083
19084 /* Length of QUOTIENT.TENTHS as a string. */
19085 int length;
19086
19087 char * psuffix;
19088 char * p;
19089
19090 if (1000 <= quotient)
19091 {
19092 /* Scale to the appropriate EXPONENT. */
19093 do
19094 {
19095 remainder = quotient % 1000;
19096 quotient /= 1000;
19097 exponent++;
19098 }
19099 while (1000 <= quotient);
19100
19101 /* Round to nearest and decide whether to use TENTHS or not. */
19102 if (quotient <= 9)
19103 {
19104 tenths = remainder / 100;
19105 if (50 <= remainder % 100)
19106 {
19107 if (tenths < 9)
19108 tenths++;
19109 else
19110 {
19111 quotient++;
19112 if (quotient == 10)
19113 tenths = -1;
19114 else
19115 tenths = 0;
19116 }
19117 }
19118 }
19119 else
19120 if (500 <= remainder)
19121 {
19122 if (quotient < 999)
19123 quotient++;
19124 else
19125 {
19126 quotient = 1;
19127 exponent++;
19128 tenths = 0;
19129 }
19130 }
19131 }
19132
19133 /* Calculate the LENGTH of QUOTIENT.TENTHS as a string. */
19134 if (tenths == -1 && quotient <= 99)
19135 if (quotient <= 9)
19136 length = 1;
19137 else
19138 length = 2;
19139 else
19140 length = 3;
19141 p = psuffix = buf + max (width, length);
19142
19143 /* Print EXPONENT. */
19144 if (exponent)
19145 *psuffix++ = power_letter[exponent];
19146 *psuffix = '\0';
19147
19148 /* Print TENTHS. */
19149 if (tenths >= 0)
19150 {
19151 *--p = '0' + tenths;
19152 *--p = '.';
19153 }
19154
19155 /* Print QUOTIENT. */
19156 do
19157 {
19158 int digit = quotient % 10;
19159 *--p = '0' + digit;
19160 }
19161 while ((quotient /= 10) != 0);
19162
19163 /* Print leading spaces. */
19164 while (buf < p)
19165 *--p = ' ';
19166 }
19167
19168 /* Set a mnemonic character for coding_system (Lisp symbol) in BUF.
19169 If EOL_FLAG is 1, set also a mnemonic character for end-of-line
19170 type of CODING_SYSTEM. Return updated pointer into BUF. */
19171
19172 static unsigned char invalid_eol_type[] = "(*invalid*)";
19173
19174 static char *
19175 decode_mode_spec_coding (Lisp_Object coding_system, register char *buf, int eol_flag)
19176 {
19177 Lisp_Object val;
19178 int multibyte = !NILP (current_buffer->enable_multibyte_characters);
19179 const unsigned char *eol_str;
19180 int eol_str_len;
19181 /* The EOL conversion we are using. */
19182 Lisp_Object eoltype;
19183
19184 val = CODING_SYSTEM_SPEC (coding_system);
19185 eoltype = Qnil;
19186
19187 if (!VECTORP (val)) /* Not yet decided. */
19188 {
19189 if (multibyte)
19190 *buf++ = '-';
19191 if (eol_flag)
19192 eoltype = eol_mnemonic_undecided;
19193 /* Don't mention EOL conversion if it isn't decided. */
19194 }
19195 else
19196 {
19197 Lisp_Object attrs;
19198 Lisp_Object eolvalue;
19199
19200 attrs = AREF (val, 0);
19201 eolvalue = AREF (val, 2);
19202
19203 if (multibyte)
19204 *buf++ = XFASTINT (CODING_ATTR_MNEMONIC (attrs));
19205
19206 if (eol_flag)
19207 {
19208 /* The EOL conversion that is normal on this system. */
19209
19210 if (NILP (eolvalue)) /* Not yet decided. */
19211 eoltype = eol_mnemonic_undecided;
19212 else if (VECTORP (eolvalue)) /* Not yet decided. */
19213 eoltype = eol_mnemonic_undecided;
19214 else /* eolvalue is Qunix, Qdos, or Qmac. */
19215 eoltype = (EQ (eolvalue, Qunix)
19216 ? eol_mnemonic_unix
19217 : (EQ (eolvalue, Qdos) == 1
19218 ? eol_mnemonic_dos : eol_mnemonic_mac));
19219 }
19220 }
19221
19222 if (eol_flag)
19223 {
19224 /* Mention the EOL conversion if it is not the usual one. */
19225 if (STRINGP (eoltype))
19226 {
19227 eol_str = SDATA (eoltype);
19228 eol_str_len = SBYTES (eoltype);
19229 }
19230 else if (CHARACTERP (eoltype))
19231 {
19232 unsigned char *tmp = (unsigned char *) alloca (MAX_MULTIBYTE_LENGTH);
19233 eol_str_len = CHAR_STRING (XINT (eoltype), tmp);
19234 eol_str = tmp;
19235 }
19236 else
19237 {
19238 eol_str = invalid_eol_type;
19239 eol_str_len = sizeof (invalid_eol_type) - 1;
19240 }
19241 memcpy (buf, eol_str, eol_str_len);
19242 buf += eol_str_len;
19243 }
19244
19245 return buf;
19246 }
19247
19248 /* Return a string for the output of a mode line %-spec for window W,
19249 generated by character C. PRECISION >= 0 means don't return a
19250 string longer than that value. FIELD_WIDTH > 0 means pad the
19251 string returned with spaces to that value. Return a Lisp string in
19252 *STRING if the resulting string is taken from that Lisp string.
19253
19254 Note we operate on the current buffer for most purposes,
19255 the exception being w->base_line_pos. */
19256
19257 static char lots_of_dashes[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
19258
19259 static const char *
19260 decode_mode_spec (struct window *w, register int c, int field_width,
19261 int precision, Lisp_Object *string)
19262 {
19263 Lisp_Object obj;
19264 struct frame *f = XFRAME (WINDOW_FRAME (w));
19265 char *decode_mode_spec_buf = f->decode_mode_spec_buffer;
19266 struct buffer *b = current_buffer;
19267
19268 obj = Qnil;
19269 *string = Qnil;
19270
19271 switch (c)
19272 {
19273 case '*':
19274 if (!NILP (b->read_only))
19275 return "%";
19276 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
19277 return "*";
19278 return "-";
19279
19280 case '+':
19281 /* This differs from %* only for a modified read-only buffer. */
19282 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
19283 return "*";
19284 if (!NILP (b->read_only))
19285 return "%";
19286 return "-";
19287
19288 case '&':
19289 /* This differs from %* in ignoring read-only-ness. */
19290 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
19291 return "*";
19292 return "-";
19293
19294 case '%':
19295 return "%";
19296
19297 case '[':
19298 {
19299 int i;
19300 char *p;
19301
19302 if (command_loop_level > 5)
19303 return "[[[... ";
19304 p = decode_mode_spec_buf;
19305 for (i = 0; i < command_loop_level; i++)
19306 *p++ = '[';
19307 *p = 0;
19308 return decode_mode_spec_buf;
19309 }
19310
19311 case ']':
19312 {
19313 int i;
19314 char *p;
19315
19316 if (command_loop_level > 5)
19317 return " ...]]]";
19318 p = decode_mode_spec_buf;
19319 for (i = 0; i < command_loop_level; i++)
19320 *p++ = ']';
19321 *p = 0;
19322 return decode_mode_spec_buf;
19323 }
19324
19325 case '-':
19326 {
19327 register int i;
19328
19329 /* Let lots_of_dashes be a string of infinite length. */
19330 if (mode_line_target == MODE_LINE_NOPROP ||
19331 mode_line_target == MODE_LINE_STRING)
19332 return "--";
19333 if (field_width <= 0
19334 || field_width > sizeof (lots_of_dashes))
19335 {
19336 for (i = 0; i < FRAME_MESSAGE_BUF_SIZE (f) - 1; ++i)
19337 decode_mode_spec_buf[i] = '-';
19338 decode_mode_spec_buf[i] = '\0';
19339 return decode_mode_spec_buf;
19340 }
19341 else
19342 return lots_of_dashes;
19343 }
19344
19345 case 'b':
19346 obj = b->name;
19347 break;
19348
19349 case 'c':
19350 /* %c and %l are ignored in `frame-title-format'.
19351 (In redisplay_internal, the frame title is drawn _before_ the
19352 windows are updated, so the stuff which depends on actual
19353 window contents (such as %l) may fail to render properly, or
19354 even crash emacs.) */
19355 if (mode_line_target == MODE_LINE_TITLE)
19356 return "";
19357 else
19358 {
19359 int col = (int) current_column (); /* iftc */
19360 w->column_number_displayed = make_number (col);
19361 pint2str (decode_mode_spec_buf, field_width, col);
19362 return decode_mode_spec_buf;
19363 }
19364
19365 case 'e':
19366 #ifndef SYSTEM_MALLOC
19367 {
19368 if (NILP (Vmemory_full))
19369 return "";
19370 else
19371 return "!MEM FULL! ";
19372 }
19373 #else
19374 return "";
19375 #endif
19376
19377 case 'F':
19378 /* %F displays the frame name. */
19379 if (!NILP (f->title))
19380 return (char *) SDATA (f->title);
19381 if (f->explicit_name || ! FRAME_WINDOW_P (f))
19382 return (char *) SDATA (f->name);
19383 return "Emacs";
19384
19385 case 'f':
19386 obj = b->filename;
19387 break;
19388
19389 case 'i':
19390 {
19391 int size = ZV - BEGV;
19392 pint2str (decode_mode_spec_buf, field_width, size);
19393 return decode_mode_spec_buf;
19394 }
19395
19396 case 'I':
19397 {
19398 int size = ZV - BEGV;
19399 pint2hrstr (decode_mode_spec_buf, field_width, size);
19400 return decode_mode_spec_buf;
19401 }
19402
19403 case 'l':
19404 {
19405 int startpos, startpos_byte, line, linepos, linepos_byte;
19406 int topline, nlines, junk, height;
19407
19408 /* %c and %l are ignored in `frame-title-format'. */
19409 if (mode_line_target == MODE_LINE_TITLE)
19410 return "";
19411
19412 startpos = XMARKER (w->start)->charpos;
19413 startpos_byte = marker_byte_position (w->start);
19414 height = WINDOW_TOTAL_LINES (w);
19415
19416 /* If we decided that this buffer isn't suitable for line numbers,
19417 don't forget that too fast. */
19418 if (EQ (w->base_line_pos, w->buffer))
19419 goto no_value;
19420 /* But do forget it, if the window shows a different buffer now. */
19421 else if (BUFFERP (w->base_line_pos))
19422 w->base_line_pos = Qnil;
19423
19424 /* If the buffer is very big, don't waste time. */
19425 if (INTEGERP (Vline_number_display_limit)
19426 && BUF_ZV (b) - BUF_BEGV (b) > XINT (Vline_number_display_limit))
19427 {
19428 w->base_line_pos = Qnil;
19429 w->base_line_number = Qnil;
19430 goto no_value;
19431 }
19432
19433 if (INTEGERP (w->base_line_number)
19434 && INTEGERP (w->base_line_pos)
19435 && XFASTINT (w->base_line_pos) <= startpos)
19436 {
19437 line = XFASTINT (w->base_line_number);
19438 linepos = XFASTINT (w->base_line_pos);
19439 linepos_byte = buf_charpos_to_bytepos (b, linepos);
19440 }
19441 else
19442 {
19443 line = 1;
19444 linepos = BUF_BEGV (b);
19445 linepos_byte = BUF_BEGV_BYTE (b);
19446 }
19447
19448 /* Count lines from base line to window start position. */
19449 nlines = display_count_lines (linepos, linepos_byte,
19450 startpos_byte,
19451 startpos, &junk);
19452
19453 topline = nlines + line;
19454
19455 /* Determine a new base line, if the old one is too close
19456 or too far away, or if we did not have one.
19457 "Too close" means it's plausible a scroll-down would
19458 go back past it. */
19459 if (startpos == BUF_BEGV (b))
19460 {
19461 w->base_line_number = make_number (topline);
19462 w->base_line_pos = make_number (BUF_BEGV (b));
19463 }
19464 else if (nlines < height + 25 || nlines > height * 3 + 50
19465 || linepos == BUF_BEGV (b))
19466 {
19467 int limit = BUF_BEGV (b);
19468 int limit_byte = BUF_BEGV_BYTE (b);
19469 int position;
19470 int distance = (height * 2 + 30) * line_number_display_limit_width;
19471
19472 if (startpos - distance > limit)
19473 {
19474 limit = startpos - distance;
19475 limit_byte = CHAR_TO_BYTE (limit);
19476 }
19477
19478 nlines = display_count_lines (startpos, startpos_byte,
19479 limit_byte,
19480 - (height * 2 + 30),
19481 &position);
19482 /* If we couldn't find the lines we wanted within
19483 line_number_display_limit_width chars per line,
19484 give up on line numbers for this window. */
19485 if (position == limit_byte && limit == startpos - distance)
19486 {
19487 w->base_line_pos = w->buffer;
19488 w->base_line_number = Qnil;
19489 goto no_value;
19490 }
19491
19492 w->base_line_number = make_number (topline - nlines);
19493 w->base_line_pos = make_number (BYTE_TO_CHAR (position));
19494 }
19495
19496 /* Now count lines from the start pos to point. */
19497 nlines = display_count_lines (startpos, startpos_byte,
19498 PT_BYTE, PT, &junk);
19499
19500 /* Record that we did display the line number. */
19501 line_number_displayed = 1;
19502
19503 /* Make the string to show. */
19504 pint2str (decode_mode_spec_buf, field_width, topline + nlines);
19505 return decode_mode_spec_buf;
19506 no_value:
19507 {
19508 char* p = decode_mode_spec_buf;
19509 int pad = field_width - 2;
19510 while (pad-- > 0)
19511 *p++ = ' ';
19512 *p++ = '?';
19513 *p++ = '?';
19514 *p = '\0';
19515 return decode_mode_spec_buf;
19516 }
19517 }
19518 break;
19519
19520 case 'm':
19521 obj = b->mode_name;
19522 break;
19523
19524 case 'n':
19525 if (BUF_BEGV (b) > BUF_BEG (b) || BUF_ZV (b) < BUF_Z (b))
19526 return " Narrow";
19527 break;
19528
19529 case 'p':
19530 {
19531 int pos = marker_position (w->start);
19532 int total = BUF_ZV (b) - BUF_BEGV (b);
19533
19534 if (XFASTINT (w->window_end_pos) <= BUF_Z (b) - BUF_ZV (b))
19535 {
19536 if (pos <= BUF_BEGV (b))
19537 return "All";
19538 else
19539 return "Bottom";
19540 }
19541 else if (pos <= BUF_BEGV (b))
19542 return "Top";
19543 else
19544 {
19545 if (total > 1000000)
19546 /* Do it differently for a large value, to avoid overflow. */
19547 total = ((pos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
19548 else
19549 total = ((pos - BUF_BEGV (b)) * 100 + total - 1) / total;
19550 /* We can't normally display a 3-digit number,
19551 so get us a 2-digit number that is close. */
19552 if (total == 100)
19553 total = 99;
19554 sprintf (decode_mode_spec_buf, "%2d%%", total);
19555 return decode_mode_spec_buf;
19556 }
19557 }
19558
19559 /* Display percentage of size above the bottom of the screen. */
19560 case 'P':
19561 {
19562 int toppos = marker_position (w->start);
19563 int botpos = BUF_Z (b) - XFASTINT (w->window_end_pos);
19564 int total = BUF_ZV (b) - BUF_BEGV (b);
19565
19566 if (botpos >= BUF_ZV (b))
19567 {
19568 if (toppos <= BUF_BEGV (b))
19569 return "All";
19570 else
19571 return "Bottom";
19572 }
19573 else
19574 {
19575 if (total > 1000000)
19576 /* Do it differently for a large value, to avoid overflow. */
19577 total = ((botpos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
19578 else
19579 total = ((botpos - BUF_BEGV (b)) * 100 + total - 1) / total;
19580 /* We can't normally display a 3-digit number,
19581 so get us a 2-digit number that is close. */
19582 if (total == 100)
19583 total = 99;
19584 if (toppos <= BUF_BEGV (b))
19585 sprintf (decode_mode_spec_buf, "Top%2d%%", total);
19586 else
19587 sprintf (decode_mode_spec_buf, "%2d%%", total);
19588 return decode_mode_spec_buf;
19589 }
19590 }
19591
19592 case 's':
19593 /* status of process */
19594 obj = Fget_buffer_process (Fcurrent_buffer ());
19595 if (NILP (obj))
19596 return "no process";
19597 #ifndef MSDOS
19598 obj = Fsymbol_name (Fprocess_status (obj));
19599 #endif
19600 break;
19601
19602 case '@':
19603 {
19604 int count = inhibit_garbage_collection ();
19605 Lisp_Object val = call1 (intern ("file-remote-p"),
19606 current_buffer->directory);
19607 unbind_to (count, Qnil);
19608
19609 if (NILP (val))
19610 return "-";
19611 else
19612 return "@";
19613 }
19614
19615 case 't': /* indicate TEXT or BINARY */
19616 #ifdef MODE_LINE_BINARY_TEXT
19617 return MODE_LINE_BINARY_TEXT (b);
19618 #else
19619 return "T";
19620 #endif
19621
19622 case 'z':
19623 /* coding-system (not including end-of-line format) */
19624 case 'Z':
19625 /* coding-system (including end-of-line type) */
19626 {
19627 int eol_flag = (c == 'Z');
19628 char *p = decode_mode_spec_buf;
19629
19630 if (! FRAME_WINDOW_P (f))
19631 {
19632 /* No need to mention EOL here--the terminal never needs
19633 to do EOL conversion. */
19634 p = decode_mode_spec_coding (CODING_ID_NAME
19635 (FRAME_KEYBOARD_CODING (f)->id),
19636 p, 0);
19637 p = decode_mode_spec_coding (CODING_ID_NAME
19638 (FRAME_TERMINAL_CODING (f)->id),
19639 p, 0);
19640 }
19641 p = decode_mode_spec_coding (b->buffer_file_coding_system,
19642 p, eol_flag);
19643
19644 #if 0 /* This proves to be annoying; I think we can do without. -- rms. */
19645 #ifdef subprocesses
19646 obj = Fget_buffer_process (Fcurrent_buffer ());
19647 if (PROCESSP (obj))
19648 {
19649 p = decode_mode_spec_coding (XPROCESS (obj)->decode_coding_system,
19650 p, eol_flag);
19651 p = decode_mode_spec_coding (XPROCESS (obj)->encode_coding_system,
19652 p, eol_flag);
19653 }
19654 #endif /* subprocesses */
19655 #endif /* 0 */
19656 *p = 0;
19657 return decode_mode_spec_buf;
19658 }
19659 }
19660
19661 if (STRINGP (obj))
19662 {
19663 *string = obj;
19664 return (char *) SDATA (obj);
19665 }
19666 else
19667 return "";
19668 }
19669
19670
19671 /* Count up to COUNT lines starting from START / START_BYTE.
19672 But don't go beyond LIMIT_BYTE.
19673 Return the number of lines thus found (always nonnegative).
19674
19675 Set *BYTE_POS_PTR to 1 if we found COUNT lines, 0 if we hit LIMIT. */
19676
19677 static int
19678 display_count_lines (int start, int start_byte, int limit_byte, int count,
19679 int *byte_pos_ptr)
19680 {
19681 register unsigned char *cursor;
19682 unsigned char *base;
19683
19684 register int ceiling;
19685 register unsigned char *ceiling_addr;
19686 int orig_count = count;
19687
19688 /* If we are not in selective display mode,
19689 check only for newlines. */
19690 int selective_display = (!NILP (current_buffer->selective_display)
19691 && !INTEGERP (current_buffer->selective_display));
19692
19693 if (count > 0)
19694 {
19695 while (start_byte < limit_byte)
19696 {
19697 ceiling = BUFFER_CEILING_OF (start_byte);
19698 ceiling = min (limit_byte - 1, ceiling);
19699 ceiling_addr = BYTE_POS_ADDR (ceiling) + 1;
19700 base = (cursor = BYTE_POS_ADDR (start_byte));
19701 while (1)
19702 {
19703 if (selective_display)
19704 while (*cursor != '\n' && *cursor != 015 && ++cursor != ceiling_addr)
19705 ;
19706 else
19707 while (*cursor != '\n' && ++cursor != ceiling_addr)
19708 ;
19709
19710 if (cursor != ceiling_addr)
19711 {
19712 if (--count == 0)
19713 {
19714 start_byte += cursor - base + 1;
19715 *byte_pos_ptr = start_byte;
19716 return orig_count;
19717 }
19718 else
19719 if (++cursor == ceiling_addr)
19720 break;
19721 }
19722 else
19723 break;
19724 }
19725 start_byte += cursor - base;
19726 }
19727 }
19728 else
19729 {
19730 while (start_byte > limit_byte)
19731 {
19732 ceiling = BUFFER_FLOOR_OF (start_byte - 1);
19733 ceiling = max (limit_byte, ceiling);
19734 ceiling_addr = BYTE_POS_ADDR (ceiling) - 1;
19735 base = (cursor = BYTE_POS_ADDR (start_byte - 1) + 1);
19736 while (1)
19737 {
19738 if (selective_display)
19739 while (--cursor != ceiling_addr
19740 && *cursor != '\n' && *cursor != 015)
19741 ;
19742 else
19743 while (--cursor != ceiling_addr && *cursor != '\n')
19744 ;
19745
19746 if (cursor != ceiling_addr)
19747 {
19748 if (++count == 0)
19749 {
19750 start_byte += cursor - base + 1;
19751 *byte_pos_ptr = start_byte;
19752 /* When scanning backwards, we should
19753 not count the newline posterior to which we stop. */
19754 return - orig_count - 1;
19755 }
19756 }
19757 else
19758 break;
19759 }
19760 /* Here we add 1 to compensate for the last decrement
19761 of CURSOR, which took it past the valid range. */
19762 start_byte += cursor - base + 1;
19763 }
19764 }
19765
19766 *byte_pos_ptr = limit_byte;
19767
19768 if (count < 0)
19769 return - orig_count + count;
19770 return orig_count - count;
19771
19772 }
19773
19774
19775 \f
19776 /***********************************************************************
19777 Displaying strings
19778 ***********************************************************************/
19779
19780 /* Display a NUL-terminated string, starting with index START.
19781
19782 If STRING is non-null, display that C string. Otherwise, the Lisp
19783 string LISP_STRING is displayed. There's a case that STRING is
19784 non-null and LISP_STRING is not nil. It means STRING is a string
19785 data of LISP_STRING. In that case, we display LISP_STRING while
19786 ignoring its text properties.
19787
19788 If FACE_STRING is not nil, FACE_STRING_POS is a position in
19789 FACE_STRING. Display STRING or LISP_STRING with the face at
19790 FACE_STRING_POS in FACE_STRING:
19791
19792 Display the string in the environment given by IT, but use the
19793 standard display table, temporarily.
19794
19795 FIELD_WIDTH is the minimum number of output glyphs to produce.
19796 If STRING has fewer characters than FIELD_WIDTH, pad to the right
19797 with spaces. If STRING has more characters, more than FIELD_WIDTH
19798 glyphs will be produced. FIELD_WIDTH <= 0 means don't pad.
19799
19800 PRECISION is the maximum number of characters to output from
19801 STRING. PRECISION < 0 means don't truncate the string.
19802
19803 This is roughly equivalent to printf format specifiers:
19804
19805 FIELD_WIDTH PRECISION PRINTF
19806 ----------------------------------------
19807 -1 -1 %s
19808 -1 10 %.10s
19809 10 -1 %10s
19810 20 10 %20.10s
19811
19812 MULTIBYTE zero means do not display multibyte chars, > 0 means do
19813 display them, and < 0 means obey the current buffer's value of
19814 enable_multibyte_characters.
19815
19816 Value is the number of columns displayed. */
19817
19818 static int
19819 display_string (const unsigned char *string, Lisp_Object lisp_string, Lisp_Object face_string,
19820 EMACS_INT face_string_pos, EMACS_INT start, struct it *it,
19821 int field_width, int precision, int max_x, int multibyte)
19822 {
19823 int hpos_at_start = it->hpos;
19824 int saved_face_id = it->face_id;
19825 struct glyph_row *row = it->glyph_row;
19826
19827 /* Initialize the iterator IT for iteration over STRING beginning
19828 with index START. */
19829 reseat_to_string (it, NILP (lisp_string) ? string : NULL, lisp_string, start,
19830 precision, field_width, multibyte);
19831 if (string && STRINGP (lisp_string))
19832 /* LISP_STRING is the one returned by decode_mode_spec. We should
19833 ignore its text properties. */
19834 it->stop_charpos = -1;
19835
19836 /* If displaying STRING, set up the face of the iterator
19837 from LISP_STRING, if that's given. */
19838 if (STRINGP (face_string))
19839 {
19840 EMACS_INT endptr;
19841 struct face *face;
19842
19843 it->face_id
19844 = face_at_string_position (it->w, face_string, face_string_pos,
19845 0, it->region_beg_charpos,
19846 it->region_end_charpos,
19847 &endptr, it->base_face_id, 0);
19848 face = FACE_FROM_ID (it->f, it->face_id);
19849 it->face_box_p = face->box != FACE_NO_BOX;
19850 }
19851
19852 /* Set max_x to the maximum allowed X position. Don't let it go
19853 beyond the right edge of the window. */
19854 if (max_x <= 0)
19855 max_x = it->last_visible_x;
19856 else
19857 max_x = min (max_x, it->last_visible_x);
19858
19859 /* Skip over display elements that are not visible. because IT->w is
19860 hscrolled. */
19861 if (it->current_x < it->first_visible_x)
19862 move_it_in_display_line_to (it, 100000, it->first_visible_x,
19863 MOVE_TO_POS | MOVE_TO_X);
19864
19865 row->ascent = it->max_ascent;
19866 row->height = it->max_ascent + it->max_descent;
19867 row->phys_ascent = it->max_phys_ascent;
19868 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
19869 row->extra_line_spacing = it->max_extra_line_spacing;
19870
19871 /* This condition is for the case that we are called with current_x
19872 past last_visible_x. */
19873 while (it->current_x < max_x)
19874 {
19875 int x_before, x, n_glyphs_before, i, nglyphs;
19876
19877 /* Get the next display element. */
19878 if (!get_next_display_element (it))
19879 break;
19880
19881 /* Produce glyphs. */
19882 x_before = it->current_x;
19883 n_glyphs_before = it->glyph_row->used[TEXT_AREA];
19884 PRODUCE_GLYPHS (it);
19885
19886 nglyphs = it->glyph_row->used[TEXT_AREA] - n_glyphs_before;
19887 i = 0;
19888 x = x_before;
19889 while (i < nglyphs)
19890 {
19891 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
19892
19893 if (it->line_wrap != TRUNCATE
19894 && x + glyph->pixel_width > max_x)
19895 {
19896 /* End of continued line or max_x reached. */
19897 if (CHAR_GLYPH_PADDING_P (*glyph))
19898 {
19899 /* A wide character is unbreakable. */
19900 it->glyph_row->used[TEXT_AREA] = n_glyphs_before;
19901 it->current_x = x_before;
19902 }
19903 else
19904 {
19905 it->glyph_row->used[TEXT_AREA] = n_glyphs_before + i;
19906 it->current_x = x;
19907 }
19908 break;
19909 }
19910 else if (x + glyph->pixel_width >= it->first_visible_x)
19911 {
19912 /* Glyph is at least partially visible. */
19913 ++it->hpos;
19914 if (x < it->first_visible_x)
19915 it->glyph_row->x = x - it->first_visible_x;
19916 }
19917 else
19918 {
19919 /* Glyph is off the left margin of the display area.
19920 Should not happen. */
19921 abort ();
19922 }
19923
19924 row->ascent = max (row->ascent, it->max_ascent);
19925 row->height = max (row->height, it->max_ascent + it->max_descent);
19926 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
19927 row->phys_height = max (row->phys_height,
19928 it->max_phys_ascent + it->max_phys_descent);
19929 row->extra_line_spacing = max (row->extra_line_spacing,
19930 it->max_extra_line_spacing);
19931 x += glyph->pixel_width;
19932 ++i;
19933 }
19934
19935 /* Stop if max_x reached. */
19936 if (i < nglyphs)
19937 break;
19938
19939 /* Stop at line ends. */
19940 if (ITERATOR_AT_END_OF_LINE_P (it))
19941 {
19942 it->continuation_lines_width = 0;
19943 break;
19944 }
19945
19946 set_iterator_to_next (it, 1);
19947
19948 /* Stop if truncating at the right edge. */
19949 if (it->line_wrap == TRUNCATE
19950 && it->current_x >= it->last_visible_x)
19951 {
19952 /* Add truncation mark, but don't do it if the line is
19953 truncated at a padding space. */
19954 if (IT_CHARPOS (*it) < it->string_nchars)
19955 {
19956 if (!FRAME_WINDOW_P (it->f))
19957 {
19958 int i, n;
19959
19960 if (it->current_x > it->last_visible_x)
19961 {
19962 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
19963 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
19964 break;
19965 for (n = row->used[TEXT_AREA]; i < n; ++i)
19966 {
19967 row->used[TEXT_AREA] = i;
19968 produce_special_glyphs (it, IT_TRUNCATION);
19969 }
19970 }
19971 produce_special_glyphs (it, IT_TRUNCATION);
19972 }
19973 it->glyph_row->truncated_on_right_p = 1;
19974 }
19975 break;
19976 }
19977 }
19978
19979 /* Maybe insert a truncation at the left. */
19980 if (it->first_visible_x
19981 && IT_CHARPOS (*it) > 0)
19982 {
19983 if (!FRAME_WINDOW_P (it->f))
19984 insert_left_trunc_glyphs (it);
19985 it->glyph_row->truncated_on_left_p = 1;
19986 }
19987
19988 it->face_id = saved_face_id;
19989
19990 /* Value is number of columns displayed. */
19991 return it->hpos - hpos_at_start;
19992 }
19993
19994
19995 \f
19996 /* This is like a combination of memq and assq. Return 1/2 if PROPVAL
19997 appears as an element of LIST or as the car of an element of LIST.
19998 If PROPVAL is a list, compare each element against LIST in that
19999 way, and return 1/2 if any element of PROPVAL is found in LIST.
20000 Otherwise return 0. This function cannot quit.
20001 The return value is 2 if the text is invisible but with an ellipsis
20002 and 1 if it's invisible and without an ellipsis. */
20003
20004 int
20005 invisible_p (register Lisp_Object propval, Lisp_Object list)
20006 {
20007 register Lisp_Object tail, proptail;
20008
20009 for (tail = list; CONSP (tail); tail = XCDR (tail))
20010 {
20011 register Lisp_Object tem;
20012 tem = XCAR (tail);
20013 if (EQ (propval, tem))
20014 return 1;
20015 if (CONSP (tem) && EQ (propval, XCAR (tem)))
20016 return NILP (XCDR (tem)) ? 1 : 2;
20017 }
20018
20019 if (CONSP (propval))
20020 {
20021 for (proptail = propval; CONSP (proptail); proptail = XCDR (proptail))
20022 {
20023 Lisp_Object propelt;
20024 propelt = XCAR (proptail);
20025 for (tail = list; CONSP (tail); tail = XCDR (tail))
20026 {
20027 register Lisp_Object tem;
20028 tem = XCAR (tail);
20029 if (EQ (propelt, tem))
20030 return 1;
20031 if (CONSP (tem) && EQ (propelt, XCAR (tem)))
20032 return NILP (XCDR (tem)) ? 1 : 2;
20033 }
20034 }
20035 }
20036
20037 return 0;
20038 }
20039
20040 DEFUN ("invisible-p", Finvisible_p, Sinvisible_p, 1, 1, 0,
20041 doc: /* Non-nil if the property makes the text invisible.
20042 POS-OR-PROP can be a marker or number, in which case it is taken to be
20043 a position in the current buffer and the value of the `invisible' property
20044 is checked; or it can be some other value, which is then presumed to be the
20045 value of the `invisible' property of the text of interest.
20046 The non-nil value returned can be t for truly invisible text or something
20047 else if the text is replaced by an ellipsis. */)
20048 (Lisp_Object pos_or_prop)
20049 {
20050 Lisp_Object prop
20051 = (NATNUMP (pos_or_prop) || MARKERP (pos_or_prop)
20052 ? Fget_char_property (pos_or_prop, Qinvisible, Qnil)
20053 : pos_or_prop);
20054 int invis = TEXT_PROP_MEANS_INVISIBLE (prop);
20055 return (invis == 0 ? Qnil
20056 : invis == 1 ? Qt
20057 : make_number (invis));
20058 }
20059
20060 /* Calculate a width or height in pixels from a specification using
20061 the following elements:
20062
20063 SPEC ::=
20064 NUM - a (fractional) multiple of the default font width/height
20065 (NUM) - specifies exactly NUM pixels
20066 UNIT - a fixed number of pixels, see below.
20067 ELEMENT - size of a display element in pixels, see below.
20068 (NUM . SPEC) - equals NUM * SPEC
20069 (+ SPEC SPEC ...) - add pixel values
20070 (- SPEC SPEC ...) - subtract pixel values
20071 (- SPEC) - negate pixel value
20072
20073 NUM ::=
20074 INT or FLOAT - a number constant
20075 SYMBOL - use symbol's (buffer local) variable binding.
20076
20077 UNIT ::=
20078 in - pixels per inch *)
20079 mm - pixels per 1/1000 meter *)
20080 cm - pixels per 1/100 meter *)
20081 width - width of current font in pixels.
20082 height - height of current font in pixels.
20083
20084 *) using the ratio(s) defined in display-pixels-per-inch.
20085
20086 ELEMENT ::=
20087
20088 left-fringe - left fringe width in pixels
20089 right-fringe - right fringe width in pixels
20090
20091 left-margin - left margin width in pixels
20092 right-margin - right margin width in pixels
20093
20094 scroll-bar - scroll-bar area width in pixels
20095
20096 Examples:
20097
20098 Pixels corresponding to 5 inches:
20099 (5 . in)
20100
20101 Total width of non-text areas on left side of window (if scroll-bar is on left):
20102 '(space :width (+ left-fringe left-margin scroll-bar))
20103
20104 Align to first text column (in header line):
20105 '(space :align-to 0)
20106
20107 Align to middle of text area minus half the width of variable `my-image'
20108 containing a loaded image:
20109 '(space :align-to (0.5 . (- text my-image)))
20110
20111 Width of left margin minus width of 1 character in the default font:
20112 '(space :width (- left-margin 1))
20113
20114 Width of left margin minus width of 2 characters in the current font:
20115 '(space :width (- left-margin (2 . width)))
20116
20117 Center 1 character over left-margin (in header line):
20118 '(space :align-to (+ left-margin (0.5 . left-margin) -0.5))
20119
20120 Different ways to express width of left fringe plus left margin minus one pixel:
20121 '(space :width (- (+ left-fringe left-margin) (1)))
20122 '(space :width (+ left-fringe left-margin (- (1))))
20123 '(space :width (+ left-fringe left-margin (-1)))
20124
20125 */
20126
20127 #define NUMVAL(X) \
20128 ((INTEGERP (X) || FLOATP (X)) \
20129 ? XFLOATINT (X) \
20130 : - 1)
20131
20132 int
20133 calc_pixel_width_or_height (double *res, struct it *it, Lisp_Object prop,
20134 struct font *font, int width_p, int *align_to)
20135 {
20136 double pixels;
20137
20138 #define OK_PIXELS(val) ((*res = (double)(val)), 1)
20139 #define OK_ALIGN_TO(val) ((*align_to = (int)(val)), 1)
20140
20141 if (NILP (prop))
20142 return OK_PIXELS (0);
20143
20144 xassert (FRAME_LIVE_P (it->f));
20145
20146 if (SYMBOLP (prop))
20147 {
20148 if (SCHARS (SYMBOL_NAME (prop)) == 2)
20149 {
20150 char *unit = SDATA (SYMBOL_NAME (prop));
20151
20152 if (unit[0] == 'i' && unit[1] == 'n')
20153 pixels = 1.0;
20154 else if (unit[0] == 'm' && unit[1] == 'm')
20155 pixels = 25.4;
20156 else if (unit[0] == 'c' && unit[1] == 'm')
20157 pixels = 2.54;
20158 else
20159 pixels = 0;
20160 if (pixels > 0)
20161 {
20162 double ppi;
20163 #ifdef HAVE_WINDOW_SYSTEM
20164 if (FRAME_WINDOW_P (it->f)
20165 && (ppi = (width_p
20166 ? FRAME_X_DISPLAY_INFO (it->f)->resx
20167 : FRAME_X_DISPLAY_INFO (it->f)->resy),
20168 ppi > 0))
20169 return OK_PIXELS (ppi / pixels);
20170 #endif
20171
20172 if ((ppi = NUMVAL (Vdisplay_pixels_per_inch), ppi > 0)
20173 || (CONSP (Vdisplay_pixels_per_inch)
20174 && (ppi = (width_p
20175 ? NUMVAL (XCAR (Vdisplay_pixels_per_inch))
20176 : NUMVAL (XCDR (Vdisplay_pixels_per_inch))),
20177 ppi > 0)))
20178 return OK_PIXELS (ppi / pixels);
20179
20180 return 0;
20181 }
20182 }
20183
20184 #ifdef HAVE_WINDOW_SYSTEM
20185 if (EQ (prop, Qheight))
20186 return OK_PIXELS (font ? FONT_HEIGHT (font) : FRAME_LINE_HEIGHT (it->f));
20187 if (EQ (prop, Qwidth))
20188 return OK_PIXELS (font ? FONT_WIDTH (font) : FRAME_COLUMN_WIDTH (it->f));
20189 #else
20190 if (EQ (prop, Qheight) || EQ (prop, Qwidth))
20191 return OK_PIXELS (1);
20192 #endif
20193
20194 if (EQ (prop, Qtext))
20195 return OK_PIXELS (width_p
20196 ? window_box_width (it->w, TEXT_AREA)
20197 : WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w));
20198
20199 if (align_to && *align_to < 0)
20200 {
20201 *res = 0;
20202 if (EQ (prop, Qleft))
20203 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA));
20204 if (EQ (prop, Qright))
20205 return OK_ALIGN_TO (window_box_right_offset (it->w, TEXT_AREA));
20206 if (EQ (prop, Qcenter))
20207 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA)
20208 + window_box_width (it->w, TEXT_AREA) / 2);
20209 if (EQ (prop, Qleft_fringe))
20210 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
20211 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (it->w)
20212 : window_box_right_offset (it->w, LEFT_MARGIN_AREA));
20213 if (EQ (prop, Qright_fringe))
20214 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
20215 ? window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
20216 : window_box_right_offset (it->w, TEXT_AREA));
20217 if (EQ (prop, Qleft_margin))
20218 return OK_ALIGN_TO (window_box_left_offset (it->w, LEFT_MARGIN_AREA));
20219 if (EQ (prop, Qright_margin))
20220 return OK_ALIGN_TO (window_box_left_offset (it->w, RIGHT_MARGIN_AREA));
20221 if (EQ (prop, Qscroll_bar))
20222 return OK_ALIGN_TO (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (it->w)
20223 ? 0
20224 : (window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
20225 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
20226 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
20227 : 0)));
20228 }
20229 else
20230 {
20231 if (EQ (prop, Qleft_fringe))
20232 return OK_PIXELS (WINDOW_LEFT_FRINGE_WIDTH (it->w));
20233 if (EQ (prop, Qright_fringe))
20234 return OK_PIXELS (WINDOW_RIGHT_FRINGE_WIDTH (it->w));
20235 if (EQ (prop, Qleft_margin))
20236 return OK_PIXELS (WINDOW_LEFT_MARGIN_WIDTH (it->w));
20237 if (EQ (prop, Qright_margin))
20238 return OK_PIXELS (WINDOW_RIGHT_MARGIN_WIDTH (it->w));
20239 if (EQ (prop, Qscroll_bar))
20240 return OK_PIXELS (WINDOW_SCROLL_BAR_AREA_WIDTH (it->w));
20241 }
20242
20243 prop = Fbuffer_local_value (prop, it->w->buffer);
20244 }
20245
20246 if (INTEGERP (prop) || FLOATP (prop))
20247 {
20248 int base_unit = (width_p
20249 ? FRAME_COLUMN_WIDTH (it->f)
20250 : FRAME_LINE_HEIGHT (it->f));
20251 return OK_PIXELS (XFLOATINT (prop) * base_unit);
20252 }
20253
20254 if (CONSP (prop))
20255 {
20256 Lisp_Object car = XCAR (prop);
20257 Lisp_Object cdr = XCDR (prop);
20258
20259 if (SYMBOLP (car))
20260 {
20261 #ifdef HAVE_WINDOW_SYSTEM
20262 if (FRAME_WINDOW_P (it->f)
20263 && valid_image_p (prop))
20264 {
20265 int id = lookup_image (it->f, prop);
20266 struct image *img = IMAGE_FROM_ID (it->f, id);
20267
20268 return OK_PIXELS (width_p ? img->width : img->height);
20269 }
20270 #endif
20271 if (EQ (car, Qplus) || EQ (car, Qminus))
20272 {
20273 int first = 1;
20274 double px;
20275
20276 pixels = 0;
20277 while (CONSP (cdr))
20278 {
20279 if (!calc_pixel_width_or_height (&px, it, XCAR (cdr),
20280 font, width_p, align_to))
20281 return 0;
20282 if (first)
20283 pixels = (EQ (car, Qplus) ? px : -px), first = 0;
20284 else
20285 pixels += px;
20286 cdr = XCDR (cdr);
20287 }
20288 if (EQ (car, Qminus))
20289 pixels = -pixels;
20290 return OK_PIXELS (pixels);
20291 }
20292
20293 car = Fbuffer_local_value (car, it->w->buffer);
20294 }
20295
20296 if (INTEGERP (car) || FLOATP (car))
20297 {
20298 double fact;
20299 pixels = XFLOATINT (car);
20300 if (NILP (cdr))
20301 return OK_PIXELS (pixels);
20302 if (calc_pixel_width_or_height (&fact, it, cdr,
20303 font, width_p, align_to))
20304 return OK_PIXELS (pixels * fact);
20305 return 0;
20306 }
20307
20308 return 0;
20309 }
20310
20311 return 0;
20312 }
20313
20314 \f
20315 /***********************************************************************
20316 Glyph Display
20317 ***********************************************************************/
20318
20319 #ifdef HAVE_WINDOW_SYSTEM
20320
20321 #if GLYPH_DEBUG
20322
20323 void
20324 dump_glyph_string (s)
20325 struct glyph_string *s;
20326 {
20327 fprintf (stderr, "glyph string\n");
20328 fprintf (stderr, " x, y, w, h = %d, %d, %d, %d\n",
20329 s->x, s->y, s->width, s->height);
20330 fprintf (stderr, " ybase = %d\n", s->ybase);
20331 fprintf (stderr, " hl = %d\n", s->hl);
20332 fprintf (stderr, " left overhang = %d, right = %d\n",
20333 s->left_overhang, s->right_overhang);
20334 fprintf (stderr, " nchars = %d\n", s->nchars);
20335 fprintf (stderr, " extends to end of line = %d\n",
20336 s->extends_to_end_of_line_p);
20337 fprintf (stderr, " font height = %d\n", FONT_HEIGHT (s->font));
20338 fprintf (stderr, " bg width = %d\n", s->background_width);
20339 }
20340
20341 #endif /* GLYPH_DEBUG */
20342
20343 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
20344 of XChar2b structures for S; it can't be allocated in
20345 init_glyph_string because it must be allocated via `alloca'. W
20346 is the window on which S is drawn. ROW and AREA are the glyph row
20347 and area within the row from which S is constructed. START is the
20348 index of the first glyph structure covered by S. HL is a
20349 face-override for drawing S. */
20350
20351 #ifdef HAVE_NTGUI
20352 #define OPTIONAL_HDC(hdc) HDC hdc,
20353 #define DECLARE_HDC(hdc) HDC hdc;
20354 #define ALLOCATE_HDC(hdc, f) hdc = get_frame_dc ((f))
20355 #define RELEASE_HDC(hdc, f) release_frame_dc ((f), (hdc))
20356 #endif
20357
20358 #ifndef OPTIONAL_HDC
20359 #define OPTIONAL_HDC(hdc)
20360 #define DECLARE_HDC(hdc)
20361 #define ALLOCATE_HDC(hdc, f)
20362 #define RELEASE_HDC(hdc, f)
20363 #endif
20364
20365 static void
20366 init_glyph_string (struct glyph_string *s,
20367 OPTIONAL_HDC (hdc)
20368 XChar2b *char2b, struct window *w, struct glyph_row *row,
20369 enum glyph_row_area area, int start, enum draw_glyphs_face hl)
20370 {
20371 memset (s, 0, sizeof *s);
20372 s->w = w;
20373 s->f = XFRAME (w->frame);
20374 #ifdef HAVE_NTGUI
20375 s->hdc = hdc;
20376 #endif
20377 s->display = FRAME_X_DISPLAY (s->f);
20378 s->window = FRAME_X_WINDOW (s->f);
20379 s->char2b = char2b;
20380 s->hl = hl;
20381 s->row = row;
20382 s->area = area;
20383 s->first_glyph = row->glyphs[area] + start;
20384 s->height = row->height;
20385 s->y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
20386 s->ybase = s->y + row->ascent;
20387 }
20388
20389
20390 /* Append the list of glyph strings with head H and tail T to the list
20391 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
20392
20393 static INLINE void
20394 append_glyph_string_lists (struct glyph_string **head, struct glyph_string **tail,
20395 struct glyph_string *h, struct glyph_string *t)
20396 {
20397 if (h)
20398 {
20399 if (*head)
20400 (*tail)->next = h;
20401 else
20402 *head = h;
20403 h->prev = *tail;
20404 *tail = t;
20405 }
20406 }
20407
20408
20409 /* Prepend the list of glyph strings with head H and tail T to the
20410 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
20411 result. */
20412
20413 static INLINE void
20414 prepend_glyph_string_lists (struct glyph_string **head, struct glyph_string **tail,
20415 struct glyph_string *h, struct glyph_string *t)
20416 {
20417 if (h)
20418 {
20419 if (*head)
20420 (*head)->prev = t;
20421 else
20422 *tail = t;
20423 t->next = *head;
20424 *head = h;
20425 }
20426 }
20427
20428
20429 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
20430 Set *HEAD and *TAIL to the resulting list. */
20431
20432 static INLINE void
20433 append_glyph_string (struct glyph_string **head, struct glyph_string **tail,
20434 struct glyph_string *s)
20435 {
20436 s->next = s->prev = NULL;
20437 append_glyph_string_lists (head, tail, s, s);
20438 }
20439
20440
20441 /* Get face and two-byte form of character C in face FACE_ID on frame
20442 F. The encoding of C is returned in *CHAR2B. MULTIBYTE_P non-zero
20443 means we want to display multibyte text. DISPLAY_P non-zero means
20444 make sure that X resources for the face returned are allocated.
20445 Value is a pointer to a realized face that is ready for display if
20446 DISPLAY_P is non-zero. */
20447
20448 static INLINE struct face *
20449 get_char_face_and_encoding (struct frame *f, int c, int face_id,
20450 XChar2b *char2b, int multibyte_p, int display_p)
20451 {
20452 struct face *face = FACE_FROM_ID (f, face_id);
20453
20454 if (face->font)
20455 {
20456 unsigned code = face->font->driver->encode_char (face->font, c);
20457
20458 if (code != FONT_INVALID_CODE)
20459 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
20460 else
20461 STORE_XCHAR2B (char2b, 0, 0);
20462 }
20463
20464 /* Make sure X resources of the face are allocated. */
20465 #ifdef HAVE_X_WINDOWS
20466 if (display_p)
20467 #endif
20468 {
20469 xassert (face != NULL);
20470 PREPARE_FACE_FOR_DISPLAY (f, face);
20471 }
20472
20473 return face;
20474 }
20475
20476
20477 /* Get face and two-byte form of character glyph GLYPH on frame F.
20478 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
20479 a pointer to a realized face that is ready for display. */
20480
20481 static INLINE struct face *
20482 get_glyph_face_and_encoding (struct frame *f, struct glyph *glyph,
20483 XChar2b *char2b, int *two_byte_p)
20484 {
20485 struct face *face;
20486
20487 xassert (glyph->type == CHAR_GLYPH);
20488 face = FACE_FROM_ID (f, glyph->face_id);
20489
20490 if (two_byte_p)
20491 *two_byte_p = 0;
20492
20493 if (face->font)
20494 {
20495 unsigned code = face->font->driver->encode_char (face->font, glyph->u.ch);
20496
20497 if (code != FONT_INVALID_CODE)
20498 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
20499 else
20500 STORE_XCHAR2B (char2b, 0, 0);
20501 }
20502
20503 /* Make sure X resources of the face are allocated. */
20504 xassert (face != NULL);
20505 PREPARE_FACE_FOR_DISPLAY (f, face);
20506 return face;
20507 }
20508
20509
20510 /* Fill glyph string S with composition components specified by S->cmp.
20511
20512 BASE_FACE is the base face of the composition.
20513 S->cmp_from is the index of the first component for S.
20514
20515 OVERLAPS non-zero means S should draw the foreground only, and use
20516 its physical height for clipping. See also draw_glyphs.
20517
20518 Value is the index of a component not in S. */
20519
20520 static int
20521 fill_composite_glyph_string (struct glyph_string *s, struct face *base_face,
20522 int overlaps)
20523 {
20524 int i;
20525 /* For all glyphs of this composition, starting at the offset
20526 S->cmp_from, until we reach the end of the definition or encounter a
20527 glyph that requires the different face, add it to S. */
20528 struct face *face;
20529
20530 xassert (s);
20531
20532 s->for_overlaps = overlaps;
20533 s->face = NULL;
20534 s->font = NULL;
20535 for (i = s->cmp_from; i < s->cmp->glyph_len; i++)
20536 {
20537 int c = COMPOSITION_GLYPH (s->cmp, i);
20538
20539 if (c != '\t')
20540 {
20541 int face_id = FACE_FOR_CHAR (s->f, base_face->ascii_face, c,
20542 -1, Qnil);
20543
20544 face = get_char_face_and_encoding (s->f, c, face_id,
20545 s->char2b + i, 1, 1);
20546 if (face)
20547 {
20548 if (! s->face)
20549 {
20550 s->face = face;
20551 s->font = s->face->font;
20552 }
20553 else if (s->face != face)
20554 break;
20555 }
20556 }
20557 ++s->nchars;
20558 }
20559 s->cmp_to = i;
20560
20561 /* All glyph strings for the same composition has the same width,
20562 i.e. the width set for the first component of the composition. */
20563 s->width = s->first_glyph->pixel_width;
20564
20565 /* If the specified font could not be loaded, use the frame's
20566 default font, but record the fact that we couldn't load it in
20567 the glyph string so that we can draw rectangles for the
20568 characters of the glyph string. */
20569 if (s->font == NULL)
20570 {
20571 s->font_not_found_p = 1;
20572 s->font = FRAME_FONT (s->f);
20573 }
20574
20575 /* Adjust base line for subscript/superscript text. */
20576 s->ybase += s->first_glyph->voffset;
20577
20578 /* This glyph string must always be drawn with 16-bit functions. */
20579 s->two_byte_p = 1;
20580
20581 return s->cmp_to;
20582 }
20583
20584 static int
20585 fill_gstring_glyph_string (struct glyph_string *s, int face_id,
20586 int start, int end, int overlaps)
20587 {
20588 struct glyph *glyph, *last;
20589 Lisp_Object lgstring;
20590 int i;
20591
20592 s->for_overlaps = overlaps;
20593 glyph = s->row->glyphs[s->area] + start;
20594 last = s->row->glyphs[s->area] + end;
20595 s->cmp_id = glyph->u.cmp.id;
20596 s->cmp_from = glyph->u.cmp.from;
20597 s->cmp_to = glyph->u.cmp.to + 1;
20598 s->face = FACE_FROM_ID (s->f, face_id);
20599 lgstring = composition_gstring_from_id (s->cmp_id);
20600 s->font = XFONT_OBJECT (LGSTRING_FONT (lgstring));
20601 glyph++;
20602 while (glyph < last
20603 && glyph->u.cmp.automatic
20604 && glyph->u.cmp.id == s->cmp_id
20605 && s->cmp_to == glyph->u.cmp.from)
20606 s->cmp_to = (glyph++)->u.cmp.to + 1;
20607
20608 for (i = s->cmp_from; i < s->cmp_to; i++)
20609 {
20610 Lisp_Object lglyph = LGSTRING_GLYPH (lgstring, i);
20611 unsigned code = LGLYPH_CODE (lglyph);
20612
20613 STORE_XCHAR2B ((s->char2b + i), code >> 8, code & 0xFF);
20614 }
20615 s->width = composition_gstring_width (lgstring, s->cmp_from, s->cmp_to, NULL);
20616 return glyph - s->row->glyphs[s->area];
20617 }
20618
20619
20620 /* Fill glyph string S from a sequence of character glyphs.
20621
20622 FACE_ID is the face id of the string. START is the index of the
20623 first glyph to consider, END is the index of the last + 1.
20624 OVERLAPS non-zero means S should draw the foreground only, and use
20625 its physical height for clipping. See also draw_glyphs.
20626
20627 Value is the index of the first glyph not in S. */
20628
20629 static int
20630 fill_glyph_string (struct glyph_string *s, int face_id,
20631 int start, int end, int overlaps)
20632 {
20633 struct glyph *glyph, *last;
20634 int voffset;
20635 int glyph_not_available_p;
20636
20637 xassert (s->f == XFRAME (s->w->frame));
20638 xassert (s->nchars == 0);
20639 xassert (start >= 0 && end > start);
20640
20641 s->for_overlaps = overlaps;
20642 glyph = s->row->glyphs[s->area] + start;
20643 last = s->row->glyphs[s->area] + end;
20644 voffset = glyph->voffset;
20645 s->padding_p = glyph->padding_p;
20646 glyph_not_available_p = glyph->glyph_not_available_p;
20647
20648 while (glyph < last
20649 && glyph->type == CHAR_GLYPH
20650 && glyph->voffset == voffset
20651 /* Same face id implies same font, nowadays. */
20652 && glyph->face_id == face_id
20653 && glyph->glyph_not_available_p == glyph_not_available_p)
20654 {
20655 int two_byte_p;
20656
20657 s->face = get_glyph_face_and_encoding (s->f, glyph,
20658 s->char2b + s->nchars,
20659 &two_byte_p);
20660 s->two_byte_p = two_byte_p;
20661 ++s->nchars;
20662 xassert (s->nchars <= end - start);
20663 s->width += glyph->pixel_width;
20664 if (glyph++->padding_p != s->padding_p)
20665 break;
20666 }
20667
20668 s->font = s->face->font;
20669
20670 /* If the specified font could not be loaded, use the frame's font,
20671 but record the fact that we couldn't load it in
20672 S->font_not_found_p so that we can draw rectangles for the
20673 characters of the glyph string. */
20674 if (s->font == NULL || glyph_not_available_p)
20675 {
20676 s->font_not_found_p = 1;
20677 s->font = FRAME_FONT (s->f);
20678 }
20679
20680 /* Adjust base line for subscript/superscript text. */
20681 s->ybase += voffset;
20682
20683 xassert (s->face && s->face->gc);
20684 return glyph - s->row->glyphs[s->area];
20685 }
20686
20687
20688 /* Fill glyph string S from image glyph S->first_glyph. */
20689
20690 static void
20691 fill_image_glyph_string (struct glyph_string *s)
20692 {
20693 xassert (s->first_glyph->type == IMAGE_GLYPH);
20694 s->img = IMAGE_FROM_ID (s->f, s->first_glyph->u.img_id);
20695 xassert (s->img);
20696 s->slice = s->first_glyph->slice;
20697 s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
20698 s->font = s->face->font;
20699 s->width = s->first_glyph->pixel_width;
20700
20701 /* Adjust base line for subscript/superscript text. */
20702 s->ybase += s->first_glyph->voffset;
20703 }
20704
20705
20706 /* Fill glyph string S from a sequence of stretch glyphs.
20707
20708 ROW is the glyph row in which the glyphs are found, AREA is the
20709 area within the row. START is the index of the first glyph to
20710 consider, END is the index of the last + 1.
20711
20712 Value is the index of the first glyph not in S. */
20713
20714 static int
20715 fill_stretch_glyph_string (struct glyph_string *s, struct glyph_row *row,
20716 enum glyph_row_area area, int start, int end)
20717 {
20718 struct glyph *glyph, *last;
20719 int voffset, face_id;
20720
20721 xassert (s->first_glyph->type == STRETCH_GLYPH);
20722
20723 glyph = s->row->glyphs[s->area] + start;
20724 last = s->row->glyphs[s->area] + end;
20725 face_id = glyph->face_id;
20726 s->face = FACE_FROM_ID (s->f, face_id);
20727 s->font = s->face->font;
20728 s->width = glyph->pixel_width;
20729 s->nchars = 1;
20730 voffset = glyph->voffset;
20731
20732 for (++glyph;
20733 (glyph < last
20734 && glyph->type == STRETCH_GLYPH
20735 && glyph->voffset == voffset
20736 && glyph->face_id == face_id);
20737 ++glyph)
20738 s->width += glyph->pixel_width;
20739
20740 /* Adjust base line for subscript/superscript text. */
20741 s->ybase += voffset;
20742
20743 /* The case that face->gc == 0 is handled when drawing the glyph
20744 string by calling PREPARE_FACE_FOR_DISPLAY. */
20745 xassert (s->face);
20746 return glyph - s->row->glyphs[s->area];
20747 }
20748
20749 static struct font_metrics *
20750 get_per_char_metric (struct frame *f, struct font *font, XChar2b *char2b)
20751 {
20752 static struct font_metrics metrics;
20753 unsigned code = (XCHAR2B_BYTE1 (char2b) << 8) | XCHAR2B_BYTE2 (char2b);
20754
20755 if (! font || code == FONT_INVALID_CODE)
20756 return NULL;
20757 font->driver->text_extents (font, &code, 1, &metrics);
20758 return &metrics;
20759 }
20760
20761 /* EXPORT for RIF:
20762 Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
20763 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
20764 assumed to be zero. */
20765
20766 void
20767 x_get_glyph_overhangs (struct glyph *glyph, struct frame *f, int *left, int *right)
20768 {
20769 *left = *right = 0;
20770
20771 if (glyph->type == CHAR_GLYPH)
20772 {
20773 struct face *face;
20774 XChar2b char2b;
20775 struct font_metrics *pcm;
20776
20777 face = get_glyph_face_and_encoding (f, glyph, &char2b, NULL);
20778 if (face->font && (pcm = get_per_char_metric (f, face->font, &char2b)))
20779 {
20780 if (pcm->rbearing > pcm->width)
20781 *right = pcm->rbearing - pcm->width;
20782 if (pcm->lbearing < 0)
20783 *left = -pcm->lbearing;
20784 }
20785 }
20786 else if (glyph->type == COMPOSITE_GLYPH)
20787 {
20788 if (! glyph->u.cmp.automatic)
20789 {
20790 struct composition *cmp = composition_table[glyph->u.cmp.id];
20791
20792 if (cmp->rbearing > cmp->pixel_width)
20793 *right = cmp->rbearing - cmp->pixel_width;
20794 if (cmp->lbearing < 0)
20795 *left = - cmp->lbearing;
20796 }
20797 else
20798 {
20799 Lisp_Object gstring = composition_gstring_from_id (glyph->u.cmp.id);
20800 struct font_metrics metrics;
20801
20802 composition_gstring_width (gstring, glyph->u.cmp.from,
20803 glyph->u.cmp.to + 1, &metrics);
20804 if (metrics.rbearing > metrics.width)
20805 *right = metrics.rbearing - metrics.width;
20806 if (metrics.lbearing < 0)
20807 *left = - metrics.lbearing;
20808 }
20809 }
20810 }
20811
20812
20813 /* Return the index of the first glyph preceding glyph string S that
20814 is overwritten by S because of S's left overhang. Value is -1
20815 if no glyphs are overwritten. */
20816
20817 static int
20818 left_overwritten (struct glyph_string *s)
20819 {
20820 int k;
20821
20822 if (s->left_overhang)
20823 {
20824 int x = 0, i;
20825 struct glyph *glyphs = s->row->glyphs[s->area];
20826 int first = s->first_glyph - glyphs;
20827
20828 for (i = first - 1; i >= 0 && x > -s->left_overhang; --i)
20829 x -= glyphs[i].pixel_width;
20830
20831 k = i + 1;
20832 }
20833 else
20834 k = -1;
20835
20836 return k;
20837 }
20838
20839
20840 /* Return the index of the first glyph preceding glyph string S that
20841 is overwriting S because of its right overhang. Value is -1 if no
20842 glyph in front of S overwrites S. */
20843
20844 static int
20845 left_overwriting (struct glyph_string *s)
20846 {
20847 int i, k, x;
20848 struct glyph *glyphs = s->row->glyphs[s->area];
20849 int first = s->first_glyph - glyphs;
20850
20851 k = -1;
20852 x = 0;
20853 for (i = first - 1; i >= 0; --i)
20854 {
20855 int left, right;
20856 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
20857 if (x + right > 0)
20858 k = i;
20859 x -= glyphs[i].pixel_width;
20860 }
20861
20862 return k;
20863 }
20864
20865
20866 /* Return the index of the last glyph following glyph string S that is
20867 overwritten by S because of S's right overhang. Value is -1 if
20868 no such glyph is found. */
20869
20870 static int
20871 right_overwritten (struct glyph_string *s)
20872 {
20873 int k = -1;
20874
20875 if (s->right_overhang)
20876 {
20877 int x = 0, i;
20878 struct glyph *glyphs = s->row->glyphs[s->area];
20879 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
20880 int end = s->row->used[s->area];
20881
20882 for (i = first; i < end && s->right_overhang > x; ++i)
20883 x += glyphs[i].pixel_width;
20884
20885 k = i;
20886 }
20887
20888 return k;
20889 }
20890
20891
20892 /* Return the index of the last glyph following glyph string S that
20893 overwrites S because of its left overhang. Value is negative
20894 if no such glyph is found. */
20895
20896 static int
20897 right_overwriting (struct glyph_string *s)
20898 {
20899 int i, k, x;
20900 int end = s->row->used[s->area];
20901 struct glyph *glyphs = s->row->glyphs[s->area];
20902 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
20903
20904 k = -1;
20905 x = 0;
20906 for (i = first; i < end; ++i)
20907 {
20908 int left, right;
20909 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
20910 if (x - left < 0)
20911 k = i;
20912 x += glyphs[i].pixel_width;
20913 }
20914
20915 return k;
20916 }
20917
20918
20919 /* Set background width of glyph string S. START is the index of the
20920 first glyph following S. LAST_X is the right-most x-position + 1
20921 in the drawing area. */
20922
20923 static INLINE void
20924 set_glyph_string_background_width (struct glyph_string *s, int start, int last_x)
20925 {
20926 /* If the face of this glyph string has to be drawn to the end of
20927 the drawing area, set S->extends_to_end_of_line_p. */
20928
20929 if (start == s->row->used[s->area]
20930 && s->area == TEXT_AREA
20931 && ((s->row->fill_line_p
20932 && (s->hl == DRAW_NORMAL_TEXT
20933 || s->hl == DRAW_IMAGE_RAISED
20934 || s->hl == DRAW_IMAGE_SUNKEN))
20935 || s->hl == DRAW_MOUSE_FACE))
20936 s->extends_to_end_of_line_p = 1;
20937
20938 /* If S extends its face to the end of the line, set its
20939 background_width to the distance to the right edge of the drawing
20940 area. */
20941 if (s->extends_to_end_of_line_p)
20942 s->background_width = last_x - s->x + 1;
20943 else
20944 s->background_width = s->width;
20945 }
20946
20947
20948 /* Compute overhangs and x-positions for glyph string S and its
20949 predecessors, or successors. X is the starting x-position for S.
20950 BACKWARD_P non-zero means process predecessors. */
20951
20952 static void
20953 compute_overhangs_and_x (struct glyph_string *s, int x, int backward_p)
20954 {
20955 if (backward_p)
20956 {
20957 while (s)
20958 {
20959 if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
20960 FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
20961 x -= s->width;
20962 s->x = x;
20963 s = s->prev;
20964 }
20965 }
20966 else
20967 {
20968 while (s)
20969 {
20970 if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
20971 FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
20972 s->x = x;
20973 x += s->width;
20974 s = s->next;
20975 }
20976 }
20977 }
20978
20979
20980
20981 /* The following macros are only called from draw_glyphs below.
20982 They reference the following parameters of that function directly:
20983 `w', `row', `area', and `overlap_p'
20984 as well as the following local variables:
20985 `s', `f', and `hdc' (in W32) */
20986
20987 #ifdef HAVE_NTGUI
20988 /* On W32, silently add local `hdc' variable to argument list of
20989 init_glyph_string. */
20990 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
20991 init_glyph_string (s, hdc, char2b, w, row, area, start, hl)
20992 #else
20993 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
20994 init_glyph_string (s, char2b, w, row, area, start, hl)
20995 #endif
20996
20997 /* Add a glyph string for a stretch glyph to the list of strings
20998 between HEAD and TAIL. START is the index of the stretch glyph in
20999 row area AREA of glyph row ROW. END is the index of the last glyph
21000 in that glyph row area. X is the current output position assigned
21001 to the new glyph string constructed. HL overrides that face of the
21002 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
21003 is the right-most x-position of the drawing area. */
21004
21005 /* SunOS 4 bundled cc, barfed on continuations in the arg lists here
21006 and below -- keep them on one line. */
21007 #define BUILD_STRETCH_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
21008 do \
21009 { \
21010 s = (struct glyph_string *) alloca (sizeof *s); \
21011 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
21012 START = fill_stretch_glyph_string (s, row, area, START, END); \
21013 append_glyph_string (&HEAD, &TAIL, s); \
21014 s->x = (X); \
21015 } \
21016 while (0)
21017
21018
21019 /* Add a glyph string for an image glyph to the list of strings
21020 between HEAD and TAIL. START is the index of the image glyph in
21021 row area AREA of glyph row ROW. END is the index of the last glyph
21022 in that glyph row area. X is the current output position assigned
21023 to the new glyph string constructed. HL overrides that face of the
21024 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
21025 is the right-most x-position of the drawing area. */
21026
21027 #define BUILD_IMAGE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
21028 do \
21029 { \
21030 s = (struct glyph_string *) alloca (sizeof *s); \
21031 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
21032 fill_image_glyph_string (s); \
21033 append_glyph_string (&HEAD, &TAIL, s); \
21034 ++START; \
21035 s->x = (X); \
21036 } \
21037 while (0)
21038
21039
21040 /* Add a glyph string for a sequence of character glyphs to the list
21041 of strings between HEAD and TAIL. START is the index of the first
21042 glyph in row area AREA of glyph row ROW that is part of the new
21043 glyph string. END is the index of the last glyph in that glyph row
21044 area. X is the current output position assigned to the new glyph
21045 string constructed. HL overrides that face of the glyph; e.g. it
21046 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
21047 right-most x-position of the drawing area. */
21048
21049 #define BUILD_CHAR_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
21050 do \
21051 { \
21052 int face_id; \
21053 XChar2b *char2b; \
21054 \
21055 face_id = (row)->glyphs[area][START].face_id; \
21056 \
21057 s = (struct glyph_string *) alloca (sizeof *s); \
21058 char2b = (XChar2b *) alloca ((END - START) * sizeof *char2b); \
21059 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
21060 append_glyph_string (&HEAD, &TAIL, s); \
21061 s->x = (X); \
21062 START = fill_glyph_string (s, face_id, START, END, overlaps); \
21063 } \
21064 while (0)
21065
21066
21067 /* Add a glyph string for a composite sequence to the list of strings
21068 between HEAD and TAIL. START is the index of the first glyph in
21069 row area AREA of glyph row ROW that is part of the new glyph
21070 string. END is the index of the last glyph in that glyph row area.
21071 X is the current output position assigned to the new glyph string
21072 constructed. HL overrides that face of the glyph; e.g. it is
21073 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
21074 x-position of the drawing area. */
21075
21076 #define BUILD_COMPOSITE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
21077 do { \
21078 int face_id = (row)->glyphs[area][START].face_id; \
21079 struct face *base_face = FACE_FROM_ID (f, face_id); \
21080 int cmp_id = (row)->glyphs[area][START].u.cmp.id; \
21081 struct composition *cmp = composition_table[cmp_id]; \
21082 XChar2b *char2b; \
21083 struct glyph_string *first_s; \
21084 int n; \
21085 \
21086 char2b = (XChar2b *) alloca ((sizeof *char2b) * cmp->glyph_len); \
21087 \
21088 /* Make glyph_strings for each glyph sequence that is drawable by \
21089 the same face, and append them to HEAD/TAIL. */ \
21090 for (n = 0; n < cmp->glyph_len;) \
21091 { \
21092 s = (struct glyph_string *) alloca (sizeof *s); \
21093 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
21094 append_glyph_string (&(HEAD), &(TAIL), s); \
21095 s->cmp = cmp; \
21096 s->cmp_from = n; \
21097 s->x = (X); \
21098 if (n == 0) \
21099 first_s = s; \
21100 n = fill_composite_glyph_string (s, base_face, overlaps); \
21101 } \
21102 \
21103 ++START; \
21104 s = first_s; \
21105 } while (0)
21106
21107
21108 /* Add a glyph string for a glyph-string sequence to the list of strings
21109 between HEAD and TAIL. */
21110
21111 #define BUILD_GSTRING_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
21112 do { \
21113 int face_id; \
21114 XChar2b *char2b; \
21115 Lisp_Object gstring; \
21116 \
21117 face_id = (row)->glyphs[area][START].face_id; \
21118 gstring = (composition_gstring_from_id \
21119 ((row)->glyphs[area][START].u.cmp.id)); \
21120 s = (struct glyph_string *) alloca (sizeof *s); \
21121 char2b = (XChar2b *) alloca ((sizeof *char2b) \
21122 * LGSTRING_GLYPH_LEN (gstring)); \
21123 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
21124 append_glyph_string (&(HEAD), &(TAIL), s); \
21125 s->x = (X); \
21126 START = fill_gstring_glyph_string (s, face_id, START, END, overlaps); \
21127 } while (0)
21128
21129
21130 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
21131 of AREA of glyph row ROW on window W between indices START and END.
21132 HL overrides the face for drawing glyph strings, e.g. it is
21133 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
21134 x-positions of the drawing area.
21135
21136 This is an ugly monster macro construct because we must use alloca
21137 to allocate glyph strings (because draw_glyphs can be called
21138 asynchronously). */
21139
21140 #define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
21141 do \
21142 { \
21143 HEAD = TAIL = NULL; \
21144 while (START < END) \
21145 { \
21146 struct glyph *first_glyph = (row)->glyphs[area] + START; \
21147 switch (first_glyph->type) \
21148 { \
21149 case CHAR_GLYPH: \
21150 BUILD_CHAR_GLYPH_STRINGS (START, END, HEAD, TAIL, \
21151 HL, X, LAST_X); \
21152 break; \
21153 \
21154 case COMPOSITE_GLYPH: \
21155 if (first_glyph->u.cmp.automatic) \
21156 BUILD_GSTRING_GLYPH_STRING (START, END, HEAD, TAIL, \
21157 HL, X, LAST_X); \
21158 else \
21159 BUILD_COMPOSITE_GLYPH_STRING (START, END, HEAD, TAIL, \
21160 HL, X, LAST_X); \
21161 break; \
21162 \
21163 case STRETCH_GLYPH: \
21164 BUILD_STRETCH_GLYPH_STRING (START, END, HEAD, TAIL, \
21165 HL, X, LAST_X); \
21166 break; \
21167 \
21168 case IMAGE_GLYPH: \
21169 BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL, \
21170 HL, X, LAST_X); \
21171 break; \
21172 \
21173 default: \
21174 abort (); \
21175 } \
21176 \
21177 if (s) \
21178 { \
21179 set_glyph_string_background_width (s, START, LAST_X); \
21180 (X) += s->width; \
21181 } \
21182 } \
21183 } while (0)
21184
21185
21186 /* Draw glyphs between START and END in AREA of ROW on window W,
21187 starting at x-position X. X is relative to AREA in W. HL is a
21188 face-override with the following meaning:
21189
21190 DRAW_NORMAL_TEXT draw normally
21191 DRAW_CURSOR draw in cursor face
21192 DRAW_MOUSE_FACE draw in mouse face.
21193 DRAW_INVERSE_VIDEO draw in mode line face
21194 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
21195 DRAW_IMAGE_RAISED draw an image with a raised relief around it
21196
21197 If OVERLAPS is non-zero, draw only the foreground of characters and
21198 clip to the physical height of ROW. Non-zero value also defines
21199 the overlapping part to be drawn:
21200
21201 OVERLAPS_PRED overlap with preceding rows
21202 OVERLAPS_SUCC overlap with succeeding rows
21203 OVERLAPS_BOTH overlap with both preceding/succeeding rows
21204 OVERLAPS_ERASED_CURSOR overlap with erased cursor area
21205
21206 Value is the x-position reached, relative to AREA of W. */
21207
21208 static int
21209 draw_glyphs (struct window *w, int x, struct glyph_row *row,
21210 enum glyph_row_area area, EMACS_INT start, EMACS_INT end,
21211 enum draw_glyphs_face hl, int overlaps)
21212 {
21213 struct glyph_string *head, *tail;
21214 struct glyph_string *s;
21215 struct glyph_string *clip_head = NULL, *clip_tail = NULL;
21216 int i, j, x_reached, last_x, area_left = 0;
21217 struct frame *f = XFRAME (WINDOW_FRAME (w));
21218 DECLARE_HDC (hdc);
21219
21220 ALLOCATE_HDC (hdc, f);
21221
21222 /* Let's rather be paranoid than getting a SEGV. */
21223 end = min (end, row->used[area]);
21224 start = max (0, start);
21225 start = min (end, start);
21226
21227 /* Translate X to frame coordinates. Set last_x to the right
21228 end of the drawing area. */
21229 if (row->full_width_p)
21230 {
21231 /* X is relative to the left edge of W, without scroll bars
21232 or fringes. */
21233 area_left = WINDOW_LEFT_EDGE_X (w);
21234 last_x = WINDOW_LEFT_EDGE_X (w) + WINDOW_TOTAL_WIDTH (w);
21235 }
21236 else
21237 {
21238 area_left = window_box_left (w, area);
21239 last_x = area_left + window_box_width (w, area);
21240 }
21241 x += area_left;
21242
21243 /* Build a doubly-linked list of glyph_string structures between
21244 head and tail from what we have to draw. Note that the macro
21245 BUILD_GLYPH_STRINGS will modify its start parameter. That's
21246 the reason we use a separate variable `i'. */
21247 i = start;
21248 BUILD_GLYPH_STRINGS (i, end, head, tail, hl, x, last_x);
21249 if (tail)
21250 x_reached = tail->x + tail->background_width;
21251 else
21252 x_reached = x;
21253
21254 /* If there are any glyphs with lbearing < 0 or rbearing > width in
21255 the row, redraw some glyphs in front or following the glyph
21256 strings built above. */
21257 if (head && !overlaps && row->contains_overlapping_glyphs_p)
21258 {
21259 struct glyph_string *h, *t;
21260 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
21261 int mouse_beg_col, mouse_end_col, check_mouse_face = 0;
21262 int dummy_x = 0;
21263
21264 /* If mouse highlighting is on, we may need to draw adjacent
21265 glyphs using mouse-face highlighting. */
21266 if (area == TEXT_AREA && row->mouse_face_p)
21267 {
21268 struct glyph_row *mouse_beg_row, *mouse_end_row;
21269
21270 mouse_beg_row = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_beg_row);
21271 mouse_end_row = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_end_row);
21272
21273 if (row >= mouse_beg_row && row <= mouse_end_row)
21274 {
21275 check_mouse_face = 1;
21276 mouse_beg_col = (row == mouse_beg_row)
21277 ? dpyinfo->mouse_face_beg_col : 0;
21278 mouse_end_col = (row == mouse_end_row)
21279 ? dpyinfo->mouse_face_end_col
21280 : row->used[TEXT_AREA];
21281 }
21282 }
21283
21284 /* Compute overhangs for all glyph strings. */
21285 if (FRAME_RIF (f)->compute_glyph_string_overhangs)
21286 for (s = head; s; s = s->next)
21287 FRAME_RIF (f)->compute_glyph_string_overhangs (s);
21288
21289 /* Prepend glyph strings for glyphs in front of the first glyph
21290 string that are overwritten because of the first glyph
21291 string's left overhang. The background of all strings
21292 prepended must be drawn because the first glyph string
21293 draws over it. */
21294 i = left_overwritten (head);
21295 if (i >= 0)
21296 {
21297 enum draw_glyphs_face overlap_hl;
21298
21299 /* If this row contains mouse highlighting, attempt to draw
21300 the overlapped glyphs with the correct highlight. This
21301 code fails if the overlap encompasses more than one glyph
21302 and mouse-highlight spans only some of these glyphs.
21303 However, making it work perfectly involves a lot more
21304 code, and I don't know if the pathological case occurs in
21305 practice, so we'll stick to this for now. --- cyd */
21306 if (check_mouse_face
21307 && mouse_beg_col < start && mouse_end_col > i)
21308 overlap_hl = DRAW_MOUSE_FACE;
21309 else
21310 overlap_hl = DRAW_NORMAL_TEXT;
21311
21312 j = i;
21313 BUILD_GLYPH_STRINGS (j, start, h, t,
21314 overlap_hl, dummy_x, last_x);
21315 start = i;
21316 compute_overhangs_and_x (t, head->x, 1);
21317 prepend_glyph_string_lists (&head, &tail, h, t);
21318 clip_head = head;
21319 }
21320
21321 /* Prepend glyph strings for glyphs in front of the first glyph
21322 string that overwrite that glyph string because of their
21323 right overhang. For these strings, only the foreground must
21324 be drawn, because it draws over the glyph string at `head'.
21325 The background must not be drawn because this would overwrite
21326 right overhangs of preceding glyphs for which no glyph
21327 strings exist. */
21328 i = left_overwriting (head);
21329 if (i >= 0)
21330 {
21331 enum draw_glyphs_face overlap_hl;
21332
21333 if (check_mouse_face
21334 && mouse_beg_col < start && mouse_end_col > i)
21335 overlap_hl = DRAW_MOUSE_FACE;
21336 else
21337 overlap_hl = DRAW_NORMAL_TEXT;
21338
21339 clip_head = head;
21340 BUILD_GLYPH_STRINGS (i, start, h, t,
21341 overlap_hl, dummy_x, last_x);
21342 for (s = h; s; s = s->next)
21343 s->background_filled_p = 1;
21344 compute_overhangs_and_x (t, head->x, 1);
21345 prepend_glyph_string_lists (&head, &tail, h, t);
21346 }
21347
21348 /* Append glyphs strings for glyphs following the last glyph
21349 string tail that are overwritten by tail. The background of
21350 these strings has to be drawn because tail's foreground draws
21351 over it. */
21352 i = right_overwritten (tail);
21353 if (i >= 0)
21354 {
21355 enum draw_glyphs_face overlap_hl;
21356
21357 if (check_mouse_face
21358 && mouse_beg_col < i && mouse_end_col > end)
21359 overlap_hl = DRAW_MOUSE_FACE;
21360 else
21361 overlap_hl = DRAW_NORMAL_TEXT;
21362
21363 BUILD_GLYPH_STRINGS (end, i, h, t,
21364 overlap_hl, x, last_x);
21365 /* Because BUILD_GLYPH_STRINGS updates the first argument,
21366 we don't have `end = i;' here. */
21367 compute_overhangs_and_x (h, tail->x + tail->width, 0);
21368 append_glyph_string_lists (&head, &tail, h, t);
21369 clip_tail = tail;
21370 }
21371
21372 /* Append glyph strings for glyphs following the last glyph
21373 string tail that overwrite tail. The foreground of such
21374 glyphs has to be drawn because it writes into the background
21375 of tail. The background must not be drawn because it could
21376 paint over the foreground of following glyphs. */
21377 i = right_overwriting (tail);
21378 if (i >= 0)
21379 {
21380 enum draw_glyphs_face overlap_hl;
21381 if (check_mouse_face
21382 && mouse_beg_col < i && mouse_end_col > end)
21383 overlap_hl = DRAW_MOUSE_FACE;
21384 else
21385 overlap_hl = DRAW_NORMAL_TEXT;
21386
21387 clip_tail = tail;
21388 i++; /* We must include the Ith glyph. */
21389 BUILD_GLYPH_STRINGS (end, i, h, t,
21390 overlap_hl, x, last_x);
21391 for (s = h; s; s = s->next)
21392 s->background_filled_p = 1;
21393 compute_overhangs_and_x (h, tail->x + tail->width, 0);
21394 append_glyph_string_lists (&head, &tail, h, t);
21395 }
21396 if (clip_head || clip_tail)
21397 for (s = head; s; s = s->next)
21398 {
21399 s->clip_head = clip_head;
21400 s->clip_tail = clip_tail;
21401 }
21402 }
21403
21404 /* Draw all strings. */
21405 for (s = head; s; s = s->next)
21406 FRAME_RIF (f)->draw_glyph_string (s);
21407
21408 #ifndef HAVE_NS
21409 /* When focus a sole frame and move horizontally, this sets on_p to 0
21410 causing a failure to erase prev cursor position. */
21411 if (area == TEXT_AREA
21412 && !row->full_width_p
21413 /* When drawing overlapping rows, only the glyph strings'
21414 foreground is drawn, which doesn't erase a cursor
21415 completely. */
21416 && !overlaps)
21417 {
21418 int x0 = clip_head ? clip_head->x : (head ? head->x : x);
21419 int x1 = (clip_tail ? clip_tail->x + clip_tail->background_width
21420 : (tail ? tail->x + tail->background_width : x));
21421 x0 -= area_left;
21422 x1 -= area_left;
21423
21424 notice_overwritten_cursor (w, TEXT_AREA, x0, x1,
21425 row->y, MATRIX_ROW_BOTTOM_Y (row));
21426 }
21427 #endif
21428
21429 /* Value is the x-position up to which drawn, relative to AREA of W.
21430 This doesn't include parts drawn because of overhangs. */
21431 if (row->full_width_p)
21432 x_reached = FRAME_TO_WINDOW_PIXEL_X (w, x_reached);
21433 else
21434 x_reached -= area_left;
21435
21436 RELEASE_HDC (hdc, f);
21437
21438 return x_reached;
21439 }
21440
21441 /* Expand row matrix if too narrow. Don't expand if area
21442 is not present. */
21443
21444 #define IT_EXPAND_MATRIX_WIDTH(it, area) \
21445 { \
21446 if (!fonts_changed_p \
21447 && (it->glyph_row->glyphs[area] \
21448 < it->glyph_row->glyphs[area + 1])) \
21449 { \
21450 it->w->ncols_scale_factor++; \
21451 fonts_changed_p = 1; \
21452 } \
21453 }
21454
21455 /* Store one glyph for IT->char_to_display in IT->glyph_row.
21456 Called from x_produce_glyphs when IT->glyph_row is non-null. */
21457
21458 static INLINE void
21459 append_glyph (struct it *it)
21460 {
21461 struct glyph *glyph;
21462 enum glyph_row_area area = it->area;
21463
21464 xassert (it->glyph_row);
21465 xassert (it->char_to_display != '\n' && it->char_to_display != '\t');
21466
21467 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
21468 if (glyph < it->glyph_row->glyphs[area + 1])
21469 {
21470 /* If the glyph row is reversed, we need to prepend the glyph
21471 rather than append it. */
21472 if (it->glyph_row->reversed_p && area == TEXT_AREA)
21473 {
21474 struct glyph *g;
21475
21476 /* Make room for the additional glyph. */
21477 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
21478 g[1] = *g;
21479 glyph = it->glyph_row->glyphs[area];
21480 }
21481 glyph->charpos = CHARPOS (it->position);
21482 glyph->object = it->object;
21483 if (it->pixel_width > 0)
21484 {
21485 glyph->pixel_width = it->pixel_width;
21486 glyph->padding_p = 0;
21487 }
21488 else
21489 {
21490 /* Assure at least 1-pixel width. Otherwise, cursor can't
21491 be displayed correctly. */
21492 glyph->pixel_width = 1;
21493 glyph->padding_p = 1;
21494 }
21495 glyph->ascent = it->ascent;
21496 glyph->descent = it->descent;
21497 glyph->voffset = it->voffset;
21498 glyph->type = CHAR_GLYPH;
21499 glyph->avoid_cursor_p = it->avoid_cursor_p;
21500 glyph->multibyte_p = it->multibyte_p;
21501 glyph->left_box_line_p = it->start_of_box_run_p;
21502 glyph->right_box_line_p = it->end_of_box_run_p;
21503 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
21504 || it->phys_descent > it->descent);
21505 glyph->glyph_not_available_p = it->glyph_not_available_p;
21506 glyph->face_id = it->face_id;
21507 glyph->u.ch = it->char_to_display;
21508 glyph->slice = null_glyph_slice;
21509 glyph->font_type = FONT_TYPE_UNKNOWN;
21510 if (it->bidi_p)
21511 {
21512 glyph->resolved_level = it->bidi_it.resolved_level;
21513 if ((it->bidi_it.type & 7) != it->bidi_it.type)
21514 abort ();
21515 glyph->bidi_type = it->bidi_it.type;
21516 }
21517 else
21518 {
21519 glyph->resolved_level = 0;
21520 glyph->bidi_type = UNKNOWN_BT;
21521 }
21522 ++it->glyph_row->used[area];
21523 }
21524 else
21525 IT_EXPAND_MATRIX_WIDTH (it, area);
21526 }
21527
21528 /* Store one glyph for the composition IT->cmp_it.id in
21529 IT->glyph_row. Called from x_produce_glyphs when IT->glyph_row is
21530 non-null. */
21531
21532 static INLINE void
21533 append_composite_glyph (struct it *it)
21534 {
21535 struct glyph *glyph;
21536 enum glyph_row_area area = it->area;
21537
21538 xassert (it->glyph_row);
21539
21540 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
21541 if (glyph < it->glyph_row->glyphs[area + 1])
21542 {
21543 /* If the glyph row is reversed, we need to prepend the glyph
21544 rather than append it. */
21545 if (it->glyph_row->reversed_p && it->area == TEXT_AREA)
21546 {
21547 struct glyph *g;
21548
21549 /* Make room for the new glyph. */
21550 for (g = glyph - 1; g >= it->glyph_row->glyphs[it->area]; g--)
21551 g[1] = *g;
21552 glyph = it->glyph_row->glyphs[it->area];
21553 }
21554 glyph->charpos = it->cmp_it.charpos;
21555 glyph->object = it->object;
21556 glyph->pixel_width = it->pixel_width;
21557 glyph->ascent = it->ascent;
21558 glyph->descent = it->descent;
21559 glyph->voffset = it->voffset;
21560 glyph->type = COMPOSITE_GLYPH;
21561 if (it->cmp_it.ch < 0)
21562 {
21563 glyph->u.cmp.automatic = 0;
21564 glyph->u.cmp.id = it->cmp_it.id;
21565 }
21566 else
21567 {
21568 glyph->u.cmp.automatic = 1;
21569 glyph->u.cmp.id = it->cmp_it.id;
21570 glyph->u.cmp.from = it->cmp_it.from;
21571 glyph->u.cmp.to = it->cmp_it.to - 1;
21572 }
21573 glyph->avoid_cursor_p = it->avoid_cursor_p;
21574 glyph->multibyte_p = it->multibyte_p;
21575 glyph->left_box_line_p = it->start_of_box_run_p;
21576 glyph->right_box_line_p = it->end_of_box_run_p;
21577 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
21578 || it->phys_descent > it->descent);
21579 glyph->padding_p = 0;
21580 glyph->glyph_not_available_p = 0;
21581 glyph->face_id = it->face_id;
21582 glyph->slice = null_glyph_slice;
21583 glyph->font_type = FONT_TYPE_UNKNOWN;
21584 if (it->bidi_p)
21585 {
21586 glyph->resolved_level = it->bidi_it.resolved_level;
21587 if ((it->bidi_it.type & 7) != it->bidi_it.type)
21588 abort ();
21589 glyph->bidi_type = it->bidi_it.type;
21590 }
21591 ++it->glyph_row->used[area];
21592 }
21593 else
21594 IT_EXPAND_MATRIX_WIDTH (it, area);
21595 }
21596
21597
21598 /* Change IT->ascent and IT->height according to the setting of
21599 IT->voffset. */
21600
21601 static INLINE void
21602 take_vertical_position_into_account (struct it *it)
21603 {
21604 if (it->voffset)
21605 {
21606 if (it->voffset < 0)
21607 /* Increase the ascent so that we can display the text higher
21608 in the line. */
21609 it->ascent -= it->voffset;
21610 else
21611 /* Increase the descent so that we can display the text lower
21612 in the line. */
21613 it->descent += it->voffset;
21614 }
21615 }
21616
21617
21618 /* Produce glyphs/get display metrics for the image IT is loaded with.
21619 See the description of struct display_iterator in dispextern.h for
21620 an overview of struct display_iterator. */
21621
21622 static void
21623 produce_image_glyph (struct it *it)
21624 {
21625 struct image *img;
21626 struct face *face;
21627 int glyph_ascent, crop;
21628 struct glyph_slice slice;
21629
21630 xassert (it->what == IT_IMAGE);
21631
21632 face = FACE_FROM_ID (it->f, it->face_id);
21633 xassert (face);
21634 /* Make sure X resources of the face is loaded. */
21635 PREPARE_FACE_FOR_DISPLAY (it->f, face);
21636
21637 if (it->image_id < 0)
21638 {
21639 /* Fringe bitmap. */
21640 it->ascent = it->phys_ascent = 0;
21641 it->descent = it->phys_descent = 0;
21642 it->pixel_width = 0;
21643 it->nglyphs = 0;
21644 return;
21645 }
21646
21647 img = IMAGE_FROM_ID (it->f, it->image_id);
21648 xassert (img);
21649 /* Make sure X resources of the image is loaded. */
21650 prepare_image_for_display (it->f, img);
21651
21652 slice.x = slice.y = 0;
21653 slice.width = img->width;
21654 slice.height = img->height;
21655
21656 if (INTEGERP (it->slice.x))
21657 slice.x = XINT (it->slice.x);
21658 else if (FLOATP (it->slice.x))
21659 slice.x = XFLOAT_DATA (it->slice.x) * img->width;
21660
21661 if (INTEGERP (it->slice.y))
21662 slice.y = XINT (it->slice.y);
21663 else if (FLOATP (it->slice.y))
21664 slice.y = XFLOAT_DATA (it->slice.y) * img->height;
21665
21666 if (INTEGERP (it->slice.width))
21667 slice.width = XINT (it->slice.width);
21668 else if (FLOATP (it->slice.width))
21669 slice.width = XFLOAT_DATA (it->slice.width) * img->width;
21670
21671 if (INTEGERP (it->slice.height))
21672 slice.height = XINT (it->slice.height);
21673 else if (FLOATP (it->slice.height))
21674 slice.height = XFLOAT_DATA (it->slice.height) * img->height;
21675
21676 if (slice.x >= img->width)
21677 slice.x = img->width;
21678 if (slice.y >= img->height)
21679 slice.y = img->height;
21680 if (slice.x + slice.width >= img->width)
21681 slice.width = img->width - slice.x;
21682 if (slice.y + slice.height > img->height)
21683 slice.height = img->height - slice.y;
21684
21685 if (slice.width == 0 || slice.height == 0)
21686 return;
21687
21688 it->ascent = it->phys_ascent = glyph_ascent = image_ascent (img, face, &slice);
21689
21690 it->descent = slice.height - glyph_ascent;
21691 if (slice.y == 0)
21692 it->descent += img->vmargin;
21693 if (slice.y + slice.height == img->height)
21694 it->descent += img->vmargin;
21695 it->phys_descent = it->descent;
21696
21697 it->pixel_width = slice.width;
21698 if (slice.x == 0)
21699 it->pixel_width += img->hmargin;
21700 if (slice.x + slice.width == img->width)
21701 it->pixel_width += img->hmargin;
21702
21703 /* It's quite possible for images to have an ascent greater than
21704 their height, so don't get confused in that case. */
21705 if (it->descent < 0)
21706 it->descent = 0;
21707
21708 it->nglyphs = 1;
21709
21710 if (face->box != FACE_NO_BOX)
21711 {
21712 if (face->box_line_width > 0)
21713 {
21714 if (slice.y == 0)
21715 it->ascent += face->box_line_width;
21716 if (slice.y + slice.height == img->height)
21717 it->descent += face->box_line_width;
21718 }
21719
21720 if (it->start_of_box_run_p && slice.x == 0)
21721 it->pixel_width += eabs (face->box_line_width);
21722 if (it->end_of_box_run_p && slice.x + slice.width == img->width)
21723 it->pixel_width += eabs (face->box_line_width);
21724 }
21725
21726 take_vertical_position_into_account (it);
21727
21728 /* Automatically crop wide image glyphs at right edge so we can
21729 draw the cursor on same display row. */
21730 if ((crop = it->pixel_width - (it->last_visible_x - it->current_x), crop > 0)
21731 && (it->hpos == 0 || it->pixel_width > it->last_visible_x / 4))
21732 {
21733 it->pixel_width -= crop;
21734 slice.width -= crop;
21735 }
21736
21737 if (it->glyph_row)
21738 {
21739 struct glyph *glyph;
21740 enum glyph_row_area area = it->area;
21741
21742 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
21743 if (glyph < it->glyph_row->glyphs[area + 1])
21744 {
21745 glyph->charpos = CHARPOS (it->position);
21746 glyph->object = it->object;
21747 glyph->pixel_width = it->pixel_width;
21748 glyph->ascent = glyph_ascent;
21749 glyph->descent = it->descent;
21750 glyph->voffset = it->voffset;
21751 glyph->type = IMAGE_GLYPH;
21752 glyph->avoid_cursor_p = it->avoid_cursor_p;
21753 glyph->multibyte_p = it->multibyte_p;
21754 glyph->left_box_line_p = it->start_of_box_run_p;
21755 glyph->right_box_line_p = it->end_of_box_run_p;
21756 glyph->overlaps_vertically_p = 0;
21757 glyph->padding_p = 0;
21758 glyph->glyph_not_available_p = 0;
21759 glyph->face_id = it->face_id;
21760 glyph->u.img_id = img->id;
21761 glyph->slice = slice;
21762 glyph->font_type = FONT_TYPE_UNKNOWN;
21763 if (it->bidi_p)
21764 {
21765 glyph->resolved_level = it->bidi_it.resolved_level;
21766 if ((it->bidi_it.type & 7) != it->bidi_it.type)
21767 abort ();
21768 glyph->bidi_type = it->bidi_it.type;
21769 }
21770 ++it->glyph_row->used[area];
21771 }
21772 else
21773 IT_EXPAND_MATRIX_WIDTH (it, area);
21774 }
21775 }
21776
21777
21778 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
21779 of the glyph, WIDTH and HEIGHT are the width and height of the
21780 stretch. ASCENT is the ascent of the glyph (0 <= ASCENT <= HEIGHT). */
21781
21782 static void
21783 append_stretch_glyph (struct it *it, Lisp_Object object,
21784 int width, int height, int ascent)
21785 {
21786 struct glyph *glyph;
21787 enum glyph_row_area area = it->area;
21788
21789 xassert (ascent >= 0 && ascent <= height);
21790
21791 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
21792 if (glyph < it->glyph_row->glyphs[area + 1])
21793 {
21794 /* If the glyph row is reversed, we need to prepend the glyph
21795 rather than append it. */
21796 if (it->glyph_row->reversed_p && area == TEXT_AREA)
21797 {
21798 struct glyph *g;
21799
21800 /* Make room for the additional glyph. */
21801 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
21802 g[1] = *g;
21803 glyph = it->glyph_row->glyphs[area];
21804 }
21805 glyph->charpos = CHARPOS (it->position);
21806 glyph->object = object;
21807 glyph->pixel_width = width;
21808 glyph->ascent = ascent;
21809 glyph->descent = height - ascent;
21810 glyph->voffset = it->voffset;
21811 glyph->type = STRETCH_GLYPH;
21812 glyph->avoid_cursor_p = it->avoid_cursor_p;
21813 glyph->multibyte_p = it->multibyte_p;
21814 glyph->left_box_line_p = it->start_of_box_run_p;
21815 glyph->right_box_line_p = it->end_of_box_run_p;
21816 glyph->overlaps_vertically_p = 0;
21817 glyph->padding_p = 0;
21818 glyph->glyph_not_available_p = 0;
21819 glyph->face_id = it->face_id;
21820 glyph->u.stretch.ascent = ascent;
21821 glyph->u.stretch.height = height;
21822 glyph->slice = null_glyph_slice;
21823 glyph->font_type = FONT_TYPE_UNKNOWN;
21824 if (it->bidi_p)
21825 {
21826 glyph->resolved_level = it->bidi_it.resolved_level;
21827 if ((it->bidi_it.type & 7) != it->bidi_it.type)
21828 abort ();
21829 glyph->bidi_type = it->bidi_it.type;
21830 }
21831 else
21832 {
21833 glyph->resolved_level = 0;
21834 glyph->bidi_type = UNKNOWN_BT;
21835 }
21836 ++it->glyph_row->used[area];
21837 }
21838 else
21839 IT_EXPAND_MATRIX_WIDTH (it, area);
21840 }
21841
21842
21843 /* Produce a stretch glyph for iterator IT. IT->object is the value
21844 of the glyph property displayed. The value must be a list
21845 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
21846 being recognized:
21847
21848 1. `:width WIDTH' specifies that the space should be WIDTH *
21849 canonical char width wide. WIDTH may be an integer or floating
21850 point number.
21851
21852 2. `:relative-width FACTOR' specifies that the width of the stretch
21853 should be computed from the width of the first character having the
21854 `glyph' property, and should be FACTOR times that width.
21855
21856 3. `:align-to HPOS' specifies that the space should be wide enough
21857 to reach HPOS, a value in canonical character units.
21858
21859 Exactly one of the above pairs must be present.
21860
21861 4. `:height HEIGHT' specifies that the height of the stretch produced
21862 should be HEIGHT, measured in canonical character units.
21863
21864 5. `:relative-height FACTOR' specifies that the height of the
21865 stretch should be FACTOR times the height of the characters having
21866 the glyph property.
21867
21868 Either none or exactly one of 4 or 5 must be present.
21869
21870 6. `:ascent ASCENT' specifies that ASCENT percent of the height
21871 of the stretch should be used for the ascent of the stretch.
21872 ASCENT must be in the range 0 <= ASCENT <= 100. */
21873
21874 static void
21875 produce_stretch_glyph (struct it *it)
21876 {
21877 /* (space :width WIDTH :height HEIGHT ...) */
21878 Lisp_Object prop, plist;
21879 int width = 0, height = 0, align_to = -1;
21880 int zero_width_ok_p = 0, zero_height_ok_p = 0;
21881 int ascent = 0;
21882 double tem;
21883 struct face *face = FACE_FROM_ID (it->f, it->face_id);
21884 struct font *font = face->font ? face->font : FRAME_FONT (it->f);
21885
21886 PREPARE_FACE_FOR_DISPLAY (it->f, face);
21887
21888 /* List should start with `space'. */
21889 xassert (CONSP (it->object) && EQ (XCAR (it->object), Qspace));
21890 plist = XCDR (it->object);
21891
21892 /* Compute the width of the stretch. */
21893 if ((prop = Fplist_get (plist, QCwidth), !NILP (prop))
21894 && calc_pixel_width_or_height (&tem, it, prop, font, 1, 0))
21895 {
21896 /* Absolute width `:width WIDTH' specified and valid. */
21897 zero_width_ok_p = 1;
21898 width = (int)tem;
21899 }
21900 else if (prop = Fplist_get (plist, QCrelative_width),
21901 NUMVAL (prop) > 0)
21902 {
21903 /* Relative width `:relative-width FACTOR' specified and valid.
21904 Compute the width of the characters having the `glyph'
21905 property. */
21906 struct it it2;
21907 unsigned char *p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
21908
21909 it2 = *it;
21910 if (it->multibyte_p)
21911 {
21912 int maxlen = ((IT_BYTEPOS (*it) >= GPT ? ZV : GPT)
21913 - IT_BYTEPOS (*it));
21914 it2.c = STRING_CHAR_AND_LENGTH (p, it2.len);
21915 }
21916 else
21917 it2.c = *p, it2.len = 1;
21918
21919 it2.glyph_row = NULL;
21920 it2.what = IT_CHARACTER;
21921 x_produce_glyphs (&it2);
21922 width = NUMVAL (prop) * it2.pixel_width;
21923 }
21924 else if ((prop = Fplist_get (plist, QCalign_to), !NILP (prop))
21925 && calc_pixel_width_or_height (&tem, it, prop, font, 1, &align_to))
21926 {
21927 if (it->glyph_row == NULL || !it->glyph_row->mode_line_p)
21928 align_to = (align_to < 0
21929 ? 0
21930 : align_to - window_box_left_offset (it->w, TEXT_AREA));
21931 else if (align_to < 0)
21932 align_to = window_box_left_offset (it->w, TEXT_AREA);
21933 width = max (0, (int)tem + align_to - it->current_x);
21934 zero_width_ok_p = 1;
21935 }
21936 else
21937 /* Nothing specified -> width defaults to canonical char width. */
21938 width = FRAME_COLUMN_WIDTH (it->f);
21939
21940 if (width <= 0 && (width < 0 || !zero_width_ok_p))
21941 width = 1;
21942
21943 /* Compute height. */
21944 if ((prop = Fplist_get (plist, QCheight), !NILP (prop))
21945 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
21946 {
21947 height = (int)tem;
21948 zero_height_ok_p = 1;
21949 }
21950 else if (prop = Fplist_get (plist, QCrelative_height),
21951 NUMVAL (prop) > 0)
21952 height = FONT_HEIGHT (font) * NUMVAL (prop);
21953 else
21954 height = FONT_HEIGHT (font);
21955
21956 if (height <= 0 && (height < 0 || !zero_height_ok_p))
21957 height = 1;
21958
21959 /* Compute percentage of height used for ascent. If
21960 `:ascent ASCENT' is present and valid, use that. Otherwise,
21961 derive the ascent from the font in use. */
21962 if (prop = Fplist_get (plist, QCascent),
21963 NUMVAL (prop) > 0 && NUMVAL (prop) <= 100)
21964 ascent = height * NUMVAL (prop) / 100.0;
21965 else if (!NILP (prop)
21966 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
21967 ascent = min (max (0, (int)tem), height);
21968 else
21969 ascent = (height * FONT_BASE (font)) / FONT_HEIGHT (font);
21970
21971 if (width > 0 && it->line_wrap != TRUNCATE
21972 && it->current_x + width > it->last_visible_x)
21973 width = it->last_visible_x - it->current_x - 1;
21974
21975 if (width > 0 && height > 0 && it->glyph_row)
21976 {
21977 Lisp_Object object = it->stack[it->sp - 1].string;
21978 if (!STRINGP (object))
21979 object = it->w->buffer;
21980 append_stretch_glyph (it, object, width, height, ascent);
21981 }
21982
21983 it->pixel_width = width;
21984 it->ascent = it->phys_ascent = ascent;
21985 it->descent = it->phys_descent = height - it->ascent;
21986 it->nglyphs = width > 0 && height > 0 ? 1 : 0;
21987
21988 take_vertical_position_into_account (it);
21989 }
21990
21991 /* Calculate line-height and line-spacing properties.
21992 An integer value specifies explicit pixel value.
21993 A float value specifies relative value to current face height.
21994 A cons (float . face-name) specifies relative value to
21995 height of specified face font.
21996
21997 Returns height in pixels, or nil. */
21998
21999
22000 static Lisp_Object
22001 calc_line_height_property (struct it *it, Lisp_Object val, struct font *font,
22002 int boff, int override)
22003 {
22004 Lisp_Object face_name = Qnil;
22005 int ascent, descent, height;
22006
22007 if (NILP (val) || INTEGERP (val) || (override && EQ (val, Qt)))
22008 return val;
22009
22010 if (CONSP (val))
22011 {
22012 face_name = XCAR (val);
22013 val = XCDR (val);
22014 if (!NUMBERP (val))
22015 val = make_number (1);
22016 if (NILP (face_name))
22017 {
22018 height = it->ascent + it->descent;
22019 goto scale;
22020 }
22021 }
22022
22023 if (NILP (face_name))
22024 {
22025 font = FRAME_FONT (it->f);
22026 boff = FRAME_BASELINE_OFFSET (it->f);
22027 }
22028 else if (EQ (face_name, Qt))
22029 {
22030 override = 0;
22031 }
22032 else
22033 {
22034 int face_id;
22035 struct face *face;
22036
22037 face_id = lookup_named_face (it->f, face_name, 0);
22038 if (face_id < 0)
22039 return make_number (-1);
22040
22041 face = FACE_FROM_ID (it->f, face_id);
22042 font = face->font;
22043 if (font == NULL)
22044 return make_number (-1);
22045 boff = font->baseline_offset;
22046 if (font->vertical_centering)
22047 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
22048 }
22049
22050 ascent = FONT_BASE (font) + boff;
22051 descent = FONT_DESCENT (font) - boff;
22052
22053 if (override)
22054 {
22055 it->override_ascent = ascent;
22056 it->override_descent = descent;
22057 it->override_boff = boff;
22058 }
22059
22060 height = ascent + descent;
22061
22062 scale:
22063 if (FLOATP (val))
22064 height = (int)(XFLOAT_DATA (val) * height);
22065 else if (INTEGERP (val))
22066 height *= XINT (val);
22067
22068 return make_number (height);
22069 }
22070
22071
22072 /* RIF:
22073 Produce glyphs/get display metrics for the display element IT is
22074 loaded with. See the description of struct it in dispextern.h
22075 for an overview of struct it. */
22076
22077 void
22078 x_produce_glyphs (struct it *it)
22079 {
22080 int extra_line_spacing = it->extra_line_spacing;
22081
22082 it->glyph_not_available_p = 0;
22083
22084 if (it->what == IT_CHARACTER)
22085 {
22086 XChar2b char2b;
22087 struct font *font;
22088 struct face *face = FACE_FROM_ID (it->f, it->face_id);
22089 struct font_metrics *pcm;
22090 int font_not_found_p;
22091 int boff; /* baseline offset */
22092 /* We may change it->multibyte_p upon unibyte<->multibyte
22093 conversion. So, save the current value now and restore it
22094 later.
22095
22096 Note: It seems that we don't have to record multibyte_p in
22097 struct glyph because the character code itself tells whether
22098 or not the character is multibyte. Thus, in the future, we
22099 must consider eliminating the field `multibyte_p' in the
22100 struct glyph. */
22101 int saved_multibyte_p = it->multibyte_p;
22102
22103 /* Maybe translate single-byte characters to multibyte, or the
22104 other way. */
22105 it->char_to_display = it->c;
22106 if (!ASCII_BYTE_P (it->c)
22107 && ! it->multibyte_p)
22108 {
22109 if (SINGLE_BYTE_CHAR_P (it->c)
22110 && unibyte_display_via_language_environment)
22111 {
22112 struct charset *unibyte = CHARSET_FROM_ID (charset_unibyte);
22113
22114 /* get_next_display_element assures that this decoding
22115 never fails. */
22116 it->char_to_display = DECODE_CHAR (unibyte, it->c);
22117 it->multibyte_p = 1;
22118 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display,
22119 -1, Qnil);
22120 face = FACE_FROM_ID (it->f, it->face_id);
22121 }
22122 }
22123
22124 /* Get font to use. Encode IT->char_to_display. */
22125 get_char_face_and_encoding (it->f, it->char_to_display, it->face_id,
22126 &char2b, it->multibyte_p, 0);
22127 font = face->font;
22128
22129 font_not_found_p = font == NULL;
22130 if (font_not_found_p)
22131 {
22132 /* When no suitable font found, display an empty box based
22133 on the metrics of the font of the default face (or what
22134 remapped). */
22135 struct face *no_font_face
22136 = FACE_FROM_ID (it->f,
22137 NILP (Vface_remapping_alist) ? DEFAULT_FACE_ID
22138 : lookup_basic_face (it->f, DEFAULT_FACE_ID));
22139 font = no_font_face->font;
22140 boff = font->baseline_offset;
22141 }
22142 else
22143 {
22144 boff = font->baseline_offset;
22145 if (font->vertical_centering)
22146 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
22147 }
22148
22149 if (it->char_to_display >= ' '
22150 && (!it->multibyte_p || it->char_to_display < 128))
22151 {
22152 /* Either unibyte or ASCII. */
22153 int stretched_p;
22154
22155 it->nglyphs = 1;
22156
22157 pcm = get_per_char_metric (it->f, font, &char2b);
22158
22159 if (it->override_ascent >= 0)
22160 {
22161 it->ascent = it->override_ascent;
22162 it->descent = it->override_descent;
22163 boff = it->override_boff;
22164 }
22165 else
22166 {
22167 it->ascent = FONT_BASE (font) + boff;
22168 it->descent = FONT_DESCENT (font) - boff;
22169 }
22170
22171 if (pcm)
22172 {
22173 it->phys_ascent = pcm->ascent + boff;
22174 it->phys_descent = pcm->descent - boff;
22175 it->pixel_width = pcm->width;
22176 }
22177 else
22178 {
22179 it->glyph_not_available_p = 1;
22180 it->phys_ascent = it->ascent;
22181 it->phys_descent = it->descent;
22182 it->pixel_width = FONT_WIDTH (font);
22183 }
22184
22185 if (it->constrain_row_ascent_descent_p)
22186 {
22187 if (it->descent > it->max_descent)
22188 {
22189 it->ascent += it->descent - it->max_descent;
22190 it->descent = it->max_descent;
22191 }
22192 if (it->ascent > it->max_ascent)
22193 {
22194 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
22195 it->ascent = it->max_ascent;
22196 }
22197 it->phys_ascent = min (it->phys_ascent, it->ascent);
22198 it->phys_descent = min (it->phys_descent, it->descent);
22199 extra_line_spacing = 0;
22200 }
22201
22202 /* If this is a space inside a region of text with
22203 `space-width' property, change its width. */
22204 stretched_p = it->char_to_display == ' ' && !NILP (it->space_width);
22205 if (stretched_p)
22206 it->pixel_width *= XFLOATINT (it->space_width);
22207
22208 /* If face has a box, add the box thickness to the character
22209 height. If character has a box line to the left and/or
22210 right, add the box line width to the character's width. */
22211 if (face->box != FACE_NO_BOX)
22212 {
22213 int thick = face->box_line_width;
22214
22215 if (thick > 0)
22216 {
22217 it->ascent += thick;
22218 it->descent += thick;
22219 }
22220 else
22221 thick = -thick;
22222
22223 if (it->start_of_box_run_p)
22224 it->pixel_width += thick;
22225 if (it->end_of_box_run_p)
22226 it->pixel_width += thick;
22227 }
22228
22229 /* If face has an overline, add the height of the overline
22230 (1 pixel) and a 1 pixel margin to the character height. */
22231 if (face->overline_p)
22232 it->ascent += overline_margin;
22233
22234 if (it->constrain_row_ascent_descent_p)
22235 {
22236 if (it->ascent > it->max_ascent)
22237 it->ascent = it->max_ascent;
22238 if (it->descent > it->max_descent)
22239 it->descent = it->max_descent;
22240 }
22241
22242 take_vertical_position_into_account (it);
22243
22244 /* If we have to actually produce glyphs, do it. */
22245 if (it->glyph_row)
22246 {
22247 if (stretched_p)
22248 {
22249 /* Translate a space with a `space-width' property
22250 into a stretch glyph. */
22251 int ascent = (((it->ascent + it->descent) * FONT_BASE (font))
22252 / FONT_HEIGHT (font));
22253 append_stretch_glyph (it, it->object, it->pixel_width,
22254 it->ascent + it->descent, ascent);
22255 }
22256 else
22257 append_glyph (it);
22258
22259 /* If characters with lbearing or rbearing are displayed
22260 in this line, record that fact in a flag of the
22261 glyph row. This is used to optimize X output code. */
22262 if (pcm && (pcm->lbearing < 0 || pcm->rbearing > pcm->width))
22263 it->glyph_row->contains_overlapping_glyphs_p = 1;
22264 }
22265 if (! stretched_p && it->pixel_width == 0)
22266 /* We assure that all visible glyphs have at least 1-pixel
22267 width. */
22268 it->pixel_width = 1;
22269 }
22270 else if (it->char_to_display == '\n')
22271 {
22272 /* A newline has no width, but we need the height of the
22273 line. But if previous part of the line sets a height,
22274 don't increase that height */
22275
22276 Lisp_Object height;
22277 Lisp_Object total_height = Qnil;
22278
22279 it->override_ascent = -1;
22280 it->pixel_width = 0;
22281 it->nglyphs = 0;
22282
22283 height = get_it_property (it, Qline_height);
22284 /* Split (line-height total-height) list */
22285 if (CONSP (height)
22286 && CONSP (XCDR (height))
22287 && NILP (XCDR (XCDR (height))))
22288 {
22289 total_height = XCAR (XCDR (height));
22290 height = XCAR (height);
22291 }
22292 height = calc_line_height_property (it, height, font, boff, 1);
22293
22294 if (it->override_ascent >= 0)
22295 {
22296 it->ascent = it->override_ascent;
22297 it->descent = it->override_descent;
22298 boff = it->override_boff;
22299 }
22300 else
22301 {
22302 it->ascent = FONT_BASE (font) + boff;
22303 it->descent = FONT_DESCENT (font) - boff;
22304 }
22305
22306 if (EQ (height, Qt))
22307 {
22308 if (it->descent > it->max_descent)
22309 {
22310 it->ascent += it->descent - it->max_descent;
22311 it->descent = it->max_descent;
22312 }
22313 if (it->ascent > it->max_ascent)
22314 {
22315 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
22316 it->ascent = it->max_ascent;
22317 }
22318 it->phys_ascent = min (it->phys_ascent, it->ascent);
22319 it->phys_descent = min (it->phys_descent, it->descent);
22320 it->constrain_row_ascent_descent_p = 1;
22321 extra_line_spacing = 0;
22322 }
22323 else
22324 {
22325 Lisp_Object spacing;
22326
22327 it->phys_ascent = it->ascent;
22328 it->phys_descent = it->descent;
22329
22330 if ((it->max_ascent > 0 || it->max_descent > 0)
22331 && face->box != FACE_NO_BOX
22332 && face->box_line_width > 0)
22333 {
22334 it->ascent += face->box_line_width;
22335 it->descent += face->box_line_width;
22336 }
22337 if (!NILP (height)
22338 && XINT (height) > it->ascent + it->descent)
22339 it->ascent = XINT (height) - it->descent;
22340
22341 if (!NILP (total_height))
22342 spacing = calc_line_height_property (it, total_height, font, boff, 0);
22343 else
22344 {
22345 spacing = get_it_property (it, Qline_spacing);
22346 spacing = calc_line_height_property (it, spacing, font, boff, 0);
22347 }
22348 if (INTEGERP (spacing))
22349 {
22350 extra_line_spacing = XINT (spacing);
22351 if (!NILP (total_height))
22352 extra_line_spacing -= (it->phys_ascent + it->phys_descent);
22353 }
22354 }
22355 }
22356 else if (it->char_to_display == '\t')
22357 {
22358 if (font->space_width > 0)
22359 {
22360 int tab_width = it->tab_width * font->space_width;
22361 int x = it->current_x + it->continuation_lines_width;
22362 int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width;
22363
22364 /* If the distance from the current position to the next tab
22365 stop is less than a space character width, use the
22366 tab stop after that. */
22367 if (next_tab_x - x < font->space_width)
22368 next_tab_x += tab_width;
22369
22370 it->pixel_width = next_tab_x - x;
22371 it->nglyphs = 1;
22372 it->ascent = it->phys_ascent = FONT_BASE (font) + boff;
22373 it->descent = it->phys_descent = FONT_DESCENT (font) - boff;
22374
22375 if (it->glyph_row)
22376 {
22377 append_stretch_glyph (it, it->object, it->pixel_width,
22378 it->ascent + it->descent, it->ascent);
22379 }
22380 }
22381 else
22382 {
22383 it->pixel_width = 0;
22384 it->nglyphs = 1;
22385 }
22386 }
22387 else
22388 {
22389 /* A multi-byte character. Assume that the display width of the
22390 character is the width of the character multiplied by the
22391 width of the font. */
22392
22393 /* If we found a font, this font should give us the right
22394 metrics. If we didn't find a font, use the frame's
22395 default font and calculate the width of the character by
22396 multiplying the width of font by the width of the
22397 character. */
22398
22399 pcm = get_per_char_metric (it->f, font, &char2b);
22400
22401 if (font_not_found_p || !pcm)
22402 {
22403 int char_width = CHAR_WIDTH (it->char_to_display);
22404
22405 if (char_width == 0)
22406 /* This is a non spacing character. But, as we are
22407 going to display an empty box, the box must occupy
22408 at least one column. */
22409 char_width = 1;
22410 it->glyph_not_available_p = 1;
22411 it->pixel_width = font->space_width * char_width;
22412 it->phys_ascent = FONT_BASE (font) + boff;
22413 it->phys_descent = FONT_DESCENT (font) - boff;
22414 }
22415 else
22416 {
22417 it->pixel_width = pcm->width;
22418 it->phys_ascent = pcm->ascent + boff;
22419 it->phys_descent = pcm->descent - boff;
22420 if (it->glyph_row
22421 && (pcm->lbearing < 0
22422 || pcm->rbearing > pcm->width))
22423 it->glyph_row->contains_overlapping_glyphs_p = 1;
22424 }
22425 it->nglyphs = 1;
22426 it->ascent = FONT_BASE (font) + boff;
22427 it->descent = FONT_DESCENT (font) - boff;
22428 if (face->box != FACE_NO_BOX)
22429 {
22430 int thick = face->box_line_width;
22431
22432 if (thick > 0)
22433 {
22434 it->ascent += thick;
22435 it->descent += thick;
22436 }
22437 else
22438 thick = - thick;
22439
22440 if (it->start_of_box_run_p)
22441 it->pixel_width += thick;
22442 if (it->end_of_box_run_p)
22443 it->pixel_width += thick;
22444 }
22445
22446 /* If face has an overline, add the height of the overline
22447 (1 pixel) and a 1 pixel margin to the character height. */
22448 if (face->overline_p)
22449 it->ascent += overline_margin;
22450
22451 take_vertical_position_into_account (it);
22452
22453 if (it->ascent < 0)
22454 it->ascent = 0;
22455 if (it->descent < 0)
22456 it->descent = 0;
22457
22458 if (it->glyph_row)
22459 append_glyph (it);
22460 if (it->pixel_width == 0)
22461 /* We assure that all visible glyphs have at least 1-pixel
22462 width. */
22463 it->pixel_width = 1;
22464 }
22465 it->multibyte_p = saved_multibyte_p;
22466 }
22467 else if (it->what == IT_COMPOSITION && it->cmp_it.ch < 0)
22468 {
22469 /* A static composition.
22470
22471 Note: A composition is represented as one glyph in the
22472 glyph matrix. There are no padding glyphs.
22473
22474 Important note: pixel_width, ascent, and descent are the
22475 values of what is drawn by draw_glyphs (i.e. the values of
22476 the overall glyphs composed). */
22477 struct face *face = FACE_FROM_ID (it->f, it->face_id);
22478 int boff; /* baseline offset */
22479 struct composition *cmp = composition_table[it->cmp_it.id];
22480 int glyph_len = cmp->glyph_len;
22481 struct font *font = face->font;
22482
22483 it->nglyphs = 1;
22484
22485 /* If we have not yet calculated pixel size data of glyphs of
22486 the composition for the current face font, calculate them
22487 now. Theoretically, we have to check all fonts for the
22488 glyphs, but that requires much time and memory space. So,
22489 here we check only the font of the first glyph. This may
22490 lead to incorrect display, but it's very rare, and C-l
22491 (recenter-top-bottom) can correct the display anyway. */
22492 if (! cmp->font || cmp->font != font)
22493 {
22494 /* Ascent and descent of the font of the first character
22495 of this composition (adjusted by baseline offset).
22496 Ascent and descent of overall glyphs should not be less
22497 than these, respectively. */
22498 int font_ascent, font_descent, font_height;
22499 /* Bounding box of the overall glyphs. */
22500 int leftmost, rightmost, lowest, highest;
22501 int lbearing, rbearing;
22502 int i, width, ascent, descent;
22503 int left_padded = 0, right_padded = 0;
22504 int c;
22505 XChar2b char2b;
22506 struct font_metrics *pcm;
22507 int font_not_found_p;
22508 int pos;
22509
22510 for (glyph_len = cmp->glyph_len; glyph_len > 0; glyph_len--)
22511 if ((c = COMPOSITION_GLYPH (cmp, glyph_len - 1)) != '\t')
22512 break;
22513 if (glyph_len < cmp->glyph_len)
22514 right_padded = 1;
22515 for (i = 0; i < glyph_len; i++)
22516 {
22517 if ((c = COMPOSITION_GLYPH (cmp, i)) != '\t')
22518 break;
22519 cmp->offsets[i * 2] = cmp->offsets[i * 2 + 1] = 0;
22520 }
22521 if (i > 0)
22522 left_padded = 1;
22523
22524 pos = (STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
22525 : IT_CHARPOS (*it));
22526 /* If no suitable font is found, use the default font. */
22527 font_not_found_p = font == NULL;
22528 if (font_not_found_p)
22529 {
22530 face = face->ascii_face;
22531 font = face->font;
22532 }
22533 boff = font->baseline_offset;
22534 if (font->vertical_centering)
22535 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
22536 font_ascent = FONT_BASE (font) + boff;
22537 font_descent = FONT_DESCENT (font) - boff;
22538 font_height = FONT_HEIGHT (font);
22539
22540 cmp->font = (void *) font;
22541
22542 pcm = NULL;
22543 if (! font_not_found_p)
22544 {
22545 get_char_face_and_encoding (it->f, c, it->face_id,
22546 &char2b, it->multibyte_p, 0);
22547 pcm = get_per_char_metric (it->f, font, &char2b);
22548 }
22549
22550 /* Initialize the bounding box. */
22551 if (pcm)
22552 {
22553 width = pcm->width;
22554 ascent = pcm->ascent;
22555 descent = pcm->descent;
22556 lbearing = pcm->lbearing;
22557 rbearing = pcm->rbearing;
22558 }
22559 else
22560 {
22561 width = FONT_WIDTH (font);
22562 ascent = FONT_BASE (font);
22563 descent = FONT_DESCENT (font);
22564 lbearing = 0;
22565 rbearing = width;
22566 }
22567
22568 rightmost = width;
22569 leftmost = 0;
22570 lowest = - descent + boff;
22571 highest = ascent + boff;
22572
22573 if (! font_not_found_p
22574 && font->default_ascent
22575 && CHAR_TABLE_P (Vuse_default_ascent)
22576 && !NILP (Faref (Vuse_default_ascent,
22577 make_number (it->char_to_display))))
22578 highest = font->default_ascent + boff;
22579
22580 /* Draw the first glyph at the normal position. It may be
22581 shifted to right later if some other glyphs are drawn
22582 at the left. */
22583 cmp->offsets[i * 2] = 0;
22584 cmp->offsets[i * 2 + 1] = boff;
22585 cmp->lbearing = lbearing;
22586 cmp->rbearing = rbearing;
22587
22588 /* Set cmp->offsets for the remaining glyphs. */
22589 for (i++; i < glyph_len; i++)
22590 {
22591 int left, right, btm, top;
22592 int ch = COMPOSITION_GLYPH (cmp, i);
22593 int face_id;
22594 struct face *this_face;
22595 int this_boff;
22596
22597 if (ch == '\t')
22598 ch = ' ';
22599 face_id = FACE_FOR_CHAR (it->f, face, ch, pos, it->string);
22600 this_face = FACE_FROM_ID (it->f, face_id);
22601 font = this_face->font;
22602
22603 if (font == NULL)
22604 pcm = NULL;
22605 else
22606 {
22607 this_boff = font->baseline_offset;
22608 if (font->vertical_centering)
22609 this_boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
22610 get_char_face_and_encoding (it->f, ch, face_id,
22611 &char2b, it->multibyte_p, 0);
22612 pcm = get_per_char_metric (it->f, font, &char2b);
22613 }
22614 if (! pcm)
22615 cmp->offsets[i * 2] = cmp->offsets[i * 2 + 1] = 0;
22616 else
22617 {
22618 width = pcm->width;
22619 ascent = pcm->ascent;
22620 descent = pcm->descent;
22621 lbearing = pcm->lbearing;
22622 rbearing = pcm->rbearing;
22623 if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS)
22624 {
22625 /* Relative composition with or without
22626 alternate chars. */
22627 left = (leftmost + rightmost - width) / 2;
22628 btm = - descent + boff;
22629 if (font->relative_compose
22630 && (! CHAR_TABLE_P (Vignore_relative_composition)
22631 || NILP (Faref (Vignore_relative_composition,
22632 make_number (ch)))))
22633 {
22634
22635 if (- descent >= font->relative_compose)
22636 /* One extra pixel between two glyphs. */
22637 btm = highest + 1;
22638 else if (ascent <= 0)
22639 /* One extra pixel between two glyphs. */
22640 btm = lowest - 1 - ascent - descent;
22641 }
22642 }
22643 else
22644 {
22645 /* A composition rule is specified by an integer
22646 value that encodes global and new reference
22647 points (GREF and NREF). GREF and NREF are
22648 specified by numbers as below:
22649
22650 0---1---2 -- ascent
22651 | |
22652 | |
22653 | |
22654 9--10--11 -- center
22655 | |
22656 ---3---4---5--- baseline
22657 | |
22658 6---7---8 -- descent
22659 */
22660 int rule = COMPOSITION_RULE (cmp, i);
22661 int gref, nref, grefx, grefy, nrefx, nrefy, xoff, yoff;
22662
22663 COMPOSITION_DECODE_RULE (rule, gref, nref, xoff, yoff);
22664 grefx = gref % 3, nrefx = nref % 3;
22665 grefy = gref / 3, nrefy = nref / 3;
22666 if (xoff)
22667 xoff = font_height * (xoff - 128) / 256;
22668 if (yoff)
22669 yoff = font_height * (yoff - 128) / 256;
22670
22671 left = (leftmost
22672 + grefx * (rightmost - leftmost) / 2
22673 - nrefx * width / 2
22674 + xoff);
22675
22676 btm = ((grefy == 0 ? highest
22677 : grefy == 1 ? 0
22678 : grefy == 2 ? lowest
22679 : (highest + lowest) / 2)
22680 - (nrefy == 0 ? ascent + descent
22681 : nrefy == 1 ? descent - boff
22682 : nrefy == 2 ? 0
22683 : (ascent + descent) / 2)
22684 + yoff);
22685 }
22686
22687 cmp->offsets[i * 2] = left;
22688 cmp->offsets[i * 2 + 1] = btm + descent;
22689
22690 /* Update the bounding box of the overall glyphs. */
22691 if (width > 0)
22692 {
22693 right = left + width;
22694 if (left < leftmost)
22695 leftmost = left;
22696 if (right > rightmost)
22697 rightmost = right;
22698 }
22699 top = btm + descent + ascent;
22700 if (top > highest)
22701 highest = top;
22702 if (btm < lowest)
22703 lowest = btm;
22704
22705 if (cmp->lbearing > left + lbearing)
22706 cmp->lbearing = left + lbearing;
22707 if (cmp->rbearing < left + rbearing)
22708 cmp->rbearing = left + rbearing;
22709 }
22710 }
22711
22712 /* If there are glyphs whose x-offsets are negative,
22713 shift all glyphs to the right and make all x-offsets
22714 non-negative. */
22715 if (leftmost < 0)
22716 {
22717 for (i = 0; i < cmp->glyph_len; i++)
22718 cmp->offsets[i * 2] -= leftmost;
22719 rightmost -= leftmost;
22720 cmp->lbearing -= leftmost;
22721 cmp->rbearing -= leftmost;
22722 }
22723
22724 if (left_padded && cmp->lbearing < 0)
22725 {
22726 for (i = 0; i < cmp->glyph_len; i++)
22727 cmp->offsets[i * 2] -= cmp->lbearing;
22728 rightmost -= cmp->lbearing;
22729 cmp->rbearing -= cmp->lbearing;
22730 cmp->lbearing = 0;
22731 }
22732 if (right_padded && rightmost < cmp->rbearing)
22733 {
22734 rightmost = cmp->rbearing;
22735 }
22736
22737 cmp->pixel_width = rightmost;
22738 cmp->ascent = highest;
22739 cmp->descent = - lowest;
22740 if (cmp->ascent < font_ascent)
22741 cmp->ascent = font_ascent;
22742 if (cmp->descent < font_descent)
22743 cmp->descent = font_descent;
22744 }
22745
22746 if (it->glyph_row
22747 && (cmp->lbearing < 0
22748 || cmp->rbearing > cmp->pixel_width))
22749 it->glyph_row->contains_overlapping_glyphs_p = 1;
22750
22751 it->pixel_width = cmp->pixel_width;
22752 it->ascent = it->phys_ascent = cmp->ascent;
22753 it->descent = it->phys_descent = cmp->descent;
22754 if (face->box != FACE_NO_BOX)
22755 {
22756 int thick = face->box_line_width;
22757
22758 if (thick > 0)
22759 {
22760 it->ascent += thick;
22761 it->descent += thick;
22762 }
22763 else
22764 thick = - thick;
22765
22766 if (it->start_of_box_run_p)
22767 it->pixel_width += thick;
22768 if (it->end_of_box_run_p)
22769 it->pixel_width += thick;
22770 }
22771
22772 /* If face has an overline, add the height of the overline
22773 (1 pixel) and a 1 pixel margin to the character height. */
22774 if (face->overline_p)
22775 it->ascent += overline_margin;
22776
22777 take_vertical_position_into_account (it);
22778 if (it->ascent < 0)
22779 it->ascent = 0;
22780 if (it->descent < 0)
22781 it->descent = 0;
22782
22783 if (it->glyph_row)
22784 append_composite_glyph (it);
22785 }
22786 else if (it->what == IT_COMPOSITION)
22787 {
22788 /* A dynamic (automatic) composition. */
22789 struct face *face = FACE_FROM_ID (it->f, it->face_id);
22790 Lisp_Object gstring;
22791 struct font_metrics metrics;
22792
22793 gstring = composition_gstring_from_id (it->cmp_it.id);
22794 it->pixel_width
22795 = composition_gstring_width (gstring, it->cmp_it.from, it->cmp_it.to,
22796 &metrics);
22797 if (it->glyph_row
22798 && (metrics.lbearing < 0 || metrics.rbearing > metrics.width))
22799 it->glyph_row->contains_overlapping_glyphs_p = 1;
22800 it->ascent = it->phys_ascent = metrics.ascent;
22801 it->descent = it->phys_descent = metrics.descent;
22802 if (face->box != FACE_NO_BOX)
22803 {
22804 int thick = face->box_line_width;
22805
22806 if (thick > 0)
22807 {
22808 it->ascent += thick;
22809 it->descent += thick;
22810 }
22811 else
22812 thick = - thick;
22813
22814 if (it->start_of_box_run_p)
22815 it->pixel_width += thick;
22816 if (it->end_of_box_run_p)
22817 it->pixel_width += thick;
22818 }
22819 /* If face has an overline, add the height of the overline
22820 (1 pixel) and a 1 pixel margin to the character height. */
22821 if (face->overline_p)
22822 it->ascent += overline_margin;
22823 take_vertical_position_into_account (it);
22824 if (it->ascent < 0)
22825 it->ascent = 0;
22826 if (it->descent < 0)
22827 it->descent = 0;
22828
22829 if (it->glyph_row)
22830 append_composite_glyph (it);
22831 }
22832 else if (it->what == IT_IMAGE)
22833 produce_image_glyph (it);
22834 else if (it->what == IT_STRETCH)
22835 produce_stretch_glyph (it);
22836
22837 /* Accumulate dimensions. Note: can't assume that it->descent > 0
22838 because this isn't true for images with `:ascent 100'. */
22839 xassert (it->ascent >= 0 && it->descent >= 0);
22840 if (it->area == TEXT_AREA)
22841 it->current_x += it->pixel_width;
22842
22843 if (extra_line_spacing > 0)
22844 {
22845 it->descent += extra_line_spacing;
22846 if (extra_line_spacing > it->max_extra_line_spacing)
22847 it->max_extra_line_spacing = extra_line_spacing;
22848 }
22849
22850 it->max_ascent = max (it->max_ascent, it->ascent);
22851 it->max_descent = max (it->max_descent, it->descent);
22852 it->max_phys_ascent = max (it->max_phys_ascent, it->phys_ascent);
22853 it->max_phys_descent = max (it->max_phys_descent, it->phys_descent);
22854 }
22855
22856 /* EXPORT for RIF:
22857 Output LEN glyphs starting at START at the nominal cursor position.
22858 Advance the nominal cursor over the text. The global variable
22859 updated_window contains the window being updated, updated_row is
22860 the glyph row being updated, and updated_area is the area of that
22861 row being updated. */
22862
22863 void
22864 x_write_glyphs (struct glyph *start, int len)
22865 {
22866 int x, hpos;
22867
22868 xassert (updated_window && updated_row);
22869 BLOCK_INPUT;
22870
22871 /* Write glyphs. */
22872
22873 hpos = start - updated_row->glyphs[updated_area];
22874 x = draw_glyphs (updated_window, output_cursor.x,
22875 updated_row, updated_area,
22876 hpos, hpos + len,
22877 DRAW_NORMAL_TEXT, 0);
22878
22879 /* Invalidate old phys cursor if the glyph at its hpos is redrawn. */
22880 if (updated_area == TEXT_AREA
22881 && updated_window->phys_cursor_on_p
22882 && updated_window->phys_cursor.vpos == output_cursor.vpos
22883 && updated_window->phys_cursor.hpos >= hpos
22884 && updated_window->phys_cursor.hpos < hpos + len)
22885 updated_window->phys_cursor_on_p = 0;
22886
22887 UNBLOCK_INPUT;
22888
22889 /* Advance the output cursor. */
22890 output_cursor.hpos += len;
22891 output_cursor.x = x;
22892 }
22893
22894
22895 /* EXPORT for RIF:
22896 Insert LEN glyphs from START at the nominal cursor position. */
22897
22898 void
22899 x_insert_glyphs (struct glyph *start, int len)
22900 {
22901 struct frame *f;
22902 struct window *w;
22903 int line_height, shift_by_width, shifted_region_width;
22904 struct glyph_row *row;
22905 struct glyph *glyph;
22906 int frame_x, frame_y;
22907 EMACS_INT hpos;
22908
22909 xassert (updated_window && updated_row);
22910 BLOCK_INPUT;
22911 w = updated_window;
22912 f = XFRAME (WINDOW_FRAME (w));
22913
22914 /* Get the height of the line we are in. */
22915 row = updated_row;
22916 line_height = row->height;
22917
22918 /* Get the width of the glyphs to insert. */
22919 shift_by_width = 0;
22920 for (glyph = start; glyph < start + len; ++glyph)
22921 shift_by_width += glyph->pixel_width;
22922
22923 /* Get the width of the region to shift right. */
22924 shifted_region_width = (window_box_width (w, updated_area)
22925 - output_cursor.x
22926 - shift_by_width);
22927
22928 /* Shift right. */
22929 frame_x = window_box_left (w, updated_area) + output_cursor.x;
22930 frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, output_cursor.y);
22931
22932 FRAME_RIF (f)->shift_glyphs_for_insert (f, frame_x, frame_y, shifted_region_width,
22933 line_height, shift_by_width);
22934
22935 /* Write the glyphs. */
22936 hpos = start - row->glyphs[updated_area];
22937 draw_glyphs (w, output_cursor.x, row, updated_area,
22938 hpos, hpos + len,
22939 DRAW_NORMAL_TEXT, 0);
22940
22941 /* Advance the output cursor. */
22942 output_cursor.hpos += len;
22943 output_cursor.x += shift_by_width;
22944 UNBLOCK_INPUT;
22945 }
22946
22947
22948 /* EXPORT for RIF:
22949 Erase the current text line from the nominal cursor position
22950 (inclusive) to pixel column TO_X (exclusive). The idea is that
22951 everything from TO_X onward is already erased.
22952
22953 TO_X is a pixel position relative to updated_area of
22954 updated_window. TO_X == -1 means clear to the end of this area. */
22955
22956 void
22957 x_clear_end_of_line (int to_x)
22958 {
22959 struct frame *f;
22960 struct window *w = updated_window;
22961 int max_x, min_y, max_y;
22962 int from_x, from_y, to_y;
22963
22964 xassert (updated_window && updated_row);
22965 f = XFRAME (w->frame);
22966
22967 if (updated_row->full_width_p)
22968 max_x = WINDOW_TOTAL_WIDTH (w);
22969 else
22970 max_x = window_box_width (w, updated_area);
22971 max_y = window_text_bottom_y (w);
22972
22973 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
22974 of window. For TO_X > 0, truncate to end of drawing area. */
22975 if (to_x == 0)
22976 return;
22977 else if (to_x < 0)
22978 to_x = max_x;
22979 else
22980 to_x = min (to_x, max_x);
22981
22982 to_y = min (max_y, output_cursor.y + updated_row->height);
22983
22984 /* Notice if the cursor will be cleared by this operation. */
22985 if (!updated_row->full_width_p)
22986 notice_overwritten_cursor (w, updated_area,
22987 output_cursor.x, -1,
22988 updated_row->y,
22989 MATRIX_ROW_BOTTOM_Y (updated_row));
22990
22991 from_x = output_cursor.x;
22992
22993 /* Translate to frame coordinates. */
22994 if (updated_row->full_width_p)
22995 {
22996 from_x = WINDOW_TO_FRAME_PIXEL_X (w, from_x);
22997 to_x = WINDOW_TO_FRAME_PIXEL_X (w, to_x);
22998 }
22999 else
23000 {
23001 int area_left = window_box_left (w, updated_area);
23002 from_x += area_left;
23003 to_x += area_left;
23004 }
23005
23006 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
23007 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, max (min_y, output_cursor.y));
23008 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, to_y);
23009
23010 /* Prevent inadvertently clearing to end of the X window. */
23011 if (to_x > from_x && to_y > from_y)
23012 {
23013 BLOCK_INPUT;
23014 FRAME_RIF (f)->clear_frame_area (f, from_x, from_y,
23015 to_x - from_x, to_y - from_y);
23016 UNBLOCK_INPUT;
23017 }
23018 }
23019
23020 #endif /* HAVE_WINDOW_SYSTEM */
23021
23022
23023 \f
23024 /***********************************************************************
23025 Cursor types
23026 ***********************************************************************/
23027
23028 /* Value is the internal representation of the specified cursor type
23029 ARG. If type is BAR_CURSOR, return in *WIDTH the specified width
23030 of the bar cursor. */
23031
23032 static enum text_cursor_kinds
23033 get_specified_cursor_type (Lisp_Object arg, int *width)
23034 {
23035 enum text_cursor_kinds type;
23036
23037 if (NILP (arg))
23038 return NO_CURSOR;
23039
23040 if (EQ (arg, Qbox))
23041 return FILLED_BOX_CURSOR;
23042
23043 if (EQ (arg, Qhollow))
23044 return HOLLOW_BOX_CURSOR;
23045
23046 if (EQ (arg, Qbar))
23047 {
23048 *width = 2;
23049 return BAR_CURSOR;
23050 }
23051
23052 if (CONSP (arg)
23053 && EQ (XCAR (arg), Qbar)
23054 && INTEGERP (XCDR (arg))
23055 && XINT (XCDR (arg)) >= 0)
23056 {
23057 *width = XINT (XCDR (arg));
23058 return BAR_CURSOR;
23059 }
23060
23061 if (EQ (arg, Qhbar))
23062 {
23063 *width = 2;
23064 return HBAR_CURSOR;
23065 }
23066
23067 if (CONSP (arg)
23068 && EQ (XCAR (arg), Qhbar)
23069 && INTEGERP (XCDR (arg))
23070 && XINT (XCDR (arg)) >= 0)
23071 {
23072 *width = XINT (XCDR (arg));
23073 return HBAR_CURSOR;
23074 }
23075
23076 /* Treat anything unknown as "hollow box cursor".
23077 It was bad to signal an error; people have trouble fixing
23078 .Xdefaults with Emacs, when it has something bad in it. */
23079 type = HOLLOW_BOX_CURSOR;
23080
23081 return type;
23082 }
23083
23084 /* Set the default cursor types for specified frame. */
23085 void
23086 set_frame_cursor_types (struct frame *f, Lisp_Object arg)
23087 {
23088 int width;
23089 Lisp_Object tem;
23090
23091 FRAME_DESIRED_CURSOR (f) = get_specified_cursor_type (arg, &width);
23092 FRAME_CURSOR_WIDTH (f) = width;
23093
23094 /* By default, set up the blink-off state depending on the on-state. */
23095
23096 tem = Fassoc (arg, Vblink_cursor_alist);
23097 if (!NILP (tem))
23098 {
23099 FRAME_BLINK_OFF_CURSOR (f)
23100 = get_specified_cursor_type (XCDR (tem), &width);
23101 FRAME_BLINK_OFF_CURSOR_WIDTH (f) = width;
23102 }
23103 else
23104 FRAME_BLINK_OFF_CURSOR (f) = DEFAULT_CURSOR;
23105 }
23106
23107
23108 /* Return the cursor we want to be displayed in window W. Return
23109 width of bar/hbar cursor through WIDTH arg. Return with
23110 ACTIVE_CURSOR arg set to 1 if cursor in window W is `active'
23111 (i.e. if the `system caret' should track this cursor).
23112
23113 In a mini-buffer window, we want the cursor only to appear if we
23114 are reading input from this window. For the selected window, we
23115 want the cursor type given by the frame parameter or buffer local
23116 setting of cursor-type. If explicitly marked off, draw no cursor.
23117 In all other cases, we want a hollow box cursor. */
23118
23119 static enum text_cursor_kinds
23120 get_window_cursor_type (struct window *w, struct glyph *glyph, int *width,
23121 int *active_cursor)
23122 {
23123 struct frame *f = XFRAME (w->frame);
23124 struct buffer *b = XBUFFER (w->buffer);
23125 int cursor_type = DEFAULT_CURSOR;
23126 Lisp_Object alt_cursor;
23127 int non_selected = 0;
23128
23129 *active_cursor = 1;
23130
23131 /* Echo area */
23132 if (cursor_in_echo_area
23133 && FRAME_HAS_MINIBUF_P (f)
23134 && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
23135 {
23136 if (w == XWINDOW (echo_area_window))
23137 {
23138 if (EQ (b->cursor_type, Qt) || NILP (b->cursor_type))
23139 {
23140 *width = FRAME_CURSOR_WIDTH (f);
23141 return FRAME_DESIRED_CURSOR (f);
23142 }
23143 else
23144 return get_specified_cursor_type (b->cursor_type, width);
23145 }
23146
23147 *active_cursor = 0;
23148 non_selected = 1;
23149 }
23150
23151 /* Detect a nonselected window or nonselected frame. */
23152 else if (w != XWINDOW (f->selected_window)
23153 #ifdef HAVE_WINDOW_SYSTEM
23154 || f != FRAME_X_DISPLAY_INFO (f)->x_highlight_frame
23155 #endif
23156 )
23157 {
23158 *active_cursor = 0;
23159
23160 if (MINI_WINDOW_P (w) && minibuf_level == 0)
23161 return NO_CURSOR;
23162
23163 non_selected = 1;
23164 }
23165
23166 /* Never display a cursor in a window in which cursor-type is nil. */
23167 if (NILP (b->cursor_type))
23168 return NO_CURSOR;
23169
23170 /* Get the normal cursor type for this window. */
23171 if (EQ (b->cursor_type, Qt))
23172 {
23173 cursor_type = FRAME_DESIRED_CURSOR (f);
23174 *width = FRAME_CURSOR_WIDTH (f);
23175 }
23176 else
23177 cursor_type = get_specified_cursor_type (b->cursor_type, width);
23178
23179 /* Use cursor-in-non-selected-windows instead
23180 for non-selected window or frame. */
23181 if (non_selected)
23182 {
23183 alt_cursor = b->cursor_in_non_selected_windows;
23184 if (!EQ (Qt, alt_cursor))
23185 return get_specified_cursor_type (alt_cursor, width);
23186 /* t means modify the normal cursor type. */
23187 if (cursor_type == FILLED_BOX_CURSOR)
23188 cursor_type = HOLLOW_BOX_CURSOR;
23189 else if (cursor_type == BAR_CURSOR && *width > 1)
23190 --*width;
23191 return cursor_type;
23192 }
23193
23194 /* Use normal cursor if not blinked off. */
23195 if (!w->cursor_off_p)
23196 {
23197 #ifdef HAVE_WINDOW_SYSTEM
23198 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
23199 {
23200 if (cursor_type == FILLED_BOX_CURSOR)
23201 {
23202 /* Using a block cursor on large images can be very annoying.
23203 So use a hollow cursor for "large" images.
23204 If image is not transparent (no mask), also use hollow cursor. */
23205 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
23206 if (img != NULL && IMAGEP (img->spec))
23207 {
23208 /* Arbitrarily, interpret "Large" as >32x32 and >NxN
23209 where N = size of default frame font size.
23210 This should cover most of the "tiny" icons people may use. */
23211 if (!img->mask
23212 || img->width > max (32, WINDOW_FRAME_COLUMN_WIDTH (w))
23213 || img->height > max (32, WINDOW_FRAME_LINE_HEIGHT (w)))
23214 cursor_type = HOLLOW_BOX_CURSOR;
23215 }
23216 }
23217 else if (cursor_type != NO_CURSOR)
23218 {
23219 /* Display current only supports BOX and HOLLOW cursors for images.
23220 So for now, unconditionally use a HOLLOW cursor when cursor is
23221 not a solid box cursor. */
23222 cursor_type = HOLLOW_BOX_CURSOR;
23223 }
23224 }
23225 #endif
23226 return cursor_type;
23227 }
23228
23229 /* Cursor is blinked off, so determine how to "toggle" it. */
23230
23231 /* First look for an entry matching the buffer's cursor-type in blink-cursor-alist. */
23232 if ((alt_cursor = Fassoc (b->cursor_type, Vblink_cursor_alist), !NILP (alt_cursor)))
23233 return get_specified_cursor_type (XCDR (alt_cursor), width);
23234
23235 /* Then see if frame has specified a specific blink off cursor type. */
23236 if (FRAME_BLINK_OFF_CURSOR (f) != DEFAULT_CURSOR)
23237 {
23238 *width = FRAME_BLINK_OFF_CURSOR_WIDTH (f);
23239 return FRAME_BLINK_OFF_CURSOR (f);
23240 }
23241
23242 #if 0
23243 /* Some people liked having a permanently visible blinking cursor,
23244 while others had very strong opinions against it. So it was
23245 decided to remove it. KFS 2003-09-03 */
23246
23247 /* Finally perform built-in cursor blinking:
23248 filled box <-> hollow box
23249 wide [h]bar <-> narrow [h]bar
23250 narrow [h]bar <-> no cursor
23251 other type <-> no cursor */
23252
23253 if (cursor_type == FILLED_BOX_CURSOR)
23254 return HOLLOW_BOX_CURSOR;
23255
23256 if ((cursor_type == BAR_CURSOR || cursor_type == HBAR_CURSOR) && *width > 1)
23257 {
23258 *width = 1;
23259 return cursor_type;
23260 }
23261 #endif
23262
23263 return NO_CURSOR;
23264 }
23265
23266
23267 #ifdef HAVE_WINDOW_SYSTEM
23268
23269 /* Notice when the text cursor of window W has been completely
23270 overwritten by a drawing operation that outputs glyphs in AREA
23271 starting at X0 and ending at X1 in the line starting at Y0 and
23272 ending at Y1. X coordinates are area-relative. X1 < 0 means all
23273 the rest of the line after X0 has been written. Y coordinates
23274 are window-relative. */
23275
23276 static void
23277 notice_overwritten_cursor (struct window *w, enum glyph_row_area area,
23278 int x0, int x1, int y0, int y1)
23279 {
23280 int cx0, cx1, cy0, cy1;
23281 struct glyph_row *row;
23282
23283 if (!w->phys_cursor_on_p)
23284 return;
23285 if (area != TEXT_AREA)
23286 return;
23287
23288 if (w->phys_cursor.vpos < 0
23289 || w->phys_cursor.vpos >= w->current_matrix->nrows
23290 || (row = w->current_matrix->rows + w->phys_cursor.vpos,
23291 !(row->enabled_p && row->displays_text_p)))
23292 return;
23293
23294 if (row->cursor_in_fringe_p)
23295 {
23296 row->cursor_in_fringe_p = 0;
23297 draw_fringe_bitmap (w, row, row->reversed_p);
23298 w->phys_cursor_on_p = 0;
23299 return;
23300 }
23301
23302 cx0 = w->phys_cursor.x;
23303 cx1 = cx0 + w->phys_cursor_width;
23304 if (x0 > cx0 || (x1 >= 0 && x1 < cx1))
23305 return;
23306
23307 /* The cursor image will be completely removed from the
23308 screen if the output area intersects the cursor area in
23309 y-direction. When we draw in [y0 y1[, and some part of
23310 the cursor is at y < y0, that part must have been drawn
23311 before. When scrolling, the cursor is erased before
23312 actually scrolling, so we don't come here. When not
23313 scrolling, the rows above the old cursor row must have
23314 changed, and in this case these rows must have written
23315 over the cursor image.
23316
23317 Likewise if part of the cursor is below y1, with the
23318 exception of the cursor being in the first blank row at
23319 the buffer and window end because update_text_area
23320 doesn't draw that row. (Except when it does, but
23321 that's handled in update_text_area.) */
23322
23323 cy0 = w->phys_cursor.y;
23324 cy1 = cy0 + w->phys_cursor_height;
23325 if ((y0 < cy0 || y0 >= cy1) && (y1 <= cy0 || y1 >= cy1))
23326 return;
23327
23328 w->phys_cursor_on_p = 0;
23329 }
23330
23331 #endif /* HAVE_WINDOW_SYSTEM */
23332
23333 \f
23334 /************************************************************************
23335 Mouse Face
23336 ************************************************************************/
23337
23338 #ifdef HAVE_WINDOW_SYSTEM
23339
23340 /* EXPORT for RIF:
23341 Fix the display of area AREA of overlapping row ROW in window W
23342 with respect to the overlapping part OVERLAPS. */
23343
23344 void
23345 x_fix_overlapping_area (struct window *w, struct glyph_row *row,
23346 enum glyph_row_area area, int overlaps)
23347 {
23348 int i, x;
23349
23350 BLOCK_INPUT;
23351
23352 x = 0;
23353 for (i = 0; i < row->used[area];)
23354 {
23355 if (row->glyphs[area][i].overlaps_vertically_p)
23356 {
23357 int start = i, start_x = x;
23358
23359 do
23360 {
23361 x += row->glyphs[area][i].pixel_width;
23362 ++i;
23363 }
23364 while (i < row->used[area]
23365 && row->glyphs[area][i].overlaps_vertically_p);
23366
23367 draw_glyphs (w, start_x, row, area,
23368 start, i,
23369 DRAW_NORMAL_TEXT, overlaps);
23370 }
23371 else
23372 {
23373 x += row->glyphs[area][i].pixel_width;
23374 ++i;
23375 }
23376 }
23377
23378 UNBLOCK_INPUT;
23379 }
23380
23381
23382 /* EXPORT:
23383 Draw the cursor glyph of window W in glyph row ROW. See the
23384 comment of draw_glyphs for the meaning of HL. */
23385
23386 void
23387 draw_phys_cursor_glyph (struct window *w, struct glyph_row *row,
23388 enum draw_glyphs_face hl)
23389 {
23390 /* If cursor hpos is out of bounds, don't draw garbage. This can
23391 happen in mini-buffer windows when switching between echo area
23392 glyphs and mini-buffer. */
23393 if ((row->reversed_p
23394 ? (w->phys_cursor.hpos >= 0)
23395 : (w->phys_cursor.hpos < row->used[TEXT_AREA])))
23396 {
23397 int on_p = w->phys_cursor_on_p;
23398 int x1;
23399 x1 = draw_glyphs (w, w->phys_cursor.x, row, TEXT_AREA,
23400 w->phys_cursor.hpos, w->phys_cursor.hpos + 1,
23401 hl, 0);
23402 w->phys_cursor_on_p = on_p;
23403
23404 if (hl == DRAW_CURSOR)
23405 w->phys_cursor_width = x1 - w->phys_cursor.x;
23406 /* When we erase the cursor, and ROW is overlapped by other
23407 rows, make sure that these overlapping parts of other rows
23408 are redrawn. */
23409 else if (hl == DRAW_NORMAL_TEXT && row->overlapped_p)
23410 {
23411 w->phys_cursor_width = x1 - w->phys_cursor.x;
23412
23413 if (row > w->current_matrix->rows
23414 && MATRIX_ROW_OVERLAPS_SUCC_P (row - 1))
23415 x_fix_overlapping_area (w, row - 1, TEXT_AREA,
23416 OVERLAPS_ERASED_CURSOR);
23417
23418 if (MATRIX_ROW_BOTTOM_Y (row) < window_text_bottom_y (w)
23419 && MATRIX_ROW_OVERLAPS_PRED_P (row + 1))
23420 x_fix_overlapping_area (w, row + 1, TEXT_AREA,
23421 OVERLAPS_ERASED_CURSOR);
23422 }
23423 }
23424 }
23425
23426
23427 /* EXPORT:
23428 Erase the image of a cursor of window W from the screen. */
23429
23430 void
23431 erase_phys_cursor (struct window *w)
23432 {
23433 struct frame *f = XFRAME (w->frame);
23434 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
23435 int hpos = w->phys_cursor.hpos;
23436 int vpos = w->phys_cursor.vpos;
23437 int mouse_face_here_p = 0;
23438 struct glyph_matrix *active_glyphs = w->current_matrix;
23439 struct glyph_row *cursor_row;
23440 struct glyph *cursor_glyph;
23441 enum draw_glyphs_face hl;
23442
23443 /* No cursor displayed or row invalidated => nothing to do on the
23444 screen. */
23445 if (w->phys_cursor_type == NO_CURSOR)
23446 goto mark_cursor_off;
23447
23448 /* VPOS >= active_glyphs->nrows means that window has been resized.
23449 Don't bother to erase the cursor. */
23450 if (vpos >= active_glyphs->nrows)
23451 goto mark_cursor_off;
23452
23453 /* If row containing cursor is marked invalid, there is nothing we
23454 can do. */
23455 cursor_row = MATRIX_ROW (active_glyphs, vpos);
23456 if (!cursor_row->enabled_p)
23457 goto mark_cursor_off;
23458
23459 /* If line spacing is > 0, old cursor may only be partially visible in
23460 window after split-window. So adjust visible height. */
23461 cursor_row->visible_height = min (cursor_row->visible_height,
23462 window_text_bottom_y (w) - cursor_row->y);
23463
23464 /* If row is completely invisible, don't attempt to delete a cursor which
23465 isn't there. This can happen if cursor is at top of a window, and
23466 we switch to a buffer with a header line in that window. */
23467 if (cursor_row->visible_height <= 0)
23468 goto mark_cursor_off;
23469
23470 /* If cursor is in the fringe, erase by drawing actual bitmap there. */
23471 if (cursor_row->cursor_in_fringe_p)
23472 {
23473 cursor_row->cursor_in_fringe_p = 0;
23474 draw_fringe_bitmap (w, cursor_row, cursor_row->reversed_p);
23475 goto mark_cursor_off;
23476 }
23477
23478 /* This can happen when the new row is shorter than the old one.
23479 In this case, either draw_glyphs or clear_end_of_line
23480 should have cleared the cursor. Note that we wouldn't be
23481 able to erase the cursor in this case because we don't have a
23482 cursor glyph at hand. */
23483 if ((cursor_row->reversed_p
23484 ? (w->phys_cursor.hpos < 0)
23485 : (w->phys_cursor.hpos >= cursor_row->used[TEXT_AREA])))
23486 goto mark_cursor_off;
23487
23488 /* If the cursor is in the mouse face area, redisplay that when
23489 we clear the cursor. */
23490 if (! NILP (dpyinfo->mouse_face_window)
23491 && coords_in_mouse_face_p (w, hpos, vpos)
23492 /* Don't redraw the cursor's spot in mouse face if it is at the
23493 end of a line (on a newline). The cursor appears there, but
23494 mouse highlighting does not. */
23495 && cursor_row->used[TEXT_AREA] > hpos && hpos >= 0)
23496 mouse_face_here_p = 1;
23497
23498 /* Maybe clear the display under the cursor. */
23499 if (w->phys_cursor_type == HOLLOW_BOX_CURSOR)
23500 {
23501 int x, y, left_x;
23502 int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
23503 int width;
23504
23505 cursor_glyph = get_phys_cursor_glyph (w);
23506 if (cursor_glyph == NULL)
23507 goto mark_cursor_off;
23508
23509 width = cursor_glyph->pixel_width;
23510 left_x = window_box_left_offset (w, TEXT_AREA);
23511 x = w->phys_cursor.x;
23512 if (x < left_x)
23513 width -= left_x - x;
23514 width = min (width, window_box_width (w, TEXT_AREA) - x);
23515 y = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, cursor_row->y));
23516 x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, max (x, left_x));
23517
23518 if (width > 0)
23519 FRAME_RIF (f)->clear_frame_area (f, x, y, width, cursor_row->visible_height);
23520 }
23521
23522 /* Erase the cursor by redrawing the character underneath it. */
23523 if (mouse_face_here_p)
23524 hl = DRAW_MOUSE_FACE;
23525 else
23526 hl = DRAW_NORMAL_TEXT;
23527 draw_phys_cursor_glyph (w, cursor_row, hl);
23528
23529 mark_cursor_off:
23530 w->phys_cursor_on_p = 0;
23531 w->phys_cursor_type = NO_CURSOR;
23532 }
23533
23534
23535 /* EXPORT:
23536 Display or clear cursor of window W. If ON is zero, clear the
23537 cursor. If it is non-zero, display the cursor. If ON is nonzero,
23538 where to put the cursor is specified by HPOS, VPOS, X and Y. */
23539
23540 void
23541 display_and_set_cursor (struct window *w, int on,
23542 int hpos, int vpos, int x, int y)
23543 {
23544 struct frame *f = XFRAME (w->frame);
23545 int new_cursor_type;
23546 int new_cursor_width;
23547 int active_cursor;
23548 struct glyph_row *glyph_row;
23549 struct glyph *glyph;
23550
23551 /* This is pointless on invisible frames, and dangerous on garbaged
23552 windows and frames; in the latter case, the frame or window may
23553 be in the midst of changing its size, and x and y may be off the
23554 window. */
23555 if (! FRAME_VISIBLE_P (f)
23556 || FRAME_GARBAGED_P (f)
23557 || vpos >= w->current_matrix->nrows
23558 || hpos >= w->current_matrix->matrix_w)
23559 return;
23560
23561 /* If cursor is off and we want it off, return quickly. */
23562 if (!on && !w->phys_cursor_on_p)
23563 return;
23564
23565 glyph_row = MATRIX_ROW (w->current_matrix, vpos);
23566 /* If cursor row is not enabled, we don't really know where to
23567 display the cursor. */
23568 if (!glyph_row->enabled_p)
23569 {
23570 w->phys_cursor_on_p = 0;
23571 return;
23572 }
23573
23574 glyph = NULL;
23575 if (!glyph_row->exact_window_width_line_p
23576 || (0 <= hpos && hpos < glyph_row->used[TEXT_AREA]))
23577 glyph = glyph_row->glyphs[TEXT_AREA] + hpos;
23578
23579 xassert (interrupt_input_blocked);
23580
23581 /* Set new_cursor_type to the cursor we want to be displayed. */
23582 new_cursor_type = get_window_cursor_type (w, glyph,
23583 &new_cursor_width, &active_cursor);
23584
23585 /* If cursor is currently being shown and we don't want it to be or
23586 it is in the wrong place, or the cursor type is not what we want,
23587 erase it. */
23588 if (w->phys_cursor_on_p
23589 && (!on
23590 || w->phys_cursor.x != x
23591 || w->phys_cursor.y != y
23592 || new_cursor_type != w->phys_cursor_type
23593 || ((new_cursor_type == BAR_CURSOR || new_cursor_type == HBAR_CURSOR)
23594 && new_cursor_width != w->phys_cursor_width)))
23595 erase_phys_cursor (w);
23596
23597 /* Don't check phys_cursor_on_p here because that flag is only set
23598 to zero in some cases where we know that the cursor has been
23599 completely erased, to avoid the extra work of erasing the cursor
23600 twice. In other words, phys_cursor_on_p can be 1 and the cursor
23601 still not be visible, or it has only been partly erased. */
23602 if (on)
23603 {
23604 w->phys_cursor_ascent = glyph_row->ascent;
23605 w->phys_cursor_height = glyph_row->height;
23606
23607 /* Set phys_cursor_.* before x_draw_.* is called because some
23608 of them may need the information. */
23609 w->phys_cursor.x = x;
23610 w->phys_cursor.y = glyph_row->y;
23611 w->phys_cursor.hpos = hpos;
23612 w->phys_cursor.vpos = vpos;
23613 }
23614
23615 FRAME_RIF (f)->draw_window_cursor (w, glyph_row, x, y,
23616 new_cursor_type, new_cursor_width,
23617 on, active_cursor);
23618 }
23619
23620
23621 /* Switch the display of W's cursor on or off, according to the value
23622 of ON. */
23623
23624 void
23625 update_window_cursor (struct window *w, int on)
23626 {
23627 /* Don't update cursor in windows whose frame is in the process
23628 of being deleted. */
23629 if (w->current_matrix)
23630 {
23631 BLOCK_INPUT;
23632 display_and_set_cursor (w, on, w->phys_cursor.hpos, w->phys_cursor.vpos,
23633 w->phys_cursor.x, w->phys_cursor.y);
23634 UNBLOCK_INPUT;
23635 }
23636 }
23637
23638
23639 /* Call update_window_cursor with parameter ON_P on all leaf windows
23640 in the window tree rooted at W. */
23641
23642 static void
23643 update_cursor_in_window_tree (struct window *w, int on_p)
23644 {
23645 while (w)
23646 {
23647 if (!NILP (w->hchild))
23648 update_cursor_in_window_tree (XWINDOW (w->hchild), on_p);
23649 else if (!NILP (w->vchild))
23650 update_cursor_in_window_tree (XWINDOW (w->vchild), on_p);
23651 else
23652 update_window_cursor (w, on_p);
23653
23654 w = NILP (w->next) ? 0 : XWINDOW (w->next);
23655 }
23656 }
23657
23658
23659 /* EXPORT:
23660 Display the cursor on window W, or clear it, according to ON_P.
23661 Don't change the cursor's position. */
23662
23663 void
23664 x_update_cursor (struct frame *f, int on_p)
23665 {
23666 update_cursor_in_window_tree (XWINDOW (f->root_window), on_p);
23667 }
23668
23669
23670 /* EXPORT:
23671 Clear the cursor of window W to background color, and mark the
23672 cursor as not shown. This is used when the text where the cursor
23673 is about to be rewritten. */
23674
23675 void
23676 x_clear_cursor (struct window *w)
23677 {
23678 if (FRAME_VISIBLE_P (XFRAME (w->frame)) && w->phys_cursor_on_p)
23679 update_window_cursor (w, 0);
23680 }
23681
23682
23683 /* EXPORT:
23684 Display the active region described by mouse_face_* according to DRAW. */
23685
23686 void
23687 show_mouse_face (Display_Info *dpyinfo, enum draw_glyphs_face draw)
23688 {
23689 struct window *w = XWINDOW (dpyinfo->mouse_face_window);
23690 struct frame *f = XFRAME (WINDOW_FRAME (w));
23691
23692 if (/* If window is in the process of being destroyed, don't bother
23693 to do anything. */
23694 w->current_matrix != NULL
23695 /* Don't update mouse highlight if hidden */
23696 && (draw != DRAW_MOUSE_FACE || !dpyinfo->mouse_face_hidden)
23697 /* Recognize when we are called to operate on rows that don't exist
23698 anymore. This can happen when a window is split. */
23699 && dpyinfo->mouse_face_end_row < w->current_matrix->nrows)
23700 {
23701 int phys_cursor_on_p = w->phys_cursor_on_p;
23702 struct glyph_row *row, *first, *last;
23703
23704 first = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_beg_row);
23705 last = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_end_row);
23706
23707 for (row = first; row <= last && row->enabled_p; ++row)
23708 {
23709 int start_hpos, end_hpos, start_x;
23710
23711 /* For all but the first row, the highlight starts at column 0. */
23712 if (row == first)
23713 {
23714 /* R2L rows have BEG and END in reversed order, but the
23715 screen drawing geometry is always left to right. So
23716 we need to mirror the beginning and end of the
23717 highlighted area in R2L rows. */
23718 if (!row->reversed_p)
23719 {
23720 start_hpos = dpyinfo->mouse_face_beg_col;
23721 start_x = dpyinfo->mouse_face_beg_x;
23722 }
23723 else if (row == last)
23724 {
23725 start_hpos = dpyinfo->mouse_face_end_col;
23726 start_x = dpyinfo->mouse_face_end_x;
23727 }
23728 else
23729 {
23730 start_hpos = 0;
23731 start_x = 0;
23732 }
23733 }
23734 else if (row->reversed_p && row == last)
23735 {
23736 start_hpos = dpyinfo->mouse_face_end_col;
23737 start_x = dpyinfo->mouse_face_end_x;
23738 }
23739 else
23740 {
23741 start_hpos = 0;
23742 start_x = 0;
23743 }
23744
23745 if (row == last)
23746 {
23747 if (!row->reversed_p)
23748 end_hpos = dpyinfo->mouse_face_end_col;
23749 else if (row == first)
23750 end_hpos = dpyinfo->mouse_face_beg_col;
23751 else
23752 {
23753 end_hpos = row->used[TEXT_AREA];
23754 if (draw == DRAW_NORMAL_TEXT)
23755 row->fill_line_p = 1; /* Clear to end of line */
23756 }
23757 }
23758 else if (row->reversed_p && row == first)
23759 end_hpos = dpyinfo->mouse_face_beg_col;
23760 else
23761 {
23762 end_hpos = row->used[TEXT_AREA];
23763 if (draw == DRAW_NORMAL_TEXT)
23764 row->fill_line_p = 1; /* Clear to end of line */
23765 }
23766
23767 if (end_hpos > start_hpos)
23768 {
23769 draw_glyphs (w, start_x, row, TEXT_AREA,
23770 start_hpos, end_hpos,
23771 draw, 0);
23772
23773 row->mouse_face_p
23774 = draw == DRAW_MOUSE_FACE || draw == DRAW_IMAGE_RAISED;
23775 }
23776 }
23777
23778 /* When we've written over the cursor, arrange for it to
23779 be displayed again. */
23780 if (phys_cursor_on_p && !w->phys_cursor_on_p)
23781 {
23782 BLOCK_INPUT;
23783 display_and_set_cursor (w, 1,
23784 w->phys_cursor.hpos, w->phys_cursor.vpos,
23785 w->phys_cursor.x, w->phys_cursor.y);
23786 UNBLOCK_INPUT;
23787 }
23788 }
23789
23790 /* Change the mouse cursor. */
23791 if (draw == DRAW_NORMAL_TEXT && !EQ (dpyinfo->mouse_face_window, f->tool_bar_window))
23792 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->text_cursor);
23793 else if (draw == DRAW_MOUSE_FACE)
23794 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->hand_cursor);
23795 else
23796 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->nontext_cursor);
23797 }
23798
23799 /* EXPORT:
23800 Clear out the mouse-highlighted active region.
23801 Redraw it un-highlighted first. Value is non-zero if mouse
23802 face was actually drawn unhighlighted. */
23803
23804 int
23805 clear_mouse_face (Display_Info *dpyinfo)
23806 {
23807 int cleared = 0;
23808
23809 if (!dpyinfo->mouse_face_hidden && !NILP (dpyinfo->mouse_face_window))
23810 {
23811 show_mouse_face (dpyinfo, DRAW_NORMAL_TEXT);
23812 cleared = 1;
23813 }
23814
23815 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
23816 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
23817 dpyinfo->mouse_face_window = Qnil;
23818 dpyinfo->mouse_face_overlay = Qnil;
23819 return cleared;
23820 }
23821
23822 /* Return non-zero if the coordinates HPOS and VPOS on windows W are
23823 within the mouse face on that window. */
23824 static int
23825 coords_in_mouse_face_p (struct window *w, int hpos, int vpos)
23826 {
23827 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (w->frame));
23828
23829 /* Quickly resolve the easy cases. */
23830 if (!(WINDOWP (dpyinfo->mouse_face_window)
23831 && XWINDOW (dpyinfo->mouse_face_window) == w))
23832 return 0;
23833 if (vpos < dpyinfo->mouse_face_beg_row
23834 || vpos > dpyinfo->mouse_face_end_row)
23835 return 0;
23836 if (vpos > dpyinfo->mouse_face_beg_row
23837 && vpos < dpyinfo->mouse_face_end_row)
23838 return 1;
23839
23840 if (!MATRIX_ROW (w->current_matrix, vpos)->reversed_p)
23841 {
23842 if (dpyinfo->mouse_face_beg_row == dpyinfo->mouse_face_end_row)
23843 {
23844 if (dpyinfo->mouse_face_beg_col <= hpos && hpos < dpyinfo->mouse_face_end_col)
23845 return 1;
23846 }
23847 else if ((vpos == dpyinfo->mouse_face_beg_row
23848 && hpos >= dpyinfo->mouse_face_beg_col)
23849 || (vpos == dpyinfo->mouse_face_end_row
23850 && hpos < dpyinfo->mouse_face_end_col))
23851 return 1;
23852 }
23853 else
23854 {
23855 if (dpyinfo->mouse_face_beg_row == dpyinfo->mouse_face_end_row)
23856 {
23857 if (dpyinfo->mouse_face_end_col < hpos && hpos <= dpyinfo->mouse_face_beg_col)
23858 return 1;
23859 }
23860 else if ((vpos == dpyinfo->mouse_face_beg_row
23861 && hpos <= dpyinfo->mouse_face_beg_col)
23862 || (vpos == dpyinfo->mouse_face_end_row
23863 && hpos > dpyinfo->mouse_face_end_col))
23864 return 1;
23865 }
23866 return 0;
23867 }
23868
23869
23870 /* EXPORT:
23871 Non-zero if physical cursor of window W is within mouse face. */
23872
23873 int
23874 cursor_in_mouse_face_p (struct window *w)
23875 {
23876 return coords_in_mouse_face_p (w, w->phys_cursor.hpos, w->phys_cursor.vpos);
23877 }
23878
23879
23880 \f
23881 /* This function sets the mouse_face_* elements of DPYINFO, assuming
23882 the mouse cursor is on a glyph with buffer charpos MOUSE_CHARPOS in
23883 window WINDOW. START_CHARPOS and END_CHARPOS are buffer positions
23884 for the overlay or run of text properties specifying the mouse
23885 face. BEFORE_STRING and AFTER_STRING, if non-nil, are a
23886 before-string and after-string that must also be highlighted.
23887 DISPLAY_STRING, if non-nil, is a display string that may cover some
23888 or all of the highlighted text. */
23889
23890 static void
23891 mouse_face_from_buffer_pos (Lisp_Object window,
23892 Display_Info *dpyinfo,
23893 EMACS_INT mouse_charpos,
23894 EMACS_INT start_charpos,
23895 EMACS_INT end_charpos,
23896 Lisp_Object before_string,
23897 Lisp_Object after_string,
23898 Lisp_Object display_string)
23899 {
23900 struct window *w = XWINDOW (window);
23901 struct glyph_row *first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
23902 struct glyph_row *r1, *r2;
23903 struct glyph *glyph, *end;
23904 EMACS_INT ignore, pos;
23905 int x;
23906 int beg_set = 0;
23907
23908 xassert (NILP (display_string) || STRINGP (display_string));
23909 xassert (NILP (before_string) || STRINGP (before_string));
23910 xassert (NILP (after_string) || STRINGP (after_string));
23911
23912 /* Find the row with START_CHARPOS. */
23913 /* FIXME: Sometimes the caller gets "wise" and gives us the window
23914 start position instead of the real start of the mouse face
23915 property. This completely messes up the logic of finding the
23916 beg_row and end_row. */
23917 if (start_charpos < MATRIX_ROW_START_CHARPOS (first)
23918 && (NILP (XBUFFER (w->buffer)->bidi_display_reordering)
23919 || row_containing_pos (w, start_charpos, first, NULL, 0) == NULL))
23920 {
23921 dpyinfo->mouse_face_beg_col = 0;
23922 dpyinfo->mouse_face_beg_row = MATRIX_ROW_VPOS (first, w->current_matrix);
23923 dpyinfo->mouse_face_beg_x = first->x;
23924 dpyinfo->mouse_face_beg_y = first->y;
23925 beg_set = 1;
23926 }
23927 else
23928 {
23929 r1 = row_containing_pos (w, start_charpos, first, NULL, 0);
23930 if (r1 == NULL)
23931 r1 = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
23932
23933 /* If the before-string or display-string contains newlines,
23934 row_containing_pos skips to its last row. Move back. */
23935 if (!NILP (before_string) || !NILP (display_string))
23936 {
23937 struct glyph_row *prev;
23938 while ((prev = r1 - 1, prev >= first)
23939 && MATRIX_ROW_END_CHARPOS (prev) == start_charpos
23940 && prev->used[TEXT_AREA] > 0)
23941 {
23942 struct glyph *beg = prev->glyphs[TEXT_AREA];
23943 glyph = beg + prev->used[TEXT_AREA];
23944 while (--glyph >= beg && INTEGERP (glyph->object));
23945 if (glyph < beg
23946 || !(EQ (glyph->object, before_string)
23947 || EQ (glyph->object, display_string)))
23948 break;
23949 r1 = prev;
23950 }
23951 }
23952 }
23953
23954 /* Find the row with END_CHARPOS. */
23955 r2 = row_containing_pos (w, end_charpos, first, NULL, 0);
23956 if (r2 == NULL)
23957 {
23958 r2 = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
23959 dpyinfo->mouse_face_past_end = 1;
23960 }
23961 else if (!NILP (after_string))
23962 {
23963 /* If the after-string has newlines, advance to its last row. */
23964 struct glyph_row *next;
23965 struct glyph_row *last
23966 = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
23967
23968 for (next = r2 + 1;
23969 next <= last
23970 && next->used[TEXT_AREA] > 0
23971 && EQ (next->glyphs[TEXT_AREA]->object, after_string);
23972 ++next)
23973 r2 = next;
23974 }
23975
23976 /* The rest of the display engine assumes that mouse_face_beg_row is
23977 either above below mouse_face_end_row or identical to it. But
23978 with bidi-reordered continued lines, the row for START_CHARPOS
23979 could be below the row for END_CHARPOS. If so, swap the rows and
23980 store them in correct order. */
23981 if (r1->y > r2->y)
23982 {
23983 struct glyph_row *tem = r2;
23984
23985 r2 = r1;
23986 r1 = tem;
23987 }
23988 dpyinfo->mouse_face_beg_y = r1->y;
23989 dpyinfo->mouse_face_beg_row = MATRIX_ROW_VPOS (r1, w->current_matrix);
23990 dpyinfo->mouse_face_end_y = r2->y;
23991 dpyinfo->mouse_face_end_row = MATRIX_ROW_VPOS (r2, w->current_matrix);
23992
23993 /* For a bidi-reordered row, the positions of BEFORE_STRING,
23994 AFTER_STRING, DISPLAY_STRING, START_CHARPOS, and END_CHARPOS
23995 could be anywhere in the row and in any order. The strategy
23996 below is to find the leftmost and the rightmost glyph that
23997 belongs to either of these 3 strings, or whose position is
23998 between START_CHARPOS and END_CHARPOS, and highlight all the
23999 glyphs between those two. This may cover more than just the text
24000 between START_CHARPOS and END_CHARPOS if the range of characters
24001 strides the bidi level boundary, e.g. if the beginning is in R2L
24002 text while the end is in L2R text or vice versa. */
24003 if (beg_set)
24004 ;
24005 else if (!r1->reversed_p)
24006 {
24007 /* This row is in a left to right paragraph. Scan it left to
24008 right. */
24009 glyph = r1->glyphs[TEXT_AREA];
24010 end = glyph + r1->used[TEXT_AREA];
24011 x = r1->x;
24012
24013 /* Skip truncation glyphs at the start of the glyph row. */
24014 if (r1->displays_text_p)
24015 for (; glyph < end
24016 && INTEGERP (glyph->object)
24017 && glyph->charpos < 0;
24018 ++glyph)
24019 x += glyph->pixel_width;
24020
24021 /* Scan the glyph row, looking for BEFORE_STRING, AFTER_STRING,
24022 or DISPLAY_STRING, and the first glyph from buffer whose
24023 position is between START_CHARPOS and END_CHARPOS. */
24024 for (; glyph < end
24025 && !INTEGERP (glyph->object)
24026 && !EQ (glyph->object, display_string)
24027 && !(BUFFERP (glyph->object)
24028 && (glyph->charpos >= start_charpos
24029 && glyph->charpos < end_charpos));
24030 ++glyph)
24031 {
24032 /* BEFORE_STRING or AFTER_STRING are only relevant if they
24033 are present at buffer positions between START_CHARPOS and
24034 END_CHARPOS, or if they come from an overlay. */
24035 if (EQ (glyph->object, before_string))
24036 {
24037 pos = string_buffer_position (w, before_string,
24038 start_charpos);
24039 /* If pos == 0, it means before_string came from an
24040 overlay, not from a buffer position. */
24041 if (!pos || pos >= start_charpos && pos < end_charpos)
24042 break;
24043 }
24044 else if (EQ (glyph->object, after_string))
24045 {
24046 pos = string_buffer_position (w, after_string, end_charpos);
24047 if (!pos || pos >= start_charpos && pos < end_charpos)
24048 break;
24049 }
24050 x += glyph->pixel_width;
24051 }
24052 dpyinfo->mouse_face_beg_x = x;
24053 dpyinfo->mouse_face_beg_col = glyph - r1->glyphs[TEXT_AREA];
24054 }
24055 else
24056 {
24057 /* This row is in a right to left paragraph. Scan it right to
24058 left. */
24059 struct glyph *g;
24060
24061 end = r1->glyphs[TEXT_AREA] - 1;
24062 glyph = end + r1->used[TEXT_AREA];
24063
24064 /* Skip truncation glyphs at the start of the glyph row. */
24065 if (r1->displays_text_p)
24066 for (; glyph > end
24067 && INTEGERP (glyph->object)
24068 && glyph->charpos < 0;
24069 --glyph)
24070 ;
24071
24072 /* Scan the glyph row, looking for BEFORE_STRING, AFTER_STRING,
24073 or DISPLAY_STRING, and the first glyph from buffer whose
24074 position is between START_CHARPOS and END_CHARPOS. */
24075 for (; glyph > end
24076 && !INTEGERP (glyph->object)
24077 && !EQ (glyph->object, display_string)
24078 && !(BUFFERP (glyph->object)
24079 && (glyph->charpos >= start_charpos
24080 && glyph->charpos < end_charpos));
24081 --glyph)
24082 {
24083 /* BEFORE_STRING or AFTER_STRING are only relevant if they
24084 are present at buffer positions between START_CHARPOS and
24085 END_CHARPOS, or if they come from an overlay. */
24086 if (EQ (glyph->object, before_string))
24087 {
24088 pos = string_buffer_position (w, before_string, start_charpos);
24089 /* If pos == 0, it means before_string came from an
24090 overlay, not from a buffer position. */
24091 if (!pos || pos >= start_charpos && pos < end_charpos)
24092 break;
24093 }
24094 else if (EQ (glyph->object, after_string))
24095 {
24096 pos = string_buffer_position (w, after_string, end_charpos);
24097 if (!pos || pos >= start_charpos && pos < end_charpos)
24098 break;
24099 }
24100 }
24101
24102 glyph++; /* first glyph to the right of the highlighted area */
24103 for (g = r1->glyphs[TEXT_AREA], x = r1->x; g < glyph; g++)
24104 x += g->pixel_width;
24105 dpyinfo->mouse_face_beg_x = x;
24106 dpyinfo->mouse_face_beg_col = glyph - r1->glyphs[TEXT_AREA];
24107 }
24108
24109 /* If the highlight ends in a different row, compute GLYPH and END
24110 for the end row. Otherwise, reuse the values computed above for
24111 the row where the highlight begins. */
24112 if (r2 != r1)
24113 {
24114 if (!r2->reversed_p)
24115 {
24116 glyph = r2->glyphs[TEXT_AREA];
24117 end = glyph + r2->used[TEXT_AREA];
24118 x = r2->x;
24119 }
24120 else
24121 {
24122 end = r2->glyphs[TEXT_AREA] - 1;
24123 glyph = end + r2->used[TEXT_AREA];
24124 }
24125 }
24126
24127 if (!r2->reversed_p)
24128 {
24129 /* Skip truncation and continuation glyphs near the end of the
24130 row, and also blanks and stretch glyphs inserted by
24131 extend_face_to_end_of_line. */
24132 while (end > glyph
24133 && INTEGERP ((end - 1)->object)
24134 && (end - 1)->charpos <= 0)
24135 --end;
24136 /* Scan the rest of the glyph row from the end, looking for the
24137 first glyph that comes from BEFORE_STRING, AFTER_STRING, or
24138 DISPLAY_STRING, or whose position is between START_CHARPOS
24139 and END_CHARPOS */
24140 for (--end;
24141 end > glyph
24142 && !INTEGERP (end->object)
24143 && !EQ (end->object, display_string)
24144 && !(BUFFERP (end->object)
24145 && (end->charpos >= start_charpos
24146 && end->charpos < end_charpos));
24147 --end)
24148 {
24149 /* BEFORE_STRING or AFTER_STRING are only relevant if they
24150 are present at buffer positions between START_CHARPOS and
24151 END_CHARPOS, or if they come from an overlay. */
24152 if (EQ (end->object, before_string))
24153 {
24154 pos = string_buffer_position (w, before_string, start_charpos);
24155 if (!pos || pos >= start_charpos && pos < end_charpos)
24156 break;
24157 }
24158 else if (EQ (end->object, after_string))
24159 {
24160 pos = string_buffer_position (w, after_string, end_charpos);
24161 if (!pos || pos >= start_charpos && pos < end_charpos)
24162 break;
24163 }
24164 }
24165 /* Find the X coordinate of the last glyph to be highlighted. */
24166 for (; glyph <= end; ++glyph)
24167 x += glyph->pixel_width;
24168
24169 dpyinfo->mouse_face_end_x = x;
24170 dpyinfo->mouse_face_end_col = glyph - r2->glyphs[TEXT_AREA];
24171 }
24172 else
24173 {
24174 /* Skip truncation and continuation glyphs near the end of the
24175 row, and also blanks and stretch glyphs inserted by
24176 extend_face_to_end_of_line. */
24177 x = r2->x;
24178 end++;
24179 while (end < glyph
24180 && INTEGERP (end->object)
24181 && end->charpos <= 0)
24182 {
24183 x += end->pixel_width;
24184 ++end;
24185 }
24186 /* Scan the rest of the glyph row from the end, looking for the
24187 first glyph that comes from BEFORE_STRING, AFTER_STRING, or
24188 DISPLAY_STRING, or whose position is between START_CHARPOS
24189 and END_CHARPOS */
24190 for ( ;
24191 end < glyph
24192 && !INTEGERP (end->object)
24193 && !EQ (end->object, display_string)
24194 && !(BUFFERP (end->object)
24195 && (end->charpos >= start_charpos
24196 && end->charpos < end_charpos));
24197 ++end)
24198 {
24199 /* BEFORE_STRING or AFTER_STRING are only relevant if they
24200 are present at buffer positions between START_CHARPOS and
24201 END_CHARPOS, or if they come from an overlay. */
24202 if (EQ (end->object, before_string))
24203 {
24204 pos = string_buffer_position (w, before_string, start_charpos);
24205 if (!pos || pos >= start_charpos && pos < end_charpos)
24206 break;
24207 }
24208 else if (EQ (end->object, after_string))
24209 {
24210 pos = string_buffer_position (w, after_string, end_charpos);
24211 if (!pos || pos >= start_charpos && pos < end_charpos)
24212 break;
24213 }
24214 x += end->pixel_width;
24215 }
24216 dpyinfo->mouse_face_end_x = x;
24217 dpyinfo->mouse_face_end_col = end - r2->glyphs[TEXT_AREA];
24218 }
24219
24220 dpyinfo->mouse_face_window = window;
24221 dpyinfo->mouse_face_face_id
24222 = face_at_buffer_position (w, mouse_charpos, 0, 0, &ignore,
24223 mouse_charpos + 1,
24224 !dpyinfo->mouse_face_hidden, -1);
24225 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
24226 }
24227
24228
24229 /* Find the position of the glyph for position POS in OBJECT in
24230 window W's current matrix, and return in *X, *Y the pixel
24231 coordinates, and return in *HPOS, *VPOS the column/row of the glyph.
24232
24233 RIGHT_P non-zero means return the position of the right edge of the
24234 glyph, RIGHT_P zero means return the left edge position.
24235
24236 If no glyph for POS exists in the matrix, return the position of
24237 the glyph with the next smaller position that is in the matrix, if
24238 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS
24239 exists in the matrix, return the position of the glyph with the
24240 next larger position in OBJECT.
24241
24242 Value is non-zero if a glyph was found. */
24243
24244 static int
24245 fast_find_string_pos (struct window *w, EMACS_INT pos, Lisp_Object object,
24246 int *hpos, int *vpos, int *x, int *y, int right_p)
24247 {
24248 int yb = window_text_bottom_y (w);
24249 struct glyph_row *r;
24250 struct glyph *best_glyph = NULL;
24251 struct glyph_row *best_row = NULL;
24252 int best_x = 0;
24253
24254 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
24255 r->enabled_p && r->y < yb;
24256 ++r)
24257 {
24258 struct glyph *g = r->glyphs[TEXT_AREA];
24259 struct glyph *e = g + r->used[TEXT_AREA];
24260 int gx;
24261
24262 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
24263 if (EQ (g->object, object))
24264 {
24265 if (g->charpos == pos)
24266 {
24267 best_glyph = g;
24268 best_x = gx;
24269 best_row = r;
24270 goto found;
24271 }
24272 else if (best_glyph == NULL
24273 || ((eabs (g->charpos - pos)
24274 < eabs (best_glyph->charpos - pos))
24275 && (right_p
24276 ? g->charpos < pos
24277 : g->charpos > pos)))
24278 {
24279 best_glyph = g;
24280 best_x = gx;
24281 best_row = r;
24282 }
24283 }
24284 }
24285
24286 found:
24287
24288 if (best_glyph)
24289 {
24290 *x = best_x;
24291 *hpos = best_glyph - best_row->glyphs[TEXT_AREA];
24292
24293 if (right_p)
24294 {
24295 *x += best_glyph->pixel_width;
24296 ++*hpos;
24297 }
24298
24299 *y = best_row->y;
24300 *vpos = best_row - w->current_matrix->rows;
24301 }
24302
24303 return best_glyph != NULL;
24304 }
24305
24306
24307 /* See if position X, Y is within a hot-spot of an image. */
24308
24309 static int
24310 on_hot_spot_p (Lisp_Object hot_spot, int x, int y)
24311 {
24312 if (!CONSP (hot_spot))
24313 return 0;
24314
24315 if (EQ (XCAR (hot_spot), Qrect))
24316 {
24317 /* CDR is (Top-Left . Bottom-Right) = ((x0 . y0) . (x1 . y1)) */
24318 Lisp_Object rect = XCDR (hot_spot);
24319 Lisp_Object tem;
24320 if (!CONSP (rect))
24321 return 0;
24322 if (!CONSP (XCAR (rect)))
24323 return 0;
24324 if (!CONSP (XCDR (rect)))
24325 return 0;
24326 if (!(tem = XCAR (XCAR (rect)), INTEGERP (tem) && x >= XINT (tem)))
24327 return 0;
24328 if (!(tem = XCDR (XCAR (rect)), INTEGERP (tem) && y >= XINT (tem)))
24329 return 0;
24330 if (!(tem = XCAR (XCDR (rect)), INTEGERP (tem) && x <= XINT (tem)))
24331 return 0;
24332 if (!(tem = XCDR (XCDR (rect)), INTEGERP (tem) && y <= XINT (tem)))
24333 return 0;
24334 return 1;
24335 }
24336 else if (EQ (XCAR (hot_spot), Qcircle))
24337 {
24338 /* CDR is (Center . Radius) = ((x0 . y0) . r) */
24339 Lisp_Object circ = XCDR (hot_spot);
24340 Lisp_Object lr, lx0, ly0;
24341 if (CONSP (circ)
24342 && CONSP (XCAR (circ))
24343 && (lr = XCDR (circ), INTEGERP (lr) || FLOATP (lr))
24344 && (lx0 = XCAR (XCAR (circ)), INTEGERP (lx0))
24345 && (ly0 = XCDR (XCAR (circ)), INTEGERP (ly0)))
24346 {
24347 double r = XFLOATINT (lr);
24348 double dx = XINT (lx0) - x;
24349 double dy = XINT (ly0) - y;
24350 return (dx * dx + dy * dy <= r * r);
24351 }
24352 }
24353 else if (EQ (XCAR (hot_spot), Qpoly))
24354 {
24355 /* CDR is [x0 y0 x1 y1 x2 y2 ...x(n-1) y(n-1)] */
24356 if (VECTORP (XCDR (hot_spot)))
24357 {
24358 struct Lisp_Vector *v = XVECTOR (XCDR (hot_spot));
24359 Lisp_Object *poly = v->contents;
24360 int n = v->size;
24361 int i;
24362 int inside = 0;
24363 Lisp_Object lx, ly;
24364 int x0, y0;
24365
24366 /* Need an even number of coordinates, and at least 3 edges. */
24367 if (n < 6 || n & 1)
24368 return 0;
24369
24370 /* Count edge segments intersecting line from (X,Y) to (X,infinity).
24371 If count is odd, we are inside polygon. Pixels on edges
24372 may or may not be included depending on actual geometry of the
24373 polygon. */
24374 if ((lx = poly[n-2], !INTEGERP (lx))
24375 || (ly = poly[n-1], !INTEGERP (lx)))
24376 return 0;
24377 x0 = XINT (lx), y0 = XINT (ly);
24378 for (i = 0; i < n; i += 2)
24379 {
24380 int x1 = x0, y1 = y0;
24381 if ((lx = poly[i], !INTEGERP (lx))
24382 || (ly = poly[i+1], !INTEGERP (ly)))
24383 return 0;
24384 x0 = XINT (lx), y0 = XINT (ly);
24385
24386 /* Does this segment cross the X line? */
24387 if (x0 >= x)
24388 {
24389 if (x1 >= x)
24390 continue;
24391 }
24392 else if (x1 < x)
24393 continue;
24394 if (y > y0 && y > y1)
24395 continue;
24396 if (y < y0 + ((y1 - y0) * (x - x0)) / (x1 - x0))
24397 inside = !inside;
24398 }
24399 return inside;
24400 }
24401 }
24402 return 0;
24403 }
24404
24405 Lisp_Object
24406 find_hot_spot (Lisp_Object map, int x, int y)
24407 {
24408 while (CONSP (map))
24409 {
24410 if (CONSP (XCAR (map))
24411 && on_hot_spot_p (XCAR (XCAR (map)), x, y))
24412 return XCAR (map);
24413 map = XCDR (map);
24414 }
24415
24416 return Qnil;
24417 }
24418
24419 DEFUN ("lookup-image-map", Flookup_image_map, Slookup_image_map,
24420 3, 3, 0,
24421 doc: /* Lookup in image map MAP coordinates X and Y.
24422 An image map is an alist where each element has the format (AREA ID PLIST).
24423 An AREA is specified as either a rectangle, a circle, or a polygon:
24424 A rectangle is a cons (rect . ((x0 . y0) . (x1 . y1))) specifying the
24425 pixel coordinates of the upper left and bottom right corners.
24426 A circle is a cons (circle . ((x0 . y0) . r)) specifying the center
24427 and the radius of the circle; r may be a float or integer.
24428 A polygon is a cons (poly . [x0 y0 x1 y1 ...]) where each pair in the
24429 vector describes one corner in the polygon.
24430 Returns the alist element for the first matching AREA in MAP. */)
24431 (Lisp_Object map, Lisp_Object x, Lisp_Object y)
24432 {
24433 if (NILP (map))
24434 return Qnil;
24435
24436 CHECK_NUMBER (x);
24437 CHECK_NUMBER (y);
24438
24439 return find_hot_spot (map, XINT (x), XINT (y));
24440 }
24441
24442
24443 /* Display frame CURSOR, optionally using shape defined by POINTER. */
24444 static void
24445 define_frame_cursor1 (struct frame *f, Cursor cursor, Lisp_Object pointer)
24446 {
24447 /* Do not change cursor shape while dragging mouse. */
24448 if (!NILP (do_mouse_tracking))
24449 return;
24450
24451 if (!NILP (pointer))
24452 {
24453 if (EQ (pointer, Qarrow))
24454 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
24455 else if (EQ (pointer, Qhand))
24456 cursor = FRAME_X_OUTPUT (f)->hand_cursor;
24457 else if (EQ (pointer, Qtext))
24458 cursor = FRAME_X_OUTPUT (f)->text_cursor;
24459 else if (EQ (pointer, intern ("hdrag")))
24460 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
24461 #ifdef HAVE_X_WINDOWS
24462 else if (EQ (pointer, intern ("vdrag")))
24463 cursor = FRAME_X_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
24464 #endif
24465 else if (EQ (pointer, intern ("hourglass")))
24466 cursor = FRAME_X_OUTPUT (f)->hourglass_cursor;
24467 else if (EQ (pointer, Qmodeline))
24468 cursor = FRAME_X_OUTPUT (f)->modeline_cursor;
24469 else
24470 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
24471 }
24472
24473 if (cursor != No_Cursor)
24474 FRAME_RIF (f)->define_frame_cursor (f, cursor);
24475 }
24476
24477 /* Take proper action when mouse has moved to the mode or header line
24478 or marginal area AREA of window W, x-position X and y-position Y.
24479 X is relative to the start of the text display area of W, so the
24480 width of bitmap areas and scroll bars must be subtracted to get a
24481 position relative to the start of the mode line. */
24482
24483 static void
24484 note_mode_line_or_margin_highlight (Lisp_Object window, int x, int y,
24485 enum window_part area)
24486 {
24487 struct window *w = XWINDOW (window);
24488 struct frame *f = XFRAME (w->frame);
24489 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
24490 Cursor cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
24491 Lisp_Object pointer = Qnil;
24492 int charpos, dx, dy, width, height;
24493 Lisp_Object string, object = Qnil;
24494 Lisp_Object pos, help;
24495
24496 Lisp_Object mouse_face;
24497 int original_x_pixel = x;
24498 struct glyph * glyph = NULL, * row_start_glyph = NULL;
24499 struct glyph_row *row;
24500
24501 if (area == ON_MODE_LINE || area == ON_HEADER_LINE)
24502 {
24503 int x0;
24504 struct glyph *end;
24505
24506 string = mode_line_string (w, area, &x, &y, &charpos,
24507 &object, &dx, &dy, &width, &height);
24508
24509 row = (area == ON_MODE_LINE
24510 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
24511 : MATRIX_HEADER_LINE_ROW (w->current_matrix));
24512
24513 /* Find glyph */
24514 if (row->mode_line_p && row->enabled_p)
24515 {
24516 glyph = row_start_glyph = row->glyphs[TEXT_AREA];
24517 end = glyph + row->used[TEXT_AREA];
24518
24519 for (x0 = original_x_pixel;
24520 glyph < end && x0 >= glyph->pixel_width;
24521 ++glyph)
24522 x0 -= glyph->pixel_width;
24523
24524 if (glyph >= end)
24525 glyph = NULL;
24526 }
24527 }
24528 else
24529 {
24530 x -= WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
24531 string = marginal_area_string (w, area, &x, &y, &charpos,
24532 &object, &dx, &dy, &width, &height);
24533 }
24534
24535 help = Qnil;
24536
24537 if (IMAGEP (object))
24538 {
24539 Lisp_Object image_map, hotspot;
24540 if ((image_map = Fplist_get (XCDR (object), QCmap),
24541 !NILP (image_map))
24542 && (hotspot = find_hot_spot (image_map, dx, dy),
24543 CONSP (hotspot))
24544 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
24545 {
24546 Lisp_Object area_id, plist;
24547
24548 area_id = XCAR (hotspot);
24549 /* Could check AREA_ID to see if we enter/leave this hot-spot.
24550 If so, we could look for mouse-enter, mouse-leave
24551 properties in PLIST (and do something...). */
24552 hotspot = XCDR (hotspot);
24553 if (CONSP (hotspot)
24554 && (plist = XCAR (hotspot), CONSP (plist)))
24555 {
24556 pointer = Fplist_get (plist, Qpointer);
24557 if (NILP (pointer))
24558 pointer = Qhand;
24559 help = Fplist_get (plist, Qhelp_echo);
24560 if (!NILP (help))
24561 {
24562 help_echo_string = help;
24563 /* Is this correct? ++kfs */
24564 XSETWINDOW (help_echo_window, w);
24565 help_echo_object = w->buffer;
24566 help_echo_pos = charpos;
24567 }
24568 }
24569 }
24570 if (NILP (pointer))
24571 pointer = Fplist_get (XCDR (object), QCpointer);
24572 }
24573
24574 if (STRINGP (string))
24575 {
24576 pos = make_number (charpos);
24577 /* If we're on a string with `help-echo' text property, arrange
24578 for the help to be displayed. This is done by setting the
24579 global variable help_echo_string to the help string. */
24580 if (NILP (help))
24581 {
24582 help = Fget_text_property (pos, Qhelp_echo, string);
24583 if (!NILP (help))
24584 {
24585 help_echo_string = help;
24586 XSETWINDOW (help_echo_window, w);
24587 help_echo_object = string;
24588 help_echo_pos = charpos;
24589 }
24590 }
24591
24592 if (NILP (pointer))
24593 pointer = Fget_text_property (pos, Qpointer, string);
24594
24595 /* Change the mouse pointer according to what is under X/Y. */
24596 if (NILP (pointer) && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE)))
24597 {
24598 Lisp_Object map;
24599 map = Fget_text_property (pos, Qlocal_map, string);
24600 if (!KEYMAPP (map))
24601 map = Fget_text_property (pos, Qkeymap, string);
24602 if (!KEYMAPP (map))
24603 cursor = dpyinfo->vertical_scroll_bar_cursor;
24604 }
24605
24606 /* Change the mouse face according to what is under X/Y. */
24607 mouse_face = Fget_text_property (pos, Qmouse_face, string);
24608 if (!NILP (mouse_face)
24609 && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE))
24610 && glyph)
24611 {
24612 Lisp_Object b, e;
24613
24614 struct glyph * tmp_glyph;
24615
24616 int gpos;
24617 int gseq_length;
24618 int total_pixel_width;
24619 EMACS_INT ignore;
24620
24621 int vpos, hpos;
24622
24623 b = Fprevious_single_property_change (make_number (charpos + 1),
24624 Qmouse_face, string, Qnil);
24625 if (NILP (b))
24626 b = make_number (0);
24627
24628 e = Fnext_single_property_change (pos, Qmouse_face, string, Qnil);
24629 if (NILP (e))
24630 e = make_number (SCHARS (string));
24631
24632 /* Calculate the position(glyph position: GPOS) of GLYPH in
24633 displayed string. GPOS is different from CHARPOS.
24634
24635 CHARPOS is the position of glyph in internal string
24636 object. A mode line string format has structures which
24637 is converted to a flatten by emacs lisp interpreter.
24638 The internal string is an element of the structures.
24639 The displayed string is the flatten string. */
24640 gpos = 0;
24641 if (glyph > row_start_glyph)
24642 {
24643 tmp_glyph = glyph - 1;
24644 while (tmp_glyph >= row_start_glyph
24645 && tmp_glyph->charpos >= XINT (b)
24646 && EQ (tmp_glyph->object, glyph->object))
24647 {
24648 tmp_glyph--;
24649 gpos++;
24650 }
24651 }
24652
24653 /* Calculate the lenght(glyph sequence length: GSEQ_LENGTH) of
24654 displayed string holding GLYPH.
24655
24656 GSEQ_LENGTH is different from SCHARS (STRING).
24657 SCHARS (STRING) returns the length of the internal string. */
24658 for (tmp_glyph = glyph, gseq_length = gpos;
24659 tmp_glyph->charpos < XINT (e);
24660 tmp_glyph++, gseq_length++)
24661 {
24662 if (!EQ (tmp_glyph->object, glyph->object))
24663 break;
24664 }
24665
24666 total_pixel_width = 0;
24667 for (tmp_glyph = glyph - gpos; tmp_glyph != glyph; tmp_glyph++)
24668 total_pixel_width += tmp_glyph->pixel_width;
24669
24670 /* Pre calculation of re-rendering position */
24671 hpos = (x - gpos);
24672 vpos = (area == ON_MODE_LINE
24673 ? (w->current_matrix)->nrows - 1
24674 : 0);
24675
24676 /* If the re-rendering position is included in the last
24677 re-rendering area, we should do nothing. */
24678 if ( EQ (window, dpyinfo->mouse_face_window)
24679 && dpyinfo->mouse_face_beg_col <= hpos
24680 && hpos < dpyinfo->mouse_face_end_col
24681 && dpyinfo->mouse_face_beg_row == vpos )
24682 return;
24683
24684 if (clear_mouse_face (dpyinfo))
24685 cursor = No_Cursor;
24686
24687 dpyinfo->mouse_face_beg_col = hpos;
24688 dpyinfo->mouse_face_beg_row = vpos;
24689
24690 dpyinfo->mouse_face_beg_x = original_x_pixel - (total_pixel_width + dx);
24691 dpyinfo->mouse_face_beg_y = 0;
24692
24693 dpyinfo->mouse_face_end_col = hpos + gseq_length;
24694 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_beg_row;
24695
24696 dpyinfo->mouse_face_end_x = 0;
24697 dpyinfo->mouse_face_end_y = 0;
24698
24699 dpyinfo->mouse_face_past_end = 0;
24700 dpyinfo->mouse_face_window = window;
24701
24702 dpyinfo->mouse_face_face_id = face_at_string_position (w, string,
24703 charpos,
24704 0, 0, 0, &ignore,
24705 glyph->face_id, 1);
24706 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
24707
24708 if (NILP (pointer))
24709 pointer = Qhand;
24710 }
24711 else if ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE))
24712 clear_mouse_face (dpyinfo);
24713 }
24714 define_frame_cursor1 (f, cursor, pointer);
24715 }
24716
24717
24718 /* EXPORT:
24719 Take proper action when the mouse has moved to position X, Y on
24720 frame F as regards highlighting characters that have mouse-face
24721 properties. Also de-highlighting chars where the mouse was before.
24722 X and Y can be negative or out of range. */
24723
24724 void
24725 note_mouse_highlight (struct frame *f, int x, int y)
24726 {
24727 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
24728 enum window_part part;
24729 Lisp_Object window;
24730 struct window *w;
24731 Cursor cursor = No_Cursor;
24732 Lisp_Object pointer = Qnil; /* Takes precedence over cursor! */
24733 struct buffer *b;
24734
24735 /* When a menu is active, don't highlight because this looks odd. */
24736 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS)
24737 if (popup_activated ())
24738 return;
24739 #endif
24740
24741 if (NILP (Vmouse_highlight)
24742 || !f->glyphs_initialized_p
24743 || f->pointer_invisible)
24744 return;
24745
24746 dpyinfo->mouse_face_mouse_x = x;
24747 dpyinfo->mouse_face_mouse_y = y;
24748 dpyinfo->mouse_face_mouse_frame = f;
24749
24750 if (dpyinfo->mouse_face_defer)
24751 return;
24752
24753 if (gc_in_progress)
24754 {
24755 dpyinfo->mouse_face_deferred_gc = 1;
24756 return;
24757 }
24758
24759 /* Which window is that in? */
24760 window = window_from_coordinates (f, x, y, &part, 0, 0, 1);
24761
24762 /* If we were displaying active text in another window, clear that.
24763 Also clear if we move out of text area in same window. */
24764 if (! EQ (window, dpyinfo->mouse_face_window)
24765 || (part != ON_TEXT && part != ON_MODE_LINE && part != ON_HEADER_LINE
24766 && !NILP (dpyinfo->mouse_face_window)))
24767 clear_mouse_face (dpyinfo);
24768
24769 /* Not on a window -> return. */
24770 if (!WINDOWP (window))
24771 return;
24772
24773 /* Reset help_echo_string. It will get recomputed below. */
24774 help_echo_string = Qnil;
24775
24776 /* Convert to window-relative pixel coordinates. */
24777 w = XWINDOW (window);
24778 frame_to_window_pixel_xy (w, &x, &y);
24779
24780 /* Handle tool-bar window differently since it doesn't display a
24781 buffer. */
24782 if (EQ (window, f->tool_bar_window))
24783 {
24784 note_tool_bar_highlight (f, x, y);
24785 return;
24786 }
24787
24788 /* Mouse is on the mode, header line or margin? */
24789 if (part == ON_MODE_LINE || part == ON_HEADER_LINE
24790 || part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
24791 {
24792 note_mode_line_or_margin_highlight (window, x, y, part);
24793 return;
24794 }
24795
24796 if (part == ON_VERTICAL_BORDER)
24797 {
24798 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
24799 help_echo_string = build_string ("drag-mouse-1: resize");
24800 }
24801 else if (part == ON_LEFT_FRINGE || part == ON_RIGHT_FRINGE
24802 || part == ON_SCROLL_BAR)
24803 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
24804 else
24805 cursor = FRAME_X_OUTPUT (f)->text_cursor;
24806
24807 /* Are we in a window whose display is up to date?
24808 And verify the buffer's text has not changed. */
24809 b = XBUFFER (w->buffer);
24810 if (part == ON_TEXT
24811 && EQ (w->window_end_valid, w->buffer)
24812 && XFASTINT (w->last_modified) == BUF_MODIFF (b)
24813 && XFASTINT (w->last_overlay_modified) == BUF_OVERLAY_MODIFF (b))
24814 {
24815 int hpos, vpos, i, dx, dy, area;
24816 EMACS_INT pos;
24817 struct glyph *glyph;
24818 Lisp_Object object;
24819 Lisp_Object mouse_face = Qnil, overlay = Qnil, position;
24820 Lisp_Object *overlay_vec = NULL;
24821 int noverlays;
24822 struct buffer *obuf;
24823 int obegv, ozv, same_region;
24824
24825 /* Find the glyph under X/Y. */
24826 glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, &dx, &dy, &area);
24827
24828 /* Look for :pointer property on image. */
24829 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
24830 {
24831 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
24832 if (img != NULL && IMAGEP (img->spec))
24833 {
24834 Lisp_Object image_map, hotspot;
24835 if ((image_map = Fplist_get (XCDR (img->spec), QCmap),
24836 !NILP (image_map))
24837 && (hotspot = find_hot_spot (image_map,
24838 glyph->slice.x + dx,
24839 glyph->slice.y + dy),
24840 CONSP (hotspot))
24841 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
24842 {
24843 Lisp_Object area_id, plist;
24844
24845 area_id = XCAR (hotspot);
24846 /* Could check AREA_ID to see if we enter/leave this hot-spot.
24847 If so, we could look for mouse-enter, mouse-leave
24848 properties in PLIST (and do something...). */
24849 hotspot = XCDR (hotspot);
24850 if (CONSP (hotspot)
24851 && (plist = XCAR (hotspot), CONSP (plist)))
24852 {
24853 pointer = Fplist_get (plist, Qpointer);
24854 if (NILP (pointer))
24855 pointer = Qhand;
24856 help_echo_string = Fplist_get (plist, Qhelp_echo);
24857 if (!NILP (help_echo_string))
24858 {
24859 help_echo_window = window;
24860 help_echo_object = glyph->object;
24861 help_echo_pos = glyph->charpos;
24862 }
24863 }
24864 }
24865 if (NILP (pointer))
24866 pointer = Fplist_get (XCDR (img->spec), QCpointer);
24867 }
24868 }
24869
24870 /* Clear mouse face if X/Y not over text. */
24871 if (glyph == NULL
24872 || area != TEXT_AREA
24873 || !MATRIX_ROW (w->current_matrix, vpos)->displays_text_p
24874 /* R2L rows have a stretch glyph at their front, which
24875 stands for no text, whereas L2R rows have no glyphs at
24876 all beyond the end of text. Treat such stretch glyphs
24877 like we do with NULL glyphs in L2R rows. */
24878 || (MATRIX_ROW (w->current_matrix, vpos)->reversed_p
24879 && glyph == MATRIX_ROW (w->current_matrix, vpos)->glyphs[TEXT_AREA]
24880 && glyph->type == STRETCH_GLYPH
24881 && glyph->avoid_cursor_p))
24882 {
24883 if (clear_mouse_face (dpyinfo))
24884 cursor = No_Cursor;
24885 if (NILP (pointer))
24886 {
24887 if (area != TEXT_AREA)
24888 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
24889 else
24890 pointer = Vvoid_text_area_pointer;
24891 }
24892 goto set_cursor;
24893 }
24894
24895 pos = glyph->charpos;
24896 object = glyph->object;
24897 if (!STRINGP (object) && !BUFFERP (object))
24898 goto set_cursor;
24899
24900 /* If we get an out-of-range value, return now; avoid an error. */
24901 if (BUFFERP (object) && pos > BUF_Z (b))
24902 goto set_cursor;
24903
24904 /* Make the window's buffer temporarily current for
24905 overlays_at and compute_char_face. */
24906 obuf = current_buffer;
24907 current_buffer = b;
24908 obegv = BEGV;
24909 ozv = ZV;
24910 BEGV = BEG;
24911 ZV = Z;
24912
24913 /* Is this char mouse-active or does it have help-echo? */
24914 position = make_number (pos);
24915
24916 if (BUFFERP (object))
24917 {
24918 /* Put all the overlays we want in a vector in overlay_vec. */
24919 GET_OVERLAYS_AT (pos, overlay_vec, noverlays, NULL, 0);
24920 /* Sort overlays into increasing priority order. */
24921 noverlays = sort_overlays (overlay_vec, noverlays, w);
24922 }
24923 else
24924 noverlays = 0;
24925
24926 same_region = coords_in_mouse_face_p (w, hpos, vpos);
24927
24928 if (same_region)
24929 cursor = No_Cursor;
24930
24931 /* Check mouse-face highlighting. */
24932 if (! same_region
24933 /* If there exists an overlay with mouse-face overlapping
24934 the one we are currently highlighting, we have to
24935 check if we enter the overlapping overlay, and then
24936 highlight only that. */
24937 || (OVERLAYP (dpyinfo->mouse_face_overlay)
24938 && mouse_face_overlay_overlaps (dpyinfo->mouse_face_overlay)))
24939 {
24940 /* Find the highest priority overlay with a mouse-face. */
24941 overlay = Qnil;
24942 for (i = noverlays - 1; i >= 0 && NILP (overlay); --i)
24943 {
24944 mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face);
24945 if (!NILP (mouse_face))
24946 overlay = overlay_vec[i];
24947 }
24948
24949 /* If we're highlighting the same overlay as before, there's
24950 no need to do that again. */
24951 if (!NILP (overlay) && EQ (overlay, dpyinfo->mouse_face_overlay))
24952 goto check_help_echo;
24953 dpyinfo->mouse_face_overlay = overlay;
24954
24955 /* Clear the display of the old active region, if any. */
24956 if (clear_mouse_face (dpyinfo))
24957 cursor = No_Cursor;
24958
24959 /* If no overlay applies, get a text property. */
24960 if (NILP (overlay))
24961 mouse_face = Fget_text_property (position, Qmouse_face, object);
24962
24963 /* Next, compute the bounds of the mouse highlighting and
24964 display it. */
24965 if (!NILP (mouse_face) && STRINGP (object))
24966 {
24967 /* The mouse-highlighting comes from a display string
24968 with a mouse-face. */
24969 Lisp_Object b, e;
24970 EMACS_INT ignore;
24971
24972 b = Fprevious_single_property_change
24973 (make_number (pos + 1), Qmouse_face, object, Qnil);
24974 e = Fnext_single_property_change
24975 (position, Qmouse_face, object, Qnil);
24976 if (NILP (b))
24977 b = make_number (0);
24978 if (NILP (e))
24979 e = make_number (SCHARS (object) - 1);
24980
24981 fast_find_string_pos (w, XINT (b), object,
24982 &dpyinfo->mouse_face_beg_col,
24983 &dpyinfo->mouse_face_beg_row,
24984 &dpyinfo->mouse_face_beg_x,
24985 &dpyinfo->mouse_face_beg_y, 0);
24986 fast_find_string_pos (w, XINT (e), object,
24987 &dpyinfo->mouse_face_end_col,
24988 &dpyinfo->mouse_face_end_row,
24989 &dpyinfo->mouse_face_end_x,
24990 &dpyinfo->mouse_face_end_y, 1);
24991 dpyinfo->mouse_face_past_end = 0;
24992 dpyinfo->mouse_face_window = window;
24993 dpyinfo->mouse_face_face_id
24994 = face_at_string_position (w, object, pos, 0, 0, 0, &ignore,
24995 glyph->face_id, 1);
24996 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
24997 cursor = No_Cursor;
24998 }
24999 else
25000 {
25001 /* The mouse-highlighting, if any, comes from an overlay
25002 or text property in the buffer. */
25003 Lisp_Object buffer, display_string;
25004
25005 if (STRINGP (object))
25006 {
25007 /* If we are on a display string with no mouse-face,
25008 check if the text under it has one. */
25009 struct glyph_row *r = MATRIX_ROW (w->current_matrix, vpos);
25010 int start = MATRIX_ROW_START_CHARPOS (r);
25011 pos = string_buffer_position (w, object, start);
25012 if (pos > 0)
25013 {
25014 mouse_face = get_char_property_and_overlay
25015 (make_number (pos), Qmouse_face, w->buffer, &overlay);
25016 buffer = w->buffer;
25017 display_string = object;
25018 }
25019 }
25020 else
25021 {
25022 buffer = object;
25023 display_string = Qnil;
25024 }
25025
25026 if (!NILP (mouse_face))
25027 {
25028 Lisp_Object before, after;
25029 Lisp_Object before_string, after_string;
25030
25031 if (NILP (overlay))
25032 {
25033 /* Handle the text property case. */
25034 before = Fprevious_single_property_change
25035 (make_number (pos + 1), Qmouse_face, buffer,
25036 Fmarker_position (w->start));
25037 after = Fnext_single_property_change
25038 (make_number (pos), Qmouse_face, buffer,
25039 make_number (BUF_Z (XBUFFER (buffer))
25040 - XFASTINT (w->window_end_pos)));
25041 before_string = after_string = Qnil;
25042 }
25043 else
25044 {
25045 /* Handle the overlay case. */
25046 before = Foverlay_start (overlay);
25047 after = Foverlay_end (overlay);
25048 before_string = Foverlay_get (overlay, Qbefore_string);
25049 after_string = Foverlay_get (overlay, Qafter_string);
25050
25051 if (!STRINGP (before_string)) before_string = Qnil;
25052 if (!STRINGP (after_string)) after_string = Qnil;
25053 }
25054
25055 mouse_face_from_buffer_pos (window, dpyinfo, pos,
25056 XFASTINT (before),
25057 XFASTINT (after),
25058 before_string, after_string,
25059 display_string);
25060 cursor = No_Cursor;
25061 }
25062 }
25063 }
25064
25065 check_help_echo:
25066
25067 /* Look for a `help-echo' property. */
25068 if (NILP (help_echo_string)) {
25069 Lisp_Object help, overlay;
25070
25071 /* Check overlays first. */
25072 help = overlay = Qnil;
25073 for (i = noverlays - 1; i >= 0 && NILP (help); --i)
25074 {
25075 overlay = overlay_vec[i];
25076 help = Foverlay_get (overlay, Qhelp_echo);
25077 }
25078
25079 if (!NILP (help))
25080 {
25081 help_echo_string = help;
25082 help_echo_window = window;
25083 help_echo_object = overlay;
25084 help_echo_pos = pos;
25085 }
25086 else
25087 {
25088 Lisp_Object object = glyph->object;
25089 int charpos = glyph->charpos;
25090
25091 /* Try text properties. */
25092 if (STRINGP (object)
25093 && charpos >= 0
25094 && charpos < SCHARS (object))
25095 {
25096 help = Fget_text_property (make_number (charpos),
25097 Qhelp_echo, object);
25098 if (NILP (help))
25099 {
25100 /* If the string itself doesn't specify a help-echo,
25101 see if the buffer text ``under'' it does. */
25102 struct glyph_row *r
25103 = MATRIX_ROW (w->current_matrix, vpos);
25104 int start = MATRIX_ROW_START_CHARPOS (r);
25105 EMACS_INT pos = string_buffer_position (w, object, start);
25106 if (pos > 0)
25107 {
25108 help = Fget_char_property (make_number (pos),
25109 Qhelp_echo, w->buffer);
25110 if (!NILP (help))
25111 {
25112 charpos = pos;
25113 object = w->buffer;
25114 }
25115 }
25116 }
25117 }
25118 else if (BUFFERP (object)
25119 && charpos >= BEGV
25120 && charpos < ZV)
25121 help = Fget_text_property (make_number (charpos), Qhelp_echo,
25122 object);
25123
25124 if (!NILP (help))
25125 {
25126 help_echo_string = help;
25127 help_echo_window = window;
25128 help_echo_object = object;
25129 help_echo_pos = charpos;
25130 }
25131 }
25132 }
25133
25134 /* Look for a `pointer' property. */
25135 if (NILP (pointer))
25136 {
25137 /* Check overlays first. */
25138 for (i = noverlays - 1; i >= 0 && NILP (pointer); --i)
25139 pointer = Foverlay_get (overlay_vec[i], Qpointer);
25140
25141 if (NILP (pointer))
25142 {
25143 Lisp_Object object = glyph->object;
25144 int charpos = glyph->charpos;
25145
25146 /* Try text properties. */
25147 if (STRINGP (object)
25148 && charpos >= 0
25149 && charpos < SCHARS (object))
25150 {
25151 pointer = Fget_text_property (make_number (charpos),
25152 Qpointer, object);
25153 if (NILP (pointer))
25154 {
25155 /* If the string itself doesn't specify a pointer,
25156 see if the buffer text ``under'' it does. */
25157 struct glyph_row *r
25158 = MATRIX_ROW (w->current_matrix, vpos);
25159 int start = MATRIX_ROW_START_CHARPOS (r);
25160 EMACS_INT pos = string_buffer_position (w, object,
25161 start);
25162 if (pos > 0)
25163 pointer = Fget_char_property (make_number (pos),
25164 Qpointer, w->buffer);
25165 }
25166 }
25167 else if (BUFFERP (object)
25168 && charpos >= BEGV
25169 && charpos < ZV)
25170 pointer = Fget_text_property (make_number (charpos),
25171 Qpointer, object);
25172 }
25173 }
25174
25175 BEGV = obegv;
25176 ZV = ozv;
25177 current_buffer = obuf;
25178 }
25179
25180 set_cursor:
25181
25182 define_frame_cursor1 (f, cursor, pointer);
25183 }
25184
25185
25186 /* EXPORT for RIF:
25187 Clear any mouse-face on window W. This function is part of the
25188 redisplay interface, and is called from try_window_id and similar
25189 functions to ensure the mouse-highlight is off. */
25190
25191 void
25192 x_clear_window_mouse_face (struct window *w)
25193 {
25194 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (w->frame));
25195 Lisp_Object window;
25196
25197 BLOCK_INPUT;
25198 XSETWINDOW (window, w);
25199 if (EQ (window, dpyinfo->mouse_face_window))
25200 clear_mouse_face (dpyinfo);
25201 UNBLOCK_INPUT;
25202 }
25203
25204
25205 /* EXPORT:
25206 Just discard the mouse face information for frame F, if any.
25207 This is used when the size of F is changed. */
25208
25209 void
25210 cancel_mouse_face (struct frame *f)
25211 {
25212 Lisp_Object window;
25213 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
25214
25215 window = dpyinfo->mouse_face_window;
25216 if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f)
25217 {
25218 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
25219 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
25220 dpyinfo->mouse_face_window = Qnil;
25221 }
25222 }
25223
25224
25225 #endif /* HAVE_WINDOW_SYSTEM */
25226
25227 \f
25228 /***********************************************************************
25229 Exposure Events
25230 ***********************************************************************/
25231
25232 #ifdef HAVE_WINDOW_SYSTEM
25233
25234 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
25235 which intersects rectangle R. R is in window-relative coordinates. */
25236
25237 static void
25238 expose_area (struct window *w, struct glyph_row *row, XRectangle *r,
25239 enum glyph_row_area area)
25240 {
25241 struct glyph *first = row->glyphs[area];
25242 struct glyph *end = row->glyphs[area] + row->used[area];
25243 struct glyph *last;
25244 int first_x, start_x, x;
25245
25246 if (area == TEXT_AREA && row->fill_line_p)
25247 /* If row extends face to end of line write the whole line. */
25248 draw_glyphs (w, 0, row, area,
25249 0, row->used[area],
25250 DRAW_NORMAL_TEXT, 0);
25251 else
25252 {
25253 /* Set START_X to the window-relative start position for drawing glyphs of
25254 AREA. The first glyph of the text area can be partially visible.
25255 The first glyphs of other areas cannot. */
25256 start_x = window_box_left_offset (w, area);
25257 x = start_x;
25258 if (area == TEXT_AREA)
25259 x += row->x;
25260
25261 /* Find the first glyph that must be redrawn. */
25262 while (first < end
25263 && x + first->pixel_width < r->x)
25264 {
25265 x += first->pixel_width;
25266 ++first;
25267 }
25268
25269 /* Find the last one. */
25270 last = first;
25271 first_x = x;
25272 while (last < end
25273 && x < r->x + r->width)
25274 {
25275 x += last->pixel_width;
25276 ++last;
25277 }
25278
25279 /* Repaint. */
25280 if (last > first)
25281 draw_glyphs (w, first_x - start_x, row, area,
25282 first - row->glyphs[area], last - row->glyphs[area],
25283 DRAW_NORMAL_TEXT, 0);
25284 }
25285 }
25286
25287
25288 /* Redraw the parts of the glyph row ROW on window W intersecting
25289 rectangle R. R is in window-relative coordinates. Value is
25290 non-zero if mouse-face was overwritten. */
25291
25292 static int
25293 expose_line (struct window *w, struct glyph_row *row, XRectangle *r)
25294 {
25295 xassert (row->enabled_p);
25296
25297 if (row->mode_line_p || w->pseudo_window_p)
25298 draw_glyphs (w, 0, row, TEXT_AREA,
25299 0, row->used[TEXT_AREA],
25300 DRAW_NORMAL_TEXT, 0);
25301 else
25302 {
25303 if (row->used[LEFT_MARGIN_AREA])
25304 expose_area (w, row, r, LEFT_MARGIN_AREA);
25305 if (row->used[TEXT_AREA])
25306 expose_area (w, row, r, TEXT_AREA);
25307 if (row->used[RIGHT_MARGIN_AREA])
25308 expose_area (w, row, r, RIGHT_MARGIN_AREA);
25309 draw_row_fringe_bitmaps (w, row);
25310 }
25311
25312 return row->mouse_face_p;
25313 }
25314
25315
25316 /* Redraw those parts of glyphs rows during expose event handling that
25317 overlap other rows. Redrawing of an exposed line writes over parts
25318 of lines overlapping that exposed line; this function fixes that.
25319
25320 W is the window being exposed. FIRST_OVERLAPPING_ROW is the first
25321 row in W's current matrix that is exposed and overlaps other rows.
25322 LAST_OVERLAPPING_ROW is the last such row. */
25323
25324 static void
25325 expose_overlaps (struct window *w,
25326 struct glyph_row *first_overlapping_row,
25327 struct glyph_row *last_overlapping_row,
25328 XRectangle *r)
25329 {
25330 struct glyph_row *row;
25331
25332 for (row = first_overlapping_row; row <= last_overlapping_row; ++row)
25333 if (row->overlapping_p)
25334 {
25335 xassert (row->enabled_p && !row->mode_line_p);
25336
25337 row->clip = r;
25338 if (row->used[LEFT_MARGIN_AREA])
25339 x_fix_overlapping_area (w, row, LEFT_MARGIN_AREA, OVERLAPS_BOTH);
25340
25341 if (row->used[TEXT_AREA])
25342 x_fix_overlapping_area (w, row, TEXT_AREA, OVERLAPS_BOTH);
25343
25344 if (row->used[RIGHT_MARGIN_AREA])
25345 x_fix_overlapping_area (w, row, RIGHT_MARGIN_AREA, OVERLAPS_BOTH);
25346 row->clip = NULL;
25347 }
25348 }
25349
25350
25351 /* Return non-zero if W's cursor intersects rectangle R. */
25352
25353 static int
25354 phys_cursor_in_rect_p (struct window *w, XRectangle *r)
25355 {
25356 XRectangle cr, result;
25357 struct glyph *cursor_glyph;
25358 struct glyph_row *row;
25359
25360 if (w->phys_cursor.vpos >= 0
25361 && w->phys_cursor.vpos < w->current_matrix->nrows
25362 && (row = MATRIX_ROW (w->current_matrix, w->phys_cursor.vpos),
25363 row->enabled_p)
25364 && row->cursor_in_fringe_p)
25365 {
25366 /* Cursor is in the fringe. */
25367 cr.x = window_box_right_offset (w,
25368 (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
25369 ? RIGHT_MARGIN_AREA
25370 : TEXT_AREA));
25371 cr.y = row->y;
25372 cr.width = WINDOW_RIGHT_FRINGE_WIDTH (w);
25373 cr.height = row->height;
25374 return x_intersect_rectangles (&cr, r, &result);
25375 }
25376
25377 cursor_glyph = get_phys_cursor_glyph (w);
25378 if (cursor_glyph)
25379 {
25380 /* r is relative to W's box, but w->phys_cursor.x is relative
25381 to left edge of W's TEXT area. Adjust it. */
25382 cr.x = window_box_left_offset (w, TEXT_AREA) + w->phys_cursor.x;
25383 cr.y = w->phys_cursor.y;
25384 cr.width = cursor_glyph->pixel_width;
25385 cr.height = w->phys_cursor_height;
25386 /* ++KFS: W32 version used W32-specific IntersectRect here, but
25387 I assume the effect is the same -- and this is portable. */
25388 return x_intersect_rectangles (&cr, r, &result);
25389 }
25390 /* If we don't understand the format, pretend we're not in the hot-spot. */
25391 return 0;
25392 }
25393
25394
25395 /* EXPORT:
25396 Draw a vertical window border to the right of window W if W doesn't
25397 have vertical scroll bars. */
25398
25399 void
25400 x_draw_vertical_border (struct window *w)
25401 {
25402 struct frame *f = XFRAME (WINDOW_FRAME (w));
25403
25404 /* We could do better, if we knew what type of scroll-bar the adjacent
25405 windows (on either side) have... But we don't :-(
25406 However, I think this works ok. ++KFS 2003-04-25 */
25407
25408 /* Redraw borders between horizontally adjacent windows. Don't
25409 do it for frames with vertical scroll bars because either the
25410 right scroll bar of a window, or the left scroll bar of its
25411 neighbor will suffice as a border. */
25412 if (FRAME_HAS_VERTICAL_SCROLL_BARS (XFRAME (w->frame)))
25413 return;
25414
25415 if (!WINDOW_RIGHTMOST_P (w)
25416 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w))
25417 {
25418 int x0, x1, y0, y1;
25419
25420 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
25421 y1 -= 1;
25422
25423 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
25424 x1 -= 1;
25425
25426 FRAME_RIF (f)->draw_vertical_window_border (w, x1, y0, y1);
25427 }
25428 else if (!WINDOW_LEFTMOST_P (w)
25429 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
25430 {
25431 int x0, x1, y0, y1;
25432
25433 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
25434 y1 -= 1;
25435
25436 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
25437 x0 -= 1;
25438
25439 FRAME_RIF (f)->draw_vertical_window_border (w, x0, y0, y1);
25440 }
25441 }
25442
25443
25444 /* Redraw the part of window W intersection rectangle FR. Pixel
25445 coordinates in FR are frame-relative. Call this function with
25446 input blocked. Value is non-zero if the exposure overwrites
25447 mouse-face. */
25448
25449 static int
25450 expose_window (struct window *w, XRectangle *fr)
25451 {
25452 struct frame *f = XFRAME (w->frame);
25453 XRectangle wr, r;
25454 int mouse_face_overwritten_p = 0;
25455
25456 /* If window is not yet fully initialized, do nothing. This can
25457 happen when toolkit scroll bars are used and a window is split.
25458 Reconfiguring the scroll bar will generate an expose for a newly
25459 created window. */
25460 if (w->current_matrix == NULL)
25461 return 0;
25462
25463 /* When we're currently updating the window, display and current
25464 matrix usually don't agree. Arrange for a thorough display
25465 later. */
25466 if (w == updated_window)
25467 {
25468 SET_FRAME_GARBAGED (f);
25469 return 0;
25470 }
25471
25472 /* Frame-relative pixel rectangle of W. */
25473 wr.x = WINDOW_LEFT_EDGE_X (w);
25474 wr.y = WINDOW_TOP_EDGE_Y (w);
25475 wr.width = WINDOW_TOTAL_WIDTH (w);
25476 wr.height = WINDOW_TOTAL_HEIGHT (w);
25477
25478 if (x_intersect_rectangles (fr, &wr, &r))
25479 {
25480 int yb = window_text_bottom_y (w);
25481 struct glyph_row *row;
25482 int cursor_cleared_p;
25483 struct glyph_row *first_overlapping_row, *last_overlapping_row;
25484
25485 TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n",
25486 r.x, r.y, r.width, r.height));
25487
25488 /* Convert to window coordinates. */
25489 r.x -= WINDOW_LEFT_EDGE_X (w);
25490 r.y -= WINDOW_TOP_EDGE_Y (w);
25491
25492 /* Turn off the cursor. */
25493 if (!w->pseudo_window_p
25494 && phys_cursor_in_rect_p (w, &r))
25495 {
25496 x_clear_cursor (w);
25497 cursor_cleared_p = 1;
25498 }
25499 else
25500 cursor_cleared_p = 0;
25501
25502 /* Update lines intersecting rectangle R. */
25503 first_overlapping_row = last_overlapping_row = NULL;
25504 for (row = w->current_matrix->rows;
25505 row->enabled_p;
25506 ++row)
25507 {
25508 int y0 = row->y;
25509 int y1 = MATRIX_ROW_BOTTOM_Y (row);
25510
25511 if ((y0 >= r.y && y0 < r.y + r.height)
25512 || (y1 > r.y && y1 < r.y + r.height)
25513 || (r.y >= y0 && r.y < y1)
25514 || (r.y + r.height > y0 && r.y + r.height < y1))
25515 {
25516 /* A header line may be overlapping, but there is no need
25517 to fix overlapping areas for them. KFS 2005-02-12 */
25518 if (row->overlapping_p && !row->mode_line_p)
25519 {
25520 if (first_overlapping_row == NULL)
25521 first_overlapping_row = row;
25522 last_overlapping_row = row;
25523 }
25524
25525 row->clip = fr;
25526 if (expose_line (w, row, &r))
25527 mouse_face_overwritten_p = 1;
25528 row->clip = NULL;
25529 }
25530 else if (row->overlapping_p)
25531 {
25532 /* We must redraw a row overlapping the exposed area. */
25533 if (y0 < r.y
25534 ? y0 + row->phys_height > r.y
25535 : y0 + row->ascent - row->phys_ascent < r.y +r.height)
25536 {
25537 if (first_overlapping_row == NULL)
25538 first_overlapping_row = row;
25539 last_overlapping_row = row;
25540 }
25541 }
25542
25543 if (y1 >= yb)
25544 break;
25545 }
25546
25547 /* Display the mode line if there is one. */
25548 if (WINDOW_WANTS_MODELINE_P (w)
25549 && (row = MATRIX_MODE_LINE_ROW (w->current_matrix),
25550 row->enabled_p)
25551 && row->y < r.y + r.height)
25552 {
25553 if (expose_line (w, row, &r))
25554 mouse_face_overwritten_p = 1;
25555 }
25556
25557 if (!w->pseudo_window_p)
25558 {
25559 /* Fix the display of overlapping rows. */
25560 if (first_overlapping_row)
25561 expose_overlaps (w, first_overlapping_row, last_overlapping_row,
25562 fr);
25563
25564 /* Draw border between windows. */
25565 x_draw_vertical_border (w);
25566
25567 /* Turn the cursor on again. */
25568 if (cursor_cleared_p)
25569 update_window_cursor (w, 1);
25570 }
25571 }
25572
25573 return mouse_face_overwritten_p;
25574 }
25575
25576
25577
25578 /* Redraw (parts) of all windows in the window tree rooted at W that
25579 intersect R. R contains frame pixel coordinates. Value is
25580 non-zero if the exposure overwrites mouse-face. */
25581
25582 static int
25583 expose_window_tree (struct window *w, XRectangle *r)
25584 {
25585 struct frame *f = XFRAME (w->frame);
25586 int mouse_face_overwritten_p = 0;
25587
25588 while (w && !FRAME_GARBAGED_P (f))
25589 {
25590 if (!NILP (w->hchild))
25591 mouse_face_overwritten_p
25592 |= expose_window_tree (XWINDOW (w->hchild), r);
25593 else if (!NILP (w->vchild))
25594 mouse_face_overwritten_p
25595 |= expose_window_tree (XWINDOW (w->vchild), r);
25596 else
25597 mouse_face_overwritten_p |= expose_window (w, r);
25598
25599 w = NILP (w->next) ? NULL : XWINDOW (w->next);
25600 }
25601
25602 return mouse_face_overwritten_p;
25603 }
25604
25605
25606 /* EXPORT:
25607 Redisplay an exposed area of frame F. X and Y are the upper-left
25608 corner of the exposed rectangle. W and H are width and height of
25609 the exposed area. All are pixel values. W or H zero means redraw
25610 the entire frame. */
25611
25612 void
25613 expose_frame (struct frame *f, int x, int y, int w, int h)
25614 {
25615 XRectangle r;
25616 int mouse_face_overwritten_p = 0;
25617
25618 TRACE ((stderr, "expose_frame "));
25619
25620 /* No need to redraw if frame will be redrawn soon. */
25621 if (FRAME_GARBAGED_P (f))
25622 {
25623 TRACE ((stderr, " garbaged\n"));
25624 return;
25625 }
25626
25627 /* If basic faces haven't been realized yet, there is no point in
25628 trying to redraw anything. This can happen when we get an expose
25629 event while Emacs is starting, e.g. by moving another window. */
25630 if (FRAME_FACE_CACHE (f) == NULL
25631 || FRAME_FACE_CACHE (f)->used < BASIC_FACE_ID_SENTINEL)
25632 {
25633 TRACE ((stderr, " no faces\n"));
25634 return;
25635 }
25636
25637 if (w == 0 || h == 0)
25638 {
25639 r.x = r.y = 0;
25640 r.width = FRAME_COLUMN_WIDTH (f) * FRAME_COLS (f);
25641 r.height = FRAME_LINE_HEIGHT (f) * FRAME_LINES (f);
25642 }
25643 else
25644 {
25645 r.x = x;
25646 r.y = y;
25647 r.width = w;
25648 r.height = h;
25649 }
25650
25651 TRACE ((stderr, "(%d, %d, %d, %d)\n", r.x, r.y, r.width, r.height));
25652 mouse_face_overwritten_p = expose_window_tree (XWINDOW (f->root_window), &r);
25653
25654 if (WINDOWP (f->tool_bar_window))
25655 mouse_face_overwritten_p
25656 |= expose_window (XWINDOW (f->tool_bar_window), &r);
25657
25658 #ifdef HAVE_X_WINDOWS
25659 #ifndef MSDOS
25660 #ifndef USE_X_TOOLKIT
25661 if (WINDOWP (f->menu_bar_window))
25662 mouse_face_overwritten_p
25663 |= expose_window (XWINDOW (f->menu_bar_window), &r);
25664 #endif /* not USE_X_TOOLKIT */
25665 #endif
25666 #endif
25667
25668 /* Some window managers support a focus-follows-mouse style with
25669 delayed raising of frames. Imagine a partially obscured frame,
25670 and moving the mouse into partially obscured mouse-face on that
25671 frame. The visible part of the mouse-face will be highlighted,
25672 then the WM raises the obscured frame. With at least one WM, KDE
25673 2.1, Emacs is not getting any event for the raising of the frame
25674 (even tried with SubstructureRedirectMask), only Expose events.
25675 These expose events will draw text normally, i.e. not
25676 highlighted. Which means we must redo the highlight here.
25677 Subsume it under ``we love X''. --gerd 2001-08-15 */
25678 /* Included in Windows version because Windows most likely does not
25679 do the right thing if any third party tool offers
25680 focus-follows-mouse with delayed raise. --jason 2001-10-12 */
25681 if (mouse_face_overwritten_p && !FRAME_GARBAGED_P (f))
25682 {
25683 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
25684 if (f == dpyinfo->mouse_face_mouse_frame)
25685 {
25686 int x = dpyinfo->mouse_face_mouse_x;
25687 int y = dpyinfo->mouse_face_mouse_y;
25688 clear_mouse_face (dpyinfo);
25689 note_mouse_highlight (f, x, y);
25690 }
25691 }
25692 }
25693
25694
25695 /* EXPORT:
25696 Determine the intersection of two rectangles R1 and R2. Return
25697 the intersection in *RESULT. Value is non-zero if RESULT is not
25698 empty. */
25699
25700 int
25701 x_intersect_rectangles (XRectangle *r1, XRectangle *r2, XRectangle *result)
25702 {
25703 XRectangle *left, *right;
25704 XRectangle *upper, *lower;
25705 int intersection_p = 0;
25706
25707 /* Rearrange so that R1 is the left-most rectangle. */
25708 if (r1->x < r2->x)
25709 left = r1, right = r2;
25710 else
25711 left = r2, right = r1;
25712
25713 /* X0 of the intersection is right.x0, if this is inside R1,
25714 otherwise there is no intersection. */
25715 if (right->x <= left->x + left->width)
25716 {
25717 result->x = right->x;
25718
25719 /* The right end of the intersection is the minimum of the
25720 the right ends of left and right. */
25721 result->width = (min (left->x + left->width, right->x + right->width)
25722 - result->x);
25723
25724 /* Same game for Y. */
25725 if (r1->y < r2->y)
25726 upper = r1, lower = r2;
25727 else
25728 upper = r2, lower = r1;
25729
25730 /* The upper end of the intersection is lower.y0, if this is inside
25731 of upper. Otherwise, there is no intersection. */
25732 if (lower->y <= upper->y + upper->height)
25733 {
25734 result->y = lower->y;
25735
25736 /* The lower end of the intersection is the minimum of the lower
25737 ends of upper and lower. */
25738 result->height = (min (lower->y + lower->height,
25739 upper->y + upper->height)
25740 - result->y);
25741 intersection_p = 1;
25742 }
25743 }
25744
25745 return intersection_p;
25746 }
25747
25748 #endif /* HAVE_WINDOW_SYSTEM */
25749
25750 \f
25751 /***********************************************************************
25752 Initialization
25753 ***********************************************************************/
25754
25755 void
25756 syms_of_xdisp (void)
25757 {
25758 Vwith_echo_area_save_vector = Qnil;
25759 staticpro (&Vwith_echo_area_save_vector);
25760
25761 Vmessage_stack = Qnil;
25762 staticpro (&Vmessage_stack);
25763
25764 Qinhibit_redisplay = intern_c_string ("inhibit-redisplay");
25765 staticpro (&Qinhibit_redisplay);
25766
25767 message_dolog_marker1 = Fmake_marker ();
25768 staticpro (&message_dolog_marker1);
25769 message_dolog_marker2 = Fmake_marker ();
25770 staticpro (&message_dolog_marker2);
25771 message_dolog_marker3 = Fmake_marker ();
25772 staticpro (&message_dolog_marker3);
25773
25774 #if GLYPH_DEBUG
25775 defsubr (&Sdump_frame_glyph_matrix);
25776 defsubr (&Sdump_glyph_matrix);
25777 defsubr (&Sdump_glyph_row);
25778 defsubr (&Sdump_tool_bar_row);
25779 defsubr (&Strace_redisplay);
25780 defsubr (&Strace_to_stderr);
25781 #endif
25782 #ifdef HAVE_WINDOW_SYSTEM
25783 defsubr (&Stool_bar_lines_needed);
25784 defsubr (&Slookup_image_map);
25785 #endif
25786 defsubr (&Sformat_mode_line);
25787 defsubr (&Sinvisible_p);
25788 defsubr (&Scurrent_bidi_paragraph_direction);
25789
25790 staticpro (&Qmenu_bar_update_hook);
25791 Qmenu_bar_update_hook = intern_c_string ("menu-bar-update-hook");
25792
25793 staticpro (&Qoverriding_terminal_local_map);
25794 Qoverriding_terminal_local_map = intern_c_string ("overriding-terminal-local-map");
25795
25796 staticpro (&Qoverriding_local_map);
25797 Qoverriding_local_map = intern_c_string ("overriding-local-map");
25798
25799 staticpro (&Qwindow_scroll_functions);
25800 Qwindow_scroll_functions = intern_c_string ("window-scroll-functions");
25801
25802 staticpro (&Qwindow_text_change_functions);
25803 Qwindow_text_change_functions = intern_c_string ("window-text-change-functions");
25804
25805 staticpro (&Qredisplay_end_trigger_functions);
25806 Qredisplay_end_trigger_functions = intern_c_string ("redisplay-end-trigger-functions");
25807
25808 staticpro (&Qinhibit_point_motion_hooks);
25809 Qinhibit_point_motion_hooks = intern_c_string ("inhibit-point-motion-hooks");
25810
25811 Qeval = intern_c_string ("eval");
25812 staticpro (&Qeval);
25813
25814 QCdata = intern_c_string (":data");
25815 staticpro (&QCdata);
25816 Qdisplay = intern_c_string ("display");
25817 staticpro (&Qdisplay);
25818 Qspace_width = intern_c_string ("space-width");
25819 staticpro (&Qspace_width);
25820 Qraise = intern_c_string ("raise");
25821 staticpro (&Qraise);
25822 Qslice = intern_c_string ("slice");
25823 staticpro (&Qslice);
25824 Qspace = intern_c_string ("space");
25825 staticpro (&Qspace);
25826 Qmargin = intern_c_string ("margin");
25827 staticpro (&Qmargin);
25828 Qpointer = intern_c_string ("pointer");
25829 staticpro (&Qpointer);
25830 Qleft_margin = intern_c_string ("left-margin");
25831 staticpro (&Qleft_margin);
25832 Qright_margin = intern_c_string ("right-margin");
25833 staticpro (&Qright_margin);
25834 Qcenter = intern_c_string ("center");
25835 staticpro (&Qcenter);
25836 Qline_height = intern_c_string ("line-height");
25837 staticpro (&Qline_height);
25838 QCalign_to = intern_c_string (":align-to");
25839 staticpro (&QCalign_to);
25840 QCrelative_width = intern_c_string (":relative-width");
25841 staticpro (&QCrelative_width);
25842 QCrelative_height = intern_c_string (":relative-height");
25843 staticpro (&QCrelative_height);
25844 QCeval = intern_c_string (":eval");
25845 staticpro (&QCeval);
25846 QCpropertize = intern_c_string (":propertize");
25847 staticpro (&QCpropertize);
25848 QCfile = intern_c_string (":file");
25849 staticpro (&QCfile);
25850 Qfontified = intern_c_string ("fontified");
25851 staticpro (&Qfontified);
25852 Qfontification_functions = intern_c_string ("fontification-functions");
25853 staticpro (&Qfontification_functions);
25854 Qtrailing_whitespace = intern_c_string ("trailing-whitespace");
25855 staticpro (&Qtrailing_whitespace);
25856 Qescape_glyph = intern_c_string ("escape-glyph");
25857 staticpro (&Qescape_glyph);
25858 Qnobreak_space = intern_c_string ("nobreak-space");
25859 staticpro (&Qnobreak_space);
25860 Qimage = intern_c_string ("image");
25861 staticpro (&Qimage);
25862 Qtext = intern_c_string ("text");
25863 staticpro (&Qtext);
25864 Qboth = intern_c_string ("both");
25865 staticpro (&Qboth);
25866 Qboth_horiz = intern_c_string ("both-horiz");
25867 staticpro (&Qboth_horiz);
25868 Qtext_image_horiz = intern_c_string ("text-image-horiz");
25869 staticpro (&Qtext_image_horiz);
25870 QCmap = intern_c_string (":map");
25871 staticpro (&QCmap);
25872 QCpointer = intern_c_string (":pointer");
25873 staticpro (&QCpointer);
25874 Qrect = intern_c_string ("rect");
25875 staticpro (&Qrect);
25876 Qcircle = intern_c_string ("circle");
25877 staticpro (&Qcircle);
25878 Qpoly = intern_c_string ("poly");
25879 staticpro (&Qpoly);
25880 Qmessage_truncate_lines = intern_c_string ("message-truncate-lines");
25881 staticpro (&Qmessage_truncate_lines);
25882 Qgrow_only = intern_c_string ("grow-only");
25883 staticpro (&Qgrow_only);
25884 Qinhibit_menubar_update = intern_c_string ("inhibit-menubar-update");
25885 staticpro (&Qinhibit_menubar_update);
25886 Qinhibit_eval_during_redisplay = intern_c_string ("inhibit-eval-during-redisplay");
25887 staticpro (&Qinhibit_eval_during_redisplay);
25888 Qposition = intern_c_string ("position");
25889 staticpro (&Qposition);
25890 Qbuffer_position = intern_c_string ("buffer-position");
25891 staticpro (&Qbuffer_position);
25892 Qobject = intern_c_string ("object");
25893 staticpro (&Qobject);
25894 Qbar = intern_c_string ("bar");
25895 staticpro (&Qbar);
25896 Qhbar = intern_c_string ("hbar");
25897 staticpro (&Qhbar);
25898 Qbox = intern_c_string ("box");
25899 staticpro (&Qbox);
25900 Qhollow = intern_c_string ("hollow");
25901 staticpro (&Qhollow);
25902 Qhand = intern_c_string ("hand");
25903 staticpro (&Qhand);
25904 Qarrow = intern_c_string ("arrow");
25905 staticpro (&Qarrow);
25906 Qtext = intern_c_string ("text");
25907 staticpro (&Qtext);
25908 Qrisky_local_variable = intern_c_string ("risky-local-variable");
25909 staticpro (&Qrisky_local_variable);
25910 Qinhibit_free_realized_faces = intern_c_string ("inhibit-free-realized-faces");
25911 staticpro (&Qinhibit_free_realized_faces);
25912
25913 list_of_error = Fcons (Fcons (intern_c_string ("error"),
25914 Fcons (intern_c_string ("void-variable"), Qnil)),
25915 Qnil);
25916 staticpro (&list_of_error);
25917
25918 Qlast_arrow_position = intern_c_string ("last-arrow-position");
25919 staticpro (&Qlast_arrow_position);
25920 Qlast_arrow_string = intern_c_string ("last-arrow-string");
25921 staticpro (&Qlast_arrow_string);
25922
25923 Qoverlay_arrow_string = intern_c_string ("overlay-arrow-string");
25924 staticpro (&Qoverlay_arrow_string);
25925 Qoverlay_arrow_bitmap = intern_c_string ("overlay-arrow-bitmap");
25926 staticpro (&Qoverlay_arrow_bitmap);
25927
25928 echo_buffer[0] = echo_buffer[1] = Qnil;
25929 staticpro (&echo_buffer[0]);
25930 staticpro (&echo_buffer[1]);
25931
25932 echo_area_buffer[0] = echo_area_buffer[1] = Qnil;
25933 staticpro (&echo_area_buffer[0]);
25934 staticpro (&echo_area_buffer[1]);
25935
25936 Vmessages_buffer_name = make_pure_c_string ("*Messages*");
25937 staticpro (&Vmessages_buffer_name);
25938
25939 mode_line_proptrans_alist = Qnil;
25940 staticpro (&mode_line_proptrans_alist);
25941 mode_line_string_list = Qnil;
25942 staticpro (&mode_line_string_list);
25943 mode_line_string_face = Qnil;
25944 staticpro (&mode_line_string_face);
25945 mode_line_string_face_prop = Qnil;
25946 staticpro (&mode_line_string_face_prop);
25947 Vmode_line_unwind_vector = Qnil;
25948 staticpro (&Vmode_line_unwind_vector);
25949
25950 help_echo_string = Qnil;
25951 staticpro (&help_echo_string);
25952 help_echo_object = Qnil;
25953 staticpro (&help_echo_object);
25954 help_echo_window = Qnil;
25955 staticpro (&help_echo_window);
25956 previous_help_echo_string = Qnil;
25957 staticpro (&previous_help_echo_string);
25958 help_echo_pos = -1;
25959
25960 Qright_to_left = intern_c_string ("right-to-left");
25961 staticpro (&Qright_to_left);
25962 Qleft_to_right = intern_c_string ("left-to-right");
25963 staticpro (&Qleft_to_right);
25964
25965 #ifdef HAVE_WINDOW_SYSTEM
25966 DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p,
25967 doc: /* *Non-nil means draw block cursor as wide as the glyph under it.
25968 For example, if a block cursor is over a tab, it will be drawn as
25969 wide as that tab on the display. */);
25970 x_stretch_cursor_p = 0;
25971 #endif
25972
25973 DEFVAR_LISP ("show-trailing-whitespace", &Vshow_trailing_whitespace,
25974 doc: /* *Non-nil means highlight trailing whitespace.
25975 The face used for trailing whitespace is `trailing-whitespace'. */);
25976 Vshow_trailing_whitespace = Qnil;
25977
25978 DEFVAR_LISP ("nobreak-char-display", &Vnobreak_char_display,
25979 doc: /* *Control highlighting of nobreak space and soft hyphen.
25980 A value of t means highlight the character itself (for nobreak space,
25981 use face `nobreak-space').
25982 A value of nil means no highlighting.
25983 Other values mean display the escape glyph followed by an ordinary
25984 space or ordinary hyphen. */);
25985 Vnobreak_char_display = Qt;
25986
25987 DEFVAR_LISP ("void-text-area-pointer", &Vvoid_text_area_pointer,
25988 doc: /* *The pointer shape to show in void text areas.
25989 A value of nil means to show the text pointer. Other options are `arrow',
25990 `text', `hand', `vdrag', `hdrag', `modeline', and `hourglass'. */);
25991 Vvoid_text_area_pointer = Qarrow;
25992
25993 DEFVAR_LISP ("inhibit-redisplay", &Vinhibit_redisplay,
25994 doc: /* Non-nil means don't actually do any redisplay.
25995 This is used for internal purposes. */);
25996 Vinhibit_redisplay = Qnil;
25997
25998 DEFVAR_LISP ("global-mode-string", &Vglobal_mode_string,
25999 doc: /* String (or mode line construct) included (normally) in `mode-line-format'. */);
26000 Vglobal_mode_string = Qnil;
26001
26002 DEFVAR_LISP ("overlay-arrow-position", &Voverlay_arrow_position,
26003 doc: /* Marker for where to display an arrow on top of the buffer text.
26004 This must be the beginning of a line in order to work.
26005 See also `overlay-arrow-string'. */);
26006 Voverlay_arrow_position = Qnil;
26007
26008 DEFVAR_LISP ("overlay-arrow-string", &Voverlay_arrow_string,
26009 doc: /* String to display as an arrow in non-window frames.
26010 See also `overlay-arrow-position'. */);
26011 Voverlay_arrow_string = make_pure_c_string ("=>");
26012
26013 DEFVAR_LISP ("overlay-arrow-variable-list", &Voverlay_arrow_variable_list,
26014 doc: /* List of variables (symbols) which hold markers for overlay arrows.
26015 The symbols on this list are examined during redisplay to determine
26016 where to display overlay arrows. */);
26017 Voverlay_arrow_variable_list
26018 = Fcons (intern_c_string ("overlay-arrow-position"), Qnil);
26019
26020 DEFVAR_INT ("scroll-step", &scroll_step,
26021 doc: /* *The number of lines to try scrolling a window by when point moves out.
26022 If that fails to bring point back on frame, point is centered instead.
26023 If this is zero, point is always centered after it moves off frame.
26024 If you want scrolling to always be a line at a time, you should set
26025 `scroll-conservatively' to a large value rather than set this to 1. */);
26026
26027 DEFVAR_INT ("scroll-conservatively", &scroll_conservatively,
26028 doc: /* *Scroll up to this many lines, to bring point back on screen.
26029 If point moves off-screen, redisplay will scroll by up to
26030 `scroll-conservatively' lines in order to bring point just barely
26031 onto the screen again. If that cannot be done, then redisplay
26032 recenters point as usual.
26033
26034 A value of zero means always recenter point if it moves off screen. */);
26035 scroll_conservatively = 0;
26036
26037 DEFVAR_INT ("scroll-margin", &scroll_margin,
26038 doc: /* *Number of lines of margin at the top and bottom of a window.
26039 Recenter the window whenever point gets within this many lines
26040 of the top or bottom of the window. */);
26041 scroll_margin = 0;
26042
26043 DEFVAR_LISP ("display-pixels-per-inch", &Vdisplay_pixels_per_inch,
26044 doc: /* Pixels per inch value for non-window system displays.
26045 Value is a number or a cons (WIDTH-DPI . HEIGHT-DPI). */);
26046 Vdisplay_pixels_per_inch = make_float (72.0);
26047
26048 #if GLYPH_DEBUG
26049 DEFVAR_INT ("debug-end-pos", &debug_end_pos, doc: /* Don't ask. */);
26050 #endif
26051
26052 DEFVAR_LISP ("truncate-partial-width-windows",
26053 &Vtruncate_partial_width_windows,
26054 doc: /* Non-nil means truncate lines in windows narrower than the frame.
26055 For an integer value, truncate lines in each window narrower than the
26056 full frame width, provided the window width is less than that integer;
26057 otherwise, respect the value of `truncate-lines'.
26058
26059 For any other non-nil value, truncate lines in all windows that do
26060 not span the full frame width.
26061
26062 A value of nil means to respect the value of `truncate-lines'.
26063
26064 If `word-wrap' is enabled, you might want to reduce this. */);
26065 Vtruncate_partial_width_windows = make_number (50);
26066
26067 DEFVAR_BOOL ("mode-line-inverse-video", &mode_line_inverse_video,
26068 doc: /* When nil, display the mode-line/header-line/menu-bar in the default face.
26069 Any other value means to use the appropriate face, `mode-line',
26070 `header-line', or `menu' respectively. */);
26071 mode_line_inverse_video = 1;
26072
26073 DEFVAR_LISP ("line-number-display-limit", &Vline_number_display_limit,
26074 doc: /* *Maximum buffer size for which line number should be displayed.
26075 If the buffer is bigger than this, the line number does not appear
26076 in the mode line. A value of nil means no limit. */);
26077 Vline_number_display_limit = Qnil;
26078
26079 DEFVAR_INT ("line-number-display-limit-width",
26080 &line_number_display_limit_width,
26081 doc: /* *Maximum line width (in characters) for line number display.
26082 If the average length of the lines near point is bigger than this, then the
26083 line number may be omitted from the mode line. */);
26084 line_number_display_limit_width = 200;
26085
26086 DEFVAR_BOOL ("highlight-nonselected-windows", &highlight_nonselected_windows,
26087 doc: /* *Non-nil means highlight region even in nonselected windows. */);
26088 highlight_nonselected_windows = 0;
26089
26090 DEFVAR_BOOL ("multiple-frames", &multiple_frames,
26091 doc: /* Non-nil if more than one frame is visible on this display.
26092 Minibuffer-only frames don't count, but iconified frames do.
26093 This variable is not guaranteed to be accurate except while processing
26094 `frame-title-format' and `icon-title-format'. */);
26095
26096 DEFVAR_LISP ("frame-title-format", &Vframe_title_format,
26097 doc: /* Template for displaying the title bar of visible frames.
26098 \(Assuming the window manager supports this feature.)
26099
26100 This variable has the same structure as `mode-line-format', except that
26101 the %c and %l constructs are ignored. It is used only on frames for
26102 which no explicit name has been set \(see `modify-frame-parameters'). */);
26103
26104 DEFVAR_LISP ("icon-title-format", &Vicon_title_format,
26105 doc: /* Template for displaying the title bar of an iconified frame.
26106 \(Assuming the window manager supports this feature.)
26107 This variable has the same structure as `mode-line-format' (which see),
26108 and is used only on frames for which no explicit name has been set
26109 \(see `modify-frame-parameters'). */);
26110 Vicon_title_format
26111 = Vframe_title_format
26112 = pure_cons (intern_c_string ("multiple-frames"),
26113 pure_cons (make_pure_c_string ("%b"),
26114 pure_cons (pure_cons (empty_unibyte_string,
26115 pure_cons (intern_c_string ("invocation-name"),
26116 pure_cons (make_pure_c_string ("@"),
26117 pure_cons (intern_c_string ("system-name"),
26118 Qnil)))),
26119 Qnil)));
26120
26121 DEFVAR_LISP ("message-log-max", &Vmessage_log_max,
26122 doc: /* Maximum number of lines to keep in the message log buffer.
26123 If nil, disable message logging. If t, log messages but don't truncate
26124 the buffer when it becomes large. */);
26125 Vmessage_log_max = make_number (100);
26126
26127 DEFVAR_LISP ("window-size-change-functions", &Vwindow_size_change_functions,
26128 doc: /* Functions called before redisplay, if window sizes have changed.
26129 The value should be a list of functions that take one argument.
26130 Just before redisplay, for each frame, if any of its windows have changed
26131 size since the last redisplay, or have been split or deleted,
26132 all the functions in the list are called, with the frame as argument. */);
26133 Vwindow_size_change_functions = Qnil;
26134
26135 DEFVAR_LISP ("window-scroll-functions", &Vwindow_scroll_functions,
26136 doc: /* List of functions to call before redisplaying a window with scrolling.
26137 Each function is called with two arguments, the window and its new
26138 display-start position. Note that these functions are also called by
26139 `set-window-buffer'. Also note that the value of `window-end' is not
26140 valid when these functions are called. */);
26141 Vwindow_scroll_functions = Qnil;
26142
26143 DEFVAR_LISP ("window-text-change-functions",
26144 &Vwindow_text_change_functions,
26145 doc: /* Functions to call in redisplay when text in the window might change. */);
26146 Vwindow_text_change_functions = Qnil;
26147
26148 DEFVAR_LISP ("redisplay-end-trigger-functions", &Vredisplay_end_trigger_functions,
26149 doc: /* Functions called when redisplay of a window reaches the end trigger.
26150 Each function is called with two arguments, the window and the end trigger value.
26151 See `set-window-redisplay-end-trigger'. */);
26152 Vredisplay_end_trigger_functions = Qnil;
26153
26154 DEFVAR_LISP ("mouse-autoselect-window", &Vmouse_autoselect_window,
26155 doc: /* *Non-nil means autoselect window with mouse pointer.
26156 If nil, do not autoselect windows.
26157 A positive number means delay autoselection by that many seconds: a
26158 window is autoselected only after the mouse has remained in that
26159 window for the duration of the delay.
26160 A negative number has a similar effect, but causes windows to be
26161 autoselected only after the mouse has stopped moving. \(Because of
26162 the way Emacs compares mouse events, you will occasionally wait twice
26163 that time before the window gets selected.\)
26164 Any other value means to autoselect window instantaneously when the
26165 mouse pointer enters it.
26166
26167 Autoselection selects the minibuffer only if it is active, and never
26168 unselects the minibuffer if it is active.
26169
26170 When customizing this variable make sure that the actual value of
26171 `focus-follows-mouse' matches the behavior of your window manager. */);
26172 Vmouse_autoselect_window = Qnil;
26173
26174 DEFVAR_LISP ("auto-resize-tool-bars", &Vauto_resize_tool_bars,
26175 doc: /* *Non-nil means automatically resize tool-bars.
26176 This dynamically changes the tool-bar's height to the minimum height
26177 that is needed to make all tool-bar items visible.
26178 If value is `grow-only', the tool-bar's height is only increased
26179 automatically; to decrease the tool-bar height, use \\[recenter]. */);
26180 Vauto_resize_tool_bars = Qt;
26181
26182 DEFVAR_BOOL ("auto-raise-tool-bar-buttons", &auto_raise_tool_bar_buttons_p,
26183 doc: /* *Non-nil means raise tool-bar buttons when the mouse moves over them. */);
26184 auto_raise_tool_bar_buttons_p = 1;
26185
26186 DEFVAR_BOOL ("make-cursor-line-fully-visible", &make_cursor_line_fully_visible_p,
26187 doc: /* *Non-nil means to scroll (recenter) cursor line if it is not fully visible. */);
26188 make_cursor_line_fully_visible_p = 1;
26189
26190 DEFVAR_LISP ("tool-bar-border", &Vtool_bar_border,
26191 doc: /* *Border below tool-bar in pixels.
26192 If an integer, use it as the height of the border.
26193 If it is one of `internal-border-width' or `border-width', use the
26194 value of the corresponding frame parameter.
26195 Otherwise, no border is added below the tool-bar. */);
26196 Vtool_bar_border = Qinternal_border_width;
26197
26198 DEFVAR_LISP ("tool-bar-button-margin", &Vtool_bar_button_margin,
26199 doc: /* *Margin around tool-bar buttons in pixels.
26200 If an integer, use that for both horizontal and vertical margins.
26201 Otherwise, value should be a pair of integers `(HORZ . VERT)' with
26202 HORZ specifying the horizontal margin, and VERT specifying the
26203 vertical margin. */);
26204 Vtool_bar_button_margin = make_number (DEFAULT_TOOL_BAR_BUTTON_MARGIN);
26205
26206 DEFVAR_INT ("tool-bar-button-relief", &tool_bar_button_relief,
26207 doc: /* *Relief thickness of tool-bar buttons. */);
26208 tool_bar_button_relief = DEFAULT_TOOL_BAR_BUTTON_RELIEF;
26209
26210 DEFVAR_LISP ("tool-bar-style", &Vtool_bar_style,
26211 doc: /* *Tool bar style to use.
26212 It can be one of
26213 image - show images only
26214 text - show text only
26215 both - show both, text below image
26216 both-horiz - show text to the right of the image
26217 text-image-horiz - show text to the left of the image
26218 any other - use system default or image if no system default. */);
26219 Vtool_bar_style = Qnil;
26220
26221 DEFVAR_INT ("tool-bar-max-label-size", &tool_bar_max_label_size,
26222 doc: /* *Maximum number of characters a label can have to be shown.
26223 The tool bar style must also show labels for this to have any effect, see
26224 `tool-bar-style'. */);
26225 tool_bar_max_label_size = DEFAULT_TOOL_BAR_LABEL_SIZE;
26226
26227 DEFVAR_LISP ("fontification-functions", &Vfontification_functions,
26228 doc: /* List of functions to call to fontify regions of text.
26229 Each function is called with one argument POS. Functions must
26230 fontify a region starting at POS in the current buffer, and give
26231 fontified regions the property `fontified'. */);
26232 Vfontification_functions = Qnil;
26233 Fmake_variable_buffer_local (Qfontification_functions);
26234
26235 DEFVAR_BOOL ("unibyte-display-via-language-environment",
26236 &unibyte_display_via_language_environment,
26237 doc: /* *Non-nil means display unibyte text according to language environment.
26238 Specifically, this means that raw bytes in the range 160-255 decimal
26239 are displayed by converting them to the equivalent multibyte characters
26240 according to the current language environment. As a result, they are
26241 displayed according to the current fontset.
26242
26243 Note that this variable affects only how these bytes are displayed,
26244 but does not change the fact they are interpreted as raw bytes. */);
26245 unibyte_display_via_language_environment = 0;
26246
26247 DEFVAR_LISP ("max-mini-window-height", &Vmax_mini_window_height,
26248 doc: /* *Maximum height for resizing mini-windows.
26249 If a float, it specifies a fraction of the mini-window frame's height.
26250 If an integer, it specifies a number of lines. */);
26251 Vmax_mini_window_height = make_float (0.25);
26252
26253 DEFVAR_LISP ("resize-mini-windows", &Vresize_mini_windows,
26254 doc: /* *How to resize mini-windows.
26255 A value of nil means don't automatically resize mini-windows.
26256 A value of t means resize them to fit the text displayed in them.
26257 A value of `grow-only', the default, means let mini-windows grow
26258 only, until their display becomes empty, at which point the windows
26259 go back to their normal size. */);
26260 Vresize_mini_windows = Qgrow_only;
26261
26262 DEFVAR_LISP ("blink-cursor-alist", &Vblink_cursor_alist,
26263 doc: /* Alist specifying how to blink the cursor off.
26264 Each element has the form (ON-STATE . OFF-STATE). Whenever the
26265 `cursor-type' frame-parameter or variable equals ON-STATE,
26266 comparing using `equal', Emacs uses OFF-STATE to specify
26267 how to blink it off. ON-STATE and OFF-STATE are values for
26268 the `cursor-type' frame parameter.
26269
26270 If a frame's ON-STATE has no entry in this list,
26271 the frame's other specifications determine how to blink the cursor off. */);
26272 Vblink_cursor_alist = Qnil;
26273
26274 DEFVAR_BOOL ("auto-hscroll-mode", &automatic_hscrolling_p,
26275 doc: /* *Non-nil means scroll the display automatically to make point visible. */);
26276 automatic_hscrolling_p = 1;
26277 Qauto_hscroll_mode = intern_c_string ("auto-hscroll-mode");
26278 staticpro (&Qauto_hscroll_mode);
26279
26280 DEFVAR_INT ("hscroll-margin", &hscroll_margin,
26281 doc: /* *How many columns away from the window edge point is allowed to get
26282 before automatic hscrolling will horizontally scroll the window. */);
26283 hscroll_margin = 5;
26284
26285 DEFVAR_LISP ("hscroll-step", &Vhscroll_step,
26286 doc: /* *How many columns to scroll the window when point gets too close to the edge.
26287 When point is less than `hscroll-margin' columns from the window
26288 edge, automatic hscrolling will scroll the window by the amount of columns
26289 determined by this variable. If its value is a positive integer, scroll that
26290 many columns. If it's a positive floating-point number, it specifies the
26291 fraction of the window's width to scroll. If it's nil or zero, point will be
26292 centered horizontally after the scroll. Any other value, including negative
26293 numbers, are treated as if the value were zero.
26294
26295 Automatic hscrolling always moves point outside the scroll margin, so if
26296 point was more than scroll step columns inside the margin, the window will
26297 scroll more than the value given by the scroll step.
26298
26299 Note that the lower bound for automatic hscrolling specified by `scroll-left'
26300 and `scroll-right' overrides this variable's effect. */);
26301 Vhscroll_step = make_number (0);
26302
26303 DEFVAR_BOOL ("message-truncate-lines", &message_truncate_lines,
26304 doc: /* If non-nil, messages are truncated instead of resizing the echo area.
26305 Bind this around calls to `message' to let it take effect. */);
26306 message_truncate_lines = 0;
26307
26308 DEFVAR_LISP ("menu-bar-update-hook", &Vmenu_bar_update_hook,
26309 doc: /* Normal hook run to update the menu bar definitions.
26310 Redisplay runs this hook before it redisplays the menu bar.
26311 This is used to update submenus such as Buffers,
26312 whose contents depend on various data. */);
26313 Vmenu_bar_update_hook = Qnil;
26314
26315 DEFVAR_LISP ("menu-updating-frame", &Vmenu_updating_frame,
26316 doc: /* Frame for which we are updating a menu.
26317 The enable predicate for a menu binding should check this variable. */);
26318 Vmenu_updating_frame = Qnil;
26319
26320 DEFVAR_BOOL ("inhibit-menubar-update", &inhibit_menubar_update,
26321 doc: /* Non-nil means don't update menu bars. Internal use only. */);
26322 inhibit_menubar_update = 0;
26323
26324 DEFVAR_LISP ("wrap-prefix", &Vwrap_prefix,
26325 doc: /* Prefix prepended to all continuation lines at display time.
26326 The value may be a string, an image, or a stretch-glyph; it is
26327 interpreted in the same way as the value of a `display' text property.
26328
26329 This variable is overridden by any `wrap-prefix' text or overlay
26330 property.
26331
26332 To add a prefix to non-continuation lines, use `line-prefix'. */);
26333 Vwrap_prefix = Qnil;
26334 staticpro (&Qwrap_prefix);
26335 Qwrap_prefix = intern_c_string ("wrap-prefix");
26336 Fmake_variable_buffer_local (Qwrap_prefix);
26337
26338 DEFVAR_LISP ("line-prefix", &Vline_prefix,
26339 doc: /* Prefix prepended to all non-continuation lines at display time.
26340 The value may be a string, an image, or a stretch-glyph; it is
26341 interpreted in the same way as the value of a `display' text property.
26342
26343 This variable is overridden by any `line-prefix' text or overlay
26344 property.
26345
26346 To add a prefix to continuation lines, use `wrap-prefix'. */);
26347 Vline_prefix = Qnil;
26348 staticpro (&Qline_prefix);
26349 Qline_prefix = intern_c_string ("line-prefix");
26350 Fmake_variable_buffer_local (Qline_prefix);
26351
26352 DEFVAR_BOOL ("inhibit-eval-during-redisplay", &inhibit_eval_during_redisplay,
26353 doc: /* Non-nil means don't eval Lisp during redisplay. */);
26354 inhibit_eval_during_redisplay = 0;
26355
26356 DEFVAR_BOOL ("inhibit-free-realized-faces", &inhibit_free_realized_faces,
26357 doc: /* Non-nil means don't free realized faces. Internal use only. */);
26358 inhibit_free_realized_faces = 0;
26359
26360 #if GLYPH_DEBUG
26361 DEFVAR_BOOL ("inhibit-try-window-id", &inhibit_try_window_id,
26362 doc: /* Inhibit try_window_id display optimization. */);
26363 inhibit_try_window_id = 0;
26364
26365 DEFVAR_BOOL ("inhibit-try-window-reusing", &inhibit_try_window_reusing,
26366 doc: /* Inhibit try_window_reusing display optimization. */);
26367 inhibit_try_window_reusing = 0;
26368
26369 DEFVAR_BOOL ("inhibit-try-cursor-movement", &inhibit_try_cursor_movement,
26370 doc: /* Inhibit try_cursor_movement display optimization. */);
26371 inhibit_try_cursor_movement = 0;
26372 #endif /* GLYPH_DEBUG */
26373
26374 DEFVAR_INT ("overline-margin", &overline_margin,
26375 doc: /* *Space between overline and text, in pixels.
26376 The default value is 2: the height of the overline (1 pixel) plus 1 pixel
26377 margin to the caracter height. */);
26378 overline_margin = 2;
26379
26380 DEFVAR_INT ("underline-minimum-offset",
26381 &underline_minimum_offset,
26382 doc: /* Minimum distance between baseline and underline.
26383 This can improve legibility of underlined text at small font sizes,
26384 particularly when using variable `x-use-underline-position-properties'
26385 with fonts that specify an UNDERLINE_POSITION relatively close to the
26386 baseline. The default value is 1. */);
26387 underline_minimum_offset = 1;
26388
26389 DEFVAR_BOOL ("display-hourglass", &display_hourglass_p,
26390 doc: /* Non-zero means Emacs displays an hourglass pointer on window systems. */);
26391 display_hourglass_p = 1;
26392
26393 DEFVAR_LISP ("hourglass-delay", &Vhourglass_delay,
26394 doc: /* *Seconds to wait before displaying an hourglass pointer.
26395 Value must be an integer or float. */);
26396 Vhourglass_delay = make_number (DEFAULT_HOURGLASS_DELAY);
26397
26398 hourglass_atimer = NULL;
26399 hourglass_shown_p = 0;
26400 }
26401
26402
26403 /* Initialize this module when Emacs starts. */
26404
26405 void
26406 init_xdisp (void)
26407 {
26408 Lisp_Object root_window;
26409 struct window *mini_w;
26410
26411 current_header_line_height = current_mode_line_height = -1;
26412
26413 CHARPOS (this_line_start_pos) = 0;
26414
26415 mini_w = XWINDOW (minibuf_window);
26416 root_window = FRAME_ROOT_WINDOW (XFRAME (WINDOW_FRAME (mini_w)));
26417
26418 if (!noninteractive)
26419 {
26420 struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (root_window)));
26421 int i;
26422
26423 XWINDOW (root_window)->top_line = make_number (FRAME_TOP_MARGIN (f));
26424 set_window_height (root_window,
26425 FRAME_LINES (f) - 1 - FRAME_TOP_MARGIN (f),
26426 0);
26427 mini_w->top_line = make_number (FRAME_LINES (f) - 1);
26428 set_window_height (minibuf_window, 1, 0);
26429
26430 XWINDOW (root_window)->total_cols = make_number (FRAME_COLS (f));
26431 mini_w->total_cols = make_number (FRAME_COLS (f));
26432
26433 scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs;
26434 scratch_glyph_row.glyphs[TEXT_AREA + 1]
26435 = scratch_glyphs + MAX_SCRATCH_GLYPHS;
26436
26437 /* The default ellipsis glyphs `...'. */
26438 for (i = 0; i < 3; ++i)
26439 default_invis_vector[i] = make_number ('.');
26440 }
26441
26442 {
26443 /* Allocate the buffer for frame titles.
26444 Also used for `format-mode-line'. */
26445 int size = 100;
26446 mode_line_noprop_buf = (char *) xmalloc (size);
26447 mode_line_noprop_buf_end = mode_line_noprop_buf + size;
26448 mode_line_noprop_ptr = mode_line_noprop_buf;
26449 mode_line_target = MODE_LINE_DISPLAY;
26450 }
26451
26452 help_echo_showing_p = 0;
26453 }
26454
26455 /* Since w32 does not support atimers, it defines its own implementation of
26456 the following three functions in w32fns.c. */
26457 #ifndef WINDOWSNT
26458
26459 /* Platform-independent portion of hourglass implementation. */
26460
26461 /* Return non-zero if houglass timer has been started or hourglass is shown. */
26462 int
26463 hourglass_started (void)
26464 {
26465 return hourglass_shown_p || hourglass_atimer != NULL;
26466 }
26467
26468 /* Cancel a currently active hourglass timer, and start a new one. */
26469 void
26470 start_hourglass (void)
26471 {
26472 #if defined (HAVE_WINDOW_SYSTEM)
26473 EMACS_TIME delay;
26474 int secs, usecs = 0;
26475
26476 cancel_hourglass ();
26477
26478 if (INTEGERP (Vhourglass_delay)
26479 && XINT (Vhourglass_delay) > 0)
26480 secs = XFASTINT (Vhourglass_delay);
26481 else if (FLOATP (Vhourglass_delay)
26482 && XFLOAT_DATA (Vhourglass_delay) > 0)
26483 {
26484 Lisp_Object tem;
26485 tem = Ftruncate (Vhourglass_delay, Qnil);
26486 secs = XFASTINT (tem);
26487 usecs = (XFLOAT_DATA (Vhourglass_delay) - secs) * 1000000;
26488 }
26489 else
26490 secs = DEFAULT_HOURGLASS_DELAY;
26491
26492 EMACS_SET_SECS_USECS (delay, secs, usecs);
26493 hourglass_atimer = start_atimer (ATIMER_RELATIVE, delay,
26494 show_hourglass, NULL);
26495 #endif
26496 }
26497
26498
26499 /* Cancel the hourglass cursor timer if active, hide a busy cursor if
26500 shown. */
26501 void
26502 cancel_hourglass (void)
26503 {
26504 #if defined (HAVE_WINDOW_SYSTEM)
26505 if (hourglass_atimer)
26506 {
26507 cancel_atimer (hourglass_atimer);
26508 hourglass_atimer = NULL;
26509 }
26510
26511 if (hourglass_shown_p)
26512 hide_hourglass ();
26513 #endif
26514 }
26515 #endif /* ! WINDOWSNT */
26516
26517 /* arch-tag: eacc864d-bb6a-4b74-894a-1a4399a1358b
26518 (do not change this comment) */